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  +*.vc
            2  +

Added .fossil-settings/ignore-glob.

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

Added .fossil-settings/manifest.

            1  +on

Changes to CHANGES.

            1  +2018-07-16  Rolf Ade  <rolf@pointsman.de>
            2  +
            3  +        The package name is tDOM, but it always has been requested by
            4  +        [package require tdom] and now the scripted helper commands in
            5  +        tdom.tcl are also in the namespace tdom (not anymore in tDOM).
            6  +        The new pullparser command is now also in this namespace.
            7  +        There are aliases from the old command names to the new one,
            8  +        so there must be nothing done; old scripts will run as they
            9  +        did. It's just, that you in new code don't have to write
           10  +        serveral upcase letters in a row because of tDOM.
           11  +
           12  +2018-07-14  Rolf Ade  <rolf@pointsman.de>
           13  +
           14  +        Updated to expat 2.2.5. Expat now want to use a "good" entropy
           15  +        source to salt internal hash table (to reduce the possibility
           16  +        of DoS attacts with malicious XML input). Configure tries to
           17  +        figure out automatically the most appropriate entropy source
           18  +        on your platform. The new configure switch --with-entropy
           19  +        gives control over that. The configure switch
           20  +        --without-entropy disables all this; expat (and in turn tDOM)
           21  +        will use what was used in earlier expat versions.
           22  +
           23  +2018-07-12  Rolf Ade  <rolf@pointsman.de>
           24  +
           25  +        Updated TEA.
           26  +
           27  +2018-05-17  Rolf Ade  <rolf@pointsman.de>
           28  +
           29  +        Added new method attributeNames to domNode (cmds).
           30  +
           31  +2018-05-10  Rolf Ade  <rolf@pointsman.de>
           32  +
           33  +        Added new methods line and column to most pull parser states.
           34  +
           35  +2018-05-04  Rolf Ade  <rolf@pointsman.de>
           36  +
           37  +        More fine grain control about serialization details: new asXML
           38  +        options -nogtescape and -noEmptyElementTag.
           39  +
           40  +2018-04-24  Rolf Ade  <rolf@pointsman.de>
           41  +
           42  +        Fixed a potentially dramatic speed problem in case of certain
           43  +        classes of XPath expressions if a threads enabled tDOM is
           44  +        used, the result set is large and the DOM tree to query was
           45  +        altered somewhere before the query by an operation, which
           46  +        appended, inserted or replaced a node.
           47  +
           48  +2018-03-09  Rolf Ade  <rolf@pointsman.de>
           49  +
           50  +        Added command tDOM::pullparser, with creates simple XML "pull"
           51  +        parser commands. This commands parse XML input and stop at
           52  +        certain points ("events"). You continue parsing at your will.
           53  +
           54  +2018-03-06  Rolf Ade  <rolf@pointsman.de>
           55  +
           56  +        Fixed a potentially dramatic speed problem, if the expat
           57  +        parser is used w/ "Welch dispatch" with any 8.6 version. The
           58  +        core changed behaviour, we had to adapt.
           59  +
           60  +        Added method "delete" to the [expat] push parser (as an alias
           61  +        to the still there "free").
           62  +
           63  +2018-02-14  Rolf Ade  <rolf@pointsman.de>
           64  +
           65  +        Added [dom featureinfo versionhash], which returns the fossil
           66  +        repository version hash of the sources build from.
           67  +        
           68  +2018-02-03  Rolf Ade  <rolf@pointsman.de>
           69  +
           70  +        In a bunch of spell fixes a few changes (partly even marginal,
           71  +        e.g. during configuration) in error messages for uniformly
           72  +        usage of names.
           73  +
           74  +2017-11-07  Rolf Ade  <rolf@pointsman.de>
           75  +
           76  +        New flag -keepCDATA for [dom parse ...].
           77  +
           78  +--- Release 0.9.0, 24. Aug. 2017 --- 
           79  +
           80  +2017-08-21 Ashok Nadkarni
           81  +
           82  +        Windows build system (VC and mingw) modernised.
           83  +
           84  +2017-08-17 Rolf Ade  <rolf@pointsman.de>
           85  +
           86  +        New feature "creating real FQ nodes with *fromScript methods",
           87  +        by adding option -namespace to [dom createNodeCmd].
           88  +
           89  +2017-08-14 Rolf Ade  <rolf@pointsman.de>
           90  +
           91  +        Updated TEA.
           92  +
           93  +2017-07-29 Rolf Ade  <rolf@pointsman.de>
           94  +
           95  +        Removed hacky check on [load] time if the tclsh and tDOM are
           96  +        build with incompatible TCL_UTF_MAX (because it did not work
           97  +        anymore with recent tcl because of changes in core).
           98  +
           99  +2017-07-28 Rolf Ade  <rolf@pointsman.de>
          100  +
          101  +        Added JSON support. New -json option to [dom parse]. New doc
          102  +        method asJSON. New node method jsonType. New option -jsonType
          103  +        of [dom createNodeCmd]. New option -tagName of [dom
          104  +        createNodeCmd]. New option -jsonType to dom method
          105  +        createDocumentNode.
          106  +
          107  +2017-04-06 Rolf Ade  <rolf@pointsman.de>
          108  +
          109  +        Added HTM5 parser (new -html5 option to [dom parse]). Requires
          110  +        gumbo lib and must be enabled at configure time.
          111  +        
          112  +2016-10-01 Rolf Ade  <rolf@pointsman.de>
          113  +
          114  +        Updated to expat 2.2.0.
          115  +
          116  +2015-09-11 Rolf Ade  <rolf@pointsman.de>
          117  +
          118  +        Added options -xmlDeclaration and -encString to the asXML
          119  +        method of the domDoc and domNode commands.
          120  +
          121  +2015-04-11 Rolf Ade  <rolf@pointsman.de>
          122  +
          123  +        Changed behavior wrt to result code of a called
          124  +        -xsltmessagecmd script. Up to now, the result code of that
          125  +        script evaluation was ignored. Now, any other return code of
          126  +        that script then TCL_OK terminates the xslt transformation and
          127  +        returns error. Purposeful termination may be signaled with
          128  +        return -code break, for which the error message will be empty.
          129  +
          130  +2015-04-01 Rolf Ade  <rolf@pointsman.de>
          131  +
          132  +        Added new expat parser cmd method currentmarkup. 
          133  +
          134  +2015-03-26 Rolf Ade  <rolf@pointsman.de>
          135  +
          136  +        Added option -indentAttrs to the domDoc/domNode method
          137  +        asXML. Thanks goes to evilotto.
          138  +
          139  +2014-10-16 Rolf Ade  <rolf@pointsman.de>
          140  +	
          141  +        Added configure option --with-expat, to build and link against
          142  +        the system or a custom expat lib. Default is, to use the
          143  +        included sources.
          144  +
          145  +2014-01-01 Rolf Ade  <rolf@pointsman.de>
          146  +
          147  +        Rework so some basic internals, for (even) more efficiency of
          148  +        token mode.
          149  +
          150  +2013-12-24 Rolf Ade  <rolf@pointsman.de>
          151  +
          152  +        Improved handling of characters beyond BMP. 
          153  +        
          154  +2013-12-20 Rolf Ade  <rolf@pointsman.de>
          155  +
          156  +        Added option -feedbackcmd to the dom parse method. This option
          157  +        allows to specify a script, which will be called as feedback
          158  +        command. For backward compatibility, if no -feedbackcmd is
          159  +        given, but there is a tcl proc named ::dom::domParseFeedback
          160  +        then this proc is used as -feedbackcmd. If there isn't such a
          161  +        proc and -feedbackAfter is used, it is an error to not also
          162  +        use -feedbackcmd. A return -code break from the -feedbackcmd
          163  +        causes the parser to almost immediately abort parsing and let
          164  +        the [dom parse] call return the empty string (instead of a
          165  +        document) without raising error. 
          166  +
          167  +        For expat parser objects: If a handler script returns -code
          168  +        return, then parsing is aborted, but no error is raised.
          169  +
          170  +2013-12-04 Rolf Ade <rolf@pointsman.de>
          171  +
          172  +        tDOM now cross-compiles on linux for windows (w32/w64) with
          173  +        mingw-w64.
          174  +        
          175  +2013-09-26 Rolf Ade  <rolf@pointsman.de>
          176  +
          177  +        Added dom method featureinfo.
          178  +
          179  +2013-08-31 Rolf Ade  <rolf@pointsman.de>
          180  +
          181  +        Raised the limit of maximum number of different XML
          182  +        namespaceses within one DOM tree to 2^31. New configure switch
          183  +        --enable-lessns restores old code.
          184  +
          185  +2013-07-21 Rolf Ade  <rolf@pointsman.de>
          186  +
          187  +        Updated TEA build system of tdom itself and the extensions.
          188  +
          189  +2013-05-16  Rolf Ade  <rolf@pointsman.de>
          190  +
          191  +        Update to expat 2.1.0.
     1    192   
     2    193   --- Release 0.8.2, 15. Aug. 2007 --- See ChangeLog for details ---
     3    194   
     4    195   2007-08-11  Rolf Ade  <rolf@pointsman.de>
     5    196   
     6    197           Now tcldomsh will source ~/.tcldomshrc at start up.
     7    198   

Changes to ChangeLog.

            1  +
            2  +NOTICE: This file isn't kept up to date anymore. Look at the timeline
            3  +of the leading fossil repository (http://tdom.org) or at the backup
            4  +repository at https://core.tcl.tk/tdom/timeline for detailed lists of
            5  +code changes.
            6  +
            7  +User interface changes/enhancements and other important changes will
            8  +still be documented in the CHANGES file.
            9  +
           10  +2012-05-17  Rolf Ade  <rolf@pointsman.de>
           11  +
           12  +        * generic/dom.h
           13  +        * generic/tcldom.c: Compatibility with Tcl 8.6 - Beginning
           14  +          with 8.6, interp->errorLine isn't public visible anymore
           15  +          (TIP 330).
           16  +
           17  +        * generic/domxslt.c: Fixed wrong size on memcpy on 64 bit
           18  +          (when sizeof(int)!=sizeof(int*))
           19  +
     1     20   2009-11-10  Rolf Ade  <rolf@pointsman.de>
     2     21   
     3     22           * expat/xmltok_impl.c: Fix for possible DoS attack (see
     4     23             CVE-2009-3720)
     5     24   
     6     25   
     7     26   2008-08-27  Rolf Ade  <rolf@pointsman.de>
................................................................................
   708    727   2005-01-11  Rolf Ade  <rolf@pointsman.de>
   709    728   
   710    729           * doc/domDoc.*
   711    730           * doc/domNode.*: Added documentation for the -cache option of
   712    731             the selectNodes method.
   713    732   
   714    733           * lib/tdom.tcl: Scripted xpath function element-available:
   715         -          moved xsl:output to the avaliable elements, since it's in
   716         -          fact avaliable in the meantime (with exception of the
          734  +          moved xsl:output to the available elements, since it's in
          735  +          fact available in the meantime (with exception of the
   717    736             'version' and 'cdata-section-elements' attributes) - the
   718    737             output options can be queried from the result doc, but it's
   719    738             the responsibility of the application, to serialize the tree
   720    739             according to that settings.
   721    740   
   722    741   2005-01-10  Rolf Ade  <rolf@pointsman.de>
   723    742   
................................................................................
   938    957           * doc/domNode.*
   939    958           * generic/tcldom.c: Improved speed of the getAttribute
   940    959             shortcut '@attname' (and, not so notable, of tcl coded
   941    960             methods of the dom, domDoc and domNode cmds). Corrected typo
   942    961             in domNode usage msg for getElementByID. Improved error msg
   943    962             for getAttribute, if attribute is not found. Changed
   944    963             behavior of getElementByID: if no element with the given id
   945         -          is found, returns now the emtpy string, not a TCL_ERROR
          964  +          is found, returns now the empty string, not a TCL_ERROR
   946    965             (closer to DOM rec, getElementByID never raise an
   947    966             exception). Bug fix: nodeName now returns the per DOM rec
   948    967             correct values for comment and cdata section nodes (were as
   949    968             yet reported as if they where text nodes).
   950    969   
   951    970           * tests/entity.test  
   952    971           * generic/tclexpat.c: Better error msg in case of 'filename'
................................................................................
  1300   1319   
  1301   1320   2003-10-16  Zoran Vasiljevic  <zv@archiware.com>
  1302   1321   
  1303   1322   	* generic/tcldom.c: added "dom detachDocument" command
  1304   1323   	  to match the already present "dom attachDocument".
  1305   1324   	  This is used only for threaded tdom builds.
  1306   1325   
  1307         -	* generic/domlock.c: changed lock caching to accomodate for
         1326  +	* generic/domlock.c: changed lock caching to accommodate for
  1308   1327   	  situation with huge number of created documnents
  1309   1328   	
  1310   1329   	  Also, added new "domDoc" command as a first-class tdom citizen,
  1311   1330   	  analogous to the already existing "domNode". It operates on the
  1312   1331   	  document token.
  1313   1332   
  1314   1333   	  Attempt has been made to start to follow Tcl-style-guide
................................................................................
  1724   1743             overwriting named templates without match attribute with an
  1725   1744             other named template). Improved error reports: for more
  1726   1745             detected errors there is now a line/column number
  1727   1746             given. Plenty of improvements in detecting erroneous
  1728   1747             stylesheets: more checks for format-number formatting
  1729   1748             patters (although especically format-number patterns are
  1730   1749             still a can of worms), added parameter number check for
  1731         -          additional XPath function current(), template, paramter,
         1750  +          additional XPath function current(), template, parameter,
  1732   1751             variable, sort, choose, copy, and message elements.
  1733   1752   
  1734   1753   2003-03-26  Rolf Ade  <rolf@pointsman.de>
  1735   1754           
  1736   1755           * generic/domxslt.c: Fixed some memory problems, mostly in
  1737   1756             case of erroneous stylesheets.
  1738   1757   
................................................................................
  1910   1929   
  1911   1930           * lib/tdom.tcl
  1912   1931             generic/dom.c: Improved ::tDOM::xml(Read|Open)File. Now
  1913   1932             handles also utf-16 files with BOM right.
  1914   1933   
  1915   1934           * generic/domxslt.c: Made some functions static. Removed a
  1916   1935             TODO note, which already was done. Improved some error msgs
  1917         -          (now with line/column info, if avaliable). Bug fix:
         1936  +          (now with line/column info, if available). Bug fix:
  1918   1937             xsltXPathFuncs must return -1 to signal error, because if
  1919   1938             the source of the function call was inside of domxslt.c the
  1920   1939             result code (rc) check rule is rc < 0. Fixed text in a
  1921   1940             xsl:attribute error msg. Fixed memory leak in error case in
  1922   1941             ExecAction, case forEach. Added a missing result code check
  1923   1942             in ExecAction, case procinstr. Bug fix: Even literal result
  1924   1943             element subtrees are relevant for xslt variable scope
................................................................................
  2070   2089           * generic/dom.c
  2071   2090           * generic/tcldom.c
  2072   2091           * tests/dom.test: Fix for the problem with ownerDocument
  2073   2092             reported by Oleg Oleinick (see test dom-29.1).
  2074   2093   
  2075   2094           * generic/tcldom.c
  2076   2095           * tests/dom.test: Fixed bug with COMMENT_NODEs while using the
  2077         -          asList method (problem reported by Ramon Ribó). While at it,
         2096  +          asList method (problem reported by Ramon Ribó). While at it,
  2078   2097             also added code for handling processing instructions, which
  2079   2098             was also missing, up to now.
  2080   2099   
  2081   2100   2003-01-11  Rolf Ade  <rolf@pointsman.de>
  2082   2101   
  2083   2102           * generic/dom.c
  2084   2103           * generic/dom.h
................................................................................
  2120   2139   2002-12-20  Zoran Vasiljevic  (zoran@archiware.com)
  2121   2140   
  2122   2141   	* generic/tcldom.c
  2123   2142   	* generic/dom.c
  2124   2143   	* generic/domxpath.c
  2125   2144   	* generic/domalloc.c
  2126   2145   	* generic/domhtml.c
  2127         -	* generic/docxpath.c: added DBG macro arround some fprintf's
         2146  +	* generic/docxpath.c: added DBG macro around some fprintf's
  2128   2147   
  2129   2148   2002-11-28  Rolf Ade  <rolf@pointsman.de>
  2130   2149   
  2131   2150           * generic/domxslt.c: Reuse already parsed trees only if it is
  2132   2151             requested again for the same matter (as stylesheet or as
  2133   2152             source dir), otherwise create a new tree, because of the
  2134   2153             different white space stripping rules for stylesheets and
................................................................................
  2276   2295           * lib/tdom.tcl: tDOM::xmlOpenFile fix for files < 4 Byte size.    
  2277   2296           
  2278   2297           * generic/domxpath.c
  2279   2298           * generic/domxpath.h: Fixed ridiculously long runtime of
  2280   2299             certain // expr on certain documents. During analysis and
  2281   2300             testing, it turned out, that it would have been an even
  2282   2301             simpler approach, to simply expand the abbreviation // in
  2283         -          the according productions. Though, the choosen implentation
         2302  +          the according productions. Though, the chosen implementation
  2284   2303             seems often to be (slightly) faster and is a start to
  2285   2304             collect experiences with early predicate evaluation.
  2286   2305   
  2287   2306   2002-11-02  Zoran Vasiljevic  <zoran@archiware.com>
  2288   2307   
  2289   2308   	* lib/tdomhtml.tcl: removed in favour of new tdom extension
  2290   2309   

Changes to Makefile.in.

     1         -# Makefile.in --
            1  +#  Makefile.in --
     2      2   #
     3         -#	This file is a Makefile for Sample TEA Extension.  If it has the name
            3  +#	This file is a Makefile for the tdom TEA Extension. If it has the name
     4      4   #	"Makefile.in" then it is a template for a Makefile;  to generate the
     5      5   #	actual Makefile, run "./configure", which is a configuration script
     6      6   #	generated by the "autoconf" program (constructs like "@foo@" will get
     7      7   #	replaced in the actual Makefile.
     8      8   #
            9  +# Copyright (c) 2013 Rolf Ade
           10  +#
           11  +# Derived from work
     9     12   # Copyright (c) 1999 Scriptics Corporation.
    10     13   # Copyright (c) 2002-2005 ActiveState Corporation.
    11     14   #
    12     15   # See the file "license.terms" for information on usage and redistribution
    13     16   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    14         -#
    15         -# RCS: @(#) $Id$
    16     17   
    17     18   #========================================================================
    18     19   # Add additional lines to handle any additional AC_SUBST cases that
    19     20   # have been added in a customized configure script.
    20     21   #========================================================================
    21     22   
    22     23   AOL_DIR		= @AOL_DIR@
................................................................................
    79     80   
    80     81   srcdir		= @srcdir@
    81     82   prefix		= @prefix@
    82     83   exec_prefix	= @exec_prefix@
    83     84   
    84     85   bindir		= @bindir@
    85     86   libdir		= @libdir@
           87  +includedir	= @includedir@
           88  +datarootdir	= @datarootdir@
    86     89   datadir		= @datadir@
    87     90   mandir		= @mandir@
    88         -includedir	= @includedir@
    89     91   
    90     92   DESTDIR		=
    91     93   
    92     94   PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
    93     95   pkgdatadir	= $(datadir)/$(PKG_DIR)
    94     96   pkglibdir	= $(libdir)/$(PKG_DIR)
    95     97   pkgincludedir	= $(includedir)/$(PKG_DIR)
    96     98   
    97     99   top_builddir	= .
    98    100   
    99         -INSTALL		= @INSTALL@
   100         -INSTALL_PROGRAM	= @INSTALL_PROGRAM@
   101         -INSTALL_DATA	= @INSTALL_DATA@
   102         -INSTALL_SCRIPT	= @INSTALL_SCRIPT@
          101  +INSTALL_OPTIONS =
          102  +INSTALL		= $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS}
          103  +INSTALL_DATA_DIR = ${INSTALL} -d -m 755
          104  +INSTALL_PROGRAM	= ${INSTALL} -m 555
          105  +INSTALL_DATA	= ${INSTALL} -m 444
          106  +INSTALL_SCRIPT	= ${INSTALL_PROGRAM}
          107  +INSTALL_LIBRARY	= ${INSTALL_DATA}
   103    108   
   104    109   PACKAGE_NAME	= @PACKAGE_NAME@
   105    110   PACKAGE_VERSION	= @PACKAGE_VERSION@
   106    111   CC		= @CC@
   107    112   CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
   108    113   CFLAGS_WARNING	= @CFLAGS_WARNING@
   109         -CLEANFILES	= @CLEANFILES@
   110    114   EXEEXT		= @EXEEXT@
   111    115   LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
   112    116   MAKE_LIB	= @MAKE_LIB@
   113    117   MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
   114    118   MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
   115    119   MAKE_STUB_LIB	= @MAKE_STUB_LIB@
   116    120   OBJEXT		= @OBJEXT@
................................................................................
   121    125   SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
   122    126   STLIB_LD	= @STLIB_LD@
   123    127   #TCL_DEFS	= @TCL_DEFS@
   124    128   TCL_BIN_DIR	= @TCL_BIN_DIR@
   125    129   TCL_SRC_DIR	= @TCL_SRC_DIR@
   126    130   #TK_BIN_DIR	= @TK_BIN_DIR@
   127    131   #TK_SRC_DIR	= @TK_SRC_DIR@
          132  +
          133  +MATH_LIBS	= @MATH_LIBS@
   128    134   
   129    135   # Not used, but retained for reference of what libs Tcl required
   130    136   #TCL_LIBS	= @TCL_LIBS@
          137  +
          138  +TDOMSHELL_LIBS = @TCL_LIBS@ @SHLIB_LD_LIBS@
   131    139   
   132    140   #========================================================================
   133    141   # TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
   134    142   # package without installing.  The other environment variables allow us
   135    143   # to test against an uninstalled Tcl.  Add special env vars that you
   136    144   # require for testing here (like TCLX_LIBRARY).
   137    145   #========================================================================
   138    146   
   139    147   EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
   140    148   #EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
   141    149   TCLLIBPATH	= $(top_builddir)
   142         -TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
   143         -		  @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
          150  +TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
          151  +PKG_ENV		= @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
   144    152   		  PATH="$(EXTRA_PATH):$(PATH)" \
   145    153   		  TCLLIBPATH="$(TCLLIBPATH)"
   146         -#		  TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
   147    154   
   148    155   TCLSH_PROG	= @TCLSH_PROG@
   149         -TCLSH   	= $(TCLSH_ENV) $(TCLSH_PROG)
          156  +TCLSH		= $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
   150    157   
          158  +#WISH_ENV	= TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
   151    159   #WISH_PROG	= @WISH_PROG@
   152         -#WISH   	= $(TCLSH_ENV) $(WISH_PROG)
   153         -
          160  +#WISH		= $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
   154    161   
   155    162   SHARED_BUILD	= @SHARED_BUILD@
   156    163   
   157         -INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
          164  +INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ -I$(top_builddir)
   158    165   #INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
   159    166   
   160    167   PKG_CFLAGS	= @PKG_CFLAGS@
   161    168   
   162    169   # TCL_DEFS is not strictly need here, but if you remove it, then you
   163    170   # must make sure that configure.in checks for the necessary components
   164    171   # that your library may use.  TCL_DEFS can actually be a problem if
   165    172   # you do not compile with a similar machine setup as the Tcl core was
   166    173   # compiled with.
   167    174   #DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
   168    175   DEFS		= @DEFS@ $(PKG_CFLAGS)
   169    176   
   170         -CONFIG_CLEAN_FILES = Makefile tdomConfig.sh tdom.tcl
          177  +# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
          178  +CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl tdomConfig.sh versionhash.h
          179  +CLEANFILES	= @CLEANFILES@
   171    180   
   172    181   CPPFLAGS	= @CPPFLAGS@
   173    182   LIBS		= @PKG_LIBS@ @LIBS@
   174    183   AR		= @AR@
   175    184   CFLAGS		= @CFLAGS@
   176    185   COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
          186  +
          187  +.SUFFIXES: .c .$(OBJEXT)
   177    188   
   178    189   #========================================================================
   179    190   # Start of user-definable TARGETS section
   180    191   #========================================================================
   181    192   
   182    193   #========================================================================
   183    194   # TEA TARGETS.  Please note that the "libraries:" target refers to platform
   184         -# independent files, and the "binaries:" target inclues executable programs and
          195  +# independent files, and the "binaries:" target includes executable programs and
   185    196   # platform-dependent libraries.  Modify these targets so that they install
   186    197   # the various pieces of your package.  The make and install rules
   187    198   # for the BINARIES that you specified above have already been done.
   188    199   #========================================================================
   189    200   
   190    201   all: binaries libraries doc
   191    202   
   192    203   #========================================================================
   193    204   # TDOM enabled shell is build as an extra directive, since non TEA. 
   194    205   #========================================================================
   195    206   
   196         -$(TDOMSHELL): $(PKG_OBJECTS)
          207  +$(TDOMSHELL): $(PKG_OBJECTS) $(srcdir)/unix/tclAppInit.c
   197    208   	$(COMPILE) -c `@CYGPATH@ $(srcdir)/unix/tclAppInit.c`
   198    209   	$(CC) @LDFLAGS@ -o $@ tclAppInit.$(OBJEXT) $(PKG_OBJECTS) \
   199         -	  $(TCL_LIBS) $(TCL_LIB_SPEC) $(LIBS) $(TDOM_LD_SEARCH_FLAGS)
          210  +	  $(TCL_LIB_SPEC) $(TDOMSHELL_LIBS) $(TDOM_LD_SEARCH_FLAGS)
   200    211   
   201    212   #========================================================================
   202    213   # The binaries target builds executable programs, Windows .dll's, unix
   203    214   # shared/static libraries, and any other platform-dependent files.
   204    215   # The list of targets to build for "binaries:" is specified at the top
   205    216   # of the Makefile, in the "BINARIES" variable.
   206    217   #========================================================================
   207    218   
   208         -binaries: $(BINARIES) pkgIndex.tcl-hand
          219  +binaries: versionhash.h $(BINARIES) pkgIndex.tcl-hand
   209    220   
   210    221   libraries:
   211         -
   212    222   
   213    223   #========================================================================
   214    224   # Your doc target should differentiate from doc builds (by the developer)
   215    225   # and doc installs (see install-doc), which just install the docs on the
   216    226   # end user machine when building from source.
   217    227   #========================================================================
   218    228   
................................................................................
   224    234   
   225    235   #========================================================================
   226    236   # This rule installs platform-independent files, such as header files.
   227    237   # The list=...; for p in $$list handles the empty list case x-platform.
   228    238   #========================================================================
   229    239   
   230    240   install-libraries: libraries
   231         -	@mkdir -p $(DESTDIR)$(includedir)
          241  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir)
   232    242   	@echo "Installing header files in $(DESTDIR)$(includedir)"
   233    243   	@list='$(PKG_HEADERS)'; for i in $$list; do \
   234    244   	    echo "Installing $(srcdir)/$$i" ; \
   235    245   	    $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
   236    246   	done;
   237    247   
   238    248   #========================================================================
   239    249   # Install documentation.  Unix manpages should go in the $(mandir)
   240    250   # directory.
   241    251   #========================================================================
   242    252   
   243    253   install-doc: doc
   244         -	@mkdir -p $(DESTDIR)$(mandir)/mann
          254  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
   245    255   	@echo "Installing documentation in $(DESTDIR)$(mandir)"
   246    256   	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
   247    257   	    echo "Installing $$i"; \
   248         -	    rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
   249    258   	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
   250    259   	done
   251    260   
   252    261   test: binaries libraries
   253    262   	@cp $(srcdir)/lib/tdom.tcl .
   254    263   	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
   255    264   
   256    265   shell: binaries libraries
   257    266   	@$(TCLSH) $(SCRIPT)
   258    267   
   259    268   gdb:
   260    269   	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
          270  +
          271  +VALGRINDARGS =	--tool=memcheck --num-callers=20 --leak-resolution=high \
          272  +		--leak-check=yes --show-reachable=yes -v
          273  +
          274  +valgrind: binaries libraries
          275  +	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
          276  +		`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
          277  +
          278  +valgrindshell: binaries libraries
          279  +	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
   261    280   
   262    281   depend:
   263    282   
   264    283   #========================================================================
   265    284   # $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
   266    285   # mentioned above.  That will ensure that this target is built when you
   267    286   # run "make binaries".
................................................................................
   292    311   # 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
   293    312   #
   294    313   # Setting the VPATH variable to a list of paths will cause the makefile
   295    314   # to look into these paths when resolving .c to .obj dependencies.
   296    315   # As necessary, add $(srcdir):$(srcdir)/compat:....
   297    316   #========================================================================
   298    317   
   299         -VPATH = $(srcdir):$(srcdir)/expat:$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win
          318  +VPATH = $(srcdir):$(srcdir)/expat:$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx
   300    319   
   301    320   .c.@OBJEXT@:
   302    321   	$(COMPILE) -c `@CYGPATH@ $<` -o $@
   303    322   
   304    323   #========================================================================
   305    324   # Create the pkgIndex.tcl file.
   306    325   #========================================================================
   307    326   
   308    327   pkgIndex.tcl-hand:
   309    328   	@(echo 'package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
   310    329   	"load [list [file join $$dir $(PKG_LIB_FILE)]];\
   311    330            source [list [file join $$dir tdom.tcl]]"'\
   312    331   	) > pkgIndex.tcl
          332  +
          333  +#========================================================================
          334  +# Create tdomDecls.h and tdomStubInit.c from tdom.decls
          335  +#========================================================================
          336  +
          337  +genstubs: $(srcdir)/generic/tdom.decls
          338  +	$(TCLSH_PROG) $(TCL_SRC_DIR)/tools/genStubs.tcl $(srcdir)/generic \
          339  +               $(srcdir)/generic/tdom.decls
          340  +
          341  +#========================================================================
          342  +# Create a include file that #define the current fossil hash
          343  +#========================================================================
          344  +versionhash.h: $(srcdir)/manifest.uuid
          345  +	@echo "#define FOSSIL_HASH \"" | tr -d '\n\r' > $(top_builddir)/versionhash.h
          346  +	@cat $(srcdir)/manifest.uuid | tr -d '\n\r' >> $(top_builddir)/versionhash.h
          347  +	@echo "\"" >> $(top_builddir)/versionhash.h
          348  +
          349  +tcldom.o: $(srcdir)/generic/tcldom.c $(top_builddir)/versionhash.h
   313    350   
   314    351   #========================================================================
   315    352   # Distribution creation
   316    353   # You may need to tweak this target to make it work correctly.
   317    354   #========================================================================
   318    355   
   319    356   #COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
   320         -COMPRESS	= gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
          357  +COMPRESS	= tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
   321    358   DIST_ROOT	= /tmp/dist
   322    359   DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)
   323    360   
   324    361   dist-clean:
   325    362   	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
   326    363   
   327    364   dist: dist-clean
................................................................................
   359    396   #========================================================================
   360    397   
   361    398   #========================================================================
   362    399   # Don't modify the file to clean here.  Instead, set the "CLEANFILES"
   363    400   # variable in configure.in
   364    401   #========================================================================
   365    402   
   366         -clean:  
          403  +clean:
   367    404   	-test -z "$(BINARIES)" || rm -f $(BINARIES)
   368    405   	-rm -f *.$(OBJEXT) core *.core
   369    406   	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
   370    407   
   371    408   distclean: clean
   372    409   	-rm -f *.tab.c
   373    410   	-rm -f $(CONFIG_CLEAN_FILES)
................................................................................
   381    418   # In addition, this will generate the pkgIndex.tcl
   382    419   # file in the install location (assuming it can find a usable tclsh shell)
   383    420   #
   384    421   # You should not have to modify this target.
   385    422   #========================================================================
   386    423   
   387    424   install-lib-binaries: binaries
   388         -	@mkdir -p $(DESTDIR)$(pkglibdir)
          425  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)
   389    426   	@list='$(lib_BINARIES)'; for p in $$list; do \
   390    427   	  if test -f $$p; then \
   391         -	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
   392         -	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
   393         -	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
   394    428   	    if test "x$$stub" = "xstub"; then \
   395         -		echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
   396         -		$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
          429  +		echo " $(RANLIB_STUB) $$p"; \
          430  +		$(RANLIB_STUB) $$p; \
   397    431   	    else \
   398         -		echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
   399         -		$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
          432  +		echo " $(RANLIB) $$p"; \
          433  +		$(RANLIB) $$p; \
   400    434   	    fi; \
          435  +	    echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
          436  +	    $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
          437  +	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
   401    438   	    ext=`echo $$p|sed -e "s/.*\.//"`; \
   402    439   	    if test "x$$ext" = "xdll"; then \
   403    440   		lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
   404    441   		if test -f $$lib; then \
   405    442   		    echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
   406    443   	            $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
   407    444   		fi; \
   408    445   	    fi; \
   409    446   	  fi; \
   410    447   	done
          448  +	@echo "Installing tdomConfig.sh to $(DESTDIR)$(libdir)/"
          449  +	@$(INSTALL_DATA) tdomConfig.sh "$(DESTDIR)$(libdir)/tdomConfig.sh"
   411    450   	@list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
   412    451   	  if test -f $(srcdir)/$$p; then \
   413    452   	    destp=`basename $$p`; \
   414    453   	    echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
   415    454   	    $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
   416    455   	  fi; \
   417    456   	done
   418    457   	@if test "x$(SHARED_BUILD)" = "x1"; then \
   419    458   	    echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
   420    459   	    $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
   421    460   	fi
   422         -	$(INSTALL_DATA) tdomConfig.sh $(DESTDIR)$(libdir)
   423    461   
   424    462   #========================================================================
   425    463   # Install binary executables (e.g. .exe files and dependent .dll files)
   426    464   # This is for files that must go in the bin directory (located next to
   427    465   # wish and tclsh), like dependent .dll files on Windows.
   428    466   #
   429    467   # You should not have to modify this target, except to define bin_BINARIES
   430    468   # above if necessary.
   431    469   #========================================================================
   432    470   
   433    471   install-bin-binaries: binaries
   434         -	@mkdir -p $(DESTDIR)$(bindir)
          472  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir)
   435    473   	@list='$(bin_BINARIES)'; for p in $$list; do \
   436    474   	  if test -f $$p; then \
   437    475   	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
   438    476   	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
   439    477   	  fi; \
   440    478   	done
   441    479   
   442         -.SUFFIXES: .c .$(OBJEXT)
   443         -
   444    480   Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
   445    481   	cd $(top_builddir) \
   446    482   	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
   447    483   
   448    484   uninstall-binaries:
   449    485   	list='$(lib_BINARIES)'; for p in $$list; do \
   450    486   	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \

Changes to README.

     1      1   
     2      2   
     3         -              tDOM - a XML/DOM/XPath/XSLT implementation for Tcl
     4         -                          (Version 0.8.3)
            3  +    tDOM - a XML/DOM/XPath/XSLT/HTML/JSON implementation for Tcl
            4  +                          (Version 0.9.1)
     5      5   
     6         -		    Jochen Loewer (loewerj@hotmail.com)
     7         -                       Rolf Ade (rolf@pointsman.de)
     8      6   
     9         -                       with some contributions by:
    10         -
    11         -                 Zoran Vasiljevic (zv@archiware.com)
    12         -                
    13         -
    14         -This directory contains a freely distributable (under the Mozilla Public 
    15         -License) thread-safe extension to Tcl/Tk called tDOM.
    16         -
            7  +This directory contains a freely distributable thread-safe extension
            8  +to Tcl/Tk called tDOM.
    17      9   
    18     10   tDOM contains:
    19     11   
    20         -    *  the newest version of Expat, the XML parser from James Clark,
    21         -       including namespace and DTD support.
           12  +    *  for convenience expat 2.2.5, the XML parser originated from
           13  +       James Clark, although you're able to link tDOM with other
           14  +       expat versions or the library provided by the system.
    22     15   
    23         -    *  a modified version of Steve Ball's Tclexpat, the Tcl interface to 
    24         -       expat, for event-like (SAX-like) XML parsing. The modifications
    25         -       are for performance improvements, to make the newest Expat
    26         -       features (XML namespace) available and for some additional features.
           16  +    *  building a DOM tree from XML in one go implemented in C for
           17  +       maximum performance and minimum memory usage, and DOM I and II
           18  +       methods to work on such a tree using either a OO-like or a
           19  +       handle syntax.
    27     20   
    28         -    *  a (partial) DOM I and II implementation in C for maximum
    29         -       performance and minimum memory need following the W3C DOM Core
    30         -       Level 1 recommendation using a OO-like syntax.
           21  +    *  a Tcl interface to expat for event-like (SAX-like) XML parsing.
    31     22   
    32         -    *  a very complete, compliant and fast XPath implementation in C
    33         -       following the November 99 W3C recommendation.
           23  +    *  a complete, compliant and fast XPath implementation in C
           24  +       following the November 99 W3C recommendation for navigating and
           25  +       data extraction.
    34     26   
    35     27       *  a fast XSLT implementation in C following the W3C Recommendation
    36     28          16 November 1999.
    37     29       
    38         -    *  a (partial) implementation in C of the XPointer (97) navigational 
    39         -       functions.
           30  +    *  optional DTD validation.
    40     31   
    41         -    *  UTF-8 to 8 bit encoding back conversion functionality to support
    42         -       Tcl version < 8.1x
           32  +    *  a JSON parser which parses any possible JSON input into a DOM
           33  +       tree without losing information.
    43     34   
    44         -    *  optional DTD validation   
           35  +    *  an efficient and Tcl'ish way to create XML and HTML documents
           36  +       and JSON string.
    45     37   
    46         -    *  additional convenience methods
           38  +    *  as build option an interface to the gumbo HTML5 parser, which
           39  +       also digests almost any other HTML.
           40  +
           41  +    *  an even faster simple XML parser for trusted XML input.
           42  +
           43  +    *  A slim Tcl interface to use expat as pull-parser.
           44  +
           45  +    *  additional convenience methods.
    47     46    
    48         -    *  documentation in TMML, HTML and nroff format
           47  +    *  and more.
           48  +
           49  +
           50  +DOCUMENTATION
           51  +
           52  +    The documentation is included into the source distribution in HTML
           53  +    and man format. Alternatively, read it online starting at
           54  +    http://tdom.org/index.html/doc/trunk/doc/index.html
           55  +
           56  +
           57  +GETTING THE CODE
           58  +
           59  +    The development repository is hosted at http://tdom.org and is
           60  +    mirrored at http://core.tcl.tk/tdom. You are encouraged to use
           61  +    trunk.
           62  +
           63  +    If you insist on using an older tDOM with lesser features and
           64  +    probably more bugs, you should use the latest release 0.9.1. Get
           65  +    the source code release from
           66  +    http://tdom.org/downloads/tdom-0.9.1-src.tgz or
           67  +    http://tdom.org/downloads/tdom-0.9.1-src.zip
           68  +
           69  +    Windows binaries (32 bit as well as 64 bit) of the 0.9.1 release
           70  +    are also available. Get it from
           71  +    http://tdom.org/downloads/tdom-0.9.1-windows-x64.zip and 
           72  +    http://tdom.org/downloads/tdom-0.9.1-windows-x86.zip
           73  +    
           74  +    The provided windows binaries include (statically linked) the
           75  +    HTML5 parser.
    49     76   
    50     77   
    51         -COMPILING/USING tDOM
           78  +COMPILING tDOM
    52     79   
    53         -    Depending on your platform, (unix or win) go to the corresponding
    54         -    directory and invoke the configure script:
           80  +    Depending on your platform (unix/mac or win), go to the
           81  +    corresponding directory and invoke the configure script:
    55     82   
    56     83           ../configure
    57     84           make 
    58     85           make test
    59     86           make install
    60     87   
    61     88       Alternatively, you can build the tDOM package in just about any
    62     89       directory elsewhere on the fileystem (since TEA-compatible).
    63     90       
    64         -    NOTE: Be sure to have the CC=gcc defined if you're using GCC.
    65         -
    66         -    You might also want to do "../configure --help" to get list of all
    67         -    supported options of the configure script. In the "unix" directory
    68         -    there is a "CONFIG" file containing some examples on how to invoke
    69         -    the "configure" script for some common cases. You can peek
    70         -    there. This file also includes a short description of the tDOM
    71         -    specific configure options.
           91  +    You might also want to do "../configure --help" to get a list of
           92  +    all supported options of the configure script. In the "unix"
           93  +    directory there is a "CONFIG" file containing some examples on how
           94  +    to invoke the "configure" script for some common cases. You can
           95  +    peek there. This file also includes a short description of the
           96  +    tDOM specific configure options.
    72     97   
    73     98       Since tDOM is TEA-compatible you should be able to build it using
    74     99       the MinGW build environment for Windows. There is also the MSVC
    75    100       nmake file so you can compile the package with Microsoft tools.
          101  +    Refer to the README in the win directory for more details about
          102  +    building on Windows.
    76    103   
    77    104       The compile process will build the tDOM shared library suitable for
    78    105       loading into the Tcl shell using standard "package require" mechanism.
    79         -    Optionally the make process can also generate the "tcldomsh" 
    80         -    executable shell with tDOM functionality built-in. You can use this
    81         -    shell as any other Tcl shell. To do this, you have to:
          106  +
          107  +
          108  +REPORTING BUGS
    82    109   
    83         -        make tcldomsh
    84         -
    85         -    Note, however, that this step is optional.
          110  +    Please head to http://tdom.org/index.html/ticket and click on "New
          111  +    Ticket". Log in as anonymous and report your findings. If you
          112  +    prefer to have an individual login write Rolf a mail.
    86    113   
    87    114   
    88         -    Note for Tcl 8.0.5 users:
    89         -    -------------------------
          115  +HISTORY
    90    116   
    91         -    Per default, this release of tDOM links against Tcl stubs
    92         -    library. To build it against Tcl8.0.5, use the configure-tcl8.0.5
    93         -    script to generate the Makefile.
    94         -
    95         -    If you want to recreate the configure script for building against
    96         -    Tcl8.0.5 please edit the "configure.in" file in this directory,
    97         -    comment-out the AC_DEFINE(USE_TCL_STUBS) directive and run
    98         -    autoconf. Please be sure to use autoconf with version 2.59.
    99         -
   100         -
   101         -PLATFORMS
   102         -    HP-UX-10.20                  (both ansi cc and gcc)
   103         -    HP-UX-9.x
   104         -    Linux 2.2.5                  (egcs 2.91.66, SuSE 6.1)
   105         -    Solaris 2.5.1+               (both gcc and SunWorks compilers)
   106         -    W2K                          (VC++ 6.0)
   107         -    Mac OS X 10.2.6              (Apple's gcc)
   108         -
   109         -    Other machines and OS's are not tested but should work too. 
   110         -
   111         -Have fun! 
   112         -
   113         -- EOF -
          117  +    tDOM was started by Jochen Loewer (loewerj@hotmail.com) and
          118  +    developed by Jochen and Rolf Ade (rolf@pointsman.de) with
          119  +    contributions by Zoran Vasiljevic (zv@archiware.com). Since more
          120  +    than a dozen years it is maintained and developed by Rolf Ade.

Changes to README.AOL.

     1      1   
     2      2   
     3      3                 tDOM - a XML/DOM/XPath/XSLT implementation for Tcl
     4         -                          (Version 0.8.3)
            4  +                          (Version 0.9.1)
     5      5   
     6      6   		    Jochen Loewer (loewerj@hotmail.com)
     7      7                          Rolf Ade (rolf@pointsman.de)
     8      8   
     9      9                          with some contributions by:
    10     10   
    11     11                    Zoran Vasiljevic (zv@archiware.com)

Changes to apps/xslt.tcl.

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

Changes to configure.

more than 10,000 changes

Deleted configure-tcl8.0.5.

     1         -#! /bin/sh
     2         -
     3         -# Guess values for system-dependent variables and create Makefiles.
     4         -# Generated automatically using autoconf version 2.13 
     5         -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
     6         -#
     7         -# This configure script is free software; the Free Software Foundation
     8         -# gives unlimited permission to copy, distribute and modify it.
     9         -
    10         -# Defaults:
    11         -ac_help=
    12         -ac_default_prefix=/usr/local
    13         -# Any additions from configure.in:
    14         -ac_help="$ac_help
    15         -  --with-tcl              directory containing tcl configuration (tclConfig.sh)"
    16         -ac_help="$ac_help
    17         -  --with-tclinclude      directory containing the public Tcl header files"
    18         -ac_help="$ac_help
    19         -  --enable-threads        build with threads"
    20         -ac_help="$ac_help
    21         -  --enable-shared         build and link with shared libraries [--enable-shared]"
    22         -ac_help="$ac_help
    23         -  --enable-64bit          enable 64bit support (where applicable)"
    24         -ac_help="$ac_help
    25         -  --enable-64bit-vis      enable 64bit Sparc VIS support"
    26         -ac_help="$ac_help
    27         -  --disable-load          disallow dynamic loading and "load" command"
    28         -ac_help="$ac_help
    29         -  --enable-symbols        build with debugging symbols [--disable-symbols]"
    30         -ac_help="$ac_help
    31         -  --with-aolserver        directory with AOLserver distribution"
    32         -ac_help="$ac_help
    33         -  --enable-dtd            build with the dtd support [--enable-dtd]"
    34         -ac_help="$ac_help
    35         -  --enable-ns             build with the namespace support [--enable-ns]"
    36         -ac_help="$ac_help
    37         -  --enable-unknown        enable built-in unknown command [--disable-unknown]"
    38         -ac_help="$ac_help
    39         -  --enable-tdomalloc      build with the tDOM allocator [--enable-tdomalloc]"
    40         -
    41         -# Initialize some variables set by options.
    42         -# The variables have the same names as the options, with
    43         -# dashes changed to underlines.
    44         -build=NONE
    45         -cache_file=./config.cache
    46         -exec_prefix=NONE
    47         -host=NONE
    48         -no_create=
    49         -nonopt=NONE
    50         -no_recursion=
    51         -prefix=NONE
    52         -program_prefix=NONE
    53         -program_suffix=NONE
    54         -program_transform_name=s,x,x,
    55         -silent=
    56         -site=
    57         -srcdir=
    58         -target=NONE
    59         -verbose=
    60         -x_includes=NONE
    61         -x_libraries=NONE
    62         -bindir='${exec_prefix}/bin'
    63         -sbindir='${exec_prefix}/sbin'
    64         -libexecdir='${exec_prefix}/libexec'
    65         -datadir='${prefix}/share'
    66         -sysconfdir='${prefix}/etc'
    67         -sharedstatedir='${prefix}/com'
    68         -localstatedir='${prefix}/var'
    69         -libdir='${exec_prefix}/lib'
    70         -includedir='${prefix}/include'
    71         -oldincludedir='/usr/include'
    72         -infodir='${prefix}/info'
    73         -mandir='${prefix}/man'
    74         -
    75         -# Initialize some other variables.
    76         -subdirs=
    77         -MFLAGS= MAKEFLAGS=
    78         -SHELL=${CONFIG_SHELL-/bin/sh}
    79         -# Maximum number of lines to put in a shell here document.
    80         -ac_max_here_lines=12
    81         -
    82         -ac_prev=
    83         -for ac_option
    84         -do
    85         -
    86         -  # If the previous option needs an argument, assign it.
    87         -  if test -n "$ac_prev"; then
    88         -    eval "$ac_prev=\$ac_option"
    89         -    ac_prev=
    90         -    continue
    91         -  fi
    92         -
    93         -  case "$ac_option" in
    94         -  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
    95         -  *) ac_optarg= ;;
    96         -  esac
    97         -
    98         -  # Accept the important Cygnus configure options, so we can diagnose typos.
    99         -
   100         -  case "$ac_option" in
   101         -
   102         -  -bindir | --bindir | --bindi | --bind | --bin | --bi)
   103         -    ac_prev=bindir ;;
   104         -  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
   105         -    bindir="$ac_optarg" ;;
   106         -
   107         -  -build | --build | --buil | --bui | --bu)
   108         -    ac_prev=build ;;
   109         -  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
   110         -    build="$ac_optarg" ;;
   111         -
   112         -  -cache-file | --cache-file | --cache-fil | --cache-fi \
   113         -  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
   114         -    ac_prev=cache_file ;;
   115         -  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
   116         -  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
   117         -    cache_file="$ac_optarg" ;;
   118         -
   119         -  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
   120         -    ac_prev=datadir ;;
   121         -  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
   122         -  | --da=*)
   123         -    datadir="$ac_optarg" ;;
   124         -
   125         -  -disable-* | --disable-*)
   126         -    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
   127         -    # Reject names that are not valid shell variable names.
   128         -    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
   129         -      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
   130         -    fi
   131         -    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
   132         -    eval "enable_${ac_feature}=no" ;;
   133         -
   134         -  -enable-* | --enable-*)
   135         -    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
   136         -    # Reject names that are not valid shell variable names.
   137         -    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
   138         -      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
   139         -    fi
   140         -    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
   141         -    case "$ac_option" in
   142         -      *=*) ;;
   143         -      *) ac_optarg=yes ;;
   144         -    esac
   145         -    eval "enable_${ac_feature}='$ac_optarg'" ;;
   146         -
   147         -  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
   148         -  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
   149         -  | --exec | --exe | --ex)
   150         -    ac_prev=exec_prefix ;;
   151         -  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
   152         -  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
   153         -  | --exec=* | --exe=* | --ex=*)
   154         -    exec_prefix="$ac_optarg" ;;
   155         -
   156         -  -gas | --gas | --ga | --g)
   157         -    # Obsolete; use --with-gas.
   158         -    with_gas=yes ;;
   159         -
   160         -  -help | --help | --hel | --he)
   161         -    # Omit some internal or obsolete options to make the list less imposing.
   162         -    # This message is too long to be a string in the A/UX 3.1 sh.
   163         -    cat << EOF
   164         -Usage: configure [options] [host]
   165         -Options: [defaults in brackets after descriptions]
   166         -Configuration:
   167         -  --cache-file=FILE       cache test results in FILE
   168         -  --help                  print this message
   169         -  --no-create             do not create output files
   170         -  --quiet, --silent       do not print \`checking...' messages
   171         -  --version               print the version of autoconf that created configure
   172         -Directory and file names:
   173         -  --prefix=PREFIX         install architecture-independent files in PREFIX
   174         -                          [$ac_default_prefix]
   175         -  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
   176         -                          [same as prefix]
   177         -  --bindir=DIR            user executables in DIR [EPREFIX/bin]
   178         -  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
   179         -  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
   180         -  --datadir=DIR           read-only architecture-independent data in DIR
   181         -                          [PREFIX/share]
   182         -  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
   183         -  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
   184         -                          [PREFIX/com]
   185         -  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
   186         -  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
   187         -  --includedir=DIR        C header files in DIR [PREFIX/include]
   188         -  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
   189         -  --infodir=DIR           info documentation in DIR [PREFIX/info]
   190         -  --mandir=DIR            man documentation in DIR [PREFIX/man]
   191         -  --srcdir=DIR            find the sources in DIR [configure dir or ..]
   192         -  --program-prefix=PREFIX prepend PREFIX to installed program names
   193         -  --program-suffix=SUFFIX append SUFFIX to installed program names
   194         -  --program-transform-name=PROGRAM
   195         -                          run sed PROGRAM on installed program names
   196         -EOF
   197         -    cat << EOF
   198         -Host type:
   199         -  --build=BUILD           configure for building on BUILD [BUILD=HOST]
   200         -  --host=HOST             configure for HOST [guessed]
   201         -  --target=TARGET         configure for TARGET [TARGET=HOST]
   202         -Features and packages:
   203         -  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   204         -  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   205         -  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   206         -  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   207         -  --x-includes=DIR        X include files are in DIR
   208         -  --x-libraries=DIR       X library files are in DIR
   209         -EOF
   210         -    if test -n "$ac_help"; then
   211         -      echo "--enable and --with options recognized:$ac_help"
   212         -    fi
   213         -    exit 0 ;;
   214         -
   215         -  -host | --host | --hos | --ho)
   216         -    ac_prev=host ;;
   217         -  -host=* | --host=* | --hos=* | --ho=*)
   218         -    host="$ac_optarg" ;;
   219         -
   220         -  -includedir | --includedir | --includedi | --included | --include \
   221         -  | --includ | --inclu | --incl | --inc)
   222         -    ac_prev=includedir ;;
   223         -  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
   224         -  | --includ=* | --inclu=* | --incl=* | --inc=*)
   225         -    includedir="$ac_optarg" ;;
   226         -
   227         -  -infodir | --infodir | --infodi | --infod | --info | --inf)
   228         -    ac_prev=infodir ;;
   229         -  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
   230         -    infodir="$ac_optarg" ;;
   231         -
   232         -  -libdir | --libdir | --libdi | --libd)
   233         -    ac_prev=libdir ;;
   234         -  -libdir=* | --libdir=* | --libdi=* | --libd=*)
   235         -    libdir="$ac_optarg" ;;
   236         -
   237         -  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
   238         -  | --libexe | --libex | --libe)
   239         -    ac_prev=libexecdir ;;
   240         -  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
   241         -  | --libexe=* | --libex=* | --libe=*)
   242         -    libexecdir="$ac_optarg" ;;
   243         -
   244         -  -localstatedir | --localstatedir | --localstatedi | --localstated \
   245         -  | --localstate | --localstat | --localsta | --localst \
   246         -  | --locals | --local | --loca | --loc | --lo)
   247         -    ac_prev=localstatedir ;;
   248         -  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
   249         -  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
   250         -  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
   251         -    localstatedir="$ac_optarg" ;;
   252         -
   253         -  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
   254         -    ac_prev=mandir ;;
   255         -  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
   256         -    mandir="$ac_optarg" ;;
   257         -
   258         -  -nfp | --nfp | --nf)
   259         -    # Obsolete; use --without-fp.
   260         -    with_fp=no ;;
   261         -
   262         -  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
   263         -  | --no-cr | --no-c)
   264         -    no_create=yes ;;
   265         -
   266         -  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
   267         -  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
   268         -    no_recursion=yes ;;
   269         -
   270         -  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
   271         -  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
   272         -  | --oldin | --oldi | --old | --ol | --o)
   273         -    ac_prev=oldincludedir ;;
   274         -  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
   275         -  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
   276         -  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
   277         -    oldincludedir="$ac_optarg" ;;
   278         -
   279         -  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
   280         -    ac_prev=prefix ;;
   281         -  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
   282         -    prefix="$ac_optarg" ;;
   283         -
   284         -  -program-prefix | --program-prefix | --program-prefi | --program-pref \
   285         -  | --program-pre | --program-pr | --program-p)
   286         -    ac_prev=program_prefix ;;
   287         -  -program-prefix=* | --program-prefix=* | --program-prefi=* \
   288         -  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
   289         -    program_prefix="$ac_optarg" ;;
   290         -
   291         -  -program-suffix | --program-suffix | --program-suffi | --program-suff \
   292         -  | --program-suf | --program-su | --program-s)
   293         -    ac_prev=program_suffix ;;
   294         -  -program-suffix=* | --program-suffix=* | --program-suffi=* \
   295         -  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
   296         -    program_suffix="$ac_optarg" ;;
   297         -
   298         -  -program-transform-name | --program-transform-name \
   299         -  | --program-transform-nam | --program-transform-na \
   300         -  | --program-transform-n | --program-transform- \
   301         -  | --program-transform | --program-transfor \
   302         -  | --program-transfo | --program-transf \
   303         -  | --program-trans | --program-tran \
   304         -  | --progr-tra | --program-tr | --program-t)
   305         -    ac_prev=program_transform_name ;;
   306         -  -program-transform-name=* | --program-transform-name=* \
   307         -  | --program-transform-nam=* | --program-transform-na=* \
   308         -  | --program-transform-n=* | --program-transform-=* \
   309         -  | --program-transform=* | --program-transfor=* \
   310         -  | --program-transfo=* | --program-transf=* \
   311         -  | --program-trans=* | --program-tran=* \
   312         -  | --progr-tra=* | --program-tr=* | --program-t=*)
   313         -    program_transform_name="$ac_optarg" ;;
   314         -
   315         -  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   316         -  | -silent | --silent | --silen | --sile | --sil)
   317         -    silent=yes ;;
   318         -
   319         -  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
   320         -    ac_prev=sbindir ;;
   321         -  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
   322         -  | --sbi=* | --sb=*)
   323         -    sbindir="$ac_optarg" ;;
   324         -
   325         -  -sharedstatedir | --sharedstatedir | --sharedstatedi \
   326         -  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
   327         -  | --sharedst | --shareds | --shared | --share | --shar \
   328         -  | --sha | --sh)
   329         -    ac_prev=sharedstatedir ;;
   330         -  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
   331         -  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
   332         -  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
   333         -  | --sha=* | --sh=*)
   334         -    sharedstatedir="$ac_optarg" ;;
   335         -
   336         -  -site | --site | --sit)
   337         -    ac_prev=site ;;
   338         -  -site=* | --site=* | --sit=*)
   339         -    site="$ac_optarg" ;;
   340         -
   341         -  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
   342         -    ac_prev=srcdir ;;
   343         -  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
   344         -    srcdir="$ac_optarg" ;;
   345         -
   346         -  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
   347         -  | --syscon | --sysco | --sysc | --sys | --sy)
   348         -    ac_prev=sysconfdir ;;
   349         -  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
   350         -  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
   351         -    sysconfdir="$ac_optarg" ;;
   352         -
   353         -  -target | --target | --targe | --targ | --tar | --ta | --t)
   354         -    ac_prev=target ;;
   355         -  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
   356         -    target="$ac_optarg" ;;
   357         -
   358         -  -v | -verbose | --verbose | --verbos | --verbo | --verb)
   359         -    verbose=yes ;;
   360         -
   361         -  -version | --version | --versio | --versi | --vers)
   362         -    echo "configure generated by autoconf version 2.13"
   363         -    exit 0 ;;
   364         -
   365         -  -with-* | --with-*)
   366         -    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
   367         -    # Reject names that are not valid shell variable names.
   368         -    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
   369         -      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
   370         -    fi
   371         -    ac_package=`echo $ac_package| sed 's/-/_/g'`
   372         -    case "$ac_option" in
   373         -      *=*) ;;
   374         -      *) ac_optarg=yes ;;
   375         -    esac
   376         -    eval "with_${ac_package}='$ac_optarg'" ;;
   377         -
   378         -  -without-* | --without-*)
   379         -    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
   380         -    # Reject names that are not valid shell variable names.
   381         -    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
   382         -      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
   383         -    fi
   384         -    ac_package=`echo $ac_package| sed 's/-/_/g'`
   385         -    eval "with_${ac_package}=no" ;;
   386         -
   387         -  --x)
   388         -    # Obsolete; use --with-x.
   389         -    with_x=yes ;;
   390         -
   391         -  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
   392         -  | --x-incl | --x-inc | --x-in | --x-i)
   393         -    ac_prev=x_includes ;;
   394         -  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
   395         -  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
   396         -    x_includes="$ac_optarg" ;;
   397         -
   398         -  -x-libraries | --x-libraries | --x-librarie | --x-librari \
   399         -  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
   400         -    ac_prev=x_libraries ;;
   401         -  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
   402         -  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
   403         -    x_libraries="$ac_optarg" ;;
   404         -
   405         -  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
   406         -    ;;
   407         -
   408         -  *)
   409         -    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
   410         -      echo "configure: warning: $ac_option: invalid host type" 1>&2
   411         -    fi
   412         -    if test "x$nonopt" != xNONE; then
   413         -      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
   414         -    fi
   415         -    nonopt="$ac_option"
   416         -    ;;
   417         -
   418         -  esac
   419         -done
   420         -
   421         -if test -n "$ac_prev"; then
   422         -  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
   423         -fi
   424         -
   425         -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
   426         -
   427         -# File descriptor usage:
   428         -# 0 standard input
   429         -# 1 file creation
   430         -# 2 errors and warnings
   431         -# 3 some systems may open it to /dev/tty
   432         -# 4 used on the Kubota Titan
   433         -# 6 checking for... messages and results
   434         -# 5 compiler messages saved in config.log
   435         -if test "$silent" = yes; then
   436         -  exec 6>/dev/null
   437         -else
   438         -  exec 6>&1
   439         -fi
   440         -exec 5>./config.log
   441         -
   442         -echo "\
   443         -This file contains any messages produced by compilers while
   444         -running configure, to aid debugging if configure makes a mistake.
   445         -" 1>&5
   446         -
   447         -# Strip out --no-create and --no-recursion so they do not pile up.
   448         -# Also quote any args containing shell metacharacters.
   449         -ac_configure_args=
   450         -for ac_arg
   451         -do
   452         -  case "$ac_arg" in
   453         -  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
   454         -  | --no-cr | --no-c) ;;
   455         -  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
   456         -  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
   457         -  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
   458         -  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
   459         -  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
   460         -  esac
   461         -done
   462         -
   463         -# NLS nuisances.
   464         -# Only set these to C if already set.  These must not be set unconditionally
   465         -# because not all systems understand e.g. LANG=C (notably SCO).
   466         -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
   467         -# Non-C LC_CTYPE values break the ctype check.
   468         -if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
   469         -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
   470         -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
   471         -if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
   472         -
   473         -# confdefs.h avoids OS command line length limits that DEFS can exceed.
   474         -rm -rf conftest* confdefs.h
   475         -# AIX cpp loses on an empty file, so make sure it contains at least a newline.
   476         -echo > confdefs.h
   477         -
   478         -# A filename unique to this package, relative to the directory that
   479         -# configure is in, which we can look for to find out if srcdir is correct.
   480         -ac_unique_file=generic/tcldom.c
   481         -
   482         -# Find the source files, if location was not specified.
   483         -if test -z "$srcdir"; then
   484         -  ac_srcdir_defaulted=yes
   485         -  # Try the directory containing this script, then its parent.
   486         -  ac_prog=$0
   487         -  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
   488         -  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
   489         -  srcdir=$ac_confdir
   490         -  if test ! -r $srcdir/$ac_unique_file; then
   491         -    srcdir=..
   492         -  fi
   493         -else
   494         -  ac_srcdir_defaulted=no
   495         -fi
   496         -if test ! -r $srcdir/$ac_unique_file; then
   497         -  if test "$ac_srcdir_defaulted" = yes; then
   498         -    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
   499         -  else
   500         -    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
   501         -  fi
   502         -fi
   503         -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
   504         -
   505         -# Prefer explicitly selected file to automatically selected ones.
   506         -if test -z "$CONFIG_SITE"; then
   507         -  if test "x$prefix" != xNONE; then
   508         -    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
   509         -  else
   510         -    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
   511         -  fi
   512         -fi
   513         -for ac_site_file in $CONFIG_SITE; do
   514         -  if test -r "$ac_site_file"; then
   515         -    echo "loading site script $ac_site_file"
   516         -    . "$ac_site_file"
   517         -  fi
   518         -done
   519         -
   520         -if test -r "$cache_file"; then
   521         -  echo "loading cache $cache_file"
   522         -  . $cache_file
   523         -else
   524         -  echo "creating cache $cache_file"
   525         -  > $cache_file
   526         -fi
   527         -
   528         -ac_ext=c
   529         -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
   530         -ac_cpp='$CPP $CPPFLAGS'
   531         -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
   532         -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
   533         -cross_compiling=$ac_cv_prog_cc_cross
   534         -
   535         -ac_exeext=
   536         -ac_objext=o
   537         -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
   538         -  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
   539         -  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
   540         -    ac_n= ac_c='
   541         -' ac_t='	'
   542         -  else
   543         -    ac_n=-n ac_c= ac_t=
   544         -  fi
   545         -else
   546         -  ac_n= ac_c='\c' ac_t=
   547         -fi
   548         -
   549         -
   550         -
   551         -#-----------------------------------------------------------------------
   552         -# Be sure we're invoked from the platform directory.
   553         -#-----------------------------------------------------------------------
   554         -
   555         -if test ${srcdir} = "." ; then
   556         -    echo ""
   557         -    echo "Please cd to the platform-specific dir (unix or win) and invoke:"
   558         -    echo "  ../configure"
   559         -    echo ""
   560         -    exit 1
   561         -fi
   562         -
   563         -#-----------------------------------------------------------------------
   564         -# These are needed for the expat compilation. Do this early so we
   565         -# do not step over some CFLAGS which will confuse the compiler.
   566         -#-----------------------------------------------------------------------
   567         -
   568         -for ac_func in memmove bcopy
   569         -do
   570         -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
   571         -echo "configure:572: checking for $ac_func" >&5
   572         -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   573         -  echo $ac_n "(cached) $ac_c" 1>&6
   574         -else
   575         -  cat > conftest.$ac_ext <<EOF
   576         -#line 577 "configure"
   577         -#include "confdefs.h"
   578         -/* System header to define __stub macros and hopefully few prototypes,
   579         -    which can conflict with char $ac_func(); below.  */
   580         -#include <assert.h>
   581         -/* Override any gcc2 internal prototype to avoid an error.  */
   582         -/* We use char because int might match the return type of a gcc2
   583         -    builtin and then its argument prototype would still apply.  */
   584         -char $ac_func();
   585         -
   586         -int main() {
   587         -
   588         -/* The GNU C library defines this for functions which it implements
   589         -    to always fail with ENOSYS.  Some functions are actually named
   590         -    something starting with __ and the normal name is an alias.  */
   591         -#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
   592         -choke me
   593         -#else
   594         -$ac_func();
   595         -#endif
   596         -
   597         -; return 0; }
   598         -EOF
   599         -if { (eval echo configure:600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   600         -  rm -rf conftest*
   601         -  eval "ac_cv_func_$ac_func=yes"
   602         -else
   603         -  echo "configure: failed program was:" >&5
   604         -  cat conftest.$ac_ext >&5
   605         -  rm -rf conftest*
   606         -  eval "ac_cv_func_$ac_func=no"
   607         -fi
   608         -rm -f conftest*
   609         -fi
   610         -
   611         -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
   612         -  echo "$ac_t""yes" 1>&6
   613         -    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
   614         -  cat >> confdefs.h <<EOF
   615         -#define $ac_tr_func 1
   616         -EOF
   617         - 
   618         -else
   619         -  echo "$ac_t""no" 1>&6
   620         -fi
   621         -done
   622         -
   623         -
   624         -#-----------------------------------------------------------------------
   625         -# Where is the tcl.m4 and brothers?
   626         -#-----------------------------------------------------------------------
   627         -
   628         -ac_aux_dir=
   629         -for ac_dir in tclconfig $srcdir/tclconfig; do
   630         -  if test -f $ac_dir/install-sh; then
   631         -    ac_aux_dir=$ac_dir
   632         -    ac_install_sh="$ac_aux_dir/install-sh -c"
   633         -    break
   634         -  elif test -f $ac_dir/install.sh; then
   635         -    ac_aux_dir=$ac_dir
   636         -    ac_install_sh="$ac_aux_dir/install.sh -c"
   637         -    break
   638         -  fi
   639         -done
   640         -if test -z "$ac_aux_dir"; then
   641         -  { echo "configure: error: can not find install-sh or install.sh in tclconfig $srcdir/tclconfig" 1>&2; exit 1; }
   642         -fi
   643         -ac_config_guess=$ac_aux_dir/config.guess
   644         -ac_config_sub=$ac_aux_dir/config.sub
   645         -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
   646         -
   647         -CONFIGDIR=${srcdir}/tclconfig
   648         -
   649         -
   650         -#----------------------------------------------------------------------
   651         -# __CHANGE__
   652         -# Set your package name and version numbers here. The NODOT_VERSION is
   653         -# required for constructing the library name on systems that don't like
   654         -# dots in library names (Windows). The VERSION variable is used on the
   655         -# other systems. Note that we substitute the VERSIN later down, after
   656         -# we have initialized TEA so we know which platform we're dealing with.
   657         -#----------------------------------------------------------------------
   658         -
   659         -PACKAGE=tdom
   660         -
   661         -
   662         -TDOMSHELL=tcldomsh
   663         -
   664         -
   665         -MAJOR_VERSION=0
   666         -
   667         -
   668         -MINOR_VERSION=8
   669         -
   670         -
   671         -PATCHLEVEL=3
   672         -
   673         -# This package name must be replaced statically for AC_SUBST to work
   674         -
   675         -
   676         -# Substitute stub_LIB_FILE if your package creates a stub library too.
   677         -
   678         -
   679         -#--------------------------------------------------------------------
   680         -# Call TEA_INIT as the first TEA_ macro to set up initial vars.
   681         -# This will define a ${TEA_PLATFORM} variable == "unix" or "windows".
   682         -#--------------------------------------------------------------------
   683         -
   684         -
   685         -    echo $ac_n "checking for correct TEA configuration""... $ac_c" 1>&6
   686         -echo "configure:688: checking for correct TEA configuration" >&5
   687         -    if test x"${PACKAGE}" = x ; then
   688         -	{ echo "configure: error: 
   689         -The PACKAGE variable must be defined by your TEA configure.in" 1>&2; exit 1; }
   690         -    fi
   691         -    echo "$ac_t""ok" 1>&6
   692         -    TEA_INITED=ok
   693         -    case "`uname -s`" in
   694         -	*win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_98*|*CYGWIN_95*|*CYGWIN_ME*|*MINGW32_*)
   695         -	    # Extract the first word of "cygpath", so it can be a program name with args.
   696         -set dummy cygpath; ac_word=$2
   697         -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
   698         -echo "configure:700: checking for $ac_word" >&5
   699         -if eval "test \"`echo '$''{'ac_cv_prog_CYGPATH'+set}'`\" = set"; then
   700         -  echo $ac_n "(cached) $ac_c" 1>&6
   701         -else
   702         -  if test -n "$CYGPATH"; then
   703         -  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
   704         -else
   705         -  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
   706         -  ac_dummy="$PATH"
   707         -  for ac_dir in $ac_dummy; do
   708         -    test -z "$ac_dir" && ac_dir=.
   709         -    if test -f $ac_dir/$ac_word; then
   710         -      ac_cv_prog_CYGPATH="cygpath -w"
   711         -      break
   712         -    fi
   713         -  done
   714         -  IFS="$ac_save_ifs"
   715         -  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
   716         -fi
   717         -fi
   718         -CYGPATH="$ac_cv_prog_CYGPATH"
   719         -if test -n "$CYGPATH"; then
   720         -  echo "$ac_t""$CYGPATH" 1>&6
   721         -else
   722         -  echo "$ac_t""no" 1>&6
   723         -fi
   724         -
   725         -	    EXEEXT=".exe"
   726         -	    TEA_PLATFORM="windows"
   727         -	    ;;
   728         -	*)
   729         -	    CYGPATH=echo
   730         -	    EXEEXT=""
   731         -	    TEA_PLATFORM="unix"
   732         -	    ;;
   733         -    esac
   734         -
   735         -    
   736         -    
   737         -
   738         -
   739         -#--------------------------------------------------------------------
   740         -# Load the tclConfig.sh file
   741         -#--------------------------------------------------------------------
   742         -
   743         -
   744         -    if test x"${TEA_INITED}" = x ; then
   745         -	# Can't refer to exact macro name or it will be substituted
   746         -	{ echo "configure: error: Must call TEA INIT before PATH_TCLCONFIG" 1>&2; exit 1; }
   747         -    fi
   748         -    #
   749         -    # Ok, lets find the tcl configuration
   750         -    # First, look for one uninstalled.
   751         -    # the alternative search directory is invoked by --with-tcl
   752         -    #
   753         -
   754         -    if test x"${no_tcl}" = x ; then
   755         -	# we reset no_tcl in case something fails here
   756         -	no_tcl=true
   757         -	# Check whether --with-tcl or --without-tcl was given.
   758         -if test "${with_tcl+set}" = set; then
   759         -  withval="$with_tcl"
   760         -  with_tclconfig=${withval}
   761         -fi
   762         -
   763         -	echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6
   764         -echo "configure:766: checking for Tcl configuration" >&5
   765         -	if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then
   766         -  echo $ac_n "(cached) $ac_c" 1>&6
   767         -else
   768         -  
   769         -
   770         -	    # First check to see if --with-tcl was specified.
   771         -	    if test x"${with_tclconfig}" != x ; then
   772         -		if test -f "${with_tclconfig}/tclConfig.sh" ; then
   773         -		    ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
   774         -		else
   775         -		    { echo "configure: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" 1>&2; exit 1; }
   776         -		fi
   777         -	    fi
   778         -
   779         -	    # then check for a private Tcl installation
   780         -	    if test x"${ac_cv_c_tclconfig}" = x ; then
   781         -		for i in \
   782         -			../tcl \
   783         -			`ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
   784         -			../../tcl \
   785         -			`ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
   786         -			../../../tcl \
   787         -			`ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
   788         -		    if test -f "$i/unix/tclConfig.sh" ; then
   789         -			ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
   790         -			break
   791         -		    fi
   792         -		done
   793         -	    fi
   794         -
   795         -	    # check in a few common install locations
   796         -	    if test x"${ac_cv_c_tclconfig}" = x ; then
   797         -		for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \
   798         -			`ls -d /usr/local/lib 2>/dev/null` \
   799         -			`ls -d /usr/contrib/lib 2>/dev/null` \
   800         -			`ls -d /usr/lib 2>/dev/null` \
   801         -			; do
   802         -		    if test -f "$i/tclConfig.sh" ; then
   803         -			ac_cv_c_tclconfig=`(cd $i; pwd)`
   804         -			break
   805         -		    fi
   806         -		done
   807         -	    fi
   808         -
   809         -	    # check in a few other private locations
   810         -	    if test x"${ac_cv_c_tclconfig}" = x ; then
   811         -		for i in \
   812         -			${srcdir}/../tcl \
   813         -			`ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
   814         -		    if test -f "$i/unix/tclConfig.sh" ; then
   815         -		    ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
   816         -		    break
   817         -		fi
   818         -		done
   819         -	    fi
   820         -	
   821         -fi
   822         -
   823         -
   824         -	if test x"${ac_cv_c_tclconfig}" = x ; then
   825         -	    TCL_BIN_DIR="# no Tcl configs found"
   826         -	    echo "configure: warning: "Cannot find Tcl configuration definitions"" 1>&2
   827         -	    exit 0
   828         -	else
   829         -	    no_tcl=
   830         -	    TCL_BIN_DIR=${ac_cv_c_tclconfig}
   831         -	    echo "$ac_t""found $TCL_BIN_DIR/tclConfig.sh" 1>&6
   832         -	fi
   833         -    fi
   834         -
   835         -
   836         -    echo $ac_n "checking for existence of $TCL_BIN_DIR/tclConfig.sh""... $ac_c" 1>&6
   837         -echo "configure:839: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5
   838         -
   839         -    if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then
   840         -        echo "$ac_t""loading" 1>&6
   841         -	. $TCL_BIN_DIR/tclConfig.sh
   842         -    else
   843         -        echo "$ac_t""file not found" 1>&6
   844         -    fi
   845         -
   846         -    #
   847         -    # If the TCL_BIN_DIR is the build directory (not the install directory),
   848         -    # then set the common variable name to the value of the build variables.
   849         -    # For example, the variable TCL_LIB_SPEC will be set to the value
   850         -    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
   851         -    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
   852         -    # installed and uninstalled version of Tcl.
   853         -    #
   854         -
   855         -    if test -f $TCL_BIN_DIR/Makefile ; then
   856         -        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
   857         -        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
   858         -        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
   859         -    fi
   860         -
   861         -    #
   862         -    # eval is required to do the TCL_DBGX substitution
   863         -    #
   864         -
   865         -    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
   866         -    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
   867         -    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
   868         -
   869         -    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
   870         -    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
   871         -    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
   872         -
   873         -    
   874         -    
   875         -    
   876         -
   877         -    
   878         -    
   879         -    
   880         -
   881         -    
   882         -    
   883         -    
   884         -
   885         -    #AC_SUBST(TCL_DBGX)
   886         -    
   887         -    
   888         -    
   889         -    
   890         -    
   891         -    #AC_SUBST(TCL_BUILD_LIB_SPEC)
   892         -    #AC_SUBST(TCL_BUILD_STUB_LIB_SPEC)
   893         -
   894         -
   895         -#--------------------------------------------------------------------
   896         -# Load the tkConfig.sh file if necessary (Tk extension)
   897         -#--------------------------------------------------------------------
   898         -
   899         -#TEA_PATH_TKCONFIG
   900         -#TEA_LOAD_TKCONFIG
   901         -
   902         -#-----------------------------------------------------------------------
   903         -# Handle the --prefix=... option by defaulting to what Tcl gave.
   904         -# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
   905         -#-----------------------------------------------------------------------
   906         -
   907         -
   908         -    # Should be AC_MSG_NOTICE, but that requires autoconf 2.50
   909         -    if test "${prefix}" = "NONE"; then
   910         -	prefix_default=yes
   911         -	if test x"${TCL_PREFIX}" != x; then
   912         -	    echo "configure: warning: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" 1>&2
   913         -	    prefix=${TCL_PREFIX}
   914         -	else
   915         -	    prefix=/usr/local
   916         -	fi
   917         -    fi
   918         -    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" ; then
   919         -	if test x"${TCL_EXEC_PREFIX}" != x; then
   920         -	    echo "configure: warning: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" 1>&2
   921         -	    exec_prefix=${TCL_EXEC_PREFIX}
   922         -	else
   923         -	    exec_prefix=$prefix
   924         -	fi
   925         -    fi
   926         -
   927         -
   928         -#-----------------------------------------------------------------------
   929         -# Standard compiler checks.
   930         -# This sets up CC by using the CC env var, or looks for gcc otherwise.
   931         -# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
   932         -# the basic setup necessary to compile executables.
   933         -#-----------------------------------------------------------------------
   934         -
   935         -echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
   936         -echo "configure:938: checking for Cygwin environment" >&5
   937         -if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
   938         -  echo $ac_n "(cached) $ac_c" 1>&6
   939         -else
   940         -  cat > conftest.$ac_ext <<EOF
   941         -#line 943 "configure"
   942         -#include "confdefs.h"
   943         -
   944         -int main() {
   945         -
   946         -#ifndef __CYGWIN__
   947         -#define __CYGWIN__ __CYGWIN32__
   948         -#endif
   949         -return __CYGWIN__;
   950         -; return 0; }
   951         -EOF
   952         -if { (eval echo configure:954: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   953         -  rm -rf conftest*
   954         -  ac_cv_cygwin=yes
   955         -else
   956         -  echo "configure: failed program was:" >&5
   957         -  cat conftest.$ac_ext >&5
   958         -  rm -rf conftest*
   959         -  ac_cv_cygwin=no
   960         -fi
   961         -rm -f conftest*
   962         -rm -f conftest*
   963         -fi
   964         -
   965         -echo "$ac_t""$ac_cv_cygwin" 1>&6
   966         -CYGWIN=
   967         -test "$ac_cv_cygwin" = yes && CYGWIN=yes
   968         -echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
   969         -echo "configure:971: checking for mingw32 environment" >&5
   970         -if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
   971         -  echo $ac_n "(cached) $ac_c" 1>&6
   972         -else
   973         -  cat > conftest.$ac_ext <<EOF
   974         -#line 976 "configure"
   975         -#include "confdefs.h"
   976         -
   977         -int main() {
   978         -return __MINGW32__;
   979         -; return 0; }
   980         -EOF
   981         -if { (eval echo configure:983: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   982         -  rm -rf conftest*
   983         -  ac_cv_mingw32=yes
   984         -else
   985         -  echo "configure: failed program was:" >&5
   986         -  cat conftest.$ac_ext >&5
   987         -  rm -rf conftest*
   988         -  ac_cv_mingw32=no
   989         -fi
   990         -rm -f conftest*
   991         -rm -f conftest*
   992         -fi
   993         -
   994         -echo "$ac_t""$ac_cv_mingw32" 1>&6
   995         -MINGW32=
   996         -test "$ac_cv_mingw32" = yes && MINGW32=yes
   997         -
   998         -    # If the user did not set CFLAGS, set it now to keep
   999         -    # the AC_PROG_CC macro from adding "-g -O2".
  1000         -    if test "${CFLAGS+set}" != "set" ; then
  1001         -	CFLAGS=""
  1002         -    fi
  1003         -
  1004         -    # Extract the first word of "gcc", so it can be a program name with args.
  1005         -set dummy gcc; ac_word=$2
  1006         -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
  1007         -echo "configure:1009: checking for $ac_word" >&5
  1008         -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
  1009         -  echo $ac_n "(cached) $ac_c" 1>&6
  1010         -else
  1011         -  if test -n "$CC"; then
  1012         -  ac_cv_prog_CC="$CC" # Let the user override the test.
  1013         -else
  1014         -  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  1015         -  ac_dummy="$PATH"
  1016         -  for ac_dir in $ac_dummy; do
  1017         -    test -z "$ac_dir" && ac_dir=.
  1018         -    if test -f $ac_dir/$ac_word; then
  1019         -      ac_cv_prog_CC="gcc"
  1020         -      break
  1021         -    fi
  1022         -  done
  1023         -  IFS="$ac_save_ifs"
  1024         -fi
  1025         -fi
  1026         -CC="$ac_cv_prog_CC"
  1027         -if test -n "$CC"; then
  1028         -  echo "$ac_t""$CC" 1>&6
  1029         -else
  1030         -  echo "$ac_t""no" 1>&6
  1031         -fi
  1032         -
  1033         -if test -z "$CC"; then
  1034         -  # Extract the first word of "cc", so it can be a program name with args.
  1035         -set dummy cc; ac_word=$2
  1036         -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
  1037         -echo "configure:1039: checking for $ac_word" >&5
  1038         -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
  1039         -  echo $ac_n "(cached) $ac_c" 1>&6
  1040         -else
  1041         -  if test -n "$CC"; then
  1042         -  ac_cv_prog_CC="$CC" # Let the user override the test.
  1043         -else
  1044         -  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  1045         -  ac_prog_rejected=no
  1046         -  ac_dummy="$PATH"
  1047         -  for ac_dir in $ac_dummy; do
  1048         -    test -z "$ac_dir" && ac_dir=.
  1049         -    if test -f $ac_dir/$ac_word; then
  1050         -      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
  1051         -        ac_prog_rejected=yes
  1052         -	continue
  1053         -      fi
  1054         -      ac_cv_prog_CC="cc"
  1055         -      break
  1056         -    fi
  1057         -  done
  1058         -  IFS="$ac_save_ifs"
  1059         -if test $ac_prog_rejected = yes; then
  1060         -  # We found a bogon in the path, so make sure we never use it.
  1061         -  set dummy $ac_cv_prog_CC
  1062         -  shift
  1063         -  if test $# -gt 0; then
  1064         -    # We chose a different compiler from the bogus one.
  1065         -    # However, it has the same basename, so the bogon will be chosen
  1066         -    # first if we set CC to just the basename; use the full file name.
  1067         -    shift
  1068         -    set dummy "$ac_dir/$ac_word" "$@"
  1069         -    shift
  1070         -    ac_cv_prog_CC="$@"
  1071         -  fi
  1072         -fi
  1073         -fi
  1074         -fi
  1075         -CC="$ac_cv_prog_CC"
  1076         -if test -n "$CC"; then
  1077         -  echo "$ac_t""$CC" 1>&6
  1078         -else
  1079         -  echo "$ac_t""no" 1>&6
  1080         -fi
  1081         -
  1082         -  if test -z "$CC"; then
  1083         -    case "`uname -s`" in
  1084         -    *win32* | *WIN32*)
  1085         -      # Extract the first word of "cl", so it can be a program name with args.
  1086         -set dummy cl; ac_word=$2
  1087         -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
  1088         -echo "configure:1090: checking for $ac_word" >&5
  1089         -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
  1090         -  echo $ac_n "(cached) $ac_c" 1>&6
  1091         -else
  1092         -  if test -n "$CC"; then
  1093         -  ac_cv_prog_CC="$CC" # Let the user override the test.
  1094         -else
  1095         -  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  1096         -  ac_dummy="$PATH"
  1097         -  for ac_dir in $ac_dummy; do
  1098         -    test -z "$ac_dir" && ac_dir=.
  1099         -    if test -f $ac_dir/$ac_word; then
  1100         -      ac_cv_prog_CC="cl"
  1101         -      break
  1102         -    fi
  1103         -  done
  1104         -  IFS="$ac_save_ifs"
  1105         -fi
  1106         -fi
  1107         -CC="$ac_cv_prog_CC"
  1108         -if test -n "$CC"; then
  1109         -  echo "$ac_t""$CC" 1>&6
  1110         -else
  1111         -  echo "$ac_t""no" 1>&6
  1112         -fi
  1113         - ;;
  1114         -    esac
  1115         -  fi
  1116         -  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
  1117         -fi
  1118         -
  1119         -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
  1120         -echo "configure:1122: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
  1121         -
  1122         -ac_ext=c
  1123         -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
  1124         -ac_cpp='$CPP $CPPFLAGS'
  1125         -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
  1126         -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
  1127         -cross_compiling=$ac_cv_prog_cc_cross
  1128         -
  1129         -cat > conftest.$ac_ext << EOF
  1130         -
  1131         -#line 1133 "configure"
  1132         -#include "confdefs.h"
  1133         -
  1134         -main(){return(0);}
  1135         -EOF
  1136         -if { (eval echo configure:1138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  1137         -  ac_cv_prog_cc_works=yes
  1138         -  # If we can't run a trivial program, we are probably using a cross compiler.
  1139         -  if (./conftest; exit) 2>/dev/null; then
  1140         -    ac_cv_prog_cc_cross=no
  1141         -  else
  1142         -    ac_cv_prog_cc_cross=yes
  1143         -  fi
  1144         -else
  1145         -  echo "configure: failed program was:" >&5
  1146         -  cat conftest.$ac_ext >&5
  1147         -  ac_cv_prog_cc_works=no
  1148         -fi
  1149         -rm -fr conftest*
  1150         -ac_ext=c
  1151         -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
  1152         -ac_cpp='$CPP $CPPFLAGS'
  1153         -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
  1154         -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
  1155         -cross_compiling=$ac_cv_prog_cc_cross
  1156         -
  1157         -echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
  1158         -if test $ac_cv_prog_cc_works = no; then
  1159         -  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
  1160         -fi
  1161         -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
  1162         -echo "configure:1164: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
  1163         -echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
  1164         -cross_compiling=$ac_cv_prog_cc_cross
  1165         -
  1166         -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
  1167         -echo "configure:1169: checking whether we are using GNU C" >&5
  1168         -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
  1169         -  echo $ac_n "(cached) $ac_c" 1>&6
  1170         -else
  1171         -  cat > conftest.c <<EOF
  1172         -#ifdef __GNUC__
  1173         -  yes;
  1174         -#endif
  1175         -EOF
  1176         -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
  1177         -  ac_cv_prog_gcc=yes
  1178         -else
  1179         -  ac_cv_prog_gcc=no
  1180         -fi
  1181         -fi
  1182         -
  1183         -echo "$ac_t""$ac_cv_prog_gcc" 1>&6
  1184         -
  1185         -if test $ac_cv_prog_gcc = yes; then
  1186         -  GCC=yes
  1187         -else
  1188         -  GCC=
  1189         -fi
  1190         -
  1191         -ac_test_CFLAGS="${CFLAGS+set}"
  1192         -ac_save_CFLAGS="$CFLAGS"
  1193         -CFLAGS=
  1194         -echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
  1195         -echo "configure:1197: checking whether ${CC-cc} accepts -g" >&5
  1196         -if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
  1197         -  echo $ac_n "(cached) $ac_c" 1>&6
  1198         -else
  1199         -  echo 'void f(){}' > conftest.c
  1200         -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
  1201         -  ac_cv_prog_cc_g=yes
  1202         -else
  1203         -  ac_cv_prog_cc_g=no
  1204         -fi
  1205         -rm -f conftest*
  1206         -
  1207         -fi
  1208         -
  1209         -echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
  1210         -if test "$ac_test_CFLAGS" = set; then
  1211         -  CFLAGS="$ac_save_CFLAGS"
  1212         -elif test $ac_cv_prog_cc_g = yes; then
  1213         -  if test "$GCC" = yes; then
  1214         -    CFLAGS="-g -O2"
  1215         -  else
  1216         -    CFLAGS="-g"
  1217         -  fi
  1218         -else
  1219         -  if test "$GCC" = yes; then
  1220         -    CFLAGS="-O2"
  1221         -  else
  1222         -    CFLAGS=
  1223         -  fi
  1224         -fi
  1225         -
  1226         -
  1227         -    #------------------------------------------------------------------------
  1228         -    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
  1229         -    # It makes compiling go faster.  (This is only a performance feature.)
  1230         -    #------------------------------------------------------------------------
  1231         -
  1232         -    if test -z "$no_pipe" -a -n "$GCC"; then
  1233         -	echo $ac_n "checking if the compiler understands -pipe""... $ac_c" 1>&6
  1234         -echo "configure:1236: checking if the compiler understands -pipe" >&5
  1235         -	OLDCC="$CC"
  1236         -	CC="$CC -pipe"
  1237         -	cat > conftest.$ac_ext <<EOF
  1238         -#line 1240 "configure"
  1239         -#include "confdefs.h"
  1240         -
  1241         -int main() {
  1242         -
  1243         -; return 0; }
  1244         -EOF
  1245         -if { (eval echo configure:1247: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  1246         -  rm -rf conftest*
  1247         -  echo "$ac_t""yes" 1>&6
  1248         -else
  1249         -  echo "configure: failed program was:" >&5
  1250         -  cat conftest.$ac_ext >&5
  1251         -  rm -rf conftest*
  1252         -  CC="$OLDCC"
  1253         -	    echo "$ac_t""no" 1>&6
  1254         -fi
  1255         -rm -f conftest*
  1256         -    fi
  1257         -
  1258         -    # Find a good install program.  We prefer a C program (faster),
  1259         -# so one script is as good as another.  But avoid the broken or
  1260         -# incompatible versions:
  1261         -# SysV /etc/install, /usr/sbin/install
  1262         -# SunOS /usr/etc/install
  1263         -# IRIX /sbin/install
  1264         -# AIX /bin/install
  1265         -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
  1266         -# AFS /usr/afsws/bin/install, which mishandles nonexistent args
  1267         -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
  1268         -# ./install, which can be erroneously created by make from ./install.sh.
  1269         -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
  1270         -echo "configure:1272: checking for a BSD compatible install" >&5
  1271         -if test -z "$INSTALL"; then
  1272         -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
  1273         -  echo $ac_n "(cached) $ac_c" 1>&6
  1274         -else
  1275         -    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
  1276         -  for ac_dir in $PATH; do
  1277         -    # Account for people who put trailing slashes in PATH elements.
  1278         -    case "$ac_dir/" in
  1279         -    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
  1280         -    *)
  1281         -      # OSF1 and SCO ODT 3.0 have their own names for install.
  1282         -      # Don't use installbsd from OSF since it installs stuff as root
  1283         -      # by default.
  1284         -      for ac_prog in ginstall scoinst install; do
  1285         -        if test -f $ac_dir/$ac_prog; then
  1286         -	  if test $ac_prog = install &&
  1287         -            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
  1288         -	    # AIX install.  It has an incompatible calling convention.
  1289         -	    :
  1290         -	  else
  1291         -	    ac_cv_path_install="$ac_dir/$ac_prog -c"
  1292         -	    break 2
  1293         -	  fi
  1294         -	fi
  1295         -      done
  1296         -      ;;
  1297         -    esac
  1298         -  done
  1299         -  IFS="$ac_save_IFS"
  1300         -
  1301         -fi
  1302         -  if test "${ac_cv_path_install+set}" = set; then
  1303         -    INSTALL="$ac_cv_path_install"
  1304         -  else
  1305         -    # As a last resort, use the slow shell script.  We don't cache a
  1306         -    # path for INSTALL within a source directory, because that will
  1307         -    # break other packages using the cache if that directory is
  1308         -    # removed, or if the path is relative.
  1309         -    INSTALL="$ac_install_sh"
  1310         -  fi
  1311         -fi
  1312         -echo "$ac_t""$INSTALL" 1>&6
  1313         -
  1314         -# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
  1315         -# It thinks the first close brace ends the variable substitution.
  1316         -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
  1317         -
  1318         -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
  1319         -
  1320         -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
  1321         -
  1322         -
  1323         -    #--------------------------------------------------------------------
  1324         -    # Checks to see if the make program sets the $MAKE variable.
  1325         -    #--------------------------------------------------------------------
  1326         -
  1327         -    echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
  1328         -echo "configure:1330: checking whether ${MAKE-make} sets \${MAKE}" >&5
  1329         -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
  1330         -if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
  1331         -  echo $ac_n "(cached) $ac_c" 1>&6
  1332         -else
  1333         -  cat > conftestmake <<\EOF
  1334         -all:
  1335         -	@echo 'ac_maketemp="${MAKE}"'
  1336         -EOF
  1337         -# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
  1338         -eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
  1339         -if test -n "$ac_maketemp"; then
  1340         -  eval ac_cv_prog_make_${ac_make}_set=yes
  1341         -else
  1342         -  eval ac_cv_prog_make_${ac_make}_set=no
  1343         -fi
  1344         -rm -f conftestmake
  1345         -fi
  1346         -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
  1347         -  echo "$ac_t""yes" 1>&6
  1348         -  SET_MAKE=
  1349         -else
  1350         -  echo "$ac_t""no" 1>&6
  1351         -  SET_MAKE="MAKE=${MAKE-make}"
  1352         -fi
  1353         -
  1354         -
  1355         -    #--------------------------------------------------------------------
  1356         -    # Find ranlib
  1357         -    #--------------------------------------------------------------------
  1358         -
  1359         -    # Extract the first word of "ranlib", so it can be a program name with args.
  1360         -set dummy ranlib; ac_word=$2
  1361         -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
  1362         -echo "configure:1364: checking for $ac_word" >&5
  1363         -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
  1364         -  echo $ac_n "(cached) $ac_c" 1>&6
  1365         -else
  1366         -  if test -n "$RANLIB"; then
  1367         -  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
  1368         -else
  1369         -  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  1370         -  ac_dummy="$PATH"
  1371         -  for ac_dir in $ac_dummy; do
  1372         -    test -z "$ac_dir" && ac_dir=.
  1373         -    if test -f $ac_dir/$ac_word; then
  1374         -      ac_cv_prog_RANLIB="ranlib"
  1375         -      break
  1376         -    fi
  1377         -  done
  1378         -  IFS="$ac_save_ifs"
  1379         -  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
  1380         -fi
  1381         -fi
  1382         -RANLIB="$ac_cv_prog_RANLIB"
  1383         -if test -n "$RANLIB"; then
  1384         -  echo "$ac_t""$RANLIB" 1>&6
  1385         -else
  1386         -  echo "$ac_t""no" 1>&6
  1387         -fi
  1388         -
  1389         -
  1390         -    #--------------------------------------------------------------------
  1391         -    # Determines the correct binary file extension (.o, .obj, .exe etc.)
  1392         -    #--------------------------------------------------------------------
  1393         -
  1394         -    echo $ac_n "checking for object suffix""... $ac_c" 1>&6
  1395         -echo "configure:1397: checking for object suffix" >&5
  1396         -if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
  1397         -  echo $ac_n "(cached) $ac_c" 1>&6
  1398         -else
  1399         -  rm -f conftest*
  1400         -echo 'int i = 1;' > conftest.$ac_ext
  1401         -if { (eval echo configure:1403: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  1402         -  for ac_file in conftest.*; do
  1403         -    case $ac_file in
  1404         -    *.c) ;;
  1405         -    *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
  1406         -    esac
  1407         -  done
  1408         -else
  1409         -  { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
  1410         -fi
  1411         -rm -f conftest*
  1412         -fi
  1413         -
  1414         -echo "$ac_t""$ac_cv_objext" 1>&6
  1415         -OBJEXT=$ac_cv_objext
  1416         -ac_objext=$ac_cv_objext
  1417         -
  1418         -    
  1419         -
  1420         -echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
  1421         -echo "configure:1423: checking for executable suffix" >&5
  1422         -if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
  1423         -  echo $ac_n "(cached) $ac_c" 1>&6
  1424         -else
  1425         -  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
  1426         -  ac_cv_exeext=.exe
  1427         -else
  1428         -  rm -f conftest*
  1429         -  echo 'int main () { return 0; }' > conftest.$ac_ext
  1430         -  ac_cv_exeext=
  1431         -  if { (eval echo configure:1433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
  1432         -    for file in conftest.*; do
  1433         -      case $file in
  1434         -      *.c | *.o | *.obj) ;;
  1435         -      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
  1436         -      esac
  1437         -    done
  1438         -  else
  1439         -    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
  1440         -  fi
  1441         -  rm -f conftest*
  1442         -  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
  1443         -fi
  1444         -fi
  1445         -
  1446         -EXEEXT=""
  1447         -test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
  1448         -echo "$ac_t""${ac_cv_exeext}" 1>&6
  1449         -ac_exeext=$EXEEXT
  1450         -
  1451         -
  1452         -
  1453         -#--------------------------------------------------------------------
  1454         -# __CHANGE__
  1455         -# Choose which headers you need.  Extension authors should try very
  1456         -# hard to only rely on the Tcl public header files.  Internal headers
  1457         -# contain private data structures and are subject to change without
  1458         -# notice.
  1459         -# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
  1460         -#--------------------------------------------------------------------
  1461         -
  1462         -
  1463         -    echo $ac_n "checking for Tcl public headers""... $ac_c" 1>&6
  1464         -echo "configure:1466: checking for Tcl public headers" >&5
  1465         -
  1466         -    # Check whether --with-tclinclude or --without-tclinclude was given.
  1467         -if test "${with_tclinclude+set}" = set; then
  1468         -  withval="$with_tclinclude"
  1469         -  with_tclinclude=${withval}
  1470         -fi
  1471         -
  1472         -
  1473         -    if eval "test \"`echo '$''{'ac_cv_c_tclh'+set}'`\" = set"; then
  1474         -  echo $ac_n "(cached) $ac_c" 1>&6
  1475         -else
  1476         -  
  1477         -	# Use the value from --with-tclinclude, if it was given
  1478         -
  1479         -	if test x"${with_tclinclude}" != x ; then
  1480         -	    if test -f "${with_tclinclude}/tcl.h" ; then
  1481         -		ac_cv_c_tclh=${with_tclinclude}
  1482         -	    else
  1483         -		{ echo "configure: error: ${with_tclinclude} directory does not contain tcl.h" 1>&2; exit 1; }
  1484         -	    fi
  1485         -	else
  1486         -	    # Check order: pkg --prefix location, Tcl's --prefix location,
  1487         -	    # directory of tclConfig.sh, and Tcl source directory.
  1488         -	    # Looking in the source dir is not ideal, but OK.
  1489         -
  1490         -	    eval "temp_includedir=${includedir}"
  1491         -	    list="`ls -d ${temp_includedir}      2>/dev/null` \
  1492         -		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
  1493         -		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null` \
  1494         -		`ls -d ${TCL_SRC_DIR}/generic    2>/dev/null`"
  1495         -	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
  1496         -		list="$list /usr/local/include /usr/include"
  1497         -	    fi
  1498         -	    for i in $list ; do
  1499         -		if test -f "$i/tcl.h" ; then
  1500         -		    ac_cv_c_tclh=$i
  1501         -		    break
  1502         -		fi
  1503         -	    done
  1504         -	fi
  1505         -    
  1506         -fi
  1507         -
  1508         -
  1509         -    # Print a message based on how we determined the include path
  1510         -
  1511         -    if test x"${ac_cv_c_tclh}" = x ; then
  1512         -	{ echo "configure: error: tcl.h not found.  Please specify its location with --with-tclinclude" 1>&2; exit 1; }
  1513         -    else
  1514         -	echo "$ac_t""${ac_cv_c_tclh}" 1>&6
  1515         -    fi
  1516         -
  1517         -    # Convert to a native path and substitute into the output files.
  1518         -
  1519         -    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
  1520         -
  1521         -    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
  1522         -
  1523         -    
  1524         -
  1525         -#TEA_PRIVATE_TCL_HEADERS
  1526         -
  1527         -#TEA_PUBLIC_TK_HEADERS
  1528         -#TEA_PRIVATE_TK_HEADERS
  1529         -
  1530         -#--------------------------------------------------------------------
  1531         -# __CHANGE__
  1532         -# A few miscellaneous platform-specific items:
  1533         -#
  1534         -# Define a special symbol for Windows (BUILD_sample in this case) so
  1535         -# that we create the export library with the dll.  See sha1.h on how
  1536         -# to use this.
  1537         -#
  1538         -# Windows creates a few extra files that need to be cleaned up.
  1539         -# You can add more files to clean if your extension creates any extra
  1540         -# files.
  1541         -#
  1542         -# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
  1543         -# These will be appended to the current set of compiler flags for
  1544         -# your system.
  1545         -#--------------------------------------------------------------------
  1546         -
  1547         -if test "${TEA_PLATFORM}" = "windows" ; then
  1548         -    cat >> confdefs.h <<\EOF
  1549         -#define BUILD_tdom 1
  1550         -EOF
  1551         -
  1552         -    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
  1553         -    EXTRA_SOURCES='$(WIN_SOURCES)'
  1554         -    VERSION=${MAJOR_VERSION}${MINOR_VERSION}${PATCHLEVEL}
  1555         -else
  1556         -    CLEANFILES="pkgIndex.tcl"
  1557         -    EXTRA_SOURCES='$(UNIX_SOURCES)'
  1558         -    VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${PATCHLEVEL}
  1559         -fi
  1560         -
  1561         -
  1562         -
  1563         -
  1564         -
  1565         -#--------------------------------------------------------------------
  1566         -# We put this here so that you can compile with -DVERSION="1.2" to
  1567         -# encode the package version directly into the source files.
  1568         -#--------------------------------------------------------------------
  1569         -
  1570         -eval cat >> confdefs.h <<EOF
  1571         -#define VERSION "${VERSION}"
  1572         -EOF
  1573         -
  1574         -
  1575         -#--------------------------------------------------------------------
  1576         -# Setup the current source directory so extensions building against
  1577         -# tDOM stub library will know where to find binary directories.
  1578         -# Setup paths and linker specification of the stub library.
  1579         -# Note: some of those below are replicated in Makefile.in as well.
  1580         -#--------------------------------------------------------------------
  1581         -
  1582         -tdom_SRC_DIR=`cd ${srcdir}; pwd`
  1583         -
  1584         -pkglibdir="${exec_prefix}/lib/${PACKAGE}${VERSION}"
  1585         -tdomstub_LIB_FLAG="-ltdomstub${VERSION}${TCL_DBGX}"
  1586         -
  1587         -tdomstub_BUILD_SPEC="-L`pwd` ${tdomstub_LIB_FLAG}"
  1588         -tdomstub_FILE_SPEC="-L${pkglibdir} ${tdomstub_LIB_FLAG}"
  1589         -
  1590         -
  1591         -
  1592         -
  1593         -
  1594         -#--------------------------------------------------------------------
  1595         -# Check whether --enable-threads or --disable-threads was given.
  1596         -#--------------------------------------------------------------------
  1597         -
  1598         -
  1599         -    # Check whether --enable-threads or --disable-threads was given.
  1600         -if test "${enable_threads+set}" = set; then
  1601         -  enableval="$enable_threads"
  1602         -  tcl_ok=$enableval
  1603         -else
  1604         -  tcl_ok=
  1605         -fi
  1606         -
  1607         -
  1608         -    if test "$tcl_ok" = "yes"; then
  1609         -	TCL_THREADS=1
  1610         -
  1611         -	if test "${TEA_PLATFORM}" != "windows" ; then
  1612         -	    # We are always OK on Windows, so check what this platform wants.
  1613         -	    cat >> confdefs.h <<\EOF
  1614         -#define USE_THREAD_ALLOC 1
  1615         -EOF
  1616         -
  1617         -	    cat >> confdefs.h <<\EOF
  1618         -#define _REENTRANT 1
  1619         -EOF
  1620         -
  1621         -	    cat >> confdefs.h <<\EOF
  1622         -#define _THREAD_SAFE 1
  1623         -EOF
  1624         -
  1625         -	    echo $ac_n "checking for pthread_mutex_init in -lpthread""... $ac_c" 1>&6
  1626         -echo "configure:1628: checking for pthread_mutex_init in -lpthread" >&5
  1627         -ac_lib_var=`echo pthread'_'pthread_mutex_init | sed 'y%./+-%__p_%'`
  1628         -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  1629         -  echo $ac_n "(cached) $ac_c" 1>&6
  1630         -else
  1631         -  ac_save_LIBS="$LIBS"
  1632         -LIBS="-lpthread  $LIBS"
  1633         -cat > conftest.$ac_ext <<EOF
  1634         -#line 1636 "configure"
  1635         -#include "confdefs.h"
  1636         -/* Override any gcc2 internal prototype to avoid an error.  */
  1637         -/* We use char because int might match the return type of a gcc2
  1638         -    builtin and then its argument prototype would still apply.  */
  1639         -char pthread_mutex_init();
  1640         -
  1641         -int main() {
  1642         -pthread_mutex_init()
  1643         -; return 0; }
  1644         -EOF
  1645         -if { (eval echo configure:1647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  1646         -  rm -rf conftest*
  1647         -  eval "ac_cv_lib_$ac_lib_var=yes"
  1648         -else
  1649         -  echo "configure: failed program was:" >&5
  1650         -  cat conftest.$ac_ext >&5
  1651         -  rm -rf conftest*
  1652         -  eval "ac_cv_lib_$ac_lib_var=no"
  1653         -fi
  1654         -rm -f conftest*
  1655         -LIBS="$ac_save_LIBS"
  1656         -
  1657         -fi
  1658         -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  1659         -  echo "$ac_t""yes" 1>&6
  1660         -  tcl_ok=yes
  1661         -else
  1662         -  echo "$ac_t""no" 1>&6
  1663         -tcl_ok=no
  1664         -fi
  1665         -
  1666         -	    if test "$tcl_ok" = "no"; then
  1667         -		# Check a little harder for __pthread_mutex_init in the
  1668         -		# same library, as some systems hide it there until
  1669         -		# pthread.h is defined.	 We could alternatively do an
  1670         -		# AC_TRY_COMPILE with pthread.h, but that will work with
  1671         -		# libpthread really doesn't exist, like AIX 4.2.
  1672         -		# [Bug: 4359]
  1673         -		echo $ac_n "checking for __pthread_mutex_init in -lpthread""... $ac_c" 1>&6
  1674         -echo "configure:1676: checking for __pthread_mutex_init in -lpthread" >&5
  1675         -ac_lib_var=`echo pthread'_'__pthread_mutex_init | sed 'y%./+-%__p_%'`
  1676         -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  1677         -  echo $ac_n "(cached) $ac_c" 1>&6
  1678         -else
  1679         -  ac_save_LIBS="$LIBS"
  1680         -LIBS="-lpthread  $LIBS"
  1681         -cat > conftest.$ac_ext <<EOF
  1682         -#line 1684 "configure"
  1683         -#include "confdefs.h"
  1684         -/* Override any gcc2 internal prototype to avoid an error.  */
  1685         -/* We use char because int might match the return type of a gcc2
  1686         -    builtin and then its argument prototype would still apply.  */
  1687         -char __pthread_mutex_init();
  1688         -
  1689         -int main() {
  1690         -__pthread_mutex_init()
  1691         -; return 0; }
  1692         -EOF
  1693         -if { (eval echo configure:1695: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  1694         -  rm -rf conftest*
  1695         -  eval "ac_cv_lib_$ac_lib_var=yes"
  1696         -else
  1697         -  echo "configure: failed program was:" >&5
  1698         -  cat conftest.$ac_ext >&5
  1699         -  rm -rf conftest*
  1700         -  eval "ac_cv_lib_$ac_lib_var=no"
  1701         -fi
  1702         -rm -f conftest*
  1703         -LIBS="$ac_save_LIBS"
  1704         -
  1705         -fi
  1706         -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  1707         -  echo "$ac_t""yes" 1>&6
  1708         -  tcl_ok=yes
  1709         -else
  1710         -  echo "$ac_t""no" 1>&6
  1711         -tcl_ok=no
  1712         -fi
  1713         -
  1714         -	    fi
  1715         -	    
  1716         -	    if test "$tcl_ok" = "yes"; then
  1717         -		# The space is needed
  1718         -		THREADS_LIBS=" -lpthread"
  1719         -	    else
  1720         -		echo $ac_n "checking for pthread_mutex_init in -lpthreads""... $ac_c" 1>&6
  1721         -echo "configure:1723: checking for pthread_mutex_init in -lpthreads" >&5
  1722         -ac_lib_var=`echo pthreads'_'pthread_mutex_init | sed 'y%./+-%__p_%'`
  1723         -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  1724         -  echo $ac_n "(cached) $ac_c" 1>&6
  1725         -else
  1726         -  ac_save_LIBS="$LIBS"
  1727         -LIBS="-lpthreads  $LIBS"
  1728         -cat > conftest.$ac_ext <<EOF
  1729         -#line 1731 "configure"
  1730         -#include "confdefs.h"
  1731         -/* Override any gcc2 internal prototype to avoid an error.  */
  1732         -/* We use char because int might match the return type of a gcc2
  1733         -    builtin and then its argument prototype would still apply.  */
  1734         -char pthread_mutex_init();
  1735         -
  1736         -int main() {
  1737         -pthread_mutex_init()
  1738         -; return 0; }
  1739         -EOF
  1740         -if { (eval echo configure:1742: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  1741         -  rm -rf conftest*
  1742         -  eval "ac_cv_lib_$ac_lib_var=yes"
  1743         -else
  1744         -  echo "configure: failed program was:" >&5
  1745         -  cat conftest.$ac_ext >&5
  1746         -  rm -rf conftest*
  1747         -  eval "ac_cv_lib_$ac_lib_var=no"
  1748         -fi
  1749         -rm -f conftest*
  1750         -LIBS="$ac_save_LIBS"
  1751         -
  1752         -fi
  1753         -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  1754         -  echo "$ac_t""yes" 1>&6
  1755         -  tcl_ok=yes
  1756         -else
  1757         -  echo "$ac_t""no" 1>&6
  1758         -tcl_ok=no
  1759         -fi
  1760         -
  1761         -		if test "$tcl_ok" = "yes"; then
  1762         -		    # The space is needed
  1763         -		    THREADS_LIBS=" -lpthreads"
  1764         -		else
  1765         -		    echo $ac_n "checking for pthread_mutex_init in -lc""... $ac_c" 1>&6
  1766         -echo "configure:1768: checking for pthread_mutex_init in -lc" >&5
  1767         -ac_lib_var=`echo c'_'pthread_mutex_init | sed 'y%./+-%__p_%'`
  1768         -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  1769         -  echo $ac_n "(cached) $ac_c" 1>&6
  1770         -else
  1771         -  ac_save_LIBS="$LIBS"
  1772         -LIBS="-lc  $LIBS"
  1773         -cat > conftest.$ac_ext <<EOF
  1774         -#line 1776 "configure"
  1775         -#include "confdefs.h"
  1776         -/* Override any gcc2 internal prototype to avoid an error.  */
  1777         -/* We use char because int might match the return type of a gcc2
  1778         -    builtin and then its argument prototype would still apply.  */
  1779         -char pthread_mutex_init();
  1780         -
  1781         -int main() {
  1782         -pthread_mutex_init()
  1783         -; return 0; }
  1784         -EOF
  1785         -if { (eval echo configure:1787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  1786         -  rm -rf conftest*
  1787         -  eval "ac_cv_lib_$ac_lib_var=yes"
  1788         -else
  1789         -  echo "configure: failed program was:" >&5
  1790         -  cat conftest.$ac_ext >&5
  1791         -  rm -rf conftest*
  1792         -  eval "ac_cv_lib_$ac_lib_var=no"
  1793         -fi
  1794         -rm -f conftest*
  1795         -LIBS="$ac_save_LIBS"
  1796         -
  1797         -fi
  1798         -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  1799         -  echo "$ac_t""yes" 1>&6
  1800         -  tcl_ok=yes
  1801         -else
  1802         -  echo "$ac_t""no" 1>&6
  1803         -tcl_ok=no
  1804         -fi
  1805         -
  1806         -		    if test "$tcl_ok" = "no"; then
  1807         -			echo $ac_n "checking for pthread_mutex_init in -lc_r""... $ac_c" 1>&6
  1808         -echo "configure:1810: checking for pthread_mutex_init in -lc_r" >&5
  1809         -ac_lib_var=`echo c_r'_'pthread_mutex_init | sed 'y%./+-%__p_%'`
  1810         -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  1811         -  echo $ac_n "(cached) $ac_c" 1>&6
  1812         -else
  1813         -  ac_save_LIBS="$LIBS"
  1814         -LIBS="-lc_r  $LIBS"
  1815         -cat > conftest.$ac_ext <<EOF
  1816         -#line 1818 "configure"
  1817         -#include "confdefs.h"
  1818         -/* Override any gcc2 internal prototype to avoid an error.  */
  1819         -/* We use char because int might match the return type of a gcc2
  1820         -    builtin and then its argument prototype would still apply.  */
  1821         -char pthread_mutex_init();
  1822         -
  1823         -int main() {
  1824         -pthread_mutex_init()
  1825         -; return 0; }
  1826         -EOF
  1827         -if { (eval echo configure:1829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  1828         -  rm -rf conftest*
  1829         -  eval "ac_cv_lib_$ac_lib_var=yes"
  1830         -else
  1831         -  echo "configure: failed program was:" >&5
  1832         -  cat conftest.$ac_ext >&5
  1833         -  rm -rf conftest*
  1834         -  eval "ac_cv_lib_$ac_lib_var=no"
  1835         -fi
  1836         -rm -f conftest*
  1837         -LIBS="$ac_save_LIBS"
  1838         -
  1839         -fi
  1840         -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  1841         -  echo "$ac_t""yes" 1>&6
  1842         -  tcl_ok=yes
  1843         -else
  1844         -  echo "$ac_t""no" 1>&6
  1845         -tcl_ok=no
  1846         -fi
  1847         -
  1848         -			if test "$tcl_ok" = "yes"; then
  1849         -			    # The space is needed
  1850         -			    THREADS_LIBS=" -pthread"
  1851         -			else
  1852         -			    TCL_THREADS=0
  1853         -			    echo "configure: warning: "Don t know how to find pthread lib on your system - thread support disabled"" 1>&2
  1854         -			fi
  1855         -		    fi
  1856         -		fi
  1857         -	    fi
  1858         -	    
  1859         -	    # Does the pthread-implementation provide
  1860         -	    # 'pthread_attr_setstacksize' ?
  1861         -	    for ac_func in pthread_attr_setstacksize
  1862         -do
  1863         -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
  1864         -echo "configure:1866: checking for $ac_func" >&5
  1865         -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
  1866         -  echo $ac_n "(cached) $ac_c" 1>&6
  1867         -else
  1868         -  cat > conftest.$ac_ext <<EOF
  1869         -#line 1871 "configure"
  1870         -#include "confdefs.h"
  1871         -/* System header to define __stub macros and hopefully few prototypes,
  1872         -    which can conflict with char $ac_func(); below.  */
  1873         -#include <assert.h>
  1874         -/* Override any gcc2 internal prototype to avoid an error.  */
  1875         -/* We use char because int might match the return type of a gcc2
  1876         -    builtin and then its argument prototype would still apply.  */
  1877         -char $ac_func();
  1878         -
  1879         -int main() {
  1880         -
  1881         -/* The GNU C library defines this for functions which it implements
  1882         -    to always fail with ENOSYS.  Some functions are actually named
  1883         -    something starting with __ and the normal name is an alias.  */
  1884         -#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
  1885         -choke me
  1886         -#else
  1887         -$ac_func();
  1888         -#endif
  1889         -
  1890         -; return 0; }
  1891         -EOF
  1892         -if { (eval echo configure:1894: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  1893         -  rm -rf conftest*
  1894         -  eval "ac_cv_func_$ac_func=yes"
  1895         -else
  1896         -  echo "configure: failed program was:" >&5
  1897         -  cat conftest.$ac_ext >&5
  1898         -  rm -rf conftest*
  1899         -  eval "ac_cv_func_$ac_func=no"
  1900         -fi
  1901         -rm -f conftest*
  1902         -fi
  1903         -
  1904         -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
  1905         -  echo "$ac_t""yes" 1>&6
  1906         -    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
  1907         -  cat >> confdefs.h <<EOF
  1908         -#define $ac_tr_func 1
  1909         -EOF
  1910         - 
  1911         -else
  1912         -  echo "$ac_t""no" 1>&6
  1913         -fi
  1914         -done
  1915         -
  1916         -	fi
  1917         -    else
  1918         -	TCL_THREADS=0
  1919         -    fi
  1920         -    # Do checking message here to not mess up interleaved configure output
  1921         -    echo $ac_n "checking for building with threads""... $ac_c" 1>&6
  1922         -echo "configure:1924: checking for building with threads" >&5
  1923         -    if test "${TCL_THREADS}" = "1"; then
  1924         -	cat >> confdefs.h <<\EOF
  1925         -#define TCL_THREADS 1
  1926         -EOF
  1927         -
  1928         -	echo "$ac_t""yes" 1>&6
  1929         -    else
  1930         -	echo "$ac_t""no (default)" 1>&6
  1931         -    fi
  1932         -    # TCL_THREADS sanity checking.  See if our request for building with
  1933         -    # threads is the same as the way Tcl was built.  If not, warn the user.
  1934         -    case ${TCL_DEFS} in
  1935         -	*THREADS=1*)
  1936         -	    if test "${TCL_THREADS}" = "0"; then
  1937         -		echo "configure: warning: 
  1938         -    Building ${PACKAGE} without threads enabled, but building against a Tcl
  1939         -    that IS thread-enabled." 1>&2
  1940         -	    fi
  1941         -	    ;;
  1942         -	*)
  1943         -	    if test "${TCL_THREADS}" = "1"; then
  1944         -		echo "configure: warning: 
  1945         -    --enable-threads requested, but attempting building against a Tcl
  1946         -    that is NOT thread-enabled." 1>&2
  1947         -	    fi
  1948         -	    ;;
  1949         -    esac
  1950         -    
  1951         -
  1952         -
  1953         -#--------------------------------------------------------------------
  1954         -# The statement below defines a collection of symbols related to
  1955         -# building as a shared library instead of a static library.
  1956         -#--------------------------------------------------------------------
  1957         -
  1958         -
  1959         -    echo $ac_n "checking how to build libraries""... $ac_c" 1>&6
  1960         -echo "configure:1962: checking how to build libraries" >&5
  1961         -    # Check whether --enable-shared or --disable-shared was given.
  1962         -if test "${enable_shared+set}" = set; then
  1963         -  enableval="$enable_shared"
  1964         -  tcl_ok=$enableval
  1965         -else
  1966         -  tcl_ok=yes
  1967         -fi
  1968         -
  1969         -
  1970         -    if test "${enable_shared+set}" = set; then
  1971         -	enableval="$enable_shared"
  1972         -	tcl_ok=$enableval
  1973         -    else
  1974         -	tcl_ok=yes
  1975         -    fi
  1976         -
  1977         -    if test "$tcl_ok" = "yes" ; then
  1978         -	echo "$ac_t""shared" 1>&6
  1979         -	SHARED_BUILD=1
  1980         -    else
  1981         -	echo "$ac_t""static" 1>&6
  1982         -	SHARED_BUILD=0
  1983         -	cat >> confdefs.h <<\EOF
  1984         -#define STATIC_BUILD 1
  1985         -EOF
  1986         -
  1987         -    fi
  1988         -
  1989         -
  1990         -#--------------------------------------------------------------------
  1991         -# This macro figures out what flags to use with the compiler/linker
  1992         -# when building shared/static debug/optimized objects.  This information
  1993         -# can be taken from the tclConfig.sh file, but this figures it all out.
  1994         -#--------------------------------------------------------------------
  1995         -
  1996         -echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
  1997         -echo "configure:1999: checking how to run the C preprocessor" >&5
  1998         -# On Suns, sometimes $CPP names a directory.
  1999         -if test -n "$CPP" && test -d "$CPP"; then
  2000         -  CPP=
  2001         -fi
  2002         -if test -z "$CPP"; then
  2003         -if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
  2004         -  echo $ac_n "(cached) $ac_c" 1>&6
  2005         -else
  2006         -    # This must be in double quotes, not single quotes, because CPP may get
  2007         -  # substituted into the Makefile and "${CC-cc}" will confuse make.
  2008         -  CPP="${CC-cc} -E"
  2009         -  # On the NeXT, cc -E runs the code through the compiler's parser,
  2010         -  # not just through cpp.
  2011         -  cat > conftest.$ac_ext <<EOF
  2012         -#line 2014 "configure"
  2013         -#include "confdefs.h"
  2014         -#include <assert.h>
  2015         -Syntax Error
  2016         -EOF
  2017         -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
  2018         -{ (eval echo configure:2020: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
  2019         -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
  2020         -if test -z "$ac_err"; then
  2021         -  :
  2022         -else
  2023         -  echo "$ac_err" >&5
  2024         -  echo "configure: failed program was:" >&5
  2025         -  cat conftest.$ac_ext >&5
  2026         -  rm -rf conftest*
  2027         -  CPP="${CC-cc} -E -traditional-cpp"
  2028         -  cat > conftest.$ac_ext <<EOF
  2029         -#line 2031 "configure"
  2030         -#include "confdefs.h"
  2031         -#include <assert.h>
  2032         -Syntax Error
  2033         -EOF
  2034         -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
  2035         -{ (eval echo configure:2037: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
  2036         -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
  2037         -if test -z "$ac_err"; then
  2038         -  :
  2039         -else
  2040         -  echo "$ac_err" >&5
  2041         -  echo "configure: failed program was:" >&5
  2042         -  cat conftest.$ac_ext >&5
  2043         -  rm -rf conftest*
  2044         -  CPP="${CC-cc} -nologo -E"
  2045         -  cat > conftest.$ac_ext <<EOF
  2046         -#line 2048 "configure"
  2047         -#include "confdefs.h"
  2048         -#include <assert.h>
  2049         -Syntax Error
  2050         -EOF
  2051         -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
  2052         -{ (eval echo configure:2054: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
  2053         -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
  2054         -if test -z "$ac_err"; then
  2055         -  :
  2056         -else
  2057         -  echo "$ac_err" >&5
  2058         -  echo "configure: failed program was:" >&5
  2059         -  cat conftest.$ac_ext >&5
  2060         -  rm -rf conftest*
  2061         -  CPP=/lib/cpp
  2062         -fi
  2063         -rm -f conftest*
  2064         -fi
  2065         -rm -f conftest*
  2066         -fi
  2067         -rm -f conftest*
  2068         -  ac_cv_prog_CPP="$CPP"
  2069         -fi
  2070         -  CPP="$ac_cv_prog_CPP"
  2071         -else
  2072         -  ac_cv_prog_CPP="$CPP"
  2073         -fi
  2074         -echo "$ac_t""$CPP" 1>&6
  2075         -
  2076         -
  2077         -    if test x"${TEA_INITED}" = x ; then
  2078         -	# Can't refer to exact macro name or it will be substituted
  2079         -	{ echo "configure: error: Must call TEA INIT before CONFIG_CFLAGS" 1>&2; exit 1; }
  2080         -    fi
  2081         -
  2082         -    # Step 0: Enable 64 bit support?
  2083         -
  2084         -    echo $ac_n "checking if 64bit support is enabled""... $ac_c" 1>&6
  2085         -echo "configure:2087: checking if 64bit support is enabled" >&5
  2086         -    # Check whether --enable-64bit or --disable-64bit was given.
  2087         -if test "${enable_64bit+set}" = set; then
  2088         -  enableval="$enable_64bit"
  2089         -  do64bit=$enableval
  2090         -else
  2091         -  do64bit=no
  2092         -fi
  2093         -
  2094         -    echo "$ac_t""$do64bit" 1>&6
  2095         - 
  2096         -    # Step 0.b: Enable Solaris 64 bit VIS support?
  2097         -
  2098         -    echo $ac_n "checking if 64bit Sparc VIS support is requested""... $ac_c" 1>&6
  2099         -echo "configure:2101: checking if 64bit Sparc VIS support is requested" >&5
  2100         -    # Check whether --enable-64bit-vis or --disable-64bit-vis was given.
  2101         -if test "${enable_64bit_vis+set}" = set; then
  2102         -  enableval="$enable_64bit_vis"
  2103         -  do64bitVIS=$enableval
  2104         -else
  2105         -  do64bitVIS=no
  2106         -fi
  2107         -
  2108         -    echo "$ac_t""$do64bitVIS" 1>&6
  2109         -
  2110         -    if test "$do64bitVIS" = "yes"; then
  2111         -	# Force 64bit on with VIS
  2112         -	do64bit=yes
  2113         -    fi
  2114         -
  2115         -    # Step 1: set the variable "system" to hold the name and version number
  2116         -    # for the system.  This can usually be done via the "uname" command, but
  2117         -    # there are a few systems, like Next, where this doesn't work.
  2118         -
  2119         -    echo $ac_n "checking system version (for dynamic loading)""... $ac_c" 1>&6
  2120         -echo "configure:2122: checking system version (for dynamic loading)" >&5
  2121         -    if test -f /usr/lib/NextStep/software_version; then
  2122         -	system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
  2123         -    else
  2124         -	system=`uname -s`-`uname -r`
  2125         -	if test "$?" -ne 0 ; then
  2126         -	    echo "$ac_t""unknown (can't find uname command)" 1>&6
  2127         -	    system=unknown
  2128         -	else
  2129         -	    # Special check for weird MP-RAS system (uname returns weird
  2130         -	    # results, and the version is kept in special file).
  2131         -	
  2132         -	    if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
  2133         -		system=MP-RAS-`awk '{print }' /etc/.relid'`
  2134         -	    fi
  2135         -	    if test "`uname -s`" = "AIX" ; then
  2136         -		system=AIX-`uname -v`.`uname -r`
  2137         -	    fi
  2138         -	    if test "${TEA_PLATFORM}" = "windows" ; then
  2139         -		system=windows
  2140         -	    fi
  2141         -	    echo "$ac_t""$system" 1>&6
  2142         -	fi
  2143         -    fi
  2144         -
  2145         -    # Step 2: check for existence of -ldl library.  This is needed because
  2146         -    # Linux can use either -ldl or -ldld for dynamic loading.
  2147         -
  2148         -    echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
  2149         -echo "configure:2151: checking for dlopen in -ldl" >&5
  2150         -ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
  2151         -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  2152         -  echo $ac_n "(cached) $ac_c" 1>&6
  2153         -else
  2154         -  ac_save_LIBS="$LIBS"
  2155         -LIBS="-ldl  $LIBS"
  2156         -cat > conftest.$ac_ext <<EOF
  2157         -#line 2159 "configure"
  2158         -#include "confdefs.h"
  2159         -/* Override any gcc2 internal prototype to avoid an error.  */
  2160         -/* We use char because int might match the return type of a gcc2
  2161         -    builtin and then its argument prototype would still apply.  */
  2162         -char dlopen();
  2163         -
  2164         -int main() {
  2165         -dlopen()
  2166         -; return 0; }
  2167         -EOF
  2168         -if { (eval echo configure:2170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  2169         -  rm -rf conftest*
  2170         -  eval "ac_cv_lib_$ac_lib_var=yes"
  2171         -else
  2172         -  echo "configure: failed program was:" >&5
  2173         -  cat conftest.$ac_ext >&5
  2174         -  rm -rf conftest*
  2175         -  eval "ac_cv_lib_$ac_lib_var=no"
  2176         -fi
  2177         -rm -f conftest*
  2178         -LIBS="$ac_save_LIBS"
  2179         -
  2180         -fi
  2181         -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  2182         -  echo "$ac_t""yes" 1>&6
  2183         -  have_dl=yes
  2184         -else
  2185         -  echo "$ac_t""no" 1>&6
  2186         -have_dl=no
  2187         -fi
  2188         -
  2189         -
  2190         -    # Step 3: set configuration options based on system name and version.
  2191         -
  2192         -    do64bit_ok=no
  2193         -    EXTRA_CFLAGS=""
  2194         -    TCL_EXPORT_FILE_SUFFIX=""
  2195         -    UNSHARED_LIB_SUFFIX=""
  2196         -    TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`'
  2197         -    ECHO_VERSION='`echo ${VERSION}`'
  2198         -    TCL_LIB_VERSIONS_OK=ok
  2199         -    CFLAGS_DEBUG=-g
  2200         -    CFLAGS_OPTIMIZE=-O
  2201         -    if test "$GCC" = "yes" ; then
  2202         -	CFLAGS_WARNING="-Wall -Wconversion -Wno-implicit-int"
  2203         -    else
  2204         -	CFLAGS_WARNING=""
  2205         -    fi
  2206         -    TCL_NEEDS_EXP_FILE=0
  2207         -    TCL_BUILD_EXP_FILE=""
  2208         -    TCL_EXP_FILE=""
  2209         -    # Extract the first word of "ar", so it can be a program name with args.
  2210         -set dummy ar; ac_word=$2
  2211         -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
  2212         -echo "configure:2214: checking for $ac_word" >&5
  2213         -if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
  2214         -  echo $ac_n "(cached) $ac_c" 1>&6
  2215         -else
  2216         -  if test -n "$AR"; then
  2217         -  ac_cv_prog_AR="$AR" # Let the user override the test.
  2218         -else
  2219         -  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  2220         -  ac_dummy="$PATH"
  2221         -  for ac_dir in $ac_dummy; do
  2222         -    test -z "$ac_dir" && ac_dir=.
  2223         -    if test -f $ac_dir/$ac_word; then
  2224         -      ac_cv_prog_AR="ar"
  2225         -      break
  2226         -    fi
  2227         -  done
  2228         -  IFS="$ac_save_ifs"
  2229         -fi
  2230         -fi
  2231         -AR="$ac_cv_prog_AR"
  2232         -if test -n "$AR"; then
  2233         -  echo "$ac_t""$AR" 1>&6
  2234         -else
  2235         -  echo "$ac_t""no" 1>&6
  2236         -fi
  2237         -
  2238         -    STLIB_LD='${AR} cr'
  2239         -    case $system in
  2240         -	windows)
  2241         -	    # This is a 2-stage check to make sure we have the 64-bit SDK
  2242         -	    # We have to know where the SDK is installed.
  2243         -	    if test "$do64bit" = "yes" ; then
  2244         -		if test "x${MSSDK}x" = "xx" ; then
  2245         -		    MSSDK="C:/Progra~1/Microsoft SDK"
  2246         -		fi
  2247         -		# In order to work in the tortured autoconf environment,
  2248         -		# we need to ensure that this path has no spaces
  2249         -		MSSDK=`cygpath -w -s "$MSSDK" | sed -e 's!\\\!/!g'`
  2250         -		if test ! -d "${MSSDK}/bin/win64" ; then
  2251         -		    echo "configure: warning: "could not find 64-bit SDK to enable 64bit mode"" 1>&2
  2252         -		    do64bit="no"
  2253         -		else
  2254         -		    do64bit_ok="yes"
  2255         -		fi
  2256         -	    fi
  2257         -
  2258         -	    if test "${SHARED_BUILD}" = "0" ; then
  2259         -		runtime=-MT
  2260         -	    else
  2261         -		runtime=-MD
  2262         -	    fi
  2263         -
  2264         -	    if test "$do64bit" = "yes" ; then
  2265         -		# All this magic is necessary for the Win64 SDK RC1 - hobbs
  2266         -		export CC="${MSSDK}/Bin/Win64/cl.exe \
  2267         -	    -I${MSSDK}/Include/prerelease -I${MSSDK}/Include/Win64/crt \
  2268         -	    -I${MSSDK}/Include"
  2269         -		export RC="${MSSDK}/bin/rc.exe"
  2270         -		export lflags="-MACHINE:IA64 -LIBPATH:${MSSDK}/Lib/IA64 \
  2271         -	    -LIBPATH:${MSSDK}/Lib/Prerelease/IA64"
  2272         -		export STLIB_LD="${MSSDK}/bin/win64/lib.exe -nologo ${lflags}"
  2273         -		export LINKBIN="${MSSDK}/bin/win64/link.exe ${lflags}"
  2274         -		CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
  2275         -		CFLAGS_OPTIMIZE="-nologo -O2 -Gs -W2 ${runtime}"
  2276         -	    else
  2277         -		RC="rc"
  2278         -		STLIB_LD="lib -nologo"
  2279         -    		LINKBIN="link -link50compat"
  2280         -		CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
  2281         -		CFLAGS_OPTIMIZE="-nologo -O2 -Gs -GD -W2 ${runtime}"
  2282         -	    fi
  2283         -
  2284         -	    if test "$MINGW32" = "yes"; then
  2285         -		# mingw gcc mode
  2286         -		CFLAGS_DEBUG="-g"
  2287         -		CFLAGS_OPTIMIZE="-O2"
  2288         -		SHLIB_LD="gcc -shared"
  2289         -		STLIB_LD='${AR} cr'
  2290         -		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
  2291         -		LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
  2292         -		LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
  2293         -	    else
  2294         -		SHLIB_LD="${LINKBIN} -dll -nologo"
  2295         -		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.lib'
  2296         -		EXTRA_CFLAGS="-YX"
  2297         -		# For information on what debugtype is most useful, see:
  2298         -		# http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
  2299         -		# This essentially turns it all on.
  2300         -		LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
  2301         -		LDFLAGS_OPTIMIZE="-release"
  2302         -		LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
  2303         -		LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
  2304         -		PATHTYPE=-w
  2305         -	    fi
  2306         -
  2307         -	    SHLIB_LD_LIBS='${LIBS}'
  2308         -	    SHLIB_SUFFIX=".dll"
  2309         -	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.dll'
  2310         -
  2311         -	    TCL_LIB_VERSIONS_OK=nodots
  2312         -	    # Bogus to avoid getting this turned off
  2313         -	    DL_OBJS="tclLoadNone.obj"
  2314         -    	    ;;
  2315         -	AIX-*)
  2316         -	    if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
  2317         -		# AIX requires the _r compiler when gcc isn't being used
  2318         -		if test "${CC}" != "cc_r" ; then
  2319         -		    CC=${CC}_r
  2320         -		fi
  2321         -		echo "$ac_t""Using $CC for compiling with threads" 1>&6
  2322         -	    fi
  2323         -	    LIBS="$LIBS -lc"
  2324         -	    SHLIB_CFLAGS=""
  2325         -	    SHLIB_SUFFIX=".so"
  2326         -	    SHLIB_LD_LIBS='${LIBS}'
  2327         -	    if test "`uname -m`" = "ia64" ; then
  2328         -		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
  2329         -		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
  2330         -		# AIX-5 has dl* in libc.so
  2331         -		DL_LIBS=""
  2332         -		if test "$GCC" = "yes" ; then
  2333         -		    LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
  2334         -		else
  2335         -		    LD_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
  2336         -		fi
  2337         -	    else
  2338         -		SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
  2339         -		DL_LIBS="-ldl"
  2340         -		LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
  2341         -		TCL_NEEDS_EXP_FILE=1
  2342         -		TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.exp'
  2343         -	    fi
  2344         -	    DL_OBJS="tclLoadDl.o"
  2345         -	    LDFLAGS=""
  2346         -
  2347         -	    # AIX v<=4.1 has some different flags than 4.2+
  2348         -	    if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
  2349         -		LIBOBJS="$LIBOBJS tclLoadAix.o"
  2350         -		DL_LIBS="-lld"
  2351         -	    fi
  2352         -
  2353         -	    # On AIX <=v4 systems, libbsd.a has to be linked in to support
  2354         -	    # non-blocking file IO.  This library has to be linked in after
  2355         -	    # the MATH_LIBS or it breaks the pow() function.  The way to
  2356         -	    # insure proper sequencing, is to add it to the tail of MATH_LIBS.
  2357         -	    # This library also supplies gettimeofday.
  2358         -	    #
  2359         -	    # AIX does not have a timezone field in struct tm. When the AIX
  2360         -	    # bsd library is used, the timezone global and the gettimeofday
  2361         -	    # methods are to be avoided for timezone deduction instead, we
  2362         -	    # deduce the timezone by comparing the localtime result on a
  2363         -	    # known GMT value.
  2364         -
  2365         -	    echo $ac_n "checking for gettimeofday in -lbsd""... $ac_c" 1>&6
  2366         -echo "configure:2368: checking for gettimeofday in -lbsd" >&5
  2367         -ac_lib_var=`echo bsd'_'gettimeofday | sed 'y%./+-%__p_%'`
  2368         -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  2369         -  echo $ac_n "(cached) $ac_c" 1>&6
  2370         -else
  2371         -  ac_save_LIBS="$LIBS"
  2372         -LIBS="-lbsd  $LIBS"
  2373         -cat > conftest.$ac_ext <<EOF
  2374         -#line 2376 "configure"
  2375         -#include "confdefs.h"
  2376         -/* Override any gcc2 internal prototype to avoid an error.  */
  2377         -/* We use char because int might match the return type of a gcc2
  2378         -    builtin and then its argument prototype would still apply.  */
  2379         -char gettimeofday();
  2380         -
  2381         -int main() {
  2382         -gettimeofday()
  2383         -; return 0; }
  2384         -EOF
  2385         -if { (eval echo configure:2387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  2386         -  rm -rf conftest*
  2387         -  eval "ac_cv_lib_$ac_lib_var=yes"
  2388         -else
  2389         -  echo "configure: failed program was:" >&5
  2390         -  cat conftest.$ac_ext >&5
  2391         -  rm -rf conftest*
  2392         -  eval "ac_cv_lib_$ac_lib_var=no"
  2393         -fi
  2394         -rm -f conftest*
  2395         -LIBS="$ac_save_LIBS"
  2396         -
  2397         -fi
  2398         -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  2399         -  echo "$ac_t""yes" 1>&6
  2400         -  libbsd=yes
  2401         -else
  2402         -  echo "$ac_t""no" 1>&6
  2403         -libbsd=no
  2404         -fi
  2405         -
  2406         -	    if test $libbsd = yes; then
  2407         -	    	MATH_LIBS="$MATH_LIBS -lbsd"
  2408         -	    	cat >> confdefs.h <<\EOF
  2409         -#define USE_DELTA_FOR_TZ 1
  2410         -EOF
  2411         -
  2412         -	    fi
  2413         -
  2414         -	    # Check to enable 64-bit flags for compiler/linker on AIX 5+
  2415         -	    if test "$do64bit" = "yes" -a "`uname -v`" -gt "4" ; then
  2416         -		if test "$GCC" = "yes" ; then
  2417         -		    echo "configure: warning: "64bit mode not supported with GCC on $system"" 1>&2
  2418         -		else 
  2419         -		    do64bit_ok=yes
  2420         -		    EXTRA_CFLAGS="-q64"
  2421         -		    LDFLAGS="-q64"
  2422         -		fi
  2423         -	    fi
  2424         -	    ;;
  2425         -	BSD/OS-2.1*|BSD/OS-3*)
  2426         -	    SHLIB_CFLAGS=""
  2427         -	    SHLIB_LD="shlicc -r"
  2428         -	    SHLIB_LD_LIBS='${LIBS}'
  2429         -	    SHLIB_SUFFIX=".so"
  2430         -	    DL_OBJS="tclLoadDl.o"
  2431         -	    DL_LIBS="-ldl"
  2432         -	    LDFLAGS=""
  2433         -	    LD_SEARCH_FLAGS=""
  2434         -	    ;;
  2435         -	BSD/OS-4.*)
  2436         -	    SHLIB_CFLAGS="-export-dynamic -fPIC"
  2437         -	    SHLIB_LD="cc -shared"
  2438         -	    SHLIB_LD_LIBS='${LIBS}'
  2439         -	    SHLIB_SUFFIX=".so"
  2440         -	    DL_OBJS="tclLoadDl.o"
  2441         -	    DL_LIBS="-ldl"
  2442         -	    LDFLAGS="-export-dynamic"
  2443         -	    LD_SEARCH_FLAGS=""
  2444         -	    ;;
  2445         -	dgux*)
  2446         -	    SHLIB_CFLAGS="-K PIC"
  2447         -	    SHLIB_LD="cc -G"
  2448         -	    SHLIB_LD_LIBS=""
  2449         -	    SHLIB_SUFFIX=".so"
  2450         -	    DL_OBJS="tclLoadDl.o"
  2451         -	    DL_LIBS="-ldl"
  2452         -	    LDFLAGS=""
  2453         -	    LD_SEARCH_FLAGS=""
  2454         -	    ;;
  2455         -	HP-UX-*.11.*)
  2456         -	    # Use updated header definitions where possible
  2457         -	    cat >> confdefs.h <<\EOF
  2458         -#define _XOPEN_SOURCE_EXTENDED 1
  2459         -EOF
  2460         -
  2461         -
  2462         -	    SHLIB_SUFFIX=".sl"
  2463         -	    echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
  2464         -echo "configure:2466: checking for shl_load in -ldld" >&5
  2465         -ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
  2466         -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  2467         -  echo $ac_n "(cached) $ac_c" 1>&6
  2468         -else
  2469         -  ac_save_LIBS="$LIBS"
  2470         -LIBS="-ldld  $LIBS"
  2471         -cat > conftest.$ac_ext <<EOF
  2472         -#line 2474 "configure"
  2473         -#include "confdefs.h"
  2474         -/* Override any gcc2 internal prototype to avoid an error.  */
  2475         -/* We use char because int might match the return type of a gcc2
  2476         -    builtin and then its argument prototype would still apply.  */
  2477         -char shl_load();
  2478         -
  2479         -int main() {
  2480         -shl_load()
  2481         -; return 0; }
  2482         -EOF
  2483         -if { (eval echo configure:2485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  2484         -  rm -rf conftest*
  2485         -  eval "ac_cv_lib_$ac_lib_var=yes"
  2486         -else
  2487         -  echo "configure: failed program was:" >&5
  2488         -  cat conftest.$ac_ext >&5
  2489         -  rm -rf conftest*
  2490         -  eval "ac_cv_lib_$ac_lib_var=no"
  2491         -fi
  2492         -rm -f conftest*
  2493         -LIBS="$ac_save_LIBS"
  2494         -
  2495         -fi
  2496         -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  2497         -  echo "$ac_t""yes" 1>&6
  2498         -  tcl_ok=yes
  2499         -else
  2500         -  echo "$ac_t""no" 1>&6
  2501         -tcl_ok=no
  2502         -fi
  2503         -
  2504         -	    if test "$tcl_ok" = yes; then
  2505         -		SHLIB_CFLAGS="+z"
  2506         -		SHLIB_LD="ld -b"
  2507         -		SHLIB_LD_LIBS=""
  2508         -		DL_OBJS="tclLoadShl.o"
  2509         -		DL_LIBS="-ldld"
  2510         -		LDFLAGS="-Wl,-E"
  2511         -		LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
  2512         -	    fi
  2513         -
  2514         -	    # Check to enable 64-bit flags for compiler/linker
  2515         -	    if test "$do64bit" = "yes" ; then
  2516         -		if test "$GCC" = "yes" ; then
  2517         -		    echo "configure: warning: "64bit mode not supported with GCC on $system"" 1>&2
  2518         -		else
  2519         -		    do64bit_ok=yes
  2520         -		    EXTRA_CFLAGS="+DA2.0W"
  2521         -		    LDFLAGS="+DA2.0W $LDFLAGS"
  2522         -		fi
  2523         -	    fi
  2524         -	    ;;
  2525         -	HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
  2526         -	    SHLIB_SUFFIX=".sl"
  2527         -	    echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
  2528         -echo "configure:2530: checking for shl_load in -ldld" >&5
  2529         -ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
  2530         -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  2531         -  echo $ac_n "(cached) $ac_c" 1>&6
  2532         -else
  2533         -  ac_save_LIBS="$LIBS"
  2534         -LIBS="-ldld  $LIBS"
  2535         -cat > conftest.$ac_ext <<EOF
  2536         -#line 2538 "configure"
  2537         -#include "confdefs.h"
  2538         -/* Override any gcc2 internal prototype to avoid an error.  */
  2539         -/* We use char because int might match the return type of a gcc2
  2540         -    builtin and then its argument prototype would still apply.  */
  2541         -char shl_load();
  2542         -
  2543         -int main() {
  2544         -shl_load()
  2545         -; return 0; }
  2546         -EOF
  2547         -if { (eval echo configure:2549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  2548         -  rm -rf conftest*
  2549         -  eval "ac_cv_lib_$ac_lib_var=yes"
  2550         -else
  2551         -  echo "configure: failed program was:" >&5
  2552         -  cat conftest.$ac_ext >&5
  2553         -  rm -rf conftest*
  2554         -  eval "ac_cv_lib_$ac_lib_var=no"
  2555         -fi
  2556         -rm -f conftest*
  2557         -LIBS="$ac_save_LIBS"
  2558         -
  2559         -fi
  2560         -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  2561         -  echo "$ac_t""yes" 1>&6
  2562         -  tcl_ok=yes
  2563         -else
  2564         -  echo "$ac_t""no" 1>&6
  2565         -tcl_ok=no
  2566         -fi
  2567         -
  2568         -	    if test "$tcl_ok" = yes; then
  2569         -		SHLIB_CFLAGS="+z"
  2570         -		SHLIB_LD="ld -b"
  2571         -		SHLIB_LD_LIBS=""
  2572         -		DL_OBJS="tclLoadShl.o"
  2573         -		DL_LIBS="-ldld"
  2574         -		LDFLAGS="-Wl,-E"
  2575         -		LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
  2576         -	    fi
  2577         -	    ;;
  2578         -	IRIX-4.*)
  2579         -	    SHLIB_CFLAGS="-G 0"
  2580         -	    SHLIB_SUFFIX=".a"
  2581         -	    SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
  2582         -	    SHLIB_LD_LIBS='${LIBS}'
  2583         -	    DL_OBJS="tclLoadAout.o"
  2584         -	    DL_LIBS=""
  2585         -	    LDFLAGS="-Wl,-D,08000000"
  2586         -	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
  2587         -	    SHARED_LIB_SUFFIX='${VERSION}\$\{DBGX\}.a'
  2588         -	    ;;
  2589         -	IRIX-5.*)
  2590         -	    SHLIB_CFLAGS=""
  2591         -	    SHLIB_LD="ld -shared -rdata_shared"
  2592         -	    SHLIB_LD_LIBS='${LIBS}'
  2593         -	    SHLIB_SUFFIX=".so"
  2594         -	    DL_OBJS="tclLoadDl.o"
  2595         -	    DL_LIBS=""
  2596         -	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  2597         -	    EXTRA_CFLAGS=""
  2598         -	    LDFLAGS=""
  2599         -	    ;;
  2600         -	IRIX-6.*|IRIX64-6.5*)
  2601         -	    SHLIB_CFLAGS=""
  2602         -	    SHLIB_LD="ld -n32 -shared -rdata_shared"
  2603         -	    SHLIB_LD_LIBS='${LIBS}'
  2604         -	    SHLIB_SUFFIX=".so"
  2605         -	    DL_OBJS="tclLoadDl.o"
  2606         -	    DL_LIBS=""
  2607         -	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  2608         -	    if test "$GCC" = "yes" ; then
  2609         -		EXTRA_CFLAGS="-mabi=n32"
  2610         -		LDFLAGS="-mabi=n32"
  2611         -	    else
  2612         -		case $system in
  2613         -		    IRIX-6.3)
  2614         -			# Use to build 6.2 compatible binaries on 6.3.
  2615         -			EXTRA_CFLAGS="-n32 -D_OLD_TERMIOS"
  2616         -			;;
  2617         -		    *)
  2618         -			EXTRA_CFLAGS="-n32"
  2619         -			;;
  2620         -		esac
  2621         -		LDFLAGS="-n32"
  2622         -	    fi
  2623         -	    ;;
  2624         -	IRIX64-6.*)
  2625         -	    SHLIB_CFLAGS=""
  2626         -	    SHLIB_LD="ld -n32 -shared -rdata_shared"
  2627         -	    SHLIB_LD_LIBS='${LIBS}'
  2628         -	    SHLIB_SUFFIX=".so"
  2629         -	    DL_OBJS="tclLoadDl.o"
  2630         -	    DL_LIBS=""
  2631         -	    LDFLAGS=""
  2632         -	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  2633         -	    ;;
  2634         -	Linux*)
  2635         -	    SHLIB_CFLAGS="-fPIC"
  2636         -	    SHLIB_LD_LIBS='${LIBS}'
  2637         -	    SHLIB_SUFFIX=".so"
  2638         -
  2639         -	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings 
  2640         -	    # when you inline the string and math operations.  Turn this off to
  2641         -	    # get rid of the warnings.
  2642         -
  2643         -	    CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
  2644         -
  2645         -	    if test "$have_dl" = yes; then
  2646         -		SHLIB_LD="${CC} -shared"
  2647         -		DL_OBJS="tclLoadDl.o"
  2648         -		DL_LIBS="-ldl"
  2649         -		LDFLAGS="-rdynamic"
  2650         -		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  2651         -	    else
  2652         -		ac_safe=`echo "dld.h" | sed 'y%./+-%__p_%'`
  2653         -echo $ac_n "checking for dld.h""... $ac_c" 1>&6
  2654         -echo "configure:2656: checking for dld.h" >&5
  2655         -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
  2656         -  echo $ac_n "(cached) $ac_c" 1>&6
  2657         -else
  2658         -  cat > conftest.$ac_ext <<EOF
  2659         -#line 2661 "configure"
  2660         -#include "confdefs.h"
  2661         -#include <dld.h>
  2662         -EOF
  2663         -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
  2664         -{ (eval echo configure:2666: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
  2665         -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
  2666         -if test -z "$ac_err"; then
  2667         -  rm -rf conftest*
  2668         -  eval "ac_cv_header_$ac_safe=yes"
  2669         -else
  2670         -  echo "$ac_err" >&5
  2671         -  echo "configure: failed program was:" >&5
  2672         -  cat conftest.$ac_ext >&5
  2673         -  rm -rf conftest*
  2674         -  eval "ac_cv_header_$ac_safe=no"
  2675         -fi
  2676         -rm -f conftest*
  2677         -fi
  2678         -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
  2679         -  echo "$ac_t""yes" 1>&6
  2680         -  
  2681         -		    SHLIB_LD="ld -shared"
  2682         -		    DL_OBJS="tclLoadDld.o"
  2683         -		    DL_LIBS="-ldld"
  2684         -		    LDFLAGS=""
  2685         -		    LD_SEARCH_FLAGS=""
  2686         -else
  2687         -  echo "$ac_t""no" 1>&6
  2688         -fi
  2689         -
  2690         -	    fi
  2691         -	    if test "`uname -m`" = "alpha" ; then
  2692         -		EXTRA_CFLAGS="-mieee"
  2693         -	    fi
  2694         -
  2695         -	    # The combo of gcc + glibc has a bug related
  2696         -	    # to inlining of functions like strtod(). The
  2697         -	    # -fno-builtin flag should address this problem
  2698         -	    # but it does not work. The -fno-inline flag
  2699         -	    # is kind of overkill but it works.
  2700         -	    # Disable inlining only when one of the
  2701         -	    # files in compat/*.c is being linked in.
  2702         -	    if test x"${LIBOBJS}" != x ; then
  2703         -	        EXTRA_CFLAGS="${EXTRA_CFLAGS} -fno-inline"
  2704         -	    fi
  2705         -
  2706         -	    ;;
  2707         -	GNU*)
  2708         -	    SHLIB_CFLAGS="-fPIC"
  2709         -	    SHLIB_LD_LIBS='${LIBS}'
  2710         -	    SHLIB_SUFFIX=".so"
  2711         -
  2712         -	    if test "$have_dl" = yes; then
  2713         -		SHLIB_LD="${CC} -shared"
  2714         -		DL_OBJS=""
  2715         -		DL_LIBS="-ldl"
  2716         -		LDFLAGS="-rdynamic"
  2717         -		LD_SEARCH_FLAGS=""
  2718         -	    else
  2719         -		ac_safe=`echo "dld.h" | sed 'y%./+-%__p_%'`
  2720         -echo $ac_n "checking for dld.h""... $ac_c" 1>&6
  2721         -echo "configure:2723: checking for dld.h" >&5
  2722         -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
  2723         -  echo $ac_n "(cached) $ac_c" 1>&6
  2724         -else
  2725         -  cat > conftest.$ac_ext <<EOF
  2726         -#line 2728 "configure"
  2727         -#include "confdefs.h"
  2728         -#include <dld.h>
  2729         -EOF
  2730         -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
  2731         -{ (eval echo configure:2733: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
  2732         -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
  2733         -if test -z "$ac_err"; then
  2734         -  rm -rf conftest*
  2735         -  eval "ac_cv_header_$ac_safe=yes"
  2736         -else
  2737         -  echo "$ac_err" >&5
  2738         -  echo "configure: failed program was:" >&5
  2739         -  cat conftest.$ac_ext >&5
  2740         -  rm -rf conftest*
  2741         -  eval "ac_cv_header_$ac_safe=no"
  2742         -fi
  2743         -rm -f conftest*
  2744         -fi
  2745         -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
  2746         -  echo "$ac_t""yes" 1>&6
  2747         -  
  2748         -		    SHLIB_LD="ld -shared"
  2749         -		    DL_OBJS=""
  2750         -		    DL_LIBS="-ldld"
  2751         -		    LDFLAGS=""
  2752         -		    LD_SEARCH_FLAGS=""
  2753         -else
  2754         -  echo "$ac_t""no" 1>&6
  2755         -fi
  2756         -
  2757         -	    fi
  2758         -	    if test "`uname -m`" = "alpha" ; then
  2759         -		EXTRA_CFLAGS="-mieee"
  2760         -	    fi
  2761         -	    ;;
  2762         -	MP-RAS-02*)
  2763         -	    SHLIB_CFLAGS="-K PIC"
  2764         -	    SHLIB_LD="cc -G"
  2765         -	    SHLIB_LD_LIBS=""
  2766         -	    SHLIB_SUFFIX=".so"
  2767         -	    DL_OBJS="tclLoadDl.o"
  2768         -	    DL_LIBS="-ldl"
  2769         -	    LDFLAGS=""
  2770         -	    LD_SEARCH_FLAGS=""
  2771         -	    ;;
  2772         -	MP-RAS-*)
  2773         -	    SHLIB_CFLAGS="-K PIC"
  2774         -	    SHLIB_LD="cc -G"
  2775         -	    SHLIB_LD_LIBS=""
  2776         -	    SHLIB_SUFFIX=".so"
  2777         -	    DL_OBJS="tclLoadDl.o"
  2778         -	    DL_LIBS="-ldl"
  2779         -	    LDFLAGS="-Wl,-Bexport"
  2780         -	    LD_SEARCH_FLAGS=""
  2781         -	    ;;
  2782         -	NetBSD-*|FreeBSD-[1-2].*|OpenBSD-*)
  2783         -	    # Not available on all versions:  check for include file.
  2784         -	    ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'`
  2785         -echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6
  2786         -echo "configure:2788: checking for dlfcn.h" >&5
  2787         -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
  2788         -  echo $ac_n "(cached) $ac_c" 1>&6
  2789         -else
  2790         -  cat > conftest.$ac_ext <<EOF
  2791         -#line 2793 "configure"
  2792         -#include "confdefs.h"
  2793         -#include <dlfcn.h>
  2794         -EOF
  2795         -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
  2796         -{ (eval echo configure:2798: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
  2797         -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
  2798         -if test -z "$ac_err"; then
  2799         -  rm -rf conftest*
  2800         -  eval "ac_cv_header_$ac_safe=yes"
  2801         -else
  2802         -  echo "$ac_err" >&5
  2803         -  echo "configure: failed program was:" >&5
  2804         -  cat conftest.$ac_ext >&5
  2805         -  rm -rf conftest*
  2806         -  eval "ac_cv_header_$ac_safe=no"
  2807         -fi
  2808         -rm -f conftest*
  2809         -fi
  2810         -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
  2811         -  echo "$ac_t""yes" 1>&6
  2812         -  
  2813         -		# NetBSD/SPARC needs -fPIC, -fpic will not do.
  2814         -		SHLIB_CFLAGS="-fPIC"
  2815         -		SHLIB_LD="ld -Bshareable -x"
  2816         -		SHLIB_LD_LIBS=""
  2817         -		SHLIB_SUFFIX=".so"
  2818         -		DL_OBJS="tclLoadDl.o"
  2819         -		DL_LIBS=""
  2820         -		LDFLAGS=""
  2821         -		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  2822         -		echo $ac_n "checking for ELF""... $ac_c" 1>&6
  2823         -echo "configure:2825: checking for ELF" >&5
  2824         -		cat > conftest.$ac_ext <<EOF
  2825         -#line 2827 "configure"
  2826         -#include "confdefs.h"
  2827         -
  2828         -#ifdef __ELF__
  2829         -	yes
  2830         -#endif
  2831         -		
  2832         -EOF
  2833         -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  2834         -  egrep "yes" >/dev/null 2>&1; then
  2835         -  rm -rf conftest*
  2836         -  echo "$ac_t""yes" 1>&6
  2837         -		    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so'
  2838         -else
  2839         -  rm -rf conftest*
  2840         -  echo "$ac_t""no" 1>&6
  2841         -		    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1.0'
  2842         -		
  2843         -fi
  2844         -rm -f conftest*
  2845         -
  2846         -	    
  2847         -else
  2848         -  echo "$ac_t""no" 1>&6
  2849         -
  2850         -		SHLIB_CFLAGS=""
  2851         -		SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r"
  2852         -		SHLIB_LD_LIBS='${LIBS}'
  2853         -		SHLIB_SUFFIX=".a"
  2854         -		DL_OBJS="tclLoadAout.o"
  2855         -		DL_LIBS=""
  2856         -		LDFLAGS=""
  2857         -		LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
  2858         -		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
  2859         -	    
  2860         -fi
  2861         -
  2862         -
  2863         -	    # FreeBSD doesn't handle version numbers with dots.
  2864         -
  2865         -	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
  2866         -	    TCL_LIB_VERSIONS_OK=nodots
  2867         -	    ;;
  2868         -	FreeBSD-*)
  2869         -	    # FreeBSD 3.* and greater have ELF.
  2870         -	    SHLIB_CFLAGS="-fPIC"
  2871         -	    SHLIB_LD="ld -Bshareable -x"
  2872         -	    SHLIB_LD_LIBS='${LIBS}'
  2873         -	    SHLIB_SUFFIX=".so"
  2874         -	    DL_OBJS="tclLoadDl.o"
  2875         -	    DL_LIBS=""
  2876         -	    LDFLAGS="-export-dynamic"
  2877         -	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  2878         -	    if test "${TCL_THREADS}" = "1" ; then
  2879         -		EXTRA_CFLAGS="-pthread"
  2880         -	    	LDFLAGS="$LDFLAGS -pthread"
  2881         -	    fi
  2882         -	    case $system in
  2883         -	    FreeBSD-3.*)
  2884         -	    	# FreeBSD-3 doesn't handle version numbers with dots.
  2885         -	    	UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
  2886         -	    	SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so'
  2887         -	    	TCL_LIB_VERSIONS_OK=nodots
  2888         -		;;
  2889         -	    esac
  2890         -	    ;;
  2891         -	Rhapsody-*|Darwin-*)
  2892         -	    SHLIB_CFLAGS="-fno-common"
  2893         -	    SHLIB_LD="cc -dynamiclib \${LDFLAGS}"
  2894         -	    TCL_SHLIB_LD_EXTRAS="-compatibility_version ${TCL_MAJOR_VERSION} -current_version \${VERSION} -install_name \${LIB_RUNTIME_DIR}/\${TCL_LIB_FILE} -prebind -seg1addr a000000"
  2895         -	    SHLIB_LD_LIBS='${LIBS}'
  2896         -	    SHLIB_SUFFIX=".dylib"
  2897         -	    DL_OBJS="tclLoadDyld.o"
  2898         -	    DL_LIBS=""
  2899         -	    LDFLAGS="-prebind"
  2900         -	    LD_SEARCH_FLAGS=""
  2901         -	    CFLAGS_OPTIMIZE="-O3"
  2902         -	    EXTRA_CFLAGS="-arch ppc -pipe"
  2903         -	    ;;
  2904         -	NEXTSTEP-*)
  2905         -	    SHLIB_CFLAGS=""
  2906         -	    SHLIB_LD="cc -nostdlib -r"
  2907         -	    SHLIB_LD_LIBS=""
  2908         -	    SHLIB_SUFFIX=".so"
  2909         -	    DL_OBJS="tclLoadNext.o"
  2910         -	    DL_LIBS=""
  2911         -	    LDFLAGS=""
  2912         -	    LD_SEARCH_FLAGS=""
  2913         -	    ;;
  2914         -	OS/390-*)
  2915         -	    CFLAGS_OPTIMIZE=""      # Optimizer is buggy
  2916         -	    cat >> confdefs.h <<\EOF
  2917         -#define _OE_SOCKETS 1
  2918         -EOF
  2919         -  # needed in sys/socket.h
  2920         -	    ;;      
  2921         -	OSF1-1.0|OSF1-1.1|OSF1-1.2)
  2922         -	    # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
  2923         -	    SHLIB_CFLAGS=""
  2924         -	    # Hack: make package name same as library name
  2925         -	    SHLIB_LD='ld -R -export :'
  2926         -	    SHLIB_LD_LIBS=""
  2927         -	    SHLIB_SUFFIX=".so"
  2928         -	    DL_OBJS="tclLoadOSF.o"
  2929         -	    DL_LIBS=""
  2930         -	    LDFLAGS=""
  2931         -	    LD_SEARCH_FLAGS=""
  2932         -	    ;;
  2933         -	OSF1-1.*)
  2934         -	    # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
  2935         -	    SHLIB_CFLAGS="-fPIC"
  2936         -	    SHLIB_LD="ld -shared"
  2937         -	    SHLIB_LD_LIBS=""
  2938         -	    SHLIB_SUFFIX=".so"
  2939         -	    DL_OBJS="tclLoadDl.o"
  2940         -	    DL_LIBS=""
  2941         -	    LDFLAGS=""
  2942         -	    LD_SEARCH_FLAGS=""
  2943         -	    ;;
  2944         -	OSF1-V*)
  2945         -	    # Digital OSF/1
  2946         -	    SHLIB_CFLAGS=""
  2947         -	    SHLIB_LD='ld -shared -expect_unresolved "*"'
  2948         -	    SHLIB_LD_LIBS=""
  2949         -	    SHLIB_SUFFIX=".so"
  2950         -	    DL_OBJS="tclLoadDl.o"
  2951         -	    DL_LIBS=""
  2952         -	    LDFLAGS=""
  2953         -	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  2954         -	    if test "$GCC" != "yes" ; then
  2955         -		EXTRA_CFLAGS="-DHAVE_TZSET -std1"
  2956         -	    fi
  2957         -	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
  2958         -	    if test "${TCL_THREADS}" = "1" ; then
  2959         -		EXTRA_CFLAGS="${EXTRA_CFLAGS} -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
  2960         -		EXTRA_CFLAGS="${EXTRA_CFLAGS} -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
  2961         -		LIBS=`echo $LIBS | sed s/-lpthreads//`
  2962         -		if test "$GCC" = "yes" ; then
  2963         -		    LIBS="$LIBS -lpthread -lmach -lexc"
  2964         -		else
  2965         -		    EXTRA_CFLAGS="${EXTRA_CFLAGS} -pthread"
  2966         -		    LDFLAGS="-pthread"
  2967         -		fi
  2968         -	    fi
  2969         -
  2970         -	    ;;
  2971         -	QNX-6*)
  2972         -	    # QNX RTP
  2973         -	    # This may work for all QNX, but it was only reported for v6.
  2974         -	    SHLIB_CFLAGS="-fPIC"
  2975         -	    SHLIB_LD="ld -Bshareable -x"
  2976         -	    SHLIB_LD_LIBS=""
  2977         -	    SHLIB_SUFFIX=".so"
  2978         -	    DL_OBJS="tclLoadDl.o"
  2979         -	    # dlopen is in -lc on QNX
  2980         -	    DL_LIBS=""
  2981         -	    LDFLAGS=""
  2982         -	    LD_SEARCH_FLAGS=""
  2983         -	    ;;
  2984         -	RISCos-*)
  2985         -	    SHLIB_CFLAGS="-G 0"
  2986         -	    SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
  2987         -	    SHLIB_LD_LIBS='${LIBS}'
  2988         -	    SHLIB_SUFFIX=".a"
  2989         -	    DL_OBJS="tclLoadAout.o"
  2990         -	    DL_LIBS=""
  2991         -	    LDFLAGS="-Wl,-D,08000000"
  2992         -	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
  2993         -	    ;;
  2994         -	SCO_SV-3.2*)
  2995         -	    # Note, dlopen is available only on SCO 3.2.5 and greater. However,
  2996         -	    # this test works, since "uname -s" was non-standard in 3.2.4 and
  2997         -	    # below.
  2998         -	    if test "$GCC" = "yes" ; then
  2999         -	    	SHLIB_CFLAGS="-fPIC -melf"
  3000         -	    	LDFLAGS="-melf -Wl,-Bexport"
  3001         -	    else
  3002         -	    	SHLIB_CFLAGS="-Kpic -belf"
  3003         -	    	LDFLAGS="-belf -Wl,-Bexport"
  3004         -	    fi
  3005         -	    SHLIB_LD="ld -G"
  3006         -	    SHLIB_LD_LIBS=""
  3007         -	    SHLIB_SUFFIX=".so"
  3008         -	    DL_OBJS="tclLoadDl.o"
  3009         -	    DL_LIBS=""
  3010         -	    LD_SEARCH_FLAGS=""
  3011         -	    ;;
  3012         -	SINIX*5.4*)
  3013         -	    SHLIB_CFLAGS="-K PIC"
  3014         -	    SHLIB_LD="cc -G"
  3015         -	    SHLIB_LD_LIBS=""
  3016         -	    SHLIB_SUFFIX=".so"
  3017         -	    DL_OBJS="tclLoadDl.o"
  3018         -	    DL_LIBS="-ldl"
  3019         -	    LDFLAGS=""
  3020         -	    LD_SEARCH_FLAGS=""
  3021         -	    ;;
  3022         -	SunOS-4*)
  3023         -	    SHLIB_CFLAGS="-PIC"
  3024         -	    SHLIB_LD="ld"
  3025         -	    SHLIB_LD_LIBS=""
  3026         -	    SHLIB_SUFFIX=".so"
  3027         -	    DL_OBJS="tclLoadDl.o"
  3028         -	    DL_LIBS="-ldl"
  3029         -	    LDFLAGS=""
  3030         -	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
  3031         -
  3032         -	    # SunOS can't handle version numbers with dots in them in library
  3033         -	    # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
  3034         -	    # requires an extra version number at the end of .so file names.
  3035         -	    # So, the library has to have a name like libtcl75.so.1.0
  3036         -
  3037         -	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1.0'
  3038         -	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
  3039         -	    TCL_LIB_VERSIONS_OK=nodots
  3040         -	    ;;
  3041         -	SunOS-5.[0-6]*)
  3042         -
  3043         -	    # Note: If _REENTRANT isn't defined, then Solaris
  3044         -	    # won't define thread-safe library routines.
  3045         -
  3046         -	    cat >> confdefs.h <<\EOF
  3047         -#define _REENTRANT 1
  3048         -EOF
  3049         -
  3050         -	    cat >> confdefs.h <<\EOF
  3051         -#define _POSIX_PTHREAD_SEMANTICS 1
  3052         -EOF
  3053         -
  3054         -
  3055         -	    SHLIB_CFLAGS="-KPIC"
  3056         -	    SHLIB_LD="/usr/ccs/bin/ld -G -z text"
  3057         -
  3058         -	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
  3059         -	    # symbols when dynamically loaded into tclsh.
  3060         -
  3061         -	    SHLIB_LD_LIBS='${LIBS}'
  3062         -	    SHLIB_SUFFIX=".so"
  3063         -	    DL_OBJS="tclLoadDl.o"
  3064         -	    DL_LIBS="-ldl"
  3065         -	    LDFLAGS=""
  3066         -	    if test "$GCC" = "yes" ; then
  3067         -		LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
  3068         -	    else
  3069         -		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
  3070         -	    fi
  3071         -	    ;;
  3072         -	SunOS-5*)
  3073         -
  3074         -	    # Note: If _REENTRANT isn't defined, then Solaris
  3075         -	    # won't define thread-safe library routines.
  3076         -
  3077         -	    cat >> confdefs.h <<\EOF
  3078         -#define _REENTRANT 1
  3079         -EOF
  3080         -
  3081         -	    cat >> confdefs.h <<\EOF
  3082         -#define _POSIX_PTHREAD_SEMANTICS 1
  3083         -EOF
  3084         -
  3085         -
  3086         -	    SHLIB_CFLAGS="-KPIC"
  3087         -	    SHLIB_LD="/usr/ccs/bin/ld -G -z text"
  3088         -	    LDFLAGS=""
  3089         -    
  3090         -	    # Check to enable 64-bit flags for compiler/linker
  3091         -	    if test "$do64bit" = "yes" ; then
  3092         -		arch=`isainfo`
  3093         -		if test "$arch" = "sparcv9 sparc" ; then
  3094         -			if test "$GCC" = "yes" ; then
  3095         -			    echo "configure: warning: "64bit mode not supported with GCC on $system"" 1>&2
  3096         -			else
  3097         -			    do64bit_ok=yes
  3098         -			    if test "$do64bitVIS" = "yes" ; then
  3099         -				EXTRA_CFLAGS="-xarch=v9a"
  3100         -			    	LDFLAGS="-xarch=v9a"
  3101         -			    else
  3102         -				EXTRA_CFLAGS="-xarch=v9"
  3103         -			    	LDFLAGS="-xarch=v9"
  3104         -			    fi
  3105         -			fi
  3106         -		else
  3107         -		    echo "configure: warning: "64bit mode only supported sparcv9 system"" 1>&2
  3108         -		fi
  3109         -	    fi
  3110         -	    
  3111         -	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
  3112         -	    # symbols when dynamically loaded into tclsh.
  3113         -
  3114         -	    SHLIB_LD_LIBS='${LIBS}'
  3115         -	    SHLIB_SUFFIX=".so"
  3116         -	    DL_OBJS="tclLoadDl.o"
  3117         -	    DL_LIBS="-ldl"
  3118         -	    if test "$GCC" = "yes" ; then
  3119         -		LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
  3120         -	    else
  3121         -		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
  3122         -	    fi
  3123         -	    ;;
  3124         -	ULTRIX-4.*)
  3125         -	    SHLIB_CFLAGS="-G 0"
  3126         -	    SHLIB_SUFFIX=".a"
  3127         -	    SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
  3128         -	    SHLIB_LD_LIBS='${LIBS}'
  3129         -	    DL_OBJS="tclLoadAout.o"
  3130         -	    DL_LIBS=""
  3131         -	    LDFLAGS="-Wl,-D,08000000"
  3132         -	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
  3133         -	    if test "$GCC" != "yes" ; then
  3134         -		EXTRA_CFLAGS="-DHAVE_TZSET -std1"
  3135         -	    fi
  3136         -	    ;;
  3137         -	UNIX_SV* | UnixWare-5*)
  3138         -	    SHLIB_CFLAGS="-KPIC"
  3139         -	    SHLIB_LD="cc -G"
  3140         -	    SHLIB_LD_LIBS=""
  3141         -	    SHLIB_SUFFIX=".so"
  3142         -	    DL_OBJS="tclLoadDl.o"
  3143         -	    DL_LIBS="-ldl"
  3144         -	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
  3145         -	    # that don't grok the -Bexport option.  Test that it does.
  3146         -	    hold_ldflags=$LDFLAGS
  3147         -	    echo $ac_n "checking for ld accepts -Bexport flag""... $ac_c" 1>&6
  3148         -echo "configure:3150: checking for ld accepts -Bexport flag" >&5
  3149         -	    LDFLAGS="${LDFLAGS} -Wl,-Bexport"
  3150         -	    cat > conftest.$ac_ext <<EOF
  3151         -#line 3153 "configure"
  3152         -#include "confdefs.h"
  3153         -
  3154         -int main() {
  3155         -int i;
  3156         -; return 0; }
  3157         -EOF
  3158         -if { (eval echo configure:3160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  3159         -  rm -rf conftest*
  3160         -  found=yes
  3161         -else
  3162         -  echo "configure: failed program was:" >&5
  3163         -  cat conftest.$ac_ext >&5
  3164         -  rm -rf conftest*
  3165         -  found=no
  3166         -fi
  3167         -rm -f conftest*
  3168         -	    LDFLAGS=$hold_ldflags
  3169         -	    echo "$ac_t""$found" 1>&6
  3170         -	    if test $found = yes; then
  3171         -	    LDFLAGS="-Wl,-Bexport"
  3172         -	    else
  3173         -	    LDFLAGS=""
  3174         -	    fi
  3175         -	    LD_SEARCH_FLAGS=""
  3176         -	    ;;
  3177         -    esac
  3178         -
  3179         -    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
  3180         -    echo "configure: warning: "64bit support being disabled -- don\'t know magic for this platform"" 1>&2
  3181         -    fi
  3182         -
  3183         -    # Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic
  3184         -    # Loading for Tcl -- What Became of It?".  Proc. 2nd Tcl/Tk Workshop,
  3185         -    # New Orleans, LA, Computerized Processes Unlimited, 1994), then we need
  3186         -    # to determine which of several header files defines the a.out file
  3187         -    # format (a.out.h, sys/exec.h, or sys/exec_aout.h).  At present, we
  3188         -    # support only a file format that is more or less version-7-compatible. 
  3189         -    # In particular,
  3190         -    #	- a.out files must begin with `struct exec'.
  3191         -    #	- the N_TXTOFF on the `struct exec' must compute the seek address
  3192         -    #	  of the text segment
  3193         -    #	- The `struct exec' must contain a_magic, a_text, a_data, a_bss
  3194         -    #	  and a_entry fields.
  3195         -    # The following compilation should succeed if and only if either sys/exec.h
  3196         -    # or a.out.h is usable for the purpose.
  3197         -    #
  3198         -    # Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the
  3199         -    # `struct exec' includes a second header that contains information that
  3200         -    # duplicates the v7 fields that are needed.
  3201         -
  3202         -    if test "x$DL_OBJS" = "xtclLoadAout.o" ; then
  3203         -	echo $ac_n "checking sys/exec.h""... $ac_c" 1>&6
  3204         -echo "configure:3206: checking sys/exec.h" >&5
  3205         -	cat > conftest.$ac_ext <<EOF
  3206         -#line 3208 "configure"
  3207         -#include "confdefs.h"
  3208         -#include <sys/exec.h>
  3209         -int main() {
  3210         -
  3211         -	    struct exec foo;
  3212         -	    unsigned long seek;
  3213         -	    int flag;
  3214         -#if defined(__mips) || defined(mips)
  3215         -	    seek = N_TXTOFF (foo.ex_f, foo.ex_o);
  3216         -#else
  3217         -	    seek = N_TXTOFF (foo);
  3218         -#endif
  3219         -	    flag = (foo.a_magic == OMAGIC);
  3220         -	    return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
  3221         -    
  3222         -; return 0; }
  3223         -EOF
  3224         -if { (eval echo configure:3226: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  3225         -  rm -rf conftest*
  3226         -  tcl_ok=usable
  3227         -else
  3228         -  echo "configure: failed program was:" >&5
  3229         -  cat conftest.$ac_ext >&5
  3230         -  rm -rf conftest*
  3231         -  tcl_ok=unusable
  3232         -fi
  3233         -rm -f conftest*
  3234         -	echo "$ac_t""$tcl_ok" 1>&6
  3235         -	if test $tcl_ok = usable; then
  3236         -	    cat >> confdefs.h <<\EOF
  3237         -#define USE_SYS_EXEC_H 1
  3238         -EOF
  3239         -
  3240         -	else
  3241         -	    echo $ac_n "checking a.out.h""... $ac_c" 1>&6
  3242         -echo "configure:3244: checking a.out.h" >&5
  3243         -	    cat > conftest.$ac_ext <<EOF
  3244         -#line 3246 "configure"
  3245         -#include "confdefs.h"
  3246         -#include <a.out.h>
  3247         -int main() {
  3248         -
  3249         -		struct exec foo;
  3250         -		unsigned long seek;
  3251         -		int flag;
  3252         -#if defined(__mips) || defined(mips)
  3253         -		seek = N_TXTOFF (foo.ex_f, foo.ex_o);
  3254         -#else
  3255         -		seek = N_TXTOFF (foo);
  3256         -#endif
  3257         -		flag = (foo.a_magic == OMAGIC);
  3258         -		return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
  3259         -	    
  3260         -; return 0; }
  3261         -EOF
  3262         -if { (eval echo configure:3264: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  3263         -  rm -rf conftest*
  3264         -  tcl_ok=usable
  3265         -else
  3266         -  echo "configure: failed program was:" >&5
  3267         -  cat conftest.$ac_ext >&5
  3268         -  rm -rf conftest*
  3269         -  tcl_ok=unusable
  3270         -fi
  3271         -rm -f conftest*
  3272         -	    echo "$ac_t""$tcl_ok" 1>&6
  3273         -	    if test $tcl_ok = usable; then
  3274         -		cat >> confdefs.h <<\EOF
  3275         -#define USE_A_OUT_H 1
  3276         -EOF
  3277         -
  3278         -	    else
  3279         -		echo $ac_n "checking sys/exec_aout.h""... $ac_c" 1>&6
  3280         -echo "configure:3282: checking sys/exec_aout.h" >&5
  3281         -		cat > conftest.$ac_ext <<EOF
  3282         -#line 3284 "configure"
  3283         -#include "confdefs.h"
  3284         -#include <sys/exec_aout.h>
  3285         -int main() {
  3286         -
  3287         -		    struct exec foo;
  3288         -		    unsigned long seek;
  3289         -		    int flag;
  3290         -#if defined(__mips) || defined(mips)
  3291         -		    seek = N_TXTOFF (foo.ex_f, foo.ex_o);
  3292         -#else
  3293         -		    seek = N_TXTOFF (foo);
  3294         -#endif
  3295         -		    flag = (foo.a_midmag == OMAGIC);
  3296         -		    return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
  3297         -		
  3298         -; return 0; }
  3299         -EOF
  3300         -if { (eval echo configure:3302: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  3301         -  rm -rf conftest*
  3302         -  tcl_ok=usable
  3303         -else
  3304         -  echo "configure: failed program was:" >&5
  3305         -  cat conftest.$ac_ext >&5
  3306         -  rm -rf conftest*
  3307         -  tcl_ok=unusable
  3308         -fi
  3309         -rm -f conftest*
  3310         -		echo "$ac_t""$tcl_ok" 1>&6
  3311         -		if test $tcl_ok = usable; then
  3312         -		    cat >> confdefs.h <<\EOF
  3313         -#define USE_SYS_EXEC_AOUT_H 1
  3314         -EOF
  3315         -
  3316         -		else
  3317         -		    DL_OBJS=""
  3318         -		fi
  3319         -	    fi
  3320         -	fi
  3321         -    fi
  3322         -
  3323         -    # Step 5: disable dynamic loading if requested via a command-line switch.
  3324         -
  3325         -    # Check whether --enable-load or --disable-load was given.
  3326         -if test "${enable_load+set}" = set; then
  3327         -  enableval="$enable_load"
  3328         -  tcl_ok=$enableval
  3329         -else
  3330         -  tcl_ok=yes
  3331         -fi
  3332         -
  3333         -    if test "$tcl_ok" = "no"; then
  3334         -	DL_OBJS=""
  3335         -    fi
  3336         -
  3337         -    if test "x$DL_OBJS" != "x" ; then
  3338         -	BUILD_DLTEST="\$(DLTEST_TARGETS)"
  3339         -    else
  3340         -	echo "Can't figure out how to do dynamic loading or shared libraries"
  3341         -	echo "on this system."
  3342         -	SHLIB_CFLAGS=""
  3343         -	SHLIB_LD=""
  3344         -	SHLIB_SUFFIX=""
  3345         -	DL_OBJS="tclLoadNone.o"
  3346         -	DL_LIBS=""
  3347         -	LDFLAGS=""
  3348         -	LD_SEARCH_FLAGS=""
  3349         -	BUILD_DLTEST=""
  3350         -    fi
  3351         -
  3352         -    # If we're running gcc, then change the C flags for compiling shared
  3353         -    # libraries to the right flags for gcc, instead of those for the
  3354         -    # standard manufacturer compiler.
  3355         -
  3356         -    if test "$DL_OBJS" != "tclLoadNone.o" ; then
  3357         -	if test "$GCC" = "yes" ; then
  3358         -	    case $system in
  3359         -		AIX-*)
  3360         -		    ;;
  3361         -		BSD/OS*)
  3362         -		    ;;
  3363         -		IRIX*)
  3364         -		    ;;
  3365         -		NetBSD-*|FreeBSD-*|OpenBSD-*)
  3366         -		    ;;
  3367         -		Rhapsody-*|Darwin-*)
  3368         -		    ;;
  3369         -		RISCos-*)
  3370         -		    ;;
  3371         -		SCO_SV-3.2*)
  3372         -		    ;;
  3373         -		ULTRIX-4.*)
  3374         -		    ;;
  3375         -		windows)
  3376         -		    if test "$MINGW32" != "yes"; then 
  3377         -		        SHLIB_CFLAGS="-fPIC"
  3378         -		    fi
  3379         -		    ;;
  3380         -		*)
  3381         -		    SHLIB_CFLAGS="-fPIC"
  3382         -		    ;;
  3383         -	    esac
  3384         -	fi
  3385         -    fi
  3386         -
  3387         -    if test "$SHARED_LIB_SUFFIX" = "" ; then
  3388         -	SHARED_LIB_SUFFIX='${VERSION}\$\{DBGX\}${SHLIB_SUFFIX}'
  3389         -    fi
  3390         -    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
  3391         -	UNSHARED_LIB_SUFFIX='${VERSION}\$\{DBGX\}.a'
  3392         -    fi
  3393         -
  3394         -    
  3395         -    
  3396         -    
  3397         -    
  3398         -    
  3399         -
  3400         -    SHLIB_LDFLAGS='$(LDFLAGS_DEFAULT)'
  3401         -    
  3402         -    
  3403         -    
  3404         -    
  3405         -    
  3406         -    
  3407         -    
  3408         -
  3409         -TDOM_LD_SEARCH_FLAGS=${LD_SEARCH_FLAGS}
  3410         -
  3411         -
  3412         -#--------------------------------------------------------------------
  3413         -# Set the default compiler switches based on the --enable-symbols option.
  3414         -#--------------------------------------------------------------------
  3415         -
  3416         -
  3417         -    if test x"${TEA_INITED}" = x ; then
  3418         -	# Can't refer to exact macro name or it will be substituted
  3419         -	{ echo "configure: error: Must call TEA INIT before ENABLE_SYMBOLS" 1>&2; exit 1; }
  3420         -    fi
  3421         -
  3422         -    if test "${TEA_PLATFORM}" = "windows" ; then
  3423         -	tcl_dbgx=d
  3424         -    else
  3425         -	tcl_dbgx=g
  3426         -    fi
  3427         -
  3428         -    echo $ac_n "checking for build with symbols""... $ac_c" 1>&6
  3429         -echo "configure:3431: checking for build with symbols" >&5
  3430         -    # Check whether --enable-symbols or --disable-symbols was given.
  3431         -if test "${enable_symbols+set}" = set; then
  3432         -  enableval="$enable_symbols"
  3433         -  tcl_ok=$enableval
  3434         -else
  3435         -  tcl_ok=no
  3436         -fi
  3437         -
  3438         -    if test "$tcl_ok" = "yes"; then
  3439         -	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
  3440         -	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
  3441         -	DBGX=${tcl_dbgx}
  3442         -	TCL_DBGX=${tcl_dbgx}
  3443         -	echo "$ac_t""yes" 1>&6
  3444         -    else
  3445         -	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
  3446         -	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
  3447         -	DBGX=""
  3448         -	TCL_DBGX=""
  3449         -	echo "$ac_t""no" 1>&6
  3450         -    fi
  3451         -
  3452         -    
  3453         -    
  3454         -    
  3455         -
  3456         -
  3457         -if test "${SHARED_BUILD}" = "1" ; then
  3458         -    CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING} ${SHLIB_CFLAGS}'
  3459         -else
  3460         -    CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING}'
  3461         -fi
  3462         -
  3463         -
  3464         -#--------------------------------------------------------------------
  3465         -# Everyone should be linking against the Tcl stub library.  If you
  3466         -# can't for some reason, remove this definition.  If you aren't using
  3467         -# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
  3468         -# link against the non-stubbed Tcl library.  Add Tk too if necessary.
  3469         -#--------------------------------------------------------------------
  3470         -
  3471         -#AC_DEFINE(USE_TCL_STUBS)
  3472         -#AC_DEFINE(USE_TK_STUBS)
  3473         -
  3474         -#--------------------------------------------------------------------
  3475         -# This macro generates a line to use when building a library.  It
  3476         -# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
  3477         -# and TEA_LOAD_TCLCONFIG macros above.
  3478         -# For tDOM we always build both, static and shared libraries
  3479         -#--------------------------------------------------------------------
  3480         -
  3481         -
  3482         -    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
  3483         -	MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(\$(PACKAGE)_OBJECTS)"
  3484         -	MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LDFLAGS} \${SHLIB_LD_LIBS} \$(LDFLAGS) -out:\$@ \$(\$(PACKAGE)_OBJECTS)"
  3485         -	MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(\$(PACKAGE)stub_OBJECTS)"
  3486         -    else
  3487         -	MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(\$(PACKAGE)_OBJECTS)"
  3488         -	MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(\$(PACKAGE)_OBJECTS) \${SHLIB_LDFLAGS} \${SHLIB_LD_LIBS}"
  3489         -	MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(\$(PACKAGE)stub_OBJECTS)"
  3490         -    fi
  3491         -
  3492         -    if test "${SHARED_BUILD}" = "1" ; then
  3493         -	MAKE_LIB="${MAKE_SHARED_LIB} "
  3494         -    else
  3495         -	MAKE_LIB="${MAKE_STATIC_LIB} "
  3496         -    fi
  3497         -
  3498         -    #--------------------------------------------------------------------
  3499         -    # Shared libraries and static libraries have different names.
  3500         -    # Use the double eval to make sure the ${DBGX} in the suffix is
  3501         -    # substituted.
  3502         -    #--------------------------------------------------------------------
  3503         -
  3504         -    if test "${TEA_PLATFORM}" = "windows" ; then
  3505         -	if test "${SHARED_BUILD}" = "1" ; then
  3506         -	    # We force the unresolved linking of symbols that are really in
  3507         -	    # the private libraries of Tcl and Tk.
  3508         -	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
  3509         -	    if test x"${TK_BIN_DIR}" != x ; then
  3510         -		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
  3511         -	    fi
  3512         -	    eval eval "${PACKAGE}_LIB_FILE=${PACKAGE}${SHARED_LIB_SUFFIX}"
  3513         -	    RANLIB=:
  3514         -	else
  3515         -	    eval eval "${PACKAGE}_LIB_FILE=${PACKAGE}${UNSHARED_LIB_SUFFIX}"
  3516         -	fi
  3517         -	# Some packages build there own stubs libraries
  3518         -	eval eval "${PACKAGE}stub_LIB_FILE=${PACKAGE}stub${UNSHARED_LIB_SUFFIX}"
  3519         -    else
  3520         -	if test "${SHARED_BUILD}" = "1" ; then
  3521         -	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
  3522         -	    if test x"${TK_BIN_DIR}" != x ; then
  3523         -		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
  3524         -	    fi
  3525         -	    eval eval "${PACKAGE}_LIB_FILE=lib${PACKAGE}${SHARED_LIB_SUFFIX}"
  3526         -	    RANLIB=:
  3527         -	else
  3528         -	    eval eval "${PACKAGE}_LIB_FILE=lib${PACKAGE}${UNSHARED_LIB_SUFFIX}"
  3529         -	fi
  3530         -	# Some packages build there own stubs libraries
  3531         -	eval eval "${PACKAGE}stub_LIB_FILE=lib${PACKAGE}stub${UNSHARED_LIB_SUFFIX}"
  3532         -    fi
  3533         -
  3534         -    
  3535         -    
  3536         -    
  3537         -    
  3538         -
  3539         -
  3540         -#--------------------------------------------------------------------
  3541         -# __CHANGE__
  3542         -# Add platform libs to LIBS or SHLIB_LD_LIBS as necessary.
  3543         -#--------------------------------------------------------------------
  3544         -
  3545         -#LIBS="${LIBS} -lsuperfly"
  3546         -
  3547         -#--------------------------------------------------------------------
  3548         -# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
  3549         -# file during the install process.  Don't run the TCLSH_PROG through
  3550         -# ${CYGPATH} because it's being used directly by make.
  3551         -# Require that we use a tclsh shell version 8.2 or later since earlier
  3552         -# versions have bugs in the pkg_mkIndex routine.
  3553         -# Add WISH as well if this is a Tk extension.
  3554         -#--------------------------------------------------------------------
  3555         -
  3556         -
  3557         -    echo $ac_n "checking for tclsh""... $ac_c" 1>&6
  3558         -echo "configure:3560: checking for tclsh" >&5
  3559         -
  3560         -    if eval "test \"`echo '$''{'ac_cv_path_tclsh'+set}'`\" = set"; then
  3561         -  echo $ac_n "(cached) $ac_c" 1>&6
  3562         -else
  3563         -  
  3564         -	search_path=`echo ${TCL_BIN_DIR}:${TCL_BIN_DIR}/../bin:${exec_prefix}/bin:${prefix}/bin:${PATH} | sed -e 's/:/ /g'`
  3565         -	for dir in $search_path ; do
  3566         -	    for j in `ls -r $dir/tclsh[8-9]*${EXEEXT} 2> /dev/null` \
  3567         -		    `ls -r $dir/tclsh*${EXEEXT} 2> /dev/null` ; do
  3568         -		if test x"$ac_cv_path_tclsh" = x ; then
  3569         -		    if test -f "$j" ; then
  3570         -			ac_cv_path_tclsh=$j
  3571         -			break
  3572         -		    fi
  3573         -		fi
  3574         -	    done
  3575         -	done
  3576         -    
  3577         -fi
  3578         -
  3579         -
  3580         -    if test -f "$ac_cv_path_tclsh" ; then
  3581         -	TCLSH_PROG=$ac_cv_path_tclsh
  3582         -	echo "$ac_t""$TCLSH_PROG" 1>&6
  3583         -    else
  3584         -	{ echo "configure: error: No tclsh found in PATH:  $search_path" 1>&2; exit 1; }
  3585         -    fi
  3586         -    
  3587         -
  3588         -#TEA_PROG_WISH
  3589         -
  3590         -#--------------------------------------------------------------------
  3591         -# Add some private include directories
  3592         -#--------------------------------------------------------------------
  3593         -
  3594         -TDOM_INCLUDES="-I${srcdir}/generic -I${srcdir}/expat"
  3595         -
  3596         -
  3597         -#--------------------------------------------------------------------
  3598         -# Add optional AOLserver includes
  3599         -#--------------------------------------------------------------------
  3600         -
  3601         -
  3602         -    echo $ac_n "checking for AOLserver configuration""... $ac_c" 1>&6
  3603         -echo "configure:3605: checking for AOLserver configuration" >&5
  3604         -    # Check whether --with-aol or --without-aol was given.
  3605         -if test "${with_aol+set}" = set; then
  3606         -  withval="$with_aol"
  3607         -  \
  3608         -    with_aolserver=${withval}
  3609         -fi
  3610         -
  3611         -
  3612         -    if eval "test \"`echo '$''{'ac_cv_c_aolserver'+set}'`\" = set"; then
  3613         -  echo $ac_n "(cached) $ac_c" 1>&6
  3614         -else
  3615         -  
  3616         -    if test x"${with_aolserver}" != x ; then
  3617         -        if test -f "${with_aolserver}/include/ns.h" ; then
  3618         -            ac_cv_c_aolserver=`(cd ${with_aolserver}; pwd)`
  3619         -        else
  3620         -            { echo "configure: error: ${with_aolserver} directory doesn't contain ns.h" 1>&2; exit 1; }
  3621         -        fi
  3622         -    fi
  3623         -    
  3624         -fi
  3625         -
  3626         -    if test x"${ac_cv_c_aolserver}" = x ; then
  3627         -        echo "$ac_t""none found" 1>&6
  3628         -    else
  3629         -        AOL_DIR=${ac_cv_c_aolserver}
  3630         -        echo "$ac_t""found AOLserver in $AOL_DIR" 1>&6
  3631         -        cat >> confdefs.h <<\EOF
  3632         -#define NS_AOLSERVER 1
  3633         -EOF
  3634         -
  3635         -        cat >> confdefs.h <<\EOF
  3636         -#define USE_NORMAL_ALLOCATOR 1
  3637         -EOF
  3638         -
  3639         -    fi
  3640         -
  3641         -if test x"${AOL_DIR}" != "x" ; then
  3642         -    AOL_INCLUDES="-I${AOL_DIR}/include"
  3643         -else
  3644         -    AOL_INCLUDES=
  3645         -fi
  3646         -
  3647         -
  3648         -
  3649         -#--------------------------------------------------------------------
  3650         -# Add some private preprocessor options
  3651         -#--------------------------------------------------------------------
  3652         -
  3653         -
  3654         -    echo $ac_n "checking wether to enable dtd support""... $ac_c" 1>&6
  3655         -echo "configure:3657: checking wether to enable dtd support" >&5
  3656         -    # Check whether --enable-dtd or --disable-dtd was given.
  3657         -if test "${enable_dtd+set}" = set; then
  3658         -  enableval="$enable_dtd"
  3659         -  tcl_ok=$enableval
  3660         -else
  3661         -  tcl_ok=yes
  3662         -fi
  3663         -
  3664         -
  3665         -    if test "${enable_dt+set}" = set; then
  3666         -        enableval="$enable_dtd"
  3667         -        tcl_ok=$enableval
  3668         -    else
  3669         -        tcl_ok=yes
  3670         -    fi
  3671         -
  3672         -    if test "$tcl_ok" = "yes" ; then
  3673         -        echo "$ac_t""yes" 1>&6
  3674         -        cat >> confdefs.h <<\EOF
  3675         -#define XML_DTD 1
  3676         -EOF
  3677         -
  3678         -    else
  3679         -        echo "$ac_t""no" 1>&6
  3680         -    fi
  3681         -
  3682         -
  3683         -    echo $ac_n "checking wether to enable namespace support""... $ac_c" 1>&6
  3684         -echo "configure:3686: checking wether to enable namespace support" >&5
  3685         -    # Check whether --enable-ns or --disable-ns was given.
  3686         -if test "${enable_ns+set}" = set; then
  3687         -  enableval="$enable_ns"
  3688         -  tcl_ok=$enableval
  3689         -else
  3690         -  tcl_ok=yes
  3691         -fi
  3692         -
  3693         -
  3694         -    if test "${enable_ns+set}" = set; then
  3695         -        enableval="$enable_ns"
  3696         -        tcl_ok=$enableval
  3697         -    else
  3698         -        tcl_ok=yes
  3699         -    fi
  3700         -
  3701         -    if test "$tcl_ok" = "yes" ; then
  3702         -        echo "$ac_t""yes" 1>&6
  3703         -        cat >> confdefs.h <<\EOF
  3704         -#define XML_NS 1
  3705         -EOF
  3706         -
  3707         -    else
  3708         -        echo "$ac_t""no" 1>&6
  3709         -    fi
  3710         -
  3711         -
  3712         -    echo $ac_n "checking wether to enable built-in unknown command""... $ac_c" 1>&6
  3713         -echo "configure:3715: checking wether to enable built-in unknown command" >&5
  3714         -    # Check whether --enable-ucmd or --disable-ucmd was given.
  3715         -if test "${enable_ucmd+set}" = set; then
  3716         -  enableval="$enable_ucmd"
  3717         -  tcl_ok=$enableval
  3718         -else
  3719         -  tcl_ok=no
  3720         -fi
  3721         -
  3722         -
  3723         -    if test "${enable_unknown+set}" = set; then
  3724         -        enableval="$enable_unknown"
  3725         -        tcl_ok=$enableval
  3726         -    else
  3727         -        tcl_ok=no
  3728         -    fi
  3729         -
  3730         -    if test "$tcl_ok" = "no" ; then
  3731         -        echo "$ac_t""no" 1>&6
  3732         -        cat >> confdefs.h <<\EOF
  3733         -#define TDOM_NO_UNKNOWN_CMD 1
  3734         -EOF
  3735         -
  3736         -    else
  3737         -        echo "$ac_t""yes" 1>&6
  3738         -    fi
  3739         -
  3740         -
  3741         -    echo $ac_n "checking wether to enable tDOMs block allocator""... $ac_c" 1>&6
  3742         -echo "configure:3744: checking wether to enable tDOMs block allocator" >&5
  3743         -    # Check whether --enable-tdomalloc or --disable-tdomalloc was given.
  3744         -if test "${enable_tdomalloc+set}" = set; then
  3745         -  enableval="$enable_tdomalloc"
  3746         -  tcl_ok=$enableval
  3747         -else
  3748         -  tcl_ok=yes
  3749         -fi
  3750         -
  3751         -
  3752         -    if test "${enable_tdomalloc+set}" = set; then
  3753         -        enableval="$enable_tdomalloc"
  3754         -        tcl_ok=$enableval
  3755         -    else
  3756         -        tcl_ok=yes
  3757         -    fi
  3758         -
  3759         -    if test "$tcl_ok" = "yes" ; then
  3760         -        echo "$ac_t""yes" 1>&6
  3761         -    else
  3762         -        echo "$ac_t""no" 1>&6
  3763         -        cat >> confdefs.h <<\EOF
  3764         -#define USE_NORMAL_ALLOCATOR 1
  3765         -EOF
  3766         -
  3767         -    fi
  3768         -
  3769         -echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
  3770         -echo "configure:3772: checking whether byte ordering is bigendian" >&5
  3771         -if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
  3772         -  echo $ac_n "(cached) $ac_c" 1>&6
  3773         -else
  3774         -  ac_cv_c_bigendian=unknown
  3775         -# See if sys/param.h defines the BYTE_ORDER macro.
  3776         -cat > conftest.$ac_ext <<EOF
  3777         -#line 3779 "configure"
  3778         -#include "confdefs.h"
  3779         -#include <sys/types.h>
  3780         -#include <sys/param.h>
  3781         -int main() {
  3782         -
  3783         -#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
  3784         - bogus endian macros
  3785         -#endif
  3786         -; return 0; }
  3787         -EOF
  3788         -if { (eval echo configure:3790: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  3789         -  rm -rf conftest*
  3790         -  # It does; now see whether it defined to BIG_ENDIAN or not.
  3791         -cat > conftest.$ac_ext <<EOF
  3792         -#line 3794 "configure"
  3793         -#include "confdefs.h"
  3794         -#include <sys/types.h>
  3795         -#include <sys/param.h>
  3796         -int main() {
  3797         -
  3798         -#if BYTE_ORDER != BIG_ENDIAN
  3799         - not big endian
  3800         -#endif
  3801         -; return 0; }
  3802         -EOF
  3803         -if { (eval echo configure:3805: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  3804         -  rm -rf conftest*
  3805         -  ac_cv_c_bigendian=yes
  3806         -else
  3807         -  echo "configure: failed program was:" >&5
  3808         -  cat conftest.$ac_ext >&5
  3809         -  rm -rf conftest*
  3810         -  ac_cv_c_bigendian=no
  3811         -fi
  3812         -rm -f conftest*
  3813         -else
  3814         -  echo "configure: failed program was:" >&5
  3815         -  cat conftest.$ac_ext >&5
  3816         -fi
  3817         -rm -f conftest*
  3818         -if test $ac_cv_c_bigendian = unknown; then
  3819         -if test "$cross_compiling" = yes; then
  3820         -   echo $ac_n "cross-compiling... " 2>&6 
  3821         -else
  3822         -  cat > conftest.$ac_ext <<EOF
  3823         -#line 3825 "configure"
  3824         -#include "confdefs.h"
  3825         -main () {
  3826         -  /* Are we little or big endian?  From Harbison&Steele.  */
  3827         -  union
  3828         -  {
  3829         -    long l;
  3830         -    char c[sizeof (long)];
  3831         -  } u;
  3832         -  u.l = 1;
  3833         -  exit (u.c[sizeof (long) - 1] == 1);
  3834         -}
  3835         -EOF
  3836         -if { (eval echo configure:3838: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
  3837         -then
  3838         -  ac_cv_c_bigendian=no
  3839         -else
  3840         -  echo "configure: failed program was:" >&5
  3841         -  cat conftest.$ac_ext >&5
  3842         -  rm -fr conftest*
  3843         -  ac_cv_c_bigendian=yes
  3844         -fi
  3845         -rm -fr conftest*
  3846         -fi
  3847         -
  3848         -fi
  3849         -fi
  3850         -
  3851         -echo "$ac_t""$ac_cv_c_bigendian" 1>&6
  3852         -if test $ac_cv_c_bigendian = unknown; then
  3853         -echo $ac_n "checking to probe for byte ordering""... $ac_c" 1>&6
  3854         -echo "configure:3856: checking to probe for byte ordering" >&5
  3855         -
  3856         -cat >conftest.c <<EOF
  3857         -short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
  3858         -short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
  3859         -void _ascii() { char* s = (char*) ascii_mm; s = (char*) ascii_ii; }
  3860         -short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
  3861         -short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
  3862         -void _ebcdic() { char* s = (char*) ebcdic_mm; s = (char*) ebcdic_ii; }
  3863         -int main() { _ascii (); _ebcdic (); return 0; }
  3864         -EOF
  3865         - if test -f conftest.c ; then
  3866         -     if ${CC-cc} -c conftest.c -o conftest.o && test -f conftest.o ; then
  3867         -        if test `grep -l BIGenDianSyS conftest.o` ; then
  3868         -           echo $ac_n ' big endian probe OK, ' 1>&6
  3869         -           ac_cv_c_bigendian=yes
  3870         -        fi
  3871         -        if test `grep -l LiTTleEnDian conftest.o` ; then
  3872         -           echo $ac_n ' little endian probe OK, ' 1>&6
  3873         -           if test $ac_cv_c_bigendian = yes ; then
  3874         -            ac_cv_c_bigendian=unknown;
  3875         -           else
  3876         -            ac_cv_c_bigendian=no
  3877         -           fi
  3878         -        fi
  3879         -        echo $ac_n 'guessing bigendian ...  ' >&6
  3880         -     fi
  3881         -  fi
  3882         -echo "$ac_t""$ac_cv_c_bigendian" 1>&6
  3883         -fi
  3884         -if test $ac_cv_c_bigendian = yes; then
  3885         -  cat >> confdefs.h <<\EOF
  3886         -#define WORDS_BIGENDIAN 1
  3887         -EOF
  3888         -
  3889         -  BYTEORDER=4321
  3890         -else
  3891         -  BYTEORDER=1234
  3892         -fi
  3893         -if test $ac_cv_c_bigendian = unknown; then
  3894         -  { echo "configure: error: unknown endianess - sorry" 1>&2; exit 1; }
  3895         -fi
  3896         -
  3897         -
  3898         -
  3899         -#--------------------------------------------------------------------
  3900         -# Finally, substitute all of the various values into the Makefile.
  3901         -# You may alternatively have a special pkgIndex.tcl.in or other files
  3902         -# which require substituting th AC variables in.  Include these here.
  3903         -#--------------------------------------------------------------------
  3904         -
  3905         -trap '' 1 2 15
  3906         -cat > confcache <<\EOF
  3907         -# This file is a shell script that caches the results of configure
  3908         -# tests run on this system so they can be shared between configure
  3909         -# scripts and configure runs.  It is not useful on other systems.
  3910         -# If it contains results you don't want to keep, you may remove or edit it.
  3911         -#
  3912         -# By default, configure uses ./config.cache as the cache file,
  3913         -# creating it if it does not exist already.  You can give configure
  3914         -# the --cache-file=FILE option to use a different cache file; that is
  3915         -# what configure does when it calls configure scripts in
  3916         -# subdirectories, so they share the cache.
  3917         -# Giving --cache-file=/dev/null disables caching, for debugging configure.
  3918         -# config.status only pays attention to the cache file if you give it the
  3919         -# --recheck option to rerun configure.
  3920         -#
  3921         -EOF
  3922         -# The following way of writing the cache mishandles newlines in values,
  3923         -# but we know of no workaround that is simple, portable, and efficient.
  3924         -# So, don't put newlines in cache variables' values.
  3925         -# Ultrix sh set writes to stderr and can't be redirected directly,
  3926         -# and sets the high bit in the cache file unless we assign to the vars.
  3927         -(set) 2>&1 |
  3928         -  case `(ac_space=' '; set | grep ac_space) 2>&1` in
  3929         -  *ac_space=\ *)
  3930         -    # `set' does not quote correctly, so add quotes (double-quote substitution
  3931         -    # turns \\\\ into \\, and sed turns \\ into \).
  3932         -    sed -n \
  3933         -      -e "s/'/'\\\\''/g" \
  3934         -      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
  3935         -    ;;
  3936         -  *)
  3937         -    # `set' quotes correctly as required by POSIX, so do not add quotes.
  3938         -    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
  3939         -    ;;
  3940         -  esac >> confcache
  3941         -if cmp -s $cache_file confcache; then
  3942         -  :
  3943         -else
  3944         -  if test -w $cache_file; then
  3945         -    echo "updating cache $cache_file"
  3946         -    cat confcache > $cache_file
  3947         -  else
  3948         -    echo "not updating unwritable cache $cache_file"
  3949         -  fi
  3950         -fi
  3951         -rm -f confcache
  3952         -
  3953         -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
  3954         -
  3955         -test "x$prefix" = xNONE && prefix=$ac_default_prefix
  3956         -# Let make expand exec_prefix.
  3957         -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
  3958         -
  3959         -# Any assignment to VPATH causes Sun make to only execute
  3960         -# the first set of double-colon rules, so remove it if not needed.
  3961         -# If there is a colon in the path, we need to keep it.
  3962         -if test "x$srcdir" = x.; then
  3963         -  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
  3964         -fi
  3965         -
  3966         -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
  3967         -
  3968         -# Transform confdefs.h into DEFS.
  3969         -# Protect against shell expansion while executing Makefile rules.
  3970         -# Protect against Makefile macro expansion.
  3971         -cat > conftest.defs <<\EOF
  3972         -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
  3973         -s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
  3974         -s%\[%\\&%g
  3975         -s%\]%\\&%g
  3976         -s%\$%$$%g
  3977         -EOF
  3978         -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
  3979         -rm -f conftest.defs
  3980         -
  3981         -
  3982         -# Without the "./", some shells look in PATH for config.status.
  3983         -: ${CONFIG_STATUS=./config.status}
  3984         -
  3985         -echo creating $CONFIG_STATUS
  3986         -rm -f $CONFIG_STATUS
  3987         -cat > $CONFIG_STATUS <<EOF
  3988         -#! /bin/sh
  3989         -# Generated automatically by configure.
  3990         -# Run this file to recreate the current configuration.
  3991         -# This directory was configured as follows,
  3992         -# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
  3993         -#
  3994         -# $0 $ac_configure_args
  3995         -#
  3996         -# Compiler output produced by configure, useful for debugging
  3997         -# configure, is in ./config.log if it exists.
  3998         -
  3999         -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
  4000         -for ac_option
  4001         -do
  4002         -  case "\$ac_option" in
  4003         -  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
  4004         -    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
  4005         -    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
  4006         -  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
  4007         -    echo "$CONFIG_STATUS generated by autoconf version 2.13"
  4008         -    exit 0 ;;
  4009         -  -help | --help | --hel | --he | --h)
  4010         -    echo "\$ac_cs_usage"; exit 0 ;;
  4011         -  *) echo "\$ac_cs_usage"; exit 1 ;;
  4012         -  esac
  4013         -done
  4014         -
  4015         -ac_given_srcdir=$srcdir
  4016         -ac_given_INSTALL="$INSTALL"
  4017         -
  4018         -trap 'rm -fr `echo "Makefile tdomConfig.sh" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
  4019         -EOF
  4020         -cat >> $CONFIG_STATUS <<EOF
  4021         -
  4022         -# Protect against being on the right side of a sed subst in config.status.
  4023         -sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
  4024         - s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
  4025         -$ac_vpsub
  4026         -$extrasub
  4027         -s%@SHELL@%$SHELL%g
  4028         -s%@CFLAGS@%$CFLAGS%g
  4029         -s%@CPPFLAGS@%$CPPFLAGS%g
  4030         -s%@CXXFLAGS@%$CXXFLAGS%g
  4031         -s%@FFLAGS@%$FFLAGS%g
  4032         -s%@DEFS@%$DEFS%g
  4033         -s%@LDFLAGS@%$LDFLAGS%g
  4034         -s%@LIBS@%$LIBS%g
  4035         -s%@exec_prefix@%$exec_prefix%g
  4036         -s%@prefix@%$prefix%g
  4037         -s%@program_transform_name@%$program_transform_name%g
  4038         -s%@bindir@%$bindir%g
  4039         -s%@sbindir@%$sbindir%g
  4040         -s%@libexecdir@%$libexecdir%g
  4041         -s%@datadir@%$datadir%g
  4042         -s%@sysconfdir@%$sysconfdir%g
  4043         -s%@sharedstatedir@%$sharedstatedir%g
  4044         -s%@localstatedir@%$localstatedir%g
  4045         -s%@libdir@%$libdir%g
  4046         -s%@includedir@%$includedir%g
  4047         -s%@oldincludedir@%$oldincludedir%g
  4048         -s%@infodir@%$infodir%g
  4049         -s%@mandir@%$mandir%g
  4050         -s%@CONFIGDIR@%$CONFIGDIR%g
  4051         -s%@PACKAGE@%$PACKAGE%g
  4052         -s%@TDOMSHELL@%$TDOMSHELL%g
  4053         -s%@MAJOR_VERSION@%$MAJOR_VERSION%g
  4054         -s%@MINOR_VERSION@%$MINOR_VERSION%g
  4055         -s%@PATCHLEVEL@%$PATCHLEVEL%g
  4056         -s%@tdom_LIB_FILE@%$tdom_LIB_FILE%g
  4057         -s%@tdomstub_LIB_FILE@%$tdomstub_LIB_FILE%g
  4058         -s%@CYGPATH@%$CYGPATH%g
  4059         -s%@EXEEXT@%$EXEEXT%g
  4060         -s%@TCL_VERSION@%$TCL_VERSION%g
  4061         -s%@TCL_BIN_DIR@%$TCL_BIN_DIR%g
  4062         -s%@TCL_SRC_DIR@%$TCL_SRC_DIR%g
  4063         -s%@TCL_LIB_FILE@%$TCL_LIB_FILE%g
  4064         -s%@TCL_LIB_FLAG@%$TCL_LIB_FLAG%g
  4065         -s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g
  4066         -s%@TCL_STUB_LIB_FILE@%$TCL_STUB_LIB_FILE%g
  4067         -s%@TCL_STUB_LIB_FLAG@%$TCL_STUB_LIB_FLAG%g
  4068         -s%@TCL_STUB_LIB_SPEC@%$TCL_STUB_LIB_SPEC%g
  4069         -s%@TCL_LIBS@%$TCL_LIBS%g
  4070         -s%@TCL_DEFS@%$TCL_DEFS%g
  4071         -s%@TCL_EXTRA_CFLAGS@%$TCL_EXTRA_CFLAGS%g
  4072         -s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g
  4073         -s%@TCL_SHLIB_LD_LIBS@%$TCL_SHLIB_LD_LIBS%g
  4074         -s%@CC@%$CC%g
  4075         -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
  4076         -s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
  4077         -s%@INSTALL_DATA@%$INSTALL_DATA%g
  4078         -s%@SET_MAKE@%$SET_MAKE%g
  4079         -s%@RANLIB@%$RANLIB%g
  4080         -s%@OBJEXT@%$OBJEXT%g
  4081         -s%@TCL_INCLUDES@%$TCL_INCLUDES%g
  4082         -s%@CLEANFILES@%$CLEANFILES%g
  4083         -s%@EXTRA_SOURCES@%$EXTRA_SOURCES%g
  4084         -s%@VERSION@%$VERSION%g
  4085         -s%@tdomstub_BUILD_SPEC@%$tdomstub_BUILD_SPEC%g
  4086         -s%@tdomstub_FILE_SPEC@%$tdomstub_FILE_SPEC%g
  4087         -s%@tdom_SRC_DIR@%$tdom_SRC_DIR%g
  4088         -s%@TCL_THREADS@%$TCL_THREADS%g
  4089         -s%@AR@%$AR%g
  4090         -s%@CPP@%$CPP%g
  4091         -s%@DL_LIBS@%$DL_LIBS%g
  4092         -s%@CFLAGS_DEBUG@%$CFLAGS_DEBUG%g
  4093         -s%@CFLAGS_OPTIMIZE@%$CFLAGS_OPTIMIZE%g
  4094         -s%@CFLAGS_WARNING@%$CFLAGS_WARNING%g
  4095         -s%@EXTRA_CFLAGS@%$EXTRA_CFLAGS%g
  4096         -s%@STLIB_LD@%$STLIB_LD%g
  4097         -s%@SHLIB_LD@%$SHLIB_LD%g
  4098         -s%@SHLIB_CFLAGS@%$SHLIB_CFLAGS%g
  4099         -s%@SHLIB_LDFLAGS@%$SHLIB_LDFLAGS%g
  4100         -s%@SHLIB_LD_LIBS@%$SHLIB_LD_LIBS%g
  4101         -s%@LDFLAGS_DEBUG@%$LDFLAGS_DEBUG%g
  4102         -s%@LDFLAGS_OPTIMIZE@%$LDFLAGS_OPTIMIZE%g
  4103         -s%@TDOM_LD_SEARCH_FLAGS@%$TDOM_LD_SEARCH_FLAGS%g
  4104         -s%@TCL_DBGX@%$TCL_DBGX%g
  4105         -s%@CFLAGS_DEFAULT@%$CFLAGS_DEFAULT%g
  4106         -s%@LDFLAGS_DEFAULT@%$LDFLAGS_DEFAULT%g
  4107         -s%@SHARED_BUILD@%$SHARED_BUILD%g
  4108         -s%@MAKE_LIB@%$MAKE_LIB%g
  4109         -s%@MAKE_SHARED_LIB@%$MAKE_SHARED_LIB%g
  4110         -s%@MAKE_STATIC_LIB@%$MAKE_STATIC_LIB%g
  4111         -s%@MAKE_STUB_LIB@%$MAKE_STUB_LIB%g
  4112         -s%@TCLSH_PROG@%$TCLSH_PROG%g
  4113         -s%@TDOM_INCLUDES@%$TDOM_INCLUDES%g
  4114         -s%@AOL_DIR@%$AOL_DIR%g
  4115         -s%@AOL_INCLUDES@%$AOL_INCLUDES%g
  4116         -s%@BYTEORDER@%$BYTEORDER%g
  4117         -
  4118         -CEOF
  4119         -EOF
  4120         -
  4121         -cat >> $CONFIG_STATUS <<\EOF
  4122         -
  4123         -# Split the substitutions into bite-sized pieces for seds with
  4124         -# small command number limits, like on Digital OSF/1 and HP-UX.
  4125         -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
  4126         -ac_file=1 # Number of current file.
  4127         -ac_beg=1 # First line for current file.
  4128         -ac_end=$ac_max_sed_cmds # Line after last line for current file.
  4129         -ac_more_lines=:
  4130         -ac_sed_cmds=""
  4131         -while $ac_more_lines; do
  4132         -  if test $ac_beg -gt 1; then
  4133         -    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
  4134         -  else
  4135         -    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
  4136         -  fi
  4137         -  if test ! -s conftest.s$ac_file; then
  4138         -    ac_more_lines=false
  4139         -    rm -f conftest.s$ac_file
  4140         -  else
  4141         -    if test -z "$ac_sed_cmds"; then
  4142         -      ac_sed_cmds="sed -f conftest.s$ac_file"
  4143         -    else
  4144         -      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
  4145         -    fi
  4146         -    ac_file=`expr $ac_file + 1`
  4147         -    ac_beg=$ac_end
  4148         -    ac_end=`expr $ac_end + $ac_max_sed_cmds`
  4149         -  fi
  4150         -done
  4151         -if test -z "$ac_sed_cmds"; then
  4152         -  ac_sed_cmds=cat
  4153         -fi
  4154         -EOF
  4155         -
  4156         -cat >> $CONFIG_STATUS <<EOF
  4157         -
  4158         -CONFIG_FILES=\${CONFIG_FILES-"Makefile tdomConfig.sh"}
  4159         -EOF
  4160         -cat >> $CONFIG_STATUS <<\EOF
  4161         -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
  4162         -  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
  4163         -  case "$ac_file" in
  4164         -  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
  4165         -       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
  4166         -  *) ac_file_in="${ac_file}.in" ;;
  4167         -  esac
  4168         -
  4169         -  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
  4170         -
  4171         -  # Remove last slash and all that follows it.  Not all systems have dirname.
  4172         -  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
  4173         -  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
  4174         -    # The file is in a subdirectory.
  4175         -    test ! -d "$ac_dir" && mkdir "$ac_dir"
  4176         -    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
  4177         -    # A "../" for each directory in $ac_dir_suffix.
  4178         -    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
  4179         -  else
  4180         -    ac_dir_suffix= ac_dots=
  4181         -  fi
  4182         -
  4183         -  case "$ac_given_srcdir" in
  4184         -  .)  srcdir=.
  4185         -      if test -z "$ac_dots"; then top_srcdir=.
  4186         -      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
  4187         -  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
  4188         -  *) # Relative path.
  4189         -    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
  4190         -    top_srcdir="$ac_dots$ac_given_srcdir" ;;
  4191         -  esac
  4192         -
  4193         -  case "$ac_given_INSTALL" in
  4194         -  [/$]*) INSTALL="$ac_given_INSTALL" ;;
  4195         -  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
  4196         -  esac
  4197         -
  4198         -  echo creating "$ac_file"
  4199         -  rm -f "$ac_file"
  4200         -  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
  4201         -  case "$ac_file" in
  4202         -  *Makefile*) ac_comsub="1i\\
  4203         -# $configure_input" ;;
  4204         -  *) ac_comsub= ;;
  4205         -  esac
  4206         -
  4207         -  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
  4208         -  sed -e "$ac_comsub
  4209         -s%@configure_input@%$configure_input%g
  4210         -s%@srcdir@%$srcdir%g
  4211         -s%@top_srcdir@%$top_srcdir%g
  4212         -s%@INSTALL@%$INSTALL%g
  4213         -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
  4214         -fi; done
  4215         -rm -f conftest.s*
  4216         -
  4217         -EOF
  4218         -cat >> $CONFIG_STATUS <<EOF
  4219         -
  4220         -EOF
  4221         -cat >> $CONFIG_STATUS <<\EOF
  4222         -
  4223         -exit 0
  4224         -EOF
  4225         -chmod +x $CONFIG_STATUS
  4226         -rm -fr confdefs* $ac_clean_files
  4227         -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
  4228         -

Changes to configure.in.

     1      1   #!/bin/bash -norc
     2      2   dnl	This file is an input file used by the GNU "autoconf" program to
     3      3   dnl	generate the file "configure", which is run during Tcl installation
     4      4   dnl	to configure the system for the local environment.
     5         -#
     6         -# RCS: @(#) $Id$
     7      5   
     8      6   #-----------------------------------------------------------------------
     9      7   # Sample configure.in for Tcl Extensions.  The only places you should
    10      8   # need to modify this file are marked by the string __CHANGE__
    11      9   #-----------------------------------------------------------------------
           10  +
    12     11   
    13     12   #-----------------------------------------------------------------------
    14     13   # __CHANGE__
    15     14   # Set your package name and version numbers here.
    16     15   #
    17     16   # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
    18     17   # set as provided.  These will also be added as -D defs in your Makefile
    19     18   # so you can encode the package version directly into the source files.
           19  +# This will also define a special symbol for Windows (BUILD_sample in
           20  +# this case) so that we create the export library with the dll.
    20     21   #-----------------------------------------------------------------------
    21     22   
    22         -AC_INIT([tdom], [0.8.3])
           23  +AC_INIT([tdom], [0.9.1])
           24  +
           25  +TDOM_EXPAT_ENTROPY
    23     26   
    24     27   #--------------------------------------------------------------------
    25     28   # Call TEA_INIT as the first TEA_ macro to set up initial vars.
    26     29   # This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
    27     30   # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
    28     31   #--------------------------------------------------------------------
    29     32   
    30         -TEA_INIT([3.6])
           33  +TEA_INIT([3.13])
    31     34   
    32     35   AC_CONFIG_AUX_DIR(tclconfig)
    33     36   
    34     37   #--------------------------------------------------------------------
    35     38   # Load the tclConfig.sh file
    36     39   #--------------------------------------------------------------------
    37     40   
................................................................................
    51     54   #-----------------------------------------------------------------------
    52     55   
    53     56   TEA_PREFIX
    54     57   
    55     58   #-----------------------------------------------------------------------
    56     59   # Standard compiler checks.
    57     60   # This sets up CC by using the CC env var, or looks for gcc otherwise.
    58         -# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
    59         -# the basic setup necessary to compile executables.
           61  +# This also calls AC_PROG_CC and a few others to create the basic setup
           62  +# necessary to compile executables.
    60     63   #-----------------------------------------------------------------------
    61     64   
    62     65   TEA_SETUP_COMPILER
    63     66   
    64     67   #-----------------------------------------------------------------------
    65     68   # Those two are needed for compiling expat.
    66     69   #-----------------------------------------------------------------------
................................................................................
    68     71   AC_CHECK_FUNCS(memmove bcopy)
    69     72   
    70     73   #--------------------------------------------------------------------
    71     74   # Add optional AOLserver includes
    72     75   #--------------------------------------------------------------------
    73     76   
    74     77   TDOM_PATH_AOLSERVER
           78  +
           79  +#--------------------------------------------------------------------
           80  +# Add shared expat includes
           81  +#--------------------------------------------------------------------
           82  +
           83  +TDOM_PATH_EXPAT
           84  +
           85  +#--------------------------------------------------------------------
           86  +# Add HTML5 parsing support.
           87  +#--------------------------------------------------------------------
           88  +
           89  +TDOM_ENABLE_HTML5
    75     90   
    76     91   #-----------------------------------------------------------------------
    77     92   # __CHANGE__
    78     93   # Specify the C source files to compile in TEA_ADD_SOURCES,
    79     94   # public headers that need to be installed in TEA_ADD_HEADERS,
    80     95   # stub library C source files to compile in TEA_ADD_STUB_SOURCES,
    81     96   # and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
    82     97   # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
    83     98   # and PKG_TCL_SOURCES.
    84     99   #-----------------------------------------------------------------------
    85    100   
    86         -TEA_ADD_SOURCES([expat/xmlrole.c     \
    87         -                 expat/xmltok.c      \
    88         -                 expat/xmlparse.c    \
    89         -                 generic/xmlsimple.c \
    90         -                 generic/utf8conv.c  \
          101  +TEA_ADD_SOURCES([generic/xmlsimple.c \
    91    102                    generic/dom.c       \
    92    103                    generic/domhtml.c   \
          104  +                 generic/domhtml5.c  \
          105  +                 generic/domjson.c   \
    93    106                    generic/domxpath.c  \
    94    107                    generic/domxslt.c   \
    95    108                    generic/domlock.c   \
    96    109                    generic/tcldom.c    \
    97    110                    generic/nodecmd.c   \
    98    111                    generic/tdominit.c  \
    99    112                    generic/tclexpat.c  \
          113  +                 generic/tclpull.c   \
   100    114                    generic/tdomStubInit.c])
   101    115   TEA_ADD_HEADERS([generic/tdom.h])
   102         -TEA_ADD_INCLUDES([-I${srcdir}/generic -I${srcdir}/expat ${AOL_INCLUDES}])
   103         -TEA_ADD_LIBS([${AOL_LIBS}])
          116  +TEA_ADD_INCLUDES([-I${srcdir}/generic ${AOL_INCLUDES} ${HTML5_INCLUDES}])
          117  +TEA_ADD_LIBS([${AOL_LIBS} ${HTML5_LIBS}])
   104    118   TEA_ADD_CFLAGS([])
   105    119   TEA_ADD_STUB_SOURCES([generic/tdomStubLib.c])
   106    120   TEA_ADD_TCL_SOURCES([lib/tdom.tcl])
   107    121   
   108    122   #--------------------------------------------------------------------
   109    123   # __CHANGE__
   110         -# A few miscellaneous platform-specific items:
   111    124   #
   112         -# Define a special symbol for Windows (BUILD_sample in this case) so
   113         -# that we create the export library with the dll.
          125  +# You can add more files to clean if your extension creates any extra
          126  +# files by extending CLEANFILES.
          127  +# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
          128  +# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
   114    129   #
   115         -# Windows creates a few extra files that need to be cleaned up.
   116         -# You can add more files to clean if your extension creates any extra
   117         -# files.
   118         -#
          130  +# A few miscellaneous platform-specific items:
   119    131   # TEA_ADD_* any platform specific compiler/build info here.
   120    132   #--------------------------------------------------------------------
   121    133   
   122    134   if test "${TEA_PLATFORM}" = "windows" ; then
   123         -    AC_DEFINE(BUILD_tdom)
   124    135       CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
   125    136       #TEA_ADD_SOURCES([win/winFile.c])
   126    137       #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
   127    138   else
   128         -    CLEANFILES="pkgIndex.tcl tcldomsh"
          139  +    CLEANFILES="pkgIndex.tcl tdom.tcl tcldomsh"
   129    140       #TEA_ADD_SOURCES([unix/unixFile.c])
   130    141       #TEA_ADD_LIBS([-lsuperfly])
   131    142   fi
   132    143   AC_SUBST(CLEANFILES)
   133    144   
   134    145   #--------------------------------------------------------------------
   135    146   # __CHANGE__
................................................................................
   181    192   #--------------------------------------------------------------------
   182    193   # Everyone should be linking against the Tcl stub library.  If you
   183    194   # can't for some reason, remove this definition.  If you aren't using
   184    195   # stubs, you also need to modify the SHLIB_LD_LIBS setting below to
   185    196   # link against the non-stubbed Tcl library.  Add Tk too if necessary.
   186    197   #--------------------------------------------------------------------
   187    198   
   188         -AC_DEFINE(USE_TCL_STUBS)
   189         -#AC_DEFINE(USE_TK_STUBS)
          199  +AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
          200  +#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
   190    201   
   191    202   #--------------------------------------------------------------------
   192    203   # This macro generates a line to use when building a library.  It
   193    204   # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
   194    205   # and TEA_LOAD_TCLCONFIG macros above.
   195    206   #--------------------------------------------------------------------
   196    207   
   197    208   TEA_MAKE_LIB
   198    209   
   199    210   #--------------------------------------------------------------------
   200         -# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
   201         -# file during the install process.  Don't run the TCLSH_PROG through
   202         -# ${CYGPATH} because it's being used directly by make.
   203         -# Require that we use a tclsh shell version 8.2 or later since earlier
   204         -# versions have bugs in the pkg_mkIndex routine.
   205         -# Add WISH as well if this is a Tk extension.
          211  +# Determine the name of the tclsh and/or wish executables in the
          212  +# Tcl and Tk build directories or the location they were installed
          213  +# into. These paths are used to support running test cases only,
          214  +# the Makefile should not be making use of these paths to generate
          215  +# a pkgIndex.tcl file or anything else at extension build time.
   206    216   #--------------------------------------------------------------------
   207    217   
   208    218   TEA_PROG_TCLSH
   209    219   #TEA_PROG_WISH
   210    220   
   211    221   #--------------------------------------------------------------------
   212    222   # Add some private preprocessor options
   213    223   #--------------------------------------------------------------------
   214    224   
   215    225   TDOM_ENABLE_DTD
   216    226   TDOM_ENABLE_NS
   217    227   TDOM_ENABLE_UNKNOWN
   218    228   TDOM_ENABLE_TDOMALLOC
          229  +TDOM_ENABLE_LESS_NS
   219    230   
   220    231   TDOMSHELL=tcldomsh
   221    232   AC_SUBST(TDOMSHELL)
   222    233   
   223    234   TDOM_EXPORT_CONFIG
   224    235   
   225    236   #--------------------------------------------------------------------
   226    237   # Finally, substitute all of the various values into the Makefile.
   227    238   # You may alternatively have a special pkgIndex.tcl.in or other files
   228    239   # which require substituting th AC variables in.  Include these here.
   229    240   #--------------------------------------------------------------------
   230    241   
   231    242   AC_OUTPUT([Makefile tdomConfig.sh])

Added doc/INDEX.MAP.

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

Changes to doc/category-index.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <h1 class="title" align="center">tDOM manual: Index</h1><p class="navaid" align="center">
     7         -<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>
            7  +<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>
     8      8   </p><hr class="navsep"><div class="navbar">
     9         -<a href="#cat_cmd">Tcl commands</a> · <a href="#cat_fun">C functions</a> · </div>
            9  +<a href="#cat_cmd">Tcl commands</a> · <a href="#cat_fun">C functions</a> · </div>
    10     10   </div><div class="body">
    11         -<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,
           11  +<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,
    12     12            CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo</a>
    13     13   </div><div class="footer">
    14     14   <hr class="navsep"><div class="navbar" align="center">
    15         -<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>
           15  +<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>
    16     16   </div>
    17     17   </div>
    18     18   </body>
    19     19   </html>

Changes to doc/dom.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <div class="navbar" align="center">
     7         -<a href="#SECTid0x80b16e8">NAME</a> · <a href="#SECTid0x80b1760">SYNOPSIS</a> · <a href="#SECTid0x80b1828">DESCRIPTION </a> · <a href="#SECTid0x80b3f38">KEYWORDS</a>
            7  +<a href="#SECTid0xc37960">NAME</a> · <a href="#SECTid0xbe8eb0">SYNOPSIS</a> · <a href="#SECTid0xb3ad40">DESCRIPTION </a> · <a href="#SECTid0xc83270">KEYWORDS</a>
     8      8   </div><hr class="navsep">
     9      9   </div><div class="body">
    10         -  <h2><a name="SECTid0x80b16e8">NAME</a></h2><p class="namesection">
           10  +  <h2><a name="SECTid0xc37960">NAME</a></h2><p class="namesection">
    11     11   <b class="names">dom - </b><br>Create an in-memory DOM tree from XML</p>
    12     12     
    13         -  <h2><a name="SECTid0x80b1760">SYNOPSIS</a></h2><pre class="syntax">package require tdom
           13  +  <h2><a name="SECTid0xbe8eb0">SYNOPSIS</a></h2><pre class="syntax">package require tdom
    14     14   
    15     15   <b class="cmd">dom</b> <i class="m">method</i> ?<i class="m">arg arg ...</i>?</pre>
    16     16   
    17         -  <h2><a name="SECTid0x80b1828">DESCRIPTION </a></h2><p>This command provides the creation of complete DOM trees in memory. In
           17  +  <h2><a name="SECTid0xb3ad40">DESCRIPTION </a></h2><p>This command provides the creation of DOM trees in memory. In
    18     18   the usual case a string containing a XML information is parsed and converted
    19         -into a DOM tree. <i class="m">method</i> indicates a specific subcommand. </p><p>The valid methods are:</p><dl class="commandlist">
           19  +into a DOM tree. Other possible parse input may be HTML or JSON.
           20  +The <i class="m">method</i> indicates a specific subcommand. </p><p>The valid methods are:</p><dl class="commandlist">
    20     21           
    21     22             <dt>
    22     23   <b class="cmd">dom</b> <b class="method">parse</b> ?<i class="m">options</i>? ?<i class="m">data</i>?</dt>
    23     24             <dd>Parses the XML information and builds up the DOM tree in memory
    24     25   providing a Tcl object command to this DOM document object. Example:
    25     26   
    26     27         <pre class="example">
................................................................................
    54     55                 
    55     56                   <dt><b>-simple</b></dt> 
    56     57                   <dd>If <i class="m">-simple</i> is
    57     58   specified, a simple but fast parser is used (conforms not fully to XML
    58     59   recommendation). That should double parsing and DOM generation speed. The
    59     60   encoding of the data is not transformed inside the parser. The simple parser
    60     61   does not respect any encoding information in the XML declaration. It skips over
    61         -the internal DTD subset and ignores any information in it. Therefor it doesn't
           62  +the internal DTD subset and ignores any information in it. Therefore it doesn't
    62     63   include defaulted attribute values into the tree, even if the according
    63     64   attribute declaration is in the internal subset. It also doesn't expand
    64     65   internal or external entity references other than the predefined entities and
    65     66   character references.</dd>
    66     67                 
    67     68   
    68     69                 
    69     70                   <dt><b>-html</b></dt>
    70     71                   <dd>If <i class="m">-html</i> is specified, a fast HTML parser is 
    71     72   used, which tries to even parse badly formed HTML into a DOM tree.</dd>
    72     73                 
    73         -       
           74  +
           75  +              
           76  +                <dt><b>-html5</b></dt>
           77  +                <dd>This option is only available if tDOM was build
           78  +                with --enable-html5. Try the <i class="m">featureinfo</i> method
           79  +                if you need to know if this feature is build in. If
           80  +                <i class="m">-html5</i> is specified, the gumbo lib html5 parser
           81  +                (https://github.com/google/gumbo-parser) is used to
           82  +                build the DOM tree. This is, as far as it goes, XML
           83  +                namespace-aware. Since this probably isn't wanted by a
           84  +                lot of users and adds only burden for no good in a lot
           85  +                of use cases <i class="m">-html5</i> can be combined with
           86  +                <i class="m">-ignorexmlns</i>, in which case all nodes and
           87  +                attributes in the DOM tree are not in an XML
           88  +                namespace. All tag and attribute names in the DOM tree
           89  +                will be lower case, even for foreign elements not in
           90  +                the xhtml, svg or mathml namespace. The DOM tree may
           91  +                include nodes, that the parser inserted because they
           92  +                are implied by the context (as &lt;head&gt;,
           93  +                &lt;tbody&gt;, etc.).</dd>
           94  +              
           95  +
           96  +              
           97  +                <dt><b>-json</b></dt>
           98  +                <dd>If <i class="m">-json</i> is specified, the <i class="m">data</i> is
           99  +                expected to be a valid JSON string (according to RFC
          100  +                7159). The command returns an ordinary DOM document
          101  +                with nesting token inside the JSON data translated
          102  +                into tree hierarchy. If a JSON array value is itself
          103  +                an object or array then container element nodes named
          104  +                (in a default build) arraycontainer or
          105  +                objectcontainer, respectively, are inserted into the
          106  +                tree. The JSON serialization of this document (with
          107  +                the domDoc method <i class="m">asJSON</i>) is the same JSON
          108  +                information as the <i class="m">data</i>, preserving JSON
          109  +                datatypes, allowing non-unique member names of objects
          110  +                while preserving their order and the full range of
          111  +                JSON string values. JSON datatype handling is done
          112  +                with an additional property "sticking" at the doc and
          113  +                tree nodes. This property isn't contained in an XML
          114  +                serialization of the document. If you need to store
          115  +                the JSON data represented by a document, store the
          116  +                JSON serialization and parse it back from there. Apart
          117  +                from this JSON type information the returned doc
          118  +                command or handle is an ordinary DOM doc, which may be
          119  +                investigated or modified with the full range of the
          120  +                doc and node methods. Please note that the element
          121  +                node names and the text node values within the tree
          122  +                may be outside of what the appropriate XML productions
          123  +                allow.</dd>
          124  +              
          125  +
          126  +              
          127  +                <dt>
          128  +<b>-jsonmaxnesting</b> <i>integer</i>
          129  +</dt>
          130  +                
          131  +                <dd>This option only has effect if used together
          132  +                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>
          133  +              
          134  +              
          135  +              
          136  +                <dt><b>--</b></dt> 
          137  +                <dd>The option <i class="m">--</i> marks the end of options.
          138  +                While respected in general this option is only needed
          139  +                in case of parsing JSON data, which may start with a
          140  +                "-".</dd>
          141  +              
          142  +
    74    143                 
    75    144                   <dt><b>-keepEmpties</b></dt> 
    76    145                   <dd>If <i class="m">-keepEmpties</i> is
    77         -specified, text nodes, which contain only whitespaces, will be part of the
          146  +specified then text nodes which contain only whitespaces will be part of the
    78    147   resulting DOM tree. In default case (<i class="m">-keepEmpties</i> not given) those empty
    79    148   text nodes are removed at parsing time.</dd>
    80    149                 
    81    150   
          151  +              
          152  +                <dt><b>-keepCDATA</b></dt> 
          153  +                <dd>If <i class="m">-keepCDATA</i> is
          154  +specified then CDATA sections aren't added to the tree as text nodes
          155  +(and, if necessary, combined with sibling text nodes into one text
          156  +node) as without this option but are added as CDATA_SECTION_NODEs to
          157  +the tree. Please note that the resulting tree isn't prepared for XPath
          158  +selects or to be the source or the stylesheet of an XSLT
          159  +transformation. If not combined with <i class="m">-keepEmpties</i> only not
          160  +whitespace only CDATA sections will be added to the resulting DOM
          161  +                tree.</dd>
          162  +              
          163  +              
    82    164                 
    83    165                   <dt>
    84    166   <b>-channel</b> <i>&lt;channel-ID&gt;</i>
    85    167   </dt>
    86    168                   
    87    169                   <dd>If <i class="m">-channel &lt;channel-ID&gt;</i> is specified, the
    88    170   input to be parsed is read from the specified channel. The encoding setting of
    89    171   the channel (via fconfigure -encoding) is respected, ie the data read from the
    90         -channel are converted to UTF-8 according to the encoding settings, befor the
          172  +channel are converted to UTF-8 according to the encoding settings before the
    91    173   data is parsed.</dd>
    92    174                 
    93    175   
    94    176                 
    95    177                   <dt>
    96    178   <b>-baseurl</b> <i>&lt;baseURI&gt;</i>
    97    179   </dt>
    98    180                   
    99         -                <dd>If <i class="m">-baseurl &lt;baseURI&gt;</i> is specified, the
   100         -baseURI is used as the base URI of the document. External entities referenced
   101         -in the document are resolved relative to this base URI. This base URI is also
   102         -stored within the DOM tree.</dd>
          181  +                <dd>If <i class="m">-baseurl &lt;baseURI&gt;</i> is specified,
          182  +                the baseURI is used as the base URI of the document.
          183  +                External entities references in the document are
          184  +                resolved relative to this base URI. This base URI is
          185  +                also stored within the DOM tree.</dd>
   103    186                 
   104    187   
   105    188                 
   106    189                   <dt>
   107    190   <b>-feedbackAfter</b> <i>&lt;#bytes&gt;</i>
   108    191   </dt>
   109    192                   
   110         -                <dd>If <i class="m">-feedbackAfter &lt;#bytes&gt;</i> is specified, the
   111         -tcl command ::dom::domParseFeedback is evaluated after parsing every #bytes. If
   112         -you use this option, you have to create a tcl proc named
   113         -::dom::domParseFeedback, otherwise you will get an error. Please notice, that
   114         -the calls of ::dom::domParseFeedback are not done exactly every #bytes, but
   115         -always at the first element start after every #bytes.</dd>
          193  +                <dd>If <i class="m">-feedbackAfter &lt;#bytes&gt;</i> is
          194  +                specified, the tcl command given by
          195  +                <i class="m">-feedbackcmd</i> is evaluated at the first element
          196  +                start within the document (or an external entity)
          197  +                after the start of the document or external entity or
          198  +                the last such call after #bytes. For backward
          199  +                compatibility if no -feedbackcmd is given but there is
          200  +                a tcl proc named ::dom::domParseFeedback this proc is
          201  +                used as -feedbackcmd. If there isn't such a proc and
          202  +                -feedbackAfter is used it is an error to not also use
          203  +                -feedbackcmd. If the called script raises error, then
          204  +                parsing will be aborted, the <i class="m">dom parse</i> call
          205  +                returns error, with the script error msg as error msg.
          206  +                If the called script <i class="m">return -code break</i>, the
          207  +                parsing will abort and the <i class="m">dom parse</i> call will
          208  +                return the empty string.</dd>
          209  +              
          210  +
          211  +              
          212  +                <dt>
          213  +<b>-feedbackcmd</b> <i>&lt;script&gt;</i>
          214  +</dt>
          215  +                
          216  +                <dd>If <i class="m">-feedbackcmd &lt;script&gt;</i> is specified, the
          217  +script <i class="m">script</i> is evaluated at the first
          218  +element start within the document (or an external entity) after the
          219  +start of the document or external entity or the last such call after
          220  +#bytes value given by the <i class="m">-feedbackAfter</i> option. If
          221  +<i class="m">-feedbackAfter</i> isn't given, using this option
          222  +doesn't has any effect. If the called
          223  +script raises error, then parsing will be aborted, the
          224  +<i class="m">dom parse</i> call returns error, with the script
          225  +error msg as error msg. If the called script <i class="m">return
          226  +-code break</i>, the parsing will abort and the <i class="m">dom
          227  +parse</i> call will return the empty string.</dd>
   116    228                 
   117    229   
   118    230                 
   119    231                   <dt>
   120    232   <b>-externalentitycommand</b> <i>&lt;script&gt;</i>
   121    233   </dt>
   122    234                   
   123    235                   <dd>If <i class="m">-externalentitycommand &lt;script&gt;</i> is
   124    236   specified, the specified tcl script is called to resolve any external entities
   125    237   of the document. The actual evaluated command consists of this option followed
   126    238   by three arguments: the base uri, the system identifier of the entity and the
   127    239   public identifier of the entity. The base uri and the public identifier may be
   128    240   the empty list. The script has to return a tcl list consisting of three
   129         -elements. The first element of this list signals, how the external entity is
   130         -returned to the processor. At the moment, the two allowed types are "string"
          241  +elements. The first element of this list signals how the external entity is
          242  +returned to the processor. Currently the two allowed types are "string"
   131    243   and "channel". The second element of the list has to be the (absolute) base URI
   132    244   of the external entity to be parsed.  The third element of the list are data,
   133    245   either the already read data out of the external entity as string in the case
   134    246   of type "string", or the name of a tcl channel, in the case of type
   135    247   "channel". Note that if the script returns a tcl channel, it will not be closed
   136    248   by the processor.  It must be closed separately if it is no longer
   137         -required.</dd>
          249  +needed.</dd>
   138    250                 
   139    251   
   140    252                 
   141    253                   <dt>
   142    254   <b>-useForeignDTD</b> <i>&lt;boolean&gt;</i>
   143    255   </dt>
   144    256                   
   145    257                   <dd>If &lt;boolean&gt; is true and the document does not have
   146    258   an external subset, the parser will call the -externalentitycommand script with
   147         -empty values for the systemId and publicID arguments. Pleace notice, that, if
          259  +empty values for the systemId and publicID arguments. Please note that if
   148    260   the document also doesn't have an internal subset, the
   149    261   -startdoctypedeclcommand and -enddoctypedeclcommand scripts, if set, are not
   150    262   called. The <i class="m">-useForeignDTD</i> respects </dd>
   151    263                 
   152    264   
   153    265                 
   154    266                   <dt>
   155    267   <b>-paramentityparsing</b> <i>&lt;always|never|notstandalone&gt;</i>
   156    268   </dt>
   157    269                   
   158         -                <dd>The <i class="m">-paramentityparsing</i> option controls, if the
   159         -parser tries to resolve the external entities (including the external DTD
   160         -subset) of the document, while building the DOM
   161         -tree. <i class="m">-paramentityparsing</i> requires an argument, which must be either
   162         -"always", "never", or "notstandalone". The value "always" means, that the
   163         -parser tries to resolves (recursively) all external entities of the XML
   164         -source. This is the default, in case <i class="m">-paramentityparsing</i> is omitted. The
   165         -value "never" means, that only the given XML source is parsed and no external
   166         -entity (including the external subset) will be resolved and parsed. The value
   167         -"notstandalone" means, that all external entities will be resolved and parsed,
   168         -with the execption of documents, which explicitly states standalone="yes" in
   169         -their XML declaration.</dd>
          270  +                <dd>The <i class="m">-paramentityparsing</i> option controls,
          271  +                if the parser tries to resolve the external entities
          272  +                (including the external DTD subset) of the document
          273  +                while building the DOM tree.
          274  +                <i class="m">-paramentityparsing</i> requires an argument, which
          275  +                must be either "always", "never", or "notstandalone".
          276  +                The value "always" means that the parser tries to
          277  +                resolves (recursively) all external entities of the
          278  +                XML source. This is the default in case
          279  +                <i class="m">-paramentityparsing</i> is omitted. The value
          280  +                "never" means that only the given XML source is
          281  +                parsed and no external entity (including the external
          282  +                subset) will be resolved and parsed. The value
          283  +                "notstandalone" means, that all external entities will
          284  +                be resolved and parsed, with the exception of
          285  +                documents, which explicitly states standalone="yes" in
          286  +                their XML declaration.</dd>
          287  +              
          288  +
          289  +
          290  +              
          291  +                <dt><b>-ignorexmlns</b></dt>
          292  +                <dd>It is recommended, that you only use this option
          293  +                with the <i class="m">-html5</i> option. If this option is
          294  +                given, no node within the created DOM tree will be
          295  +                internally marked as placed into an XML Namespace,
          296  +                even if there is a default namespace in scope for
          297  +                un-prefixed elements or even if the element has a
          298  +                defined namespace prefix. One consequence is that
          299  +                XPath node expressions on such a DOM tree doesn't work
          300  +                as expected. Prefixed element nodes can't be selected
          301  +                and element nodes without prefix will be seen by XPath
          302  +                expressions as if they are not in any namespace (no
          303  +                matter if they are in fact should be in a default
          304  +                namespace).
          305  +                </dd>
   170    306                 
   171    307   
   172    308               </dl>
   173    309   <p></p>
   174    310   </dd>
   175    311           
   176    312   
................................................................................
   193    329   memory handling as explained above.</dd>
   194    330           
   195    331   
   196    332           
   197    333             <dt>
   198    334   <b class="cmd">dom</b> <b class="method">createDocumentNode</b>
   199    335   ?<i class="m">objVar</i>?</dt>
   200         -          <dd>Creates a new, 'empty' DOM document object without any element
          336  +          <dd>Creates a new 'empty' DOM document object without any element
   201    337   node. <i class="m">objVar</i> controls the memory handling as explained above.</dd>
   202    338           
   203    339   
   204         -        
   205         -          <dt>
   206         -<b class="cmd">dom</b> <b class="method">setResultEncoding</b> ?<i class="m">encodingName</i>?</dt>
   207         -          <dd>If <i class="m">encodingName</i> is not given the current global
   208         -result encoding is returned.  Otherwise the global result encoding is set to
   209         -<i class="m">encodingName</i>.  All character data, attribute values, etc. will
   210         -then be converted from UTF-8, which is delivered from the Expat XML parser, to
   211         -the given 8 bit encoding at XML/DOM parse time.  Valid values for
   212         -<i class="m">encodingName</i> are: utf-8, ascii, cp1250, cp1251, cp1252, cp1253,
   213         -cp1254, cp1255, cp1256, cp437, cp850, en, iso8859-1, iso8859-2, iso8859-3,
   214         -iso8859-4, iso8859-5, iso8859-6, iso8859-7, iso8859-8, iso8859-9, koi8-r.</dd>
   215         -        
   216         -
   217    340           
   218    341             <dt>
   219    342   <b class="cmd">dom</b> <b class="method">createNodeCmd</b>
   220         -<i class="m">?-returnNodeCmd?</i> <i class="m">(element|comment|text|cdata|pi)Node</i> <i class="m">commandName</i>
          343  +<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>
   221    344   </dt>
   222         -          <dd>This method creates Tcl commands, which in turn create tDOM nodes.
   223         -Tcl commands created by this command are only avaliable inside a script given to the
   224         -domNode method <i class="m">appendFromScript</i>. If a command created with
   225         -<i class="m">createNodeCmd</i> is invoked in any other context, it will return error. The
   226         -created command <i class="m">commandName</i> replaces any existing command or procedure
   227         -with that name. If the <i class="m">commandName</i> includes any namespace qualifiers, 
   228         -it is created in the specified namespace.
   229         -
   230         -<p>If such command is invoked inside a script given as argument to
   231         -the domNode method <i class="m">appendFromScript</i>, it creates a new node and
   232         -appends this node at the end of the child list of the invoking element
   233         -node. If the option <i class="m">-returnNodeCmd</i> was given, the command returns the
   234         -created node as Tcl command. If this option was omitted, the command returns
   235         -nothing. Each command creates always the same type of node. Which type of 
   236         -node is created by the command is determined by the first argument to the
   237         -<i class="m">createNodeCmd</i>. The syntax of the created command depends on the 
   238         -type of the node it creates.</p>
   239         -
   240         -<p>If the first argument of the method is <i class="m">elementNode</i>, the created
   241         -command will create an element node. The tag name of the created
   242         -node is <i class="m">commandName</i> without namespace qualifiers. The syntax of the 
   243         -created command is:</p>
          345  +          <dd>This method creates Tcl commands, which in turn create
          346  +          tDOM nodes. Tcl commands created by this command are only
          347  +          available inside a script given to the domNode methods
          348  +          <i class="m">appendFromScript</i> or <i class="m">insertBeforeFromScript</i>. If
          349  +          a command created with <i class="m">createNodeCmd</i> is invoked in
          350  +          any other context, it will return error. The created command
          351  +          <i class="m">commandName</i> replaces any existing command or
          352  +          procedure with that name. If the <i class="m">commandName</i> includes
          353  +          any namespace qualifiers, it is created in the specified
          354  +          namespace. The <i class="m">-tagName</i> option is only allowed for
          355  +          the elementNode type. The <i class="m">-jsonType</i> option is only
          356  +          allowed for elementNode and textNode types.
          357  +
          358  +<p>If such command is invoked inside a script given as argument to the
          359  +domNode method <i class="m">appendFromScript</i> or
          360  +<i class="m">insertBeforeFromScript</i> it creates a new node and appends this
          361  +node at the end of the child list of the invoking element node. If the
          362  +option <i class="m">-returnNodeCmd</i> was given, the command returns the
          363  +created node as Tcl command. If this option was omitted, the command
          364  +returns nothing. Each command creates always the same type of node.
          365  +Which type of node is created by the command is determined by the
          366  +first argument to the <i class="m">createNodeCmd</i>. The syntax of the created
          367  +command depends on the type of the node it creates.</p>
          368  +
          369  +<p>If the command type to create is <i class="m">elementNode</i>, the created
          370  +command will create an element node, if called. Without the
          371  +<i class="m">-tagName</i> option the tag name of the created node is
          372  +<i class="m">commandName</i> without namespace qualifiers. If the
          373  +<i class="m">-tagName</i> option was given then the created command the created
          374  +elements will have this tag name. If the <i class="m">-jsonType</i> option was
          375  +given then the created node elements will have the given JSON type. If
          376  +the <i class="m">-namespace</i> option is given the created element node will be
          377  +XML namespaced and in the namespace given by the option. The element
          378  +name will be literal as given either by the command name or the
          379  +<i class="m">-tagname</i> option, if that was given. An appropriate XML
          380  +namespace declaration will be automatically added, to bind the prefix
          381  +(if the element name has one) or the default namespace (if the element
          382  +name hasn't a prefix) to the namespace if such a binding isn't in
          383  +scope.</p>
          384  +
          385  +<p>The syntax of the created command is:</p>
   244    386   
   245    387   <pre class="syntax">
   246    388   <b class="cmd">elementNodeCmd</b> <i class="m">?attributeName attributeValue ...? ?script?</i>
   247    389   <b class="cmd">elementNodeCmd</b> <i class="m">?-attributeName attributeValue ...? ?script?</i>
   248    390   <b class="cmd">elementNodeCmd</b> <i class="m">name_value_list script</i>
   249    391   </pre>
   250    392   
................................................................................
   258    400   will be stripped off.</p>
   259    401   
   260    402   <p>Every <i class="m">elementNodeCmd</i> accepts an optional Tcl script as last
   261    403   argument. This script is evaluated as recursive <i class="m">appendFromScript</i> script
   262    404   with the node created by the <i class="m">elementNodeCmd</i> as parent of all nodes
   263    405   created by the script.</p>
   264    406   
   265         -<p>If the first argument of the method is <i class="m">textNode</i>, the command will create
   266         -a text node. The syntax of the created command is:</p>
          407  +<p>If the first argument of the method is <i class="m">textNode</i>, the command
          408  +will create a text node. If the <i class="m">-jsonType</i> option was given then
          409  +the created text node will have that JSON type. The syntax of the
          410  +created command is:</p>
   267    411   
   268    412   <pre class="syntax">
   269    413   <b class="cmd">textNodeCmd</b> ?-disableOutputEscaping? <i class="m">data</i>
   270    414   </pre>
   271    415   
   272    416   <p>If the optional flag <i class="m">-disableOutputEscaping</i> is given, the
   273    417   escaping of the ampersand character (&amp;) and the left angle bracket (&lt;)
   274    418   inside the data is disabled. You should use this flag carefully.</p>
   275    419   
   276         -<p>If the first argument of the method is <i class="m">commentNode</i>, or 
   277         -<i class="m">cdataNode</i>, the command will create an comment node or CDATA section 
          420  +<p>If the first argument of the method is <i class="m">commentNode</i> or 
          421  +<i class="m">cdataNode</i> the command will create an comment node or CDATA section 
   278    422   node. The syntax of the created command is:</p>
   279    423   
   280    424   <pre class="syntax">
   281    425   <b class="cmd">nodeCmd</b> <i class="m">data</i>
   282    426   </pre>
   283    427   
   284    428   <p>If the first argument of the method is <i class="m">piNode</i>, the command will
................................................................................
   293    437           
   294    438   
   295    439           
   296    440             <dt>
   297    441   <b class="cmd">dom</b> <b class="method">setStoreLineColumn</b> <i class="m">?boolean</i>?</dt>
   298    442             <dd>If switched on, the DOM nodes will contain line and column
   299    443   position information for the original XML document after parsing. The default
   300         -is, not to store line and column position information.</dd>
          444  +is not to store line and column position information.</dd>
   301    445           
   302    446   
   303    447           
   304    448             <dt>
   305    449   <b class="cmd">dom</b> <b class="method">setNameCheck</b> <i class="m">?boolean</i>?</dt>
   306    450             <dd>If NameCheck is true, every method which expects an XML Name,
   307    451   a full qualified name or a processing instructing target will check, if the
   308         -given string is valid according to his production rule. For commands created
          452  +given string is valid according to its production rule. For commands created
   309    453   with the <i class="m">createNodeCmd</i> method to be used in the context of
   310    454   <i class="m">appendFromScript</i> the status of the flag at creation time
   311    455   decides. If NameCheck is true at creation time, the command will
   312         -check his arguments, otherwise not. The <i class="m">setNameCheck</i>
          456  +check its arguments, otherwise not. The <i class="m">setNameCheck</i>
   313    457   set this flag. It returns the current NameCheck flag state. The
   314    458   default state for NameCheck is true. </dd>
   315    459           
   316    460   
   317    461           
   318    462             <dt>
   319    463   <b class="cmd">dom</b> <b class="method">setTextCheck</b> <i class="m">?boolean</i>?</dt>
   320    464             <dd>If TextCheck is true, every command which expects XML Chars,
   321    465   a comment, a CDATA section value or a processing instructing value will check,
   322         -if the given string is valid according to his production rule. For commands
          466  +if the given string is valid according to its production rule. For commands
   323    467   created with the <i class="m">createNodeCmd</i> method to be used in the
   324    468   context of <i class="m">appendFromScript</i> the status of the flag at
   325    469   creation time decides. If TextCheck is true at creation time, the
   326         -command will check his arguments, otherwise not.The
   327         -<i class="m">setTextCheck</i> method set this flag. It returns the current
          470  +command will check its arguments, otherwise not.The
          471  +<i class="m">setTextCheck</i> method sets this flag. It returns the current
   328    472   TextCheck flag state. The default state for TextCheck is true.</dd>
   329    473         
   330    474   
   331    475           
   332    476             <dt>
   333    477   <b class="cmd">dom</b> <b class="method">setObjectCommands</b> ?<i class="m">(automatic|token|command)</i>?</dt>
   334         -          <dd>Controls, if documents and nodes are created as tcl commands or
          478  +          <dd>Controls if documents and nodes are created as tcl commands or
   335    479   as token to be
   336    480   used with the domNode and domDoc commands. If the mode is
   337    481   'automatic', then methods used at tcl commands will create tcl
   338    482   commands and methods used at doc or node tokes will create tokens. If
   339    483   the mode is 'command' then always tcl commands will be created. If
   340    484   the mode is 'token', then always token will be created. The method
   341    485   returns the current mode. This method is an experimental interface.</dd>
   342    486         
   343    487   
   344    488           
   345    489             <dt>
   346    490   <b class="cmd">dom</b> <b class="method">isName</b> <i class="m">name</i>
   347    491   </dt>
   348         -          <dd>Returns 1, if <i class="m">name</i> is a valid XML Name according to
          492  +          <dd>Returns 1 if <i class="m">name</i> is a valid XML Name according to
   349    493   production 5 of the <a href="http://www.w3.org/TR/2004/REC-xml-20040204/#NT-NameChar">XML
   350         -            1.0</a> recommendation. This means, that <i class="m">name</i> is a valid
          494  +            1.0</a> recommendation. This means that <i class="m">name</i> is a valid
   351    495             XML element or attribute name. Otherwise it returns 0.</dd>
   352    496           
   353    497   
   354    498           
   355    499             <dt>
   356    500   <b class="cmd">dom</b> <b class="method">isPIName</b> <i class="m">name</i>
   357    501   </dt>
   358         -          <dd>Returns 1, if <i class="m">name</i> is a valid XML processing instruction
          502  +          <dd>Returns 1 if <i class="m">name</i> is a valid XML processing instruction
   359    503             target according to
   360    504   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>
   361    505           
   362    506   
   363    507           
   364    508             <dt>
   365    509   <b class="cmd">dom</b> <b class="method">isNCName</b> <i class="m">name</i>
   366    510   </dt>
   367         -          <dd>Returns 1, if <i class="m">name</i> is a valid NCName according
          511  +          <dd>Returns 1 if <i class="m">name</i> is a valid NCName according
   368    512   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
   369    513   0.</dd>
   370    514           
   371    515   
   372    516           
   373    517             <dt>
   374    518   <b class="cmd">dom</b> <b class="method">isQName</b> <i class="m">name</i>
   375    519   </dt>
   376         -          <dd>Returns 1, if <i class="m">name</i> is a valid QName according
          520  +          <dd>Returns 1 if <i class="m">name</i> is a valid QName according
   377    521   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
   378    522   0.</dd>
   379    523           
   380    524   
   381    525           
   382    526             <dt>
   383    527   <b class="cmd">dom</b> <b class="method">isCharData</b>
   384    528   <i class="m">string</i>
   385    529   </dt>
   386         -          <dd>Returns 1, if every character in <i class="m">string</i> is
          530  +          <dd>Returns 1 if every character in <i class="m">string</i> is
   387    531   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>
   388    532   recommendation. Otherwise it returns 0.</dd>
   389    533           
          534  +
          535  +        
          536  +          <dt>
          537  +<b class="cmd">dom</b> <b class="method">isBMPCharData</b>
          538  +<i class="m">string</i>
          539  +</dt>
          540  +          <dd>Returns 1 if every character in <i class="m">string</i> is
          541  +a valid XML Char with a Unicode code point within the Basic
          542  +Multilingual Plane (that means, that every character within the string
          543  +is at most 3 bytes long). Otherwise it returns 0.</dd>
          544  +        
   390    545   
   391    546           
   392    547             <dt>
   393    548   <b class="cmd">dom</b> <b class="method">isComment</b>
   394    549   <i class="m">string</i>
   395    550   </dt>
   396         -          <dd>Returns 1, if <i class="m">string</i> is
          551  +          <dd>Returns 1 if <i class="m">string</i> is
   397    552   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>
   398    553   recommendation. Otherwise it returns 0.</dd>
   399    554           
   400    555   
   401    556           
   402    557             <dt>
   403    558   <b class="cmd">dom</b> <b class="method">isCDATA</b>
   404    559   <i class="m">string</i>
   405    560   </dt>
   406         -          <dd>Returns 1, if <i class="m">string</i> is
          561  +          <dd>Returns 1 if <i class="m">string</i> is
   407    562   valid according to production 20 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
   408    563   recommendation. Otherwise it returns 0.</dd>
   409    564           
   410    565   
   411    566           
   412    567             <dt>
   413    568   <b class="cmd">dom</b> <b class="method">isPIValue</b>
   414    569   <i class="m">string</i>
   415    570   </dt>
   416         -          <dd>Returns 1, if <i class="m">string</i> is
          571  +          <dd>Returns 1 if <i class="m">string</i> is
   417    572   valid according to production 16 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
   418    573   recommendation. Otherwise it returns 0.</dd>
   419    574           
   420    575   
   421         -      </dl>
          576  +        
          577  +            <dt>
          578  +<b class="cmd">dom</b> <b class="method">featureinfo</b> <i class="m">feature</i>
          579  +</dt>
          580  +            <dd>This method provides information about the used
          581  +            build options and the expat version. The valid values for
          582  +            the <i class="m">feature</i> argument are:
          583  +            <dl class="optlist">
          584  +                
          585  +                    <dt><b>expatversion</b></dt>
          586  +                    <dd>Returns the version of the underlyling expat
          587  +                    version as string, something like
          588  +                    "exapt_2.1.0". This is what the expat API
          589  +                    function XML_ExpatVersion() returns.</dd>
          590  +                
          591  +                
          592  +                    <dt><b>expatmajorversion</b></dt>
          593  +                    <dd>Returns the major version of the underlyling
          594  +                    expat version as integer.</dd>
          595  +                
          596  +                
          597  +                    <dt><b>expatminorversion</b></dt>
          598  +                    <dd>Returns the minor version of the underlyling
          599  +                    expat version as integer.</dd>
          600  +                
          601  +                
          602  +                    <dt><b>expatmicroversion</b></dt>
          603  +                    <dd>Returns the micro version of the underlyling
          604  +                    expat version as integer.</dd>
          605  +                
          606  +                
          607  +                    <dt><b>dtd</b></dt>
          608  +                    <dd>Returns as boolean if build with
          609  +                    <i class="m">--enable-dtd</i>.</dd>
          610  +                
          611  +                
          612  +                    <dt><b>ns</b></dt>
          613  +                    <dd>Returns as boolean if build with
          614  +                    <i class="m">--enable-ns</i>.</dd>
          615  +                
          616  +                
          617  +                    <dt><b>unknown</b></dt>
          618  +                    <dd>Returns as boolean if build with
          619  +                    <i class="m">--enable-unknown</i>.</dd>
          620  +                
          621  +                
          622  +                    <dt><b>tdomalloc</b></dt>
          623  +                    <dd>Returns as boolean if build with
          624  +                    <i class="m">--enable-tdomalloc</i>.</dd>
          625  +                
          626  +                
          627  +                    <dt><b>lessns</b></dt>
          628  +                    <dd>Returns as boolean if build with
          629  +                    <i class="m">--enable-lessns</i>.</dd>
          630  +                
          631  +                
          632  +                    <dt><b>TCL_UTF_MAX</b></dt>
          633  +                    <dd>Returns the TCL_UTF_MAX value of the tcl
          634  +                    core, tDOM was build with as integer</dd>
          635  +                
          636  +                
          637  +                    <dt><b>html5</b></dt>
          638  +                    <dd>Returns as boolean, if build with
          639  +                    <i class="m">--enable-html5</i>.</dd>
          640  +                
          641  +                
          642  +                    <dt><b>versionhash</b></dt>
          643  +                    <dd>Returns the fossil repository version hash.</dd>
          644  +                
          645  +                
          646  +                    <dt><b>pullparser</b></dt>
          647  +                    <dd>Returns as boolean if the pullparser command
          648  +                    is build in.</dd>
          649  +                
          650  +            </dl>
          651  +            </dd>   
          652  +        
          653  +    </dl>
   422    654   
   423         -  <h2><a name="SECTid0x80b3f38">KEYWORDS</a></h2><p class="keywords">
          655  +<h2><a name="SECTid0xc83270">KEYWORDS</a></h2><p class="keywords">
   424    656   <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>
   425    657   </p>
   426         -</div><div class="footer">
   427         -<hr class="navsep"><!-- footer.html: Standard navigational footer --><div class="navbar" align="center">
   428         -        <a class="navaid" href="index.html">tDOM Overview</a>
   429         - ·	<a class="navaid" href="doc-index.html">Table of Contents</a>
   430         - ·	<a class="navaid" href="category-index.html">Index</a>
   431         - ·	<a class="navaid" href="keyword-index.html">Keywords</a>
   432         -</div>
          658  +</div><hr class="navsep"><div class="navbar" align="center">
          659  +<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>
   433    660   </div>
   434    661   </body>
   435    662   </html>

Changes to doc/dom.n.

   166    166   package require tdom
   167    167   
   168    168   \&\fBdom\fP \fImethod\fR ?\fIarg arg ...\fR?
   169    169   .fi
   170    170   .BE
   171    171   .SH "DESCRIPTION "
   172    172   .PP
   173         -This command provides the creation of complete DOM trees in memory. In
          173  +This command provides the creation of DOM trees in memory. In
   174    174   the usual case a string containing a XML information is parsed and converted
   175         -into a DOM tree. \fImethod\fR indicates a specific subcommand.
          175  +into a DOM tree. Other possible parse input may be HTML or JSON.
          176  +The \fImethod\fR indicates a specific subcommand.
   176    177   .PP
   177    178   The valid methods are:
   178    179   .TP
   179    180   \&\fB\fBdom\fP \fBparse\fP ?\fIoptions\fB? ?\fIdata\fB?
   180    181   \&\fRParses the XML information and builds up the DOM tree in memory
   181    182   providing a Tcl object command to this DOM document object. Example:
   182    183   
................................................................................
   225    226   The valid options are:
   226    227   .IP "\fB-simple\fR"
   227    228   If \fI-simple\fR is
   228    229   specified, a simple but fast parser is used (conforms not fully to XML
   229    230   recommendation). That should double parsing and DOM generation speed. The
   230    231   encoding of the data is not transformed inside the parser. The simple parser
   231    232   does not respect any encoding information in the XML declaration. It skips over
   232         -the internal DTD subset and ignores any information in it. Therefor it doesn't
          233  +the internal DTD subset and ignores any information in it. Therefore it doesn't
   233    234   include defaulted attribute values into the tree, even if the according
   234    235   attribute declaration is in the internal subset. It also doesn't expand
   235    236   internal or external entity references other than the predefined entities and
   236    237   character references.
   237    238   .IP "\fB-html\fR"
   238    239   If \fI-html\fR is specified, a fast HTML parser is
   239    240   used, which tries to even parse badly formed HTML into a DOM tree.
          241  +.IP "\fB-html5\fR"
          242  +This option is only available if tDOM was build
          243  +with --enable-html5. Try the \fIfeatureinfo\fR method
          244  +if you need to know if this feature is build in. If
          245  +\&\fI-html5\fR is specified, the gumbo lib html5 parser
          246  +(https://github.com/google/gumbo-parser) is used to
          247  +build the DOM tree. This is, as far as it goes, XML
          248  +namespace-aware. Since this probably isn't wanted by a
          249  +lot of users and adds only burden for no good in a lot
          250  +of use cases \fI-html5\fR can be combined with
          251  +\&\fI-ignorexmlns\fR, in which case all nodes and
          252  +attributes in the DOM tree are not in an XML
          253  +namespace. All tag and attribute names in the DOM tree
          254  +will be lower case, even for foreign elements not in
          255  +the xhtml, svg or mathml namespace. The DOM tree may
          256  +include nodes, that the parser inserted because they
          257  +are implied by the context (as <head>,
          258  +<tbody>, etc.).
          259  +.IP "\fB-json\fR"
          260  +If \fI-json\fR is specified, the \fIdata\fR is
          261  +expected to be a valid JSON string (according to RFC
          262  +7159). The command returns an ordinary DOM document
          263  +with nesting token inside the JSON data translated
          264  +into tree hierarchy. If a JSON array value is itself
          265  +an object or array then container element nodes named
          266  +(in a default build) arraycontainer or
          267  +objectcontainer, respectively, are inserted into the
          268  +tree. The JSON serialization of this document (with
          269  +the domDoc method \fIasJSON\fR) is the same JSON
          270  +information as the \fIdata\fR, preserving JSON
          271  +datatypes, allowing non-unique member names of objects
          272  +while preserving their order and the full range of
          273  +JSON string values. JSON datatype handling is done
          274  +with an additional property "sticking" at the doc and
          275  +tree nodes. This property isn't contained in an XML
          276  +serialization of the document. If you need to store
          277  +the JSON data represented by a document, store the
          278  +JSON serialization and parse it back from there. Apart
          279  +from this JSON type information the returned doc
          280  +command or handle is an ordinary DOM doc, which may be
          281  +investigated or modified with the full range of the
          282  +doc and node methods. Please note that the element
          283  +node names and the text node values within the tree
          284  +may be outside of what the appropriate XML productions
          285  +allow.
          286  +.IP "\fB-jsonmaxnesting  \fIinteger\fP\fR"
          287  +This option only has effect if used together
          288  +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.
          289  +.IP "\fB--\fR"
          290  +The option \fI--\fR marks the end of options.
          291  +While respected in general this option is only needed
          292  +in case of parsing JSON data, which may start with a
          293  +"-".
   240    294   .IP "\fB-keepEmpties\fR"
   241    295   If \fI-keepEmpties\fR is
   242         -specified, text nodes, which contain only whitespaces, will be part of the
          296  +specified then text nodes which contain only whitespaces will be part of the
   243    297   resulting DOM tree. In default case (\fI-keepEmpties\fR not given) those empty
   244    298   text nodes are removed at parsing time.
          299  +.IP "\fB-keepCDATA\fR"
          300  +If \fI-keepCDATA\fR is
          301  +specified then CDATA sections aren't added to the tree as text nodes
          302  +(and, if necessary, combined with sibling text nodes into one text
          303  +node) as without this option but are added as CDATA_SECTION_NODEs to
          304  +the tree. Please note that the resulting tree isn't prepared for XPath
          305  +selects or to be the source or the stylesheet of an XSLT
          306  +transformation. If not combined with \fI-keepEmpties\fR only not
          307  +whitespace only CDATA sections will be added to the resulting DOM
          308  +tree.
   245    309   .IP "\fB-channel  \fI<channel-ID>\fP\fR"
   246    310   If \fI-channel <channel-ID>\fR is specified, the
   247    311   input to be parsed is read from the specified channel. The encoding setting of
   248    312   the channel (via fconfigure -encoding) is respected, ie the data read from the
   249         -channel are converted to UTF-8 according to the encoding settings, befor the
          313  +channel are converted to UTF-8 according to the encoding settings before the
   250    314   data is parsed.
   251    315   .IP "\fB-baseurl  \fI<baseURI>\fP\fR"
   252         -If \fI-baseurl <baseURI>\fR is specified, the
   253         -baseURI is used as the base URI of the document. External entities referenced
   254         -in the document are resolved relative to this base URI. This base URI is also
   255         -stored within the DOM tree.
          316  +If \fI-baseurl <baseURI>\fR is specified,
          317  +the baseURI is used as the base URI of the document.
          318  +External entities references in the document are
          319  +resolved relative to this base URI. This base URI is
          320  +also stored within the DOM tree.
   256    321   .IP "\fB-feedbackAfter  \fI<#bytes>\fP\fR"
   257         -If \fI-feedbackAfter <#bytes>\fR is specified, the
   258         -tcl command ::dom::domParseFeedback is evaluated after parsing every #bytes. If
   259         -you use this option, you have to create a tcl proc named
   260         -::dom::domParseFeedback, otherwise you will get an error. Please notice, that
   261         -the calls of ::dom::domParseFeedback are not done exactly every #bytes, but
   262         -always at the first element start after every #bytes.
          322  +If \fI-feedbackAfter <#bytes>\fR is
          323  +specified, the tcl command given by
          324  +\&\fI-feedbackcmd\fR is evaluated at the first element
          325  +start within the document (or an external entity)
          326  +after the start of the document or external entity or
          327  +the last such call after #bytes. For backward
          328  +compatibility if no -feedbackcmd is given but there is
          329  +a tcl proc named ::dom::domParseFeedback this proc is
          330  +used as -feedbackcmd. If there isn't such a proc and
          331  +-feedbackAfter is used it is an error to not also use
          332  +-feedbackcmd. If the called script raises error, then
          333  +parsing will be aborted, the \fIdom parse\fR call
          334  +returns error, with the script error msg as error msg.
          335  +If the called script \fIreturn -code break\fR, the
          336  +parsing will abort and the \fIdom parse\fR call will
          337  +return the empty string.
          338  +.IP "\fB-feedbackcmd  \fI<script>\fP\fR"
          339  +If \fI-feedbackcmd <script>\fR is specified, the
          340  +script \fIscript\fR is evaluated at the first
          341  +element start within the document (or an external entity) after the
          342  +start of the document or external entity or the last such call after
          343  +#bytes value given by the \fI-feedbackAfter\fR option. If
          344  +\&\fI-feedbackAfter\fR isn't given, using this option
          345  +doesn't has any effect. If the called
          346  +script raises error, then parsing will be aborted, the
          347  +\&\fIdom parse\fR call returns error, with the script
          348  +error msg as error msg. If the called script \fIreturn
          349  +-code break\fR, the parsing will abort and the \fIdom
          350  +parse\fR call will return the empty string.
   263    351   .IP "\fB-externalentitycommand  \fI<script>\fP\fR"
   264    352   If \fI-externalentitycommand <script>\fR is
   265    353   specified, the specified tcl script is called to resolve any external entities
   266    354   of the document. The actual evaluated command consists of this option followed
   267    355   by three arguments: the base uri, the system identifier of the entity and the
   268    356   public identifier of the entity. The base uri and the public identifier may be
   269    357   the empty list. The script has to return a tcl list consisting of three
   270         -elements. The first element of this list signals, how the external entity is
   271         -returned to the processor. At the moment, the two allowed types are "string"
          358  +elements. The first element of this list signals how the external entity is
          359  +returned to the processor. Currently the two allowed types are "string"
   272    360   and "channel". The second element of the list has to be the (absolute) base URI
   273    361   of the external entity to be parsed.  The third element of the list are data,
   274    362   either the already read data out of the external entity as string in the case
   275    363   of type "string", or the name of a tcl channel, in the case of type
   276    364   "channel". Note that if the script returns a tcl channel, it will not be closed
   277    365   by the processor.  It must be closed separately if it is no longer
   278         -required.
          366  +needed.
   279    367   .IP "\fB-useForeignDTD  \fI<boolean>\fP\fR"
   280    368   If <boolean> is true and the document does not have
   281    369   an external subset, the parser will call the -externalentitycommand script with
   282         -empty values for the systemId and publicID arguments. Pleace notice, that, if
          370  +empty values for the systemId and publicID arguments. Please note that if
   283    371   the document also doesn't have an internal subset, the
   284    372   -startdoctypedeclcommand and -enddoctypedeclcommand scripts, if set, are not
   285    373   called. The \fI-useForeignDTD\fR respects
   286    374   .IP "\fB-paramentityparsing  \fI<always|never|notstandalone>\fP\fR"
   287         -The \fI-paramentityparsing\fR option controls, if the
   288         -parser tries to resolve the external entities (including the external DTD
   289         -subset) of the document, while building the DOM
   290         -tree. \fI-paramentityparsing\fR requires an argument, which must be either
   291         -"always", "never", or "notstandalone". The value "always" means, that the
   292         -parser tries to resolves (recursively) all external entities of the XML
   293         -source. This is the default, in case \fI-paramentityparsing\fR is omitted. The
   294         -value "never" means, that only the given XML source is parsed and no external
   295         -entity (including the external subset) will be resolved and parsed. The value
   296         -"notstandalone" means, that all external entities will be resolved and parsed,
   297         -with the execption of documents, which explicitly states standalone="yes" in
          375  +The \fI-paramentityparsing\fR option controls,
          376  +if the parser tries to resolve the external entities
          377  +(including the external DTD subset) of the document
          378  +while building the DOM tree.
          379  +\&\fI-paramentityparsing\fR requires an argument, which
          380  +must be either "always", "never", or "notstandalone".
          381  +The value "always" means that the parser tries to
          382  +resolves (recursively) all external entities of the
          383  +XML source. This is the default in case
          384  +\&\fI-paramentityparsing\fR is omitted. The value
          385  +"never" means that only the given XML source is
          386  +parsed and no external entity (including the external
          387  +subset) will be resolved and parsed. The value
          388  +"notstandalone" means, that all external entities will
          389  +be resolved and parsed, with the exception of
          390  +documents, which explicitly states standalone="yes" in
   298    391   their XML declaration.
          392  +.IP "\fB-ignorexmlns\fR"
          393  +It is recommended, that you only use this option
          394  +with the \fI-html5\fR option. If this option is
          395  +given, no node within the created DOM tree will be
          396  +internally marked as placed into an XML Namespace,
          397  +even if there is a default namespace in scope for
          398  +un-prefixed elements or even if the element has a
          399  +defined namespace prefix. One consequence is that
          400  +XPath node expressions on such a DOM tree doesn't work
          401  +as expected. Prefixed element nodes can't be selected
          402  +and element nodes without prefix will be seen by XPath
          403  +expressions as if they are not in any namespace (no
          404  +matter if they are in fact should be in a default
          405  +namespace).
   299    406   .PP
   300    407   .RE
   301    408   .TP
   302    409   \&\fB\fBdom\fP \fBcreateDocument\fP \fIdocElemName\fB ?\fIobjVar\fB?
   303    410   \&\fRCreates a new DOM document object with one element node with
   304    411   node name \fIdocElemName\fR. The \fIobjVar\fR controls the
   305    412   memory handling as explained above.
................................................................................
   307    414   \&\fB\fBdom\fP \fBcreateDocumentNS\fP \fIuri\fB \fIdocElemName\fB ?\fIobjVar\fB?
   308    415   \&\fRCreates a new DOM document object with one element node with
   309    416   node name \fIdocElemName\fR. \fIUri\fR gives the namespace of the
   310    417   document element to create. The \fIobjVar\fR controls the
   311    418   memory handling as explained above.
   312    419   .TP
   313    420   \&\fB\fBdom\fP \fBcreateDocumentNode\fP ?\fIobjVar\fB?
   314         -\&\fRCreates a new, 'empty' DOM document object without any element
          421  +\&\fRCreates a new 'empty' DOM document object without any element
   315    422   node. \fIobjVar\fR controls the memory handling as explained above.
   316    423   .TP
   317         -\&\fB\fBdom\fP \fBsetResultEncoding\fP ?\fIencodingName\fB?
   318         -\&\fRIf \fIencodingName\fR is not given the current global
   319         -result encoding is returned.  Otherwise the global result encoding is set to
   320         -\&\fIencodingName\fR.  All character data, attribute values, etc. will
   321         -then be converted from UTF-8, which is delivered from the Expat XML parser, to
   322         -the given 8 bit encoding at XML/DOM parse time.  Valid values for
   323         -\&\fIencodingName\fR are: utf-8, ascii, cp1250, cp1251, cp1252, cp1253,
   324         -cp1254, cp1255, cp1256, cp437, cp850, en, iso8859-1, iso8859-2, iso8859-3,
   325         -iso8859-4, iso8859-5, iso8859-6, iso8859-7, iso8859-8, iso8859-9, koi8-r.
   326         -.TP
   327         -\&\fB\fBdom\fP \fBcreateNodeCmd\fP \fI?-returnNodeCmd?\fB \fI(element|comment|text|cdata|pi)Node\fB \fIcommandName\fB
   328         -\&\fRThis method creates Tcl commands, which in turn create tDOM nodes.
   329         -Tcl commands created by this command are only avaliable inside a script given to the
   330         -domNode method \fIappendFromScript\fR. If a command created with
   331         -\&\fIcreateNodeCmd\fR is invoked in any other context, it will return error. The
   332         -created command \fIcommandName\fR replaces any existing command or procedure
   333         -with that name. If the \fIcommandName\fR includes any namespace qualifiers,
   334         -it is created in the specified namespace.
          424  +\&\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
          425  +\&\fRThis method creates Tcl commands, which in turn create
          426  +tDOM nodes. Tcl commands created by this command are only
          427  +available inside a script given to the domNode methods
          428  +\&\fIappendFromScript\fR or \fIinsertBeforeFromScript\fR. If
          429  +a command created with \fIcreateNodeCmd\fR is invoked in
          430  +any other context, it will return error. The created command
          431  +\&\fIcommandName\fR replaces any existing command or
          432  +procedure with that name. If the \fIcommandName\fR includes
          433  +any namespace qualifiers, it is created in the specified
          434  +namespace. The \fI-tagName\fR option is only allowed for
          435  +the elementNode type. The \fI-jsonType\fR option is only
          436  +allowed for elementNode and textNode types.
   335    437   .RS
   336    438   .PP
   337         -If such command is invoked inside a script given as argument to
   338         -the domNode method \fIappendFromScript\fR, it creates a new node and
   339         -appends this node at the end of the child list of the invoking element
   340         -node. If the option \fI-returnNodeCmd\fR was given, the command returns the
   341         -created node as Tcl command. If this option was omitted, the command returns
   342         -nothing. Each command creates always the same type of node. Which type of
   343         -node is created by the command is determined by the first argument to the
   344         -\&\fIcreateNodeCmd\fR. The syntax of the created command depends on the
   345         -type of the node it creates.
          439  +If such command is invoked inside a script given as argument to the
          440  +domNode method \fIappendFromScript\fR or
          441  +\&\fIinsertBeforeFromScript\fR it creates a new node and appends this
          442  +node at the end of the child list of the invoking element node. If the
          443  +option \fI-returnNodeCmd\fR was given, the command returns the
          444  +created node as Tcl command. If this option was omitted, the command
          445  +returns nothing. Each command creates always the same type of node.
          446  +Which type of node is created by the command is determined by the
          447  +first argument to the \fIcreateNodeCmd\fR. The syntax of the created
          448  +command depends on the type of the node it creates.
          449  +.PP
          450  +If the command type to create is \fIelementNode\fR, the created
          451  +command will create an element node, if called. Without the
          452  +\&\fI-tagName\fR option the tag name of the created node is
          453  +\&\fIcommandName\fR without namespace qualifiers. If the
          454  +\&\fI-tagName\fR option was given then the created command the created
          455  +elements will have this tag name. If the \fI-jsonType\fR option was
          456  +given then the created node elements will have the given JSON type. If
          457  +the \fI-namespace\fR option is given the created element node will be
          458  +XML namespaced and in the namespace given by the option. The element
          459  +name will be literal as given either by the command name or the
          460  +\&\fI-tagname\fR option, if that was given. An appropriate XML
          461  +namespace declaration will be automatically added, to bind the prefix
          462  +(if the element name has one) or the default namespace (if the element
          463  +name hasn't a prefix) to the namespace if such a binding isn't in
          464  +scope.
   346    465   .PP
   347         -If the first argument of the method is \fIelementNode\fR, the created
   348         -command will create an element node. The tag name of the created
   349         -node is \fIcommandName\fR without namespace qualifiers. The syntax of the
   350         -created command is:
          466  +The syntax of the created command is:
   351    467   
   352    468   
   353    469   
   354    470   .CS
   355    471   
   356    472   \&\fBelementNodeCmd\fP \fI?attributeName attributeValue ...? ?script?\fR
   357    473   \&\fBelementNodeCmd\fP \fI?-attributeName attributeValue ...? ?script?\fR
................................................................................
   369    485   will be stripped off.
   370    486   .PP
   371    487   Every \fIelementNodeCmd\fR accepts an optional Tcl script as last
   372    488   argument. This script is evaluated as recursive \fIappendFromScript\fR script
   373    489   with the node created by the \fIelementNodeCmd\fR as parent of all nodes
   374    490   created by the script.
   375    491   .PP
   376         -If the first argument of the method is \fItextNode\fR, the command will create
   377         -a text node. The syntax of the created command is:
          492  +If the first argument of the method is \fItextNode\fR, the command
          493  +will create a text node. If the \fI-jsonType\fR option was given then
          494  +the created text node will have that JSON type. The syntax of the
          495  +created command is:
   378    496   
   379    497   
   380    498   
   381    499   .CS
   382    500   
   383    501   \&\fBtextNodeCmd\fP ?-disableOutputEscaping? \fIdata\fR
   384    502   
   385    503   .CE
   386    504   .PP
   387    505   If the optional flag \fI-disableOutputEscaping\fR is given, the
   388    506   escaping of the ampersand character (&) and the left angle bracket (<)
   389    507   inside the data is disabled. You should use this flag carefully.
   390    508   .PP
   391         -If the first argument of the method is \fIcommentNode\fR, or
   392         -\&\fIcdataNode\fR, the command will create an comment node or CDATA section
          509  +If the first argument of the method is \fIcommentNode\fR or
          510  +\&\fIcdataNode\fR the command will create an comment node or CDATA section
   393    511   node. The syntax of the created command is:
   394    512   
   395    513   
   396    514   
   397    515   .CS
   398    516   
   399    517   \&\fBnodeCmd\fP \fIdata\fR
................................................................................
   412    530   
   413    531   .CE
   414    532   .RE
   415    533   .TP
   416    534   \&\fB\fBdom\fP \fBsetStoreLineColumn\fP \fI?boolean\fB?
   417    535   \&\fRIf switched on, the DOM nodes will contain line and column
   418    536   position information for the original XML document after parsing. The default
   419         -is, not to store line and column position information.
          537  +is not to store line and column position information.
   420    538   .TP
   421    539   \&\fB\fBdom\fP \fBsetNameCheck\fP \fI?boolean\fB?
   422    540   \&\fRIf NameCheck is true, every method which expects an XML Name,
   423    541   a full qualified name or a processing instructing target will check, if the
   424         -given string is valid according to his production rule. For commands created
          542  +given string is valid according to its production rule. For commands created
   425    543   with the \fIcreateNodeCmd\fR method to be used in the context of
   426    544   \&\fIappendFromScript\fR the status of the flag at creation time
   427    545   decides. If NameCheck is true at creation time, the command will
   428         -check his arguments, otherwise not. The \fIsetNameCheck\fR
          546  +check its arguments, otherwise not. The \fIsetNameCheck\fR
   429    547   set this flag. It returns the current NameCheck flag state. The
   430    548   default state for NameCheck is true.
   431    549   .TP
   432    550   \&\fB\fBdom\fP \fBsetTextCheck\fP \fI?boolean\fB?
   433    551   \&\fRIf TextCheck is true, every command which expects XML Chars,
   434    552   a comment, a CDATA section value or a processing instructing value will check,
   435         -if the given string is valid according to his production rule. For commands
          553  +if the given string is valid according to its production rule. For commands
   436    554   created with the \fIcreateNodeCmd\fR method to be used in the
   437    555   context of \fIappendFromScript\fR the status of the flag at
   438    556   creation time decides. If TextCheck is true at creation time, the
   439         -command will check his arguments, otherwise not.The
   440         -\&\fIsetTextCheck\fR method set this flag. It returns the current
          557  +command will check its arguments, otherwise not.The
          558  +\&\fIsetTextCheck\fR method sets this flag. It returns the current
   441    559   TextCheck flag state. The default state for TextCheck is true.
   442    560   .TP
   443    561   \&\fB\fBdom\fP \fBsetObjectCommands\fP ?\fI(automatic|token|command)\fB?
   444         -\&\fRControls, if documents and nodes are created as tcl commands or
          562  +\&\fRControls if documents and nodes are created as tcl commands or
   445    563   as token to be
   446    564   used with the domNode and domDoc commands. If the mode is
   447    565   \&'automatic', then methods used at tcl commands will create tcl
   448    566   commands and methods used at doc or node tokes will create tokens. If
   449    567   the mode is 'command' then always tcl commands will be created. If
   450    568   the mode is 'token', then always token will be created. The method
   451    569   returns the current mode. This method is an experimental interface.
   452    570   .TP
   453    571   \&\fB\fBdom\fP \fBisName\fP \fIname\fB
   454         -\&\fRReturns 1, if \fIname\fR is a valid XML Name according to
          572  +\&\fRReturns 1 if \fIname\fR is a valid XML Name according to
   455    573   production 5 of the XML
   456         -1.0 recommendation. This means, that \fIname\fR is a valid
          574  +1.0 recommendation. This means that \fIname\fR is a valid
   457    575   XML element or attribute name. Otherwise it returns 0.
   458    576   .TP
   459    577   \&\fB\fBdom\fP \fBisPIName\fP \fIname\fB
   460         -\&\fRReturns 1, if \fIname\fR is a valid XML processing instruction
          578  +\&\fRReturns 1 if \fIname\fR is a valid XML processing instruction
   461    579   target according to
   462    580   production 17 of the XML 1.0 recommendation. Otherwise it returns 0.
   463    581   .TP
   464    582   \&\fB\fBdom\fP \fBisNCName\fP \fIname\fB
   465         -\&\fRReturns 1, if \fIname\fR is a valid NCName according
          583  +\&\fRReturns 1 if \fIname\fR is a valid NCName according
   466    584   to production 4 of the of the Namespaces in XML recommendation. Otherwise it returns
   467    585   0.
   468    586   .TP
   469    587   \&\fB\fBdom\fP \fBisQName\fP \fIname\fB
   470         -\&\fRReturns 1, if \fIname\fR is a valid QName according
          588  +\&\fRReturns 1 if \fIname\fR is a valid QName according
   471    589   to production 6 of the of the Namespaces in XML recommendation. Otherwise it returns
   472    590   0.
   473    591   .TP
   474    592   \&\fB\fBdom\fP \fBisCharData\fP \fIstring\fB
   475         -\&\fRReturns 1, if every character in \fIstring\fR is
          593  +\&\fRReturns 1 if every character in \fIstring\fR is
   476    594   a valid XML Char according to production 2 of the XML 1.0
   477    595   recommendation. Otherwise it returns 0.
   478    596   .TP
          597  +\&\fB\fBdom\fP \fBisBMPCharData\fP \fIstring\fB
          598  +\&\fRReturns 1 if every character in \fIstring\fR is
          599  +a valid XML Char with a Unicode code point within the Basic
          600  +Multilingual Plane (that means, that every character within the string
          601  +is at most 3 bytes long). Otherwise it returns 0.
          602  +.TP
   479    603   \&\fB\fBdom\fP \fBisComment\fP \fIstring\fB
   480         -\&\fRReturns 1, if \fIstring\fR is
          604  +\&\fRReturns 1 if \fIstring\fR is
   481    605   a valid comment according to production 15 of the XML 1.0
   482    606   recommendation. Otherwise it returns 0.
   483    607   .TP
   484    608   \&\fB\fBdom\fP \fBisCDATA\fP \fIstring\fB
   485         -\&\fRReturns 1, if \fIstring\fR is
          609  +\&\fRReturns 1 if \fIstring\fR is
   486    610   valid according to production 20 of the XML 1.0
   487    611   recommendation. Otherwise it returns 0.
   488    612   .TP
   489    613   \&\fB\fBdom\fP \fBisPIValue\fP \fIstring\fB
   490         -\&\fRReturns 1, if \fIstring\fR is
          614  +\&\fRReturns 1 if \fIstring\fR is
   491    615   valid according to production 16 of the XML 1.0
   492    616   recommendation. Otherwise it returns 0.
          617  +.TP
          618  +\&\fB\fBdom\fP \fBfeatureinfo\fP \fIfeature\fB
          619  +\&\fRThis method provides information about the used
          620  +build options and the expat version. The valid values for
          621  +the \fIfeature\fR argument are:
          622  +.RS
          623  +.IP "\fBexpatversion\fR"
          624  +Returns the version of the underlyling expat
          625  +version as string, something like
          626  +"exapt_2.1.0". This is what the expat API
          627  +function XML_ExpatVersion() returns.
          628  +.IP "\fBexpatmajorversion\fR"
          629  +Returns the major version of the underlyling
          630  +expat version as integer.
          631  +.IP "\fBexpatminorversion\fR"
          632  +Returns the minor version of the underlyling
          633  +expat version as integer.
          634  +.IP "\fBexpatmicroversion\fR"
          635  +Returns the micro version of the underlyling
          636  +expat version as integer.
          637  +.IP "\fBdtd\fR"
          638  +Returns as boolean if build with
          639  +\&\fI--enable-dtd\fR.
          640  +.IP "\fBns\fR"
          641  +Returns as boolean if build with
          642  +\&\fI--enable-ns\fR.
          643  +.IP "\fBunknown\fR"
          644  +Returns as boolean if build with
          645  +\&\fI--enable-unknown\fR.
          646  +.IP "\fBtdomalloc\fR"
          647  +Returns as boolean if build with
          648  +\&\fI--enable-tdomalloc\fR.
          649  +.IP "\fBlessns\fR"
          650  +Returns as boolean if build with
          651  +\&\fI--enable-lessns\fR.
          652  +.IP "\fBTCL_UTF_MAX\fR"
          653  +Returns the TCL_UTF_MAX value of the tcl
          654  +core, tDOM was build with as integer
          655  +.IP "\fBhtml5\fR"
          656  +Returns as boolean, if build with
          657  +\&\fI--enable-html5\fR.
          658  +.IP "\fBversionhash\fR"
          659  +Returns the fossil repository version hash.
          660  +.IP "\fBpullparser\fR"
          661  +Returns as boolean if the pullparser command
          662  +is build in.
          663  +.RE
   493    664   .SH KEYWORDS
   494    665   XML, DOM, document, node, parsing

Changes to doc/dom.xml.

    16     16   
    17     17   <cmd>dom</cmd> <m>method</m> ?<m>arg arg ...</m>?</syntax>
    18     18     </synopsis>
    19     19   
    20     20     <section>
    21     21       <title>DESCRIPTION </title>    
    22     22   
    23         -    <p>This command provides the creation of complete DOM trees in memory. In
           23  +    <p>This command provides the creation of DOM trees in memory. In
    24     24   the usual case a string containing a XML information is parsed and converted
    25         -into a DOM tree. <m>method</m> indicates a specific subcommand. </p>
           25  +into a DOM tree. Other possible parse input may be HTML or JSON.
           26  +The <m>method</m> indicates a specific subcommand. </p>
    26     27   
    27     28       <p>The valid methods are:</p>
    28     29   
    29     30         <commandlist>
    30     31           <commanddef>
    31     32             <command><cmd>dom</cmd> <method>parse</method> ?<m>options</m>? ?<m>data</m>?</command>
    32     33             <desc>Parses the XML information and builds up the DOM tree in memory
................................................................................
    63     64                 <optdef>
    64     65                   <optname>-simple</optname> 
    65     66                   <desc>If <m>-simple</m> is
    66     67   specified, a simple but fast parser is used (conforms not fully to XML
    67     68   recommendation). That should double parsing and DOM generation speed. The
    68     69   encoding of the data is not transformed inside the parser. The simple parser
    69     70   does not respect any encoding information in the XML declaration. It skips over
    70         -the internal DTD subset and ignores any information in it. Therefor it doesn't
           71  +the internal DTD subset and ignores any information in it. Therefore it doesn't
    71     72   include defaulted attribute values into the tree, even if the according
    72     73   attribute declaration is in the internal subset. It also doesn't expand
    73     74   internal or external entity references other than the predefined entities and
    74     75   character references.</desc>
    75     76                 </optdef>
    76     77   
    77     78                 <optdef>
    78     79                   <optname>-html</optname>
    79     80                   <desc>If <m>-html</m> is specified, a fast HTML parser is 
    80     81   used, which tries to even parse badly formed HTML into a DOM tree.</desc>
    81     82                 </optdef>
    82         -       
           83  +
           84  +              <optdef>
           85  +                <optname>-html5</optname>
           86  +                <desc>This option is only available if tDOM was build
           87  +                with --enable-html5. Try the <m>featureinfo</m> method
           88  +                if you need to know if this feature is build in. If
           89  +                <m>-html5</m> is specified, the gumbo lib html5 parser
           90  +                (https://github.com/google/gumbo-parser) is used to
           91  +                build the DOM tree. This is, as far as it goes, XML
           92  +                namespace-aware. Since this probably isn't wanted by a
           93  +                lot of users and adds only burden for no good in a lot
           94  +                of use cases <m>-html5</m> can be combined with
           95  +                <m>-ignorexmlns</m>, in which case all nodes and
           96  +                attributes in the DOM tree are not in an XML
           97  +                namespace. All tag and attribute names in the DOM tree
           98  +                will be lower case, even for foreign elements not in
           99  +                the xhtml, svg or mathml namespace. The DOM tree may
          100  +                include nodes, that the parser inserted because they
          101  +                are implied by the context (as &lt;head&gt;,
          102  +                &lt;tbody&gt;, etc.).</desc>
          103  +              </optdef>
          104  +
          105  +              <optdef>
          106  +                <optname>-json</optname>
          107  +                <desc>If <m>-json</m> is specified, the <m>data</m> is
          108  +                expected to be a valid JSON string (according to RFC
          109  +                7159). The command returns an ordinary DOM document
          110  +                with nesting token inside the JSON data translated
          111  +                into tree hierarchy. If a JSON array value is itself
          112  +                an object or array then container element nodes named
          113  +                (in a default build) arraycontainer or
          114  +                objectcontainer, respectively, are inserted into the
          115  +                tree. The JSON serialization of this document (with
          116  +                the domDoc method <m>asJSON</m>) is the same JSON
          117  +                information as the <m>data</m>, preserving JSON
          118  +                datatypes, allowing non-unique member names of objects
          119  +                while preserving their order and the full range of
          120  +                JSON string values. JSON datatype handling is done
          121  +                with an additional property "sticking" at the doc and
          122  +                tree nodes. This property isn't contained in an XML
          123  +                serialization of the document. If you need to store
          124  +                the JSON data represented by a document, store the
          125  +                JSON serialization and parse it back from there. Apart
          126  +                from this JSON type information the returned doc
          127  +                command or handle is an ordinary DOM doc, which may be
          128  +                investigated or modified with the full range of the
          129  +                doc and node methods. Please note that the element
          130  +                node names and the text node values within the tree
          131  +                may be outside of what the appropriate XML productions
          132  +                allow.</desc>
          133  +              </optdef>
          134  +
          135  +              <optdef>
          136  +                <optname>-jsonmaxnesting</optname>
          137  +                <optarg>integer</optarg>
          138  +                <desc>This option only has effect if used together
          139  +                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>
          140  +              </optdef>
          141  +              
          142  +              <optdef>
          143  +                <optname>--</optname> 
          144  +                <desc>The option <m>--</m> marks the end of options.
          145  +                While respected in general this option is only needed
          146  +                in case of parsing JSON data, which may start with a
          147  +                "-".</desc>
          148  +              </optdef>
          149  +
    83    150                 <optdef>
    84    151                   <optname>-keepEmpties</optname> 
    85    152                   <desc>If <m>-keepEmpties</m> is
    86         -specified, text nodes, which contain only whitespaces, will be part of the
          153  +specified then text nodes which contain only whitespaces will be part of the
    87    154   resulting DOM tree. In default case (<m>-keepEmpties</m> not given) those empty
    88    155   text nodes are removed at parsing time.</desc>
    89    156                 </optdef>
    90    157   
          158  +              <optdef>
          159  +                <optname>-keepCDATA</optname> 
          160  +                <desc>If <m>-keepCDATA</m> is
          161  +specified then CDATA sections aren't added to the tree as text nodes
          162  +(and, if necessary, combined with sibling text nodes into one text
          163  +node) as without this option but are added as CDATA_SECTION_NODEs to
          164  +the tree. Please note that the resulting tree isn't prepared for XPath
          165  +selects or to be the source or the stylesheet of an XSLT
          166  +transformation. If not combined with <m>-keepEmpties</m> only not
          167  +whitespace only CDATA sections will be added to the resulting DOM
          168  +                tree.</desc>
          169  +              </optdef>
          170  +              
    91    171                 <optdef>
    92    172                   <optname>-channel</optname>
    93    173                   <optarg>&lt;channel-ID&gt;</optarg>
    94    174                   <desc>If <m>-channel &lt;channel-ID&gt;</m> is specified, the
    95    175   input to be parsed is read from the specified channel. The encoding setting of
    96    176   the channel (via fconfigure -encoding) is respected, ie the data read from the
    97         -channel are converted to UTF-8 according to the encoding settings, befor the
          177  +channel are converted to UTF-8 according to the encoding settings before the
    98    178   data is parsed.</desc>
    99    179                 </optdef>
   100    180   
   101    181                 <optdef>
   102    182                   <optname>-baseurl</optname>
   103    183                   <optarg>&lt;baseURI&gt;</optarg>
   104         -                <desc>If <m>-baseurl &lt;baseURI&gt;</m> is specified, the
   105         -baseURI is used as the base URI of the document. External entities referenced
   106         -in the document are resolved relative to this base URI. This base URI is also
   107         -stored within the DOM tree.</desc>
          184  +                <desc>If <m>-baseurl &lt;baseURI&gt;</m> is specified,
          185  +                the baseURI is used as the base URI of the document.
          186  +                External entities references in the document are
          187  +                resolved relative to this base URI. This base URI is
          188  +                also stored within the DOM tree.</desc>
   108    189                 </optdef>
   109    190   
   110    191                 <optdef>
   111    192                   <optname>-feedbackAfter</optname>
   112    193                   <optarg>&lt;#bytes&gt;</optarg>
   113         -                <desc>If <m>-feedbackAfter &lt;#bytes&gt;</m> is specified, the
   114         -tcl command ::dom::domParseFeedback is evaluated after parsing every #bytes. If
   115         -you use this option, you have to create a tcl proc named
   116         -::dom::domParseFeedback, otherwise you will get an error. Please notice, that
   117         -the calls of ::dom::domParseFeedback are not done exactly every #bytes, but
   118         -always at the first element start after every #bytes.</desc>
          194  +                <desc>If <m>-feedbackAfter &lt;#bytes&gt;</m> is
          195  +                specified, the tcl command given by
          196  +                <m>-feedbackcmd</m> is evaluated at the first element
          197  +                start within the document (or an external entity)
          198  +                after the start of the document or external entity or
          199  +                the last such call after #bytes. For backward
          200  +                compatibility if no -feedbackcmd is given but there is
          201  +                a tcl proc named ::dom::domParseFeedback this proc is
          202  +                used as -feedbackcmd. If there isn't such a proc and
          203  +                -feedbackAfter is used it is an error to not also use
          204  +                -feedbackcmd. If the called script raises error, then
          205  +                parsing will be aborted, the <m>dom parse</m> call
          206  +                returns error, with the script error msg as error msg.
          207  +                If the called script <m>return -code break</m>, the
          208  +                parsing will abort and the <m>dom parse</m> call will
          209  +                return the empty string.</desc>
          210  +              </optdef>
          211  +
          212  +              <optdef>
          213  +                <optname>-feedbackcmd</optname>
          214  +                <optarg>&lt;script&gt;</optarg>
          215  +                <desc>If <m>-feedbackcmd &lt;script&gt;</m> is specified, the
          216  +script <m>script</m> is evaluated at the first
          217  +element start within the document (or an external entity) after the
          218  +start of the document or external entity or the last such call after
          219  +#bytes value given by the <m>-feedbackAfter</m> option. If
          220  +<m>-feedbackAfter</m> isn't given, using this option
          221  +doesn't has any effect. If the called
          222  +script raises error, then parsing will be aborted, the
          223  +<m>dom parse</m> call returns error, with the script
          224  +error msg as error msg. If the called script <m>return
          225  +-code break</m>, the parsing will abort and the <m>dom
          226  +parse</m> call will return the empty string.</desc>
   119    227                 </optdef>
   120    228   
   121    229                 <optdef>
   122    230                   <optname>-externalentitycommand</optname>
   123    231                   <optarg>&lt;script&gt;</optarg>
   124    232                   <desc>If <m>-externalentitycommand &lt;script&gt;</m> is
   125    233   specified, the specified tcl script is called to resolve any external entities
   126    234   of the document. The actual evaluated command consists of this option followed
   127    235   by three arguments: the base uri, the system identifier of the entity and the
   128    236   public identifier of the entity. The base uri and the public identifier may be
   129    237   the empty list. The script has to return a tcl list consisting of three
   130         -elements. The first element of this list signals, how the external entity is
   131         -returned to the processor. At the moment, the two allowed types are "string"
          238  +elements. The first element of this list signals how the external entity is
          239  +returned to the processor. Currently the two allowed types are "string"
   132    240   and "channel". The second element of the list has to be the (absolute) base URI
   133    241   of the external entity to be parsed.  The third element of the list are data,
   134    242   either the already read data out of the external entity as string in the case
   135    243   of type "string", or the name of a tcl channel, in the case of type
   136    244   "channel". Note that if the script returns a tcl channel, it will not be closed
   137    245   by the processor.  It must be closed separately if it is no longer
   138         -required.</desc>
          246  +needed.</desc>
   139    247                 </optdef>
   140    248   
   141    249                 <optdef>
   142    250                   <optname>-useForeignDTD</optname>
   143    251                   <optarg>&lt;boolean&gt;</optarg>
   144    252                   <desc>If &lt;boolean&gt; is true and the document does not have
   145    253   an external subset, the parser will call the -externalentitycommand script with
   146         -empty values for the systemId and publicID arguments. Pleace notice, that, if
          254  +empty values for the systemId and publicID arguments. Please note that if
   147    255   the document also doesn't have an internal subset, the
   148    256   -startdoctypedeclcommand and -enddoctypedeclcommand scripts, if set, are not
   149    257   called. The <m>-useForeignDTD</m> respects </desc>
   150    258                 </optdef>
   151    259   
   152    260                 <optdef>
   153    261                   <optname>-paramentityparsing</optname>
   154    262                   <optarg>&lt;always|never|notstandalone&gt;</optarg>
   155         -                <desc>The <m>-paramentityparsing</m> option controls, if the
   156         -parser tries to resolve the external entities (including the external DTD
   157         -subset) of the document, while building the DOM
   158         -tree. <m>-paramentityparsing</m> requires an argument, which must be either
   159         -"always", "never", or "notstandalone". The value "always" means, that the
   160         -parser tries to resolves (recursively) all external entities of the XML
   161         -source. This is the default, in case <m>-paramentityparsing</m> is omitted. The
   162         -value "never" means, that only the given XML source is parsed and no external
   163         -entity (including the external subset) will be resolved and parsed. The value
   164         -"notstandalone" means, that all external entities will be resolved and parsed,
   165         -with the execption of documents, which explicitly states standalone="yes" in
   166         -their XML declaration.</desc>
          263  +                <desc>The <m>-paramentityparsing</m> option controls,
          264  +                if the parser tries to resolve the external entities
          265  +                (including the external DTD subset) of the document
          266  +                while building the DOM tree.
          267  +                <m>-paramentityparsing</m> requires an argument, which
          268  +                must be either "always", "never", or "notstandalone".
          269  +                The value "always" means that the parser tries to
          270  +                resolves (recursively) all external entities of the
          271  +                XML source. This is the default in case
          272  +                <m>-paramentityparsing</m> is omitted. The value
          273  +                "never" means that only the given XML source is
          274  +                parsed and no external entity (including the external
          275  +                subset) will be resolved and parsed. The value
          276  +                "notstandalone" means, that all external entities will
          277  +                be resolved and parsed, with the exception of
          278  +                documents, which explicitly states standalone="yes" in
          279  +                their XML declaration.</desc>
          280  +              </optdef>
          281  +
          282  +
          283  +              <optdef>
          284  +                <optname>-ignorexmlns</optname>
          285  +                <desc>It is recommended, that you only use this option
          286  +                with the <m>-html5</m> option. If this option is
          287  +                given, no node within the created DOM tree will be
          288  +                internally marked as placed into an XML Namespace,
          289  +                even if there is a default namespace in scope for
          290  +                un-prefixed elements or even if the element has a
          291  +                defined namespace prefix. One consequence is that
          292  +                XPath node expressions on such a DOM tree doesn't work
          293  +                as expected. Prefixed element nodes can't be selected
          294  +                and element nodes without prefix will be seen by XPath
          295  +                expressions as if they are not in any namespace (no
          296  +                matter if they are in fact should be in a default
          297  +                namespace).
          298  +                </desc>
   167    299                 </optdef>
   168    300   
   169    301               </optlist>
   170    302   <p/>
   171    303   </desc>
   172    304           </commanddef>
   173    305   
................................................................................
   187    319   document element to create. The <m>objVar</m> controls the
   188    320   memory handling as explained above.</desc>
   189    321           </commanddef>
   190    322   
   191    323           <commanddef>
   192    324             <command><cmd>dom</cmd> <method>createDocumentNode</method>
   193    325   ?<m>objVar</m>?</command>
   194         -          <desc>Creates a new, 'empty' DOM document object without any element
          326  +          <desc>Creates a new 'empty' DOM document object without any element
   195    327   node. <m>objVar</m> controls the memory handling as explained above.</desc>
   196    328           </commanddef>
   197    329   
   198         -        <commanddef>
   199         -          <command><cmd>dom</cmd> <method>setResultEncoding</method> ?<m>encodingName</m>?</command>
   200         -          <desc>If <m>encodingName</m> is not given the current global
   201         -result encoding is returned.  Otherwise the global result encoding is set to
   202         -<m>encodingName</m>.  All character data, attribute values, etc. will
   203         -then be converted from UTF-8, which is delivered from the Expat XML parser, to
   204         -the given 8 bit encoding at XML/DOM parse time.  Valid values for
   205         -<m>encodingName</m> are: utf-8, ascii, cp1250, cp1251, cp1252, cp1253,
   206         -cp1254, cp1255, cp1256, cp437, cp850, en, iso8859-1, iso8859-2, iso8859-3,
   207         -iso8859-4, iso8859-5, iso8859-6, iso8859-7, iso8859-8, iso8859-9, koi8-r.</desc>
   208         -        </commanddef>
   209         -
   210    330           <commanddef>
   211    331             <command><cmd>dom</cmd> <method>createNodeCmd</method>
   212         -<m>?-returnNodeCmd?</m> <m>(element|comment|text|cdata|pi)Node</m> <m>commandName</m></command>
   213         -          <desc>This method creates Tcl commands, which in turn create tDOM nodes.
   214         -Tcl commands created by this command are only avaliable inside a script given to the
   215         -domNode method <m>appendFromScript</m>. If a command created with
   216         -<m>createNodeCmd</m> is invoked in any other context, it will return error. The
   217         -created command <m>commandName</m> replaces any existing command or procedure
   218         -with that name. If the <m>commandName</m> includes any namespace qualifiers, 
   219         -it is created in the specified namespace.
   220         -
   221         -<p>If such command is invoked inside a script given as argument to
   222         -the domNode method <m>appendFromScript</m>, it creates a new node and
   223         -appends this node at the end of the child list of the invoking element
   224         -node. If the option <m>-returnNodeCmd</m> was given, the command returns the
   225         -created node as Tcl command. If this option was omitted, the command returns
   226         -nothing. Each command creates always the same type of node. Which type of 
   227         -node is created by the command is determined by the first argument to the
   228         -<m>createNodeCmd</m>. The syntax of the created command depends on the 
   229         -type of the node it creates.</p>
   230         -
   231         -<p>If the first argument of the method is <m>elementNode</m>, the created
   232         -command will create an element node. The tag name of the created
   233         -node is <m>commandName</m> without namespace qualifiers. The syntax of the 
   234         -created command is:</p>
          332  +<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>
          333  +          <desc>This method creates Tcl commands, which in turn create
          334  +          tDOM nodes. Tcl commands created by this command are only
          335  +          available inside a script given to the domNode methods
          336  +          <m>appendFromScript</m> or <m>insertBeforeFromScript</m>. If
          337  +          a command created with <m>createNodeCmd</m> is invoked in
          338  +          any other context, it will return error. The created command
          339  +          <m>commandName</m> replaces any existing command or
          340  +          procedure with that name. If the <m>commandName</m> includes
          341  +          any namespace qualifiers, it is created in the specified
          342  +          namespace. The <m>-tagName</m> option is only allowed for
          343  +          the elementNode type. The <m>-jsonType</m> option is only
          344  +          allowed for elementNode and textNode types.
          345  +
          346  +<p>If such command is invoked inside a script given as argument to the
          347  +domNode method <m>appendFromScript</m> or
          348  +<m>insertBeforeFromScript</m> it creates a new node and appends this
          349  +node at the end of the child list of the invoking element node. If the
          350  +option <m>-returnNodeCmd</m> was given, the command returns the
          351  +created node as Tcl command. If this option was omitted, the command
          352  +returns nothing. Each command creates always the same type of node.
          353  +Which type of node is created by the command is determined by the
          354  +first argument to the <m>createNodeCmd</m>. The syntax of the created
          355  +command depends on the type of the node it creates.</p>
          356  +
          357  +<p>If the command type to create is <m>elementNode</m>, the created
          358  +command will create an element node, if called. Without the
          359  +<m>-tagName</m> option the tag name of the created node is
          360  +<m>commandName</m> without namespace qualifiers. If the
          361  +<m>-tagName</m> option was given then the created command the created
          362  +elements will have this tag name. If the <m>-jsonType</m> option was
          363  +given then the created node elements will have the given JSON type. If
          364  +the <m>-namespace</m> option is given the created element node will be
          365  +XML namespaced and in the namespace given by the option. The element
          366  +name will be literal as given either by the command name or the
          367  +<m>-tagname</m> option, if that was given. An appropriate XML
          368  +namespace declaration will be automatically added, to bind the prefix
          369  +(if the element name has one) or the default namespace (if the element
          370  +name hasn't a prefix) to the namespace if such a binding isn't in
          371  +scope.</p>
          372  +
          373  +<p>The syntax of the created command is:</p>
   235    374   
   236    375   <syntax>
   237    376   <cmd>elementNodeCmd</cmd> <m>?attributeName attributeValue ...? ?script?</m>
   238    377   <cmd>elementNodeCmd</cmd> <m>?-attributeName attributeValue ...? ?script?</m>
   239    378   <cmd>elementNodeCmd</cmd> <m>name_value_list script</m>
   240    379   </syntax>
   241    380   
................................................................................
   249    388   will be stripped off.</p>
   250    389   
   251    390   <p>Every <m>elementNodeCmd</m> accepts an optional Tcl script as last
   252    391   argument. This script is evaluated as recursive <m>appendFromScript</m> script
   253    392   with the node created by the <m>elementNodeCmd</m> as parent of all nodes
   254    393   created by the script.</p>
   255    394   
   256         -<p>If the first argument of the method is <m>textNode</m>, the command will create
   257         -a text node. The syntax of the created command is:</p>
          395  +<p>If the first argument of the method is <m>textNode</m>, the command
          396  +will create a text node. If the <m>-jsonType</m> option was given then
          397  +the created text node will have that JSON type. The syntax of the
          398  +created command is:</p>
   258    399   
   259    400   <syntax>
   260    401   <cmd>textNodeCmd</cmd> ?-disableOutputEscaping? <m>data</m>
   261    402   </syntax>
   262    403   
   263    404   <p>If the optional flag <m>-disableOutputEscaping</m> is given, the
   264    405   escaping of the ampersand character (&amp;) and the left angle bracket (&lt;)
   265    406   inside the data is disabled. You should use this flag carefully.</p>
   266    407   
   267         -<p>If the first argument of the method is <m>commentNode</m>, or 
   268         -<m>cdataNode</m>, the command will create an comment node or CDATA section 
          408  +<p>If the first argument of the method is <m>commentNode</m> or 
          409  +<m>cdataNode</m> the command will create an comment node or CDATA section 
   269    410   node. The syntax of the created command is:</p>
   270    411   
   271    412   <syntax>
   272    413   <cmd>nodeCmd</cmd> <m>data</m>
   273    414   </syntax>
   274    415   
   275    416   <p>If the first argument of the method is <m>piNode</m>, the command will
................................................................................
   283    424   </desc>
   284    425           </commanddef>
   285    426   
   286    427           <commanddef>
   287    428             <command><cmd>dom</cmd> <method>setStoreLineColumn</method> <m>?boolean</m>?</command>
   288    429             <desc>If switched on, the DOM nodes will contain line and column
   289    430   position information for the original XML document after parsing. The default
   290         -is, not to store line and column position information.</desc>
          431  +is not to store line and column position information.</desc>
   291    432           </commanddef>
   292    433   
   293    434           <commanddef>
   294    435             <command><cmd>dom</cmd> <method>setNameCheck</method> <m>?boolean</m>?</command>
   295    436             <desc>If NameCheck is true, every method which expects an XML Name,
   296    437   a full qualified name or a processing instructing target will check, if the
   297         -given string is valid according to his production rule. For commands created
          438  +given string is valid according to its production rule. For commands created
   298    439   with the <m>createNodeCmd</m> method to be used in the context of
   299    440   <m>appendFromScript</m> the status of the flag at creation time
   300    441   decides. If NameCheck is true at creation time, the command will
   301         -check his arguments, otherwise not. The <m>setNameCheck</m>
          442  +check its arguments, otherwise not. The <m>setNameCheck</m>
   302    443   set this flag. It returns the current NameCheck flag state. The
   303    444   default state for NameCheck is true. </desc>
   304    445           </commanddef>
   305    446   
   306    447           <commanddef>
   307    448             <command><cmd>dom</cmd> <method>setTextCheck</method> <m>?boolean</m>?</command>
   308    449             <desc>If TextCheck is true, every command which expects XML Chars,
   309    450   a comment, a CDATA section value or a processing instructing value will check,
   310         -if the given string is valid according to his production rule. For commands
          451  +if the given string is valid according to its production rule. For commands
   311    452   created with the <m>createNodeCmd</m> method to be used in the
   312    453   context of <m>appendFromScript</m> the status of the flag at
   313    454   creation time decides. If TextCheck is true at creation time, the
   314         -command will check his arguments, otherwise not.The
   315         -<m>setTextCheck</m> method set this flag. It returns the current
          455  +command will check its arguments, otherwise not.The
          456  +<m>setTextCheck</m> method sets this flag. It returns the current
   316    457   TextCheck flag state. The default state for TextCheck is true.</desc>
   317    458         </commanddef>
   318    459   
   319    460           <commanddef>
   320    461             <command><cmd>dom</cmd> <method>setObjectCommands</method> ?<m>(automatic|token|command)</m>?</command>
   321         -          <desc>Controls, if documents and nodes are created as tcl commands or
          462  +          <desc>Controls if documents and nodes are created as tcl commands or
   322    463   as token to be
   323    464   used with the domNode and domDoc commands. If the mode is
   324    465   'automatic', then methods used at tcl commands will create tcl
   325    466   commands and methods used at doc or node tokes will create tokens. If
   326    467   the mode is 'command' then always tcl commands will be created. If
   327    468   the mode is 'token', then always token will be created. The method
   328    469   returns the current mode. This method is an experimental interface.</desc>
   329    470         </commanddef>
   330    471   
   331    472           <commanddef>
   332    473             <command><cmd>dom</cmd> <method>isName</method> <m>name</m></command>
   333         -          <desc>Returns 1, if <m>name</m> is a valid XML Name according to
          474  +          <desc>Returns 1 if <m>name</m> is a valid XML Name according to
   334    475   production 5 of the <ref
   335    476               href="http://www.w3.org/TR/2004/REC-xml-20040204/#NT-NameChar">XML
   336         -            1.0</ref> recommendation. This means, that <m>name</m> is a valid
          477  +            1.0</ref> recommendation. This means that <m>name</m> is a valid
   337    478             XML element or attribute name. Otherwise it returns 0.</desc>
   338    479           </commanddef>
   339    480   
   340    481           <commanddef>
   341    482             <command><cmd>dom</cmd> <method>isPIName</method> <m>name</m></command>
   342         -          <desc>Returns 1, if <m>name</m> is a valid XML processing instruction
          483  +          <desc>Returns 1 if <m>name</m> is a valid XML processing instruction
   343    484             target according to
   344    485   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>
   345    486           </commanddef>
   346    487   
   347    488           <commanddef>
   348    489             <command><cmd>dom</cmd> <method>isNCName</method> <m>name</m></command>
   349         -          <desc>Returns 1, if <m>name</m> is a valid NCName according
          490  +          <desc>Returns 1 if <m>name</m> is a valid NCName according
   350    491   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
   351    492   0.</desc>
   352    493           </commanddef>
   353    494   
   354    495           <commanddef>
   355    496             <command><cmd>dom</cmd> <method>isQName</method> <m>name</m></command>
   356         -          <desc>Returns 1, if <m>name</m> is a valid QName according
          497  +          <desc>Returns 1 if <m>name</m> is a valid QName according
   357    498   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
   358    499   0.</desc>
   359    500           </commanddef>
   360    501   
   361    502           <commanddef>
   362    503             <command><cmd>dom</cmd> <method>isCharData</method>
   363    504   <m>string</m></command>
   364         -          <desc>Returns 1, if every character in <m>string</m> is
          505  +          <desc>Returns 1 if every character in <m>string</m> is
   365    506   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>
   366    507   recommendation. Otherwise it returns 0.</desc>
   367    508           </commanddef>
   368    509   
          510  +        <commanddef>
          511  +          <command><cmd>dom</cmd> <method>isBMPCharData</method>
          512  +<m>string</m></command>
          513  +          <desc>Returns 1 if every character in <m>string</m> is
          514  +a valid XML Char with a Unicode code point within the Basic
          515  +Multilingual Plane (that means, that every character within the string
          516  +is at most 3 bytes long). Otherwise it returns 0.</desc>
          517  +        </commanddef>
          518  +
   369    519           <commanddef>
   370    520             <command><cmd>dom</cmd> <method>isComment</method>
   371    521   <m>string</m></command>
   372         -          <desc>Returns 1, if <m>string</m> is
          522  +          <desc>Returns 1 if <m>string</m> is
   373    523   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>
   374    524   recommendation. Otherwise it returns 0.</desc>
   375    525           </commanddef>
   376    526   
   377    527           <commanddef>
   378    528             <command><cmd>dom</cmd> <method>isCDATA</method>
   379    529   <m>string</m></command>
   380         -          <desc>Returns 1, if <m>string</m> is
          530  +          <desc>Returns 1 if <m>string</m> is
   381    531   valid according to production 20 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
   382    532   recommendation. Otherwise it returns 0.</desc>
   383    533           </commanddef>
   384    534   
   385    535           <commanddef>
   386    536             <command><cmd>dom</cmd> <method>isPIValue</method>
   387    537   <m>string</m></command>
   388         -          <desc>Returns 1, if <m>string</m> is
          538  +          <desc>Returns 1 if <m>string</m> is
   389    539   valid according to production 16 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
   390    540   recommendation. Otherwise it returns 0.</desc>
   391    541           </commanddef>
   392    542   
   393         -      </commandlist>
   394         -  </section>
          543  +        <commanddef>
          544  +            <command><cmd>dom</cmd> <method>featureinfo</method> <m>feature</m></command>
          545  +            <desc>This method provides information about the used
          546  +            build options and the expat version. The valid values for
          547  +            the <m>feature</m> argument are:
          548  +            <optlist>
          549  +                <optdef>
          550  +                    <optname>expatversion</optname>
          551  +                    <desc>Returns the version of the underlyling expat
          552  +                    version as string, something like
          553  +                    "exapt_2.1.0". This is what the expat API
          554  +                    function XML_ExpatVersion() returns.</desc>
          555  +                </optdef>
          556  +                <optdef>
          557  +                    <optname>expatmajorversion</optname>
          558  +                    <desc>Returns the major version of the underlyling
          559  +                    expat version as integer.</desc>
          560  +                </optdef>
          561  +                <optdef>
          562  +                    <optname>expatminorversion</optname>
          563  +                    <desc>Returns the minor version of the underlyling
          564  +                    expat version as integer.</desc>
          565  +                </optdef>
          566  +                <optdef>
          567  +                    <optname>expatmicroversion</optname>
          568  +                    <desc>Returns the micro version of the underlyling
          569  +                    expat version as integer.</desc>
          570  +                </optdef>
          571  +                <optdef>
          572  +                    <optname>dtd</optname>
          573  +                    <desc>Returns as boolean if build with
          574  +                    <m>--enable-dtd</m>.</desc>
          575  +                </optdef>
          576  +                <optdef>
          577  +                    <optname>ns</optname>
          578  +                    <desc>Returns as boolean if build with
          579  +                    <m>--enable-ns</m>.</desc>
          580  +                </optdef>
          581  +                <optdef>
          582  +                    <optname>unknown</optname>
          583  +                    <desc>Returns as boolean if build with
          584  +                    <m>--enable-unknown</m>.</desc>
          585  +                </optdef>
          586  +                <optdef>
          587  +                    <optname>tdomalloc</optname>
          588  +                    <desc>Returns as boolean if build with
          589  +                    <m>--enable-tdomalloc</m>.</desc>
          590  +                </optdef>
          591  +                <optdef>
          592  +                    <optname>lessns</optname>
          593  +                    <desc>Returns as boolean if build with
          594  +                    <m>--enable-lessns</m>.</desc>
          595  +                </optdef>
          596  +                <optdef>
          597  +                    <optname>TCL_UTF_MAX</optname>
          598  +                    <desc>Returns the TCL_UTF_MAX value of the tcl
          599  +                    core, tDOM was build with as integer</desc>
          600  +                </optdef>
          601  +                <optdef>
          602  +                    <optname>html5</optname>
          603  +                    <desc>Returns as boolean, if build with
          604  +                    <m>--enable-html5</m>.</desc>
          605  +                </optdef>
          606  +                <optdef>
          607  +                    <optname>versionhash</optname>
          608  +                    <desc>Returns the fossil repository version hash.</desc>
          609  +                </optdef>
          610  +                <optdef>
          611  +                    <optname>pullparser</optname>
          612  +                    <desc>Returns as boolean if the pullparser command
          613  +                    is build in.</desc>
          614  +                </optdef>
          615  +            </optlist>
          616  +            </desc>   
          617  +        </commanddef>
          618  +    </commandlist>
          619  +</section>
   395    620   
   396         -  <keywords>
          621  +<keywords>
   397    622       <keyword>XML</keyword>
   398    623       <keyword>DOM</keyword>
   399    624       <keyword>document</keyword>
   400    625       <keyword>node</keyword>
   401    626       <keyword>parsing</keyword>
   402         -  </keywords>
          627  +</keywords>
   403    628   </manpage>

Changes to doc/domDoc.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <div class="navbar" align="center">
     7         -<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>
            7  +<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>
     8      8   </div><hr class="navsep">
     9      9   </div><div class="body">
    10         -  <h2><a name="SECTid0x80a9a60">NAME</a></h2><p class="namesection">
           10  +  <h2><a name="SECTid0x1eae960">NAME</a></h2><p class="namesection">
    11     11   <b class="names">domDoc - </b><br>Manipulates an instance of a DOM document object</p>
    12     12     
    13         -  <h2><a name="SECTid0x80a7380">SYNOPSIS</a></h2><pre class="syntax">
    14         -<b class="cmd">domDocObjCmd</b> <i class="m">method</i> ?<i class="m">arg arg ...</i>?</pre>
           13  +  <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>
    15     14   
    16         -  <h2><a name="SECTid0x80967e0">DESCRIPTION </a></h2><p>This command manipulates one particular instance of a document
           15  +  <h2><a name="SECTid0x1e97f70">DESCRIPTION </a></h2><p>This command manipulates one particular instance of a document
    17     16   object. <i class="m">method</i> indicates a specific method of the document class. These
    18     17   methods should closely conform to the W3C recommendation "Document Object Model
    19     18   (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
    20     19   at these documents for a deeper understanding of the functionality.</p><p>The valid methods are:</p><dl class="commandlist">
    21     20           
    22     21             <dt>
    23     22   <b class="method">documentElement</b> ?<i class="m">objVar</i>?</dt>
................................................................................
    44     43   
    45     44           
    46     45             <dt>
    47     46   <b class="method">createElement</b> <i class="m">tagName</i> ?<i class="m">objVar</i>?</dt>
    48     47             <dd>Creates (allocates) a new element node with node name
    49     48   <i class="m">tagName</i>, append it to the hidden fragment list in the document
    50     49   object and returns the node object.  If <i class="m">objVar</i> is given the new
    51         -node object store in this variable.</dd>
           50  +node object is stored in this variable.</dd>
    52     51           
    53     52   
    54     53           
    55     54             <dt>
    56     55   <b class="method">createElementNS</b> <i class="m">url</i> <i class="m">tagName</i> ?<i class="m">objVar</i>?</dt>
    57     56             <dd>Creates (allocates) a new element node within a namespace
    58     57   having <i class="m">uri</i> as the URI and node name <i class="m">tagName</i>, which
    59     58   could include the namespace prefix, append it to the hidden fragment list in
    60     59   the document object and returns the node object.  If <i class="m">objVar</i> is
    61         -given the new node object store in this variable.</dd>
           60  +given the new node object is stored in this variable.</dd>
    62     61           
    63     62   
    64     63           
    65     64             <dt>
    66     65   <b class="method">createTextNode</b> <i class="m">text</i> ?<i class="m">objVar</i>?</dt>
    67     66             <dd>Creates (allocates) a new text node with node value
    68     67   <i class="m">text</i>, appends it to the hidden fragment list in the document
................................................................................
   107    106             <dt><b class="method">getDefaultOutputMethod</b></dt>
   108    107             <dd>Returns the default output method of the document. This is
   109    108   usually a result of a XSLT transformation.</dd>
   110    109           
   111    110   
   112    111         
   113    112           <dt>
   114         -<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>
   115         -</dt>
   116         -        <dd>Returns the DOM tree as an (optional indented) XML
   117         -string or sends the output directly to the given channelId. If the
   118         -option <i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII
   119         -character in attribute values or element PCDATA content will be
   120         -escaped as character reference in decimal representation. The flag
   121         -<i class="m">-doctypeDeclaration</i> determines, whether there will be a DOCTYPE
   122         -declaration emitted before the first node of the document. The default
   123         -is, to do not. The DOCTYPE name will always be the element name of the
   124         -document element. An external entity declaration of the external
   125         -subset is only emitted, if the document has a system identifier. If
   126         -the option <i class="m">-escapeAllQuot</i> is given, quotation marks will be
   127         -escaped with &amp;quot; even in text content of elements.</dd>
          113  +<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>
          114  +</dt>
          115  +        <dd>
          116  +<p>Returns the DOM tree as an (optional indented) XML
          117  +        string or sends the output directly to the given
          118  +        channelId.</p>
          119  +
          120  +        <p>If the option <i class="m">-escapeNonASCII</i> is given,
          121  +        every non 7 bit ASCII character in attribute values or element
          122  +        PCDATA content will be escaped as character reference in
          123  +        decimal representation.</p>
          124  +
          125  +        <p>The flag <i class="m">-doctypeDeclaration</i> determines whether
          126  +        there will be a DOCTYPE declaration emitted before the first
          127  +        node of the document. The default is not to emit it. The
          128  +        DOCTYPE name will always be the element name of the document
          129  +        element. An external entity declaration of the external subset
          130  +        is only emitted if the document has a system identifier.</p>
          131  +
          132  +        <p>The flag <i class="m">-xmlDeclaration</i> determines whether there
          133  +        will be an XML Declaration and a newline emitted before
          134  +        anything else. The default is not to emit one. If this flag is
          135  +        given with a true argument then</p>
          136  +
          137  +        <p>
          138  +<i class="m">-encString</i> sets the encoding value in the XML
          139  +        Declaration. Otherwise this option is ignored. Please note
          140  +        that this option just enhances the string representation of the
          141  +        generated XML Declaration with an encoding information string,
          142  +        nothing more. It's up to the user to handle encoding in case
          143  +        of writing to a channel or reparsing.</p>
          144  +            
          145  +        <p>If the option <i class="m">-escapeAllQuot</i> is given,
          146  +        quotation marks will be escaped with &amp;quot; even in text
          147  +        content of elements.</p>
          148  +
          149  +        <p>If the option <i class="m">-indentAttrs</i> is
          150  +        given, then attributes will each be separated with newlines
          151  +        and indented to the same level as the parent node plus the
          152  +        value given as argument to <i class="m">-indentAttrs</i> (0..8).</p>
          153  +
          154  +        <p>If the option <i class="m">-nogtescape</i> is given then the
          155  +        character '&gt;' won't get escaped in attribute values and text
          156  +        content of elements. The default is to escape this
          157  +        character.</p>
          158  +
          159  +        <p>If the option <i class="m">-noEmptyElementTag</i> is given then no
          160  +        empty tag syntax will be used. Instead, if an element has
          161  +        empty content it will be serialized with an element start tag
          162  +        and an immediately following element end tag.</p>
          163  +</dd>
   128    164   
   129    165         
   130    166   
   131    167         
   132    168           <dt>
   133    169   <b class="method">asHTML</b> <b class="option">?-channel
   134    170   channelId?</b> <b class="option">?-escapeNonASCII?</b> <b class="option">?-htmlEntities?</b> <b class="option">?-doctypeDeclaration &lt;boolean&gt;?</b>
   135    171   </dt> 
   136         -        <dd>Returns the DOM tree serialized acording to HTML rules (HTML
   137         -elements are recognized regardless of case, without end tags for emtpy HTML
   138         -elements etc.), as string or sends the output directly to the given
   139         -channelId. If the option <i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII
   140         -character in attribute values or element PCDATA content will be escaped as
   141         -character reference in decimal representation. If the option
   142         -<i class="m">-htmlEntities</i> is given, a character is outputed using a HTML 4.01
   143         -character entity reference, if one is defined for it. The flag
   144         -<i class="m">-doctypeDeclaration</i> determines, whether there will be a DOCTYPE
   145         -declaration emitted before the first node of the document. The default is, to
   146         -do not. The DOCTYPE name will always be the element name of the document
   147         -element without case normalization. An external entity declaration of the
   148         -external subset is only emitted, if the document has a system identifier. The
   149         -doctype declaration will be written from the avaliable informations, without
   150         -check, if this is a known (w3c) HTML version information or if the document
   151         -confirms to the given HTML version.</dd>
          172  +        <dd>Returns the DOM tree serialized according to HTML rules
          173  +        (HTML elements are recognized regardless of case, without end
          174  +        tags for empty HTML elements etc.) as string or sends the
          175  +        output directly to the given channelId. If the option
          176  +        <i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII
          177  +        character in attribute values or element PCDATA content will
          178  +        be escaped as character reference in decimal representation.
          179  +        If the option <i class="m">-htmlEntities</i> is given, a character is
          180  +        written using its HTML 4.01 character entity reference, if it
          181  +        has one. If the flag <i class="m">-doctypeDeclaration</i> is given there
          182  +        will be a DOCTYPE declaration emitted before the first node of
          183  +        the document. The default is, to do not. The DOCTYPE name will
          184  +        always be the element name of the document element without
          185  +        case normalization. An external entity declaration of the
          186  +        external subset is only emitted, if the document has a system
          187  +        identifier. The doctype declaration will be written from the
          188  +        available information, without check, if this is a known
          189  +        (w3c) HTML version information or if the document confirms to
          190  +        the given HTML version.</dd>
   152    191         
   153    192   
   154    193         
   155    194           <dt><b class="method">asText</b></dt>
   156         -          <dd>The asText method outputs the result tree by outputting
   157         -the string-value of every text node in the result tree in document
   158         -order without any escaping. In effect, this is what the xslt output method
   159         -"text" (XSLT 1.0 recommendation, section 16.3) does.</dd>
   160         -      
   161         -
          195  +          <dd>The asText method returns the tree by serializing the
          196  +          string-value of every text node in document order without
          197  +          any escaping. In effect, this is what the xslt output method
          198  +          "text" (XSLT 1.0 recommendation, section 16.3) does.</dd>
          199  +      
          200  +
          201  +      
          202  +        <dt>
          203  +<b class="method">asJSON</b> <b class="option">?-indent none/0..8?</b> <b class="option">?-channel channelId?</b>
          204  +</dt>
          205  +          <dd>
          206  +<p>The asJSON method serializes the tree into a valid
          207  +          JSON data string. In general, this may be a lossy
          208  +          serialization. For this serialization all comment, character
          209  +          data sections and processing instruction nodes, all
          210  +          attributes and all XML namespaces are ignored. Only element
          211  +          and text nodes may be reflected in the generated JSON
          212  +          serialization. Appropriate JSON data type information of a
          213  +          node will be respected.</p>
          214  +
          215  +          <p>If an element node has the JSON type OBJECT, then every
          216  +          element node child of this element will be serialized as
          217  +          member of that object, with the node name of the child as
          218  +          the member name and the relevant children of that child as
          219  +          the value. Every other child nodes will be ignored.</p>
          220  +
          221  +          <p>If an element node has the JSON type ARRAY, then the text
          222  +          and element node children of that element node are serialized
          223  +          as the consecutive values of the array. Element node children
          224  +          of an ARRAY element will be container nodes for nested ARRAY
          225  +          or OBJECT values.</p>
          226  +
          227  +          <p>Text nodes with the JSON types TRUE, FALSE or NULL will
          228  +          be serialized to the corresponding JSON token without
          229  +          looking at the value of the text node. A text node without
          230  +          JSON type will always be serialized as a JSON string token.
          231  +          A text node with JSON type NUMBER will be serialized as JSON
          232  +          number token if the text node value is in fact a valid JSON
          233  +          number and as a JSON string if not.</p>
          234  +
          235  +          <p>If an element node doesn't has a JSON type then the
          236  +          serialization of its children is determined by the following
          237  +          rules:</p>
          238  +
          239  +          <p>Only text and element node child are relevant. If the
          240  +          element node to serialize is the member of a JSON object and
          241  +          there is no relevant child node the value of that member
          242  +          will be an empty JSON string. If the only relevant child
          243  +          node of this element node is a text node then the JSON
          244  +          value of that text node will be the value of the object
          245  +          member. If the element has more than one relevant child
          246  +          nodes and the first one is a text node then the relevant
          247  +          children will be serialized as JSON array. If the only
          248  +          relevant child node is an element node or the first relevant
          249  +          child is an element node and the node name of that only or
          250  +          first relevant child isn't equal to the array container node
          251  +          name all element node children will be serialized as the
          252  +          members of a JSON object (while ignoring any intermixed text
          253  +          nodes). If the only or first relevant child is an element
          254  +          node and the node name of this child is equal to the array
          255  +          container element name then all relevant children will be
          256  +          serialized as the values of a JSON array.</p>
          257  +
          258  +          <p>If the element to serialize is a value of a JSON array
          259  +          and the node name of this element isn't equal to the array
          260  +          container node name that element will be seen as a container
          261  +          node for a JSON object and all element node children will be
          262  +          serialized as the members of that array while ignoring any
          263  +          text node children. If the element to serialize is a value of
          264  +          a JSON array and the node name of this element is equal to
          265  +          the array container node name, all relevant children will be
          266  +          serialized as JSON array.</p>
          267  +
          268  +          <p>If the <i class="m">-channel</i> option is given the serialization
          269  +          isn't returned as string but send directly to the channel,
          270  +          given as argument to the option.</p>
          271  +
          272  +          <p>If the <i class="m">-indent</i> option is given and the argument
          273  +          given to this option isn't "none" then the returned JSON
          274  +          string is "pretty-printed". The numeric argument to this
          275  +          option defines the number of spaces for any indentation
          276  +          level. The default is to not emit any additional
          277  +          white space.</p>
          278  +</dd>
          279  +      
          280  +      
   162    281         
   163    282           <dt>
   164    283   <b class="method">publicId</b> <i class="m">?publicId?</i>
   165    284   </dt>
   166    285           <dd>Returns the public identifier of the doctype declaration of the
   167    286   document, if there is one, otherwise the empty string. If there is a value
   168    287   given to the method, the public identifier of the document is set to this
................................................................................
   176    295           <dd>Returns the system identifier of the doctype declaration of the
   177    296   document, if there is one, otherwise the empty string. If there is a value
   178    297   given to the method, the system identifier of the document is set to this
   179    298   value.</dd>
   180    299         
   181    300   
   182    301         
   183         -        <dt><b class="method">internalSubset <i class="m">?internalSubset?</i>
   184         -</b></dt>
          302  +        <dt>
          303  +<b class="method">internalSubset</b> <i class="m">?internalSubset?</i>
          304  +</dt>
   185    305           <dd>Returns the internal subset of the doctype declaration of the
   186    306   document, if there is one, otherwise the empty string. If there is a value
   187    307   given to the method, the internal subset of the document is set to this
   188         -value. Note, that none of the parsing methods preserve the internal subset
          308  +value. Note that none of the parsing methods preserve the internal subset
   189    309   of a document; a freshly parsed document will always have an empty internal
   190         -subset. Also note, that the method doesen't do any syntactical check on a
          310  +subset. Also note, that the method doesn't do any syntactical check on a
   191    311   given internal subset.</dd>
   192    312         
   193    313   
   194    314         
   195    315           <dt>
   196    316   <b class="method">cdataSectionElements</b> <i class="m">(?URI:?localname|*) ?&lt;boolean&gt;?</i>
   197    317   </dt>
   198         -        <dd>This method allows to control, for which element nodes
   199         -the text node childs will be serialized as CDATA sections (this affects only
          318  +        <dd>This method allows one to control for which element nodes
          319  +the text node children will be serialized as CDATA sections (this affects only
   200    320   serialization with the asXML method, no text node is altered in any
   201    321   way by this method). IF the method is called with an element name as
   202    322   first argument and a boolean with value true as second argument, every
   203    323   text node child of every element node in the document with the same
   204    324   name as the first argument will be serialized as CDATA section. If the
   205    325   second argument is a boolean with value false, all text nodes of all
   206    326   elements with the same name as the first argument will be serialized
   207         -as usual. Namespaced element names have to given in the form
          327  +as usual. Namespaced element names have to be given in the form
   208    328   namespace_URI:localname, not in the otherwise usual prefix:localname
   209    329   form. With two arguments called, the method returns the used boolean
   210    330   value. If the method is called with only an element name, it will
   211         -return a boolean value, indicating, if the text nodes childs of all
          331  +return a boolean value, indicating that the text node children of all
   212    332   elements with that name in the document will be serialized as CDATA
   213    333   section elements (return value 1) or not (return value 0). If the
   214    334   method is called with only one argument and that argument is an
   215    335   asterisk ('*'), then the method returns an unordered list of all
   216         -element names of the document, for which the text node childs will be
          336  +element names of the document, for which the text node children will be
   217    337   serialized as CDATA section nodes.</dd>
   218    338         
   219    339   
   220    340         
   221    341           <dt>
   222    342   <b class="method">selectNodesNamespaces</b> <b class="option">?prefixUriList?</b>
   223    343   </dt>
   224         -        <dd>This method allows to control a document global prefix
   225         -to namespace URI mapping, which will be used for selectNodes method
   226         -calls (on document as well as on all nodes, which belongs to the
   227         -document), if it is not overwritten by using the -namespaces option of
   228         -the selectNodes method. Any namespace prefix within an xpath
   229         -expression will be first resolved against this list. If the list bind
   230         -the same prefix to different namespaces, then the first binding will
   231         -win. If a prefix could not resolved against the document global prefix
   232         -/ namespaces list, then the namespace definitions in scope of the
   233         -context node will be used to resolve the prefix, as usual. If the
   234         -optional argument <i class="m">prefixUriList</i> is given, then the global prefix /
   235         -namespace list is set to this list and returns it. Without
   236         -the optional argument the method returns the current list. The
   237         -default is the empty list.</dd>
          344  +        <dd>This method allows one to control a document global prefix
          345  +        to namespace URI mapping, which will be used for selectNodes
          346  +        method calls (on document as well as on all nodes, which
          347  +        belongs to the document) if it is not overwritten by using
          348  +        the -namespaces option of the selectNodes method. Any
          349  +        namespace prefix within an xpath expression will be first
          350  +        resolved against this list. If the list binds the same prefix
          351  +        to different namespaces, then the first binding will win. If a
          352  +        prefix could not resolved against the document global prefix /
          353  +        namespaces list, then the namespace definitions in scope of
          354  +        the context node will be used to resolve the prefix, as usual.
          355  +        If the optional argument <i class="m">prefixUriList</i> is given, then
          356  +        the global prefix / namespace list is set to this list and
          357  +        returns it. Without the optional argument the method returns
          358  +        the current list. The default is the empty list.</dd>
   238    359         
   239    360   
   240    361         
   241    362           <dt>
   242    363   <b class="method">xslt</b> <b class="option">?-parameters
   243    364   parameterList?</b> <b class="option">?-ignoreUndeclaredParameters?</b>
          365  +<b class="option">?-maxApplyDepth int?</b>
   244    366   <b class="option">?-xsltmessagecmd script?</b> <i class="m">stylesheet</i> <i class="m">?outputVar?</i>
   245    367   </dt>
   246    368           <dd>Applies an XSLT transformation on the whole document of the node
   247    369   object using the XSLT <i class="m">stylesheet</i> (given as domDoc). Returns a document
   248    370   object containing the result document of the transformation and stores that
   249    371   document object in the optional <i class="m">outputVar</i>, if that was given.
   250    372   
................................................................................
   251    373   <p>The optional <i class="m">-parameters</i> option sets top level
   252    374   &lt;xsl:param&gt; to string values. The <i class="m">parameterList</i> has to be a tcl
   253    375   list consisting of parameter name and value pairs.</p>
   254    376   
   255    377   <p>If the option <i class="m">-ignoreUndeclaredParameters</i> is given, then parameter
   256    378   names in the <i class="m">parameterList</i> given to the <i class="m">-parameters</i> options that
   257    379   are not declared as top-level parameters in the stylesheet are silently
   258         -ignored. Without this option, an error is raised, if the user tries to set a
   259         -top-level parameter, which is not declared in the stylesheet.</p>
          380  +ignored. Without this option, an error is raised if the user tries to set a
          381  +top-level parameter that is not declared in the stylesheet.</p>
          382  +
          383  +<p>The option <i class="m">-maxApplyDepth</i> expects a positiv integer as
          384  +argument. By default, the xslt engine allows xslt templates to nest up
          385  +to 3000 levels (and raises error if they nest deeper). This limit can
          386  +be set by the <i class="m">-maxApplyDepth</i> option.</p>
   260    387   
   261    388   <p>The <i class="m">-xsltmessagecmd</i> option sets a callback for xslt:message elements
   262    389   in the stylesheet. The actual command consists of the script, given as argument
   263    390   to the option, appended with the XML Fragment from instantiating the
   264    391   xsl:message element content as string (as if the XPath string() function would
   265    392   have been applied to the XML Fragment) and a flag, which indicates, if the
   266         -xsl:message has an attribute "terminate" with the value "yes".</p>
          393  +xsl:message has an attribute "terminate" with the value "yes". If the
          394  +called script returns anything else then TCL_OK then the xslt
          395  +transformation will be aborted, returning error. If the called script
          396  +returns -code break, the error message is empty, otherwise the result
          397  +code is reported. In case of terminated transformation, the outputVar,
          398  +if given, is set to the empty string.</p>
   267    399   </dd>
   268    400         
   269    401   
   270    402         
   271    403           <dt>
   272    404   <b class="method">toXSLTcmd</b> ?<i class="m">objVar</i>?</dt>
   273    405        
   274    406           <dd>If the DOM tree represents a valid XSLT stylesheet, this method
   275    407   transforms the DOM tree into an xslt command, otherwise it returns error. The
   276         -created xsltCmd is returnd and stored in the <i class="m">objVar</i>, if a var name was
          408  +created xsltCmd is returned and stored in the <i class="m">objVar</i>, if a var name was
   277    409   given. A successful transformation of the DOM tree to an xsltCmd removes the
   278    410   domDoc cmd and all nodeCmds of the document. 
   279    411   
   280    412   <p>The syntax of the created xsltCmd is:</p>
   281    413    
   282    414   <pre class="syntax">
   283    415   <b class="cmd">xsltCmd</b> <b class="option">method</b> <b class="option">?arg ...?</b>
................................................................................
   286    418   <p>The valid methods are:</p>
   287    419   
   288    420   <dl class="commandlist">
   289    421     
   290    422       <dt>
   291    423   <b class="method">transform</b> <b class="option">?-parameters
   292    424   parameterList?</b> <b class="option">?-ignoreUndeclaredParameters?</b>
          425  +<b class="option">?-maxApplyDepth int?</b> 
   293    426   <b class="option">?-xsltmessagecmd script?</b> <i class="m">domDoc</i> <i class="m">?outputVar?</i>
   294    427   </dt>          
   295    428   
   296    429           <dd>Applies XSLT transformation on the document
   297    430   <i class="m">domDoc</i>. Returns a document object containing the
   298    431   result document of that transformation and stores it in the optional
   299    432   <i class="m">outputVar</i>. 
................................................................................
   301    434   <p>The optional <i class="m">-parameters</i> option sets top level
   302    435   &lt;xsl:param&gt; to string values. The <i class="m">parameterList</i> has to be a tcl
   303    436   list consisting of parameter name and value pairs.</p>
   304    437   
   305    438   <p>If the option <i class="m">-ignoreUndeclaredParameters</i> is given, then parameter
   306    439   names in the <i class="m">parameterList</i> given to the <i class="m">-parameters</i> options that
   307    440   are not declared as top-level parameters in the stylesheet are silently
   308         -ignored. Without this option, an error is raised, if the user tries to set a
          441  +ignored. Without this option, an error is raised if the user tries to set a
   309    442   top-level parameter, which is not declared in the stylesheet.</p>
          443  +
          444  +<p>The option <i class="m">-maxApplyDepth</i> expects a positiv integer as
          445  +argument. By default, the xslt engine allows xslt templates to nest up
          446  +to 3000 levels (and raises error if they nest deeper). This limit can
          447  +be set by the <i class="m">-maxApplyDepth</i> option.</p>
   310    448   
   311    449   <p>The <i class="m">-xsltmessagecmd</i> option sets a callback for xslt:message elements
   312    450   in the stylesheet. The actual command consists of the script, given as argument
   313    451   to the option, appended with the XML Fragment from instantiating the
   314    452   xsl:message element content as string (as if the XPath string() function would
   315    453   have been applied to the XML Fragment) and a flag, which indicates, if the
   316    454   xsl:message has an attribute "terminate" with the value "yes".</p>
................................................................................
   329    467    </dd>
   330    468         
   331    469   
   332    470         
   333    471           <dt>
   334    472   <b class="method">normalize</b> <i class="m">?-forXPath?</i>
   335    473   </dt>
   336         -        <dd>Puts all Text nodes in the document
          474  +        <dd>Puts all text nodes in the document
   337    475   into a "normal" form where only structure (e.g., elements,
   338    476   comments, processing instructions and CDATA
   339         -sections) separates Text nodes, i.e., there
   340         -are neither adjacent Text nodes nor empty Text nodes. If the option
          477  +sections) separates text nodes, i.e., there
          478  +are neither adjacent text nodes nor empty text nodes. If the option
   341    479   <i class="m">-forXPath</i> is given, all CDATA sections in the nodes are
   342    480   converted to text nodes, as a first step before the
   343    481   normalization. </dd>
   344    482         
   345    483   
   346    484         
   347    485           <dt><b class="method">nodeType</b></dt>
................................................................................
   350    488         
   351    489   
   352    490         
   353    491           <dt>
   354    492   <b class="method">getElementById</b> <i class="m">id</i>
   355    493   </dt>
   356    494           <dd>Returns the node having a id attribute with value
   357         -<i class="m">id</i> or the emtpy string, if no node has an id attribute with that value.</dd>
          495  +<i class="m">id</i> or the empty string, if no node has an id attribute with that value.</dd>
   358    496         
   359    497   
   360    498         
   361    499           <dt>
   362    500   <b class="method">firstChild</b> <b class="variable">?objVar?</b>
   363    501   </dt>
   364    502           <dd>Returns the first top level node of the document.</dd>
................................................................................
   406    544         
   407    545   
   408    546         
   409    547           <dt>
   410    548   <b class="method">insertBefore</b> <i class="m">newChild</i>  <i class="m">refChild</i>
   411    549   </dt>
   412    550           <dd>Insert <i class="m">newChild</i> before the <i class="m">refChild</i> into the list of
   413         -top level nodes of the document. If <i class="m">refChild</i> is the empty string, insert
          551  +top level nodes of the document. If <i class="m">refChild</i> is the empty string, inserts
   414    552   <i class="m">newChild</i> at the end of the top level nodes.</dd>
   415    553         
   416    554   
   417    555         
   418    556           <dt>
   419    557   <b class="method">replaceChild</b> <i class="m">newChild</i>  <i class="m">oldChild</i>
   420    558   </dt>
   421         -        <dd>Replace <i class="m">oldChild</i> with <i class="m">newChild</i> in the list of
          559  +        <dd>Replaces <i class="m">oldChild</i> with <i class="m">newChild</i> in the list of
   422    560   children of that node. The <i class="m">oldChild</i> node will be part of the
   423    561   document fragment list after this operation.</dd>
   424    562         
   425    563   
   426    564         
   427    565           <dt>
   428    566   <b class="method">appendFromList</b> <i class="m">list</i>
................................................................................
   455    593   <p>The argument <i class="m">xpathQuery</i> has to be a valid XPath
   456    594   expression. However, there is one exception to that rule. Tcl variable
   457    595   names can appear in the XPath statement at any position where it is
   458    596   legal according to the rules of the XPath syntax to put an XPath
   459    597   variable. The value of the variable is substituted for the variable
   460    598   name. Ignoring the syntax rules of XPath the Tcl variable name may be
   461    599   any legal Tcl var name: local variables, global variables, array
   462         -entries and so on.</p>
          600  +entries and so on.  The value will always be seen as string literal by
          601  +the xpath engine. Cast the value explicitly with the according xpath
          602  +functions (number(), boolean()) to another data type, if needed.</p>
   463    603   
   464    604   <p>The option <i class="m">-namespaces</i> expects a tcl list with prefix /
   465    605   namespace pairs as argument. If this option is not given, then any
   466    606   namespace prefix within the xpath expression will be first resolved
   467    607   against the list of prefix / namespace pairs set with the
   468         -selectNodesNamespaces method for the document, the node belongs to. If
          608  +selectNodesNamespaces method for the document the node belongs to. If
   469    609   this fails, then the namespace definitions in scope of the context
   470    610   node will be used to resolve the prefix. If this option is given, any
   471    611   namespace prefix within the xpath expression will be first resolved
   472    612   against that given list (and ignoring the document global prefix /
   473         -namespace list). If the list bind the same prefix to different
          613  +namespace list). If the list binds the same prefix to different
   474    614   namespaces, then the first binding will win.  If this fails, then the
   475    615   namespace definitions in scope of the context node will be used to
   476    616   resolve the prefix, as usual.</p>
   477    617   
   478    618   <p>If the <i class="m">-cache</i> option is used with a true value, then the
   479         -<i class="m">xpathQuery</i> will be looked up in a document specific cache. If the query
   480         -is found, then the stored pre-compiled query will be used. If the
   481         -query isn't found, it will be pre-compiled and stored in the cache,
   482         -for use in further calls. Please notice, that the <i class="m">xpathQuery</i> as given as
   483         -string is used as key for the cache. This means, that equal XPath
   484         -expressions, which differ only in white space are treated as
   485         -different cache entries. Special care is needed, if the XPath
   486         -expression includes namespace prefixes. During pre-compilation, the
   487         -prefixes will be resolved first to the prefix / namespace pairs of
   488         -the <i class="m">-namespaces</i> option, if given, and to the namespaces
   489         -in scope of the context node at pre-compilation time. If the XPath
   490         -is found in the cache, neither the <i class="m">-namespaces</i> option nor
   491         -the namespaces in scope of the context node will be taken in
   492         -account but the already resolved (stored) namespaces will be used
   493         -for the query.</p>
          619  +<i class="m">xpathQuery</i> will be looked up in a document specific cache. If
          620  +the query is found, then the stored pre-compiled query will be used.
          621  +If the query isn't found, it will be compiled and stored in the cache,
          622  +for use in further calls. Please notice, that the <i class="m">xpathQuery</i> as
          623  +given as string is used as key for the cache. This means that equal
          624  +XPath expressions, which differ only in white space, are treated as
          625  +different cache entries. Special care is needed if the XPath
          626  +expression includes namespace prefixes or references to tcl variables.
          627  +Both namespace prefixes and tcl variable references will be resolved
          628  +according to the XML prefix namespace mappings and tcl variable values
          629  +at expression compilation time. If the same XPath expression is used
          630  +later on in a context with other XML prefix namespace mappings or
          631  +values of the used tcl variables, make sure to first remove the
          632  +compiled expression from the cache with the help of the
          633  +<b class="method">deleteXPathCache</b> method, to force a recompilation.
          634  +Without using the <i class="m">-cache</i> option such consideration is never
          635  +needed.</p>
   494    636   
   495    637   <p>Examples:</p>
   496    638             <pre class="example">set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
   497    639   foreach paragraph $paragraphNodes {
   498    640       lappend  values [$paragraph selectNodes attribute::type]
   499    641   }
   500    642   
................................................................................
   502    644   set root [$doc documentElement]
   503    645   set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</pre>
   504    646   
   505    647             </dd>
   506    648         
   507    649   
   508    650         
   509         -        <dt><b class="method">baseURI <i class="m">?URI?</i>
   510         -</b></dt>
          651  +        <dt>
          652  +<b class="method">baseURI</b> <i class="m">?URI?</i>
          653  +</dt>
   511    654           <dd>Returns the present baseURI of the document. If the optional 
   512    655   argument URI is given, sets the base URI of the document to the given URI.</dd>
   513    656         
   514    657   
   515    658         
   516    659           <dt>
   517    660   <b class="method">appendFromScript</b> <i class="m">tclScript</i>
................................................................................
   540    683   expressions of the document are freed. If called with the optional
   541    684   argument <i class="m">xpathQuery</i>, this single XPath query will be removed
   542    685   from the cache, if it is there. The method always returns an
   543    686   empty string.</dd>
   544    687         
   545    688   
   546    689     </dl><p>Otherwise, if an unknown method name is given, the command with the
   547         -same name as the given metho within the namespace <tt class="samp">::dom::domDoc</tt> is
          690  +same name as the given method within the namespace <tt class="samp">::dom::domDoc</tt> is
   548    691   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
   549         -are not moved into the tree they are automaticaly deleted, when the whole
          692  +are not moved into the tree they are automatically deleted as soon as the whole
   550    693   document gets deleted.</p>
   551    694   
   552         -    <h2><a name="SECTid0x80cf590">SEE ALSO</a></h2><p class="seealso">dom, domNode</p>
          695  +    <h2><a name="SECTid0x1efaea0">SEE ALSO</a></h2><p class="seealso">dom, domNode</p>
   553    696   
   554         -    <h2><a name="SECTid0x80cf7b0">KEYWORDS</a></h2><p class="keywords">
          697  +    <h2><a name="SECTid0x1efb230">KEYWORDS</a></h2><p class="keywords">
   555    698   <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>
   556    699   </p>
   557    700   
   558    701   </div><hr class="navsep"><div class="navbar" align="center">
   559         -<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>
          702  +<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>
   560    703   </div>
   561    704   </body>
   562    705   </html>

Changes to doc/domDoc.n.

   159    159   '\" END man.macros
   160    160   .TH domDoc n "" Tcl ""
   161    161   .BS
   162    162   .SH NAME
   163    163   domDoc \- Manipulates an instance of a DOM document object
   164    164   .SH SYNOPSIS
   165    165   .nf
   166         -\&\fBdomDocObjCmd\fP \fImethod\fR ?\fIarg arg ...\fR?
          166  +domDocObjCmd \fImethod\fR ?\fIarg arg ...\fR?
          167  +.fi
          168  +.nf
          169  +domDoc \fIdocToken\fR \fImethod\fR ?\fIarg arg ...\fR?
   167    170   .fi
   168    171   .BE
   169    172   .SH "DESCRIPTION "
   170    173   .PP
   171    174   This command manipulates one particular instance of a document
   172    175   object. \fImethod\fR indicates a specific method of the document class. These
   173    176   methods should closely conform to the W3C recommendation "Document Object Model
................................................................................
   189    192   matching (glob style) \fIlocalname\fR and having the given namespace
   190    193   \&\fIuri\fR.
   191    194   .TP
   192    195   \&\fB\fBcreateElement\fP \fItagName\fB ?\fIobjVar\fB?
   193    196   \&\fRCreates (allocates) a new element node with node name
   194    197   \&\fItagName\fR, append it to the hidden fragment list in the document
   195    198   object and returns the node object.  If \fIobjVar\fR is given the new
   196         -node object store in this variable.
          199  +node object is stored in this variable.
   197    200   .TP
   198    201   \&\fB\fBcreateElementNS\fP \fIurl\fB \fItagName\fB ?\fIobjVar\fB?
   199    202   \&\fRCreates (allocates) a new element node within a namespace
   200    203   having \fIuri\fR as the URI and node name \fItagName\fR, which
   201    204   could include the namespace prefix, append it to the hidden fragment list in
   202    205   the document object and returns the node object.  If \fIobjVar\fR is
   203         -given the new node object store in this variable.
          206  +given the new node object is stored in this variable.
   204    207   .TP
   205    208   \&\fB\fBcreateTextNode\fP \fItext\fB ?\fIobjVar\fB?
   206    209   \&\fRCreates (allocates) a new text node with node value
   207    210   \&\fItext\fR, appends it to the hidden fragment list in the document
   208    211   object and returns the node object.  If \fIobjVar\fR is given, the new
   209    212   node object is stored in this variable.
   210    213   .TP
................................................................................
   230    233   Tcl object commands (for nodes, fragment/new nodes, the document object itself)
   231    234   and the underlying DOM tree.
   232    235   .TP
   233    236   \&\fB\fBgetDefaultOutputMethod\fP
   234    237   \&\fRReturns the default output method of the document. This is
   235    238   usually a result of a XSLT transformation.
   236    239   .TP
   237         -\&\fB\fBasXML\fP \fB?-indent none/1..8?\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP \fB?-doctypeDeclaration <boolean>?\fP \fB?-escapeAllQuot?\fP
   238         -\&\fRReturns the DOM tree as an (optional indented) XML
   239         -string or sends the output directly to the given channelId. If the
   240         -option \fI-escapeNonASCII\fR is given, every non 7 bit ASCII
   241         -character in attribute values or element PCDATA content will be
   242         -escaped as character reference in decimal representation. The flag
   243         -\&\fI-doctypeDeclaration\fR determines, whether there will be a DOCTYPE
   244         -declaration emitted before the first node of the document. The default
   245         -is, to do not. The DOCTYPE name will always be the element name of the
   246         -document element. An external entity declaration of the external
   247         -subset is only emitted, if the document has a system identifier. If
   248         -the option \fI-escapeAllQuot\fR is given, quotation marks will be
   249         -escaped with &quot; even in text content of elements.
          240  +\&\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
          241  +\&\fR
          242  +.RS
          243  +.PP
          244  +Returns the DOM tree as an (optional indented) XML
          245  +string or sends the output directly to the given
          246  +channelId.
          247  +.PP
          248  +If the option \fI-escapeNonASCII\fR is given,
          249  +every non 7 bit ASCII character in attribute values or element
          250  +PCDATA content will be escaped as character reference in
          251  +decimal representation.
          252  +.PP
          253  +The flag \fI-doctypeDeclaration\fR determines whether
          254  +there will be a DOCTYPE declaration emitted before the first
          255  +node of the document. The default is not to emit it. The
          256  +DOCTYPE name will always be the element name of the document
          257  +element. An external entity declaration of the external subset
          258  +is only emitted if the document has a system identifier.
          259  +.PP
          260  +The flag \fI-xmlDeclaration\fR determines whether there
          261  +will be an XML Declaration and a newline emitted before
          262  +anything else. The default is not to emit one. If this flag is
          263  +given with a true argument then
          264  +.PP
          265  +\&\fI-encString\fR sets the encoding value in the XML
          266  +Declaration. Otherwise this option is ignored. Please note
          267  +that this option just enhances the string representation of the
          268  +generated XML Declaration with an encoding information string,
          269  +nothing more. It's up to the user to handle encoding in case
          270  +of writing to a channel or reparsing.
          271  +.PP
          272  +If the option \fI-escapeAllQuot\fR is given,
          273  +quotation marks will be escaped with &quot; even in text
          274  +content of elements.
          275  +.PP
          276  +If the option \fI-indentAttrs\fR is
          277  +given, then attributes will each be separated with newlines
          278  +and indented to the same level as the parent node plus the
          279  +value given as argument to \fI-indentAttrs\fR (0..8).
          280  +.PP
          281  +If the option \fI-nogtescape\fR is given then the
          282  +character '>' won't get escaped in attribute values and text
          283  +content of elements. The default is to escape this
          284  +character.
          285  +.PP
          286  +If the option \fI-noEmptyElementTag\fR is given then no
          287  +empty tag syntax will be used. Instead, if an element has
          288  +empty content it will be serialized with an element start tag
          289  +and an immediately following element end tag.
          290  +.RE
   250    291   .TP
   251    292   \&\fB\fBasHTML\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP \fB?-htmlEntities?\fP \fB?-doctypeDeclaration <boolean>?\fP
   252         -\&\fRReturns the DOM tree serialized acording to HTML rules (HTML
   253         -elements are recognized regardless of case, without end tags for emtpy HTML
   254         -elements etc.), as string or sends the output directly to the given
   255         -channelId. If the option \fI-escapeNonASCII\fR is given, every non 7 bit ASCII
   256         -character in attribute values or element PCDATA content will be escaped as
   257         -character reference in decimal representation. If the option
   258         -\&\fI-htmlEntities\fR is given, a character is outputed using a HTML 4.01
   259         -character entity reference, if one is defined for it. The flag
   260         -\&\fI-doctypeDeclaration\fR determines, whether there will be a DOCTYPE
   261         -declaration emitted before the first node of the document. The default is, to
   262         -do not. The DOCTYPE name will always be the element name of the document
   263         -element without case normalization. An external entity declaration of the
   264         -external subset is only emitted, if the document has a system identifier. The
   265         -doctype declaration will be written from the avaliable informations, without
   266         -check, if this is a known (w3c) HTML version information or if the document
   267         -confirms to the given HTML version.
          293  +\&\fRReturns the DOM tree serialized according to HTML rules
          294  +(HTML elements are recognized regardless of case, without end
          295  +tags for empty HTML elements etc.) as string or sends the
          296  +output directly to the given channelId. If the option
          297  +\&\fI-escapeNonASCII\fR is given, every non 7 bit ASCII
          298  +character in attribute values or element PCDATA content will
          299  +be escaped as character reference in decimal representation.
          300  +If the option \fI-htmlEntities\fR is given, a character is
          301  +written using its HTML 4.01 character entity reference, if it
          302  +has one. If the flag \fI-doctypeDeclaration\fR is given there
          303  +will be a DOCTYPE declaration emitted before the first node of
          304  +the document. The default is, to do not. The DOCTYPE name will
          305  +always be the element name of the document element without
          306  +case normalization. An external entity declaration of the
          307  +external subset is only emitted, if the document has a system
          308  +identifier. The doctype declaration will be written from the
          309  +available information, without check, if this is a known
          310  +(w3c) HTML version information or if the document confirms to
          311  +the given HTML version.
   268    312   .TP
   269    313   \&\fB\fBasText\fP
   270         -\&\fRThe asText method outputs the result tree by outputting
   271         -the string-value of every text node in the result tree in document
   272         -order without any escaping. In effect, this is what the xslt output method
          314  +\&\fRThe asText method returns the tree by serializing the
          315  +string-value of every text node in document order without
          316  +any escaping. In effect, this is what the xslt output method
   273    317   "text" (XSLT 1.0 recommendation, section 16.3) does.
          318  +.TP
          319  +\&\fB\fBasJSON\fP \fB?-indent none/0..8?\fP \fB?-channel channelId?\fP
          320  +\&\fR
          321  +.RS
          322  +.PP
          323  +The asJSON method serializes the tree into a valid
          324  +JSON data string. In general, this may be a lossy
          325  +serialization. For this serialization all comment, character
          326  +data sections and processing instruction nodes, all
          327  +attributes and all XML namespaces are ignored. Only element
          328  +and text nodes may be reflected in the generated JSON
          329  +serialization. Appropriate JSON data type information of a
          330  +node will be respected.
          331  +.PP
          332  +If an element node has the JSON type OBJECT, then every
          333  +element node child of this element will be serialized as
          334  +member of that object, with the node name of the child as
          335  +the member name and the relevant children of that child as
          336  +the value. Every other child nodes will be ignored.
          337  +.PP
          338  +If an element node has the JSON type ARRAY, then the text
          339  +and element node children of that element node are serialized
          340  +as the consecutive values of the array. Element node children
          341  +of an ARRAY element will be container nodes for nested ARRAY
          342  +or OBJECT values.
          343  +.PP
          344  +Text nodes with the JSON types TRUE, FALSE or NULL will
          345  +be serialized to the corresponding JSON token without
          346  +looking at the value of the text node. A text node without
          347  +JSON type will always be serialized as a JSON string token.
          348  +A text node with JSON type NUMBER will be serialized as JSON
          349  +number token if the text node value is in fact a valid JSON
          350  +number and as a JSON string if not.
          351  +.PP
          352  +If an element node doesn't has a JSON type then the
          353  +serialization of its children is determined by the following
          354  +rules:
          355  +.PP
          356  +Only text and element node child are relevant. If the
          357  +element node to serialize is the member of a JSON object and
          358  +there is no relevant child node the value of that member
          359  +will be an empty JSON string. If the only relevant child
          360  +node of this element node is a text node then the JSON
          361  +value of that text node will be the value of the object
          362  +member. If the element has more than one relevant child
          363  +nodes and the first one is a text node then the relevant
          364  +children will be serialized as JSON array. If the only
          365  +relevant child node is an element node or the first relevant
          366  +child is an element node and the node name of that only or
          367  +first relevant child isn't equal to the array container node
          368  +name all element node children will be serialized as the
          369  +members of a JSON object (while ignoring any intermixed text
          370  +nodes). If the only or first relevant child is an element
          371  +node and the node name of this child is equal to the array
          372  +container element name then all relevant children will be
          373  +serialized as the values of a JSON array.
          374  +.PP
          375  +If the element to serialize is a value of a JSON array
          376  +and the node name of this element isn't equal to the array
          377  +container node name that element will be seen as a container
          378  +node for a JSON object and all element node children will be
          379  +serialized as the members of that array while ignoring any
          380  +text node children. If the element to serialize is a value of
          381  +a JSON array and the node name of this element is equal to
          382  +the array container node name, all relevant children will be
          383  +serialized as JSON array.
          384  +.PP
          385  +If the \fI-channel\fR option is given the serialization
          386  +isn't returned as string but send directly to the channel,
          387  +given as argument to the option.
          388  +.PP
          389  +If the \fI-indent\fR option is given and the argument
          390  +given to this option isn't "none" then the returned JSON
          391  +string is "pretty-printed". The numeric argument to this
          392  +option defines the number of spaces for any indentation
          393  +level. The default is to not emit any additional
          394  +white space.
          395  +.RE
   274    396   .TP
   275    397   \&\fB\fBpublicId\fP \fI?publicId?\fB
   276    398   \&\fRReturns the public identifier of the doctype declaration of the
   277    399   document, if there is one, otherwise the empty string. If there is a value
   278    400   given to the method, the public identifier of the document is set to this
   279    401   value.
   280    402   .TP
   281    403   \&\fB\fBsystemId\fP \fI?systemId?\fB
   282    404   \&\fRReturns the system identifier of the doctype declaration of the
   283    405   document, if there is one, otherwise the empty string. If there is a value
   284    406   given to the method, the system identifier of the document is set to this
   285    407   value.
   286    408   .TP
   287         -\&\fB\fBinternalSubset \fI?internalSubset?\fB\fP
          409  +\&\fB\fBinternalSubset\fP \fI?internalSubset?\fB
   288    410   \&\fRReturns the internal subset of the doctype declaration of the
   289    411   document, if there is one, otherwise the empty string. If there is a value
   290    412   given to the method, the internal subset of the document is set to this
   291         -value. Note, that none of the parsing methods preserve the internal subset
          413  +value. Note that none of the parsing methods preserve the internal subset
   292    414   of a document; a freshly parsed document will always have an empty internal
   293         -subset. Also note, that the method doesen't do any syntactical check on a
          415  +subset. Also note, that the method doesn't do any syntactical check on a
   294    416   given internal subset.
   295    417   .TP
   296    418   \&\fB\fBcdataSectionElements\fP \fI(?URI:?localname|*) ?<boolean>?\fB
   297         -\&\fRThis method allows to control, for which element nodes
   298         -the text node childs will be serialized as CDATA sections (this affects only
          419  +\&\fRThis method allows one to control for which element nodes
          420  +the text node children will be serialized as CDATA sections (this affects only
   299    421   serialization with the asXML method, no text node is altered in any
   300    422   way by this method). IF the method is called with an element name as
   301    423   first argument and a boolean with value true as second argument, every
   302    424   text node child of every element node in the document with the same
   303    425   name as the first argument will be serialized as CDATA section. If the
   304    426   second argument is a boolean with value false, all text nodes of all
   305    427   elements with the same name as the first argument will be serialized
   306         -as usual. Namespaced element names have to given in the form
          428  +as usual. Namespaced element names have to be given in the form
   307    429   namespace_URI:localname, not in the otherwise usual prefix:localname
   308    430   form. With two arguments called, the method returns the used boolean
   309    431   value. If the method is called with only an element name, it will
   310         -return a boolean value, indicating, if the text nodes childs of all
          432  +return a boolean value, indicating that the text node children of all
   311    433   elements with that name in the document will be serialized as CDATA
   312    434   section elements (return value 1) or not (return value 0). If the
   313    435   method is called with only one argument and that argument is an
   314    436   asterisk ('*'), then the method returns an unordered list of all
   315         -element names of the document, for which the text node childs will be
          437  +element names of the document, for which the text node children will be
   316    438   serialized as CDATA section nodes.
   317    439   .TP
   318    440   \&\fB\fBselectNodesNamespaces\fP \fB?prefixUriList?\fP
   319         -\&\fRThis method allows to control a document global prefix
   320         -to namespace URI mapping, which will be used for selectNodes method
   321         -calls (on document as well as on all nodes, which belongs to the
   322         -document), if it is not overwritten by using the -namespaces option of
   323         -the selectNodes method. Any namespace prefix within an xpath
   324         -expression will be first resolved against this list. If the list bind
   325         -the same prefix to different namespaces, then the first binding will
   326         -win. If a prefix could not resolved against the document global prefix
   327         -/ namespaces list, then the namespace definitions in scope of the
   328         -context node will be used to resolve the prefix, as usual. If the
   329         -optional argument \fIprefixUriList\fR is given, then the global prefix /
   330         -namespace list is set to this list and returns it. Without
   331         -the optional argument the method returns the current list. The
   332         -default is the empty list.
          441  +\&\fRThis method allows one to control a document global prefix
          442  +to namespace URI mapping, which will be used for selectNodes
          443  +method calls (on document as well as on all nodes, which
          444  +belongs to the document) if it is not overwritten by using
          445  +the -namespaces option of the selectNodes method. Any
          446  +namespace prefix within an xpath expression will be first
          447  +resolved against this list. If the list binds the same prefix
          448  +to different namespaces, then the first binding will win. If a
          449  +prefix could not resolved against the document global prefix /
          450  +namespaces list, then the namespace definitions in scope of
          451  +the context node will be used to resolve the prefix, as usual.
          452  +If the optional argument \fIprefixUriList\fR is given, then
          453  +the global prefix / namespace list is set to this list and
          454  +returns it. Without the optional argument the method returns
          455  +the current list. The default is the empty list.
   333    456   .TP
   334         -\&\fB\fBxslt\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-xsltmessagecmd script?\fP \fIstylesheet\fB \fI?outputVar?\fB
          457  +\&\fB\fBxslt\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-maxApplyDepth int?\fP \fB?-xsltmessagecmd script?\fP \fIstylesheet\fB \fI?outputVar?\fB
   335    458   \&\fRApplies an XSLT transformation on the whole document of the node
   336    459   object using the XSLT \fIstylesheet\fR (given as domDoc). Returns a document
   337    460   object containing the result document of the transformation and stores that
   338    461   document object in the optional \fIoutputVar\fR, if that was given.
   339    462   .RS
   340    463   .PP
   341    464   The optional \fI-parameters\fR option sets top level
   342    465   <xsl:param> to string values. The \fIparameterList\fR has to be a tcl
   343    466   list consisting of parameter name and value pairs.
   344    467   .PP
   345    468   If the option \fI-ignoreUndeclaredParameters\fR is given, then parameter
   346    469   names in the \fIparameterList\fR given to the \fI-parameters\fR options that
   347    470   are not declared as top-level parameters in the stylesheet are silently
   348         -ignored. Without this option, an error is raised, if the user tries to set a
   349         -top-level parameter, which is not declared in the stylesheet.
          471  +ignored. Without this option, an error is raised if the user tries to set a
          472  +top-level parameter that is not declared in the stylesheet.
          473  +.PP
          474  +The option \fI-maxApplyDepth\fR expects a positiv integer as
          475  +argument. By default, the xslt engine allows xslt templates to nest up
          476  +to 3000 levels (and raises error if they nest deeper). This limit can
          477  +be set by the \fI-maxApplyDepth\fR option.
   350    478   .PP
   351    479   The \fI-xsltmessagecmd\fR option sets a callback for xslt:message elements
   352    480   in the stylesheet. The actual command consists of the script, given as argument
   353    481   to the option, appended with the XML Fragment from instantiating the
   354    482   xsl:message element content as string (as if the XPath string() function would
   355    483   have been applied to the XML Fragment) and a flag, which indicates, if the
   356         -xsl:message has an attribute "terminate" with the value "yes".
          484  +xsl:message has an attribute "terminate" with the value "yes". If the
          485  +called script returns anything else then TCL_OK then the xslt
          486  +transformation will be aborted, returning error. If the called script
          487  +returns -code break, the error message is empty, otherwise the result
          488  +code is reported. In case of terminated transformation, the outputVar,
          489  +if given, is set to the empty string.
   357    490   .RE
   358    491   .TP
   359    492   \&\fB\fBtoXSLTcmd\fP ?\fIobjVar\fB?
   360    493   \&\fRIf the DOM tree represents a valid XSLT stylesheet, this method
   361    494   transforms the DOM tree into an xslt command, otherwise it returns error. The
   362         -created xsltCmd is returnd and stored in the \fIobjVar\fR, if a var name was
          495  +created xsltCmd is returned and stored in the \fIobjVar\fR, if a var name was
   363    496   given. A successful transformation of the DOM tree to an xsltCmd removes the
   364    497   domDoc cmd and all nodeCmds of the document.
   365    498   .RS
   366    499   .PP
   367    500   The syntax of the created xsltCmd is:
   368    501   
   369    502    
................................................................................
   372    505   
   373    506   \&\fBxsltCmd\fP \fBmethod\fP \fB?arg ...?\fP
   374    507   
   375    508   .CE
   376    509   .PP
   377    510   The valid methods are:
   378    511   .TP
   379         -\&\fB\fBtransform\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-xsltmessagecmd script?\fP \fIdomDoc\fB \fI?outputVar?\fB
          512  +\&\fB\fBtransform\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-maxApplyDepth int?\fP  \fB?-xsltmessagecmd script?\fP \fIdomDoc\fB \fI?outputVar?\fB
   380    513   \&\fRApplies XSLT transformation on the document
   381    514   \&\fIdomDoc\fR. Returns a document object containing the
   382    515   result document of that transformation and stores it in the optional
   383    516   \&\fIoutputVar\fR.
   384    517   .RS
   385    518   .PP
   386    519   The optional \fI-parameters\fR option sets top level
   387    520   <xsl:param> to string values. The \fIparameterList\fR has to be a tcl
   388    521   list consisting of parameter name and value pairs.
   389    522   .PP
   390    523   If the option \fI-ignoreUndeclaredParameters\fR is given, then parameter
   391    524   names in the \fIparameterList\fR given to the \fI-parameters\fR options that
   392    525   are not declared as top-level parameters in the stylesheet are silently
   393         -ignored. Without this option, an error is raised, if the user tries to set a
          526  +ignored. Without this option, an error is raised if the user tries to set a
   394    527   top-level parameter, which is not declared in the stylesheet.
          528  +.PP
          529  +The option \fI-maxApplyDepth\fR expects a positiv integer as
          530  +argument. By default, the xslt engine allows xslt templates to nest up
          531  +to 3000 levels (and raises error if they nest deeper). This limit can
          532  +be set by the \fI-maxApplyDepth\fR option.
   395    533   .PP
   396    534   The \fI-xsltmessagecmd\fR option sets a callback for xslt:message elements
   397    535   in the stylesheet. The actual command consists of the script, given as argument
   398    536   to the option, appended with the XML Fragment from instantiating the
   399    537   xsl:message element content as string (as if the XPath string() function would
   400    538   have been applied to the XML Fragment) and a flag, which indicates, if the
   401    539   xsl:message has an attribute "terminate" with the value "yes".
................................................................................
   406    544   .PP
   407    545   If the first argument to an xsltCmd is a domDoc or starts with a "-",
   408    546   then the command is processed in the same way as
   409    547   \&\fI<xsltCmd> transform\fR.
   410    548   .RE
   411    549   .TP
   412    550   \&\fB\fBnormalize\fP \fI?-forXPath?\fB
   413         -\&\fRPuts all Text nodes in the document
          551  +\&\fRPuts all text nodes in the document
   414    552   into a "normal" form where only structure (e.g., elements,
   415    553   comments, processing instructions and CDATA
   416         -sections) separates Text nodes, i.e., there
   417         -are neither adjacent Text nodes nor empty Text nodes. If the option
          554  +sections) separates text nodes, i.e., there
          555  +are neither adjacent text nodes nor empty text nodes. If the option
   418    556   \&\fI-forXPath\fR is given, all CDATA sections in the nodes are
   419    557   converted to text nodes, as a first step before the
   420    558   normalization.
   421    559   .TP
   422    560   \&\fB\fBnodeType\fP
   423    561   \&\fRReturns the node type of the document node. This is always
   424    562   DOCUMENT_NODE.
   425    563   .TP
   426    564   \&\fB\fBgetElementById\fP \fIid\fB
   427    565   \&\fRReturns the node having a id attribute with value
   428         -\&\fIid\fR or the emtpy string, if no node has an id attribute with that value.
          566  +\&\fIid\fR or the empty string, if no node has an id attribute with that value.
   429    567   .TP
   430    568   \&\fB\fBfirstChild\fP \fB?objVar?\fP
   431    569   \&\fRReturns the first top level node of the document.
   432    570   .TP
   433    571   \&\fB\fBlastChild\fP \fB?objVar?\fP
   434    572   \&\fRReturns the last top level node of the document.
   435    573   .TP
................................................................................
   449    587   \&\fRReturns a list of the top level nodes of the document.
   450    588   .TP
   451    589   \&\fB\fBownerDocument\fP \fB?domObjVar?\fP
   452    590   \&\fRReturns the document itself.
   453    591   .TP
   454    592   \&\fB\fBinsertBefore\fP \fInewChild\fB  \fIrefChild\fB
   455    593   \&\fRInsert \fInewChild\fR before the \fIrefChild\fR into the list of
   456         -top level nodes of the document. If \fIrefChild\fR is the empty string, insert
          594  +top level nodes of the document. If \fIrefChild\fR is the empty string, inserts
   457    595   \&\fInewChild\fR at the end of the top level nodes.
   458    596   .TP
   459    597   \&\fB\fBreplaceChild\fP \fInewChild\fB  \fIoldChild\fB
   460         -\&\fRReplace \fIoldChild\fR with \fInewChild\fR in the list of
          598  +\&\fRReplaces \fIoldChild\fR with \fInewChild\fR in the list of
   461    599   children of that node. The \fIoldChild\fR node will be part of the
   462    600   document fragment list after this operation.
   463    601   .TP
   464    602   \&\fB\fBappendFromList\fP \fIlist\fB
   465    603   \&\fRParses \fIlist\fR , creates an according DOM subtree and
   466    604   appends this subtree at the end of the current list of top level nodes of the document.
   467    605   .TP
................................................................................
   484    622   The argument \fIxpathQuery\fR has to be a valid XPath
   485    623   expression. However, there is one exception to that rule. Tcl variable
   486    624   names can appear in the XPath statement at any position where it is
   487    625   legal according to the rules of the XPath syntax to put an XPath
   488    626   variable. The value of the variable is substituted for the variable
   489    627   name. Ignoring the syntax rules of XPath the Tcl variable name may be
   490    628   any legal Tcl var name: local variables, global variables, array
   491         -entries and so on.
          629  +entries and so on.  The value will always be seen as string literal by
          630  +the xpath engine. Cast the value explicitly with the according xpath
          631  +functions (number(), boolean()) to another data type, if needed.
   492    632   .PP
   493    633   The option \fI-namespaces\fR expects a tcl list with prefix /
   494    634   namespace pairs as argument. If this option is not given, then any
   495    635   namespace prefix within the xpath expression will be first resolved
   496    636   against the list of prefix / namespace pairs set with the
   497         -selectNodesNamespaces method for the document, the node belongs to. If
          637  +selectNodesNamespaces method for the document the node belongs to. If
   498    638   this fails, then the namespace definitions in scope of the context
   499    639   node will be used to resolve the prefix. If this option is given, any
   500    640   namespace prefix within the xpath expression will be first resolved
   501    641   against that given list (and ignoring the document global prefix /
   502         -namespace list). If the list bind the same prefix to different
          642  +namespace list). If the list binds the same prefix to different
   503    643   namespaces, then the first binding will win.  If this fails, then the
   504    644   namespace definitions in scope of the context node will be used to
   505    645   resolve the prefix, as usual.
   506    646   .PP
   507    647   If the \fI-cache\fR option is used with a true value, then the
   508         -\&\fIxpathQuery\fR will be looked up in a document specific cache. If the query
   509         -is found, then the stored pre-compiled query will be used. If the
   510         -query isn't found, it will be pre-compiled and stored in the cache,
   511         -for use in further calls. Please notice, that the \fIxpathQuery\fR as given as
   512         -string is used as key for the cache. This means, that equal XPath
   513         -expressions, which differ only in white space are treated as
   514         -different cache entries. Special care is needed, if the XPath
   515         -expression includes namespace prefixes. During pre-compilation, the
   516         -prefixes will be resolved first to the prefix / namespace pairs of
   517         -the \fI-namespaces\fR option, if given, and to the namespaces
   518         -in scope of the context node at pre-compilation time. If the XPath
   519         -is found in the cache, neither the \fI-namespaces\fR option nor
   520         -the namespaces in scope of the context node will be taken in
   521         -account but the already resolved (stored) namespaces will be used
   522         -for the query.
          648  +\&\fIxpathQuery\fR will be looked up in a document specific cache. If
          649  +the query is found, then the stored pre-compiled query will be used.
          650  +If the query isn't found, it will be compiled and stored in the cache,
          651  +for use in further calls. Please notice, that the \fIxpathQuery\fR as
          652  +given as string is used as key for the cache. This means that equal
          653  +XPath expressions, which differ only in white space, are treated as
          654  +different cache entries. Special care is needed if the XPath
          655  +expression includes namespace prefixes or references to tcl variables.
          656  +Both namespace prefixes and tcl variable references will be resolved
          657  +according to the XML prefix namespace mappings and tcl variable values
          658  +at expression compilation time. If the same XPath expression is used
          659  +later on in a context with other XML prefix namespace mappings or
          660  +values of the used tcl variables, make sure to first remove the
          661  +compiled expression from the cache with the help of the
          662  +\&\fBdeleteXPathCache\fP method, to force a recompilation.
          663  +Without using the \fI-cache\fR option such consideration is never
          664  +needed.
   523    665   .PP
   524    666   Examples:
   525    667   
   526    668             
   527    669   .CS
   528    670   set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
   529    671   foreach paragraph $paragraphNodes {
................................................................................
   532    674   
   533    675   set doc [dom parse {<doc xmlns="http://www.defaultnamespace.org"><child/></doc>}]
   534    676   set root [$doc documentElement]
   535    677   set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]
   536    678   .CE
   537    679   .RE
   538    680   .TP
   539         -\&\fB\fBbaseURI \fI?URI?\fB\fP
          681  +\&\fB\fBbaseURI\fP \fI?URI?\fB
   540    682   \&\fRReturns the present baseURI of the document. If the optional
   541    683   argument URI is given, sets the base URI of the document to the given URI.
   542    684   .TP
   543    685   \&\fB\fBappendFromScript\fP \fItclScript\fB
   544    686   \&\fRAppends the nodes created by the \fItclScript\fR by
   545    687   Tcl functions, which have been built using \fIdom createNodeCmd\fR, at the end
   546    688   of the current list of top level nodes of the document.
................................................................................
   556    698   \&\fRIf called without the optional argument, all cached XPath
   557    699   expressions of the document are freed. If called with the optional
   558    700   argument \fIxpathQuery\fR, this single XPath query will be removed
   559    701   from the cache, if it is there. The method always returns an
   560    702   empty string.
   561    703   .PP
   562    704   Otherwise, if an unknown method name is given, the command with the
   563         -same name as the given metho within the namespace \fB::dom::domDoc\fR is
          705  +same name as the given method within the namespace \fB::dom::domDoc\fR is
   564    706   tried to be executed. This allows quick method additions on Tcl level.
   565    707   .PP
   566    708   Newly created nodes are appended to a hidden fragment list. If they
   567         -are not moved into the tree they are automaticaly deleted, when the whole
          709  +are not moved into the tree they are automatically deleted as soon as the whole
   568    710   document gets deleted.
   569    711   .SH "SEE ALSO"
   570    712   dom, domNode
   571    713   .SH KEYWORDS
   572    714   DOM node creation, document element

Changes to doc/domDoc.xml.

     9      9     Copyright (c) 2002-2005 Rolf Ade (rolf@pointsman.de)
    10     10   
    11     11     See the file "LICENSE" for information on usage and redistribution
    12     12     of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    13     13     
    14     14     -->
    15     15     <synopsis>
    16         -    <syntax><cmd>domDocObjCmd</cmd> <m>method</m> ?<m>arg arg ...</m>?</syntax>
           16  +    <syntax>domDocObjCmd <m>method</m> ?<m>arg arg ...</m>?</syntax>
           17  +    <syntax>domDoc <m>docToken</m> <m>method</m> ?<m>arg arg ...</m>?</syntax>
    17     18     </synopsis>
    18     19   
    19     20     <section>
    20     21       <title>DESCRIPTION </title>
    21     22   
    22     23       <p>This command manipulates one particular instance of a document
    23     24   object. <m>method</m> indicates a specific method of the document class. These
................................................................................
    49     50         </commanddef>
    50     51   
    51     52           <commanddef>
    52     53             <command><method>createElement</method> <m>tagName</m> ?<m>objVar</m>?</command>
    53     54             <desc>Creates (allocates) a new element node with node name
    54     55   <m>tagName</m>, append it to the hidden fragment list in the document
    55     56   object and returns the node object.  If <m>objVar</m> is given the new
    56         -node object store in this variable.</desc>
           57  +node object is stored in this variable.</desc>
    57     58           </commanddef>
    58     59   
    59     60           <commanddef>
    60     61             <command><method>createElementNS</method> <m>url</m> <m>tagName</m> ?<m>objVar</m>?</command>
    61     62             <desc>Creates (allocates) a new element node within a namespace
    62     63   having <m>uri</m> as the URI and node name <m>tagName</m>, which
    63     64   could include the namespace prefix, append it to the hidden fragment list in
    64     65   the document object and returns the node object.  If <m>objVar</m> is
    65         -given the new node object store in this variable.</desc>
           66  +given the new node object is stored in this variable.</desc>
    66     67           </commanddef>
    67     68   
    68     69           <commanddef>
    69     70             <command><method>createTextNode</method> <m>text</m> ?<m>objVar</m>?</command>
    70     71             <desc>Creates (allocates) a new text node with node value
    71     72   <m>text</m>, appends it to the hidden fragment list in the document
    72     73   object and returns the node object.  If <m>objVar</m> is given, the new
................................................................................
   106    107           <commanddef>
   107    108             <command><method>getDefaultOutputMethod</method></command>
   108    109             <desc>Returns the default output method of the document. This is
   109    110   usually a result of a XSLT transformation.</desc>
   110    111           </commanddef>
   111    112   
   112    113         <commanddef>
   113         -        <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>
   114         -        <desc>Returns the DOM tree as an (optional indented) XML
   115         -string or sends the output directly to the given channelId. If the
   116         -option <m>-escapeNonASCII</m> is given, every non 7 bit ASCII
   117         -character in attribute values or element PCDATA content will be
   118         -escaped as character reference in decimal representation. The flag
   119         -<m>-doctypeDeclaration</m> determines, whether there will be a DOCTYPE
   120         -declaration emitted before the first node of the document. The default
   121         -is, to do not. The DOCTYPE name will always be the element name of the
   122         -document element. An external entity declaration of the external
   123         -subset is only emitted, if the document has a system identifier. If
   124         -the option <m>-escapeAllQuot</m> is given, quotation marks will be
   125         -escaped with &amp;quot; even in text content of elements.</desc>
          114  +        <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>
          115  +        <desc><p>Returns the DOM tree as an (optional indented) XML
          116  +        string or sends the output directly to the given
          117  +        channelId.</p>
          118  +
          119  +        <p>If the option <m>-escapeNonASCII</m> is given,
          120  +        every non 7 bit ASCII character in attribute values or element
          121  +        PCDATA content will be escaped as character reference in
          122  +        decimal representation.</p>
          123  +
          124  +        <p>The flag <m>-doctypeDeclaration</m> determines whether
          125  +        there will be a DOCTYPE declaration emitted before the first
          126  +        node of the document. The default is not to emit it. The
          127  +        DOCTYPE name will always be the element name of the document
          128  +        element. An external entity declaration of the external subset
          129  +        is only emitted if the document has a system identifier.</p>
          130  +
          131  +        <p>The flag <m>-xmlDeclaration</m> determines whether there
          132  +        will be an XML Declaration and a newline emitted before
          133  +        anything else. The default is not to emit one. If this flag is
          134  +        given with a true argument then</p>
          135  +
          136  +        <p><m>-encString</m> sets the encoding value in the XML
          137  +        Declaration. Otherwise this option is ignored. Please note
          138  +        that this option just enhances the string representation of the
          139  +        generated XML Declaration with an encoding information string,
          140  +        nothing more. It's up to the user to handle encoding in case
          141  +        of writing to a channel or reparsing.</p>
          142  +            
          143  +        <p>If the option <m>-escapeAllQuot</m> is given,
          144  +        quotation marks will be escaped with &amp;quot; even in text
          145  +        content of elements.</p>
          146  +
          147  +        <p>If the option <m>-indentAttrs</m> is
          148  +        given, then attributes will each be separated with newlines
          149  +        and indented to the same level as the parent node plus the
          150  +        value given as argument to <m>-indentAttrs</m> (0..8).</p>
          151  +
          152  +        <p>If the option <m>-nogtescape</m> is given then the
          153  +        character '>' won't get escaped in attribute values and text
          154  +        content of elements. The default is to escape this
          155  +        character.</p>
          156  +
          157  +        <p>If the option <m>-noEmptyElementTag</m> is given then no
          158  +        empty tag syntax will be used. Instead, if an element has
          159  +        empty content it will be serialized with an element start tag
          160  +        and an immediately following element end tag.</p></desc>
   126    161   
   127    162         </commanddef>
   128    163   
   129    164         <commanddef>
   130    165           <command><method>asHTML</method> <option>?-channel
   131    166   channelId?</option> <option>?-escapeNonASCII?</option> <option>?-htmlEntities?</option> <option>?-doctypeDeclaration &lt;boolean&gt;?</option></command> 
   132         -        <desc>Returns the DOM tree serialized acording to HTML rules (HTML
   133         -elements are recognized regardless of case, without end tags for emtpy HTML
   134         -elements etc.), as string or sends the output directly to the given
   135         -channelId. If the option <m>-escapeNonASCII</m> is given, every non 7 bit ASCII
   136         -character in attribute values or element PCDATA content will be escaped as
   137         -character reference in decimal representation. If the option
   138         -<m>-htmlEntities</m> is given, a character is outputed using a HTML 4.01
   139         -character entity reference, if one is defined for it. The flag
   140         -<m>-doctypeDeclaration</m> determines, whether there will be a DOCTYPE
   141         -declaration emitted before the first node of the document. The default is, to
   142         -do not. The DOCTYPE name will always be the element name of the document
   143         -element without case normalization. An external entity declaration of the
   144         -external subset is only emitted, if the document has a system identifier. The
   145         -doctype declaration will be written from the avaliable informations, without
   146         -check, if this is a known (w3c) HTML version information or if the document
   147         -confirms to the given HTML version.</desc>
          167  +        <desc>Returns the DOM tree serialized according to HTML rules
          168  +        (HTML elements are recognized regardless of case, without end
          169  +        tags for empty HTML elements etc.) as string or sends the
          170  +        output directly to the given channelId. If the option
          171  +        <m>-escapeNonASCII</m> is given, every non 7 bit ASCII
          172  +        character in attribute values or element PCDATA content will
          173  +        be escaped as character reference in decimal representation.
          174  +        If the option <m>-htmlEntities</m> is given, a character is
          175  +        written using its HTML 4.01 character entity reference, if it
          176  +        has one. If the flag <m>-doctypeDeclaration</m> is given there
          177  +        will be a DOCTYPE declaration emitted before the first node of
          178  +        the document. The default is, to do not. The DOCTYPE name will
          179  +        always be the element name of the document element without
          180  +        case normalization. An external entity declaration of the
          181  +        external subset is only emitted, if the document has a system
          182  +        identifier. The doctype declaration will be written from the
          183  +        available information, without check, if this is a known
          184  +        (w3c) HTML version information or if the document confirms to
          185  +        the given HTML version.</desc>
   148    186         </commanddef>
   149    187   
   150    188         <commanddef>
   151    189           <command><method>asText</method></command>
   152         -          <desc>The asText method outputs the result tree by outputting
   153         -the string-value of every text node in the result tree in document
   154         -order without any escaping. In effect, this is what the xslt output method
   155         -"text" (XSLT 1.0 recommendation, section 16.3) does.</desc>
   156         -      </commanddef>
   157         -
          190  +          <desc>The asText method returns the tree by serializing the
          191  +          string-value of every text node in document order without
          192  +          any escaping. In effect, this is what the xslt output method
          193  +          "text" (XSLT 1.0 recommendation, section 16.3) does.</desc>
          194  +      </commanddef>
          195  +
          196  +      <commanddef>
          197  +        <command><method>asJSON</method> <option>?-indent none/0..8?</option> <option>?-channel channelId?</option></command>
          198  +          <desc><p>The asJSON method serializes the tree into a valid
          199  +          JSON data string. In general, this may be a lossy
          200  +          serialization. For this serialization all comment, character
          201  +          data sections and processing instruction nodes, all
          202  +          attributes and all XML namespaces are ignored. Only element
          203  +          and text nodes may be reflected in the generated JSON
          204  +          serialization. Appropriate JSON data type information of a
          205  +          node will be respected.</p>
          206  +
          207  +          <p>If an element node has the JSON type OBJECT, then every
          208  +          element node child of this element will be serialized as
          209  +          member of that object, with the node name of the child as
          210  +          the member name and the relevant children of that child as
          211  +          the value. Every other child nodes will be ignored.</p>
          212  +
          213  +          <p>If an element node has the JSON type ARRAY, then the text
          214  +          and element node children of that element node are serialized
          215  +          as the consecutive values of the array. Element node children
          216  +          of an ARRAY element will be container nodes for nested ARRAY
          217  +          or OBJECT values.</p>
          218  +
          219  +          <p>Text nodes with the JSON types TRUE, FALSE or NULL will
          220  +          be serialized to the corresponding JSON token without
          221  +          looking at the value of the text node. A text node without
          222  +          JSON type will always be serialized as a JSON string token.
          223  +          A text node with JSON type NUMBER will be serialized as JSON
          224  +          number token if the text node value is in fact a valid JSON
          225  +          number and as a JSON string if not.</p>
          226  +
          227  +          <p>If an element node doesn't has a JSON type then the
          228  +          serialization of its children is determined by the following
          229  +          rules:</p>
          230  +
          231  +          <p>Only text and element node child are relevant. If the
          232  +          element node to serialize is the member of a JSON object and
          233  +          there is no relevant child node the value of that member
          234  +          will be an empty JSON string. If the only relevant child
          235  +          node of this element node is a text node then the JSON
          236  +          value of that text node will be the value of the object
          237  +          member. If the element has more than one relevant child
          238  +          nodes and the first one is a text node then the relevant
          239  +          children will be serialized as JSON array. If the only
          240  +          relevant child node is an element node or the first relevant
          241  +          child is an element node and the node name of that only or
          242  +          first relevant child isn't equal to the array container node
          243  +          name all element node children will be serialized as the
          244  +          members of a JSON object (while ignoring any intermixed text
          245  +          nodes). If the only or first relevant child is an element
          246  +          node and the node name of this child is equal to the array
          247  +          container element name then all relevant children will be
          248  +          serialized as the values of a JSON array.</p>
          249  +
          250  +          <p>If the element to serialize is a value of a JSON array
          251  +          and the node name of this element isn't equal to the array
          252  +          container node name that element will be seen as a container
          253  +          node for a JSON object and all element node children will be
          254  +          serialized as the members of that array while ignoring any
          255  +          text node children. If the element to serialize is a value of
          256  +          a JSON array and the node name of this element is equal to
          257  +          the array container node name, all relevant children will be
          258  +          serialized as JSON array.</p>
          259  +
          260  +          <p>If the <m>-channel</m> option is given the serialization
          261  +          isn't returned as string but send directly to the channel,
          262  +          given as argument to the option.</p>
          263  +
          264  +          <p>If the <m>-indent</m> option is given and the argument
          265  +          given to this option isn't "none" then the returned JSON
          266  +          string is "pretty-printed". The numeric argument to this
          267  +          option defines the number of spaces for any indentation
          268  +          level. The default is to not emit any additional
          269  +          white space.</p></desc>
          270  +      </commanddef>
          271  +      
   158    272         <commanddef>
   159    273           <command><method>publicId</method> <m>?publicId?</m></command>
   160    274           <desc>Returns the public identifier of the doctype declaration of the
   161    275   document, if there is one, otherwise the empty string. If there is a value
   162    276   given to the method, the public identifier of the document is set to this
   163    277   value.</desc>
   164    278         </commanddef>
................................................................................
   168    282           <desc>Returns the system identifier of the doctype declaration of the
   169    283   document, if there is one, otherwise the empty string. If there is a value
   170    284   given to the method, the system identifier of the document is set to this
   171    285   value.</desc>
   172    286         </commanddef>
   173    287   
   174    288         <commanddef>
   175         -        <command><method>internalSubset <m>?internalSubset?</m></method></command>
          289  +        <command><method>internalSubset</method> <m>?internalSubset?</m></command>
   176    290           <desc>Returns the internal subset of the doctype declaration of the
   177    291   document, if there is one, otherwise the empty string. If there is a value
   178    292   given to the method, the internal subset of the document is set to this
   179         -value. Note, that none of the parsing methods preserve the internal subset
          293  +value. Note that none of the parsing methods preserve the internal subset
   180    294   of a document; a freshly parsed document will always have an empty internal
   181         -subset. Also note, that the method doesen't do any syntactical check on a
          295  +subset. Also note, that the method doesn't do any syntactical check on a
   182    296   given internal subset.</desc>
   183    297         </commanddef>
   184    298   
   185    299         <commanddef>
   186    300           <command><method>cdataSectionElements</method> <m>(?URI:?localname|*) ?&lt;boolean&gt;?</m></command>
   187         -        <desc>This method allows to control, for which element nodes
   188         -the text node childs will be serialized as CDATA sections (this affects only
          301  +        <desc>This method allows one to control for which element nodes
          302  +the text node children will be serialized as CDATA sections (this affects only
   189    303   serialization with the asXML method, no text node is altered in any
   190    304   way by this method). IF the method is called with an element name as
   191    305   first argument and a boolean with value true as second argument, every
   192    306   text node child of every element node in the document with the same
   193    307   name as the first argument will be serialized as CDATA section. If the
   194    308   second argument is a boolean with value false, all text nodes of all
   195    309   elements with the same name as the first argument will be serialized
   196         -as usual. Namespaced element names have to given in the form
          310  +as usual. Namespaced element names have to be given in the form
   197    311   namespace_URI:localname, not in the otherwise usual prefix:localname
   198    312   form. With two arguments called, the method returns the used boolean
   199    313   value. If the method is called with only an element name, it will
   200         -return a boolean value, indicating, if the text nodes childs of all
          314  +return a boolean value, indicating that the text node children of all
   201    315   elements with that name in the document will be serialized as CDATA
   202    316   section elements (return value 1) or not (return value 0). If the
   203    317   method is called with only one argument and that argument is an
   204    318   asterisk ('*'), then the method returns an unordered list of all
   205         -element names of the document, for which the text node childs will be
          319  +element names of the document, for which the text node children will be
   206    320   serialized as CDATA section nodes.</desc>
   207    321         </commanddef>
   208    322   
   209    323         <commanddef>
   210    324           <command><method>selectNodesNamespaces</method> <option>?prefixUriList?</option></command>
   211         -        <desc>This method allows to control a document global prefix
   212         -to namespace URI mapping, which will be used for selectNodes method
   213         -calls (on document as well as on all nodes, which belongs to the
   214         -document), if it is not overwritten by using the -namespaces option of
   215         -the selectNodes method. Any namespace prefix within an xpath
   216         -expression will be first resolved against this list. If the list bind
   217         -the same prefix to different namespaces, then the first binding will
   218         -win. If a prefix could not resolved against the document global prefix
   219         -/ namespaces list, then the namespace definitions in scope of the
   220         -context node will be used to resolve the prefix, as usual. If the
   221         -optional argument <m>prefixUriList</m> is given, then the global prefix /
   222         -namespace list is set to this list and returns it. Without
   223         -the optional argument the method returns the current list. The
   224         -default is the empty list.</desc>
          325  +        <desc>This method allows one to control a document global prefix
          326  +        to namespace URI mapping, which will be used for selectNodes
          327  +        method calls (on document as well as on all nodes, which
          328  +        belongs to the document) if it is not overwritten by using
          329  +        the -namespaces option of the selectNodes method. Any
          330  +        namespace prefix within an xpath expression will be first
          331  +        resolved against this list. If the list binds the same prefix
          332  +        to different namespaces, then the first binding will win. If a
          333  +        prefix could not resolved against the document global prefix /
          334  +        namespaces list, then the namespace definitions in scope of
          335  +        the context node will be used to resolve the prefix, as usual.
          336  +        If the optional argument <m>prefixUriList</m> is given, then
          337  +        the global prefix / namespace list is set to this list and
          338  +        returns it. Without the optional argument the method returns
          339  +        the current list. The default is the empty list.</desc>
   225    340         </commanddef>
   226    341   
   227    342         <commanddef>
   228    343           <command><method>xslt</method> <option>?-parameters
   229    344   parameterList?</option> <option>?-ignoreUndeclaredParameters?</option>
          345  +<option>?-maxApplyDepth int?</option>
   230    346   <option>?-xsltmessagecmd script?</option> <m>stylesheet</m> <m>?outputVar?</m></command>
   231    347           <desc>Applies an XSLT transformation on the whole document of the node
   232    348   object using the XSLT <m>stylesheet</m> (given as domDoc). Returns a document
   233    349   object containing the result document of the transformation and stores that
   234    350   document object in the optional <m>outputVar</m>, if that was given.
   235    351   
   236    352   <p>The optional <m>-parameters</m> option sets top level
   237    353   &lt;xsl:param&gt; to string values. The <m>parameterList</m> has to be a tcl
   238    354   list consisting of parameter name and value pairs.</p>
   239    355   
   240    356   <p>If the option <m>-ignoreUndeclaredParameters</m> is given, then parameter
   241    357   names in the <m>parameterList</m> given to the <m>-parameters</m> options that
   242    358   are not declared as top-level parameters in the stylesheet are silently
   243         -ignored. Without this option, an error is raised, if the user tries to set a
   244         -top-level parameter, which is not declared in the stylesheet.</p>
          359  +ignored. Without this option, an error is raised if the user tries to set a
          360  +top-level parameter that is not declared in the stylesheet.</p>
          361  +
          362  +<p>The option <m>-maxApplyDepth</m> expects a positiv integer as
          363  +argument. By default, the xslt engine allows xslt templates to nest up
          364  +to 3000 levels (and raises error if they nest deeper). This limit can
          365  +be set by the <m>-maxApplyDepth</m> option.</p>
   245    366   
   246    367   <p>The <m>-xsltmessagecmd</m> option sets a callback for xslt:message elements
   247    368   in the stylesheet. The actual command consists of the script, given as argument
   248    369   to the option, appended with the XML Fragment from instantiating the
   249    370   xsl:message element content as string (as if the XPath string() function would
   250    371   have been applied to the XML Fragment) and a flag, which indicates, if the
   251         -xsl:message has an attribute "terminate" with the value "yes".</p>
          372  +xsl:message has an attribute "terminate" with the value "yes". If the
          373  +called script returns anything else then TCL_OK then the xslt
          374  +transformation will be aborted, returning error. If the called script
          375  +returns -code break, the error message is empty, otherwise the result
          376  +code is reported. In case of terminated transformation, the outputVar,
          377  +if given, is set to the empty string.</p>
   252    378   </desc>
   253    379         </commanddef>
   254    380   
   255    381         <commanddef>
   256    382           <command><method>toXSLTcmd</method> ?<m>objVar</m>?</command>
   257    383        
   258    384           <desc>If the DOM tree represents a valid XSLT stylesheet, this method
   259    385   transforms the DOM tree into an xslt command, otherwise it returns error. The
   260         -created xsltCmd is returnd and stored in the <m>objVar</m>, if a var name was
          386  +created xsltCmd is returned and stored in the <m>objVar</m>, if a var name was
   261    387   given. A successful transformation of the DOM tree to an xsltCmd removes the
   262    388   domDoc cmd and all nodeCmds of the document. 
   263    389   
   264    390   <p>The syntax of the created xsltCmd is:</p>
   265    391    
   266    392   <syntax>
   267    393   <cmd>xsltCmd</cmd> <option>method</option> <option>?arg ...?</option>
................................................................................
   269    395   
   270    396   <p>The valid methods are:</p>
   271    397   
   272    398   <commandlist>
   273    399     <commanddef>
   274    400       <command><method>transform</method> <option>?-parameters
   275    401   parameterList?</option> <option>?-ignoreUndeclaredParameters?</option>
          402  +<option>?-maxApplyDepth int?</option> 
   276    403   <option>?-xsltmessagecmd script?</option> <m>domDoc</m> <m>?outputVar?</m></command>          
   277    404   
   278    405           <desc>Applies XSLT transformation on the document
   279    406   <m>domDoc</m>. Returns a document object containing the
   280    407   result document of that transformation and stores it in the optional
   281    408   <m>outputVar</m>. 
   282    409   
................................................................................
   283    410   <p>The optional <m>-parameters</m> option sets top level
   284    411   &lt;xsl:param&gt; to string values. The <m>parameterList</m> has to be a tcl
   285    412   list consisting of parameter name and value pairs.</p>
   286    413   
   287    414   <p>If the option <m>-ignoreUndeclaredParameters</m> is given, then parameter
   288    415   names in the <m>parameterList</m> given to the <m>-parameters</m> options that
   289    416   are not declared as top-level parameters in the stylesheet are silently
   290         -ignored. Without this option, an error is raised, if the user tries to set a
          417  +ignored. Without this option, an error is raised if the user tries to set a
   291    418   top-level parameter, which is not declared in the stylesheet.</p>
          419  +
          420  +<p>The option <m>-maxApplyDepth</m> expects a positiv integer as
          421  +argument. By default, the xslt engine allows xslt templates to nest up
          422  +to 3000 levels (and raises error if they nest deeper). This limit can
          423  +be set by the <m>-maxApplyDepth</m> option.</p>
   292    424   
   293    425   <p>The <m>-xsltmessagecmd</m> option sets a callback for xslt:message elements
   294    426   in the stylesheet. The actual command consists of the script, given as argument
   295    427   to the option, appended with the XML Fragment from instantiating the
   296    428   xsl:message element content as string (as if the XPath string() function would
   297    429   have been applied to the XML Fragment) and a flag, which indicates, if the
   298    430   xsl:message has an attribute "terminate" with the value "yes".</p>
................................................................................
   309    441   then the command is processed in the same way as 
   310    442   <m>&lt;xsltCmd&gt; transform</m>.</p>
   311    443    </desc>
   312    444         </commanddef>
   313    445   
   314    446         <commanddef>
   315    447           <command><method>normalize</method> <m>?-forXPath?</m></command>
   316         -        <desc>Puts all Text nodes in the document
          448  +        <desc>Puts all text nodes in the document
   317    449   into a "normal" form where only structure (e.g., elements,
   318    450   comments, processing instructions and CDATA
   319         -sections) separates Text nodes, i.e., there
   320         -are neither adjacent Text nodes nor empty Text nodes. If the option
          451  +sections) separates text nodes, i.e., there
          452  +are neither adjacent text nodes nor empty text nodes. If the option
   321    453   <m>-forXPath</m> is given, all CDATA sections in the nodes are
   322    454   converted to text nodes, as a first step before the
   323    455   normalization. </desc>
   324    456         </commanddef>
   325    457   
   326    458         <commanddef>
   327    459           <command><method>nodeType</method></command>
................................................................................
   328    460           <desc>Returns the node type of the document node. This is always
   329    461   DOCUMENT_NODE.</desc>
   330    462         </commanddef>
   331    463   
   332    464         <commanddef>
   333    465           <command><method>getElementById</method> <m>id</m></command>
   334    466           <desc>Returns the node having a id attribute with value
   335         -<m>id</m> or the emtpy string, if no node has an id attribute with that value.</desc>
          467  +<m>id</m> or the empty string, if no node has an id attribute with that value.</desc>
   336    468         </commanddef>
   337    469   
   338    470         <commanddef>
   339    471           <command><method>firstChild</method> <variable>?objVar?</variable></command>
   340    472           <desc>Returns the first top level node of the document.</desc>
   341    473         </commanddef>
   342    474   
................................................................................
   372    504           <command><method>ownerDocument</method> <variable>?domObjVar?</variable></command>
   373    505           <desc>Returns the document itself.</desc>
   374    506         </commanddef>
   375    507   
   376    508         <commanddef>
   377    509           <command><method>insertBefore</method> <m>newChild</m>  <m>refChild</m></command>
   378    510           <desc>Insert <m>newChild</m> before the <m>refChild</m> into the list of
   379         -top level nodes of the document. If <m>refChild</m> is the empty string, insert
          511  +top level nodes of the document. If <m>refChild</m> is the empty string, inserts
   380    512   <m>newChild</m> at the end of the top level nodes.</desc>
   381    513         </commanddef>
   382    514   
   383    515         <commanddef>
   384    516           <command><method>replaceChild</method> <m>newChild</m>  <m>oldChild</m></command>
   385         -        <desc>Replace <m>oldChild</m> with <m>newChild</m> in the list of
          517  +        <desc>Replaces <m>oldChild</m> with <m>newChild</m> in the list of
   386    518   children of that node. The <m>oldChild</m> node will be part of the
   387    519   document fragment list after this operation.</desc>
   388    520         </commanddef>
   389    521   
   390    522         <commanddef>
   391    523           <command><method>appendFromList</method> <m>list</m></command>
   392    524           <desc>Parses <m>list</m> , creates an according DOM subtree and
................................................................................
   412    544   <p>The argument <m>xpathQuery</m> has to be a valid XPath
   413    545   expression. However, there is one exception to that rule. Tcl variable
   414    546   names can appear in the XPath statement at any position where it is
   415    547   legal according to the rules of the XPath syntax to put an XPath
   416    548   variable. The value of the variable is substituted for the variable
   417    549   name. Ignoring the syntax rules of XPath the Tcl variable name may be
   418    550   any legal Tcl var name: local variables, global variables, array
   419         -entries and so on.</p>
          551  +entries and so on.  The value will always be seen as string literal by
          552  +the xpath engine. Cast the value explicitly with the according xpath
          553  +functions (number(), boolean()) to another data type, if needed.</p>
   420    554   
   421    555   <p>The option <m>-namespaces</m> expects a tcl list with prefix /
   422    556   namespace pairs as argument. If this option is not given, then any
   423    557   namespace prefix within the xpath expression will be first resolved
   424    558   against the list of prefix / namespace pairs set with the
   425         -selectNodesNamespaces method for the document, the node belongs to. If
          559  +selectNodesNamespaces method for the document the node belongs to. If
   426    560   this fails, then the namespace definitions in scope of the context
   427    561   node will be used to resolve the prefix. If this option is given, any
   428    562   namespace prefix within the xpath expression will be first resolved
   429    563   against that given list (and ignoring the document global prefix /
   430         -namespace list). If the list bind the same prefix to different
          564  +namespace list). If the list binds the same prefix to different
   431    565   namespaces, then the first binding will win.  If this fails, then the
   432    566   namespace definitions in scope of the context node will be used to
   433    567   resolve the prefix, as usual.</p>
   434    568   
   435    569   <p>If the <m>-cache</m> option is used with a true value, then the
   436         -<m>xpathQuery</m> will be looked up in a document specific cache. If the query
   437         -is found, then the stored pre-compiled query will be used. If the
   438         -query isn't found, it will be pre-compiled and stored in the cache,
   439         -for use in further calls. Please notice, that the <m>xpathQuery</m> as given as
   440         -string is used as key for the cache. This means, that equal XPath
   441         -expressions, which differ only in white space are treated as
   442         -different cache entries. Special care is needed, if the XPath
   443         -expression includes namespace prefixes. During pre-compilation, the
   444         -prefixes will be resolved first to the prefix / namespace pairs of
   445         -the <m>-namespaces</m> option, if given, and to the namespaces
   446         -in scope of the context node at pre-compilation time. If the XPath
   447         -is found in the cache, neither the <m>-namespaces</m> option nor
   448         -the namespaces in scope of the context node will be taken in
   449         -account but the already resolved (stored) namespaces will be used
   450         -for the query.</p>
          570  +<m>xpathQuery</m> will be looked up in a document specific cache. If
          571  +the query is found, then the stored pre-compiled query will be used.
          572  +If the query isn't found, it will be compiled and stored in the cache,
          573  +for use in further calls. Please notice, that the <m>xpathQuery</m> as
          574  +given as string is used as key for the cache. This means that equal
          575  +XPath expressions, which differ only in white space, are treated as
          576  +different cache entries. Special care is needed if the XPath
          577  +expression includes namespace prefixes or references to tcl variables.
          578  +Both namespace prefixes and tcl variable references will be resolved
          579  +according to the XML prefix namespace mappings and tcl variable values
          580  +at expression compilation time. If the same XPath expression is used
          581  +later on in a context with other XML prefix namespace mappings or
          582  +values of the used tcl variables, make sure to first remove the
          583  +compiled expression from the cache with the help of the
          584  +<method>deleteXPathCache</method> method, to force a recompilation.
          585  +Without using the <m>-cache</m> option such consideration is never
          586  +needed.</p>
   451    587   
   452    588   <p>Examples:</p>
   453    589             <example>set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
   454    590   foreach paragraph $paragraphNodes {
   455    591       lappend  values [$paragraph selectNodes attribute::type]
   456    592   }
   457    593   
................................................................................
   459    595   set root [$doc documentElement]
   460    596   set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</example>
   461    597   
   462    598             </desc>
   463    599         </commanddef>
   464    600   
   465    601         <commanddef>
   466         -        <command><method>baseURI <m>?URI?</m></method></command>
          602  +        <command><method>baseURI</method> <m>?URI?</m></command>
   467    603           <desc>Returns the present baseURI of the document. If the optional 
   468    604   argument URI is given, sets the base URI of the document to the given URI.</desc>
   469    605         </commanddef>
   470    606   
   471    607         <commanddef>
   472    608           <command><method>appendFromScript</method> <m>tclScript</m></command>
   473    609           <desc>Appends the nodes created by the <m>tclScript</m> by
................................................................................
   492    628   from the cache, if it is there. The method always returns an
   493    629   empty string.</desc>
   494    630         </commanddef>
   495    631   
   496    632     </commandlist>
   497    633   
   498    634         <p>Otherwise, if an unknown method name is given, the command with the
   499         -same name as the given metho within the namespace <samp>::dom::domDoc</samp> is
          635  +same name as the given method within the namespace <samp>::dom::domDoc</samp> is
   500    636   tried to be executed. This allows quick method additions on Tcl level.</p>
   501    637   
   502    638         <p>Newly created nodes are appended to a hidden fragment list. If they
   503         -are not moved into the tree they are automaticaly deleted, when the whole
          639  +are not moved into the tree they are automatically deleted as soon as the whole
   504    640   document gets deleted.</p>
   505    641   
   506    642       </section>
   507    643   
   508    644       <seealso>
   509    645         <ref>dom</ref>
   510    646         <ref>domNode</ref>

Changes to doc/domNode.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <div class="navbar" align="center">
     7         -<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>
            7  +<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>
     8      8   </div><hr class="navsep">
     9      9   </div><div class="body">
    10         -  <h2><a name="SECTid0x80a9a60">NAME</a></h2><p class="namesection">
           10  +  <h2><a name="SECTid0xd75c60">NAME</a></h2><p class="namesection">
    11     11   <b class="names">domNode - </b><br>Manipulates an instance of a DOM node object</p>
    12     12   
    13     13   
    14     14   
    15         -  <h2><a name="SECTid0x80a7378">SYNOPSIS</a></h2><pre class="syntax"> $nodeObject <i class="m">method</i>  <i class="m">arg arg ...</i>
           15  +  <h2><a name="SECTid0xc89db0">SYNOPSIS</a></h2><pre class="syntax">$nodeObject <i class="m">method</i> <i class="m">arg arg ...</i>
           16  +</pre><pre class="syntax">domNode <i class="m">nodeToken</i> <i class="m">method</i> <i class="m">arg arg ...</i>
    16     17   </pre>
    17         -  <h2><a name="SECTid0x80967a8"> DESCRIPTION </a></h2><p>This command manipulates one particular instance of a DOM node object.
           18  +  <h2><a name="SECTid0xd6fd90"> DESCRIPTION </a></h2><p>This command manipulates one particular instance of a DOM node object.
    18     19   <i class="m">method</i> indicates a specific method of the node class. These methods
    19     20   should closely conform to the W3C recommendation "Document Object Model
    20     21   (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>)
    21     22   as well to parts of the W3C draft "XML Pointer Language (XPointer)"
    22     23   (<a href="http://www.w3.org/TR/1998/WD-xptr-19980303">http://www.w3.org/TR/1998/WD-xptr-19980303</a>).
    23     24   Please note, that the XPointer methods are deprecated. Use DOM methods
    24     25   or XPath expressions instead of them.</p><p>The selectNodes method implements the "XML Path
................................................................................
    40     41   nodes.</dd>
    41     42         
    42     43   
    43     44         
    44     45           <dt>
    45     46   <b class="method">nodeValue</b> <i class="m">?newValue?</i>
    46     47   </dt>
    47         -        <dd>Returns the value of that node object. This is the the text or
           48  +        <dd>Returns the value of that node object. This is the text or
    48     49   the data for element nodes of type TEXT_NODE, COMMENT_NODE,
    49     50   PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty. If
    50     51   the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the
    51     52   optional argument <i class="m">newValue</i> is given, the node is set to that
    52     53   value.</dd>
    53     54   
    54     55         
    55     56   
    56     57         
    57     58           <dt><b class="method">hasChildNodes</b></dt>
    58         -        <dd>Returns 1 if the has children. Otherwise 0 is returned.</dd>
           59  +        <dd>Returns 1 if the node has children. Otherwise 0 is returned.</dd>
    59     60         
    60     61   
    61     62         
    62     63           <dt>
    63     64   <b class="method">parentNode</b> <b class="variable">?objVar?</b>
    64     65   </dt>
    65     66           <dd>Returns the parent node.</dd>
................................................................................
    73     74         
    74     75           <dt><b class="method">childNodesLive</b></dt>
    75     76           <dd>Returns a "live" nodeList object of the child nodes of
    76     77   the node in the sense of the DOM recommendation. This nodeList object is
    77     78   "live" in the sense that, for instance, changes to the children of
    78     79   the node object that it was created from are immediately reflected in the nodes
    79     80   returned by the NodeList accessors; it is not a static snapshot of the content
    80         -of the node. The both accessors know by the nodeList object are "item
           81  +of the node. The two accessors known by the nodeList object are "item
    81     82   &lt;index&gt;", which returns the indexth item in the collection, and
    82     83   "length", which returns the number of nodes in the list.</dd>
    83     84         
    84     85   
    85     86         
    86     87           <dt>
    87     88   <b class="method">firstChild</b> <b class="variable">?objVar?</b>
................................................................................
    96     97           <dd>Returns the last child as a node object.</dd>
    97     98         
    98     99         
    99    100         
   100    101           <dt>
   101    102   <b class="method">nextSibling</b>  <b class="variable">?objVar?</b>
   102    103   </dt>
   103         -        <dd>Returns the next sibling relativ to the current node as a node
          104  +        <dd>Returns the next sibling relative to the current node as a node
   104    105   object.</dd>
   105    106         
   106    107   
   107    108         
   108    109           <dt>
   109    110   <b class="method">previousSibling</b> <b class="variable">?objVar?</b>
   110    111   </dt>
   111         -        <dd>Returns the next sibling relativ to the current node as a node
          112  +        <dd>Returns the next sibling relative to the current node as a node
   112    113   object.</dd>
   113    114         
   114    115   
   115    116         
   116    117           <dt>
   117    118   <b class="method">getElementsByTagName</b> <i class="m">name</i>
   118    119   </dt>
................................................................................
   129    130   <i class="m">uri</i>.</dd>
   130    131         
   131    132   
   132    133         
   133    134           <dt>
   134    135   <b class="method">getElementById</b> <i class="m">id</i>
   135    136   </dt>
   136         -        <dd>Returns the node having a id attribute with value
   137         -<i class="m">id</i> or the emtpy string, if no node has an id attribute with that value.</dd>
          137  +        <dd>Returns the node having an id attribute with value
          138  +<i class="m">id</i> or the empty string if no node has an id attribute with that value.</dd>
   138    139         
   139    140   
   140    141         
   141    142           <dt>
   142    143   <b class="method">hasAttribute</b> <i class="m">attributeName</i>
   143    144   </dt>
   144    145           <dd>Returns 1 if the object node contains an attribute with name
................................................................................
   145    146   <i class="m">attributeName</i> . Otherwise 0 is returned.</dd>
   146    147         
   147    148   
   148    149         
   149    150           <dt>
   150    151   <b class="method">getAttribute</b> <i class="m">attributeName  ?defaultValue?</i>
   151    152   </dt>
   152         -        <dd>Returns the value of the attribute <i class="m">attributeName</i>. If
          153  +        <dd>Returns the value of the attribute <i class="m">attributeName</i>. If the
   153    154   attribute is not available <i class="m">defaultValue</i> is returned.</dd>
   154    155         
   155    156   
   156    157         
   157    158           <dt>
   158    159   <b class="method">setAttribute</b> <i class="m">attributeName newValue 
   159    160   ?attributeName newValue ...?</i>
   160    161   </dt>
   161    162           <dd>Sets the value for one or more attributes. Every
   162         -<i class="m">attributeName</i> is set to the corresponding <i class="m">newValue</i>. If there
   163         -isn't an attribute for one or more of the <i class="m">attributeName</i> this will
   164         -create that attribute.</dd>
   165         -
          163  +        <i class="m">attributeName</i> is set to the corresponding
          164  +        <i class="m">newValue</i>. If there isn't an attribute for one or more
          165  +        of the <i class="m">attributeName</i>, this will create that attribute.
          166  +        It is not recommended to set attributes that look like xml
          167  +        namespace declarations.</dd>
   166    168         
   167    169   
   168    170         
   169    171           <dt>
   170    172   <b class="method">removeAttribute</b> <i class="m">attributeName</i>
   171    173   </dt>
   172    174           <dd>Removes the attribute <i class="m">attributeName</i>.</dd>
................................................................................
   208    210           <pre class="example">$node setAttributeNS "http://some.uri.com/wow" prefix:attr1 attrValue</pre>
   209    211   
   210    212   <p>If the uri is the empty string and the attribute name hasn't a prefix, this
   211    213   method has the same effect as the method <b>setAttribute</b>.</p>
   212    214   
   213    215           <pre class="example">$node setAttributeNS "" attri "some Value"</pre>
   214    216   
   215         -<p>XML namespace nodes are not in any namespace. Set them this way:</p>
   216         -
   217         -        <pre class="example">$node setAttributeNS "" xmlns:myprefix "myNamespaceURI"
   218         -$node setAttributeNS "" xmlns "newDefaultNamespace"</pre>
   219         -
   220         -<p>If your <i class="m">qualifiedName</i> has the prefix "xml" and you give the empty
   221         -string as <i class="m">uri</i>, the namespace of the attribute defaults to
   222         -"http://www.w3.org/XML/1998/namespace", as the DOM 2 recommendation
   223         -requests. With the exceptions of the special prefixes "xmlns" and "xml" you
   224         -always must provide a non emtpy <i class="m">uri</i>, if your <i class="m">qualifiedName</i> has a
   225         -prefix.</p>
   226         -        </dd>
          217  +<p>With the exceptions of the special prefixes "xmlns" and "xml" you
          218  +always must provide a non empty <i class="m">uri</i>, if your <i class="m">qualifiedName</i> has a
          219  +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>
          220  +</dd>
   227    221         
   228    222   
   229    223         
   230    224           <dt>
   231    225   <b class="method">removeAttributeNS</b> <i class="m">uri</i> <i class="m">localName</i>
   232    226   </dt>
   233    227           <dd>Removes the attribute with the local name <i class="m">localName</i> within
................................................................................
   234    228    the namespace <i class="m">uri</i>.</dd>
   235    229         
   236    230   
   237    231         
   238    232           <dt>
   239    233   <b class="method">attributes</b> <b class="option">?attributeNamePattern?</b>
   240    234   </dt>
   241         -        <dd>Returns all attributes matching the <i class="m">attributeNamePattern</i>.
   242         -If <i class="m">attributeNamePattern</i> isn't given all attributes are returned as a Tcl
   243         -list.</dd>
          235  +        <dd>Returns information about the attriubtes matching the
          236  +        <i class="m">attributeNamePattern</i>. If <i class="m">attributeNamePattern</i>
          237  +        isn't given, information about all attributes are returned.
          238  +        The return value is a Tcl list, the elements just the
          239  +        attriubute name in case of non namespaced attriubtes and three
          240  +        element sublists for namespaced attributes. n case of an
          241  +        "ordinary" namespaced attribute, the sublist elements are
          242  +        {&lt;localname&gt; &lt;prefix&gt; &lt;namespace_uri&gt;}. In the special case of
          243  +        an xml namespace declaration it is {&lt;the prefix defined&gt;
          244  +        &lt;localname&gt; ""}.
          245  +        </dd>
   244    246         
   245    247   
          248  +      
          249  +        <dt>
          250  +<b class="method">attributeNames</b> <b class="option">?attributeNamePattern?</b>
          251  +</dt>
          252  +        <dd>Returns a flat list of all attributes names (as found in
          253  +        the XML source) matching the <i class="m">attributeNamePattern</i>. If
          254  +        <i class="m">attributeNamePattern</i> isn't given, all attribute names
          255  +        are returned as a Tcl list.</dd>
          256  +      
          257  +      
   246    258         
   247    259           <dt>
   248    260   <b class="method">appendChild</b> <i class="m">newChild</i>
   249    261   </dt>
   250         -        <dd>Append <i class="m">newChild</i> to the end of the child list of the
          262  +        <dd>Appends <i class="m">newChild</i> to the end of the child list of the
   251    263   node.</dd>
   252    264         
   253    265   
   254    266         
   255    267           <dt>
   256    268   <b class="method">insertBefore</b> <i class="m">newChild</i>  <i class="m">refChild</i>
   257    269   </dt>
   258         -        <dd>Insert <i class="m">newChild</i> before the <i class="m">refChild</i> into the list of
          270  +        <dd>Inserts <i class="m">newChild</i> before the <i class="m">refChild</i> into the list of
   259    271   children of node. If <i class="m">refChild</i> is the empty string, insert
   260    272   <i class="m">newChild</i> at the end of the child nodes list of that node.</dd>
   261    273         
   262    274   
   263    275         
   264    276           <dt>
   265    277   <b class="method">replaceChild</b> <i class="m">newChild</i>  <i class="m">oldChild</i>
   266    278   </dt>
   267         -        <dd>Replace <i class="m">oldChild</i> with <i class="m">newChild</i> in the list of
          279  +        <dd>Replaces <i class="m">oldChild</i> with <i class="m">newChild</i> in the list of
   268    280   children of that node. The <i class="m">oldChild</i> node will be part of the
   269    281   document fragment list after this operation.</dd>
   270    282         
   271    283   
   272    284         
   273    285           <dt>
   274    286   <b class="method">removeChild</b> <i class="m">child</i>
   275    287   </dt>
   276         -        <dd>Removes <i class="m">child</i> from the list of children of that node
          288  +        <dd>Removes <i class="m">child</i> from the list of children of that node.
   277    289   <i class="m">child</i> will be part of the document fragment list after this
   278         -operation. It is not physically deleted.</dd>
          290  +operation.</dd>
   279    291         
   280    292   
   281    293         
   282    294           <dt><b class="method">delete</b></dt>
   283    295           <dd>Deletes the given node and its complete child tree
   284    296   and frees the complete internal memory. The affected nodes are not accessible
   285    297   through the document fragment list.</dd>
................................................................................
   400    412   <p>Returns the result of applying the XPath query
   401    413   <i class="m">xpathQuery</i> to the subtree. This can be a
   402    414   string/value, a list of strings, a list of nodes or a list
   403    415   of attribute name / value pairs. If <i class="m">typeVar</i> is given
   404    416   the result type name is stored into that variable (empty,
   405    417   bool, number, string, nodes, attrnodes or mixed).</p>
   406    418   
   407         -<p>The argument <i class="m">xpathQuery</i> has to be a valid XPath
   408         -expression. However, there is one exception to that rule. Tcl variable
   409         -names can appear in the XPath statement at any position where it is
   410         -legal according to the rules of the XPath syntax to put an XPath
   411         -variable. The value of the variable is substituted for the variable
   412         -name. Ignoring the syntax rules of XPath the Tcl variable name may be
   413         -any legal Tcl var name: local variables, global variables, array
   414         -entries and so on.</p>
          419  +<p>The argument <i class="m">xpathQuery</i> has to be a valid XPath expression.
          420  +However there are a few exceptions to that rule. Tcl variable
          421  +references (in the usual tcl syntax: $varname) may appear in the XPath
          422  +statement at any position where it is legal according to the rules of
          423  +the XPath syntax to put an XPath variable. Ignoring the syntax rules of
          424  +XPath the Tcl variable name may be any legal Tcl var name: local
          425  +variables, global variables, array entries and so on. The value will
          426  +always be seen as string literal by the xpath engine. Cast the value
          427  +explicitly with the according xpath functions (number(), boolean()) to
          428  +another data type, if needed.</p>
          429  +
          430  +<p>Similar to the way described above to inject literals in a secure
          431  +way into the XPath expression using tcl variable references there is a
          432  +syntax to inject element names from tcl variables. At every place
          433  +where the XPath syntax allows a node test there could be a tcl
          434  +variable reference (in any form), just the leading $ replaced with %.
          435  +This allows one to select nodes with 'strange' (invalid, according to the
          436  +appropriate XML production rule) node names which may be needed in
          437  +case of working with JSON data.</p>
   415    438   
   416    439   <p>The option <i class="m">-namespaces</i> expects a tcl list with prefix /
   417    440   namespace pairs as argument. If this option is not given, then any
   418    441   namespace prefix within the xpath expression will be first resolved
   419    442   against the list of prefix / namespace pairs set with the
   420    443   selectNodesNamespaces method for the document, the node belongs to. If
   421    444   this fails, then the namespace definitions in scope of the context
   422    445   node will be used to resolve the prefix. If this option is given, any
   423    446   namespace prefix within the xpath expression will be first resolved
   424    447   against that given list (and ignoring the document global prefix /
   425         -namespace list). If the list bind the same prefix to different
          448  +namespace list). If the list binds the same prefix to different
   426    449   namespaces, then the first binding will win.  If this fails, then the
   427    450   namespace definitions in scope of the context node will be used to
   428    451   resolve the prefix, as usual.</p>
   429    452   
   430    453   <p>If the <i class="m">-cache</i> option is used with a true value, then the
   431         -<i class="m">xpathQuery</i> will be looked up in a document specific cache. If the query
   432         -is found, then the stored pre-compiled query will be used. If the
   433         -query isn't found, it will be pre-compiled and stored in the cache,
   434         -for use in further calls. Please notice, that the <i class="m">xpathQuery</i> as given as
   435         -string is used as key for the cache. This means, that equal XPath
   436         -expressions, which differ only in white space are treated as
          454  +<i class="m">xpathQuery</i> will be looked up in a document specific cache. If
          455  +the query is found, then the stored pre-compiled query will be used.
          456  +If the query isn't found, it will be compiled and stored in the cache,
          457  +for use in further calls. Please note that the <i class="m">xpathQuery</i> 
          458  +given as string is used as key for the cache. This means, that equal
          459  +XPath expressions, which differ only in white space are treated as
   437    460   different cache entries. Special care is needed, if the XPath
   438         -expression includes namespace prefixes. During pre-compilation, the
   439         -prefixes will be resolved first to the prefix / namespace pairs of
   440         -the <i class="m">-namespaces</i> option, if given, and to the namespaces
   441         -in scope of the context node at pre-compilation time. If the XPath
   442         -is found in the cache, neither the <i class="m">-namespaces</i> option nor
   443         -the namespaces in scope of the context node will be taken in
   444         -account but the already resolved (stored) namespaces will be used
   445         -for the query.</p>
          461  +expression includes namespace prefixes or references to tcl variables.
          462  +Both namespace prefixes and tcl variable references will be resolved
          463  +according to the XML prefix namespace mappings and tcl variable values
          464  +at expression compilation time. If the same XPath expression is used
          465  +later on in a context with other XML prefix namespace mappings or
          466  +values of the used tcl variables, make sure to first remove the
          467  +compiled expression from the cache with the help of the
          468  +<b class="method">deleteXPathCache</b> method, to force a recompilation.
          469  +Without using the <i class="m">-cache</i> option such consideration is never
          470  +needed.</p>
   446    471   
   447    472   <p>Examples:</p>
   448    473             <pre class="example">set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
   449    474   foreach paragraph $paragraphNodes {
   450    475       lappend  values [$paragraph selectNodes attribute::type]
   451    476   }
   452    477   
................................................................................
   455    480   set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</pre>
   456    481   
   457    482             </dd>
   458    483         
   459    484   
   460    485         
   461    486           <dt><b class="method">getLine</b></dt>
   462         -        <dd>Returns the line number of that node in the orignal parsed
          487  +        <dd>Returns the line number of that node in the originally parsed
   463    488   XML.</dd>
   464    489         
   465    490         
   466    491         
   467    492           <dt><b class="method">getColumn</b></dt>
   468         -        <dd>Returns the column number of that node in the orignal parsed
          493  +        <dd>Returns the column number of that node in the originally parsed
   469    494   XML.</dd>
   470    495         
   471    496   
   472    497         
   473    498           <dt><b class="method">asList</b></dt>
   474    499           <dd>Returns the DOM substree starting form the current node as a
   475    500   nested Tcl list.</dd>
   476    501         
   477    502   
   478    503         
   479    504           <dt>
   480         -<b class="method">asXML</b> <b class="option">?-indent none/1..8?</b>
   481         -<b class="option">?-channel channelId?</b> <b class="option">?-escapeNonASCII?</b><b class="option">?-escapeAllQuot?</b>
   482         -</dt>
   483         -
   484         -        <dd>Returns the DOM substree starting from the current node
   485         -as the root node of the result as an (optional indented) XML string or
   486         -sends the output directly to the given channelId. If the option
   487         -<i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII character in
   488         -attribute values or element PCDATA content will be escaped as
   489         -character reference in decimal representation. If the option
   490         -<i class="m">-escapeAllQuot</i> is given, quotation marks will be escaped with
   491         -&amp;quot; even in text content of elements.</dd>
          505  +<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>
          506  +</dt>
          507  +        <dd>
          508  +<p>Returns the DOM substree starting from the current
          509  +        node as the root node of the result as an (optional indented)
          510  +        XML string or sends the output directly to the given
          511  +        channelId.</p>
          512  +
          513  +        <p>If the option <i class="m">-escapeNonASCII</i> is given,
          514  +        every non 7 bit ASCII character in attribute values or element
          515  +        PCDATA content will be escaped as character reference in
          516  +        decimal representation.</p>
          517  +
          518  +        <p>The flag <i class="m">-xmlDeclaration</i> determines whether there
          519  +        will be an XML Declaration and a newline emitted before
          520  +        anything else. The default is, to do not. If this flag is
          521  +        given with a true argument then</p>
          522  +
          523  +        <p>
          524  +<i class="m">-encString</i> sets the encoding value in the XML
          525  +        Declaration. Otherwise, this option is ignored. Please note,
          526  +        that this option just enhance the string representation of the
          527  +        generated XML Declaration with an encoding information string,
          528  +        nothing more. It's up to the user to handle encoding in case
          529  +        of writing to a channel or reparsing.</p>
          530  +            
          531  +        <p>If the option <i class="m">-escapeAllQuot</i> is given,
          532  +        quotation marks will be escaped with &amp;quot; even in text
          533  +        content of elements.</p>
          534  +
          535  +        <p>If the option <i class="m">-indentAttrs</i> is
          536  +        given, then attributes will each be separated with newlines
          537  +        and indented to the same level as the parent node plus the
          538  +        value given as argument to <i class="m">-indentAttrs</i> (0..8).</p>
          539  +
          540  +        <p>If the option <i class="m">-nogtescape</i> is given then the
          541  +        character '&gt;' won't get escaped in attribute values and text
          542  +        content of elements. The default is to escape this
          543  +        character.</p>
          544  +
          545  +        <p>If the option <i class="m">-noEmptyElementTag</i> is given then no
          546  +        empty tag syntax will be used. Instead, if an element has
          547  +        empty content it will be serialized with an element start tag
          548  +        and an immediately following element end tag.</p>
          549  +</dd>
          550  +
   492    551         
   493    552   
   494    553         
   495    554           <dt>
   496    555   <b class="method">asHTML</b> <b class="option">?-channel channelId?</b>
   497    556   <b class="option">?-escapeNonASCII?</b>  <b class="option">?-htmlEntities?</b>
   498    557   </dt>
   499    558           <dd>Returns the DOM substree starting from the current node as the
   500         -root node of the result serialized acording to HTML rules (HTML elements are
   501         -recognized regardless of case, without end tags for emtpy HTML elements etc.),
          559  +root node of the result serialized according to HTML rules (HTML elements are
          560  +recognized regardless of case, without end tags for empty HTML elements etc.),
   502    561   as string or sends the output directly to the given channelId. If the option
   503    562   <i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII character in attribute
   504    563   values or element PCDATA content will be escaped as character reference in
   505    564   decimal representation. If the option <i class="m">-htmlEntities</i> is given, a
   506         -character is outputed using a HTML 4.01 character entity reference, if one is
          565  +character is written using its HTML 4.01 character entity reference, if one is
   507    566   defined for it.</dd>
   508    567         
   509    568   
   510    569         
   511    570           <dt><b class="method">asText</b></dt>
   512    571             <dd>For ELEMENT_NODEs, the asText method outputs 
   513    572   the string-value of every text node descendant of node in document
   514         -order without any escaping. For every other node type, this method outputs the
   515         -the XPath string value of that node.</dd>
          573  +order without any escaping. For every other node type, this method outputs the XPath string value of that node.</dd>
   516    574         
   517    575   
   518    576         
   519    577           <dt>
   520    578   <b class="method">appendFromList</b> <i class="m">list</i>
   521    579   </dt>
   522    580           <dd>Parses <i class="m">list</i> , creates an according DOM subtree and
................................................................................
   534    592   
   535    593         
   536    594           <dt>
   537    595   <b class="method">insertBeforeFromScript</b> <i class="m">tclScript</i> <i class="m">refChild</i>
   538    596   </dt>
   539    597           <dd>Inserts the nodes created in the <i class="m">tclScript</i> by
   540    598   Tcl functions, which have been built using <i class="m">dom createNodeCmd</i>, before the
   541         -<i class="m">refChild</i> into to the list of children of node. If <i class="m">refChild</i> is
          599  +<i class="m">refChild</i> into the list of children of node. If <i class="m">refChild</i> is
   542    600   the empty string, the new nodes will be appended.</dd>
   543    601         
   544    602   
   545    603         
   546    604           <dt>
   547    605   <b class="method">appendXML</b> <i class="m">XMLstring</i>
   548    606   </dt>
................................................................................
   551    609         
   552    610   
   553    611         
   554    612           <dt>
   555    613   <b class="method">simpleTranslate</b> <i class="m">outputVar</i>
   556    614   <i class="m">specifications</i>
   557    615   </dt>
   558         -        <dd>Translate the subtree starting at the object node according to
          616  +        <dd>Translates the subtree starting at the object node according to
   559    617   the specifications in <i class="m">specifications</i> and outputs the result in the
   560    618   variable <i class="m">outputVar</i> . The translation is very similar to Cost Simple
   561    619   mode.</dd>
   562    620         
   563    621   
   564    622         
   565         -        <dt><b class="method">toXPath</b></dt>
          623  +        <dt>
          624  +<b class="method">toXPath</b> <i class="m">?-legacy?</i>
          625  +</dt>
   566    626           <dd>Returns an XPath, which exactly addresses the given
   567    627   node in its document. This XPath is only valid as there are no changes to DOM
   568         -tree made later one.</dd>
          628  +tree made later one. With the -legacy option, other XPath expressions
          629  +are returned, which doesn't work in all cases.</dd>
   569    630         
   570    631   
   571    632         
   572    633           <dt><b class="method">getBaseURI</b></dt>
   573    634           <dd>Returns the baseURI of the node. This method is deprecated in
   574    635             favor of the <i class="m">baseURI</i> method.</dd>
   575    636         
   576    637   
   577    638         
   578         -        <dt><b class="method">baseURI <i class="m">?URI?</i>
   579         -</b></dt>
          639  +        <dt>
          640  +<b class="method">baseURI</b> <i class="m">?URI?</i>
          641  +</dt>
   580    642           <dd>Returns the present baseURI of the node. If the optional 
   581         -argument URI is given, sets the base URI of the node and of all of its child
   582         -nodes out of the same enitity as node to the given URI.</dd>
          643  +argument URI is given, it sets the base URI of the node and of all of its child
          644  +nodes out of the same entity as node to the given URI.</dd>
   583    645         
   584    646   
   585    647         
   586    648           <dt>
   587    649   <b class="method">disableOutputEscaping</b> <i class="m">?boolean?</i>
   588    650   </dt>
   589         -        <dd>This method works only for text nodes; for every other nodes it
          651  +        <dd>This method works only for text nodes; for every other node it
   590    652   returns error. Without the optional argument it returns, if disabling output
   591    653   escaping is on. The return value 0 means, the characters of the text node will
   592    654   be escaped, to generate valid XML, if serialized. This is the default for
   593    655   every parsed or created text node (with the exception of that text nodes in a
   594    656   result tree of an XSLT transformation, for which disabling output escaping was
   595         -requested explicitely in the stylesheet). The return value 1 means, that output
          657  +requested explicitly in the stylesheet). The return value 1 means, that output
   596    658   escaping is disabled for this text node. If such a text node is serialized
   597         -(with asXML or asHTML), it is literarily written, without escaping of the
          659  +(with asXML or asHTML), it is literally written, without escaping of the
   598    660   special XML characters. If the optional boolean value <i class="m">boolean</i> is given,
   599         -the flag is set accordingly. You should not set this flag to 1, until you
   600         -really know, what you do.</dd>
          661  +the flag is set accordingly. You should not set this flag to 1 until you
          662  +really know what you do.</dd>
   601    663         
   602    664   
   603    665         
   604    666           <dt>
   605    667   <b class="method">precedes</b> <i class="m">refnode</i>
   606    668   </dt>
   607    669           <dd>Compares the relative order of the node and <i class="m">refnode</i>. Both
   608    670   nodes must be part of the same documents and not out of the fragment list of
   609         -the document. Returns true, if node is in document order (in the sense of the
   610         -XPath 1.0 recommendation) before <i class="m">refnode</i> and false otherwise.</dd>
          671  +the document. Returns true if node is in document order (in the sense of the
          672  +XPath 1.0 recommendation) before <i class="m">refnode</i>, and false otherwise.</dd>
   611    673         
   612    674   
   613    675   
   614    676         
   615    677           <dt>
   616    678   <b class="method">normalize</b> <i class="m">?-forXPath?</i>
   617    679   </dt>
................................................................................
   625    687   normalization. </dd>
   626    688         
   627    689   
   628    690         
   629    691           <dt>
   630    692   <b class="method">xslt</b> <b class="option">?-parameters
   631    693   parameterList?</b> <b class="option">?-ignoreUndeclaredParameters?</b>
          694  +<b class="option">?-maxApplyDepth int?</b>
   632    695   <b class="option">?-xsltmessagecmd script?</b> <i class="m">stylesheet</i> <i class="m">?outputVar?</i>
   633    696   </dt>
   634    697           <dd>Applies an XSLT transformation on the document using the XSLT
   635    698   <i class="m">stylesheet</i> (given as domDoc). Returns a document object containing the
   636    699   result document of that transformation and stores it in the optional
   637    700   <i class="m">outputVar</i>. 
   638    701   
................................................................................
   639    702   <p>The optional <i class="m">-parameters</i> option sets top level
   640    703   &lt;xsl:param&gt; to string values. The <i class="m">parameterList</i> has to be a tcl
   641    704   list consisting of parameter name and value pairs.</p>
   642    705   
   643    706   <p>If the option <i class="m">-ignoreUndeclaredParameters</i> is given, then parameter
   644    707   names in the <i class="m">parameterList</i> given to the <i class="m">-parameters</i> options that
   645    708   are not declared as top-level parameters in the stylesheet are silently
   646         -ignored. Without this option, an error is raised, if the user tries to set a
   647         -top-level parameter, which is not declared in the stylesheet.</p>
          709  +ignored. Without this option, an error is raised if the user tries to set a
          710  +top-level parameter which is not declared in the stylesheet.</p>
          711  +
          712  +<p>The option <i class="m">-maxApplyDepth</i> expects a positive integer as
          713  +argument. By default, the xslt engine allows xslt templates to nest up
          714  +to 3000 levels (and raises error if they nest deeper). This limit can
          715  +be set by the <i class="m">-maxApplyDepth</i> option.</p>
   648    716   
   649    717   <p>The <i class="m">-xsltmessagecmd</i> option sets a callback for xslt:message elements
   650    718   in the stylesheet. The actual command consists of the script, given as argument
   651    719   to the option, appended with the XML Fragment from instantiating the
   652    720   xsl:message element content as string (as if the XPath string() function would
   653         -have been applied to the XML Fragment) and a flag, which indicates, if the
   654         -xsl:message has an attribute "terminate" with the value "yes".</p>
          721  +have been applied to the XML Fragment) and a flag, which indicates whether the
          722  +xsl:message has an attribute "terminate" with the value "yes". If the
          723  +called script returns anything else then TCL_OK then the xslt
          724  +transformation will be aborted, returning error. If the called script
          725  +returns -code break the error message is empty, otherwise the result
          726  +code is reported. In case of terminated transformation the outputVar,
          727  +if given, is set to the empty string.</p>
   655    728   </dd>
   656    729         
   657    730   
   658    731         
   659    732           <dt><i class="m">@attrName</i></dt>
   660    733           <dd>Returns the value of the attribute <i class="m">attrName</i>.  Short cut
   661    734   for <i class="m">getAttribute</i>.</dd>
   662    735         
          736  +
          737  +      
          738  +        <dt>
          739  +<b class="method">jsonType</b> <i class="m">?OBJECT|ARRAY|NONE)|(STRING|NUMBER|TRUE|FALSE|NULL|NONE)?</i>
          740  +</dt>
          741  +        <dd>Only element and text nodes may have a JSON type and
          742  +        only this types of nodes support the <i class="m">jsonType</i> method;
          743  +        the other node types return error if called with this method.
          744  +        Returns the jsonType of the node. If the optional argument is
          745  +        given, the JSON type of the node is set to the given type and
          746  +        returned. Valid type arguments for element nodes are OBJECT,
          747  +        ARRAY and NONE. Valid type arguments for text nodes are
          748  +        STRING, NUMBER, TRUE, FALSE, NULL and NONE.</dd>
          749  +      
          750  +
   663    751       </dl><p>Otherwise, if an unknown method name is given, the command with the same
   664    752   name as the given method within the namespace <tt class="l">::dom::domNode</tt> is tried to
   665    753   be executed. This allows quick method additions on Tcl level.</p>
   666    754   
   667    755   
   668         -  <h2><a name="SECTid0x80d2050">SEE ALSO</a></h2><p class="seealso">dom, domDoc</p>
          756  +  <h2><a name="SECTid0xdd72b0">SEE ALSO</a></h2><p class="seealso">dom, domDoc</p>
   669    757     
   670         -  <h2><a name="SECTid0x80d2270">KEYWORDS</a></h2><p class="keywords">
          758  +  <h2><a name="SECTid0xdd7640">KEYWORDS</a></h2><p class="keywords">
   671    759   <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>
   672    760   </p>
   673    761     
   674    762   </div><hr class="navsep"><div class="navbar" align="center">
   675         -<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>
          763  +<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>
   676    764   </div>
   677    765   </body>
   678    766   </html>

Changes to doc/domNode.n.

   159    159   '\" END man.macros
   160    160   .TH domNode n "" Tcl ""
   161    161   .BS
   162    162   .SH NAME
   163    163   domNode \- Manipulates an instance of a DOM node object
   164    164   .SH SYNOPSIS
   165    165   .nf
   166         - $nodeObject \fImethod\fR  \fIarg arg ...\fR
          166  +$nodeObject \fImethod\fR \fIarg arg ...\fR
          167  +.fi
          168  +.nf
          169  +domNode \fInodeToken\fR \fImethod\fR \fIarg arg ...\fR
   167    170   .fi
   168    171   .BE
   169    172   .SH " DESCRIPTION "
   170    173   .PP
   171    174   This command manipulates one particular instance of a DOM node object.
   172    175   \&\fImethod\fR indicates a specific method of the node class. These methods
   173    176   should closely conform to the W3C recommendation "Document Object Model
................................................................................
   192    195   \&\fRReturns the node name of that node object. This is the element
   193    196   (tag) name for element nodes (type ELEMENT_NODE), the processing-instruction
   194    197   target for processing-instructions, "#text" for text node,
   195    198   "#comment" for comment nodes or "#cdata" for cdata section
   196    199   nodes.
   197    200   .TP
   198    201   \&\fB\fBnodeValue\fP \fI?newValue?\fB
   199         -\&\fRReturns the value of that node object. This is the the text or
          202  +\&\fRReturns the value of that node object. This is the text or
   200    203   the data for element nodes of type TEXT_NODE, COMMENT_NODE,
   201    204   PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty. If
   202    205   the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the
   203    206   optional argument \fInewValue\fR is given, the node is set to that
   204    207   value.
   205    208   .TP
   206    209   \&\fB\fBhasChildNodes\fP
   207         -\&\fRReturns 1 if the has children. Otherwise 0 is returned.
          210  +\&\fRReturns 1 if the node has children. Otherwise 0 is returned.
   208    211   .TP
   209    212   \&\fB\fBparentNode\fP \fB?objVar?\fP
   210    213   \&\fRReturns the parent node.
   211    214   .TP
   212    215   \&\fB\fBchildNodes\fP
   213    216   \&\fRReturns a list of direct children node objects.
   214    217   .TP
   215    218   \&\fB\fBchildNodesLive\fP
   216    219   \&\fRReturns a "live" nodeList object of the child nodes of
   217    220   the node in the sense of the DOM recommendation. This nodeList object is
   218    221   "live" in the sense that, for instance, changes to the children of
   219    222   the node object that it was created from are immediately reflected in the nodes
   220    223   returned by the NodeList accessors; it is not a static snapshot of the content
   221         -of the node. The both accessors know by the nodeList object are "item
          224  +of the node. The two accessors known by the nodeList object are "item
   222    225   <index>", which returns the indexth item in the collection, and
   223    226   "length", which returns the number of nodes in the list.
   224    227   .TP
   225    228   \&\fB\fBfirstChild\fP \fB?objVar?\fP
   226    229   \&\fRReturns the first child as a node object.
   227    230   .TP
   228    231   \&\fB\fBlastChild\fP \fB?objVar?\fP
   229    232   \&\fRReturns the last child as a node object.
   230    233   .TP
   231    234   \&\fB\fBnextSibling\fP  \fB?objVar?\fP
   232         -\&\fRReturns the next sibling relativ to the current node as a node
          235  +\&\fRReturns the next sibling relative to the current node as a node
   233    236   object.
   234    237   .TP
   235    238   \&\fB\fBpreviousSibling\fP \fB?objVar?\fP
   236         -\&\fRReturns the next sibling relativ to the current node as a node
          239  +\&\fRReturns the next sibling relative to the current node as a node
   237    240   object.
   238    241   .TP
   239    242   \&\fB\fBgetElementsByTagName\fP \fIname\fB
   240    243   \&\fRReturns a list of all elements in the subtree matching (glob
   241    244   style) \fIname\fR.
   242    245   .TP
   243    246   \&\fB\fBgetElementsByTagNameNS\fP \fIuri\fB \fIlocalname\fB
   244    247   \&\fRReturns a list of all elements in the subtree
   245    248   matching (glob style) \fIlocalname\fR and having the given namespace
   246    249   \&\fIuri\fR.
   247    250   .TP
   248    251   \&\fB\fBgetElementById\fP \fIid\fB
   249         -\&\fRReturns the node having a id attribute with value
   250         -\&\fIid\fR or the emtpy string, if no node has an id attribute with that value.
          252  +\&\fRReturns the node having an id attribute with value
          253  +\&\fIid\fR or the empty string if no node has an id attribute with that value.
   251    254   .TP
   252    255   \&\fB\fBhasAttribute\fP \fIattributeName\fB
   253    256   \&\fRReturns 1 if the object node contains an attribute with name
   254    257   \&\fIattributeName\fR . Otherwise 0 is returned.
   255    258   .TP
   256    259   \&\fB\fBgetAttribute\fP \fIattributeName  ?defaultValue?\fB
   257         -\&\fRReturns the value of the attribute \fIattributeName\fR. If
          260  +\&\fRReturns the value of the attribute \fIattributeName\fR. If the
   258    261   attribute is not available \fIdefaultValue\fR is returned.
   259    262   .TP
   260    263   \&\fB\fBsetAttribute\fP \fIattributeName newValue  ?attributeName newValue ...?\fB
   261    264   \&\fRSets the value for one or more attributes. Every
   262         -\&\fIattributeName\fR is set to the corresponding \fInewValue\fR. If there
   263         -isn't an attribute for one or more of the \fIattributeName\fR this will
   264         -create that attribute.
          265  +\&\fIattributeName\fR is set to the corresponding
          266  +\&\fInewValue\fR. If there isn't an attribute for one or more
          267  +of the \fIattributeName\fR, this will create that attribute.
          268  +It is not recommended to set attributes that look like xml
          269  +namespace declarations.
   265    270   .TP
   266    271   \&\fB\fBremoveAttribute\fP \fIattributeName\fB
   267    272   \&\fRRemoves the attribute \fIattributeName\fR.
   268    273   .TP
   269    274   \&\fB\fBhasAttributeNS\fP \fIuri\fB \fIlocalName\fB
   270    275   \&\fRReturns 1 if the object node contains an attribute with the
   271    276   local name \fIlocalName\fR within the namespace \fIuri\fR.  Otherwise 0 is
................................................................................
   300    305   
   301    306   
   302    307           
   303    308   .CS
   304    309   $node setAttributeNS "" attri "some Value"
   305    310   .CE
   306    311   .PP
   307         -XML namespace nodes are not in any namespace. Set them this way:
   308         -
   309         -
   310         -        
   311         -.CS
   312         -$node setAttributeNS "" xmlns:myprefix "myNamespaceURI"
   313         -$node setAttributeNS "" xmlns "newDefaultNamespace"
   314         -.CE
   315         -.PP
   316         -If your \fIqualifiedName\fR has the prefix "xml" and you give the empty
   317         -string as \fIuri\fR, the namespace of the attribute defaults to
   318         -"http://www.w3.org/XML/1998/namespace", as the DOM 2 recommendation
   319         -requests. With the exceptions of the special prefixes "xmlns" and "xml" you
   320         -always must provide a non emtpy \fIuri\fR, if your \fIqualifiedName\fR has a
   321         -prefix.
          312  +With the exceptions of the special prefixes "xmlns" and "xml" you
          313  +always must provide a non empty \fIuri\fR, if your \fIqualifiedName\fR has a
          314  +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.
   322    315   .RE
   323    316   .TP
   324    317   \&\fB\fBremoveAttributeNS\fP \fIuri\fB \fIlocalName\fB
   325    318   \&\fRRemoves the attribute with the local name \fIlocalName\fR within
   326    319   the namespace \fIuri\fR.
   327    320   .TP
   328    321   \&\fB\fBattributes\fP \fB?attributeNamePattern?\fP
   329         -\&\fRReturns all attributes matching the \fIattributeNamePattern\fR.
   330         -If \fIattributeNamePattern\fR isn't given all attributes are returned as a Tcl
   331         -list.
          322  +\&\fRReturns information about the attriubtes matching the
          323  +\&\fIattributeNamePattern\fR. If \fIattributeNamePattern\fR
          324  +isn't given, information about all attributes are returned.
          325  +The return value is a Tcl list, the elements just the
          326  +attriubute name in case of non namespaced attriubtes and three
          327  +element sublists for namespaced attributes. n case of an
          328  +"ordinary" namespaced attribute, the sublist elements are
          329  +{<localname> <prefix> <namespace_uri>}. In the special case of
          330  +an xml namespace declaration it is {<the prefix defined>
          331  +<localname> ""}.
          332  +.TP
          333  +\&\fB\fBattributeNames\fP \fB?attributeNamePattern?\fP
          334  +\&\fRReturns a flat list of all attributes names (as found in
          335  +the XML source) matching the \fIattributeNamePattern\fR. If
          336  +\&\fIattributeNamePattern\fR isn't given, all attribute names
          337  +are returned as a Tcl list.
   332    338   .TP
   333    339   \&\fB\fBappendChild\fP \fInewChild\fB
   334         -\&\fRAppend \fInewChild\fR to the end of the child list of the
          340  +\&\fRAppends \fInewChild\fR to the end of the child list of the
   335    341   node.
   336    342   .TP
   337    343   \&\fB\fBinsertBefore\fP \fInewChild\fB  \fIrefChild\fB
   338         -\&\fRInsert \fInewChild\fR before the \fIrefChild\fR into the list of
          344  +\&\fRInserts \fInewChild\fR before the \fIrefChild\fR into the list of
   339    345   children of node. If \fIrefChild\fR is the empty string, insert
   340    346   \&\fInewChild\fR at the end of the child nodes list of that node.
   341    347   .TP
   342    348   \&\fB\fBreplaceChild\fP \fInewChild\fB  \fIoldChild\fB
   343         -\&\fRReplace \fIoldChild\fR with \fInewChild\fR in the list of
          349  +\&\fRReplaces \fIoldChild\fR with \fInewChild\fR in the list of
   344    350   children of that node. The \fIoldChild\fR node will be part of the
   345    351   document fragment list after this operation.
   346    352   .TP
   347    353   \&\fB\fBremoveChild\fP \fIchild\fB
   348         -\&\fRRemoves \fIchild\fR from the list of children of that node
          354  +\&\fRRemoves \fIchild\fR from the list of children of that node.
   349    355   \&\fIchild\fR will be part of the document fragment list after this
   350         -operation. It is not physically deleted.
          356  +operation.
   351    357   .TP
   352    358   \&\fB\fBdelete\fP
   353    359   \&\fRDeletes the given node and its complete child tree
   354    360   and frees the complete internal memory. The affected nodes are not accessible
   355    361   through the document fragment list.
   356    362   .TP
   357    363   \&\fB\fBcloneNode\fP \fB?-deep?\fP
................................................................................
   414    420   Returns the result of applying the XPath query
   415    421   \&\fIxpathQuery\fR to the subtree. This can be a
   416    422   string/value, a list of strings, a list of nodes or a list
   417    423   of attribute name / value pairs. If \fItypeVar\fR is given
   418    424   the result type name is stored into that variable (empty,
   419    425   bool, number, string, nodes, attrnodes or mixed).
   420    426   .PP
   421         -The argument \fIxpathQuery\fR has to be a valid XPath
   422         -expression. However, there is one exception to that rule. Tcl variable
   423         -names can appear in the XPath statement at any position where it is
   424         -legal according to the rules of the XPath syntax to put an XPath
   425         -variable. The value of the variable is substituted for the variable
   426         -name. Ignoring the syntax rules of XPath the Tcl variable name may be
   427         -any legal Tcl var name: local variables, global variables, array
   428         -entries and so on.
          427  +The argument \fIxpathQuery\fR has to be a valid XPath expression.
          428  +However there are a few exceptions to that rule. Tcl variable
          429  +references (in the usual tcl syntax: $varname) may appear in the XPath
          430  +statement at any position where it is legal according to the rules of
          431  +the XPath syntax to put an XPath variable. Ignoring the syntax rules of
          432  +XPath the Tcl variable name may be any legal Tcl var name: local
          433  +variables, global variables, array entries and so on. The value will
          434  +always be seen as string literal by the xpath engine. Cast the value
          435  +explicitly with the according xpath functions (number(), boolean()) to
          436  +another data type, if needed.
          437  +.PP
          438  +Similar to the way described above to inject literals in a secure
          439  +way into the XPath expression using tcl variable references there is a
          440  +syntax to inject element names from tcl variables. At every place
          441  +where the XPath syntax allows a node test there could be a tcl
          442  +variable reference (in any form), just the leading $ replaced with %.
          443  +This allows one to select nodes with 'strange' (invalid, according to the
          444  +appropriate XML production rule) node names which may be needed in
          445  +case of working with JSON data.
   429    446   .PP
   430    447   The option \fI-namespaces\fR expects a tcl list with prefix /
   431    448   namespace pairs as argument. If this option is not given, then any
   432    449   namespace prefix within the xpath expression will be first resolved
   433    450   against the list of prefix / namespace pairs set with the
   434    451   selectNodesNamespaces method for the document, the node belongs to. If
   435    452   this fails, then the namespace definitions in scope of the context
   436    453   node will be used to resolve the prefix. If this option is given, any
   437    454   namespace prefix within the xpath expression will be first resolved
   438    455   against that given list (and ignoring the document global prefix /
   439         -namespace list). If the list bind the same prefix to different
          456  +namespace list). If the list binds the same prefix to different
   440    457   namespaces, then the first binding will win.  If this fails, then the
   441    458   namespace definitions in scope of the context node will be used to
   442    459   resolve the prefix, as usual.
   443    460   .PP
   444    461   If the \fI-cache\fR option is used with a true value, then the
   445         -\&\fIxpathQuery\fR will be looked up in a document specific cache. If the query
   446         -is found, then the stored pre-compiled query will be used. If the
   447         -query isn't found, it will be pre-compiled and stored in the cache,
   448         -for use in further calls. Please notice, that the \fIxpathQuery\fR as given as
   449         -string is used as key for the cache. This means, that equal XPath
   450         -expressions, which differ only in white space are treated as
          462  +\&\fIxpathQuery\fR will be looked up in a document specific cache. If
          463  +the query is found, then the stored pre-compiled query will be used.
          464  +If the query isn't found, it will be compiled and stored in the cache,
          465  +for use in further calls. Please note that the \fIxpathQuery\fR
          466  +given as string is used as key for the cache. This means, that equal
          467  +XPath expressions, which differ only in white space are treated as
   451    468   different cache entries. Special care is needed, if the XPath
   452         -expression includes namespace prefixes. During pre-compilation, the
   453         -prefixes will be resolved first to the prefix / namespace pairs of
   454         -the \fI-namespaces\fR option, if given, and to the namespaces
   455         -in scope of the context node at pre-compilation time. If the XPath
   456         -is found in the cache, neither the \fI-namespaces\fR option nor
   457         -the namespaces in scope of the context node will be taken in
   458         -account but the already resolved (stored) namespaces will be used
   459         -for the query.
          469  +expression includes namespace prefixes or references to tcl variables.
          470  +Both namespace prefixes and tcl variable references will be resolved
          471  +according to the XML prefix namespace mappings and tcl variable values
          472  +at expression compilation time. If the same XPath expression is used
          473  +later on in a context with other XML prefix namespace mappings or
          474  +values of the used tcl variables, make sure to first remove the
          475  +compiled expression from the cache with the help of the
          476  +\&\fBdeleteXPathCache\fP method, to force a recompilation.
          477  +Without using the \fI-cache\fR option such consideration is never
          478  +needed.
   460    479   .PP
   461    480   Examples:
   462    481   
   463    482             
   464    483   .CS
   465    484   set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
   466    485   foreach paragraph $paragraphNodes {
................................................................................
   470    489   set doc [dom parse {<doc xmlns="http://www.defaultnamespace.org"><child/></doc>}]
   471    490   set root [$doc documentElement]
   472    491   set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]
   473    492   .CE
   474    493   .RE
   475    494   .TP
   476    495   \&\fB\fBgetLine\fP
   477         -\&\fRReturns the line number of that node in the orignal parsed
          496  +\&\fRReturns the line number of that node in the originally parsed
   478    497   XML.
   479    498   .TP
   480    499   \&\fB\fBgetColumn\fP
   481         -\&\fRReturns the column number of that node in the orignal parsed
          500  +\&\fRReturns the column number of that node in the originally parsed
   482    501   XML.
   483    502   .TP
   484    503   \&\fB\fBasList\fP
   485    504   \&\fRReturns the DOM substree starting form the current node as a
   486    505   nested Tcl list.
   487    506   .TP
   488         -\&\fB\fBasXML\fP \fB?-indent none/1..8?\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP\fB?-escapeAllQuot?\fP
   489         -\&\fRReturns the DOM substree starting from the current node
   490         -as the root node of the result as an (optional indented) XML string or
   491         -sends the output directly to the given channelId. If the option
   492         -\&\fI-escapeNonASCII\fR is given, every non 7 bit ASCII character in
   493         -attribute values or element PCDATA content will be escaped as
   494         -character reference in decimal representation. If the option
   495         -\&\fI-escapeAllQuot\fR is given, quotation marks will be escaped with
   496         -&quot; even in text content of elements.
          507  +\&\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
          508  +\&\fR
          509  +.RS
          510  +.PP
          511  +Returns the DOM substree starting from the current
          512  +node as the root node of the result as an (optional indented)
          513  +XML string or sends the output directly to the given
          514  +channelId.
          515  +.PP
          516  +If the option \fI-escapeNonASCII\fR is given,
          517  +every non 7 bit ASCII character in attribute values or element
          518  +PCDATA content will be escaped as character reference in
          519  +decimal representation.
          520  +.PP
          521  +The flag \fI-xmlDeclaration\fR determines whether there
          522  +will be an XML Declaration and a newline emitted before
          523  +anything else. The default is, to do not. If this flag is
          524  +given with a true argument then
          525  +.PP
          526  +\&\fI-encString\fR sets the encoding value in the XML
          527  +Declaration. Otherwise, this option is ignored. Please note,
          528  +that this option just enhance the string representation of the
          529  +generated XML Declaration with an encoding information string,
          530  +nothing more. It's up to the user to handle encoding in case
          531  +of writing to a channel or reparsing.
          532  +.PP
          533  +If the option \fI-escapeAllQuot\fR is given,
          534  +quotation marks will be escaped with &quot; even in text
          535  +content of elements.
          536  +.PP
          537  +If the option \fI-indentAttrs\fR is
          538  +given, then attributes will each be separated with newlines
          539  +and indented to the same level as the parent node plus the
          540  +value given as argument to \fI-indentAttrs\fR (0..8).
          541  +.PP
          542  +If the option \fI-nogtescape\fR is given then the
          543  +character '>' won't get escaped in attribute values and text
          544  +content of elements. The default is to escape this
          545  +character.
          546  +.PP
          547  +If the option \fI-noEmptyElementTag\fR is given then no
          548  +empty tag syntax will be used. Instead, if an element has
          549  +empty content it will be serialized with an element start tag
          550  +and an immediately following element end tag.
          551  +.RE
   497    552   .TP
   498    553   \&\fB\fBasHTML\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP  \fB?-htmlEntities?\fP
   499    554   \&\fRReturns the DOM substree starting from the current node as the
   500         -root node of the result serialized acording to HTML rules (HTML elements are
   501         -recognized regardless of case, without end tags for emtpy HTML elements etc.),
          555  +root node of the result serialized according to HTML rules (HTML elements are
          556  +recognized regardless of case, without end tags for empty HTML elements etc.),
   502    557   as string or sends the output directly to the given channelId. If the option
   503    558   \&\fI-escapeNonASCII\fR is given, every non 7 bit ASCII character in attribute
   504    559   values or element PCDATA content will be escaped as character reference in
   505    560   decimal representation. If the option \fI-htmlEntities\fR is given, a
   506         -character is outputed using a HTML 4.01 character entity reference, if one is
          561  +character is written using its HTML 4.01 character entity reference, if one is
   507    562   defined for it.
   508    563   .TP
   509    564   \&\fB\fBasText\fP
   510    565   \&\fRFor ELEMENT_NODEs, the asText method outputs
   511    566   the string-value of every text node descendant of node in document
   512         -order without any escaping. For every other node type, this method outputs the
   513         -the XPath string value of that node.
          567  +order without any escaping. For every other node type, this method outputs the XPath string value of that node.
   514    568   .TP
   515    569   \&\fB\fBappendFromList\fP \fIlist\fB
   516    570   \&\fRParses \fIlist\fR , creates an according DOM subtree and
   517    571   appends this subtree to the current node.
   518    572   .TP
   519    573   \&\fB\fBappendFromScript\fP \fItclScript\fB
   520    574   \&\fRAppends the nodes created in the \fItclScript\fR by
   521    575   Tcl functions, which have been built using \fIdom createNodeCmd\fR, to the
   522    576   given node.
   523    577   .TP
   524    578   \&\fB\fBinsertBeforeFromScript\fP \fItclScript\fB \fIrefChild\fB
   525    579   \&\fRInserts the nodes created in the \fItclScript\fR by
   526    580   Tcl functions, which have been built using \fIdom createNodeCmd\fR, before the
   527         -\&\fIrefChild\fR into to the list of children of node. If \fIrefChild\fR is
          581  +\&\fIrefChild\fR into the list of children of node. If \fIrefChild\fR is
   528    582   the empty string, the new nodes will be appended.
   529    583   .TP
   530    584   \&\fB\fBappendXML\fP \fIXMLstring\fB
   531    585   \&\fRParses \fIXMLstring\fR, creates an according DOM subtree and
   532    586   appends this subtree to the current node.
   533    587   .TP
   534    588   \&\fB\fBsimpleTranslate\fP \fIoutputVar\fB \fIspecifications\fB
   535         -\&\fRTranslate the subtree starting at the object node according to
          589  +\&\fRTranslates the subtree starting at the object node according to
   536    590   the specifications in \fIspecifications\fR and outputs the result in the
   537    591   variable \fIoutputVar\fR . The translation is very similar to Cost Simple
   538    592   mode.
   539    593   .TP
   540         -\&\fB\fBtoXPath\fP
          594  +\&\fB\fBtoXPath\fP \fI?-legacy?\fB
   541    595   \&\fRReturns an XPath, which exactly addresses the given
   542    596   node in its document. This XPath is only valid as there are no changes to DOM
   543         -tree made later one.
          597  +tree made later one. With the -legacy option, other XPath expressions
          598  +are returned, which doesn't work in all cases.
   544    599   .TP
   545    600   \&\fB\fBgetBaseURI\fP
   546    601   \&\fRReturns the baseURI of the node. This method is deprecated in
   547    602   favor of the \fIbaseURI\fR method.
   548    603   .TP
   549         -\&\fB\fBbaseURI \fI?URI?\fB\fP
          604  +\&\fB\fBbaseURI\fP \fI?URI?\fB
   550    605   \&\fRReturns the present baseURI of the node. If the optional
   551         -argument URI is given, sets the base URI of the node and of all of its child
   552         -nodes out of the same enitity as node to the given URI.
          606  +argument URI is given, it sets the base URI of the node and of all of its child
          607  +nodes out of the same entity as node to the given URI.
   553    608   .TP
   554    609   \&\fB\fBdisableOutputEscaping\fP \fI?boolean?\fB
   555         -\&\fRThis method works only for text nodes; for every other nodes it
          610  +\&\fRThis method works only for text nodes; for every other node it
   556    611   returns error. Without the optional argument it returns, if disabling output
   557    612   escaping is on. The return value 0 means, the characters of the text node will
   558    613   be escaped, to generate valid XML, if serialized. This is the default for
   559    614   every parsed or created text node (with the exception of that text nodes in a
   560    615   result tree of an XSLT transformation, for which disabling output escaping was
   561         -requested explicitely in the stylesheet). The return value 1 means, that output
          616  +requested explicitly in the stylesheet). The return value 1 means, that output
   562    617   escaping is disabled for this text node. If such a text node is serialized
   563         -(with asXML or asHTML), it is literarily written, without escaping of the
          618  +(with asXML or asHTML), it is literally written, without escaping of the
   564    619   special XML characters. If the optional boolean value \fIboolean\fR is given,
   565         -the flag is set accordingly. You should not set this flag to 1, until you
   566         -really know, what you do.
          620  +the flag is set accordingly. You should not set this flag to 1 until you
          621  +really know what you do.
   567    622   .TP
   568    623   \&\fB\fBprecedes\fP \fIrefnode\fB
   569    624   \&\fRCompares the relative order of the node and \fIrefnode\fR. Both
   570    625   nodes must be part of the same documents and not out of the fragment list of
   571         -the document. Returns true, if node is in document order (in the sense of the
   572         -XPath 1.0 recommendation) before \fIrefnode\fR and false otherwise.
          626  +the document. Returns true if node is in document order (in the sense of the
          627  +XPath 1.0 recommendation) before \fIrefnode\fR, and false otherwise.
   573    628   .TP
   574    629   \&\fB\fBnormalize\fP \fI?-forXPath?\fB
   575    630   \&\fRPuts all Text nodes in the full depth of the sub-tree underneath
   576    631   this Node into a "normal" form where only structure (e.g., elements,
   577    632   comments, processing instructions and CDATA
   578    633   sections) separates Text nodes, i.e., there
   579    634   are neither adjacent Text nodes nor empty Text nodes. If the option
   580    635   \&\fI-forXPath\fR is given, all CDATA sections in the nodes are
   581    636   converted to text nodes, as a first step before the
   582    637   normalization.
   583    638   .TP
   584         -\&\fB\fBxslt\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-xsltmessagecmd script?\fP \fIstylesheet\fB \fI?outputVar?\fB
          639  +\&\fB\fBxslt\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-maxApplyDepth int?\fP \fB?-xsltmessagecmd script?\fP \fIstylesheet\fB \fI?outputVar?\fB
   585    640   \&\fRApplies an XSLT transformation on the document using the XSLT
   586    641   \&\fIstylesheet\fR (given as domDoc). Returns a document object containing the
   587    642   result document of that transformation and stores it in the optional
   588    643   \&\fIoutputVar\fR.
   589    644   .RS
   590    645   .PP
   591    646   The optional \fI-parameters\fR option sets top level
   592    647   <xsl:param> to string values. The \fIparameterList\fR has to be a tcl
   593    648   list consisting of parameter name and value pairs.
   594    649   .PP
   595    650   If the option \fI-ignoreUndeclaredParameters\fR is given, then parameter
   596    651   names in the \fIparameterList\fR given to the \fI-parameters\fR options that
   597    652   are not declared as top-level parameters in the stylesheet are silently
   598         -ignored. Without this option, an error is raised, if the user tries to set a
   599         -top-level parameter, which is not declared in the stylesheet.
          653  +ignored. Without this option, an error is raised if the user tries to set a
          654  +top-level parameter which is not declared in the stylesheet.
          655  +.PP
          656  +The option \fI-maxApplyDepth\fR expects a positive integer as
          657  +argument. By default, the xslt engine allows xslt templates to nest up
          658  +to 3000 levels (and raises error if they nest deeper). This limit can
          659  +be set by the \fI-maxApplyDepth\fR option.
   600    660   .PP
   601    661   The \fI-xsltmessagecmd\fR option sets a callback for xslt:message elements
   602    662   in the stylesheet. The actual command consists of the script, given as argument
   603    663   to the option, appended with the XML Fragment from instantiating the
   604    664   xsl:message element content as string (as if the XPath string() function would
   605         -have been applied to the XML Fragment) and a flag, which indicates, if the
   606         -xsl:message has an attribute "terminate" with the value "yes".
          665  +have been applied to the XML Fragment) and a flag, which indicates whether the
          666  +xsl:message has an attribute "terminate" with the value "yes". If the
          667  +called script returns anything else then TCL_OK then the xslt
          668  +transformation will be aborted, returning error. If the called script
          669  +returns -code break the error message is empty, otherwise the result
          670  +code is reported. In case of terminated transformation the outputVar,
          671  +if given, is set to the empty string.
   607    672   .RE
   608    673   .TP
   609    674   \&\fB\fI@attrName\fB
   610    675   \&\fRReturns the value of the attribute \fIattrName\fR.  Short cut
   611    676   for \fIgetAttribute\fR.
          677  +.TP
          678  +\&\fB\fBjsonType\fP \fI?OBJECT|ARRAY|NONE)|(STRING|NUMBER|TRUE|FALSE|NULL|NONE)?\fB
          679  +\&\fROnly element and text nodes may have a JSON type and
          680  +only this types of nodes support the \fIjsonType\fR method;
          681  +the other node types return error if called with this method.
          682  +Returns the jsonType of the node. If the optional argument is
          683  +given, the JSON type of the node is set to the given type and
          684  +returned. Valid type arguments for element nodes are OBJECT,
          685  +ARRAY and NONE. Valid type arguments for text nodes are
          686  +STRING, NUMBER, TRUE, FALSE, NULL and NONE.
   612    687   .PP
   613    688   Otherwise, if an unknown method name is given, the command with the same
   614    689   name as the given method within the namespace \fB::dom::domNode\fR is tried to
   615    690   be executed. This allows quick method additions on Tcl level.
   616    691   .SH "SEE ALSO"
   617    692   dom, domDoc
   618    693   .SH KEYWORDS
   619    694   XML, DOM, document, node, parsing

Changes to doc/domNode.xml.

    11     11   
    12     12    See the file "LICENSE" for information on usage and redistribution
    13     13    of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    14     14   
    15     15   -->
    16     16   
    17     17     <synopsis>
    18         -    <syntax> $nodeObject <m>method</m>  <m>arg arg ...</m></syntax>
           18  +    <syntax>$nodeObject <m>method</m> <m>arg arg ...</m></syntax>
           19  +    <syntax>domNode <m>nodeToken</m> <m>method</m> <m>arg arg ...</m></syntax>
    19     20     </synopsis>
    20     21     <section>
    21     22       <title> DESCRIPTION </title>
    22     23   
    23     24       <p>This command manipulates one particular instance of a DOM node object.
    24     25   <m>method</m> indicates a specific method of the node class. These methods
    25     26   should closely conform to the W3C recommendation &quot;Document Object Model
................................................................................
    53     54   target for processing-instructions, &quot;#text&quot; for text node,
    54     55   &quot;#comment&quot; for comment nodes or &quot;#cdata&quot; for cdata section
    55     56   nodes.</desc>
    56     57         </commanddef>
    57     58   
    58     59         <commanddef>
    59     60           <command><method>nodeValue</method> <m>?newValue?</m></command>
    60         -        <desc>Returns the value of that node object. This is the the text or
           61  +        <desc>Returns the value of that node object. This is the text or
    61     62   the data for element nodes of type TEXT_NODE, COMMENT_NODE,
    62     63   PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty. If
    63     64   the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the
    64     65   optional argument <m>newValue</m> is given, the node is set to that
    65     66   value.</desc>
    66     67   
    67     68         </commanddef>
    68     69   
    69     70         <commanddef>
    70     71           <command><method>hasChildNodes</method></command>
    71         -        <desc>Returns 1 if the has children. Otherwise 0 is returned.</desc>
           72  +        <desc>Returns 1 if the node has children. Otherwise 0 is returned.</desc>
    72     73         </commanddef>
    73     74   
    74     75         <commanddef>
    75     76           <command><method>parentNode</method> <variable>?objVar?</variable></command>
    76     77           <desc>Returns the parent node.</desc>
    77     78         </commanddef>
    78     79   
................................................................................
    84     85         <commanddef>
    85     86           <command><method>childNodesLive</method></command>
    86     87           <desc>Returns a &quot;live&quot; nodeList object of the child nodes of
    87     88   the node in the sense of the DOM recommendation. This nodeList object is
    88     89   &quot;live&quot; in the sense that, for instance, changes to the children of
    89     90   the node object that it was created from are immediately reflected in the nodes
    90     91   returned by the NodeList accessors; it is not a static snapshot of the content
    91         -of the node. The both accessors know by the nodeList object are &quot;item
           92  +of the node. The two accessors known by the nodeList object are &quot;item
    92     93   &lt;index&gt;&quot;, which returns the indexth item in the collection, and
    93     94   &quot;length&quot;, which returns the number of nodes in the list.</desc>
    94     95         </commanddef>
    95     96   
    96     97         <commanddef>
    97     98           <command><method>firstChild</method> <variable>?objVar?</variable></command>
    98     99           <desc>Returns the first child as a node object.</desc>
................................................................................
   101    102         <commanddef>
   102    103           <command><method>lastChild</method> <variable>?objVar?</variable></command>
   103    104           <desc>Returns the last child as a node object.</desc>
   104    105         </commanddef>
   105    106         
   106    107         <commanddef>
   107    108           <command><method>nextSibling</method>  <variable>?objVar?</variable></command>
   108         -        <desc>Returns the next sibling relativ to the current node as a node
          109  +        <desc>Returns the next sibling relative to the current node as a node
   109    110   object.</desc>
   110    111         </commanddef>
   111    112   
   112    113         <commanddef>
   113    114           <command><method>previousSibling</method> <variable>?objVar?</variable></command>
   114         -        <desc>Returns the next sibling relativ to the current node as a node
          115  +        <desc>Returns the next sibling relative to the current node as a node
   115    116   object.</desc>
   116    117         </commanddef>
   117    118   
   118    119         <commanddef>
   119    120           <command><method>getElementsByTagName</method> <m>name</m></command>
   120    121           <desc>Returns a list of all elements in the subtree matching (glob
   121    122   style) <m>name</m>.</desc>
................................................................................
   126    127           <desc>Returns a list of all elements in the subtree
   127    128   matching (glob style) <m>localname</m> and having the given namespace
   128    129   <m>uri</m>.</desc>
   129    130         </commanddef>
   130    131   
   131    132         <commanddef>
   132    133           <command><method>getElementById</method> <m>id</m></command>
   133         -        <desc>Returns the node having a id attribute with value
   134         -<m>id</m> or the emtpy string, if no node has an id attribute with that value.</desc>
          134  +        <desc>Returns the node having an id attribute with value
          135  +<m>id</m> or the empty string if no node has an id attribute with that value.</desc>
   135    136         </commanddef>
   136    137   
   137    138         <commanddef>
   138    139           <command><method>hasAttribute</method> <m>attributeName</m></command>
   139    140           <desc>Returns 1 if the object node contains an attribute with name
   140    141   <m>attributeName</m> . Otherwise 0 is returned.</desc>
   141    142         </commanddef>
   142    143   
   143    144         <commanddef>
   144    145           <command><method>getAttribute</method> <m>attributeName  ?defaultValue?</m></command>
   145         -        <desc>Returns the value of the attribute <m>attributeName</m>. If
          146  +        <desc>Returns the value of the attribute <m>attributeName</m>. If the
   146    147   attribute is not available <m>defaultValue</m> is returned.</desc>
   147    148         </commanddef>
   148    149   
   149    150         <commanddef>
   150    151           <command><method>setAttribute</method> <m>attributeName newValue 
   151    152   ?attributeName newValue ...?</m></command>
   152    153           <desc>Sets the value for one or more attributes. Every
   153         -<m>attributeName</m> is set to the corresponding <m>newValue</m>. If there
   154         -isn't an attribute for one or more of the <m>attributeName</m> this will
   155         -create that attribute.</desc>
   156         -
          154  +        <m>attributeName</m> is set to the corresponding
          155  +        <m>newValue</m>. If there isn't an attribute for one or more
          156  +        of the <m>attributeName</m>, this will create that attribute.
          157  +        It is not recommended to set attributes that look like xml
          158  +        namespace declarations.</desc>
   157    159         </commanddef>
   158    160   
   159    161         <commanddef>
   160    162           <command><method>removeAttribute</method> <m>attributeName</m></command>
   161    163           <desc>Removes the attribute <m>attributeName</m>.</desc>
   162    164         </commanddef>
   163    165   
................................................................................
   191    193           <example>$node setAttributeNS "http://some.uri.com/wow" prefix:attr1 attrValue</example>
   192    194   
   193    195   <p>If the uri is the empty string and the attribute name hasn't a prefix, this
   194    196   method has the same effect as the method <b>setAttribute</b>.</p>
   195    197   
   196    198           <example>$node setAttributeNS "" attri "some Value"</example>
   197    199   
   198         -<p>XML namespace nodes are not in any namespace. Set them this way:</p>
   199         -
   200         -        <example>$node setAttributeNS "" xmlns:myprefix "myNamespaceURI"
   201         -$node setAttributeNS "" xmlns "newDefaultNamespace"</example>
   202         -
   203         -<p>If your <m>qualifiedName</m> has the prefix "xml" and you give the empty
   204         -string as <m>uri</m>, the namespace of the attribute defaults to
   205         -"http://www.w3.org/XML/1998/namespace", as the DOM 2 recommendation
   206         -requests. With the exceptions of the special prefixes "xmlns" and "xml" you
   207         -always must provide a non emtpy <m>uri</m>, if your <m>qualifiedName</m> has a
   208         -prefix.</p>
   209         -        </desc>
          200  +<p>With the exceptions of the special prefixes "xmlns" and "xml" you
          201  +always must provide a non empty <m>uri</m>, if your <m>qualifiedName</m> has a
          202  +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>
   210    203         </commanddef>
   211    204   
   212    205         <commanddef>
   213    206           <command><method>removeAttributeNS</method> <m>uri</m> <m>localName</m></command>
   214    207           <desc>Removes the attribute with the local name <m>localName</m> within
   215    208    the namespace <m>uri</m>.</desc>
   216    209         </commanddef>
   217    210   
   218    211         <commanddef>
   219    212           <command><method>attributes</method> <option>?attributeNamePattern?</option></command>
   220         -        <desc>Returns all attributes matching the <m>attributeNamePattern</m>.
   221         -If <m>attributeNamePattern</m> isn't given all attributes are returned as a Tcl
   222         -list.</desc>
          213  +        <desc>Returns information about the attriubtes matching the
          214  +        <m>attributeNamePattern</m>. If <m>attributeNamePattern</m>
          215  +        isn't given, information about all attributes are returned.
          216  +        The return value is a Tcl list, the elements just the
          217  +        attriubute name in case of non namespaced attriubtes and three
          218  +        element sublists for namespaced attributes. n case of an
          219  +        "ordinary" namespaced attribute, the sublist elements are
          220  +        {&lt;localname&gt; &lt;prefix&gt; &lt;namespace_uri&gt;}. In the special case of
          221  +        an xml namespace declaration it is {&lt;the prefix defined&gt;
          222  +        &lt;localname&gt; ""}.
          223  +        </desc>
   223    224         </commanddef>
   224    225   
          226  +      <commanddef>
          227  +        <command><method>attributeNames</method> <option>?attributeNamePattern?</option></command>
          228  +        <desc>Returns a flat list of all attributes names (as found in
          229  +        the XML source) matching the <m>attributeNamePattern</m>. If
          230  +        <m>attributeNamePattern</m> isn't given, all attribute names
          231  +        are returned as a Tcl list.</desc>
          232  +      </commanddef>
          233  +      
   225    234         <commanddef>
   226    235           <command><method>appendChild</method> <m>newChild</m></command>
   227         -        <desc>Append <m>newChild</m> to the end of the child list of the
          236  +        <desc>Appends <m>newChild</m> to the end of the child list of the
   228    237   node.</desc>
   229    238         </commanddef>
   230    239   
   231    240         <commanddef>
   232    241           <command><method>insertBefore</method> <m>newChild</m>  <m>refChild</m></command>
   233         -        <desc>Insert <m>newChild</m> before the <m>refChild</m> into the list of
          242  +        <desc>Inserts <m>newChild</m> before the <m>refChild</m> into the list of
   234    243   children of node. If <m>refChild</m> is the empty string, insert
   235    244   <m>newChild</m> at the end of the child nodes list of that node.</desc>
   236    245         </commanddef>
   237    246   
   238    247         <commanddef>
   239    248           <command><method>replaceChild</method> <m>newChild</m>  <m>oldChild</m></command>
   240         -        <desc>Replace <m>oldChild</m> with <m>newChild</m> in the list of
          249  +        <desc>Replaces <m>oldChild</m> with <m>newChild</m> in the list of
   241    250   children of that node. The <m>oldChild</m> node will be part of the
   242    251   document fragment list after this operation.</desc>
   243    252         </commanddef>
   244    253   
   245    254         <commanddef>
   246    255           <command><method>removeChild</method> <m>child</m></command>
   247         -        <desc>Removes <m>child</m> from the list of children of that node
          256  +        <desc>Removes <m>child</m> from the list of children of that node.
   248    257   <m>child</m> will be part of the document fragment list after this
   249         -operation. It is not physically deleted.</desc>
          258  +operation.</desc>
   250    259         </commanddef>
   251    260   
   252    261         <commanddef>
   253    262           <command><method>delete</method></command>
   254    263           <desc>Deletes the given node and its complete child tree
   255    264   and frees the complete internal memory. The affected nodes are not accessible
   256    265   through the document fragment list.</desc>
................................................................................
   350    359             <desc><p>Returns the result of applying the XPath query
   351    360   <m>xpathQuery</m> to the subtree. This can be a
   352    361   string/value, a list of strings, a list of nodes or a list
   353    362   of attribute name / value pairs. If <m>typeVar</m> is given
   354    363   the result type name is stored into that variable (empty,
   355    364   bool, number, string, nodes, attrnodes or mixed).</p>
   356    365   
   357         -<p>The argument <m>xpathQuery</m> has to be a valid XPath
   358         -expression. However, there is one exception to that rule. Tcl variable
   359         -names can appear in the XPath statement at any position where it is
   360         -legal according to the rules of the XPath syntax to put an XPath
   361         -variable. The value of the variable is substituted for the variable
   362         -name. Ignoring the syntax rules of XPath the Tcl variable name may be
   363         -any legal Tcl var name: local variables, global variables, array
   364         -entries and so on.</p>
          366  +<p>The argument <m>xpathQuery</m> has to be a valid XPath expression.
          367  +However there are a few exceptions to that rule. Tcl variable
          368  +references (in the usual tcl syntax: $varname) may appear in the XPath
          369  +statement at any position where it is legal according to the rules of
          370  +the XPath syntax to put an XPath variable. Ignoring the syntax rules of
          371  +XPath the Tcl variable name may be any legal Tcl var name: local
          372  +variables, global variables, array entries and so on. The value will
          373  +always be seen as string literal by the xpath engine. Cast the value
          374  +explicitly with the according xpath functions (number(), boolean()) to
          375  +another data type, if needed.</p>
          376  +
          377  +<p>Similar to the way described above to inject literals in a secure
          378  +way into the XPath expression using tcl variable references there is a
          379  +syntax to inject element names from tcl variables. At every place
          380  +where the XPath syntax allows a node test there could be a tcl
          381  +variable reference (in any form), just the leading $ replaced with %.
          382  +This allows one to select nodes with 'strange' (invalid, according to the
          383  +appropriate XML production rule) node names which may be needed in
          384  +case of working with JSON data.</p>
   365    385   
   366    386   <p>The option <m>-namespaces</m> expects a tcl list with prefix /
   367    387   namespace pairs as argument. If this option is not given, then any
   368    388   namespace prefix within the xpath expression will be first resolved
   369    389   against the list of prefix / namespace pairs set with the
   370    390   selectNodesNamespaces method for the document, the node belongs to. If
   371    391   this fails, then the namespace definitions in scope of the context
   372    392   node will be used to resolve the prefix. If this option is given, any
   373    393   namespace prefix within the xpath expression will be first resolved
   374    394   against that given list (and ignoring the document global prefix /
   375         -namespace list). If the list bind the same prefix to different
          395  +namespace list). If the list binds the same prefix to different
   376    396   namespaces, then the first binding will win.  If this fails, then the
   377    397   namespace definitions in scope of the context node will be used to
   378    398   resolve the prefix, as usual.</p>
   379    399   
   380    400   <p>If the <m>-cache</m> option is used with a true value, then the
   381         -<m>xpathQuery</m> will be looked up in a document specific cache. If the query
   382         -is found, then the stored pre-compiled query will be used. If the
   383         -query isn't found, it will be pre-compiled and stored in the cache,
   384         -for use in further calls. Please notice, that the <m>xpathQuery</m> as given as
   385         -string is used as key for the cache. This means, that equal XPath
   386         -expressions, which differ only in white space are treated as
          401  +<m>xpathQuery</m> will be looked up in a document specific cache. If
          402  +the query is found, then the stored pre-compiled query will be used.
          403  +If the query isn't found, it will be compiled and stored in the cache,
          404  +for use in further calls. Please note that the <m>xpathQuery</m> 
          405  +given as string is used as key for the cache. This means, that equal
          406  +XPath expressions, which differ only in white space are treated as
   387    407   different cache entries. Special care is needed, if the XPath
   388         -expression includes namespace prefixes. During pre-compilation, the
   389         -prefixes will be resolved first to the prefix / namespace pairs of
   390         -the <m>-namespaces</m> option, if given, and to the namespaces
   391         -in scope of the context node at pre-compilation time. If the XPath
   392         -is found in the cache, neither the <m>-namespaces</m> option nor
   393         -the namespaces in scope of the context node will be taken in
   394         -account but the already resolved (stored) namespaces will be used
   395         -for the query.</p>
          408  +expression includes namespace prefixes or references to tcl variables.
          409  +Both namespace prefixes and tcl variable references will be resolved
          410  +according to the XML prefix namespace mappings and tcl variable values
          411  +at expression compilation time. If the same XPath expression is used
          412  +later on in a context with other XML prefix namespace mappings or
          413  +values of the used tcl variables, make sure to first remove the
          414  +compiled expression from the cache with the help of the
          415  +<method>deleteXPathCache</method> method, to force a recompilation.
          416  +Without using the <m>-cache</m> option such consideration is never
          417  +needed.</p>
   396    418   
   397    419   <p>Examples:</p>
   398    420             <example>set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
   399    421   foreach paragraph $paragraphNodes {
   400    422       lappend  values [$paragraph selectNodes attribute::type]
   401    423   }
   402    424   
................................................................................
   405    427   set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</example>
   406    428   
   407    429             </desc>
   408    430         </commanddef>
   409    431   
   410    432         <commanddef>
   411    433           <command><method>getLine</method></command>
   412         -        <desc>Returns the line number of that node in the orignal parsed
          434  +        <desc>Returns the line number of that node in the originally parsed
   413    435   XML.</desc>
   414    436         </commanddef>
   415    437         
   416    438         <commanddef>
   417    439           <command><method>getColumn</method></command>
   418         -        <desc>Returns the column number of that node in the orignal parsed
          440  +        <desc>Returns the column number of that node in the originally parsed
   419    441   XML.</desc>
   420    442         </commanddef>
   421    443   
   422    444         <commanddef>
   423    445           <command><method>asList</method></command>
   424    446           <desc>Returns the DOM substree starting form the current node as a
   425    447   nested Tcl list.</desc>
   426    448         </commanddef>
   427    449   
   428    450         <commanddef>
   429         -        <command><method>asXML</method> <option>?-indent none/1..8?</option>
   430         -<option>?-channel channelId?</option> <option>?-escapeNonASCII?</option><option>?-escapeAllQuot?</option></command>
   431         -
   432         -        <desc>Returns the DOM substree starting from the current node
   433         -as the root node of the result as an (optional indented) XML string or
   434         -sends the output directly to the given channelId. If the option
   435         -<m>-escapeNonASCII</m> is given, every non 7 bit ASCII character in
   436         -attribute values or element PCDATA content will be escaped as
   437         -character reference in decimal representation. If the option
   438         -<m>-escapeAllQuot</m> is given, quotation marks will be escaped with
   439         -&amp;quot; even in text content of elements.</desc>
          451  +        <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>
          452  +        <desc><p>Returns the DOM substree starting from the current
          453  +        node as the root node of the result as an (optional indented)
          454  +        XML string or sends the output directly to the given
          455  +        channelId.</p>
          456  +
          457  +        <p>If the option <m>-escapeNonASCII</m> is given,
          458  +        every non 7 bit ASCII character in attribute values or element
          459  +        PCDATA content will be escaped as character reference in
          460  +        decimal representation.</p>
          461  +
          462  +        <p>The flag <m>-xmlDeclaration</m> determines whether there
          463  +        will be an XML Declaration and a newline emitted before
          464  +        anything else. The default is, to do not. If this flag is
          465  +        given with a true argument then</p>
          466  +
          467  +        <p><m>-encString</m> sets the encoding value in the XML
          468  +        Declaration. Otherwise, this option is ignored. Please note,
          469  +        that this option just enhance the string representation of the
          470  +        generated XML Declaration with an encoding information string,
          471  +        nothing more. It's up to the user to handle encoding in case
          472  +        of writing to a channel or reparsing.</p>
          473  +            
          474  +        <p>If the option <m>-escapeAllQuot</m> is given,
          475  +        quotation marks will be escaped with &amp;quot; even in text
          476  +        content of elements.</p>
          477  +
          478  +        <p>If the option <m>-indentAttrs</m> is
          479  +        given, then attributes will each be separated with newlines
          480  +        and indented to the same level as the parent node plus the
          481  +        value given as argument to <m>-indentAttrs</m> (0..8).</p>
          482  +
          483  +        <p>If the option <m>-nogtescape</m> is given then the
          484  +        character '>' won't get escaped in attribute values and text
          485  +        content of elements. The default is to escape this
          486  +        character.</p>
          487  +
          488  +        <p>If the option <m>-noEmptyElementTag</m> is given then no
          489  +        empty tag syntax will be used. Instead, if an element has
          490  +        empty content it will be serialized with an element start tag
          491  +        and an immediately following element end tag.</p></desc>
          492  +
   440    493         </commanddef>
   441    494   
   442    495         <commanddef>
   443    496           <command><method>asHTML</method> <option>?-channel channelId?</option>
   444    497   <option>?-escapeNonASCII?</option>  <option>?-htmlEntities?</option></command>
   445    498           <desc>Returns the DOM substree starting from the current node as the
   446         -root node of the result serialized acording to HTML rules (HTML elements are
   447         -recognized regardless of case, without end tags for emtpy HTML elements etc.),
          499  +root node of the result serialized according to HTML rules (HTML elements are
          500  +recognized regardless of case, without end tags for empty HTML elements etc.),
   448    501   as string or sends the output directly to the given channelId. If the option
   449    502   <m>-escapeNonASCII</m> is given, every non 7 bit ASCII character in attribute
   450    503   values or element PCDATA content will be escaped as character reference in
   451    504   decimal representation. If the option <m>-htmlEntities</m> is given, a
   452         -character is outputed using a HTML 4.01 character entity reference, if one is
          505  +character is written using its HTML 4.01 character entity reference, if one is
   453    506   defined for it.</desc>
   454    507         </commanddef>
   455    508   
   456    509         <commanddef>
   457    510           <command><method>asText</method></command>
   458    511             <desc>For ELEMENT_NODEs, the asText method outputs 
   459    512   the string-value of every text node descendant of node in document
   460         -order without any escaping. For every other node type, this method outputs the
   461         -the XPath string value of that node.</desc>
          513  +order without any escaping. For every other node type, this method outputs the XPath string value of that node.</desc>
   462    514         </commanddef>
   463    515   
   464    516         <commanddef>
   465    517           <command><method>appendFromList</method> <m>list</m></command>
   466    518           <desc>Parses <m>list</m> , creates an according DOM subtree and
   467    519   appends this subtree to the current node.</desc>
   468    520         </commanddef>
................................................................................
   474    526   given node.</desc>
   475    527         </commanddef>
   476    528   
   477    529         <commanddef>
   478    530           <command><method>insertBeforeFromScript</method> <m>tclScript</m> <m>refChild</m></command>
   479    531           <desc>Inserts the nodes created in the <m>tclScript</m> by
   480    532   Tcl functions, which have been built using <m>dom createNodeCmd</m>, before the
   481         -<m>refChild</m> into to the list of children of node. If <m>refChild</m> is
          533  +<m>refChild</m> into the list of children of node. If <m>refChild</m> is
   482    534   the empty string, the new nodes will be appended.</desc>
   483    535         </commanddef>
   484    536   
   485    537         <commanddef>
   486    538           <command><method>appendXML</method> <m>XMLstring</m></command>
   487    539           <desc>Parses <m>XMLstring</m>, creates an according DOM subtree and
   488    540   appends this subtree to the current node.</desc>
   489    541         </commanddef>
   490    542   
   491    543         <commanddef>
   492    544           <command><method>simpleTranslate</method> <m>outputVar</m>
   493    545   <m>specifications</m></command>
   494         -        <desc>Translate the subtree starting at the object node according to
          546  +        <desc>Translates the subtree starting at the object node according to
   495    547   the specifications in <m>specifications</m> and outputs the result in the
   496    548   variable <m>outputVar</m> . The translation is very similar to Cost Simple
   497    549   mode.</desc>
   498    550         </commanddef>
   499    551   
   500    552         <commanddef>
   501         -        <command><method>toXPath</method></command>
          553  +        <command><method>toXPath</method> <m>?-legacy?</m></command>
   502    554           <desc>Returns an XPath, which exactly addresses the given
   503    555   node in its document. This XPath is only valid as there are no changes to DOM
   504         -tree made later one.</desc>
          556  +tree made later one. With the -legacy option, other XPath expressions
          557  +are returned, which doesn't work in all cases.</desc>
   505    558         </commanddef>
   506    559   
   507    560         <commanddef>
   508    561           <command><method>getBaseURI</method></command>
   509    562           <desc>Returns the baseURI of the node. This method is deprecated in
   510    563             favor of the <m>baseURI</m> method.</desc>
   511    564         </commanddef>
   512    565   
   513    566         <commanddef>
   514         -        <command><method>baseURI <m>?URI?</m></method></command>
          567  +        <command><method>baseURI</method> <m>?URI?</m></command>
   515    568           <desc>Returns the present baseURI of the node. If the optional 
   516         -argument URI is given, sets the base URI of the node and of all of its child
   517         -nodes out of the same enitity as node to the given URI.</desc>
          569  +argument URI is given, it sets the base URI of the node and of all of its child
          570  +nodes out of the same entity as node to the given URI.</desc>
   518    571         </commanddef>
   519    572   
   520    573         <commanddef>
   521    574           <command><method>disableOutputEscaping</method> <m>?boolean?</m></command>
   522         -        <desc>This method works only for text nodes; for every other nodes it
          575  +        <desc>This method works only for text nodes; for every other node it
   523    576   returns error. Without the optional argument it returns, if disabling output
   524    577   escaping is on. The return value 0 means, the characters of the text node will
   525    578   be escaped, to generate valid XML, if serialized. This is the default for
   526    579   every parsed or created text node (with the exception of that text nodes in a
   527    580   result tree of an XSLT transformation, for which disabling output escaping was
   528         -requested explicitely in the stylesheet). The return value 1 means, that output
          581  +requested explicitly in the stylesheet). The return value 1 means, that output
   529    582   escaping is disabled for this text node. If such a text node is serialized
   530         -(with asXML or asHTML), it is literarily written, without escaping of the
          583  +(with asXML or asHTML), it is literally written, without escaping of the
   531    584   special XML characters. If the optional boolean value <m>boolean</m> is given,
   532         -the flag is set accordingly. You should not set this flag to 1, until you
   533         -really know, what you do.</desc>
          585  +the flag is set accordingly. You should not set this flag to 1 until you
          586  +really know what you do.</desc>
   534    587         </commanddef>
   535    588   
   536    589         <commanddef>
   537    590           <command><method>precedes</method> <m>refnode</m></command>
   538    591           <desc>Compares the relative order of the node and <m>refnode</m>. Both
   539    592   nodes must be part of the same documents and not out of the fragment list of
   540         -the document. Returns true, if node is in document order (in the sense of the
   541         -XPath 1.0 recommendation) before <m>refnode</m> and false otherwise.</desc>
          593  +the document. Returns true if node is in document order (in the sense of the
          594  +XPath 1.0 recommendation) before <m>refnode</m>, and false otherwise.</desc>
   542    595         </commanddef>
   543    596   
   544    597   
   545    598         <commanddef>
   546    599           <command><method>normalize</method> <m>?-forXPath?</m></command>
   547    600           <desc>Puts all Text nodes in the full depth of the sub-tree underneath
   548    601   this Node into a "normal" form where only structure (e.g., elements,
................................................................................
   553    606   converted to text nodes, as a first step before the
   554    607   normalization. </desc>
   555    608         </commanddef>
   556    609   
   557    610         <commanddef>
   558    611           <command><method>xslt</method> <option>?-parameters
   559    612   parameterList?</option> <option>?-ignoreUndeclaredParameters?</option>
          613  +<option>?-maxApplyDepth int?</option>
   560    614   <option>?-xsltmessagecmd script?</option> <m>stylesheet</m> <m>?outputVar?</m></command>
   561    615           <desc>Applies an XSLT transformation on the document using the XSLT
   562    616   <m>stylesheet</m> (given as domDoc). Returns a document object containing the
   563    617   result document of that transformation and stores it in the optional
   564    618   <m>outputVar</m>. 
   565    619   
   566    620   <p>The optional <m>-parameters</m> option sets top level
   567    621   &lt;xsl:param&gt; to string values. The <m>parameterList</m> has to be a tcl
   568    622   list consisting of parameter name and value pairs.</p>
   569    623   
   570    624   <p>If the option <m>-ignoreUndeclaredParameters</m> is given, then parameter
   571    625   names in the <m>parameterList</m> given to the <m>-parameters</m> options that
   572    626   are not declared as top-level parameters in the stylesheet are silently
   573         -ignored. Without this option, an error is raised, if the user tries to set a
   574         -top-level parameter, which is not declared in the stylesheet.</p>
          627  +ignored. Without this option, an error is raised if the user tries to set a
          628  +top-level parameter which is not declared in the stylesheet.</p>
          629  +
          630  +<p>The option <m>-maxApplyDepth</m> expects a positive integer as
          631  +argument. By default, the xslt engine allows xslt templates to nest up
          632  +to 3000 levels (and raises error if they nest deeper). This limit can
          633  +be set by the <m>-maxApplyDepth</m> option.</p>
   575    634   
   576    635   <p>The <m>-xsltmessagecmd</m> option sets a callback for xslt:message elements
   577    636   in the stylesheet. The actual command consists of the script, given as argument
   578    637   to the option, appended with the XML Fragment from instantiating the
   579    638   xsl:message element content as string (as if the XPath string() function would
   580         -have been applied to the XML Fragment) and a flag, which indicates, if the
   581         -xsl:message has an attribute "terminate" with the value "yes".</p>
          639  +have been applied to the XML Fragment) and a flag, which indicates whether the
          640  +xsl:message has an attribute "terminate" with the value "yes". If the
          641  +called script returns anything else then TCL_OK then the xslt
          642  +transformation will be aborted, returning error. If the called script
          643  +returns -code break the error message is empty, otherwise the result
          644  +code is reported. In case of terminated transformation the outputVar,
          645  +if given, is set to the empty string.</p>
   582    646   </desc>
   583    647         </commanddef>
   584    648   
   585    649         <commanddef>
   586    650           <command><m>@attrName</m></command>
   587    651           <desc>Returns the value of the attribute <m>attrName</m>.  Short cut
   588    652   for <m>getAttribute</m>.</desc>
   589    653         </commanddef>
          654  +
          655  +      <commanddef>
          656  +        <command><method>jsonType</method> <m>?OBJECT|ARRAY|NONE)|(STRING|NUMBER|TRUE|FALSE|NULL|NONE)?</m></command>
          657  +        <desc>Only element and text nodes may have a JSON type and
          658  +        only this types of nodes support the <m>jsonType</m> method;
          659  +        the other node types return error if called with this method.
          660  +        Returns the jsonType of the node. If the optional argument is
          661  +        given, the JSON type of the node is set to the given type and
          662  +        returned. Valid type arguments for element nodes are OBJECT,
          663  +        ARRAY and NONE. Valid type arguments for text nodes are
          664  +        STRING, NUMBER, TRUE, FALSE, NULL and NONE.</desc>
          665  +      </commanddef>
          666  +
   590    667       </commandlist>
   591    668   
          669  +    
   592    670       <p>Otherwise, if an unknown method name is given, the command with the same
   593    671   name as the given method within the namespace <l>::dom::domNode</l> is tried to
   594    672   be executed. This allows quick method additions on Tcl level.</p>
   595    673   
   596    674     </section>
   597    675   
   598    676   

Changes to doc/expat.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <div class="navbar" align="center">
     7         -<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>
            7  +<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>
     8      8   </div><hr class="navsep">
     9      9   </div><div class="body">
    10         -    <h2><a name="SECTid80acb10">NAME</a></h2><p class="namesection">
           10  +    <h2><a name="SECTid0x1708960">NAME</a></h2><p class="namesection">
    11     11   <b class="names">expat - </b><br>Creates an instance of an expat parser object</p>
    12     12   
    13     13   
    14     14   
    15         -    <h2><a name="SECTid80acb88">SYNOPSIS</a></h2><pre class="syntax">
    16         -<b class="cmd">package require tdom</b>
           15  +    <h2><a name="SECTid0x160bf00">SYNOPSIS</a></h2><pre class="syntax">package require tdom
    17     16   
    18     17   <b class="cmd">expat</b> ?<i class="m">parsername</i>? ?<i class="m">-namespace</i>? ?<i class="m">arg arg ..</i>
    19     18   
    20     19   <b class="cmd">xml::parser</b> ?<i class="m">parsername</i>? ?<i class="m">-namespace</i>? ?<i class="m">arg arg ..</i>
    21     20   </pre>
    22         -    <h2><a name="SECTid80acd40">DESCRIPTION</a></h2><p>The parser created with <i class="m">expat</i> or <i class="m">xml::parser</i>
           21  +    <h2><a name="SECTid0x16ee020">DESCRIPTION</a></h2><p>The parser created with <i class="m">expat</i> or <i class="m">xml::parser</i>
    23     22   (which is just another name for the same command in an own namespace) are able
    24     23   to parse any kind of well-formed XML. The parsers are stream oriented XML
    25     24   parser. This means that you register handler scripts with the parser prior to
    26     25   starting the parse. These handler scripts are called when the parser discovers
    27     26   the associated structures in the document being parsed.  A start tag is an
    28     27   example of the kind of structures for which you may register a handler
    29     28   script.</p><p>The parsers do not validate the XML document. They do parse the internal DTD
................................................................................
    32     31   there).</p><p>Additionly, the Tcl extension code that implements this command provides an
    33     32   API for adding C level coded handlers. Up to now, there exists the parser
    34     33   extension command "tdom". The handler set installed by this extension build an
    35     34   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
    36     35   and C level handlers for most of the events. If the event occurs, they are
    37     36   called in turn.</p>
    38     37   
    39         -    <h2><a name="SECTid80ace80">COMMAND OPTIONS</a></h2><dl class="optlist">
           38  +    <h2><a name="SECTid0x16eed60">COMMAND OPTIONS</a></h2><dl class="optlist">
    40     39           
    41     40             <dt><b>-namespace</b></dt>
    42     41   
    43     42             <dd>
    44     43   <p>Enables namespace parsing. You must use this option while
    45     44   creating the parser with the <tt class="samp">expat</tt> or <tt class="samp">xml::parser</tt>
    46     45   command. You can't enable (nor disable) namespace parsing with
................................................................................
   604    603   </dt>
   605    604             
   606    605             <dd>If &lt;boolen&gt; is true and the document does not have an
   607    606   external subset, the parser will call the -externalentitycommand script with
   608    607   empty values for the systemId and publicID arguments. This option must be set,
   609    608   before the first piece of data is parsed. Setting this option, after the
   610    609   parsing has started has no effect. The default is not to use a foreign DTD. The
   611         -default is restored, after reseting the parser. Pleace notice, that a
          610  +default is restored, after resetting the parser. Pleace notice, that a
   612    611   -paramentityparsing value of "never" (which is the default) suppresses any call
   613    612   to the -externalentitycommand script. Pleace notice, that, if the document also
   614    613   doesn't have an internal subset, the -startdoctypedeclcommand and
   615    614   enddoctypedeclcommand scripts, if set, are not called.</dd>
   616    615           
   617    616   
   618    617         </dl>
   619         -    <h2><a name="SECTid80aeac8"> COMMAND METHODS </a></h2><dl class="commandlist">
          618  +    <h2><a name="SECTid0x1746b80"> COMMAND METHODS </a></h2><dl class="commandlist">
   620    619           
   621    620             <dt>
   622    621   <b class="cmd">parser</b> <b class="method">configure</b> <i class="m">option value ?option value?</i>
   623    622   </dt>
   624    623   
   625    624             <dd><p>Sets configuration options for the parser. Every command
   626    625   option, except <i class="m">-namespace</i> can be set or modified with this method.</p></dd>
   627    626           
   628    627   
   629    628           
   630    629             <dt>
   631         -<b class="cmd">parser</b> <b class="method">cget <i class="m">?-handlerset name? option</i>
   632         -</b>
          630  +<b class="cmd">parser</b> <b class="method">cget</b> <i class="m">?-handlerset name? option</i>
   633    631   </dt>
   634    632   
   635    633             <dd>
   636    634   <p>Return the current configuration value option for the
   637    635   parser.</p> 
   638    636             <p>If the -handlerset option is used, the configuration for the
   639    637   named handler set is returned.</p>
   640    638             </dd>
   641    639           
   642    640   
   643    641           
   644    642             <dt>
   645         -<b class="cmd">parser</b> <b class="method">free</b>
          643  +<b class="cmd">parser</b> <b class="method">currentmarkup</b>
          644  +</dt>
          645  +
          646  +          <dd><p>Returns the current markup as found in the XML, if
          647  +          called from within one of its markup event handler script
          648  +          (-elementstartcommand, -elementendcommand, -commentcommand
          649  +          and -processinginstructioncommand). Otherwise it return the
          650  +          empty string.</p></dd>
          651  +        
          652  +
          653  +        
          654  +          <dt>
          655  +<b class="cmd">parser</b> <b class="method">delete</b>
   646    656   </dt>
   647    657   
   648    658             <dd><p>Deletes the parser and the parser command. A parser cannot
   649         -be freed from within one of its handler callbacks (neither directly nor
          659  +be deleted from within one of its handler callbacks (neither directly nor
   650    660   indirectly) and will raise a tcl error in this case.</p></dd>
   651    661           
          662  +
          663  +        
          664  +          <dt>
          665  +<b class="cmd">parser</b> <b class="method">free</b>
          666  +</dt>
          667  +
          668  +          <dd><p>Another name to call the method <i class="m">delete</i>, see
          669  +          there.</p></dd>
          670  +        
   652    671   
   653    672           
   654    673             <dt>
   655    674   <b class="cmd">parser</b> <b class="method">get</b> <i class="m">-specifiedattributecount|-idattributeindex|-currentbytecount|-currentlinenumber|-currentcolumnnumber|-currentbyteindex</i>
   656    675   </dt>
   657    676             <dd>
   658    677   <dl class="optlist">
................................................................................
   746    765   
   747    766           
   748    767             <dt>
   749    768   <b class="cmd">parser</b> <b class="method">reset</b>
   750    769   </dt>
   751    770   
   752    771             <dd><p>Resets the parser in preparation for parsing another
   753         -document. A parser cannot be reseted from within one of its handler callbacks
          772  +document. A parser cannot be reset from within one of its handler callbacks
   754    773   (neither directly nor indirectly) and will raise a tcl error in this
   755    774   cases.</p></dd>
   756    775           
   757    776         </dl>
   758    777   
   759         -    <h2><a name="SECTid80af860">Callback Command Return Codes</a></h2><p>A script invoked for any of the parser callback commands, such as
          778  +    <h2><a name="SECTid0x174d660">Callback Command Return Codes</a></h2><p>A script invoked for any of the parser callback commands, such as
   760    779   -elementstartcommand, -elementendcommand, etc, may return an error code other
   761    780   than "ok" or "error". All callbacks may in addition return
   762    781   "break" or "continue".</p><p>If a callback script returns an "error" error code then
   763    782   processing of the document is terminated and the error is propagated in the
   764    783   usual fashion.</p><p>If a callback script returns a "break" error code then all
   765    784   further processing of every handler script out of this Tcl handler set is
   766    785   suppressed for the further parsing. This does not influence any other handler
   767    786   set.</p><p>If a callback script returns a "continue" error code then
   768    787   processing of the current element, and its children, ceases for every handler
   769    788   script out of this Tcl handler set and processing continues with the next
   770         -(sibling) element. This does not influence any other handler set.</p>
          789  +(sibling) element. This does not influence any other handler set.</p><p>If a callback script returns a "return" error
          790  +code then parsing is canceled altogether, but no error is raised.</p>
   771    791   
   772         -    <h2><a name="SECTid80af950">SEE ALSO</a></h2><p class="seealso">
          792  +    <h2><a name="SECTid0x174e1f0">SEE ALSO</a></h2><p class="seealso">
   773    793   <a href="expatapi.html">expatapi</a>, <a href="tdomcmd.html">tdom</a>
   774    794   </p>
   775    795   
   776         -    <h2><a name="SECTid80af9c8">KEYWORDS</a></h2><p class="keywords"><a class="keyword" href="keyword-index.html#KW-SAX">SAX</a></p>
          796  +    <h2><a name="SECTid0x174e5b0">KEYWORDS</a></h2><p class="keywords"><a class="keyword" href="keyword-index.html#KW-SAX">SAX</a></p>
   777    797     </div><hr class="navsep"><div class="navbar" align="center">
   778         -<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>
          798  +<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>
   779    799   </div>
   780    800   </body>
   781    801   </html>

Changes to doc/expat.n.

   159    159   '\" END man.macros
   160    160   .TH expat n "" Tcl ""
   161    161   .BS
   162    162   .SH NAME
   163    163   expat \- Creates an instance of an expat parser object
   164    164   .SH SYNOPSIS
   165    165   .nf
   166         -\&\fBpackage require tdom\fP
          166  +package require tdom
   167    167   
   168    168   \&\fBexpat\fP ?\fIparsername\fR? ?\fI-namespace\fR? ?\fIarg arg ..\fR
   169    169   
   170    170   \&\fBxml::parser\fP ?\fIparsername\fR? ?\fI-namespace\fR? ?\fIarg arg ..\fR
   171    171   .fi
   172    172   .BE
   173    173   .SH DESCRIPTION
................................................................................
   695    695   .RE
   696    696   .IP "\fB-useForeignDTD  \fI<boolen>\fP\fR"
   697    697   If <boolen> is true and the document does not have an
   698    698   external subset, the parser will call the -externalentitycommand script with
   699    699   empty values for the systemId and publicID arguments. This option must be set,
   700    700   before the first piece of data is parsed. Setting this option, after the
   701    701   parsing has started has no effect. The default is not to use a foreign DTD. The
   702         -default is restored, after reseting the parser. Pleace notice, that a
          702  +default is restored, after resetting the parser. Pleace notice, that a
   703    703   -paramentityparsing value of "never" (which is the default) suppresses any call
   704    704   to the -externalentitycommand script. Pleace notice, that, if the document also
   705    705   doesn't have an internal subset, the -startdoctypedeclcommand and
   706    706   enddoctypedeclcommand scripts, if set, are not called.
   707    707   .SH " COMMAND METHODS "
   708    708   .TP
   709    709   \&\fB\fBparser\fP \fBconfigure\fP \fIoption value ?option value?\fB
................................................................................
   710    710   \&\fR
   711    711   .RS
   712    712   .PP
   713    713   Sets configuration options for the parser. Every command
   714    714   option, except \fI-namespace\fR can be set or modified with this method.
   715    715   .RE
   716    716   .TP
   717         -\&\fB\fBparser\fP \fBcget \fI?-handlerset name? option\fB\fP
          717  +\&\fB\fBparser\fP \fBcget\fP \fI?-handlerset name? option\fB
   718    718   \&\fR
   719    719   .RS
   720    720   .PP
   721    721   Return the current configuration value option for the
   722    722   parser.
   723    723   .PP
   724    724   If the -handlerset option is used, the configuration for the
   725    725   named handler set is returned.
   726    726   .RE
   727    727   .TP
   728         -\&\fB\fBparser\fP \fBfree\fP
          728  +\&\fB\fBparser\fP \fBcurrentmarkup\fP
          729  +\&\fR
          730  +.RS
          731  +.PP
          732  +Returns the current markup as found in the XML, if
          733  +called from within one of its markup event handler script
          734  +(-elementstartcommand, -elementendcommand, -commentcommand
          735  +and -processinginstructioncommand). Otherwise it return the
          736  +empty string.
          737  +.RE
          738  +.TP
          739  +\&\fB\fBparser\fP \fBdelete\fP
   729    740   \&\fR
   730    741   .RS
   731    742   .PP
   732    743   Deletes the parser and the parser command. A parser cannot
   733         -be freed from within one of its handler callbacks (neither directly nor
          744  +be deleted from within one of its handler callbacks (neither directly nor
   734    745   indirectly) and will raise a tcl error in this case.
   735    746   .RE
          747  +.TP
          748  +\&\fB\fBparser\fP \fBfree\fP
          749  +\&\fR
          750  +.RS
          751  +.PP
          752  +Another name to call the method \fIdelete\fR, see
          753  +there.
          754  +.RE
   736    755   .TP
   737    756   \&\fB\fBparser\fP \fBget\fP \fI-specifiedattributecount|-idattributeindex|-currentbytecount|-currentlinenumber|-currentcolumnnumber|-currentbyteindex\fB
   738    757   \&\fR
   739    758   .RS
   740    759   .IP "\fB-specifiedattributecount\fR"
   741    760   .RS
   742    761   .PP
................................................................................
   818    837   .RE
   819    838   .TP
   820    839   \&\fB\fBparser\fP \fBreset\fP
   821    840   \&\fR
   822    841   .RS
   823    842   .PP
   824    843   Resets the parser in preparation for parsing another
   825         -document. A parser cannot be reseted from within one of its handler callbacks
          844  +document. A parser cannot be reset from within one of its handler callbacks
   826    845   (neither directly nor indirectly) and will raise a tcl error in this
   827    846   cases.
   828    847   .RE
   829    848   .SH "Callback Command Return Codes"
   830    849   .PP
   831    850   A script invoked for any of the parser callback commands, such as
   832    851   -elementstartcommand, -elementendcommand, etc, may return an error code other
................................................................................
   842    861   suppressed for the further parsing. This does not influence any other handler
   843    862   set.
   844    863   .PP
   845    864   If a callback script returns a "continue" error code then
   846    865   processing of the current element, and its children, ceases for every handler
   847    866   script out of this Tcl handler set and processing continues with the next
   848    867   (sibling) element. This does not influence any other handler set.
          868  +.PP
          869  +If a callback script returns a "return" error
          870  +code then parsing is canceled altogether, but no error is raised.
   849    871   .SH "SEE ALSO"
   850    872   expatapi, tdom
   851    873   .SH KEYWORDS
   852    874   SAX

Changes to doc/expat.xml.

     1         -  <manpage id="expat" cat="cmd" title="expat">
            1  +<manpage id="expat" cat="cmd" title="expat">
     2      2       <namesection>
     3      3         <name>expat</name>
     4      4         <desc>Creates an instance of an expat parser object</desc>
     5      5       </namesection>
     6      6   
     7      7   <!--
     8      8   
................................................................................
    10     10   
    11     11    See the file "LICENSE" for information on usage and redistribution
    12     12    of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    13     13   
    14     14   -->
    15     15   
    16     16       <synopsis>
    17         -      <syntax><cmd>package require tdom</cmd>
           17  +      <syntax>package require tdom
    18     18   
    19     19   <cmd>expat</cmd> ?<m>parsername</m>? ?<m>-namespace</m>? ?<m>arg arg ..</m>
    20     20   
    21     21   <cmd>xml::parser</cmd> ?<m>parsername</m>? ?<m>-namespace</m>? ?<m>arg arg ..</m></syntax>
    22     22       </synopsis>
    23     23       <section>
    24     24         <title>DESCRIPTION</title>
................................................................................
   553    553             <optname>-useForeignDTD</optname>
   554    554             <optarg>&lt;boolen&gt;</optarg>
   555    555             <desc>If &lt;boolen&gt; is true and the document does not have an
   556    556   external subset, the parser will call the -externalentitycommand script with
   557    557   empty values for the systemId and publicID arguments. This option must be set,
   558    558   before the first piece of data is parsed. Setting this option, after the
   559    559   parsing has started has no effect. The default is not to use a foreign DTD. The
   560         -default is restored, after reseting the parser. Pleace notice, that a
          560  +default is restored, after resetting the parser. Pleace notice, that a
   561    561   -paramentityparsing value of "never" (which is the default) suppresses any call
   562    562   to the -externalentitycommand script. Pleace notice, that, if the document also
   563    563   doesn't have an internal subset, the -startdoctypedeclcommand and
   564    564   enddoctypedeclcommand scripts, if set, are not called.</desc>
   565    565           </optdef>
   566    566   
   567    567         </optlist>
................................................................................
   574    574             <command><cmd>parser</cmd> <method>configure</method> <m>option value ?option value?</m></command>
   575    575   
   576    576             <desc><p>Sets configuration options for the parser. Every command
   577    577   option, except <m>-namespace</m> can be set or modified with this method.</p></desc>
   578    578           </commanddef>
   579    579   
   580    580           <commanddef>
   581         -          <command><cmd>parser</cmd> <method>cget <m>?-handlerset name? option</m></method></command>
          581  +          <command><cmd>parser</cmd> <method>cget</method> <m>?-handlerset name? option</m></command>
   582    582   
   583    583             <desc><p>Return the current configuration value option for the
   584    584   parser.</p> 
   585    585             <p>If the -handlerset option is used, the configuration for the
   586    586   named handler set is returned.</p>
   587    587             </desc>
   588    588           </commanddef>
   589    589   
   590    590           <commanddef>
   591         -          <command><cmd>parser</cmd> <method>free</method></command>
          591  +          <command><cmd>parser</cmd> <method>currentmarkup</method></command>
          592  +
          593  +          <desc><p>Returns the current markup as found in the XML, if
          594  +          called from within one of its markup event handler script
          595  +          (-elementstartcommand, -elementendcommand, -commentcommand
          596  +          and -processinginstructioncommand). Otherwise it return the
          597  +          empty string.</p></desc>
          598  +        </commanddef>
          599  +
          600  +        <commanddef>
          601  +          <command><cmd>parser</cmd> <method>delete</method></command>
   592    602   
   593    603             <desc><p>Deletes the parser and the parser command. A parser cannot
   594         -be freed from within one of its handler callbacks (neither directly nor
          604  +be deleted from within one of its handler callbacks (neither directly nor
   595    605   indirectly) and will raise a tcl error in this case.</p></desc>
   596    606           </commanddef>
   597    607   
          608  +        <commanddef>
          609  +          <command><cmd>parser</cmd> <method>free</method></command>
          610  +
          611  +          <desc><p>Another name to call the method <m>delete</m>, see
          612  +          there.</p></desc>
          613  +        </commanddef>
          614  +
   598    615           <commanddef>
   599    616             <command><cmd>parser</cmd> <method>get</method> <m>-specifiedattributecount|-idattributeindex|-currentbytecount|-currentlinenumber|-currentcolumnnumber|-currentbyteindex</m></command>
   600    617             <desc>
   601    618   <optlist>
   602    619                 <optdef>
   603    620                   <optname>-specifiedattributecount</optname>
   604    621   
................................................................................
   681    698   of the parser to be used and will raise an error in this case.</p></desc>
   682    699           </commanddef>
   683    700   
   684    701           <commanddef>
   685    702             <command><cmd>parser</cmd> <method>reset</method></command>
   686    703   
   687    704             <desc><p>Resets the parser in preparation for parsing another
   688         -document. A parser cannot be reseted from within one of its handler callbacks
          705  +document. A parser cannot be reset from within one of its handler callbacks
   689    706   (neither directly nor indirectly) and will raise a tcl error in this
   690    707   cases.</p></desc>
   691    708           </commanddef>
   692    709         </commandlist>
   693    710       </section>
   694    711   
   695    712       <section>
................................................................................
   710    727   set.</p>
   711    728   
   712    729         <p>If a callback script returns a &quot;continue&quot; error code then
   713    730   processing of the current element, and its children, ceases for every handler
   714    731   script out of this Tcl handler set and processing continues with the next
   715    732   (sibling) element. This does not influence any other handler set.</p>
   716    733   
          734  +      <p>If a callback script returns a &quot;return&quot; error
          735  +code then parsing is canceled altogether, but no error is raised.</p>
          736  +
   717    737       </section>
   718    738   
   719    739       <seealso>
   720    740         <ref>expatapi</ref>
   721    741         <ref>tdom</ref>
   722    742       </seealso>
   723    743   
   724    744       <keywords>
   725    745         <keyword>SAX</keyword>
          746  +      <keyword>push</keyword>
          747  +      <keyword>pushparser</keyword>
   726    748       </keywords>
   727    749     </manpage>
   728    750   
   729    751   
   730    752   
   731    753     

Changes to doc/expatapi.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <div class="navbar" align="center">
     7         -<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>
            7  +<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>
     8      8   </div><hr class="navsep">
     9      9   </div><div class="body">
    10         -    <h2><a name="SECTnode8831">NAME</a></h2><p class="namesection">
           10  +    <h2><a name="SECTid0x1e7b920">NAME</a></h2><p class="namesection">
    11     11   <b class="names">CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
    12     12            CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo - </b><br>Functions to create, install and remove expat parser object
    13     13   extensions.</p>
    14         -  <h2><a name="SECTnode8840">SYNOPSIS</a></h2><pre class="syntax">#include &lt;tclexpat.h&gt;
           14  +  <h2><a name="SECTid0x1d90950">SYNOPSIS</a></h2><pre class="syntax">#include &lt;tclexpat.h&gt;
    15     15   
    16     16   int 
    17     17   <b class="fun">CheckExpatParserObj</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-nameObj"><i>nameObj</i></a>)  
    18     18   
    19     19   int
    20     20   <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>)
    21     21   
................................................................................
    31     31   void*
    32     32   <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>)
    33     33   
    34     34   TclGenExpatInfo*
    35     35   <b class="fun">GetExpatInfo</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-expatObj"><i>expatObj</i></a>)
    36     36   </pre>
    37     37   
    38         -  <h2><a name="SECTnode8918">ARGUMENTS</a></h2><div class="arglist"><table width="100%" rules="none" cellpadding="5%">
           38  +  <h2><a name="SECTid0x1eef570">ARGUMENTS</a></h2><div class="arglist"><table width="100%" rules="none" cellpadding="5%">
    39     39   <thead><tr class="heading">
    40     40   <th width="20%">Type</th><th width="70%">Name</th><th width="10%">Mode</th>
    41     41   </tr></thead><tr class="syntax">
    42     42   <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>
    43     43   </tr><tr class="desc">
    44         -<td class="padding" width="20%"> </td><td class="argdesc" width="80%" align="left" colspan="2">Interpreter with the expat parser object.</td>
           44  +<td class="padding" width="20%"> </td><td class="argdesc" width="80%" align="left" colspan="2">Interpreter with the expat parser object.</td>
    45     45   </tr><tr class="syntax">
    46     46   <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>
    47     47   </tr><tr class="desc">
    48         -<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>
           48  +<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>
    49     49   </tr><tr class="syntax">
    50     50   <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>
    51     51   </tr><tr class="desc">
    52         -<td class="padding" width="20%"> </td><td class="argdesc" width="80%" align="left" colspan="2">Identifier of the handler set.</td>
           52  +<td class="padding" width="20%"> </td><td class="argdesc" width="80%" align="left" colspan="2">Identifier of the handler set.</td>
    53     53   </tr><tr class="syntax">
    54     54   <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>
    55     55   </tr><tr class="desc">
    56         -<td class="padding" width="20%"> </td><td class="argdesc" width="80%" align="left" colspan="2">Pointer to a C handler set.</td>
           56  +<td class="padding" width="20%"> </td><td class="argdesc" width="80%" align="left" colspan="2">Pointer to a C handler set.</td>
    57     57   </tr><tr class="syntax">
    58     58   <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>
    59     59   </tr><tr class="desc">
    60         -<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>
           60  +<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>
    61     61   </tr>
    62     62   </table></div>
    63     63   
    64         -  <h2><a name="SECTnode8999">DESCRIPTION</a></h2><p>The functions described in this manual allows to add C level coded event
           64  +  <h2><a name="SECTid0x1ef1660">DESCRIPTION</a></h2><p>The functions described in this manual allows one to add C level coded event
    65     65   handler to an tDOM Tcl expat parser objects. A tDOM Tcl expat parser object is
    66     66   able to have several Tcl scripts and C functions associated with an specific
    67     67   event. If the event occurs, first the Tcl scripts then the C functions
    68     68   associated with the event are called in turn.</p><p>A tDOM Tcl expat parser extension is an ordinary Tcl extension and loaded
    69     69   like every other Tcl extension. It must install at least one new Tcl Level
    70     70   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">
    71     71   typedef struct CHandlerSet {
    72     72       struct CHandlerSet *nextHandlerSet;
    73     73       char *name;                     /* refname of the handler set */
    74     74       int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */
    75     75   
    76     76       void *userData;                 /* Handler set specific Data Structure;
    77         -                                       the C handler set extention has to
           77  +                                       the C handler set extension has to
    78     78                                          malloc the needed structure in his
    79     79                                          init func and has to provide a
    80     80                                          cleanup func (to free it). */
    81     81   
    82     82       CHandlerSet_userDataReset        resetProc;
    83     83       CHandlerSet_userDataFree         freeProc;
    84     84   
................................................................................
   100    100       XML_NotationDeclHandler          notationcommand;
   101    101       /* C func for external entity */
   102    102       XML_ExternalEntityRefHandler     externalentitycommand;
   103    103       /* C func for unknown encoding */
   104    104       XML_UnknownEncodingHandler       unknownencodingcommand;
   105    105       /* C func for comments */
   106    106       XML_CommentHandler               commentCommand;
   107         -    /* C func for &quot;not standalone&quot; docs */
          107  +    /* C func for "not standalone" docs */
   108    108       XML_NotStandaloneHandler         notStandaloneCommand;
   109    109       /* C func for CDATA section start */
   110    110       XML_StartCdataSectionHandler     startCdataSectionCommand;
   111    111       /* C func for CDATA section end */
   112    112       XML_EndCdataSectionHandler       endCdataSectionCommand;
   113    113       /* C func for !ELEMENT decl's */
   114    114       XML_ElementDeclHandler           elementDeclCommand;
................................................................................
   128    128   initialized to NULL by CHandlerSetCreate).</p><p>The <i class="m">name</i> of this structure is used to identify the handler set.
   129    129   </p><p>If the flag <i class="m">ignoreWhiteCDATAs</i> is set, element content which
   130    130   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
   131    131   event handler functions are called with this pointer as userData argument.
   132    132   </p><p>
   133    133   <i class="m">resetProc</i> and <i class="m">freeProc</i> must have arguments that match the
   134    134   type</p><pre class="syntax">void (Tcl_Interp *interp, void *userData)</pre><p>
   135         -<i class="m">resetProc</i> is called in case the parser is reseted with
          135  +<i class="m">resetProc</i> is called in case the parser is reset with
   136    136   <tt class="samp">&lt;parserObj&gt; reset</tt> and should do any necessary cleanup and
   137    137   reinitializing to prepare the C handler set for a new XML document. The
   138    138   <i class="m">freeProc</i> is called, if the parser is deleted and should do memory
   139    139   cleanup etc.  </p><p> <i class="m">CHandlerSetCreate</i> create a C handler set, gives it the name
   140    140   <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
   141    141   <i class="m">expatObj</i>. The parser has to be a tDOM Tcl expat parser object in the
   142    142   interpreter <i class="m">interp</i>. The name of the C handler set has to be unique for
................................................................................
   154    154   parser object in the interpreter <i class="m">interp</i>, otherwise it returns
   155    155   0. Example:</p><pre class="example">
   156    156   int
   157    157   TclExampleObjCmd(dummy, interp, objc, objv)
   158    158        ClientData dummy;
   159    159        Tcl_Interp *interp;
   160    160        int objc;
   161         -     Tcl_Obj *CONST objv[];
          161  +     Tcl_Obj *const objv[];
   162    162   {
   163    163       char          *method;
   164    164       CHandlerSet   *handlerSet;
   165    165       int            methodIndex, result;
   166    166       simpleCounter *counter;
   167    167       
   168    168   
   169    169       static char *exampleMethods[] = {
   170         -        &quot;enable&quot;, &quot;getresult&quot;, &quot;remove&quot;,
          170  +        "enable", "getresult", "remove",
   171    171           NULL
   172    172       };
   173    173       enum exampleMethod {
   174    174           m_enable, m_getresult, m_remove
   175    175       };
   176    176   
   177    177       if (objc != 3) {
   178    178           Tcl_WrongNumArgs (interp, 1, objv, example_usage);
   179    179           return TCL_ERROR;
   180    180       }
   181    181   
   182    182       if (!CheckExpatParserObj (interp, objv[1])) {
   183         -        Tcl_SetResult (interp, &quot;First argument has to be a expat parser object&quot;, NULL);
          183  +        Tcl_SetResult (interp, "First argument has to be a expat parser object", NULL);
   184    184           return TCL_ERROR;
   185    185       }
   186    186       /* ... */
   187    187   </pre><p> <i class="m">CHandlerSetGet</i> returns a pointer to the C handler Set referenced
   188    188   by the name <i class="m">handlerSetName</i> of the parser object
   189    189   <i class="m">expatObj</i>. <i class="m">expatObj</i> has to be an expat parser object in the
   190    190   interpreter <i class="m">interp</i>. Returns NULL in case of error.</p><p>
................................................................................
   195    195   TclGenExpatInfo structure of the tDOM Tcl expat parser object
   196    196   <i class="m">expatObj</i>. The <i class="m">expatObj</i> has to be a tDOM Tcl expat parser object
   197    197   in the interpreter <i class="m">interp</i>. This is most useful, to set the application
   198    198   status of the parser object.</p><p>See the simple but full functionally example in the extensions/example
   199    199   dir or the more complex example tnc in the extensions/tnc dir (a simple DTD
   200    200   validation extension).</p>
   201    201   
   202         -  <h2><a name="SECTnode9184">SEE ALSO</a></h2><p class="seealso"><a href="expat.html">expat</a></p>
          202  +  <h2><a name="SECTid0x1ea6080">SEE ALSO</a></h2><p class="seealso">expat</p>
   203    203   
   204         -  <h2><a name="SECTnode9190">KEYWORDS</a></h2><p class="keywords"><a class="keyword" href="keyword-index.html#KW-Chandlerset">C handler set</a></p>
   205         -</div><div class="footer">
   206         -<hr class="navsep"><!-- footer.html: Standard navigational footer --><div class="navbar" align="center">
   207         -	<a class="navaid" href="index.html">Table of Contents</a>
   208         - ·	<a class="navaid" href="category-index.html">Index</a>
   209         - ·	<a class="navaid" href="keyword-index.html">Keywords</a>
   210         -</div>
          204  +  <h2><a name="SECTid0x1ea6320">KEYWORDS</a></h2><p class="keywords"><a class="keyword" href="keyword-index.html#KW-Chandlerset">C handler set</a></p>
          205  +</div><hr class="navsep"><div class="navbar" align="center">
          206  +<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>
   211    207   </div>
   212    208   </body>
   213    209   </html>

Changes to doc/expatapi.n.

   200    200   .AP CHandlerSet "*handlerSet" in
   201    201   Pointer to a C handler set.
   202    202   .AP Tcl_Obj "*nameObj" ""
   203    203   A Tcl Object containing the name of a expat parser object
   204    204   .BE
   205    205   .SH DESCRIPTION
   206    206   .PP
   207         -The functions described in this manual allows to add C level coded event
          207  +The functions described in this manual allows one to add C level coded event
   208    208   handler to an tDOM Tcl expat parser objects. A tDOM Tcl expat parser object is
   209    209   able to have several Tcl scripts and C functions associated with an specific
   210    210   event. If the event occurs, first the Tcl scripts then the C functions
   211    211   associated with the event are called in turn.
   212    212   .PP
   213    213   A tDOM Tcl expat parser extension is an ordinary Tcl extension and loaded
   214    214   like every other Tcl extension. It must install at least one new Tcl Level
................................................................................
   219    219   
   220    220   typedef struct CHandlerSet {
   221    221       struct CHandlerSet *nextHandlerSet;
   222    222       char *name;                     /* refname of the handler set */
   223    223       int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */
   224    224   
   225    225       void *userData;                 /* Handler set specific Data Structure;
   226         -                                       the C handler set extention has to
          226  +                                       the C handler set extension has to
   227    227                                          malloc the needed structure in his
   228    228                                          init func and has to provide a
   229    229                                          cleanup func (to free it). */
   230    230   
   231    231       CHandlerSet_userDataReset        resetProc;
   232    232       CHandlerSet_userDataFree         freeProc;
   233    233   
................................................................................
   289    289   .PP
   290    290   \&\fIresetProc\fR and \fIfreeProc\fR must have arguments that match the
   291    291   type
   292    292   .CS
   293    293   void (Tcl_Interp *interp, void *userData)
   294    294   .CE
   295    295   .PP
   296         -\&\fIresetProc\fR is called in case the parser is reseted with
          296  +\&\fIresetProc\fR is called in case the parser is reset with
   297    297   \&\fB<parserObj> reset\fR and should do any necessary cleanup and
   298    298   reinitializing to prepare the C handler set for a new XML document. The
   299    299   \&\fIfreeProc\fR is called, if the parser is deleted and should do memory
   300    300   cleanup etc.
   301    301   .PP
   302    302   \&\fICHandlerSetCreate\fR create a C handler set, gives it the name
   303    303   \&\fIname\fR and initializes any other element with NULL.
................................................................................
   324    324   .CS
   325    325   
   326    326   int
   327    327   TclExampleObjCmd(dummy, interp, objc, objv)
   328    328        ClientData dummy;
   329    329        Tcl_Interp *interp;
   330    330        int objc;
   331         -     Tcl_Obj *CONST objv[];
          331  +     Tcl_Obj *const objv[];
   332    332   {
   333    333       char          *method;
   334    334       CHandlerSet   *handlerSet;
   335    335       int            methodIndex, result;
   336    336       simpleCounter *counter;
   337    337       
   338    338   

Changes to doc/expatapi.xml.

     1         -  <manpage id="expatapi" cat="fun" title="expatapi">
            1  +<manpage id="expatapi" cat="fun" title="expatapi">
     2      2       <namesection>
     3      3         <name>CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
     4      4            CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo</name>
     5      5   
     6      6         <desc>Functions to create, install and remove expat parser object
     7      7   extensions.</desc>
     8      8       </namesection>
................................................................................
    65     65           <desc>A Tcl Object containing the name of a expat parser object</desc>
    66     66         </argdef>
    67     67       </arglist>
    68     68     </section>
    69     69   
    70     70     <section>
    71     71       <title>DESCRIPTION</title>
    72         -<p>The functions described in this manual allows to add C level coded event
           72  +<p>The functions described in this manual allows one to add C level coded event
    73     73   handler to an tDOM Tcl expat parser objects. A tDOM Tcl expat parser object is
    74     74   able to have several Tcl scripts and C functions associated with an specific
    75     75   event. If the event occurs, first the Tcl scripts then the C functions
    76     76   associated with the event are called in turn.</p>  
    77     77   
    78     78   <p>A tDOM Tcl expat parser extension is an ordinary Tcl extension and loaded
    79     79   like every other Tcl extension. It must install at least one new Tcl Level
................................................................................
    84     84   <example>
    85     85   typedef struct CHandlerSet {
    86     86       struct CHandlerSet *nextHandlerSet;
    87     87       char *name;                     /* refname of the handler set */
    88     88       int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */
    89     89   
    90     90       void *userData;                 /* Handler set specific Data Structure;
    91         -                                       the C handler set extention has to
           91  +                                       the C handler set extension has to
    92     92                                          malloc the needed structure in his
    93     93                                          init func and has to provide a
    94     94                                          cleanup func (to free it). */
    95     95   
    96     96       CHandlerSet_userDataReset        resetProc;
    97     97       CHandlerSet_userDataFree         freeProc;
    98     98   
................................................................................
   156    156   event handler functions are called with this pointer as userData argument.
   157    157   </p>
   158    158   
   159    159       <p><m>resetProc</m> and <m>freeProc</m> must have arguments that match the
   160    160   type</p>
   161    161       <syntax>void (Tcl_Interp *interp, void *userData)</syntax>
   162    162   
   163         -    <p><m>resetProc</m> is called in case the parser is reseted with
          163  +    <p><m>resetProc</m> is called in case the parser is reset with
   164    164   <samp>&lt;parserObj&gt; reset</samp> and should do any necessary cleanup and
   165    165   reinitializing to prepare the C handler set for a new XML document. The
   166    166   <m>freeProc</m> is called, if the parser is deleted and should do memory
   167    167   cleanup etc.  </p>
   168    168   
   169    169       <p> <m>CHandlerSetCreate</m> create a C handler set, gives it the name
   170    170   <m>name</m> and initializes any other element with NULL.</p>
................................................................................
   191    191   
   192    192   <example>
   193    193   int
   194    194   TclExampleObjCmd(dummy, interp, objc, objv)
   195    195        ClientData dummy;
   196    196        Tcl_Interp *interp;
   197    197        int objc;
   198         -     Tcl_Obj *CONST objv[];
          198  +     Tcl_Obj *const objv[];
   199    199   {
   200    200       char          *method;
   201    201       CHandlerSet   *handlerSet;
   202    202       int            methodIndex, result;
   203    203       simpleCounter *counter;
   204    204       
   205    205   

Changes to doc/index.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <h1 class="title" align="center">tDOM manual: Contents</h1><p class="navaid" align="center">
     7         -<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>
            7  +<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>
     8      8   </p><hr class="navsep">
     9      9   </div><div class="body"><ul class="toc">
    10     10   <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
    11         -extensions.</a></li><li class="tocentry"><a href="tdomcmd.html">tdom - tdom is an expat parser object extension to create an in-memory
           11  +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
    12     12   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
    13     13   stream against the document DTD while parsing.</a></li>
    14     14   </ul></div><div class="footer">
    15     15   <hr class="navsep"><div class="navbar" align="center">
    16         -<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>
           16  +<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>
    17     17   </div>
    18     18   </div>
    19     19   </body>
    20     20   </html>

Changes to doc/keyword-index.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <h1 class="title" align="center">tDOM manual: Keywords</h1><p class="navaid" align="center">
     7         -<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>
            7  +<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>
     8      8   </p><hr class="navsep"><div class="navbar">
     9         -<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>
            9  +<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>
    10     10   </div><div class="body"><div class="table"><table width="100%">
    11     11   <tr class="header"><th colspan="2"><a name="KEYWORDS-C">Keywords: C</a></th></tr><tr class="row1">
    12     12   <td width="35%"><a name="KW-Chandlerset">C handler set</a></td><td width="65%">
    13         -<a href="expatapi.html">expatapi</a> · <a href="tdomcmd.html">tdom</a>
           13  +<a href="expatapi.html">expatapi</a> · <a href="tdomcmd.html">tdom</a>
    14     14   </td>
    15     15   </tr><tr class="row0">
    16     16   <td width="35%"><a name="KW-CheckExpatParserObj,CHandlerSetInstall,CHandlerSetRemove,CHandlerSetCreate,CHandlerSetGetUserData,GetExpatInfo">CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
    17     17            CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo</a></td><td width="65%"><a href="expatapi.html">expatapi</a></td>
    18     18   </tr><tr class="header"><th colspan="2"><a name="KEYWORDS-D">Keywords: D</a></th></tr><tr class="row1">
    19         -<td width="35%"><a name="KW-Document">Document</a></td><td width="65%">
    20         -<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a>
           19  +<td width="35%"><a name="KW-document">document</a></td><td width="65%">
           20  +<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a>
    21     21   </td>
    22     22   </tr><tr class="row0">
    23     23   <td width="35%"><a name="KW-documentelement">document element</a></td><td width="65%"><a href="domDoc.html">domDoc</a></td>
    24     24   </tr><tr class="row1">
    25     25   <td width="35%"><a name="KW-dom">dom</a></td><td width="65%">
    26         -<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a> · <a href="tdomcmd.html">tdom</a>
           26  +<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a> · <a href="tdomcmd.html">tdom</a>
    27     27   </td>
    28     28   </tr><tr class="row0">
    29     29   <td width="35%"><a name="KW-DOMnodecreation">DOM node creation</a></td><td width="65%"><a href="domDoc.html">domDoc</a></td>
    30     30   </tr><tr class="row1">
    31     31   <td width="35%"><a name="KW-domDoc">domDoc</a></td><td width="65%"><a href="domDoc.html">domDoc</a></td>
    32     32   </tr><tr class="row0">
    33     33   <td width="35%"><a name="KW-domNode">domNode</a></td><td width="65%"><a href="domNode.html">domNode</a></td>
................................................................................
    35     35   <td width="35%"><a name="KW-DTD">DTD</a></td><td width="65%"><a href="tnc.html">tnc</a></td>
    36     36   </tr><tr class="header"><th colspan="2"><a name="KEYWORDS-E">Keywords: E</a></th></tr><tr class="row0">
    37     37   <td width="35%"><a name="KW-expat">expat</a></td><td width="65%"><a href="expat.html">expat</a></td>
    38     38   </tr><tr class="row1">
    39     39   <td width="35%"><a name="KW-expatapi">expatapi</a></td><td width="65%"><a href="expatapi.html">expatapi</a></td>
    40     40   </tr><tr class="header"><th colspan="2"><a name="KEYWORDS-N">Keywords: N</a></th></tr><tr class="row0">
    41     41   <td width="35%"><a name="KW-node">node</a></td><td width="65%">
    42         -<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a>
           42  +<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a>
    43     43   </td>
    44     44   </tr><tr class="header"><th colspan="2"><a name="KEYWORDS-P">Keywords: P</a></th></tr><tr class="row1">
    45     45   <td width="35%"><a name="KW-parsing">parsing</a></td><td width="65%">
    46         -<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a>
           46  +<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a> · <a href="pullparser.html">pullparser</a>
    47     47   </td>
           48  +</tr><tr class="row0">
           49  +<td width="35%"><a name="KW-pull">pull</a></td><td width="65%"><a href="pullparser.html">pullparser</a></td>
           50  +</tr><tr class="row1">
           51  +<td width="35%"><a name="KW-pullparser">pullparser</a></td><td width="65%"><a href="pullparser.html">pullparser</a></td>
           52  +</tr><tr class="row0">
           53  +<td width="35%"><a name="KW-push">push</a></td><td width="65%"><a href="expat.html">expat</a></td>
           54  +</tr><tr class="row1">
           55  +<td width="35%"><a name="KW-pushparser">pushparser</a></td><td width="65%"><a href="expat.html">expat</a></td>
    48     56   </tr><tr class="header"><th colspan="2"><a name="KEYWORDS-S">Keywords: S</a></th></tr><tr class="row0">
    49     57   <td width="35%"><a name="KW-SAX">SAX</a></td><td width="65%">
    50         -<a href="expat.html">expat</a> · <a href="tdomcmd.html">tdom</a>
           58  +<a href="expat.html">expat</a> · <a href="tdomcmd.html">tdom</a>
    51     59   </td>
    52     60   </tr><tr class="header"><th colspan="2"><a name="KEYWORDS-T">Keywords: T</a></th></tr><tr class="row1">
    53     61   <td width="35%"><a name="KW-tdom">tdom</a></td><td width="65%"><a href="tdomcmd.html">tdom</a></td>
    54     62   </tr><tr class="row0">
    55         -<td width="35%"><a name="KW-tdomcmd">tdomcmd</a></td><td width="65%"><a href="tdomcmd.html">tdom</a></td>
           63  +<td width="35%"><a name="KW-tDOM::pullparser">tDOM::pullparser</a></td><td width="65%"><a href="pullparser.html">pullparser</a></td>
    56     64   </tr><tr class="row1">
           65  +<td width="35%"><a name="KW-tdomcmd">tdomcmd</a></td><td width="65%"><a href="tdomcmd.html">tdom</a></td>
           66  +</tr><tr class="row0">
    57     67   <td width="35%"><a name="KW-tnc">tnc</a></td><td width="65%"><a href="tnc.html">tnc</a></td>
    58         -</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-V">Keywords: V</a></th></tr><tr class="row0">
           68  +</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-V">Keywords: V</a></th></tr><tr class="row1">
    59     69   <td width="35%"><a name="KW-Validation">Validation</a></td><td width="65%"><a href="tnc.html">tnc</a></td>
    60         -</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-X">Keywords: X</a></th></tr><tr class="row1">
           70  +</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-X">Keywords: X</a></th></tr><tr class="row0">
    61     71   <td width="35%"><a name="KW-XML">XML</a></td><td width="65%">
    62         -<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a>
           72  +<a href="dom.html">dom</a> · <a href="domNode.html">domNode</a> · <a href="pullparser.html">pullparser</a>
    63     73   </td>
    64         -</tr><tr class="row0">
           74  +</tr><tr class="row1">
    65     75   <td width="35%"><a name="KW-xml::parser">xml::parser</a></td><td width="65%"><a href="expat.html">expat</a></td>
    66     76   </tr>
    67     77   </table></div></div><div class="footer">
    68     78   <hr class="navsep"><div class="navbar" align="center">
    69         -<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>
           79  +<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>
    70     80   </div>
    71     81   </div>
    72     82   </body>
    73     83   </html>

Changes to doc/manpage.css.

     1      1   /*
     2         - * $Id$
            2  + * $Id: manpage.css,v 1.4 2002/06/20 00:44:17 jenglish Exp $
     3      3    * Author: 	Joe English, <jenglish@flightab.com>
     4      4    * Created: 	26 Jun 2000
     5      5    * Description:	CSS stylesheet for TCL man pages
     6      6    */
     7      7   
     8      8   HTML {
     9      9       background: 	#FFFFFF;

Added doc/pullparser.html.

            1  +<html>
            2  +<head>
            3  +<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">
            4  +</head><body>
            5  +<div class="header">
            6  +<div class="navbar" align="center">
            7  +<a href="#SECTid0x11bc970">NAME</a> · <a href="#SECTid0x10a6540">SYNOPSIS</a> · <a href="#SECTid0x10bbbc0">DESCRIPTION </a> · <a href="#SECTid0x11e0cb0">KEYWORDS</a>
            8  +</div><hr class="navsep">
            9  +</div><div class="body">
           10  +  <h2><a name="SECTid0x11bc970">NAME</a></h2><p class="namesection">
           11  +<b class="names">tdom::pullparser - </b><br>Create an XML pull parser command</p>
           12  +
           13  +  <h2><a name="SECTid0x10a6540">SYNOPSIS</a></h2><pre class="syntax">package require tdom
           14  +
           15  +    <b class="cmd">tdom::pullparser</b> <i class="m">cmdName</i>  ? -ignorewhitecdata ? 
           16  +    </pre>
           17  +
           18  +  <h2><a name="SECTid0x10bbbc0">DESCRIPTION </a></h2><p>This command creates XML pull parser commands with a simple
           19  +    API, along the lines of a simple StAX parser. After creation,
           20  +    you've to set an input source, to do anything useful with the pull
           21  +    parser. For this see the methods <i class="m">input</i>, <i class="m">inputchannel</i>
           22  +    and <i class="m">inputfile</i>.</p><p>The parser has always a <i class="m">state</i>. You start parsing the XML
           23  +    data until some next state, do what has to be done and skip again
           24  +    to the next state. XML well-formedness errors along the way will
           25  +    be reported as TCL_ERROR with additional info in the error
           26  +    message.</p><p>The pull parsers don't follow external entities and are XML
           27  +    1.0 only, they know nothing about XML Namespaces. You get the tags
           28  +    and attribute names as in the source. You aren't noticed about
           29  +    comments, processing instructions and external entities; they are
           30  +    silently ignored for you. CDATA Sections are handled as if their
           31  +    content would have been provided without using a CDATA Section.
           32  +    </p><p>On the brighter side is that character entity and attribute
           33  +    default declarations in the internal subset are respected (because
           34  +    of using expat as underlying parser). It is probably somewhat
           35  +    faster than a comperable implementation with the SAX interface.
           36  +    It's a nice programming model. It's a slim interface.
           37  +    </p><p>If the option <i class="m">-ignorewhitecdata</i> is given, the created
           38  +    XML pull parser command will ignore any white space only (' ', \t,
           39  +    \n and \r) text content between START_TAG and START_TAG / END_TAG.
           40  +    The parser won't stop at such input and will create TEXT state
           41  +    events only for not white space only text. </p><p>Not all methods are valid in every state. The parser will raise
           42  +    TCL_ERROR if a method is called in a state the method isn't valid
           43  +    for. Valid methods of the created commands are:</p><dl class="commandlist">
           44  +      
           45  +        <dt><b class="method">state</b></dt>
           46  +        <dd>This method is valid in all parser states. The
           47  +        possible return values and their meanings are:
           48  +        <ul>
           49  +            <li>
           50  +<i class="m">READY</i> - The parser is created or reset, but no
           51  +            input is set.</li>
           52  +            <li>
           53  +<i class="m">START_DOCUMENT</i> - Input is set, parser is ready
           54  +            to start parsing.</li>
           55  +            <li>
           56  +<i class="m">START_TAG</i> - Parser has stopped parsing at a
           57  +            start tag.</li>
           58  +            <li>
           59  +<i class="m">END_TAG</i> - Parser has stopped parsing at an end tag</li>
           60  +            <li>
           61  +<i class="m">TEXT</i> - Parser has stopped parsing to report
           62  +            text between tags.</li>
           63  +            <li>
           64  +<i class="m">END_DOKUMENT</i> - Parser has finished parsing
           65  +            without error.</li>
           66  +            <li>
           67  +<i class="m">PARSE_ERROR</i> - Parser stopped parsing at XML
           68  +            error in input.</li>
           69  +        </ul>
           70  +        </dd>
           71  +      
           72  +
           73  +      
           74  +        <dt>
           75  +<b class="method">input</b> <i class="m">data</i>
           76  +</dt>
           77  +        <dd>This method is only valid in state <i class="m">READY</i>. It
           78  +        prepares the parser to use <i class="m">data</i> as XML input to parse
           79  +        and switches the parser into state START_DOCUMENT.</dd>
           80  +      
           81  +
           82  +      
           83  +        <dt>
           84  +<b class="method">inputchannel</b> <i class="m">channel</i>
           85  +</dt>
           86  +        <dd>This method is only valid in state <i class="m">READY</i>. It
           87  +        prepares the parser to read the XML input to parse out of
           88  +        <i class="m">channel</i> and switches the parser into state START_DOCUMENT.</dd>
           89  +      
           90  +
           91  +      
           92  +        <dt>
           93  +<b class="method">inputfile</b> <i class="m">filename</i>
           94  +</dt>
           95  +        <dd>This method is only valid in state <i class="m">READY</i>. It
           96  +        open <i class="m">filename</i> and prepares the parser to read the XML
           97  +        input to parse out of that file. The method returns TCL_ERROR,
           98  +        if the file could not be open in read mode. Otherwise it
           99  +        switches the parser into state START_DOCUMENT.</dd>
          100  +      
          101  +
          102  +      
          103  +        <dt><b class="method">next</b></dt>
          104  +        <dd>This method is valid in state <i class="m">START_DOCUMENT</i>,
          105  +        <i class="m">START_TAG</i>, <i class="m">END_TAG</i> and <i class="m">TEXT</i>. It continues
          106  +        parsing of the XML input until the next event, which it will
          107  +        return.</dd>
          108  +      
          109  +
          110  +      
          111  +        <dt><b class="method">tag</b></dt>
          112  +        <dd>This method is only valid in states <i class="m">START_TAG</i> and
          113  +        <i class="m">END_TAG</i>. It returns the tag name of the current start
          114  +        or end tag.</dd>
          115  +      
          116  +
          117  +      
          118  +        <dt><b class="method">attributes</b></dt>
          119  +        <dd>This method is only valid in state <i class="m">START_TAG</i>. It
          120  +        returns all attributes of the element in a name value list.</dd>
          121  +      
          122  +
          123  +      
          124  +        <dt><b class="method">text</b></dt>
          125  +        <dd>This method is only valid in state <i class="m">TEXT</i>. It
          126  +        returns the character data of the event. There will be always
          127  +        at most one TEXT event between START_TAG and the next
          128  +        START_TAG or END_TAG event.</dd>
          129  +      
          130  +
          131  +      
          132  +        <dt><b class="method">skip</b></dt>
          133  +        <dd>This method is only valid in state <i class="m">START_TAG</i>. It
          134  +        skips to the corresponding end tag and ignores all events (but
          135  +        not XML parsing errors) on the way and returns the new state
          136  +        END_TAG.</dd>
          137  +      
          138  +
          139  +      
          140  +        <dt>
          141  +<b class="method">find-element</b> <i class="m">tagname</i>
          142  +</dt>
          143  +        <dd>This method is only valid in states
          144  +        <i class="m">START_DOCUMENT</i>, <i class="m">START_TAG</i> and <i class="m">END_TAG</i>. It
          145  +        skips forward until the next element start tag with tag name
          146  +        <i class="m">tagname</i> and returns the new start START_TAG. If there
          147  +        isn't such an element the parser stops at the end of the input
          148  +        and returns END_DOCUMENT.</dd>
          149  +      
          150  +
          151  +      
          152  +        <dt><b class="method">reset</b></dt>
          153  +        <dd>This method is valid in all parser states. It resets the
          154  +        parser into READY state and returns that.</dd>
          155  +      
          156  +
          157  +      
          158  +        <dt><b class="method">delete</b></dt>
          159  +        <dd>This method is valid in all parser states. It deletes
          160  +        the parser command.</dd>
          161  +      
          162  +    </dl><p>Miscellaneous methods:</p><dl class="commandlist">
          163  +      
          164  +        <dt><b class="method">line</b></dt>
          165  +        <dd>This method is valid in all parser states except READY
          166  +        and TEXT. It returns the line number of the parsing
          167  +        position.</dd>
          168  +      
          169  +
          170  +      
          171  +        <dt><b class="method">line</b></dt>
          172  +        <dd>This method is valid in all parser states except READY
          173  +        and TEXT. It returns the offset, from the beginning of the
          174  +        current line, of the parsing position.</dd>
          175  +      
          176  +    </dl>
          177  +
          178  +  <h2><a name="SECTid0x11e0cb0">KEYWORDS</a></h2><p class="keywords">
          179  +<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>
          180  +</p>
          181  +</div><hr class="navsep"><div class="navbar" align="center">
          182  +<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>
          183  +</div>
          184  +</body>
          185  +</html>

Added doc/pullparser.n.

            1  +'\"
            2  +'\" Generated from pullparser.xml
            3  +'\"
            4  +'\" BEGIN man.macros
            5  +.if t .wh -1.3i ^B
            6  +.nr ^l \n(.l
            7  +.ad b
            8  +.de AP
            9  +.ie !"\\$4"" .TP \\$4
           10  +.el \{\
           11  +.   ie !"\\$2"" .TP \\n()Cu
           12  +.   el          .TP 15
           13  +.\}
           14  +.ta \\n()Au \\n()Bu
           15  +.ie !"\\$3"" \{\
           16  +\&\\$1	\\fI\\$2\\fP	(\\$3)
           17  +.\".b
           18  +.\}
           19  +.el \{\
           20  +.br
           21  +.ie !"\\$2"" \{\
           22  +\&\\$1	\\fI\\$2\\fP
           23  +.\}
           24  +.el \{\
           25  +\&\\fI\\$1\\fP
           26  +.\}
           27  +.\}
           28  +..
           29  +.de AS
           30  +.nr )A 10n
           31  +.if !"\\$1"" .nr )A \\w'\\$1'u+3n
           32  +.nr )B \\n()Au+15n
           33  +.\"
           34  +.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
           35  +.nr )C \\n()Bu+\\w'(in/out)'u+2n
           36  +..
           37  +.AS Tcl_Interp Tcl_CreateInterp in/out
           38  +.de BS
           39  +.br
           40  +.mk ^y
           41  +.nr ^b 1u
           42  +.if n .nf
           43  +.if n .ti 0
           44  +.if n \l'\\n(.lu\(ul'
           45  +.if n .fi
           46  +..
           47  +.de BE
           48  +.nf
           49  +.ti 0
           50  +.mk ^t
           51  +.ie n \l'\\n(^lu\(ul'
           52  +.el \{\
           53  +.\"	Draw four-sided box normally, but don't draw top of
           54  +.\"	box if the box started on an earlier page.
           55  +.ie !\\n(^b-1 \{\
           56  +\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
           57  +.\}
           58  +.el \}\
           59  +\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
           60  +.\}
           61  +.\}
           62  +.fi
           63  +.br
           64  +.nr ^b 0
           65  +..
           66  +.de VS
           67  +.if !"\\$2"" .br
           68  +.mk ^Y
           69  +.ie n 'mc \s12\(br\s0
           70  +.el .nr ^v 1u
           71  +..
           72  +.de VE
           73  +.ie n 'mc
           74  +.el \{\
           75  +.ev 2
           76  +.nf
           77  +.ti 0
           78  +.mk ^t
           79  +\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
           80  +.sp -1
           81  +.fi
           82  +.ev
           83  +.\}
           84  +.nr ^v 0
           85  +..
           86  +.de ^B
           87  +.ev 2
           88  +'ti 0
           89  +'nf
           90  +.mk ^t
           91  +.if \\n(^b \{\
           92  +.\"	Draw three-sided box if this is the box's first page,
           93  +.\"	draw two sides but no top otherwise.
           94  +.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
           95  +.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
           96  +.\}
           97  +.if \\n(^v \{\
           98  +.nr ^x \\n(^tu+1v-\\n(^Yu
           99  +\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
          100  +.\}
          101  +.bp
          102  +'fi
          103  +.ev
          104  +.if \\n(^b \{\
          105  +.mk ^y
          106  +.nr ^b 2
          107  +.\}
          108  +.if \\n(^v \{\
          109  +.mk ^Y
          110  +.\}
          111  +..
          112  +.de DS
          113  +.RS
          114  +.nf
          115  +.sp
          116  +..
          117  +.de DE
          118  +.fi
          119  +.RE
          120  +.sp
          121  +..
          122  +.de SO
          123  +.SH "STANDARD OPTIONS"
          124  +.LP
          125  +.nf
          126  +.ta 5.5c 11c
          127  +.ft B
          128  +..
          129  +.de SE
          130  +.fi
          131  +.ft R
          132  +.LP
          133  +See the \\fBoptions\\fR manual entry for details on the standard options.
          134  +..
          135  +.de OP
          136  +.LP
          137  +.nf
          138  +.ta 4c
          139  +Command-Line Name:	\\fB\\$1\\fR
          140  +Database Name:	\\fB\\$2\\fR
          141  +Database Class:	\\fB\\$3\\fR
          142  +.fi
          143  +.IP
          144  +..
          145  +.de CS
          146  +.RS
          147  +.nf
          148  +.ta .25i .5i .75i 1i
          149  +.if t .ft C
          150  +..
          151  +.de CE
          152  +.fi
          153  +.if t .ft R
          154  +.RE
          155  +..
          156  +.de UL
          157  +\\$1\l'|0\(ul'\\$2
          158  +..
          159  +'\" END man.macros
          160  +.TH pullparser n "" Tcl ""
          161  +.BS
          162  +.SH NAME
          163  +tdom::pullparser \- Create an XML pull parser command
          164  +.SH SYNOPSIS
          165  +.nf
          166  +package require tdom
          167  +
          168  +    \fBtdom::pullparser\fP \fIcmdName\fR  \fR?\fP -ignorewhitecdata \fR?\fP 
          169  +    
          170  +.fi
          171  +.BE
          172  +.SH "DESCRIPTION "
          173  +.PP
          174  +This command creates XML pull parser commands with a simple
          175  +API, along the lines of a simple StAX parser. After creation,
          176  +you've to set an input source, to do anything useful with the pull
          177  +parser. For this see the methods \fIinput\fR, \fIinputchannel\fR
          178  +and \fIinputfile\fR.
          179  +.PP
          180  +The parser has always a \fIstate\fR. You start parsing the XML
          181  +data until some next state, do what has to be done and skip again
          182  +to the next state. XML well-formedness errors along the way will
          183  +be reported as TCL_ERROR with additional info in the error
          184  +message.
          185  +.PP
          186  +The pull parsers don't follow external entities and are XML
          187  +1.0 only, they know nothing about XML Namespaces. You get the tags
          188  +and attribute names as in the source. You aren't noticed about
          189  +comments, processing instructions and external entities; they are
          190  +silently ignored for you. CDATA Sections are handled as if their
          191  +content would have been provided without using a CDATA Section.
          192  +.PP
          193  +On the brighter side is that character entity and attribute
          194  +default declarations in the internal subset are respected (because
          195  +of using expat as underlying parser). It is probably somewhat
          196  +faster than a comperable implementation with the SAX interface.
          197  +It's a nice programming model. It's a slim interface.
          198  +.PP
          199  +If the option \fI-ignorewhitecdata\fR is given, the created
          200  +XML pull parser command will ignore any white space only (' ', \et,
          201  +\&\en and \er) text content between START_TAG and START_TAG / END_TAG.
          202  +The parser won't stop at such input and will create TEXT state
          203  +events only for not white space only text.
          204  +.PP
          205  +Not all methods are valid in every state. The parser will raise
          206  +TCL_ERROR if a method is called in a state the method isn't valid
          207  +for. Valid methods of the created commands are:
          208  +.TP
          209  +\&\fB\fBstate\fP
          210  +\&\fRThis method is valid in all parser states. The
          211  +possible return values and their meanings are:
          212  +.RS
          213  +.IP "\(bu"
          214  +\&\fIREADY\fR - The parser is created or reset, but no
          215  +input is set.
          216  +.IP "\(bu"
          217  +\&\fISTART_DOCUMENT\fR - Input is set, parser is ready
          218  +to start parsing.
          219  +.IP "\(bu"
          220  +\&\fISTART_TAG\fR - Parser has stopped parsing at a
          221  +start tag.
          222  +.IP "\(bu"
          223  +\&\fIEND_TAG\fR - Parser has stopped parsing at an end tag
          224  +.IP "\(bu"
          225  +\&\fITEXT\fR - Parser has stopped parsing to report
          226  +text between tags.
          227  +.IP "\(bu"
          228  +\&\fIEND_DOKUMENT\fR - Parser has finished parsing
          229  +without error.
          230  +.IP "\(bu"
          231  +\&\fIPARSE_ERROR\fR - Parser stopped parsing at XML
          232  +error in input.
          233  +.RE
          234  +.TP
          235  +\&\fB\fBinput\fP \fIdata\fB
          236  +\&\fRThis method is only valid in state \fIREADY\fR. It
          237  +prepares the parser to use \fIdata\fR as XML input to parse
          238  +and switches the parser into state START_DOCUMENT.
          239  +.TP
          240  +\&\fB\fBinputchannel\fP \fIchannel\fB
          241  +\&\fRThis method is only valid in state \fIREADY\fR. It
          242  +prepares the parser to read the XML input to parse out of
          243  +\&\fIchannel\fR and switches the parser into state START_DOCUMENT.
          244  +.TP
          245  +\&\fB\fBinputfile\fP \fIfilename\fB
          246  +\&\fRThis method is only valid in state \fIREADY\fR. It
          247  +open \fIfilename\fR and prepares the parser to read the XML
          248  +input to parse out of that file. The method returns TCL_ERROR,
          249  +if the file could not be open in read mode. Otherwise it
          250  +switches the parser into state START_DOCUMENT.
          251  +.TP
          252  +\&\fB\fBnext\fP
          253  +\&\fRThis method is valid in state \fISTART_DOCUMENT\fR,
          254  +\&\fISTART_TAG\fR, \fIEND_TAG\fR and \fITEXT\fR. It continues
          255  +parsing of the XML input until the next event, which it will
          256  +return.
          257  +.TP
          258  +\&\fB\fBtag\fP
          259  +\&\fRThis method is only valid in states \fISTART_TAG\fR and
          260  +\&\fIEND_TAG\fR. It returns the tag name of the current start
          261  +or end tag.
          262  +.TP
          263  +\&\fB\fBattributes\fP
          264  +\&\fRThis method is only valid in state \fISTART_TAG\fR. It
          265  +returns all attributes of the element in a name value list.
          266  +.TP
          267  +\&\fB\fBtext\fP
          268  +\&\fRThis method is only valid in state \fITEXT\fR. It
          269  +returns the character data of the event. There will be always
          270  +at most one TEXT event between START_TAG and the next
          271  +START_TAG or END_TAG event.
          272  +.TP
          273  +\&\fB\fBskip\fP
          274  +\&\fRThis method is only valid in state \fISTART_TAG\fR. It
          275  +skips to the corresponding end tag and ignores all events (but
          276  +not XML parsing errors) on the way and returns the new state
          277  +END_TAG.
          278  +.TP
          279  +\&\fB\fBfind-element\fP \fItagname\fB
          280  +\&\fRThis method is only valid in states
          281  +\&\fISTART_DOCUMENT\fR, \fISTART_TAG\fR and \fIEND_TAG\fR. It
          282  +skips forward until the next element start tag with tag name
          283  +\&\fItagname\fR and returns the new start START_TAG. If there
          284  +isn't such an element the parser stops at the end of the input
          285  +and returns END_DOCUMENT.
          286  +.TP
          287  +\&\fB\fBreset\fP
          288  +\&\fRThis method is valid in all parser states. It resets the
          289  +parser into READY state and returns that.
          290  +.TP
          291  +\&\fB\fBdelete\fP
          292  +\&\fRThis method is valid in all parser states. It deletes
          293  +the parser command.
          294  +.PP
          295  +Miscellaneous methods:
          296  +.TP
          297  +\&\fB\fBline\fP
          298  +\&\fRThis method is valid in all parser states except READY
          299  +and TEXT. It returns the line number of the parsing
          300  +position.
          301  +.TP
          302  +\&\fB\fBline\fP
          303  +\&\fRThis method is valid in all parser states except READY
          304  +and TEXT. It returns the offset, from the beginning of the
          305  +current line, of the parsing position.
          306  +.SH KEYWORDS
          307  +XML, pull, parsing

Added doc/pullparser.xml.

            1  +<manpage id="pullparser" cat="pullparser" title="pullparser">
            2  +  <namesection>
            3  +    <name>tdom::pullparser</name>
            4  +    <desc>Create an XML pull parser command</desc>
            5  +  </namesection>
            6  +
            7  +  <synopsis>
            8  +    <syntax>package require tdom
            9  +
           10  +    <cmd>tdom::pullparser</cmd> <m>cmdName</m> <o>-ignorewhitecdata</o>
           11  +    </syntax>
           12  +  </synopsis>
           13  +
           14  +  <section>
           15  +    <title>DESCRIPTION </title>    
           16  +    
           17  +    <p>This command creates XML pull parser commands with a simple
           18  +    API, along the lines of a simple StAX parser. After creation,
           19  +    you've to set an input source, to do anything useful with the pull
           20  +    parser. For this see the methods <m>input</m>, <m>inputchannel</m>
           21  +    and <m>inputfile</m>.</p>
           22  +
           23  +    <p>The parser has always a <m>state</m>. You start parsing the XML
           24  +    data until some next state, do what has to be done and skip again
           25  +    to the next state. XML well-formedness errors along the way will
           26  +    be reported as TCL_ERROR with additional info in the error
           27  +    message.</p>
           28  +
           29  +    <p>The pull parsers don't follow external entities and are XML
           30  +    1.0 only, they know nothing about XML Namespaces. You get the tags
           31  +    and attribute names as in the source. You aren't noticed about
           32  +    comments, processing instructions and external entities; they are
           33  +    silently ignored for you. CDATA Sections are handled as if their
           34  +    content would have been provided without using a CDATA Section.
           35  +    </p>
           36  +
           37  +    <p>On the brighter side is that character entity and attribute
           38  +    default declarations in the internal subset are respected (because
           39  +    of using expat as underlying parser). It is probably somewhat
           40  +    faster than a comperable implementation with the SAX interface.
           41  +    It's a nice programming model. It's a slim interface.
           42  +    </p>
           43  +
           44  +    <p>If the option <m>-ignorewhitecdata</m> is given, the created
           45  +    XML pull parser command will ignore any white space only (' ', \t,
           46  +    \n and \r) text content between START_TAG and START_TAG / END_TAG.
           47  +    The parser won't stop at such input and will create TEXT state
           48  +    events only for not white space only text. </p>
           49  +
           50  +    <p>Not all methods are valid in every state. The parser will raise
           51  +    TCL_ERROR if a method is called in a state the method isn't valid
           52  +    for. Valid methods of the created commands are:</p>
           53  +    <commandlist>
           54  +      <commanddef>
           55  +        <command><method>state</method></command>
           56  +        <desc>This method is valid in all parser states. The
           57  +        possible return values and their meanings are:
           58  +        <ul>
           59  +            <li><m>READY</m> - The parser is created or reset, but no
           60  +            input is set.</li>
           61  +            <li><m>START_DOCUMENT</m> - Input is set, parser is ready
           62  +            to start parsing.</li>
           63  +            <li><m>START_TAG</m> - Parser has stopped parsing at a
           64  +            start tag.</li>
           65  +            <li><m>END_TAG</m> - Parser has stopped parsing at an end tag</li>
           66  +            <li><m>TEXT</m> - Parser has stopped parsing to report
           67  +            text between tags.</li>
           68  +            <li><m>END_DOKUMENT</m> - Parser has finished parsing
           69  +            without error.</li>
           70  +            <li><m>PARSE_ERROR</m> - Parser stopped parsing at XML
           71  +            error in input.</li>
           72  +        </ul>
           73  +        </desc>
           74  +      </commanddef>
           75  +
           76  +      <commanddef>
           77  +        <command><method>input</method> <m>data</m></command>
           78  +        <desc>This method is only valid in state <m>READY</m>. It
           79  +        prepares the parser to use <m>data</m> as XML input to parse
           80  +        and switches the parser into state START_DOCUMENT.</desc>
           81  +      </commanddef>
           82  +
           83  +      <commanddef>
           84  +        <command><method>inputchannel</method> <m>channel</m></command>
           85  +        <desc>This method is only valid in state <m>READY</m>. It
           86  +        prepares the parser to read the XML input to parse out of
           87  +        <m>channel</m> and switches the parser into state START_DOCUMENT.</desc>
           88  +      </commanddef>
           89  +
           90  +      <commanddef>
           91  +        <command><method>inputfile</method> <m>filename</m></command>
           92  +        <desc>This method is only valid in state <m>READY</m>. It
           93  +        open <m>filename</m> and prepares the parser to read the XML
           94  +        input to parse out of that file. The method returns TCL_ERROR,
           95  +        if the file could not be open in read mode. Otherwise it
           96  +        switches the parser into state START_DOCUMENT.</desc>
           97  +      </commanddef>
           98  +
           99  +      <commanddef>
          100  +        <command><method>next</method></command>
          101  +        <desc>This method is valid in state <m>START_DOCUMENT</m>,
          102  +        <m>START_TAG</m>, <m>END_TAG</m> and <m>TEXT</m>. It continues
          103  +        parsing of the XML input until the next event, which it will
          104  +        return.</desc>
          105  +      </commanddef>
          106  +
          107  +      <commanddef>
          108  +        <command><method>tag</method></command>
          109  +        <desc>This method is only valid in states <m>START_TAG</m> and
          110  +        <m>END_TAG</m>. It returns the tag name of the current start
          111  +        or end tag.</desc>
          112  +      </commanddef>
          113  +
          114  +      <commanddef>
          115  +        <command><method>attributes</method></command>
          116  +        <desc>This method is only valid in state <m>START_TAG</m>. It
          117  +        returns all attributes of the element in a name value list.</desc>
          118  +      </commanddef>
          119  +
          120  +      <commanddef>
          121  +        <command><method>text</method></command>
          122  +        <desc>This method is only valid in state <m>TEXT</m>. It
          123  +        returns the character data of the event. There will be always
          124  +        at most one TEXT event between START_TAG and the next
          125  +        START_TAG or END_TAG event.</desc>
          126  +      </commanddef>
          127  +
          128  +      <commanddef>
          129  +        <command><method>skip</method></command>
          130  +        <desc>This method is only valid in state <m>START_TAG</m>. It
          131  +        skips to the corresponding end tag and ignores all events (but
          132  +        not XML parsing errors) on the way and returns the new state
          133  +        END_TAG.</desc>
          134  +      </commanddef>
          135  +
          136  +      <commanddef>
          137  +        <command><method>find-element</method> <m>tagname</m></command>
          138  +        <desc>This method is only valid in states
          139  +        <m>START_DOCUMENT</m>, <m>START_TAG</m> and <m>END_TAG</m>. It
          140  +        skips forward until the next element start tag with tag name
          141  +        <m>tagname</m> and returns the new start START_TAG. If there
          142  +        isn't such an element the parser stops at the end of the input
          143  +        and returns END_DOCUMENT.</desc>
          144  +      </commanddef>
          145  +
          146  +      <commanddef>
          147  +        <command><method>reset</method></command>
          148  +        <desc>This method is valid in all parser states. It resets the
          149  +        parser into READY state and returns that.</desc>
          150  +      </commanddef>
          151  +
          152  +      <commanddef>
          153  +        <command><method>delete</method></command>
          154  +        <desc>This method is valid in all parser states. It deletes
          155  +        the parser command.</desc>
          156  +      </commanddef>
          157  +    </commandlist>
          158  +
          159  +    <p>Miscellaneous methods:</p>
          160  +    <commandlist>
          161  +      <commanddef>
          162  +        <command><method>line</method></command>
          163  +        <desc>This method is valid in all parser states except READY
          164  +        and TEXT. It returns the line number of the parsing
          165  +        position.</desc>
          166  +      </commanddef>
          167  +
          168  +      <commanddef>
          169  +        <command><method>line</method></command>
          170  +        <desc>This method is valid in all parser states except READY
          171  +        and TEXT. It returns the offset, from the beginning of the
          172  +        current line, of the parsing position.</desc>
          173  +      </commanddef>
          174  +    </commandlist>
          175  +  </section>
          176  +
          177  +  <keywords>
          178  +    <keyword>XML</keyword>
          179  +    <keyword>pull</keyword>
          180  +    <keyword>parsing</keyword>
          181  +  </keywords>
          182  +</manpage>

Changes to doc/tDOM.xml.

     1      1   <!DOCTYPE manual PUBLIC "-//jenglish//DTD TMML 0.5//EN" "tmml.dtd" [
     2      2   <!ENTITY dom SYSTEM "dom.xml">
     3      3   <!ENTITY domDoc SYSTEM "domDoc.xml">
     4      4   <!ENTITY domNode SYSTEM "domNode.xml">
     5      5   <!ENTITY expat SYSTEM "expat.xml">
     6      6   <!ENTITY expatapi SYSTEM "expatapi.xml">
            7  +<!ENTITY pullparser SYSTEM "pullparser.xml">
     7      8   <!ENTITY tdomcmd SYSTEM "tdomcmd.xml">
     8      9   <!ENTITY tnc SYSTEM "tnc.xml">
     9     10   ]>
    10     11   <manual package="tDOM">
    11     12   <title>tDOM manual</title>
    12     13   
    13     14   &dom;
................................................................................
    15     16   &domDoc;
    16     17   
    17     18   &domNode;
    18     19   
    19     20   &expat;
    20     21   
    21     22   &expatapi;
           23  +
           24  +&pullparser;
    22     25   
    23     26   &tdomcmd;
    24     27   
    25     28   &tnc;
    26     29   
    27     30   </manual>
    28     31   

Changes to doc/tdomcmd.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <div class="navbar" align="center">
     7         -<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>
            7  +<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>
     8      8   </div><hr class="navsep">
     9      9   </div><div class="body">
    10         -    <h2><a name="SECTnode13446">NAME</a></h2><p class="namesection">
           10  +    <h2><a name="SECTid0x1e30200">NAME</a></h2><p class="namesection">
    11     11   <b class="names">tdom - </b><br>tdom is an expat parser object extension to create an in-memory
    12     12   DOM tree from the input while parsing.</p>
    13     13   
    14     14   
    15         -  <h2><a name="SECTnode13455">SYNOPSIS</a></h2><pre class="syntax">package require tdom
           15  +  <h2><a name="SECTid0x1f5add0">SYNOPSIS</a></h2><pre class="syntax">package require tdom
    16     16   
    17     17   set parser [expat]
    18     18   
    19     19   tdom $parser enable</pre>
    20     20   
    21         -  <h2><a name="SECTnode13461">DESCRIPTION</a></h2><p>
    22         -<i class="m">tdom</i> adds the C handler set &quot;tdom&quot; to an tcl expat
           21  +  <h2><a name="SECTid0x1e4db90">DESCRIPTION</a></h2><p>
           22  +<i class="m">tdom</i> adds the C handler set "tdom" to an tcl expat
    23     23   parser obj. This handler set builds an in-memory DOM tree out of the input,
    24     24   parsed by the parser. A DOM tree created this way behave exactly like a DOM
    25         -tree created by the &quot;dom&quot; command (see there). In fact, tdom is only
           25  +tree created by the "dom" command (see there). In fact, tdom is only
    26     26   another interface to the same functionality; it uses the code behind the
    27     27   <tt class="samp">dom</tt> code for building the DOM tree.</p><dl class="commandlist">
    28     28         
    29     29           <dt>
    30     30   <b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">enable</b>
    31     31   </dt>
    32     32   
................................................................................
    39     39           <dt>
    40     40   <b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">getdoc</b>
    41     41   </dt>
    42     42   
    43     43           <dd><p>Returns the DOM tree as domDoc (see there) object.</p></dd>
    44     44         
    45     45   
    46         -      
    47         -        <dt>
    48         -<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">setResultEncoding</b>
    49         -</dt>
    50         -
    51         -        <dd><p>See the method <tt class="samp">setResultEncoding</tt> of the
    52         -<b class="cmd"><a href="dom.html">dom</a></b> command.</p></dd>
    53         -      
    54         -
    55     46         
    56     47           <dt>
    57     48   <b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">setStoreLineColumn</b> ?<i class="m">boolean</i>?</dt>
    58     49   
    59     50           <dd><p>See the method <tt class="samp">setStoreLineColumn</tt> of the
    60         -<b class="cmd"><a href="dom.html">dom</a></b> command.</p></dd>
           51  +<b class="cmd">dom</b> command.</p></dd>
    61     52         
    62     53   
    63     54         
    64     55           <dt>
    65     56   <b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">remove</b>
    66     57   </dt>
    67     58   
................................................................................
    70     61         
    71     62   
    72     63         
    73     64           <dt>
    74     65   <b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">keepEmpties</b>
    75     66   </dt>
    76     67   
    77         -        <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>
           68  +        <dd><p>See the option <tt class="samp">-keepEmpties</tt> of the <b class="cmd">dom</b> command.</p></dd>
    78     69         
    79     70   
    80     71         
    81     72           <dt>
    82     73   <b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">setExternalEntityResolver</b> <i class="m">script</i>
    83     74   </dt>
    84     75           <dd></dd>
    85     76         
    86     77   
    87     78       </dl>
    88     79   
    89         -  <h2><a name="SECTnode13620">SEE ALSO</a></h2><p class="seealso">
    90         -<a href="dom.html">dom</a>, <a href="expat.html">expat</a>
    91         -</p>
           80  +  <h2><a name="SECTid0x1f20b70">SEE ALSO</a></h2><p class="seealso">dom, expat</p>
    92     81   
    93         -  <h2><a name="SECTnode13629">KEYWORDS</a></h2><p class="keywords">
           82  +  <h2><a name="SECTid0x1f20f00">KEYWORDS</a></h2><p class="keywords">
    94     83   <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>
    95     84   </p>
    96     85   
    97         -</div><div class="footer">
    98         -<hr class="navsep"><!-- footer.html: Standard navigational footer --><div class="navbar" align="center">
    99         -	<a class="navaid" href="index.html">Table of Contents</a>
   100         - ·	<a class="navaid" href="category-index.html">Index</a>
   101         - ·	<a class="navaid" href="keyword-index.html">Keywords</a>
   102         -</div>
           86  +</div><hr class="navsep"><div class="navbar" align="center">
           87  +<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>
   103     88   </div>
   104     89   </body>
   105     90   </html>

Changes to doc/tdomcmd.n.

   191    191   .TP
   192    192   \&\fB\fBtdom\fP \fIparserObj\fB \fBgetdoc\fP
   193    193   \&\fR
   194    194   .RS
   195    195   .PP
   196    196   Returns the DOM tree as domDoc (see there) object.
   197    197   .RE
   198         -.TP
   199         -\&\fB\fBtdom\fP \fIparserObj\fB \fBsetResultEncoding\fP
   200         -\&\fR
   201         -.RS
   202         -.PP
   203         -See the method \fBsetResultEncoding\fR of the
   204         -\&\fBdom\fP command.
   205         -.RE
   206    198   .TP
   207    199   \&\fB\fBtdom\fP \fIparserObj\fB \fBsetStoreLineColumn\fP ?\fIboolean\fB?
   208    200   \&\fR
   209    201   .RS
   210    202   .PP
   211    203   See the method \fBsetStoreLineColumn\fR of the
   212    204   \&\fBdom\fP command.

Changes to doc/tdomcmd.xml.

     1         -  <manpage id="tdomcmd" cat="cmd" title="tdom">
            1  +<manpage id="tdomcmd" cat="cmd" title="tdom">
     2      2       <namesection>
     3      3         <name>tdom</name>
     4      4   
     5      5         <desc>tdom is an expat parser object extension to create an in-memory
     6      6   DOM tree from the input while parsing.</desc>
     7      7       </namesection>
     8      8   
................................................................................
    36     36   
    37     37         <commanddef>
    38     38           <command><cmd>tdom</cmd> <m>parserObj</m> <method>getdoc</method></command>
    39     39   
    40     40           <desc><p>Returns the DOM tree as domDoc (see there) object.</p></desc>
    41     41         </commanddef>
    42     42   
    43         -      <commanddef>
    44         -        <command><cmd>tdom</cmd> <m>parserObj</m> <method>setResultEncoding</method></command>
    45         -
    46         -        <desc><p>See the method <samp>setResultEncoding</samp> of the
    47         -<cmd>dom</cmd> command.</p></desc>
    48         -      </commanddef>
    49         -
    50     43         <commanddef>
    51     44           <command><cmd>tdom</cmd> <m>parserObj</m> <method>setStoreLineColumn</method> ?<m>boolean</m>?</command>
    52     45   
    53     46           <desc><p>See the method <samp>setStoreLineColumn</samp> of the
    54     47   <cmd>dom</cmd> command.</p></desc>
    55     48         </commanddef>
    56     49   

Changes to doc/tmml.options.

     1      1   array set Options {
     2      2       xsltProcessor       tdom
     3      3       masterDocument      "tDOM.xml"
     4      4       tomanOptions        -soelim
            5  +    htmlDirectory       .
            6  +    nroffDirectory      .
     5      7   }

Added doc/tmml.rnc.

            1  +# $Id: tmml.dtd,v 1.8 2002/05/20 20:46:11 jenglish Exp $
            2  +# 
            3  +# Author:	Joe English, <jenglish@users.sourceforge.net>
            4  +# Created:	8 Feb 1999
            5  +# Revised:	24 Jul 1999
            6  +# Usage:
            7  +# 
            8  +# <!DOCTYPE  (manpage | manual)  PUBLIC "-//jenglish//DTD TMML 0.6//EN" >
            9  +# 
           10  +# XML DTD for TMML, Tcl Manual Markup language.
           11  +# 
           12  +# See  <URL: http://tmml.sourceforge.net/ > for more information
           13  +
           14  +# ============================================================
           15  +# 
           16  +# Information pool parameter entities:
           17  +# 
           18  +# e.syntax 	Phrase-level elements that refer to Tcl syntactic entities.
           19  +# e.phrase	Other phrase-level elements
           20  +# e.block	Block-level elements
           21  +# e.struct	Structural elements that can appear directly in a section
           22  +# 
           23  +# x.block
           24  +# x.inline	Used for customization
           25  +
           26  +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"
           27  +
           28  +e.syntax =
           29  +  m
           30  +  | l
           31  +  | o
           32  +  | i
           33  +  | b
           34  +  | br
           35  +  | term
           36  +  | cmd
           37  +  | variable
           38  +  | method
           39  +  | option
           40  +  | file
           41  +  | syscmd
           42  +  | fun
           43  +  | widget
           44  +  | package
           45  +  | type
           46  +  | class
           47  +e.phrase = emph | ref | url | samp | command | new
           48  +e.block =
           49  +  p | ul | ol | dl | sl | xl | example | syntax | commandlist | optlist
           50  +e.struct = arglist | optionlist
           51  +x.inline = notAllowed
           52  +x.block = notAllowed
           53  +# ============================================================
           54  +# Content models:
           55  +# 
           56  +# m.code	(computer) text
           57  +# m.inline	inline text
           58  +# m.mixed	mixed inline and block elements
           59  +# m.top	top-level elements (inside sections)
           60  +m.inline = (text | e.phrase | e.syntax | x.inline)*
           61  +m.code = (text | new | e.syntax | x.inline)*
           62  +m.mixed = (text | e.phrase | e.syntax | e.block | x.block | x.inline)*
           63  +m.top = (e.block | e.struct | x.block)*
           64  +# ============================================================
           65  +# Common attributes:
           66  +a.version = attribute version { text }?
           67  +# ============================================================
           68  +# Top-level element: manual
           69  +m.division =
           70  +  title,
           71  +  (division* | (manpage | subdoc | extref)*)
           72  +m.manual =
           73  +  title,
           74  +  head?,
           75  +  (division* | (manpage | subdoc | extref)*)
           76  +manual = element manual { attlist.manual, m.manual }
           77  +division = element division { attlist.division, m.division }
           78  +attlist.division &= empty
           79  +subdoc = element subdoc { attlist.subdoc, empty }
           80  +extref = element extref { attlist.extref, empty }
           81  +attlist.manual &=
           82  +  attribute package { text },
           83  +  attribute version { text }?
           84  +attlist.extref &=
           85  +  attribute href { text },
           86  +  attribute title { text },
           87  +  attribute type { text }
           88  +attlist.subdoc &= attribute href { text }
           89  +# ============================================================
           90  +# Top-level element: manpage
           91  +manpage =
           92  +  element manpage {
           93  +    attlist.manpage,
           94  +    head?,
           95  +    namesection,
           96  +    synopsis?,
           97  +    section*,
           98  +    seealso?,
           99  +    keywords?
          100  +  }
          101  +attlist.manpage &=
          102  +  attribute id { xsd:ID },
          103  +  attribute cat { text },
          104  +  attribute title { text },
          105  +  attribute package { text }?,
          106  +  a.version
          107  +section = element section { attlist.section, title, m.top, subsection* }
          108  +attlist.section &=
          109  +  attribute id { xsd:ID }?,
          110  +  a.version
          111  +subsection = element subsection { attlist.subsection, title, m.top }
          112  +attlist.subsection &=
          113  +  attribute id { xsd:ID }?,
          114  +  a.version
          115  +# ============================================================
          116  +# Standard sections:
          117  +namesection =
          118  +  element namesection {
          119  +    attlist.namesection,
          120  +    (name+ | (title, name*)),
          121  +    desc
          122  +  }
          123  +attlist.namesection &= empty
          124  +synopsis = element synopsis { attlist.synopsis, (syntax | example)+ }
          125  +attlist.synopsis &= empty
          126  +keywords = element keywords { attlist.keywords, keyword+ }
          127  +attlist.keywords &= empty
          128  +keyword = element keyword { attlist.keyword, text }
          129  +attlist.keyword &= empty
          130  +seealso = element seealso { attlist.seealso, (ref | url)+ }
          131  +attlist.seealso &= empty
          132  +# ============================================================
          133  +# Common Constructs
          134  +title = element title { attlist.title, text }
          135  +attlist.title &= empty
          136  +name = element name { attlist.name, text }
          137  +desc = element desc { attlist.desc, m.mixed }
          138  +attlist.desc &= empty
          139  +# OR: desc: %m.inline;  description:  %m.mixed;
          140  +attlist.name &=
          141  +  attribute name { text }?,
          142  +  attribute cat { text }?
          143  +# ============================================================
          144  +# Block-level elements:
          145  +ul = element ul { attlist.ul, li+ }
          146  +attlist.ul &= empty
          147  +ol = element ol { attlist.ol, li+ }
          148  +attlist.ol &= empty
          149  +li = element li { attlist.li, m.mixed }
          150  +attlist.li &= a.version
          151  +sl = element sl { attlist.sl, li+ }
          152  +attlist.sl &=
          153  +  attribute cols { text }?,
          154  +  attribute cat { text }?
          155  +dl =
          156  +  element dl {
          157  +    attlist.dl,
          158  +    (dle | (dt, dd))+
          159  +  }
          160  +dle = element dle { attlist.dle, dt+, dd }
          161  +attlist.dle &= a.version
          162  +dt = element dt { attlist.dt, m.inline }
          163  +attlist.dt &= empty
          164  +dd = element dd { attlist.dd, m.mixed }
          165  +attlist.dd &= empty
          166  +attlist.dl &=
          167  +  [ a:defaultValue = "local" ] attribute scope { "local" | "global" }?,
          168  +  attribute cat { text }?
          169  +# Extended lists:  
          170  +# Similar to DocBook SegmentedLists
          171  +xl = element xl { attlist.xl, xlh?, xle+ }
          172  +attlist.xl &= empty
          173  +xlh = element xlh { attlist.xlh, xh+ }
          174  +xh = element xh { attlist.xh, m.inline }
          175  +attlist.xh &= empty
          176  +xle = element xle { attlist.xle, xt+, desc? }
          177  +attlist.xle &= empty
          178  +xt = element xt { attlist.xt, m.inline }
          179  +attlist.xt &= empty
          180  +p = element p { attlist.p, m.inline }
          181  +attlist.p &= a.version
          182  +example = element example { attlist.example, m.code }
          183  +attlist.example &= empty
          184  +syntax = element syntax { attlist.syntax, m.code }
          185  +attlist.syntax &=
          186  +  attribute scope { "local" | "global" }?,
          187  +  attribute cat { text }?,
          188  +  attribute name { text }?
          189  +# ============================================================
          190  +# Inline elements:
          191  +i = element i { attlist.i, m.inline }
          192  +attlist.i &= attribute cat { text }?
          193  +b = element b { attlist.b, m.inline }
          194  +attlist.b &= attribute cat { text }?
          195  +emph = element emph { attlist.emph, m.inline }
          196  +attlist.emph &= empty
          197  +samp = element samp { attlist.samp, m.code }
          198  +attlist.samp &= empty
          199  +o = element o { attlist.o, m.code }
          200  +attlist.o &= empty
          201  +url = element url { attlist.url, text }
          202  +attlist.url &= empty
          203  +ref = element ref { attlist.ref, m.inline }
          204  +attlist.ref &=
          205  +  attribute refid { text }?,
          206  +  attribute href { text }?,
          207  +  attribute cat { text }?
          208  +# @@ ALSO:
          209  +#	package	CDATA	#IMPLIED
          210  +#	manpage	CDATA	#IMPLIED
          211  +#	cat	CDATA	#IMPLIED
          212  +#	name	CDATA	#IMPLIED
          213  +# Legal combinations: (package? & ((manpage? & refid?) | (name? & cat?)))
          214  +new = element new { attlist.new, m.inline }
          215  +attlist.new &= attribute version { text }
          216  +br = element br { attlist.br, empty }
          217  +attlist.br &= empty
          218  +# ============================================================
          219  +# Syntax elements:
          220  +m = element m { attlist.m, text }
          221  +attlist.m &= empty
          222  +l = element l { attlist.l, text }
          223  +attlist.l &= empty
          224  +term = element term { attlist.term, text }
          225  +attlist.term &= attribute cat { text }?
          226  +cmd = element cmd { attlist.cmd, text }
          227  +attlist.cmd &= empty
          228  +method = element method { attlist.method, text }
          229  +attlist.method &= empty
          230  +option = element option { attlist.option, text }
          231  +attlist.option &= empty
          232  +syscmd = element syscmd { attlist.syscmd, text }
          233  +attlist.syscmd &= empty
          234  +widget = element widget { attlist.widget, text }
          235  +attlist.widget &= empty
          236  +fun = element fun { attlist.fun, text }
          237  +attlist.fun &= empty
          238  +variable = element variable { attlist.variable, text }
          239  +attlist.variable &= empty
          240  +package = element package { attlist.package, text }
          241  +attlist.package &= empty
          242  +type = element type { attlist.type, text }
          243  +attlist.type &= empty
          244  +class = element class { attlist.class, text }
          245  +attlist.class &= empty
          246  +file = element file { attlist.file, text }
          247  +attlist.file &= empty
          248  +# ============================================================
          249  +# Tcl entity definition elements:
          250  +arglist = element arglist { attlist.arglist, argdef+ }
          251  +attlist.arglist &= empty
          252  +argdef =
          253  +  element argdef { attlist.argdef, argtype, name, argmode?, desc }
          254  +attlist.argdef &= a.version
          255  +argtype = element argtype { attlist.argtype, text }
          256  +attlist.argtype &= empty
          257  +argmode = element argmode { attlist.argmode, text }
          258  +attlist.argmode &= empty
          259  +commandlist = element commandlist { attlist.commandlist, commanddef+ }
          260  +attlist.commandlist &= empty
          261  +commanddef = element commanddef { attlist.commanddef, command, desc }
          262  +attlist.commanddef &= a.version
          263  +command = element command { attlist.command, m.code }
          264  +attlist.command &= empty
          265  +optlist = element optlist { attlist.optlist, optdef+ }
          266  +attlist.optlist &= empty
          267  +optdef = element optdef { attlist.optdef, optname, optarg?, desc }
          268  +attlist.optdef &= empty
          269  +optname = element optname { attlist.optname, text }
          270  +attlist.optname &= empty
          271  +optarg = element optarg { attlist.optarg, text }
          272  +attlist.optarg &= empty
          273  +optionlist = element optionlist { attlist.optionlist, optiondef+ }
          274  +optiondef =
          275  +  element optiondef { attlist.optiondef, name, dbname, dbclass, desc }
          276  +attlist.optiondef &= a.version
          277  +dbname = element dbname { attlist.dbname, text }
          278  +attlist.dbname &= empty
          279  +dbclass = element dbclass { attlist.dbclass, text }
          280  +attlist.dbclass &= empty
          281  +attlist.optionlist &=
          282  +  [ a:defaultValue = "local" ] attribute scope { "local" | "global" }?,
          283  +  attribute cat { text }?
          284  +# ============================================================
          285  +# #FIXED attributes:
          286  +# A DTD-aware processor may take advantage of these
          287  +# if it simplifies processing.
          288  +
          289  +# ============================================================
          290  +# Metainformation:
          291  +# Note that these elements do not normally appear
          292  +# inside TMML documents; they're for administrative
          293  +# purposes only.
          294  +head =
          295  +  element head { attlist.head, (extensions | info | link | category)* }
          296  +attlist.head &= empty
          297  +extensions =
          298  +  element extensions { attlist.extensions, (extension | xlh)* }
          299  +attlist.extensions &= empty
          300  +extension = element extension { attlist.extension, empty }
          301  +attlist.extension &=
          302  +  attribute gi { text },
          303  +  attribute tmml { text }
          304  +attlist.xlh &= attribute gi { text }?
          305  +info = element info { attlist.info, empty }
          306  +attlist.info &=
          307  +  attribute key { text },
          308  +  attribute value { text }
          309  +link = element link { attlist.link, empty }
          310  +attlist.link &=
          311  +  attribute rel { text },
          312  +  attribute href { text }
          313  +categories = element categories { attlist.categories, category+ }
          314  +attlist.categories &= empty
          315  +category = element category { attlist.category, empty }
          316  +attlist.category &=
          317  +  attribute id { xsd:ID },
          318  +  attribute title { text }?
          319  +INDEX = element INDEX { attlist.INDEX, head?, (MAN | DEF | KWD)* }
          320  +attlist.INDEX &=
          321  +  attribute title { text },
          322  +  attribute standalone { text }?,
          323  +  attribute package { text }?
          324  +DEF = element DEF { attlist.DEF, empty }
          325  +attlist.DEF &=
          326  +  attribute name { text },
          327  +  attribute cat { text }?,
          328  +  attribute package { text }?,
          329  +  attribute manpage { text }?,
          330  +  attribute subpart { text }?
          331  +KWD = element KWD { attlist.KWD, empty }
          332  +attlist.KWD &=
          333  +  attribute name { text },
          334  +  attribute manpage { text }?
          335  +MAN = element MAN { attlist.MAN, empty }
          336  +attlist.MAN &=
          337  +  attribute id { text },
          338  +  attribute title { text }
          339  +start = INDEX | manual | manpage | categories
          340  +# EOF

Changes to doc/tnc.html.

     1      1   <html>
     2      2   <head>
     3         -<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$">
            3  +<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">
     4      4   </head><body>
     5      5   <div class="header">
     6      6   <div class="navbar" align="center">
     7         -<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>
            7  +<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>
     8      8   </div><hr class="navsep">
     9      9   </div><div class="body">
    10         -  <h2><a name="SECTid883">NAME</a></h2><p class="namesection">
           10  +  <h2><a name="SECTid0x1ee4b70">NAME</a></h2><p class="namesection">
    11     11   <b class="names">tnc - </b><br>tnc is an expat parser object extension, that validates the XML
    12     12   stream against the document DTD while parsing.</p>
    13     13     
    14         -  <h2><a name="SECTid892">SYNOPSIS</a></h2><pre class="syntax">package require tdom
           14  +  <h2><a name="SECTid0x1d90950">SYNOPSIS</a></h2><pre class="syntax">package require tdom
    15     15   package require tnc
    16     16   
    17     17   set parser [expat]
    18     18   
    19     19   tnc $parser enable</pre>
    20     20   
    21         -  <h2><a name="SECTid898">DESCRIPTION</a></h2><p>
           21  +  <h2><a name="SECTid0x1ec21b0">DESCRIPTION</a></h2><p>
    22     22   <i class="m">tnc</i> adds the C handler set "tnc" to a tcl expat parser
    23     23   obj. This handler set is a simple DTD validator. If the validator detects a
    24     24   validation error, it sets the interp result, signals error and stops
    25     25   parsing. There isn't any validation error recovering. As a consequence, only
    26     26   valid documents are completely parsed.</p><p>This handler set has only three methods:</p><dl class="commandlist">
    27     27         
    28     28           <dt>
................................................................................
    43     43   
    44     44         
    45     45           <dt>
    46     46   <b class="cmd">tnc</b> <i class="m">parserObj</i> <b class="method">getValidateCmd</b> <b class="option">?validateCmdName?</b>
    47     47   </dt>
    48     48   
    49     49           <dd>
    50         -<p>Returns a new created validation command, if one is avaliable
           50  +<p>Returns a new created validation command, if one is available
    51     51   from the parser command, otherwise it signals error. The name of the validation
    52     52   command is the <i class="m">validateCmdName</i>, if this optional argument was given, or
    53         -a random choosen name. A validation command is avaliable in a parser command,
           53  +a random chosen name. A validation command is available in a parser command,
    54     54   if the parser with tnc enabled was previously used, to parse an XML document
    55     55   with a valid doctype declaration, a valid external subset, if one was given by
    56     56   the doctype declaration, and a valid internal subset. The further document
    57         -doesn't need to be valid, to make the validation command avaliable. The
           57  +doesn't need to be valid, to make the validation command available. The
    58     58   validation command can only get received one time from the parser command. The
    59     59   created validation command has this syntax:</p>
    60     60   
    61     61   <pre class="syntax">
    62     62   <b class="cmd">validationCmd</b> <i class="m">method</i> <i class="m">?args?</i>
    63     63   </pre>
    64     64   
................................................................................
    78     78   
    79     79         
    80     80           <dt>
    81     81   <b class="method">validateTree</b> <i class="m">elementNode</i> <i class="m">?varName?</i>
    82     82   </dt>
    83     83   
    84     84           <dd>Checks, if the given subtree with <i class="m">domNode</i> as root element
    85         -is a posible valid subtree of a document conforming to the DTD information
    86         -represented by teh validation command. IDREF could not checked, while
           85  +is a possible valid subtree of a document conforming to the DTD information
           86  +represented by the validation command. IDREF could not checked, while
    87     87   validating only a subtree, but it is checked, that every known ID attribute in
    88     88   the subtree is unique. Returns 1, if the subtree is OK, 0 otherwise. If the
    89     89   <i class="m">varName</i> argument is given, then the variable it names is set to the
    90     90   detected reason for the validation error or to the empty string in case of
    91     91   a valid subtree.</dd>
    92     92   
    93     93         
................................................................................
   116    116         
   117    117   
   118    118         </dl>
   119    119        </dd>
   120    120         
   121    121       </dl>
   122    122   
   123         -  <h2><a name="SECTid1068">BUGS</a></h2><p>The validation error reports could be much more informative and
          123  +  <h2><a name="SECTid0x1ebb7b0">BUGS</a></h2><p>The validation error reports could be much more informative and
   124    124   user-friendly.</p><p>The validator doesn't detect ambiguous content models (see XML
   125    125   recomendation Section 3.2.1 and Appendix E). Most Java validators also doesn't,
   126    126   but handle such content models right anyhow. Tnc does not; if your DTD has
   127    127   such ambiguous content models, tnc can not used to validate documents against
   128    128   such (not completely XML spec compliant) DTDs.</p><p>It isn't possible to validate XML documents with standalone="yes" in the
   129    129   XML Declaration</p><p>Violations of the validity constraints Proper Group/PE Nesting and
   130    130   Proper Conditional Section/PE Nesting are not detected. They could only happen
   131    131   inside a invalid DTD, not in the content of a document.</p>
   132         -  <h2><a name="SECTid1086">KEYWORDS</a></h2><p class="keywords">
          132  +  <h2><a name="SECTid0x1ebc120">KEYWORDS</a></h2><p class="keywords">
   133    133   <a class="keyword" href="keyword-index.html#KW-Validation">Validation</a>, <a class="keyword" href="keyword-index.html#KW-DTD">DTD</a>
   134    134   </p>
   135    135     
   136    136   </div><hr class="navsep"><div class="navbar" align="center">
   137         -<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>
          137  +<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>
   138    138   </div>
   139    139   </body>
   140    140   </html>

Changes to doc/tnc.n.

   197    197   and frees all information, stored by it.
   198    198   .RE
   199    199   .TP
   200    200   \&\fB\fBtnc\fP \fIparserObj\fB \fBgetValidateCmd\fP \fB?validateCmdName?\fP
   201    201   \&\fR
   202    202   .RS
   203    203   .PP
   204         -Returns a new created validation command, if one is avaliable
          204  +Returns a new created validation command, if one is available
   205    205   from the parser command, otherwise it signals error. The name of the validation
   206    206   command is the \fIvalidateCmdName\fR, if this optional argument was given, or
   207         -a random choosen name. A validation command is avaliable in a parser command,
          207  +a random chosen name. A validation command is available in a parser command,
   208    208   if the parser with tnc enabled was previously used, to parse an XML document
   209    209   with a valid doctype declaration, a valid external subset, if one was given by
   210    210   the doctype declaration, and a valid internal subset. The further document
   211         -doesn't need to be valid, to make the validation command avaliable. The
          211  +doesn't need to be valid, to make the validation command available. The
   212    212   validation command can only get received one time from the parser command. The
   213    213   created validation command has this syntax:
   214    214   
   215    215   
   216    216   
   217    217   .CS
   218    218   \&\fBvalidationCmd\fP \fImethod\fR \fI?args?\fR
................................................................................
   225    225   information represented by the validation command. Returns 1, if the document
   226    226   ist valid, 0 otherwise. If the \fIvarName\fR argument is given, then the
   227    227   variable it names is set to the detected reason for the validation error or to
   228    228   the empty string in case of a valid document.
   229    229   .TP
   230    230   \&\fB\fBvalidateTree\fP \fIelementNode\fB \fI?varName?\fB
   231    231   \&\fRChecks, if the given subtree with \fIdomNode\fR as root element
   232         -is a posible valid subtree of a document conforming to the DTD information
   233         -represented by teh validation command. IDREF could not checked, while
          232  +is a possible valid subtree of a document conforming to the DTD information
          233  +represented by the validation command. IDREF could not checked, while
   234    234   validating only a subtree, but it is checked, that every known ID attribute in
   235    235   the subtree is unique. Returns 1, if the subtree is OK, 0 otherwise. If the
   236    236   \&\fIvarName\fR argument is given, then the variable it names is set to the
   237    237   detected reason for the validation error or to the empty string in case of
   238    238   a valid subtree.
   239    239   .TP
   240    240   \&\fB\fBvalidateAttributes\fP \fIelementNode\fB \fI?varName?\fB

Changes to doc/tnc.xml.

    38     38           <desc><p>Removes the tnc validatore from the parser <m>parserObj</m>
    39     39   and frees all information, stored by it.</p></desc>
    40     40         </commanddef>
    41     41   
    42     42         <commanddef>
    43     43           <command><cmd>tnc</cmd> <m>parserObj</m> <method>getValidateCmd</method> <option>?validateCmdName?</option></command>
    44     44   
    45         -        <desc><p>Returns a new created validation command, if one is avaliable
           45  +        <desc><p>Returns a new created validation command, if one is available
    46     46   from the parser command, otherwise it signals error. The name of the validation
    47     47   command is the <m>validateCmdName</m>, if this optional argument was given, or
    48         -a random choosen name. A validation command is avaliable in a parser command,
           48  +a random chosen name. A validation command is available in a parser command,
    49     49   if the parser with tnc enabled was previously used, to parse an XML document
    50     50   with a valid doctype declaration, a valid external subset, if one was given by
    51     51   the doctype declaration, and a valid internal subset. The further document
    52         -doesn't need to be valid, to make the validation command avaliable. The
           52  +doesn't need to be valid, to make the validation command available. The
    53     53   validation command can only get received one time from the parser command. The
    54     54   created validation command has this syntax:</p>
    55     55   
    56     56   <syntax><cmd>validationCmd</cmd> <m>method</m> <m>?args?</m></syntax>
    57     57   
    58     58       <p>The valid methods are:</p>
    59     59   
................................................................................
    67     67   the empty string in case of a valid document.</desc>
    68     68         </commanddef>
    69     69   
    70     70         <commanddef>
    71     71           <command><method>validateTree</method> <m>elementNode</m> <m>?varName?</m></command>
    72     72   
    73     73           <desc>Checks, if the given subtree with <m>domNode</m> as root element
    74         -is a posible valid subtree of a document conforming to the DTD information
    75         -represented by teh validation command. IDREF could not checked, while
           74  +is a possible valid subtree of a document conforming to the DTD information
           75  +represented by the validation command. IDREF could not checked, while
    76     76   validating only a subtree, but it is checked, that every known ID attribute in
    77     77   the subtree is unique. Returns 1, if the subtree is OK, 0 otherwise. If the
    78     78   <m>varName</m> argument is given, then the variable it names is set to the
    79     79   detected reason for the validation error or to the empty string in case of
    80     80   a valid subtree.</desc>
    81     81   
    82     82         </commanddef>

Deleted encodings/GenCompactCodings.

     1         -#!/opt/tcl/bin/tclsh
     2         -#-----------------------------------------------------------------------------
     3         -#   Copyright (c) 1999 Jochen C. Loewer (loewerj@hotmail.com) 
     4         -#-----------------------------------------------------------------------------
     5         -#
     6         -#
     7         -#   Script to generate 'space and time optimal' C code for fixed 
     8         -#   converting tables from Unicode to 8bit encodings (ISO-8859*,CP850...)
     9         -#   from the Tcl 8.2 encoding files (*.enc)
    10         -#
    11         -#
    12         -#
    13         -#   The contents of this file are subject to the Mozilla Public License
    14         -#   Version 1.1 (the "License"); you may not use this file except in
    15         -#   compliance with the License. You may obtain a copy of the License at
    16         -#   http://www.mozilla.org/MPL/
    17         -#
    18         -#   Software distributed under the License is distributed on an "AS IS"
    19         -#   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
    20         -#   License for the specific language governing rights and limitations
    21         -#   under the License.
    22         -#
    23         -#   The Original Code is tDOM.
    24         -#
    25         -#   The Initial Developer of the Original Code is Jochen Loewer
    26         -#   Portions created by Jochen Loewer are Copyright (C) 1998, 1999
    27         -#   Jochen Loewer. All Rights Reserved.
    28         -#
    29         -#   Contributor(s):                                      
    30         -#   
    31         -#
    32         -#   written by Jochen Loewer
    33         -#   November, 1999
    34         -#
    35         -#-----------------------------------------------------------------------------
    36         -
    37         -
    38         -
    39         -#-----------------------------------------------------------------------------
    40         -#   Log
    41         -#
    42         -#-----------------------------------------------------------------------------
    43         -proc Log { message } {
    44         -    puts stderr $message
    45         -}
    46         -
    47         -
    48         -#-----------------------------------------------------------------------------
    49         -#   HexValue
    50         -#
    51         -#-----------------------------------------------------------------------------
    52         -proc HexValue { v } {
    53         -    return [format "0x%2X" $v]
    54         -}
    55         -
    56         -
    57         -#-----------------------------------------------------------------------------
    58         -#   HEX
    59         -#
    60         -#-----------------------------------------------------------------------------
    61         -proc HEX { v } {
    62         -    return [format "\\%03o" $v]
    63         -}
    64         -
    65         -
    66         -#-----------------------------------------------------------------------------
    67         -#   ReadEncodingFile
    68         -#
    69         -#-----------------------------------------------------------------------------
    70         -proc ReadEncodingFile { encodingFile info_var map_var } {
    71         -
    72         -    upvar $info_var info $map_var map
    73         -
    74         -    catch { unset info }
    75         -    catch { unset map  }
    76         -
    77         -    set info(max) 0
    78         -
    79         -    Log "Reading encoding file $encodingFile ..."
    80         -
    81         -    set fd [open $encodingFile r]
    82         -
    83         -    #--------------------------------------------------------------
    84         -    #   read header
    85         -    #
    86         -    #--------------------------------------------------------------
    87         -    set line [gets $fd]   ;# ignore comment line
    88         -
    89         -    set line [gets $fd]   
    90         -
    91         -    if {$line != "S"} {
    92         -        error "Only single byte encodings are supported"
    93         -    }
    94         -    set line [gets $fd]
    95         -    scan $line "%s %d %d" fbHex info(symbol) info(npages)
    96         -
    97         -    set fb [binary format H2 [string range $fbHex 2 4]]
    98         -    binary scan $fb c info(fallback)
    99         - 
   100         -    #--------------------------------------------------------------
   101         -    #   read each single mapping page
   102         -    #
   103         -    #--------------------------------------------------------------
   104         -    for {set p 0} {$p < $info(npages)} {incr p} {
   105         - 
   106         -        set line [gets $fd]
   107         -
   108         -        binary scan [binary format H2 $line] c page
   109         -
   110         -        #----------------------------------------------------
   111         -        #   read 16 * 16 hex number -> 256 mappings
   112         -        #
   113         -        #----------------------------------------------------
   114         -        for {set l 0} {$l < 16} {incr l} {
   115         -
   116         -            set line [gets $fd]
   117         -
   118         -            for {set k 0} {$k < 16} {incr k} {
   119         -
   120         -                set hex [string range $line 0 3]
   121         -                set line [string range $line 4 end]
   122         -                binary scan [binary format H4 $hex] S from
   123         -                set to [expr ($page << 8) + ($l * 16) + $k]
   124         -                Log "$from -> $to"
   125         -
   126         -                #------------------------------
   127         -                #   set mapping
   128         -                #------------------------------
   129         -                set map($from) $to
   130         -
   131         -                if {$from > $info(max)} {set info(max) $from}
   132         -            }
   133         -        }
   134         -    }
   135         -    close $fd
   136         -    Log "fallback='$info(fallback)' max=$info(max) symbol=$info(symbol) npages=$info(npages)"
   137         -    Log "Reading done."
   138         -    Log ""
   139         -}
   140         -
   141         -
   142         -
   143         -
   144         -#-----------------------------------------------------------------------------
   145         -#   BuildInitalRanges
   146         -#
   147         -#-----------------------------------------------------------------------------
   148         -proc BuildInitalRanges { info_var map_var} {
   149         -
   150         -    upvar $info_var info $map_var map
   151         -
   152         -    set mode different
   153         -    set last -1
   154         -
   155         -    set ranges {}
   156         -
   157         -    for {set from 1} {$from <= $info(max)} {incr from} {
   158         -        if {![info exists map($from)]} {
   159         -            set to $info(fallback)
   160         -        } else {   
   161         -            set to $map($from)
   162         -        }
   163         -        if {$mode == "identic"} {
   164         -            if {$from == $to} {
   165         -                set last $from
   166         -            } else {
   167         -                lappend ranges [list $identicStart [expr $last - $identicStart +1] {}]            
   168         -                Log "$identicStart, $last, IDENTIC, NULL, "
   169         -                if {$to == $info(fallback)} { 
   170         -                    set mode fallback
   171         -                } else {
   172         -                    lappend ranges [list $from 1 $to]            
   173         -                    Log "$from -> $to"
   174         -                    set mode different
   175         -                }
   176         -            }
   177         -        } elseif {$mode == "different"} {
   178         -            if {$from == $to} {
   179         -                set identicStart $from
   180         -                set last         $from
   181         -                set mode identic
   182         -            } elseif {$to == $info(fallback)} {
   183         -                set mode fallback
   184         -            } else {
   185         -                lappend ranges [list $from 1 $to]            
   186         -                Log"$from -> $to"
   187         -            }        
   188         -        } else {
   189         -            if {$to != $info(fallback)} {
   190         -                if {$from == $to} {
   191         -                    set identicStart $from
   192         -                    set last         $from
   193         -                    set mode identic
   194         -                } else {
   195         -                    lappend ranges [list $from 1 $to]            
   196         -                    Log "$from -> $to"
   197         -                }        
   198         -            }
   199         -        } 
   200         -    }
   201         -    if {$mode == "identic"} {
   202         -        lappend ranges [list $identicStart [expr $last - $identicStart +1] {}]            
   203         -        Log "$identicStart, $last, IDENTIC, NULL, "
   204         -    }
   205         -    return $ranges
   206         -}
   207         -
   208         -
   209         -#-----------------------------------------------------------------------------
   210         -#   OptimizeRanges
   211         -#
   212         -#-----------------------------------------------------------------------------
   213         -proc OptimizeRanges { fallback ranges } {
   214         -
   215         -    set newranges {}
   216         -    set lastfrom  {}
   217         -
   218         -    foreach range $ranges {
   219         -        foreach {from len values} $range break
   220         -
   221         -        if {($len > 50) && ($values == {}) } {
   222         -            if {$lastfrom != {} } {
   223         -                lappend newranges [list $lastfrom $lastlen $lastvalues]
   224         -            }
   225         -            lappend newranges [list $from $len $values]
   226         -            set lastfrom {}
   227         -        } elseif {$lastfrom != {} } {
   228         -            #Log "lastfrom=$lastfrom lastlen=$lastlen"
   229         -            if { ($lastfrom + $lastlen + 20) > $from} {
   230         - 
   231         -                if {$lastvalues == {}} {
   232         -                    for {set j 0} {$j < $lastlen} {incr j} {
   233         -                        lappend lastvalues [expr $lastfrom + $j]
   234         -                    }
   235         -                    incr lastlen $lastlen
   236         -                }
   237         -                for {set i [expr $lastfrom + $lastlen]} {$i < $from} {incr i} { 
   238         -                    lappend lastvalues $fallback
   239         -                    incr lastlen 
   240         -                }
   241         -                if {$values == {}} {
   242         -                    for {set j 0} {$j < $len} {incr j} {
   243         -                        lappend lastvalues [expr $from + $j]
   244         -                    }
   245         -                    incr lastlen $len
   246         -                } else {
   247         -                    set lastvalues [concat $lastvalues $values]
   248         -                    incr lastlen $len
   249         -                }
   250         -            } else {
   251         -                lappend newranges [list $lastfrom $lastlen $lastvalues]
   252         -                set lastfrom   $from
   253         -                set lastlen    $len
   254         -                set lastvalues $values
   255         -            }
   256         -        } else {
   257         -            set lastfrom   $from
   258         -            set lastlen    $len
   259         -            set lastvalues $values
   260         -        }
   261         -    }
   262         -    if {$lastfrom != {} } {
   263         -        lappend newranges [list $lastfrom $lastlen $lastvalues]
   264         -    }
   265         -    return $newranges
   266         -}
   267         -
   268         -
   269         -#-----------------------------------------------------------------------------
   270         -#   OutputCode
   271         -#
   272         -#-----------------------------------------------------------------------------
   273         -proc OutputCode { encVar fallback ranges } {   
   274         -
   275         -    puts "static TEncodingRule TDOM_UnicodeTo$encVar \[\] = \{"
   276         -
   277         -    foreach range $ranges {
   278         -        foreach {from len values} $range break
   279         -        if {$values == {}} {
   280         -            puts "    \{ ENC_IDENTITY, $from, $len, \"\" \}, "
   281         -        } else {
   282         -            puts "    \{ ENC_MAP, $from, $len, "
   283         -            set i 0
   284         -            foreach value $values {
   285         -                if {$i == 0} { 
   286         -                    puts -nonewline "        \""
   287         -                }
   288         -                puts -nonewline "[HEX $value]"
   289         -                incr i
   290         -                if {$i == 14} { 
   291         -                    puts -nonewline "\"\n"
   292         -                    set i 0 
   293         -                }
   294         -            }
   295         -            if {$i > 0} {
   296         -                puts  -nonewline "\" \},\n"
   297         -            } else {
   298         -                puts  -nonewline "    \},\n"
   299         -            }
   300         -        }
   301         -    }
   302         -    puts "    \{ ENC_END, 0, 0, NULL \} "
   303         -    puts "\};\n"
   304         -}
   305         -
   306         -
   307         -
   308         -#-----------------------------------------------------------------------------
   309         -#   begin of main part
   310         -#-----------------------------------------------------------------------------
   311         -
   312         -
   313         -  puts "/*------------------------------------------------------------------------"
   314         -  puts "|   WARNING! This is file automatically generated by GenCompactCodings !  "
   315         -  puts "|   WARNING!         Do not edit!                                         "
   316         -  puts "|                                                                         "
   317         -  puts "|   Unicode(UTF) ---> 8bit code conversion tables                         "
   318         -  puts "|                                                                         "
   319         -  puts "\\-----------------------------------------------------------------------*/"
   320         -
   321         -
   322         -  set fallbacks {}
   323         -  set encodings {}
   324         -
   325         -  foreach encodingFile $argv {
   326         -
   327         -      regsub {(\.enc)$} $encodingFile {} encoding
   328         -      set encVar [string toupper $encoding]
   329         -      regsub -- {-} $encVar {} encVar
   330         -     
   331         -      ReadEncodingFile $encodingFile info map
   332         -
   333         -      foreach from [lsort -integer [array names map]] {
   334         -          Log "$from -> $map($from)"
   335         -      }
   336         -
   337         -      #-------------------------------------------
   338         -      #   build the initial map ranges
   339         -      #-------------------------------------------
   340         -      set ranges [ BuildInitalRanges info map ]
   341         -
   342         -      Log "Starting ranges [llength $ranges]:"
   343         -      foreach range $ranges {
   344         -          foreach {from len values} $range break
   345         -          Log [format "%3d %3d '%s'" $from $len $values]
   346         -      }
   347         -
   348         -      #-------------------------------------------
   349         -      #   iterate to optimize ranges
   350         -      #-------------------------------------------
   351         -      for {set loop 0} {$loop < 4} {incr loop} {
   352         -          set ranges [OptimizeRanges $info(fallback) $ranges]
   353         -      }
   354         -
   355         -      Log "End ranges [llength $ranges]:"
   356         -      foreach range $ranges {
   357         -          foreach {from len values} $range break
   358         -          Log [format "%3d %3d '%s'\n" $from $len $values]
   359         -      }
   360         -
   361         -      lappend fallbacks $info(fallback)  
   362         -      lappend encodings $encoding $encVar  
   363         -
   364         -      OutputCode $encVar $info(fallback) $ranges
   365         -  }
   366         -
   367         -  puts ""
   368         -  puts "static TEncoding TDOM_UnicodeTo8bitEncodings \[\] = \{"
   369         -  foreach {encoding encVar} $encodings fallback $fallbacks {
   370         -      puts stdout  [format "    { %-12s, %4s, %s }," \
   371         -                           "\"$encoding\""           \
   372         -                           [HexValue $fallback]      \
   373         -                           TDOM_UnicodeTo$encVar     ]
   374         -     
   375         -  }
   376         -  puts "    { NULL, 0, NULL }"
   377         -  puts "\};"
   378         -
   379         -
   380         -#-----------------------------------------------------------------------------
   381         -#   end of main part
   382         -#-----------------------------------------------------------------------------
   383         -

Deleted encodings/ascii.enc.

     1         -# Encoding file: ascii, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E0000
    13         -0000000000000000000000000000000000000000000000000000000000000000
    14         -0000000000000000000000000000000000000000000000000000000000000000
    15         -0000000000000000000000000000000000000000000000000000000000000000
    16         -0000000000000000000000000000000000000000000000000000000000000000
    17         -0000000000000000000000000000000000000000000000000000000000000000
    18         -0000000000000000000000000000000000000000000000000000000000000000
    19         -0000000000000000000000000000000000000000000000000000000000000000
    20         -0000000000000000000000000000000000000000000000000000000000000000

Deleted encodings/cp1250.enc.

     1         -# Encoding file: cp1250, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -00800081201A0083201E2026202020210088203001602039015A0164017D0179
    14         -009020182019201C201D202220132014009821220161203A015B0165017E017A
    15         -00A002C702D8014100A4010400A600A700A800A9015E00AB000000AD00AE017B
    16         -00B000B102DB014200B400B500B600B700B80105015F00BB013D02DD013E017C
    17         -015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
    18         -01100143014700D300D4015000D600D70158016E00DA017000DC00DD016200DF
    19         -015500E100E2010300E4013A010700E7010D00E9011900EB011B00ED00EE010F
    20         -01110144014800F300F4015100F600F70159016F00FA017100FC00FD016302D9

Deleted encodings/cp1251.enc.

     1         -# Encoding file: cp1251, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -04020403201A0453201E2026202020210088203004092039040A040C040B040F
    14         -045220182019201C201D202220132014009821220459203A045A045C045B045F
    15         -00A0040E045E040800A4049000A600A7040100A9040400AB00AC00AD00AE0407
    16         -00B000B104060456049100B500B600B704512116045400BB0458040504550457
    17         -0410041104120413041404150416041704180419041A041B041C041D041E041F
    18         -0420042104220423042404250426042704280429042A042B042C042D042E042F
    19         -0430043104320433043404350436043704380439043A043B043C043D043E043F
    20         -0440044104420443044404450446044704480449044A044B044C044D044E044F

Deleted encodings/cp1252.enc.

     1         -# Encoding file: cp1252, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -00800081201A0192201E20262020202102C62030016020390152008D008E008F
    14         -009020182019201C201D20222013201402DC21220161203A0153009D009E0178
    15         -00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
    16         -00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
    17         -00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
    18         -00D000D100D200D300D400D500D600D700D800D900DA00DB00DC00DD00DE00DF
    19         -00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
    20         -00F000F100F200F300F400F500F600F700F800F900FA00FB00FC00FD00FE00FF

Deleted encodings/cp1253.enc.

     1         -# Encoding file: cp1253, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -00800081201A0192201E20262020202100882030008A2039008C008D008E008F
    14         -009020182019201C201D20222013201400982122009A203A009C009D009E009F
    15         -00A00385038600A300A400A500A600A700A800A9000000AB00AC00AD00AE2015
    16         -00B000B100B200B3038400B500B600B703880389038A00BB038C00BD038E038F
    17         -0390039103920393039403950396039703980399039A039B039C039D039E039F
    18         -03A003A1000003A303A403A503A603A703A803A903AA03AB03AC03AD03AE03AF
    19         -03B003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
    20         -03C003C103C203C303C403C503C603C703C803C903CA03CB03CC03CD03CE0000

Deleted encodings/cp1254.enc.

     1         -# Encoding file: cp1254, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -00800081201A0192201E20262020202102C62030016020390152008D008E008F
    14         -009020182019201C201D20222013201402DC21220161203A0153009D009E0178
    15         -00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
    16         -00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
    17         -00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
    18         -011E00D100D200D300D400D500D600D700D800D900DA00DB00DC0130015E00DF
    19         -00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
    20         -011F00F100F200F300F400F500F600F700F800F900FA00FB00FC0131015F00FF

Deleted encodings/cp1255.enc.

     1         -# Encoding file: cp1255, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -00800081201A0192201E20262020202102C62030008A2039008C008D008E008F
    14         -009020182019201C201D20222013201402DC2122009A203A009C009D009E009F
    15         -00A0000000A200A320AA00A500A600A700A800A9000000AB00AC00AD00AE00AF
    16         -00B000B100B200B300B400B500B600B7000000B9000000BB00BC00BD00BE0000
    17         -05B005B105B205B305B405B505B605B705B805B905BA05BB05BC05BD05BE05BF
    18         -05C005C105C205C305F005F105F2000000000000000000000000000000000000
    19         -05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
    20         -05E005E105E205E305E405E505E605E705E805E905EA00000000200E200F0000

Deleted encodings/cp1256.enc.

     1         -# Encoding file: cp1256, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080067E201A0192201E20262020202102C62030008A2039015206860698008F
    14         -06AF20182019201C201D20222013201400982122009A203A0153200C200D009F
    15         -00A0060C00A200A300A400A500A600A700A800A9000000AB00AC00AD00AE00AF
    16         -00B000B100B200B300B400B500B600B700B800B9061B00BB00BC00BD00BE061F
    17         -0000062106220623062406250626062706280629062A062B062C062D062E062F
    18         -063006310632063306340635063600D7063706380639063A0640064106420643
    19         -00E0064400E2064506460647064800E700E800E900EA00EB0649064A00EE00EF
    20         -064B064C064D064E00F4064F065000F7065100F9065200FB00FC200E200F0000

Deleted encodings/cp437.enc.

     1         -# Encoding file: cp437, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
    14         -00C900E600C600F400F600F200FB00F900FF00D600DC00A200A300A520A70192
    15         -00E100ED00F300FA00F100D100AA00BA00BF231000AC00BD00BC00A100AB00BB
    16         -259125922593250225242561256225562555256325512557255D255C255B2510
    17         -25142534252C251C2500253C255E255F255A25542569256625602550256C2567
    18         -2568256425652559255825522553256B256A2518250C25882584258C25902580
    19         -03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
    20         -226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0

Deleted encodings/cp850.enc.

     1         -# Encoding file: cp850, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
    14         -00C900E600C600F400F600F200FB00F900FF00D600DC00F800A300D800D70192
    15         -00E100ED00F300FA00F100D100AA00BA00BF00AE00AC00BD00BC00A100AB00BB
    16         -2591259225932502252400C100C200C000A9256325512557255D00A200A52510
    17         -25142534252C251C2500253C00E300C3255A25542569256625602550256C00A4
    18         -00F000D000CA00CB00C8013100CD00CE00CF2518250C2588258400A600CC2580
    19         -00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4
    20         -00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0

Deleted encodings/iso8859-1.enc.

     1         -# Encoding file: iso8859-1, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080008100820083008400850086008700880089008A008B008C008D008E008F
    14         -0090009100920093009400950096009700980099009A009B009C009D009E009F
    15         -00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
    16         -00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
    17         -00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
    18         -00D000D100D200D300D400D500D600D700D800D900DA00DB00DC00DD00DE00DF
    19         -00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
    20         -00F000F100F200F300F400F500F600F700F800F900FA00FB00FC00FD00FE00FF

Deleted encodings/iso8859-2.enc.

     1         -# Encoding file: iso8859-2, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080008100820083008400850086008700880089008A008B008C008D008E008F
    14         -0090009100920093009400950096009700980099009A009B009C009D009E009F
    15         -00A0010402D8014100A4013D015A00A700A80160015E0164017900AD017D017B
    16         -00B0010502DB014200B4013E015B02C700B80161015F0165017A02DD017E017C
    17         -015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
    18         -01100143014700D300D4015000D600D70158016E00DA017000DC00DD016200DF
    19         -015500E100E2010300E4013A010700E7010D00E9011900EB011B00ED00EE010F
    20         -01110144014800F300F4015100F600F70159016F00FA017100FC00FD016302D9

Deleted encodings/iso8859-3.enc.

     1         -# Encoding file: iso8859-3, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080008100820083008400850086008700880089008A008B008C008D008E008F
    14         -0090009100920093009400950096009700980099009A009B009C009D009E009F
    15         -00A0012602D800A300A40000012400A700A80130015E011E013400AD0000017B
    16         -00B0012700B200B300B400B5012500B700B80131015F011F013500BD0000017C
    17         -00C000C100C2000000C4010A010800C700C800C900CA00CB00CC00CD00CE00CF
    18         -000000D100D200D300D4012000D600D7011C00D900DA00DB00DC016C015C00DF
    19         -00E000E100E2000000E4010B010900E700E800E900EA00EB00EC00ED00EE00EF
    20         -000000F100F200F300F4012100F600F7011D00F900FA00FB00FC016D015D02D9

Deleted encodings/iso8859-4.enc.

     1         -# Encoding file: iso8859-4, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080008100820083008400850086008700880089008A008B008C008D008E008F
    14         -0090009100920093009400950096009700980099009A009B009C009D009E009F
    15         -00A001040138015600A40128013B00A700A8016001120122016600AD017D00AF
    16         -00B0010502DB015700B40129013C02C700B80161011301230167014A017E014B
    17         -010000C100C200C300C400C500C6012E010C00C9011800CB011600CD00CE012A
    18         -01100145014C013600D400D500D600D700D8017200DA00DB00DC0168016A00DF
    19         -010100E100E200E300E400E500E6012F010D00E9011900EB011700ED00EE012B
    20         -01110146014D013700F400F500F600F700F8017300FA00FB00FC0169016B02D9

Deleted encodings/iso8859-5.enc.

     1         -# Encoding file: iso8859-5, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080008100820083008400850086008700880089008A008B008C008D008E008F
    14         -0090009100920093009400950096009700980099009A009B009C009D009E009F
    15         -00A0040104020403040404050406040704080409040A040B040C00AD040E040F
    16         -0410041104120413041404150416041704180419041A041B041C041D041E041F
    17         -0420042104220423042404250426042704280429042A042B042C042D042E042F
    18         -0430043104320433043404350436043704380439043A043B043C043D043E043F
    19         -0440044104420443044404450446044704480449044A044B044C044D044E044F
    20         -2116045104520453045404550456045704580459045A045B045C00A7045E045F

Deleted encodings/iso8859-6.enc.

     1         -# Encoding file: iso8859-6, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0660066106620663066406650666066706680669003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080008100820083008400850086008700880089008A008B008C008D008E008F
    14         -0090009100920093009400950096009700980099009A009B009C009D009E009F
    15         -00A000000000000000A40000000000000000000000000000060C00AD00000000
    16         -00000000000000000000000000000000000000000000061B000000000000061F
    17         -0000062106220623062406250626062706280629062A062B062C062D062E062F
    18         -0630063106320633063406350636063706380639063A00000000000000000000
    19         -0640064106420643064406450646064706480649064A064B064C064D064E064F
    20         -0650065106520000000000000000000000000000000000000000000000000000

Deleted encodings/iso8859-7.enc.

     1         -# Encoding file: iso8859-7, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080008100820083008400850086008700880089008A008B008C008D008E008F
    14         -0090009100920093009400950096009700980099009A009B009C009D009E009F
    15         -00A002BD02BC00A30000000000A600A700A800A9000000AB00AC00AD00002015
    16         -00B000B100B200B303840385038600B703880389038A00BB038C00BD038E038F
    17         -0390039103920393039403950396039703980399039A039B039C039D039E039F
    18         -03A003A1000003A303A403A503A603A703A803A903AA03AB03AC03AD03AE03AF
    19         -03B003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
    20         -03C003C103C203C303C403C503C603C703C803C903CA03CB03CC03CD03CE0000

Deleted encodings/iso8859-8.enc.

     1         -# Encoding file: iso8859-8, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080008100820083008400850086008700880089008A008B008C008D008E008F
    14         -0090009100920093009400950096009700980099009A009B009C009D009E009F
    15         -00A0000000A200A300A400A500A600A700A800A900D700AB00AC00AD00AE203E
    16         -00B000B100B200B300B400B500B600B700B800B900F700BB00BC00BD00BE0000
    17         -0000000000000000000000000000000000000000000000000000000000000000
    18         -0000000000000000000000000000000000000000000000000000000000002017
    19         -05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
    20         -05E005E105E205E305E405E505E605E705E805E905EA00000000000000000000

Deleted encodings/iso8859-9.enc.

     1         -# Encoding file: iso8859-9, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -0080008100820083008400850086008700880089008A008B008C008D008E008F
    14         -0090009100920093009400950096009700980099009A009B009C009D009E009F
    15         -00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
    16         -00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
    17         -00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
    18         -011E00D100D200D300D400D500D600D700D800D900DA00DB00DC0130015E00DF
    19         -00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
    20         -011F00F100F200F300F400F500F600F700F800F900FA00FB00FC0131015F00FF

Deleted encodings/koi8-r.enc.

     1         -# Encoding file: koi8-r, single-byte
     2         -S
     3         -003F 0 1
     4         -00
     5         -0000000100020003000400050006000700080009000A000B000C000D000E000F
     6         -0010001100120013001400150016001700180019001A001B001C001D001E001F
     7         -0020002100220023002400250026002700280029002A002B002C002D002E002F
     8         -0030003100320033003400350036003700380039003A003B003C003D003E003F
     9         -0040004100420043004400450046004700480049004A004B004C004D004E004F
    10         -0050005100520053005400550056005700580059005A005B005C005D005E005F
    11         -0060006100620063006400650066006700680069006A006B006C006D006E006F
    12         -0070007100720073007400750076007700780079007A007B007C007D007E007F
    13         -25002502250C251025142518251C2524252C2534253C258025842588258C2590
    14         -259125922593232025A02219221A22482264226500A0232100B000B200B700F7
    15         -25502551255204512553255425552556255725582559255A255B255C255D255E
    16         -255F25602561040125622563256425652566256725682569256A256B256C00A9
    17         -044E0430043104460434043504440433044504380439043A043B043C043D043E
    18         -043F044F044004410442044304360432044C044B04370448044D04490447044A
    19         -042E0410041104260414041504240413042504180419041A041B041C041D041E
    20         -041F042F042004210422042304160412042C042B04170428042D04290427042A

Changes to expat/COPYING.

     1         -Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
     2         -                               and Clark Cooper
     3         -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.
            1  +Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper
            2  +Copyright (c) 2001-2017 Expat maintainers
     4      3   
     5      4   Permission is hereby granted, free of charge, to any person obtaining
     6      5   a copy of this software and associated documentation files (the
     7      6   "Software"), to deal in the Software without restriction, including
     8      7   without limitation the rights to use, copy, modify, merge, publish,
     9      8   distribute, sublicense, and/or sell copies of the Software, and to
    10      9   permit persons to whom the Software is furnished to do so, subject to

Changes to expat/Changes.

            1  +NOTE: We are looking for help with a few things:
            2  +      https://github.com/libexpat/libexpat/labels/help%20wanted
            3  +      If you can help, please get in touch.  Thanks!
            4  +
            5  +Release 2.2.5 Tue October 31 2017
            6  +        Bug fixes:
            7  +              #8  If the parser runs out of memory, make sure its internal
            8  +                    state reflects the memory it actually has, not the memory
            9  +                    it wanted to have.
           10  +             #11  The default handler wasn't being called when it should for
           11  +                    a SYSTEM or PUBLIC doctype if an entity declaration handler
           12  +                    was registered.
           13  +       #137 #138  Fix a case of mistakenly reported parsing success where
           14  +                    XML_StopParser was called from an element handler
           15  +            #162  Function XML_ErrorString was returning NULL rather than
           16  +                    a message for code XML_ERROR_INVALID_ARGUMENT
           17  +                    introduced with release 2.2.1
           18  +
           19  +        Other changes:
           20  +            #106  xmlwf: Add argument -N adding notation declarations
           21  +        #75 #106  Test suite: Resolve expected failure cases where xmlwf
           22  +                    output was incomplete
           23  +            #127  Windows: Fix test suite compilation
           24  +       #126 #127  Windows: Fix compilation for Visual Studio 2012
           25  +        #33 #132  tests: Mass-fix compilation for XML_UNICODE_WCHAR_T
           26  +            #129  examples: Fix compilation for XML_UNICODE_WCHAR_T
           27  +            #130  benchmark: Fix compilation for XML_UNICODE_WCHAR_T
           28  +            #144  xmlwf: Fix compilation for XML_UNICODE_WCHAR_T; still needs
           29  +                    Windows or MinGW for 2-byte wchar_t
           30  +              #9  Address two Clang Static Analyzer false positives
           31  +             #59  Resolve troublesome macros hiding parser struct membership
           32  +                    and dereferencing that pointer
           33  +              #6  Resolve superfluous internal malloc/realloc switch
           34  +       #153 #155  Improve docbook2x-man detection
           35  +            #160  Undefine NDEBUG in the test suite (rather than rejecting it)
           36  +            #161  Address compiler warnings
           37  +                  Version info bumped from 7:6:6 to 7:7:6
           38  +
           39  +        Special thanks to:
           40  +            Benbuck Nason
           41  +            Hans Wennborg
           42  +            José Gutiérrez de la Concha
           43  +            Pedro Monreal Gonzalez
           44  +            Rhodri James
           45  +            Rolf Ade
           46  +            Stephen Groat
           47  +                 and
           48  +            Core Infrastructure Initiative
           49  +
           50  +Release 2.2.4 Sat August 19 2017
           51  +        Bug fixes:
           52  +            #115  Fix copying of partial characters for UTF-8 input
           53  +
           54  +        Other changes:
           55  +            #109  Fix "make check" for non-x86 architectures that default
           56  +                    to unsigned type char (-128..127 rather than 0..255)
           57  +            #109  coverage.sh: Cover -funsigned-char
           58  +                  Autotools: Introduce --without-xmlwf argument
           59  +             #65  Autotools: Replace handwritten Makefile with GNU Automake
           60  +             #43  CMake: Auto-detect high quality entropy extractors, add new
           61  +                    option USE_libbsd=ON to use arc4random_buf of libbsd
           62  +             #74  CMake: Add -fno-strict-aliasing only where supported
           63  +            #114  CMake: Always honor manually set BUILD_* options
           64  +            #114  CMake: Compile man page if docbook2x-man is available, only
           65  +            #117  Include file tests/xmltest.log.expected in source tarball
           66  +                    (required for "make run-xmltest")
           67  +            #117  Include (existing) Visual Studio 2013 files in source tarball
           68  +                  Improve test suite error output
           69  +            #111  Fix some typos in documentation
           70  +                  Version info bumped from 7:5:6 to 7:6:6
           71  +
           72  +        Special thanks to:
           73  +            Jakub Wilk
           74  +            Joe Orton
           75  +            Lin Tian
           76  +            Rolf Eike Beer
           77  +
           78  +Release 2.2.3 Wed August 2 2017
           79  +        Security fixes:
           80  +             #82  CVE-2017-11742 -- Windows: Fix DLL hijacking vulnerability
           81  +                    using Steve Holme's LoadLibrary wrapper for/of cURL
           82  +
           83  +        Bug fixes:
           84  +             #85  Fix a dangling pointer issue related to realloc
           85  +
           86  +        Other changes:
           87  +                  Increase code coverage
           88  +             #91  Linux: Allow getrandom to fail if nonblocking pool has not
           89  +                    yet been initialized and read /dev/urandom then, instead.
           90  +                    This is in line with what recent Python does.
           91  +             #81  Pre-10.7/Lion macOS: Support entropy from arc4random
           92  +             #86  Check that a UTF-16 encoding in an XML declaration has the
           93  +                    right endianness
           94  +        #4 #5 #7  Recover correctly when some reallocations fail
           95  +                  Repair "./configure && make" for systems without any
           96  +                    provider of high quality entropy
           97  +                    and try reading /dev/urandom on those
           98  +                  Ensure that user-defined character encodings have converter
           99  +                    functions when they are needed
          100  +                  Fix mis-leading description of argument -c in xmlwf.1
          101  +                  Rely on macro HAVE_ARC4RANDOM_BUF (rather than __CloudABI__)
          102  +                    for CloudABI
          103  +            #100  Fix use of SIPHASH_MAIN in siphash.h
          104  +             #23  Test suite: Fix memory leaks
          105  +                  Version info bumped from 7:4:6 to 7:5:6
          106  +
          107  +        Special thanks to:
          108  +            Chanho Park
          109  +            Joe Orton
          110  +            Pascal Cuoq
          111  +            Rhodri James
          112  +            Simon McVittie
          113  +            Vadim Zeitlin
          114  +            Viktor Szakats
          115  +                 and
          116  +            Core Infrastructure Initiative
          117  +
          118  +Release 2.2.2 Wed July 12 2017
          119  +        Security fixes:
          120  +             #43  Protect against compilation without any source of high
          121  +                    quality entropy enabled, e.g. with CMake build system;
          122  +                    commit ff0207e6076e9828e536b8d9cd45c9c92069b895
          123  +             #60  Windows with _UNICODE:
          124  +                    Unintended use of LoadLibraryW with a non-wide string
          125  +                    resulted in failure to load advapi32.dll and degradation
          126  +                    in quality of used entropy when compiled with _UNICODE for
          127  +                    Windows; you can launch existing binaries with
          128  +                    EXPAT_ENTROPY_DEBUG=1 in the environment to inspect the
          129  +                    quality of entropy used during runtime; commits
          130  +                    * 95b95032f907ef1cd17ee7a9a1768010a825d61d
          131  +                    * 73a5a2e9c081f49f2d775cf7ced864158b68dc80
          132  +   [MOX-006]      Fix non-NULL parser parameter validation in XML_Parse;
          133  +                    resulted in NULL dereference, previously;
          134  +                    commit ac256dafdffc9622ab0dc2c62fcecb0dfcfa71fe
          135  +
          136  +        Bug fixes:
          137  +             #69  Fix improper use of unsigned long long integer literals
          138  +
          139  +        Other changes:
          140  +             #73  Start requiring a C99 compiler
          141  +             #49  Fix "==" Bashism in configure script
          142  +             #50  Fix too eager getrandom detection for Debian GNU/kFreeBSD
          143  +             #52    and macOS
          144  +             #51  Address lack of stdint.h in Visual Studio 2003 to 2008
          145  +             #58  Address compile warnings
          146  +             #68  Fix "./buildconf.sh && ./configure" for some versions
          147  +                    of Dash for /bin/sh
          148  +             #72  CMake: Ease use of Expat in context of a parent project
          149  +                    with multiple CMakeLists.txt files
          150  +             #72  CMake: Resolve mistaken executable permissions
          151  +             #76  Address compile warning with -DNDEBUG (not recommended!)
          152  +             #77  Address compile warning about macro redefinition
          153  +
          154  +        Special thanks to:
          155  +            Alexander Bluhm
          156  +            Ben Boeckel
          157  +            Cătălin Răceanu
          158  +            Kerin Millar
          159  +            László Böszörményi
          160  +            S. P. Zeidler
          161  +            Segev Finer
          162  +            Václav Slavík
          163  +            Victor Stinner
          164  +            Viktor Szakats
          165  +                 and
          166  +            Radically Open Security
          167  +
          168  +Release 2.2.1 Sat June 17 2017
          169  +        Security fixes:
          170  +                  CVE-2017-9233 -- External entity infinite loop DoS
          171  +                    Details: https://libexpat.github.io/doc/cve-2017-9233/
          172  +                    Commit c4bf96bb51dd2a1b0e185374362ee136fe2c9d7f
          173  +   [MOX-002]      CVE-2016-9063 -- Detect integer overflow; commit
          174  +                    d4f735b88d9932bd5039df2335eefdd0723dbe20
          175  +                    (Fixed version of existing downstream patches!)
          176  +   (SF.net) #539  Fix regression from fix to CVE-2016-0718 cutting off
          177  +                    longer tag names; commits
          178  +                    * 896b6c1fd3b842f377d1b62135dccf0a579cf65d
          179  +                    * af507cef2c93cb8d40062a0abe43a4f4e9158fb2
          180  +             #16    * 0dbbf43fdb20f593ddf4fa1ff67288000dd4a7fd
          181  +             #25  More integer overflow detection (function poolGrow); commits
          182  +                    * 810b74e4703dcfdd8f404e3cb177d44684775143
          183  +                    * 44178553f3539ce69d34abee77a05e879a7982ac
          184  +   [MOX-002]      Detect overflow from len=INT_MAX call to XML_Parse; commits
          185  +                    * 4be2cb5afcc018d996f34bbbce6374b7befad47f
          186  +                    * 7e5b71b748491b6e459e5c9a1d090820f94544d8
          187  +   [MOX-005] #30  Use high quality entropy for hash initialization:
          188  +                    * arc4random_buf on BSD, systems with libbsd
          189  +                      (when configured with --with-libbsd), CloudABI
          190  +                    * RtlGenRandom on Windows XP / Server 2003 and later
          191  +                    * getrandom on Linux 3.17+
          192  +                    In a way, that's still part of CVE-2016-5300.
          193  +                    https://github.com/libexpat/libexpat/pull/30/commits
          194  +   [MOX-005]      For the low quality entropy extraction fallback code,
          195  +                    the parser instance address can no longer leak, commit
          196  +                    04ad658bd3079dd15cb60fc67087900f0ff4b083
          197  +   [MOX-003]      Prevent use of uninitialised variable; commit
          198  +   [MOX-004]        a4dc944f37b664a3ca7199c624a98ee37babdb4b
          199  +                  Add missing parameter validation to public API functions
          200  +                    and dedicated error code XML_ERROR_INVALID_ARGUMENT:
          201  +   [MOX-006]        * NULL checks; commits
          202  +                      * d37f74b2b7149a3a95a680c4c4cd2a451a51d60a (merge/many)
          203  +                      * 9ed727064b675b7180c98cb3d4f75efba6966681
          204  +                      * 6a747c837c50114dfa413994e07c0ba477be4534
          205  +                    * Negative length (XML_Parse); commit
          206  +   [MOX-002]          70db8d2538a10f4c022655d6895e4c3e78692e7f
          207  +   [MOX-001] #35  Change hash algorithm to William Ahern's version of SipHash
          208  +                    to go further with fixing CVE-2012-0876.
          209  +                    https://github.com/libexpat/libexpat/pull/39/commits
          210  +
          211  +        Bug fixes:
          212  +             #32  Fix sharing of hash salt across parsers;
          213  +                    relevant where XML_ExternalEntityParserCreate is called
          214  +                    prior to XML_Parse, in particular (e.g. FBReader)
          215  +             #28  xmlwf: Auto-disable use of memory-mapping (and parsing
          216  +                    as a single chunk) for files larger than ~1 GB (2^30 bytes)
          217  +                    rather than failing with error "out of memory"
          218  +              #3  Fix double free after malloc failure in DTD code; commit
          219  +                    7ae9c3d3af433cd4defe95234eae7dc8ed15637f
          220  +             #17  Fix memory leak on parser error for unbound XML attribute
          221  +                    prefix with new namespaces defined in the same tag;
          222  +                    found by Google's OSS-Fuzz; commits
          223  +                    * 16f87daae5a16132e479e4f71862128c7a915c73
          224  +                    * b47dbc9745932c160893d433220e462bd605f8cd
          225  +                  xmlwf on Windows: Add missing calls to CloseHandle
          226  +
          227  +        New features:
          228  +             #30  Introduced environment switch EXPAT_ENTROPY_DEBUG=1
          229  +                    for runtime debugging of entropy extraction
          230  +
          231  +        Other changes:
          232  +                  Increase code coverage
          233  +             #33  Reject use of XML_UNICODE_WCHAR_T with sizeof(wchar_t) != 2;
          234  +                    XML_UNICODE_WCHAR_T was never meant to be used outside
          235  +                    of Windows; 4-byte wchar_t is common on Linux
          236  +   (SF.net) #538  Start using -fno-strict-aliasing
          237  +   (SF.net) #540  Support compilation against cloudlibc of CloudABI
          238  +                  Allow MinGW cross-compilation
          239  +   (SF.net) #534  CMake: Introduce option "BUILD_doc" (enabled by default)
          240  +                    to bypass compilation of the xmlwf.1 man page
          241  +   (SF.net)  pr2  CMake: Introduce option "INSTALL" (enabled by default)
          242  +                    to bypass installation of expat files
          243  +                  CMake: Fix ninja support
          244  +                  Autotools: Add parameters --enable-xml-context [COUNT]
          245  +                    and --disable-xml-context; default of context of 1024
          246  +                    bytes enabled unchanged
          247  +             #14  Drop AmigaOS 4.x code and includes
          248  +             #14  Drop ancient build systems:
          249  +                    * Borland C++ Builder
          250  +                    * OpenVMS
          251  +                    * Open Watcom
          252  +                    * Visual Studio 6.0
          253  +                    * Pre-X Mac OS (MPW Makefile)
          254  +                    If you happen to rely on some of these, please get in
          255  +                    touch for joining with maintenance.
          256  +             #10  Move from WIN32 to _WIN32
          257  +             #13  Fix "make run-xmltest" order instability
          258  +                  Address compile warnings
          259  +                  Bump version info from 7:2:6 to 7:3:6
          260  +                  Add AUTHORS file
          261  +
          262  +        Infrastructure:
          263  +              #1  Migrate from SourceForge to GitHub (except downloads):
          264  +                    https://github.com/libexpat/
          265  +              #1  Re-create http://libexpat.org/ project website
          266  +                  Start utilizing Travis CI
          267  +
          268  +        Special thanks to:
          269  +            Andy Wang
          270  +            Don Lewis
          271  +            Ed Schouten
          272  +            Karl Waclawek
          273  +            Pascal Cuoq
          274  +            Rhodri James
          275  +            Sergei Nikulov
          276  +            Tobias Taschner
          277  +            Viktor Szakats
          278  +                 and
          279  +            Core Infrastructure Initiative
          280  +            Mozilla Foundation (MOSS Track 3: Secure Open Source)
          281  +            Radically Open Security
          282  +
          283  +Release 2.2.0 Tue June 21 2016
          284  +        Security fixes:
          285  +            #537  CVE-2016-0718 -- Fix crash on malformed input
          286  +                  CVE-2016-4472 -- Improve insufficient fix to CVE-2015-1283 /
          287  +                                   CVE-2015-2716 introduced with Expat 2.1.1
          288  +            #499  CVE-2016-5300 -- Use more entropy for hash initialization
          289  +                                   than the original fix to CVE-2012-0876
          290  +            #519  CVE-2012-6702 -- Resolve troublesome internal call to srand
          291  +                                   that was introduced with Expat 2.1.0
          292  +                                   when addressing CVE-2012-0876 (issue #496)
          293  +
          294  +        Bug fixes:
          295  +                  Fix uninitialized reads of size 1
          296  +                    (e.g. in little2_updatePosition)
          297  +                  Fix detection of UTF-8 character boundaries
          298  +
          299  +        Other changes:
          300  +            #532  Fix compilation for Visual Studio 2010 (keyword "C99")
          301  +                  Autotools: Resolve use of "$<" to better support bmake
          302  +                  Autotools: Add QA script "qa.sh" (and make target "qa")
          303  +                  Autotools: Respect CXXFLAGS if given
          304  +                  Autotools: Fix "make run-xmltest"
          305  +                  Autotools: Have "make run-xmltest" check for expected output
          306  +             p90  CMake: Fix static build (BUILD_shared=OFF) on Windows
          307  +            #536  CMake: Add soversion, support -DNO_SONAME=yes to bypass
          308  +            #323  CMake: Add suffix "d" to differentiate debug from release
          309  +                  CMake: Define WIN32 with CMake on Windows
          310  +                  Annotate memory allocators for GCC
          311  +                  Address all currently known compile warnings
          312  +                  Make sure that API symbols remain visible despite
          313  +                    -fvisibility=hidden
          314  +                  Remove executable flag from source files
          315  +                  Resolve COMPILED_FROM_DSP in favor of WIN32
          316  +
          317  +        Special thanks to:
          318  +            Björn Lindahl
          319  +            Christian Heimes
          320  +            Cristian Rodríguez
          321  +            Daniel Krügler
          322  +            Gustavo Grieco
          323  +            Karl Waclawek
          324  +            László Böszörményi
          325  +            Marco Grassi
          326  +            Pascal Cuoq
          327  +            Sergei Nikulov
          328  +            Thomas Beutlich
          329  +            Warren Young
          330  +            Yann Droneaud
          331  +
          332  +Release 2.1.1 Sat March 12 2016
          333  +        Security fixes:
          334  +            #582: CVE-2015-1283 - Multiple integer overflows in XML_GetBuffer
          335  +
          336  +        Bug fixes:
          337  +            #502: Fix potential null pointer dereference
          338  +            #520: Symbol XML_SetHashSalt was not exported
          339  +            Output of "xmlwf -h" was incomplete
          340  +
          341  +        Other changes:
          342  +            #503: Document behavior of calling XML_SetHashSalt with salt 0
          343  +            Minor improvements to man page xmlwf(1)
          344  +            Improvements to the experimental CMake build system
          345  +            libtool now invoked with --verbose
          346  +
          347  +Release 2.1.0 Sat March 24 2012
          348  +        - Security fixes:
          349  +          #2958794: CVE-2012-1148 - Memory leak in poolGrow.
          350  +          #2895533: CVE-2012-1147 - Resource leak in readfilemap.c.
          351  +          #3496608: CVE-2012-0876 - Hash DOS attack.
          352  +          #2894085: CVE-2009-3560 - Buffer over-read and crash in big2_toUtf8().
          353  +          #1990430: CVE-2009-3720 - Parser crash with special UTF-8 sequences.
          354  +        - Bug Fixes:
          355  +          #1742315: Harmful XML_ParserCreateNS suggestion.
          356  +          #1785430: Expat build fails on linux-amd64 with gcc version>=4.1 -O3.
          357  +          #1983953, 2517952, 2517962, 2649838: 
          358  +                Build modifications using autoreconf instead of buildconf.sh.
          359  +          #2815947, #2884086: OBJEXT and EXEEXT support while building.
          360  +          #2517938: xmlwf should return non-zero exit status if not well-formed.
          361  +          #2517946: Wrong statement about XMLDecl in xmlwf.1 and xmlwf.sgml.
          362  +          #2855609: Dangling positionPtr after error.
          363  +          #2990652: CMake support.
          364  +          #3010819: UNEXPECTED_STATE with a trailing "%" in entity value.
          365  +          #3206497: Uninitialized memory returned from XML_Parse.
          366  +          #3287849: make check fails on mingw-w64.
          367  +        - Patches:
          368  +          #1749198: pkg-config support.
          369  +          #3010222: Fix for bug #3010819.
          370  +          #3312568: CMake support.
          371  +          #3446384: Report byte offsets for attr names and values.
          372  +        - New Features / API changes:
          373  +          Added new API member XML_SetHashSalt() that allows setting an initial
          374  +                value (salt) for hash calculations. This is part of the fix for
          375  +                bug #3496608 to randomize hash parameters.
          376  +          When compiled with XML_ATTR_INFO defined, adds new API member
          377  +                XML_GetAttributeInfo() that allows retrieving the byte
          378  +                offsets for attribute names and values (patch #3446384).
          379  +          Added CMake build system.
          380  +                See bug #2990652 and patch #3312568.
          381  +          Added run-benchmark target to Makefile.in - relies on testdata module
          382  +                present in the same relative location as in the repository.
          383  +          
     1    384   Release 2.0.1 Tue June 5 2007
     2         -        - Fixed bugs #1515266, 1515600: The character data handler's calling
          385  +        - Fixed bugs #1515266, #1515600: The character data handler's calling
     3    386             of XML_StopParser() was not handled properly; if the parser was
     4    387             stopped and the handler set to NULL, the parser would segfault.
     5    388           - Fixed bug #1690883: Expat failed on EBCDIC systems as it assumed
     6    389             some character constants to be ASCII encoded.
     7    390           - Minor cleanups of the test harness.
     8    391           - Fixed xmlwf bug #1513566: "out of memory" error on file size zero.
     9    392           - Fixed outline.c bug #1543233: missing a final XML_ParserFree() call.
    10    393           - Fixes and improvements for Windows platform:
    11         -          bugs #1409451, #1476160, 1548182, 1602769, 1717322.
          394  +          bugs #1409451, #1476160, #1548182, #1602769, #1717322.
    12    395           - Build fixes for various platforms:
    13    396             HP-UX, Tru64, Solaris 9: patch #1437840, bug #1196180.
    14    397             All Unix: #1554618 (refreshed config.sub/config.guess).
    15    398                       #1490371, #1613457: support both, DESTDIR and INSTALL_ROOT,
    16    399                       without relying on GNU-Make specific features.
    17    400             #1647805: Patched configure.in to work better with Intel compiler.
    18    401           - Fixes to Makefile.in to have make check work correctly:
................................................................................
    26    409           - Fixed headers for use from C++.
    27    410           - XML_GetCurrentLineNumber() and  XML_GetCurrentColumnNumber()
    28    411             now return unsigned integers.
    29    412           - Added XML_LARGE_SIZE switch to enable 64-bit integers for
    30    413             byte indexes and line/column numbers.
    31    414           - Updated to use libtool 1.5.22 (the most recent).
    32    415           - Added support for AmigaOS.
    33         -        - Some mostly minor bug fixes. SF issues include: 1006708,
    34         -          1021776, 1023646, 1114960, 1156398, 1221160, 1271642.
          416  +        - Some mostly minor bug fixes. SF issues include: #1006708,
          417  +          #1021776, #1023646, #1114960, #1156398, #1221160, #1271642.
    35    418   
    36    419   Release 1.95.8 Fri Jul 23 2004
    37    420           - Major new feature: suspend/resume.  Handlers can now request
    38    421             that a parse be suspended for later resumption or aborted
    39    422             altogether.  See "Temporarily Stopping Parsing" in the
    40    423             documentation for more details.
    41    424           - Some mostly minor bug fixes, but compilation should no
    42    425             longer generate warnings on most platforms.  SF issues
    43         -          include: 827319, 840173, 846309, 888329, 896188, 923913,
    44         -          928113, 961698, 985192.
          426  +          include: #827319, #840173, #846309, #888329, #896188, #923913,
          427  +          #928113, #961698, #985192.
    45    428   
    46    429   Release 1.95.7 Mon Oct 20 2003
    47    430           - Fixed enum XML_Status issue (reported on SourceForge many
    48    431             times), so compilers that are properly picky will be happy.
    49    432           - Introduced an XMLCALL macro to control the calling
    50    433             convention used by the Expat API; this macro should be used
    51    434             to annotate prototypes and definitions of callback
    52    435             implementations in code compiled with a calling convention
    53    436             other than the default convention for the host platform.
    54    437           - Improved ability to build without the configure-generated
    55    438             expat_config.h header.  This is useful for applications
    56    439             which embed Expat rather than linking in the library.
    57         -        - Fixed a variety of bugs: see SF issues 458907, 609603,
    58         -          676844, 679754, 692878, 692964, 695401, 699323, 699487,
    59         -          820946.
          440  +        - Fixed a variety of bugs: see SF issues #458907, #609603,
          441  +          #676844, #679754, #692878, #692964, #695401, #699323, #699487,
          442  +          #820946.
    60    443           - Improved hash table lookups.
    61    444           - Added more regression tests and improved documentation.
    62    445   
    63    446   Release 1.95.6 Tue Jan 28 2003
    64    447           - Added XML_FreeContentModel().
    65    448           - Added XML_MemMalloc(), XML_MemRealloc(), XML_MemFree().
    66         -        - Fixed a variety of bugs: see SF issues 615606, 616863,
    67         -          618199, 653180, 673791.
          449  +        - Fixed a variety of bugs: see SF issues #615606, #616863,
          450  +          #618199, #653180, #673791.
    68    451           - Enhanced the regression test suite.
    69         -        - Man page improvements: includes SF issue 632146.
          452  +        - Man page improvements: includes SF issue #632146.
    70    453   
    71    454   Release 1.95.5 Fri Sep 6 2002
    72    455           - Added XML_UseForeignDTD() for improved SAX2 support.
    73    456           - Added XML_GetFeatureList().
    74    457           - Defined XML_Bool type and the values XML_TRUE and XML_FALSE.
    75    458           - Use an incomplete struct instead of a void* for the parser
    76    459             (may not retain).
................................................................................
    80    463             Initial patch contributed by Darryl Miles.
    81    464           - Removed unnecessary DllMain() function that caused static
    82    465             linking into a DLL to be difficult.
    83    466           - Added VC++ projects for building static libraries.
    84    467           - Reduced line-length for all source code and headers to be
    85    468             no longer than 80 characters, to help with AS/400 support.
    86    469           - Reduced memory copying during parsing (SF patch #600964).
    87         -        - Fixed a variety of bugs: see SF issues 580793, 434664,
    88         -          483514, 580503, 581069, 584041, 584183, 584832, 585537,
    89         -          596555, 596678, 598352, 598944, 599715, 600479, 600971.
          470  +        - Fixed a variety of bugs: see SF issues #580793, #434664,
          471  +          #483514, #580503, #581069, #584041, #584183, #584832, #585537,
          472  +          #596555, #596678, #598352, #598944, #599715, #600479, #600971.
    90    473   
    91    474   Release 1.95.4 Fri Jul 12 2002
    92    475           - Added support for VMS, contributed by Craig Berry.  See
    93    476             vms/README.vms for more information.
    94    477           - Added Mac OS (classic) support, with a makefile for MPW,
    95    478             contributed by Thomas Wegner and Daryle Walker.
    96    479           - Added Borland C++ Builder 5 / BCC 5.5 support, contributed
    97    480             by Patrick McConnell (SF patch #538032).
    98         -        - Fixed a variety of bugs: see SF issues 441449, 563184,
    99         -          564342, 566334, 566901, 569461, 570263, 575168, 579196.
          481  +        - Fixed a variety of bugs: see SF issues #441449, #563184,
          482  +          #564342, #566334, #566901, #569461, #570263, #575168, #579196.
   100    483           - Made skippedEntityHandler conform to SAX2 (see source comment)
   101    484           - Re-implemented WFC: Entity Declared from XML 1.0 spec and
   102    485             added a new error "entity declared in parameter entity":
   103         -          see SF bug report 569461 and SF patch 578161
          486  +          see SF bug report #569461 and SF patch #578161
   104    487           - Re-implemented section 5.1 from XML 1.0 spec:
   105         -          see SF bug report 570263 and SF patch 578161
          488  +          see SF bug report #570263 and SF patch #578161
   106    489   
   107    490   Release 1.95.3 Mon Jun 3 2002
   108    491           - Added a project to the MSVC workspace to create a wchar_t
   109    492             version of the library; the DLLs are named libexpatw.dll.
   110    493           - Changed the name of the Windows DLLs from expat.dll to
   111    494             libexpat.dll; this fixes SF bug #432456.
   112    495           - Added the XML_ParserReset() API function.
   113    496           - Fixed XML_SetReturnNSTriplet() to work for element names.
   114    497           - Made the XML_UNICODE builds usable (thanks, Karl!).
   115    498           - Allow xmlwf to read from standard input.
   116    499           - Install a man page for xmlwf on Unix systems.
   117         -        - Fixed many bugs; see SF bug reports 231864, 461380, 464837,
   118         -          466885, 469226, 477667, 484419, 487840, 494749, 496505,
   119         -          547350.  Other bugs which we can't test as easily may also
          500  +        - Fixed many bugs; see SF bug reports #231864, #461380, #464837,
          501  +          #466885, #469226, #477667, #484419, #487840, #494749, #496505,
          502  +          #547350.  Other bugs which we can't test as easily may also
   120    503             have been fixed, especially in the area of build support.
   121    504   
   122    505   Release 1.95.2 Fri Jul 27 2001
   123    506           - More changes to make MSVC happy with the build; add a single
   124    507             workspace to support both the library and xmlwf application.
   125    508           - Added a Windows installer for Windows users; includes
   126    509             xmlwf.exe.

Deleted expat/README.

     1         -
     2         -                        Expat, Release 2.0.1
     3         -
     4         -This is Expat, a C library for parsing XML, written by James Clark.
     5         -Expat is a stream-oriented XML parser.  This means that you register
     6         -handlers with the parser before starting the parse.  These handlers
     7         -are called when the parser discovers the associated structures in the
     8         -document being parsed.  A start tag is an example of the kind of
     9         -structures for which you may register handlers.
    10         -
    11         -Windows users should use the expat_win32bin package, which includes
    12         -both precompiled libraries and executables, and source code for
    13         -developers.
    14         -
    15         -Expat is free software.  You may copy, distribute, and modify it under
    16         -the terms of the License contained in the file COPYING distributed
    17         -with this package.  This license is the same as the MIT/X Consortium
    18         -license.
    19         -
    20         -Versions of Expat that have an odd minor version (the middle number in
    21         -the release above), are development releases and should be considered
    22         -as beta software.  Releases with even minor version numbers are
    23         -intended to be production grade software.
    24         -
    25         -If you are building Expat from a check-out from the CVS repository,
    26         -you need to run a script that generates the configure script using the
    27         -GNU autoconf and libtool tools.  To do this, you need to have
    28         -autoconf 2.52 or newer and libtool 1.4 or newer (1.5 or newer preferred).
    29         -Run the script like this:
    30         -
    31         -        ./buildconf.sh
    32         -
    33         -Once this has been done, follow the same instructions as for building
    34         -from a source distribution.
    35         -
    36         -To build Expat from a source distribution, you first run the
    37         -configuration shell script in the top level distribution directory:
    38         -
    39         -        ./configure
    40         -
    41         -There are many options which you may provide to configure (which you
    42         -can discover by running configure with the --help option).  But the
    43         -one of most interest is the one that sets the installation directory.
    44         -By default, the configure script will set things up to install
    45         -libexpat into /usr/local/lib, expat.h into /usr/local/include, and
    46         -xmlwf into /usr/local/bin.  If, for example, you'd prefer to install
    47         -into /home/me/mystuff/lib, /home/me/mystuff/include, and
    48         -/home/me/mystuff/bin, you can tell configure about that with:
    49         -
    50         -        ./configure --prefix=/home/me/mystuff
    51         -        
    52         -Another interesting option is to enable 64-bit integer support for
    53         -line and column numbers and the over-all byte index:
    54         -
    55         -        ./configure CPPFLAGS=-DXML_LARGE_SIZE
    56         -        
    57         -However, such a modification would be a breaking change to the ABI
    58         -and is therefore not recommended for general use - e.g. as part of
    59         -a Linux distribution - but rather for builds with special requirements.
    60         -
    61         -After running the configure script, the "make" command will build
    62         -things and "make install" will install things into their proper
    63         -location.  Have a look at the "Makefile" to learn about additional
    64         -"make" options.  Note that you need to have write permission into
    65         -the directories into which things will be installed.
    66         -
    67         -If you are interested in building Expat to provide document
    68         -information in UTF-16 rather than the default UTF-8, follow these
    69         -instructions (after having run "make distclean"):
    70         -
    71         -        1. For UTF-16 output as unsigned short (and version/error
    72         -           strings as char), run:
    73         -
    74         -               ./configure CPPFLAGS=-DXML_UNICODE
    75         -
    76         -           For UTF-16 output as wchar_t (incl. version/error strings),
    77         -           run:
    78         -
    79         -               ./configure CFLAGS="-g -O2 -fshort-wchar" \
    80         -                           CPPFLAGS=-DXML_UNICODE_WCHAR_T
    81         -
    82         -        2. Edit the MakeFile, changing:
    83         -
    84         -               LIBRARY = libexpat.la
    85         -
    86         -           to:
    87         -
    88         -               LIBRARY = libexpatw.la
    89         -
    90         -           (Note the additional "w" in the library name.)
    91         -
    92         -        3. Run "make buildlib" (which builds the library only).
    93         -           Or, to save step 2, run "make buildlib LIBRARY=libexpatw.la".
    94         -
    95         -        4. Run "make installlib" (which installs the library only).
    96         -           Or, if step 2 was omitted, run "make installlib LIBRARY=libexpatw.la".
    97         -           
    98         -Using DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default
    99         -value for DESTDIR, and the rest of the make file using only DESTDIR.
   100         -It works as follows:
   101         -   $ make install DESTDIR=/path/to/image
   102         -overrides the in-makefile set DESTDIR, while both
   103         -   $ INSTALL_ROOT=/path/to/image make install
   104         -   $ make install INSTALL_ROOT=/path/to/image
   105         -use DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the
   106         -environment, because variable-setting priority is
   107         -1) commandline
   108         -2) in-makefile
   109         -3) environment           
   110         -
   111         -Note for Solaris users:  The "ar" command is usually located in
   112         -"/usr/ccs/bin", which is not in the default PATH.  You will need to
   113         -add this to your path for the "make" command, and probably also switch
   114         -to GNU make (the "make" found in /usr/ccs/bin does not seem to work
   115         -properly -- appearantly it does not understand .PHONY directives).  If
   116         -you're using ksh or bash, use this command to build:
   117         -
   118         -        PATH=/usr/ccs/bin:$PATH make
   119         -
   120         -When using Expat with a project using autoconf for configuration, you
   121         -can use the probing macro in conftools/expat.m4 to determine how to
   122         -include Expat.  See the comments at the top of that file for more
   123         -information.
   124         -
   125         -A reference manual is available in the file doc/reference.html in this
   126         -distribution.
   127         -
   128         -The homepage for this project is http://www.libexpat.org/.  There
   129         -are links there to connect you to the bug reports page.  If you need
   130         -to report a bug when you don't have access to a browser, you may also
   131         -send a bug report by email to expat-bugs@mail.libexpat.org.
   132         -
   133         -Discussion related to the direction of future expat development takes
   134         -place on expat-discuss@mail.libexpat.org.  Archives of this list and
   135         -other Expat-related lists may be found at:
   136         -
   137         -        http://mail.libexpat.org/mailman/listinfo/

Added expat/README.md.

            1  +[![Travis CI Build Status](https://travis-ci.org/libexpat/libexpat.svg?branch=master)](https://travis-ci.org/libexpat/libexpat)
            2  +[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/libexpat/libexpat?svg=true)](https://ci.appveyor.com/project/libexpat/libexpat)
            3  +
            4  +
            5  +# Expat, Release 2.2.5
            6  +
            7  +This is Expat, a C library for parsing XML, started by
            8  +[James Clark](https://en.wikipedia.org/wiki/James_Clark_(programmer)) in 1997.
            9  +Expat is a stream-oriented XML parser.  This means that you register
           10  +handlers with the parser before starting the parse.  These handlers
           11  +are called when the parser discovers the associated structures in the
           12  +document being parsed.  A start tag is an example of the kind of
           13  +structures for which you may register handlers.
           14  +
           15  +Windows users should use the
           16  +[`expat_win32` package](https://sourceforge.net/projects/expat/files/expat_win32/),
           17  +which includes both precompiled libraries and executables, and source code for
           18  +developers.
           19  +
           20  +Expat is [free software](https://www.gnu.org/philosophy/free-sw.en.html).
           21  +You may copy, distribute, and modify it under the terms of the License
           22  +contained in the file
           23  +[`COPYING`](https://github.com/libexpat/libexpat/blob/master/expat/COPYING)
           24  +distributed with this package.
           25  +This license is the same as the MIT/X Consortium license.
           26  +
           27  +If you are building Expat from a check-out from the
           28  +[Git repository](https://github.com/libexpat/libexpat/),
           29  +you need to run a script that generates the configure script using the
           30  +GNU autoconf and libtool tools.  To do this, you need to have
           31  +autoconf 2.58 or newer. Run the script like this:
           32  +
           33  +```console
           34  +./buildconf.sh
           35  +```
           36  +
           37  +Once this has been done, follow the same instructions as for building
           38  +from a source distribution.
           39  +
           40  +To build Expat from a source distribution, you first run the
           41  +configuration shell script in the top level distribution directory:
           42  +
           43  +```console
           44  +./configure
           45  +```
           46  +
           47  +There are many options which you may provide to configure (which you
           48  +can discover by running configure with the `--help` option).  But the
           49  +one of most interest is the one that sets the installation directory.
           50  +By default, the configure script will set things up to install
           51  +libexpat into `/usr/local/lib`, `expat.h` into `/usr/local/include`, and
           52  +`xmlwf` into `/usr/local/bin`.  If, for example, you'd prefer to install
           53  +into `/home/me/mystuff/lib`, `/home/me/mystuff/include`, and
           54  +`/home/me/mystuff/bin`, you can tell `configure` about that with:
           55  +
           56  +```console
           57  +./configure --prefix=/home/me/mystuff
           58  +```
           59  +
           60  +Another interesting option is to enable 64-bit integer support for
           61  +line and column numbers and the over-all byte index:
           62  +
           63  +```console
           64  +./configure CPPFLAGS=-DXML_LARGE_SIZE
           65  +```
           66  +
           67  +However, such a modification would be a breaking change to the ABI
           68  +and is therefore not recommended for general use &mdash; e.g. as part of
           69  +a Linux distribution &mdash; but rather for builds with special requirements.
           70  +
           71  +After running the configure script, the `make` command will build
           72  +things and `make install` will install things into their proper
           73  +location.  Have a look at the `Makefile` to learn about additional
           74  +`make` options.  Note that you need to have write permission into
           75  +the directories into which things will be installed.
           76  +
           77  +If you are interested in building Expat to provide document
           78  +information in UTF-16 encoding rather than the default UTF-8, follow
           79  +these instructions (after having run `make distclean`).
           80  +Please note that we configure with `--without-xmlwf` as xmlwf does not
           81  +support this mode of compilation (yet):
           82  +
           83  +1. Mass-patch `Makefile.am` files to use `libexpatw.la` for a library name:
           84  +   <br/>
           85  +   `find -name Makefile.am -exec sed
           86  +       -e 's,libexpat\.la,libexpatw.la,'
           87  +       -e 's,libexpat_la,libexpatw_la,'
           88  +       -i {} +`
           89  +
           90  +1. Run `automake` to re-write `Makefile.in` files:<br/>
           91  +   `automake`
           92  +
           93  +1. For UTF-16 output as unsigned short (and version/error strings as char),
           94  +   run:<br/>
           95  +   `./configure CPPFLAGS=-DXML_UNICODE --without-xmlwf`<br/>
           96  +   For UTF-16 output as `wchar_t` (incl. version/error strings), run:<br/>
           97  +   `./configure CFLAGS="-g -O2 -fshort-wchar" CPPFLAGS=-DXML_UNICODE_WCHAR_T
           98  +       --without-xmlwf`
           99  +   <br/>Note: The latter requires libc compiled with `-fshort-wchar`, as well.
          100  +
          101  +1. Run `make` (which excludes xmlwf).
          102  +
          103  +1. Run `make install` (again, excludes xmlwf).
          104  +
          105  +Using `DESTDIR` is supported.  It works as follows:
          106  +
          107  +```console
          108  +make install DESTDIR=/path/to/image
          109  +```
          110  +
          111  +overrides the in-makefile set `DESTDIR`, because variable-setting priority is
          112  +
          113  +1. commandline
          114  +1. in-makefile
          115  +1. environment
          116  +
          117  +Note: This only applies to the Expat library itself, building UTF-16 versions
          118  +of xmlwf and the tests is currently not supported.
          119  +
          120  +When using Expat with a project using autoconf for configuration, you
          121  +can use the probing macro in `conftools/expat.m4` to determine how to
          122  +include Expat.  See the comments at the top of that file for more
          123  +information.
          124  +
          125  +A reference manual is available in the file `doc/reference.html` in this
          126  +distribution.

Changes to expat/VERSION.

     1         -expat-2.0.1
            1  +expat-2.2.5

Deleted expat/amigaconfig.h.

     1         -#ifndef AMIGACONFIG_H
     2         -#define AMIGACONFIG_H
     3         -
     4         -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
     5         -#define BYTEORDER 4321
     6         -
     7         -/* Define to 1 if you have the `bcopy' function. */
     8         -#define HAVE_BCOPY 1
     9         -
    10         -/* Define to 1 if you have the <check.h> header file. */
    11         -#undef HAVE_CHECK_H
    12         -
    13         -/* Define to 1 if you have the `memmove' function. */
    14         -#define HAVE_MEMMOVE 1
    15         -
    16         -/* Define to 1 if you have the <unistd.h> header file. */
    17         -#define HAVE_UNISTD_H 1
    18         -
    19         -/* whether byteorder is bigendian */
    20         -#define WORDS_BIGENDIAN
    21         -
    22         -/* Define to specify how much context to retain around the current parse
    23         -   point. */
    24         -#define XML_CONTEXT_BYTES 1024
    25         -
    26         -/* Define to make parameter entity parsing functionality available. */
    27         -#define XML_DTD
    28         -
    29         -/* Define to make XML Namespaces functionality available. */
    30         -#define XML_NS
    31         -
    32         -#endif  /* AMIGACONFIG_H */

Changes to expat/ascii.h.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   #define ASCII_A 0x41
     6     34   #define ASCII_B 0x42
     7     35   #define ASCII_C 0x43
     8     36   #define ASCII_D 0x44
     9     37   #define ASCII_E 0x45

Changes to expat/asciitab.h.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
     6     34   /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
     7     35   /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
     8     36   /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
     9     37   /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,

Changes to expat/expat.h.

     1         -/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   #ifndef Expat_INCLUDED
     6     34   #define Expat_INCLUDED 1
     7     35   
     8     36   #ifdef __VMS
     9     37   /*      0        1         2         3      0        1         2         3
................................................................................
    20     48   #ifdef __cplusplus
    21     49   extern "C" {
    22     50   #endif
    23     51   
    24     52   struct XML_ParserStruct;
    25     53   typedef struct XML_ParserStruct *XML_Parser;
    26     54   
    27         -/* Should this be defined using stdbool.h when C99 is available? */
    28     55   typedef unsigned char XML_Bool;
    29     56   #define XML_TRUE   ((XML_Bool) 1)
    30     57   #define XML_FALSE  ((XML_Bool) 0)
    31     58   
    32     59   /* The XML_Status enum gives the possible return values for several
    33     60      API functions.  The preprocessor #defines are included so this
    34     61      stanza can be added to code that still needs to support older
................................................................................
    91    118     XML_ERROR_NOT_SUSPENDED,
    92    119     XML_ERROR_ABORTED,
    93    120     XML_ERROR_FINISHED,
    94    121     XML_ERROR_SUSPEND_PE,
    95    122     /* Added in 2.0. */
    96    123     XML_ERROR_RESERVED_PREFIX_XML,
    97    124     XML_ERROR_RESERVED_PREFIX_XMLNS,
    98         -  XML_ERROR_RESERVED_NAMESPACE_URI
          125  +  XML_ERROR_RESERVED_NAMESPACE_URI,
          126  +  /* Added in 2.2.1. */
          127  +  XML_ERROR_INVALID_ARGUMENT
    99    128   };
   100    129   
   101    130   enum XML_Content_Type {
   102    131     XML_CTYPE_EMPTY = 1,
   103    132     XML_CTYPE_ANY,
   104    133     XML_CTYPE_MIXED,
   105    134     XML_CTYPE_NAME,
................................................................................
   231    260   */
   232    261   XMLPARSEAPI(XML_Parser)
   233    262   XML_ParserCreate_MM(const XML_Char *encoding,
   234    263                       const XML_Memory_Handling_Suite *memsuite,
   235    264                       const XML_Char *namespaceSeparator);
   236    265   
   237    266   /* Prepare a parser object to be re-used.  This is particularly
   238         -   valuable when memory allocation overhead is disproportionatly high,
          267  +   valuable when memory allocation overhead is disproportionately high,
   239    268      such as when a large number of small documnents need to be parsed.
   240    269      All handlers are cleared from the parser, except for the
   241    270      unknownEncodingHandler. The parser's external state is re-initialized
   242    271      except for the values of ns and ns_triplets.
   243    272   
   244    273      Added in Expat 1.95.3.
   245    274   */
................................................................................
   338    367                                 const XML_Char *notationName);
   339    368   
   340    369   XMLPARSEAPI(void)
   341    370   XML_SetEntityDeclHandler(XML_Parser parser,
   342    371                            XML_EntityDeclHandler handler);
   343    372   
   344    373   /* OBSOLETE -- OBSOLETE -- OBSOLETE
   345         -   This handler has been superceded by the EntityDeclHandler above.
          374  +   This handler has been superseded by the EntityDeclHandler above.
   346    375      It is provided here for backward compatibility.
   347    376   
   348    377      This is called for a declaration of an unparsed (NDATA) entity.
   349    378      The base argument is whatever was set by XML_SetBase. The
   350    379      entityName, systemId and notationName arguments will never be
   351    380      NULL. The other arguments may be.
   352    381   */
................................................................................
   702    731        have no effect after that.  Returns
   703    732        XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
   704    733      Note: If the document does not have a DOCTYPE declaration at all,
   705    734        then startDoctypeDeclHandler and endDoctypeDeclHandler will not
   706    735        be called, despite an external subset being parsed.
   707    736      Note: If XML_DTD is not defined when Expat is compiled, returns
   708    737        XML_ERROR_FEATURE_REQUIRES_XML_DTD.
          738  +   Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT.
   709    739   */
   710    740   XMLPARSEAPI(enum XML_Error)
   711    741   XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
   712    742   
   713    743   
   714    744   /* Sets the base to be used for resolving relative URIs in system
   715    745      identifiers in declarations.  Resolving relative identifiers is
................................................................................
   725    755   XMLPARSEAPI(const XML_Char *)
   726    756   XML_GetBase(XML_Parser parser);
   727    757   
   728    758   /* Returns the number of the attribute/value pairs passed in last call
   729    759      to the XML_StartElementHandler that were specified in the start-tag
   730    760      rather than defaulted. Each attribute/value pair counts as 2; thus
   731    761      this correspondds to an index into the atts array passed to the
   732         -   XML_StartElementHandler.
          762  +   XML_StartElementHandler.  Returns -1 if parser == NULL.
   733    763   */
   734    764   XMLPARSEAPI(int)
   735    765   XML_GetSpecifiedAttributeCount(XML_Parser parser);
   736    766   
   737    767   /* Returns the index of the ID attribute passed in the last call to
   738         -   XML_StartElementHandler, or -1 if there is no ID attribute.  Each
   739         -   attribute/value pair counts as 2; thus this correspondds to an
   740         -   index into the atts array passed to the XML_StartElementHandler.
          768  +   XML_StartElementHandler, or -1 if there is no ID attribute or
          769  +   parser == NULL.  Each attribute/value pair counts as 2; thus this
          770  +   correspondds to an index into the atts array passed to the
          771  +   XML_StartElementHandler.
   741    772   */
   742    773   XMLPARSEAPI(int)
   743    774   XML_GetIdAttributeIndex(XML_Parser parser);
          775  +
          776  +#ifdef XML_ATTR_INFO
          777  +/* Source file byte offsets for the start and end of attribute names and values.
          778  +   The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
          779  +   file an attribute value of "blah" will yield:
          780  +   info->valueEnd - info->valueStart = 4 bytes.
          781  +*/
          782  +typedef struct {
          783  +  XML_Index  nameStart;  /* Offset to beginning of the attribute name. */
          784  +  XML_Index  nameEnd;    /* Offset after the attribute name's last byte. */
          785  +  XML_Index  valueStart; /* Offset to beginning of the attribute value. */
          786  +  XML_Index  valueEnd;   /* Offset after the attribute value's last byte. */
          787  +} XML_AttrInfo;
          788  +
          789  +/* Returns an array of XML_AttrInfo structures for the attribute/value pairs
          790  +   passed in last call to the XML_StartElementHandler that were specified
          791  +   in the start-tag rather than defaulted. Each attribute/value pair counts
          792  +   as 1; thus the number of entries in the array is
          793  +   XML_GetSpecifiedAttributeCount(parser) / 2.
          794  +*/
          795  +XMLPARSEAPI(const XML_AttrInfo *)
          796  +XML_GetAttributeInfo(XML_Parser parser);
          797  +#endif
   744    798   
   745    799   /* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
   746    800      detected.  The last call to XML_Parse must have isFinal true; len
   747    801      may be zero for this call (or any other).
   748    802   
   749    803      Though the return values for these functions has always been
   750    804      described as a Boolean value, the implementation, at least for the
................................................................................
   874    928      XML_ParserFree has been called on the newly created parser.
   875    929      If the library has been compiled without support for parameter
   876    930      entity parsing (ie without XML_DTD being defined), then
   877    931      XML_SetParamEntityParsing will return 0 if parsing of parameter
   878    932      entities is requested; otherwise it will return non-zero.
   879    933      Note: If XML_SetParamEntityParsing is called after XML_Parse or
   880    934         XML_ParseBuffer, then it has no effect and will always return 0.
          935  +   Note: If parser == NULL, the function will do nothing and return 0.
   881    936   */
   882    937   XMLPARSEAPI(int)
   883    938   XML_SetParamEntityParsing(XML_Parser parser,
   884    939                             enum XML_ParamEntityParsing parsing);
          940  +
          941  +/* Sets the hash salt to use for internal hash calculations.
          942  +   Helps in preventing DoS attacks based on predicting hash
          943  +   function behavior. This must be called before parsing is started.
          944  +   Returns 1 if successful, 0 when called after parsing has started.
          945  +   Note: If parser == NULL, the function will do nothing and return 0.
          946  +*/
          947  +XMLPARSEAPI(int)
          948  +XML_SetHashSalt(XML_Parser parser,
          949  +                unsigned long hash_salt);
   885    950   
   886    951   /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
   887    952      XML_GetErrorCode returns information about the error.
   888    953   */
   889    954   XMLPARSEAPI(enum XML_Error)
   890    955   XML_GetErrorCode(XML_Parser parser);
   891    956   
................................................................................
   900    965      event (regardless of whether there was an associated callback).
   901    966      
   902    967      They may also be called after returning from a call to XML_Parse
   903    968      or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then
   904    969      the location is the location of the character at which the error
   905    970      was detected; otherwise the location is the location of the last
   906    971      parse event, as described above.
          972  +
          973  +   Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber
          974  +   return 0 to indicate an error.
          975  +   Note: XML_GetCurrentByteIndex returns -1 to indicate an error.
   907    976   */
   908    977   XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
   909    978   XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
   910    979   XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
   911    980   
   912    981   /* Return the number of bytes in the current event.
   913    982      Returns 0 if the event is in an internal entity.
................................................................................
   937   1006   
   938   1007   /* Frees the content model passed to the element declaration handler */
   939   1008   XMLPARSEAPI(void)
   940   1009   XML_FreeContentModel(XML_Parser parser, XML_Content *model);
   941   1010   
   942   1011   /* Exposing the memory handling functions used in Expat */
   943   1012   XMLPARSEAPI(void *)
         1013  +XML_ATTR_MALLOC
         1014  +XML_ATTR_ALLOC_SIZE(2)
   944   1015   XML_MemMalloc(XML_Parser parser, size_t size);
   945   1016   
   946   1017   XMLPARSEAPI(void *)
         1018  +XML_ATTR_ALLOC_SIZE(3)
   947   1019   XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
   948   1020   
   949   1021   XMLPARSEAPI(void)
   950   1022   XML_MemFree(XML_Parser parser, void *ptr);
   951   1023   
   952   1024   /* Frees memory used by the parser. */
   953   1025   XMLPARSEAPI(void)
................................................................................
   980   1052     XML_FEATURE_UNICODE_WCHAR_T,
   981   1053     XML_FEATURE_DTD,
   982   1054     XML_FEATURE_CONTEXT_BYTES,
   983   1055     XML_FEATURE_MIN_SIZE,
   984   1056     XML_FEATURE_SIZEOF_XML_CHAR,
   985   1057     XML_FEATURE_SIZEOF_XML_LCHAR,
   986   1058     XML_FEATURE_NS,
   987         -  XML_FEATURE_LARGE_SIZE
         1059  +  XML_FEATURE_LARGE_SIZE,
         1060  +  XML_FEATURE_ATTR_INFO
   988   1061     /* Additional features must be added to the end of this enum. */
   989   1062   };
   990   1063   
   991   1064   typedef struct {
   992   1065     enum XML_FeatureEnum  feature;
   993   1066     const XML_LChar       *name;
   994   1067     long int              value;
   995   1068   } XML_Feature;
   996   1069   
   997   1070   XMLPARSEAPI(const XML_Feature *)
   998   1071   XML_GetFeatureList(void);
   999   1072   
  1000   1073   
  1001         -/* Expat follows the GNU/Linux convention of odd number minor version for
  1002         -   beta/development releases and even number minor version for stable
  1003         -   releases. Micro is bumped with each release, and set to 0 with each
  1004         -   change to major or minor version.
         1074  +/* Expat follows the semantic versioning convention.
         1075  +   See http://semver.org.
  1005   1076   */
  1006   1077   #define XML_MAJOR_VERSION 2
  1007         -#define XML_MINOR_VERSION 0
  1008         -#define XML_MICRO_VERSION 1
         1078  +#define XML_MINOR_VERSION 2
         1079  +#define XML_MICRO_VERSION 5
  1009   1080   
  1010   1081   #ifdef __cplusplus
  1011   1082   }
  1012   1083   #endif
  1013   1084   
  1014   1085   #endif /* not Expat_INCLUDED */

Changes to expat/expat_external.h.

     1         -/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   #ifndef Expat_External_INCLUDED
     6     34   #define Expat_External_INCLUDED 1
     7     35   
     8     36   /* External API definitions */
     9     37   
    10     38   #if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
    11         -#define XML_USE_MSC_EXTENSIONS 1
           39  +# define XML_USE_MSC_EXTENSIONS 1
    12     40   #endif
    13     41   
    14     42   /* Expat tries very hard to make the API boundary very specifically
    15     43      defined.  There are two macros defined to control this boundary;
    16     44      each of these can be defined before including this header to
    17     45      achieve some different behavior, but doing so it not recommended or
    18     46      tested frequently.
................................................................................
    30     58      expected to be directly useful in client code is XMLCALL.
    31     59   
    32     60      Note that on at least some Unix versions, the Expat library must be
    33     61      compiled with the cdecl calling convention as the default since
    34     62      system headers may assume the cdecl convention.
    35     63   */
    36     64   #ifndef XMLCALL
    37         -#if defined(_MSC_VER)
    38         -#define XMLCALL __cdecl
    39         -#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
    40         -#define XMLCALL __attribute__((cdecl))
    41         -#else
           65  +# if defined(_MSC_VER)
           66  +#  define XMLCALL __cdecl
           67  +# elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
           68  +#  define XMLCALL __attribute__((cdecl))
           69  +# else
    42     70   /* For any platform which uses this definition and supports more than
    43     71      one calling convention, we need to extend this definition to
    44     72      declare the convention used on that platform, if it's possible to
    45     73      do so.
    46     74   
    47     75      If this is the case for your platform, please file a bug report
    48     76      with information on how to identify your platform via the C
    49     77      pre-processor and how to specify the same calling convention as the
    50     78      platform's malloc() implementation.
    51     79   */
    52         -#define XMLCALL
    53         -#endif
           80  +#  define XMLCALL
           81  +# endif
    54     82   #endif  /* not defined XMLCALL */
    55     83   
    56     84   
    57     85   #if !defined(XML_STATIC) && !defined(XMLIMPORT)
    58         -#ifndef XML_BUILDING_EXPAT
           86  +# ifndef XML_BUILDING_EXPAT
    59     87   /* using Expat from an application */
    60     88   
    61         -#ifdef XML_USE_MSC_EXTENSIONS
    62         -#define XMLIMPORT __declspec(dllimport)
    63         -#endif
           89  +#  ifdef XML_USE_MSC_EXTENSIONS
           90  +#   define XMLIMPORT __declspec(dllimport)
           91  +#  endif
    64     92   
    65         -#endif
           93  +# endif
    66     94   #endif  /* not defined XML_STATIC */
    67     95   
           96  +#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
           97  +# define XMLIMPORT __attribute__ ((visibility ("default")))
           98  +#endif
    68     99   
    69    100   /* If we didn't define it above, define it away: */
    70    101   #ifndef XMLIMPORT
    71         -#define XMLIMPORT
          102  +# define XMLIMPORT
          103  +#endif
          104  +
          105  +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
          106  +# define XML_ATTR_MALLOC __attribute__((__malloc__))
          107  +#else
          108  +# define XML_ATTR_MALLOC
    72    109   #endif
    73    110   
          111  +#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
          112  +# define XML_ATTR_ALLOC_SIZE(x)  __attribute__((__alloc_size__(x)))
          113  +#else
          114  +# define XML_ATTR_ALLOC_SIZE(x)
          115  +#endif
    74    116   
    75    117   #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
    76    118   
    77    119   #ifdef __cplusplus
    78    120   extern "C" {
    79    121   #endif
    80    122   
    81    123   #ifdef XML_UNICODE_WCHAR_T
    82         -#define XML_UNICODE
          124  +# ifndef XML_UNICODE
          125  +#  define XML_UNICODE
          126  +# endif
          127  +# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
          128  +#  error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
          129  +# endif
    83    130   #endif
    84    131   
    85    132   #ifdef XML_UNICODE     /* Information is UTF-16 encoded. */
    86         -#ifdef XML_UNICODE_WCHAR_T
          133  +# ifdef XML_UNICODE_WCHAR_T
    87    134   typedef wchar_t XML_Char;
    88    135   typedef wchar_t XML_LChar;
    89         -#else
          136  +# else
    90    137   typedef unsigned short XML_Char;
    91    138   typedef char XML_LChar;
    92         -#endif /* XML_UNICODE_WCHAR_T */
          139  +# endif /* XML_UNICODE_WCHAR_T */
    93    140   #else                  /* Information is UTF-8 encoded. */
    94    141   typedef char XML_Char;
    95    142   typedef char XML_LChar;
    96    143   #endif /* XML_UNICODE */
    97    144   
    98    145   #ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */
    99         -#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
          146  +# if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
   100    147   typedef __int64 XML_Index; 
   101    148   typedef unsigned __int64 XML_Size;
   102         -#else
          149  +# else
   103    150   typedef long long XML_Index;
   104    151   typedef unsigned long long XML_Size;
   105         -#endif
          152  +# endif
   106    153   #else
   107    154   typedef long XML_Index;
   108    155   typedef unsigned long XML_Size;
   109    156   #endif /* XML_LARGE_SIZE */
   110    157   
   111    158   #ifdef __cplusplus
   112    159   }
   113    160   #endif
   114    161   
   115    162   #endif /* not Expat_External_INCLUDED */

Changes to expat/iasciitab.h.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   /* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
     6     34   /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
     7     35   /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
     8     36   /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
     9     37   /* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,

Changes to expat/internal.h.

    14     14      PTRFASTCALL - Like PTRCALL, but for low number of arguments.
    15     15   
    16     16      inline      - Used for selected internal functions for which inlining
    17     17                    may improve performance on some platforms.
    18     18   
    19     19      Note: Use of these macros is based on judgement, not hard rules,
    20     20            and therefore subject to change.
           21  +                            __  __            _
           22  +                         ___\ \/ /_ __   __ _| |_
           23  +                        / _ \\  /| '_ \ / _` | __|
           24  +                       |  __//  \| |_) | (_| | |_
           25  +                        \___/_/\_\ .__/ \__,_|\__|
           26  +                                 |_| XML parser
           27  +
           28  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           29  +   Copyright (c) 2000-2017 Expat development team
           30  +   Licensed under the MIT license:
           31  +
           32  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           33  +   a  copy  of  this  software   and  associated  documentation  files  (the
           34  +   "Software"),  to  deal in  the  Software  without restriction,  including
           35  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           36  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           37  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           38  +   following conditions:
           39  +
           40  +   The above copyright  notice and this permission notice  shall be included
           41  +   in all copies or substantial portions of the Software.
           42  +
           43  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           44  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           45  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           46  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           47  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           48  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           49  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
    21     50   */
    22     51   
    23     52   #if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
    24     53   /* We'll use this version by default only where we know it helps.
    25     54   
    26     55      regparm() generates warnings on Solaris boxes.   See SF bug #692878.
    27     56   
................................................................................
    67     96   #ifdef __cplusplus
    68     97   #define inline inline
    69     98   #else
    70     99   #ifndef inline
    71    100   #define inline
    72    101   #endif
    73    102   #endif
          103  +
          104  +#ifndef UNUSED_P
          105  +# ifdef __GNUC__
          106  +#  define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
          107  +# else
          108  +#  define UNUSED_P(p) UNUSED_ ## p
          109  +# endif
          110  +#endif
          111  +
          112  +
          113  +#ifdef __cplusplus
          114  +extern "C" {
          115  +#endif
          116  +
          117  +
          118  +void
          119  +_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef);
          120  +
          121  +
          122  +#ifdef __cplusplus
          123  +}
          124  +#endif

Changes to expat/latin1tab.h.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   /* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
     6     34   /* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
     7     35   /* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
     8     36   /* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
     9     37   /* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,

Added expat/loadlibrary.c.

            1  +/***************************************************************************
            2  + *                                  _   _ ____  _
            3  + *  Project                     ___| | | |  _ \| |
            4  + *                             / __| | | | |_) | |
            5  + *                            | (__| |_| |  _ <| |___
            6  + *                             \___|\___/|_| \_\_____|
            7  + *
            8  + * Copyright (C) 2016 - 2017, Steve Holme, <steve_holme@hotmail.com>.
            9  + * Copyright (C) 2017, Expat development team
           10  + *
           11  + * All rights reserved.
           12  + * Licensed under the MIT license:
           13  + *
           14  + * Permission to  use, copy,  modify, and distribute  this software  for any
           15  + * purpose with  or without fee is  hereby granted, provided that  the above
           16  + * copyright notice and this permission notice appear in all copies.
           17  + *
           18  + * THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           19  + * EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           20  + * MERCHANTABILITY, FITNESS FOR A  PARTICULAR PURPOSE AND NONINFRINGEMENT OF
           21  + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
           22  + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
           23  + * CONTRACT, TORT OR  OTHERWISE, ARISING FROM, OUT OF OR  IN CONNECTION WITH
           24  + * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
           25  + *
           26  + * Except as contained in this notice,  the name of a copyright holder shall
           27  + * not be used in advertising or otherwise to promote the sale, use or other
           28  + * dealings  in this  Software without  prior written  authorization of  the
           29  + * copyright holder.
           30  + *
           31  + ***************************************************************************/
           32  +
           33  +#if defined(_WIN32)
           34  +
           35  +#include <windows.h>
           36  +#include <tchar.h>
           37  +
           38  +
           39  +HMODULE _Expat_LoadLibrary(LPCTSTR filename);
           40  +
           41  +
           42  +#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH)
           43  +#define LOAD_WITH_ALTERED_SEARCH_PATH  0x00000008
           44  +#endif
           45  +
           46  +#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
           47  +#define LOAD_LIBRARY_SEARCH_SYSTEM32   0x00000800
           48  +#endif
           49  +
           50  +/* We use our own typedef here since some headers might lack these */
           51  +typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
           52  +
           53  +/* See function definitions in winbase.h */
           54  +#ifdef UNICODE
           55  +#  ifdef _WIN32_WCE
           56  +#    define LOADLIBARYEX  L"LoadLibraryExW"
           57  +#  else
           58  +#    define LOADLIBARYEX  "LoadLibraryExW"
           59  +#  endif
           60  +#else
           61  +#  define LOADLIBARYEX    "LoadLibraryExA"
           62  +#endif
           63  +
           64  +
           65  +/*
           66  + * _Expat_LoadLibrary()
           67  + *
           68  + * This is used to dynamically load DLLs using the most secure method available
           69  + * for the version of Windows that we are running on.
           70  + *
           71  + * Parameters:
           72  + *
           73  + * filename  [in] - The filename or full path of the DLL to load. If only the
           74  + *                  filename is passed then the DLL will be loaded from the
           75  + *                  Windows system directory.
           76  + *
           77  + * Returns the handle of the module on success; otherwise NULL.
           78  + */
           79  +HMODULE _Expat_LoadLibrary(LPCTSTR filename)
           80  +{
           81  +  HMODULE hModule = NULL;
           82  +  LOADLIBRARYEX_FN pLoadLibraryEx = NULL;
           83  +
           84  +  /* Get a handle to kernel32 so we can access it's functions at runtime */
           85  +  HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
           86  +  if(!hKernel32)
           87  +    return NULL;  /* LCOV_EXCL_LINE */
           88  +
           89  +  /* Attempt to find LoadLibraryEx() which is only available on Windows 2000
           90  +     and above */
           91  +  pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX);
           92  +
           93  +  /* Detect if there's already a path in the filename and load the library if
           94  +     there is. Note: Both back slashes and forward slashes have been supported
           95  +     since the earlier days of DOS at an API level although they are not
           96  +     supported by command prompt */
           97  +  if(_tcspbrk(filename, TEXT("\\/"))) {
           98  +    /** !checksrc! disable BANNEDFUNC 1 **/
           99  +    hModule = pLoadLibraryEx ?
          100  +      pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
          101  +      LoadLibrary(filename);
          102  +  }
          103  +  /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only
          104  +     supported on Windows Vista, Windows Server 2008, Windows 7 and Windows
          105  +     Server 2008 R2 with this patch or natively on Windows 8 and above */
          106  +  else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) {
          107  +    /* Load the DLL from the Windows system directory */
          108  +    hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
          109  +  }
          110  +  else {
          111  +    /* Attempt to get the Windows system path */
          112  +    UINT systemdirlen = GetSystemDirectory(NULL, 0);
          113  +    if(systemdirlen) {
          114  +      /* Allocate space for the full DLL path (Room for the null terminator
          115  +         is included in systemdirlen) */
          116  +      size_t filenamelen = _tcslen(filename);
          117  +      TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen));
          118  +      if(path && GetSystemDirectory(path, systemdirlen)) {
          119  +        /* Calculate the full DLL path */
          120  +        _tcscpy(path + _tcslen(path), TEXT("\\"));
          121  +        _tcscpy(path + _tcslen(path), filename);
          122  +
          123  +        /* Load the DLL from the Windows system directory */
          124  +        /** !checksrc! disable BANNEDFUNC 1 **/
          125  +        hModule = pLoadLibraryEx ?
          126  +          pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
          127  +          LoadLibrary(path);
          128  +
          129  +      }
          130  +      free(path);
          131  +    }
          132  +  }
          133  +
          134  +  return hModule;
          135  +}
          136  +
          137  +#else /* defined(_WIN32) */
          138  +
          139  +/* ISO C requires a translation unit to contain at least one declaration
          140  +   [-Wempty-translation-unit] */
          141  +typedef int _TRANSLATION_UNIT_LOAD_LIBRARY_C_NOT_EMTPY;
          142  +
          143  +#endif /* defined(_WIN32) */

Changes to expat/nametab.h.

            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
           31  +*/
           32  +
     1     33   static const unsigned namingBitmap[] = {
     2     34   0x00000000, 0x00000000, 0x00000000, 0x00000000,
     3     35   0x00000000, 0x00000000, 0x00000000, 0x00000000,
     4     36   0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
     5     37   0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
     6     38   0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
     7     39   0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,

Added expat/siphash.h.

            1  +/* ==========================================================================
            2  + * siphash.h - SipHash-2-4 in a single header file
            3  + * --------------------------------------------------------------------------
            4  + * Derived by William Ahern from the reference implementation[1] published[2]
            5  + * by Jean-Philippe Aumasson and Daniel J. Berstein.
            6  + * Minimal changes by Sebastian Pipping and Victor Stinner on top, see below.
            7  + * Licensed under the CC0 Public Domain Dedication license.
            8  + *
            9  + * 1. https://www.131002.net/siphash/siphash24.c
           10  + * 2. https://www.131002.net/siphash/
           11  + * --------------------------------------------------------------------------
           12  + * HISTORY:
           13  + *
           14  + * 2017-07-25  (Vadim Zeitlin)
           15  + *   - Fix use of SIPHASH_MAIN macro
           16  + *
           17  + * 2017-07-05  (Sebastian Pipping)
           18  + *   - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++
           19  + *   - Add const qualifiers at two places
           20  + *   - Ensure <=80 characters line length (assuming tab width 4)
           21  + *
           22  + * 2017-06-23  (Victor Stinner)
           23  + *   - Address Win64 compile warnings
           24  + *
           25  + * 2017-06-18  (Sebastian Pipping)
           26  + *   - Clarify license note in the header
           27  + *   - Address C89 issues:
           28  + *     - Stop using inline keyword (and let compiler decide)
           29  + *     - Replace _Bool by int
           30  + *     - Turn macro siphash24 into a function
           31  + *     - Address invalid conversion (void pointer) by explicit cast
           32  + *   - Address lack of stdint.h for Visual Studio 2003 to 2008
           33  + *   - Always expose sip24_valid (for self-tests)
           34  + *
           35  + * 2012-11-04 - Born.  (William Ahern)
           36  + * --------------------------------------------------------------------------
           37  + * USAGE:
           38  + *
           39  + * SipHash-2-4 takes as input two 64-bit words as the key, some number of
           40  + * message bytes, and outputs a 64-bit word as the message digest. This
           41  + * implementation employs two data structures: a struct sipkey for
           42  + * representing the key, and a struct siphash for representing the hash
           43  + * state.
           44  + *
           45  + * For converting a 16-byte unsigned char array to a key, use either the
           46  + * macro sip_keyof or the routine sip_tokey. The former instantiates a
           47  + * compound literal key, while the latter requires a key object as a
           48  + * parameter.
           49  + *
           50  + * 	unsigned char secret[16];
           51  + * 	arc4random_buf(secret, sizeof secret);
           52  + * 	struct sipkey *key = sip_keyof(secret);
           53  + *
           54  + * For hashing a message, use either the convenience macro siphash24 or the
           55  + * routines sip24_init, sip24_update, and sip24_final.
           56  + *
           57  + * 	struct siphash state;
           58  + * 	void *msg;
           59  + * 	size_t len;
           60  + * 	uint64_t hash;
           61  + *
           62  + * 	sip24_init(&state, key);
           63  + * 	sip24_update(&state, msg, len);
           64  + * 	hash = sip24_final(&state);
           65  + *
           66  + * or
           67  + *
           68  + * 	hash = siphash24(msg, len, key);
           69  + *
           70  + * To convert the 64-bit hash value to a canonical 8-byte little-endian
           71  + * binary representation, use either the macro sip_binof or the routine
           72  + * sip_tobin. The former instantiates and returns a compound literal array,
           73  + * while the latter requires an array object as a parameter.
           74  + * --------------------------------------------------------------------------
           75  + * NOTES:
           76  + *
           77  + * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers
           78  + *   lacking compound literal support. Instead, you must use the lower-level
           79  + *   interfaces which take as parameters the temporary state objects.
           80  + *
           81  + * o Uppercase macros may evaluate parameters more than once. Lowercase
           82  + *   macros should not exhibit any such side effects.
           83  + * ==========================================================================
           84  + */
           85  +#ifndef SIPHASH_H
           86  +#define SIPHASH_H
           87  +
           88  +#include <stddef.h> /* size_t */
           89  +
           90  +#if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600)
           91  +  /* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */
           92  +  typedef unsigned __int8   uint8_t;
           93  +  typedef unsigned __int32 uint32_t;
           94  +  typedef unsigned __int64 uint64_t;
           95  +#else
           96  + #include <stdint.h> /* uint64_t uint32_t uint8_t */
           97  +#endif
           98  +
           99  +
          100  +/*
          101  + * Workaround to not require a C++11 compiler for using ULL suffix
          102  + * if this code is included and compiled as C++; related GCC warning is:
          103  + * warning: use of C++11 long long integer constant [-Wlong-long]
          104  + */
          105  +#define _SIP_ULL(high, low)  (((uint64_t)high << 32) | low)
          106  +
          107  +
          108  +#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b))))
          109  +
          110  +#define SIP_U32TO8_LE(p, v) \
          111  +	(p)[0] = (uint8_t)((v) >>  0); (p)[1] = (uint8_t)((v) >>  8); \
          112  +	(p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24);
          113  +
          114  +#define SIP_U64TO8_LE(p, v) \
          115  +	SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >>  0)); \
          116  +	SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
          117  +
          118  +#define SIP_U8TO64_LE(p) \
          119  +	(((uint64_t)((p)[0]) <<  0) | \
          120  +	 ((uint64_t)((p)[1]) <<  8) | \
          121  +	 ((uint64_t)((p)[2]) << 16) | \
          122  +	 ((uint64_t)((p)[3]) << 24) | \
          123  +	 ((uint64_t)((p)[4]) << 32) | \
          124  +	 ((uint64_t)((p)[5]) << 40) | \
          125  +	 ((uint64_t)((p)[6]) << 48) | \
          126  +	 ((uint64_t)((p)[7]) << 56))
          127  +
          128  +
          129  +#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 }
          130  +
          131  +struct siphash {
          132  +	uint64_t v0, v1, v2, v3;
          133  +
          134  +	unsigned char buf[8], *p;
          135  +	uint64_t c;
          136  +}; /* struct siphash */
          137  +
          138  +
          139  +#define SIP_KEYLEN 16
          140  +
          141  +struct sipkey {
          142  +	uint64_t k[2];
          143  +}; /* struct sipkey */
          144  +
          145  +#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k))
          146  +
          147  +static struct sipkey *sip_tokey(struct sipkey *key, const void *src) {
          148  +	key->k[0] = SIP_U8TO64_LE((const unsigned char *)src);
          149  +	key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8);
          150  +	return key;
          151  +} /* sip_tokey() */
          152  +
          153  +
          154  +#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v))
          155  +
          156  +static void *sip_tobin(void *dst, uint64_t u64) {
          157  +	SIP_U64TO8_LE((unsigned char *)dst, u64);
          158  +	return dst;
          159  +} /* sip_tobin() */
          160  +
          161  +
          162  +static void sip_round(struct siphash *H, const int rounds) {
          163  +	int i;
          164  +
          165  +	for (i = 0; i < rounds; i++) {
          166  +		H->v0 += H->v1;
          167  +		H->v1 = SIP_ROTL(H->v1, 13);
          168  +		H->v1 ^= H->v0;
          169  +		H->v0 = SIP_ROTL(H->v0, 32);
          170  +
          171  +		H->v2 += H->v3;
          172  +		H->v3 = SIP_ROTL(H->v3, 16);
          173  +		H->v3 ^= H->v2;
          174  +
          175  +		H->v0 += H->v3;
          176  +		H->v3 = SIP_ROTL(H->v3, 21);
          177  +		H->v3 ^= H->v0;
          178  +
          179  +		H->v2 += H->v1;
          180  +		H->v1 = SIP_ROTL(H->v1, 17);
          181  +		H->v1 ^= H->v2;
          182  +		H->v2 = SIP_ROTL(H->v2, 32);
          183  +	}
          184  +} /* sip_round() */
          185  +
          186  +
          187  +static struct siphash *sip24_init(struct siphash *H,
          188  +		const struct sipkey *key) {
          189  +	H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0];
          190  +	H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1];
          191  +	H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0];
          192  +	H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1];
          193  +
          194  +	H->p = H->buf;
          195  +	H->c = 0;
          196  +
          197  +	return H;
          198  +} /* sip24_init() */
          199  +
          200  +
          201  +#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)])
          202  +
          203  +static struct siphash *sip24_update(struct siphash *H, const void *src,
          204  +		size_t len) {
          205  +	const unsigned char *p = (const unsigned char *)src, *pe = p + len;
          206  +	uint64_t m;
          207  +
          208  +	do {
          209  +		while (p < pe && H->p < sip_endof(H->buf))
          210  +			*H->p++ = *p++;
          211  +
          212  +		if (H->p < sip_endof(H->buf))
          213  +			break;
          214  +
          215  +		m = SIP_U8TO64_LE(H->buf);
          216  +		H->v3 ^= m;
          217  +		sip_round(H, 2);
          218  +		H->v0 ^= m;
          219  +
          220  +		H->p = H->buf;
          221  +		H->c += 8;
          222  +	} while (p < pe);
          223  +
          224  +	return H;
          225  +} /* sip24_update() */
          226  +
          227  +
          228  +static uint64_t sip24_final(struct siphash *H) {
          229  +	const char left = (char)(H->p - H->buf);
          230  +	uint64_t b = (H->c + left) << 56;
          231  +
          232  +	switch (left) {
          233  +	case 7: b |= (uint64_t)H->buf[6] << 48;
          234  +	case 6: b |= (uint64_t)H->buf[5] << 40;
          235  +	case 5: b |= (uint64_t)H->buf[4] << 32;
          236  +	case 4: b |= (uint64_t)H->buf[3] << 24;
          237  +	case 3: b |= (uint64_t)H->buf[2] << 16;
          238  +	case 2: b |= (uint64_t)H->buf[1] << 8;
          239  +	case 1: b |= (uint64_t)H->buf[0] << 0;
          240  +	case 0: break;
          241  +	}
          242  +
          243  +	H->v3 ^= b;
          244  +	sip_round(H, 2);
          245  +	H->v0 ^= b;
          246  +	H->v2 ^= 0xff;
          247  +	sip_round(H, 4);
          248  +
          249  +	return H->v0 ^ H->v1 ^ H->v2  ^ H->v3;
          250  +} /* sip24_final() */
          251  +
          252  +
          253  +static uint64_t siphash24(const void *src, size_t len,
          254  +		const struct sipkey *key) {
          255  +	struct siphash state = SIPHASH_INITIALIZER;
          256  +	return sip24_final(sip24_update(sip24_init(&state, key), src, len));
          257  +} /* siphash24() */
          258  +
          259  +
          260  +/*
          261  + * SipHash-2-4 output with
          262  + * k = 00 01 02 ...
          263  + * and
          264  + * in = (empty string)
          265  + * in = 00 (1 byte)
          266  + * in = 00 01 (2 bytes)
          267  + * in = 00 01 02 (3 bytes)
          268  + * ...
          269  + * in = 00 01 02 ... 3e (63 bytes)
          270  + */
          271  +static int sip24_valid(void) {
          272  +	static const unsigned char vectors[64][8] = {
          273  +		{ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
          274  +		{ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
          275  +		{ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
          276  +		{ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
          277  +		{ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
          278  +		{ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
          279  +		{ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
          280  +		{ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
          281  +		{ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
          282  +		{ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
          283  +		{ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
          284  +		{ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
          285  +		{ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
          286  +		{ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
          287  +		{ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
          288  +		{ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
          289  +		{ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
          290  +		{ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
          291  +		{ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
          292  +		{ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
          293  +		{ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
          294  +		{ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
          295  +		{ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
          296  +		{ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
          297  +		{ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
          298  +		{ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
          299  +		{ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
          300  +		{ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
          301  +		{ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
          302  +		{ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
          303  +		{ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
          304  +		{ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
          305  +		{ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
          306  +		{ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
          307  +		{ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
          308  +		{ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
          309  +		{ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
          310  +		{ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
          311  +		{ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
          312  +		{ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
          313  +		{ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
          314  +		{ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
          315  +		{ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
          316  +		{ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
          317  +		{ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
          318  +		{ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
          319  +		{ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
          320  +		{ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
          321  +		{ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
          322  +		{ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
          323  +		{ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
          324  +		{ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
          325  +		{ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
          326  +		{ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
          327  +		{ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
          328  +		{ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
          329  +		{ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
          330  +		{ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
          331  +		{ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
          332  +		{ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
          333  +		{ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
          334  +		{ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
          335  +		{ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
          336  +		{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
          337  +	};
          338  +	unsigned char in[64];
          339  +	struct sipkey k;
          340  +	size_t i;
          341  +
          342  +	sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011"
          343  +			"\012\013\014\015\016\017");
          344  +
          345  +	for (i = 0; i < sizeof in; ++i) {
          346  +		in[i] = (unsigned char)i;
          347  +
          348  +		if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))
          349  +			return 0;
          350  +	}
          351  +
          352  +	return 1;
          353  +} /* sip24_valid() */
          354  +
          355  +
          356  +#ifdef SIPHASH_MAIN
          357  +
          358  +#include <stdio.h>
          359  +
          360  +int main(void) {
          361  +	const int ok = sip24_valid();
          362  +
          363  +	if (ok)
          364  +		puts("OK");
          365  +	else
          366  +		puts("FAIL");
          367  +
          368  +	return !ok;
          369  +} /* main() */
          370  +
          371  +#endif /* SIPHASH_MAIN */
          372  +
          373  +
          374  +#endif /* SIPHASH_H */

Changes to expat/utf8tab.h.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
     3         -*/
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
     4     23   
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
           31  +*/
     5     32   
     6     33   /* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
     7     34   /* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
     8     35   /* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
     9     36   /* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
    10     37   /* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
    11     38   /* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,

Changes to expat/winconfig.h.

     1         -/*================================================================
     2         -** Copyright 2000, Clark Cooper
     3         -** All rights reserved.
     4         -**
     5         -** This is free software. You are permitted to copy, distribute, or modify
     6         -** it under the terms of the MIT/X license (contained in the COPYING file
     7         -** with this distribution.)
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     8     31   */
     9     32   
    10     33   #ifndef WINCONFIG_H
    11     34   #define WINCONFIG_H
    12     35   
    13     36   #define WIN32_LEAN_AND_MEAN
    14     37   #include <windows.h>
    15     38   #undef WIN32_LEAN_AND_MEAN
    16     39   
    17     40   #include <memory.h>
    18     41   #include <string.h>
           42  +
           43  +
           44  +#if defined(HAVE_EXPAT_CONFIG_H)  /* e.g. MinGW */
           45  +# include <expat_config.h>
           46  +#else  /* !defined(HAVE_EXPAT_CONFIG_H) */
           47  +
    19     48   
    20     49   #define XML_NS 1
    21     50   #define XML_DTD 1
    22     51   #define XML_CONTEXT_BYTES 1024
    23     52   
    24     53   /* we will assume all Windows platforms are little endian */
    25     54   #define BYTEORDER 1234
    26     55   
    27     56   /* Windows has memmove() available. */
    28     57   #define HAVE_MEMMOVE
           58  +
           59  +
           60  +#endif /* !defined(HAVE_EXPAT_CONFIG_H) */
           61  +
    29     62   
    30     63   #endif /* ndef WINCONFIG_H */

Changes to expat/xmlparse.c.

     1         -/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/* 4b74aa710b4ed5ce464b0ce544852cb47bf905c85a49c7bae2749f5885cb966d (2.2.5+)
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
           32  +
           33  +#if !defined(_GNU_SOURCE)
           34  +# define _GNU_SOURCE 1                  /* syscall prototype */
           35  +#endif
     4     36   
     5     37   #include <stddef.h>
     6     38   #include <string.h>                     /* memset(), memcpy() */
     7     39   #include <assert.h>
           40  +#include <limits.h>                     /* UINT_MAX */
           41  +#include <stdio.h>                      /* fprintf */
           42  +#include <stdlib.h>                     /* getenv */
           43  +
           44  +#ifdef _WIN32
           45  +#define getpid GetCurrentProcessId
           46  +#else
           47  +#include <sys/time.h>                   /* gettimeofday() */
           48  +#include <sys/types.h>                  /* getpid() */
           49  +#include <unistd.h>                     /* getpid() */
           50  +#include <fcntl.h>                      /* O_RDONLY */
           51  +#include <errno.h>
           52  +#endif
     8     53   
     9     54   #define XML_BUILDING_EXPAT 1
    10     55   
    11         -#ifdef COMPILED_FROM_DSP
           56  +#ifdef _WIN32
    12     57   #include "winconfig.h"
    13         -#elif defined(MACOS_CLASSIC)
    14         -#include "macconfig.h"
    15         -#elif defined(__amigaos4__)
    16         -#include "amigaconfig.h"
    17         -#elif defined(__WATCOMC__)
    18         -#include "watcomconfig.h"
    19     58   #elif defined(HAVE_EXPAT_CONFIG_H)
    20     59   #include <expat_config.h>
    21         -#endif /* ndef COMPILED_FROM_DSP */
           60  +#endif /* ndef _WIN32 */
    22     61   
    23     62   #include "ascii.h"
    24     63   #include "expat.h"
           64  +#include "siphash.h"
           65  +
           66  +#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
           67  +# if defined(HAVE_GETRANDOM)
           68  +#  include <sys/random.h>    /* getrandom */
           69  +# else
           70  +#  include <unistd.h>        /* syscall */
           71  +#  include <sys/syscall.h>   /* SYS_getrandom */
           72  +# endif
           73  +# if ! defined(GRND_NONBLOCK)
           74  +#  define GRND_NONBLOCK  0x0001
           75  +# endif  /* defined(GRND_NONBLOCK) */
           76  +#endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
           77  +
           78  +#if defined(HAVE_LIBBSD) \
           79  +    && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
           80  +# include <bsd/stdlib.h>
           81  +#endif
           82  +
           83  +#if defined(_WIN32) && !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
           84  +# define LOAD_LIBRARY_SEARCH_SYSTEM32  0x00000800
           85  +#endif
           86  +
           87  +#if !defined(HAVE_GETRANDOM) && !defined(HAVE_SYSCALL_GETRANDOM) \
           88  +    && !defined(HAVE_ARC4RANDOM_BUF) && !defined(HAVE_ARC4RANDOM) \
           89  +    && !defined(XML_DEV_URANDOM) \
           90  +    && !defined(_WIN32) \
           91  +    && !defined(XML_POOR_ENTROPY)
           92  +# error  \
           93  +    You do not have support for any sources of high quality entropy \
           94  +    enabled.  For end user security, that is probably not what you want. \
           95  +    \
           96  +    Your options include: \
           97  +      * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
           98  +      * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
           99  +      * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
          100  +      * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \
          101  +      * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
          102  +      * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
          103  +      * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \
          104  +      * Windows (RtlGenRandom): _WIN32. \
          105  +    \
          106  +    If insist on not using any of these, bypass this error by defining \
          107  +    XML_POOR_ENTROPY; you have been warned. \
          108  +    \
          109  +    If you have reasons to patch this detection code away or need changes \
          110  +    to the build system, please open a bug.  Thank you!
          111  +#endif
          112  +
    25    113   
    26    114   #ifdef XML_UNICODE
    27    115   #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
    28    116   #define XmlConvert XmlUtf16Convert
    29    117   #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
    30    118   #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
    31    119   #define XmlEncode XmlUtf16Encode
................................................................................
    96    184     NAMED **v;
    97    185     unsigned char power;
    98    186     size_t size;
    99    187     size_t used;
   100    188     const XML_Memory_Handling_Suite *mem;
   101    189   } HASH_TABLE;
   102    190   
   103         -/* Basic character hash algorithm, taken from Python's string hash:
   104         -   h = h * 1000003 ^ character, the constant being a prime number.
          191  +static size_t
          192  +keylen(KEY s);
   105    193   
   106         -*/
   107         -#ifdef XML_UNICODE
   108         -#define CHAR_HASH(h, c) \
   109         -  (((h) * 0xF4243) ^ (unsigned short)(c))
   110         -#else
   111         -#define CHAR_HASH(h, c) \
   112         -  (((h) * 0xF4243) ^ (unsigned char)(c))
   113         -#endif
          194  +static void
          195  +copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);
   114    196   
   115    197   /* For probing (after a collision) we need a step size relative prime
   116    198      to the hash table size, which is a power of 2. We use double-hashing,
   117    199      since we can calculate a second hash value cheaply by taking those bits
   118    200      of the first hash value that were discarded (masked out) when the table
   119    201      index was calculated: index = hash & mask, where mask = table->size - 1.
   120    202      We limit the maximum step size to table->size / 4 (mask >> 2) and make
................................................................................
   323    405   handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
   324    406   static enum XML_Error
   325    407   processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
   326    408                  const char *s, const char *next);
   327    409   static enum XML_Error
   328    410   initializeEncoding(XML_Parser parser);
   329    411   static enum XML_Error
   330         -doProlog(XML_Parser parser, const ENCODING *enc, const char *s, 
   331         -         const char *end, int tok, const char *next, const char **nextPtr, 
          412  +doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
          413  +         const char *end, int tok, const char *next, const char **nextPtr,
   332    414            XML_Bool haveMore);
   333    415   static enum XML_Error
   334         -processInternalEntity(XML_Parser parser, ENTITY *entity, 
          416  +processInternalEntity(XML_Parser parser, ENTITY *entity,
   335    417                         XML_Bool betweenDecl);
   336    418   static enum XML_Error
   337    419   doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
   338         -          const char *start, const char *end, const char **endPtr, 
          420  +          const char *start, const char *end, const char **endPtr,
   339    421             XML_Bool haveMore);
   340    422   static enum XML_Error
   341    423   doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
   342    424                  const char *end, const char **nextPtr, XML_Bool haveMore);
   343    425   #ifdef XML_DTD
   344    426   static enum XML_Error
   345    427   doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
   346    428                   const char *end, const char **nextPtr, XML_Bool haveMore);
   347    429   #endif /* XML_DTD */
   348    430   
          431  +static void
          432  +freeBindings(XML_Parser parser, BINDING *bindings);
   349    433   static enum XML_Error
   350    434   storeAtts(XML_Parser parser, const ENCODING *, const char *s,
   351    435             TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
   352    436   static enum XML_Error
   353    437   addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
   354    438              const XML_Char *uri, BINDING **bindingsPtr);
   355    439   static int
   356         -defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 
          440  +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
   357    441                   XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
   358    442   static enum XML_Error
   359    443   storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
   360    444                       const char *, const char *, STRING_POOL *);
   361    445   static enum XML_Error
   362    446   appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
   363    447                        const char *, const char *, STRING_POOL *);
................................................................................
   382    466   static const XML_Char * getContext(XML_Parser parser);
   383    467   static XML_Bool
   384    468   setContext(XML_Parser parser, const XML_Char *context);
   385    469   
   386    470   static void FASTCALL normalizePublicId(XML_Char *s);
   387    471   
   388    472   static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
   389         -/* do not call if parentParser != NULL */
          473  +/* do not call if m_parentParser != NULL */
   390    474   static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
   391    475   static void
   392    476   dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
   393    477   static int
   394         -dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
          478  +dtdCopy(XML_Parser oldParser,
          479  +        DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
   395    480   static int
   396         -copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
   397         -
          481  +copyEntityTable(XML_Parser oldParser,
          482  +                HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
   398    483   static NAMED *
   399         -lookup(HASH_TABLE *table, KEY name, size_t createSize);
          484  +lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
   400    485   static void FASTCALL
   401    486   hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
   402    487   static void FASTCALL hashTableClear(HASH_TABLE *);
   403    488   static void FASTCALL hashTableDestroy(HASH_TABLE *);
   404    489   static void FASTCALL
   405    490   hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
   406    491   static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
................................................................................
   425    510   
   426    511   static int FASTCALL nextScaffoldPart(XML_Parser parser);
   427    512   static XML_Content * build_model(XML_Parser parser);
   428    513   static ELEMENT_TYPE *
   429    514   getElementType(XML_Parser parser, const ENCODING *enc,
   430    515                  const char *ptr, const char *end);
   431    516   
          517  +static XML_Char *copyString(const XML_Char *s,
          518  +                            const XML_Memory_Handling_Suite *memsuite);
          519  +
          520  +static unsigned long generate_hash_secret_salt(XML_Parser parser);
          521  +static XML_Bool startParsing(XML_Parser parser);
          522  +
   432    523   static XML_Parser
   433    524   parserCreate(const XML_Char *encodingName,
   434    525                const XML_Memory_Handling_Suite *memsuite,
   435    526                const XML_Char *nameSep,
   436    527                DTD *dtd);
          528  +
   437    529   static void
   438    530   parserInit(XML_Parser parser, const XML_Char *encodingName);
   439    531   
   440    532   #define poolStart(pool) ((pool)->start)
   441    533   #define poolEnd(pool) ((pool)->ptr)
   442    534   #define poolLength(pool) ((pool)->ptr - (pool)->start)
   443    535   #define poolChop(pool) ((void)--(pool->ptr))
................................................................................
   446    538   #define poolFinish(pool) ((pool)->start = (pool)->ptr)
   447    539   #define poolAppendChar(pool, c) \
   448    540     (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
   449    541      ? 0 \
   450    542      : ((*((pool)->ptr)++ = c), 1))
   451    543   
   452    544   struct XML_ParserStruct {
   453         -  /* The first member must be userData so that the XML_GetUserData
          545  +  /* The first member must be m_userData so that the XML_GetUserData
   454    546        macro works. */
   455    547     void *m_userData;
   456    548     void *m_handlerArg;
   457    549     char *m_buffer;
   458    550     const XML_Memory_Handling_Suite m_mem;
   459    551     /* first character to be parsed */
   460    552     const char *m_bufferPtr;
   461    553     /* past last character to be parsed */
   462    554     char *m_bufferEnd;
   463         -  /* allocated end of buffer */
          555  +  /* allocated end of m_buffer */
   464    556     const char *m_bufferLim;
   465    557     XML_Index m_parseEndByteIndex;
   466    558     const char *m_parseEndPtr;
   467    559     XML_Char *m_dataBuf;
   468    560     XML_Char *m_dataBufEnd;
   469    561     XML_StartElementHandler m_startElementHandler;
   470    562     XML_EndElementHandler m_endElementHandler;
................................................................................
   529    621     int m_attsSize;
   530    622     int m_nSpecifiedAtts;
   531    623     int m_idAttIndex;
   532    624     ATTRIBUTE *m_atts;
   533    625     NS_ATT *m_nsAtts;
   534    626     unsigned long m_nsAttsVersion;
   535    627     unsigned char m_nsAttsPower;
          628  +#ifdef XML_ATTR_INFO
          629  +  XML_AttrInfo *m_attInfo;
          630  +#endif
   536    631     POSITION m_position;
   537    632     STRING_POOL m_tempPool;
   538    633     STRING_POOL m_temp2Pool;
   539    634     char *m_groupConnector;
   540    635     unsigned int m_groupSize;
   541    636     XML_Char m_namespaceSeparator;
   542    637     XML_Parser m_parentParser;
   543    638     XML_ParsingStatus m_parsingStatus;
   544    639   #ifdef XML_DTD
   545    640     XML_Bool m_isParamEntity;
   546    641     XML_Bool m_useForeignDTD;
   547    642     enum XML_ParamEntityParsing m_paramEntityParsing;
   548    643   #endif
          644  +  unsigned long m_hash_secret_salt;
   549    645   };
   550    646   
   551         -#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
   552         -#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
   553         -#define FREE(p) (parser->m_mem.free_fcn((p)))
   554         -
   555         -#define userData (parser->m_userData)
   556         -#define handlerArg (parser->m_handlerArg)
   557         -#define startElementHandler (parser->m_startElementHandler)
   558         -#define endElementHandler (parser->m_endElementHandler)
   559         -#define characterDataHandler (parser->m_characterDataHandler)
   560         -#define processingInstructionHandler \
   561         -        (parser->m_processingInstructionHandler)
   562         -#define commentHandler (parser->m_commentHandler)
   563         -#define startCdataSectionHandler \
   564         -        (parser->m_startCdataSectionHandler)
   565         -#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
   566         -#define defaultHandler (parser->m_defaultHandler)
   567         -#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
   568         -#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
   569         -#define unparsedEntityDeclHandler \
   570         -        (parser->m_unparsedEntityDeclHandler)
   571         -#define notationDeclHandler (parser->m_notationDeclHandler)
   572         -#define startNamespaceDeclHandler \
   573         -        (parser->m_startNamespaceDeclHandler)
   574         -#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
   575         -#define notStandaloneHandler (parser->m_notStandaloneHandler)
   576         -#define externalEntityRefHandler \
   577         -        (parser->m_externalEntityRefHandler)
   578         -#define externalEntityRefHandlerArg \
   579         -        (parser->m_externalEntityRefHandlerArg)
   580         -#define internalEntityRefHandler \
   581         -        (parser->m_internalEntityRefHandler)
   582         -#define skippedEntityHandler (parser->m_skippedEntityHandler)
   583         -#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
   584         -#define elementDeclHandler (parser->m_elementDeclHandler)
   585         -#define attlistDeclHandler (parser->m_attlistDeclHandler)
   586         -#define entityDeclHandler (parser->m_entityDeclHandler)
   587         -#define xmlDeclHandler (parser->m_xmlDeclHandler)
   588         -#define encoding (parser->m_encoding)
   589         -#define initEncoding (parser->m_initEncoding)
   590         -#define internalEncoding (parser->m_internalEncoding)
   591         -#define unknownEncodingMem (parser->m_unknownEncodingMem)
   592         -#define unknownEncodingData (parser->m_unknownEncodingData)
   593         -#define unknownEncodingHandlerData \
   594         -  (parser->m_unknownEncodingHandlerData)
   595         -#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
   596         -#define protocolEncodingName (parser->m_protocolEncodingName)
   597         -#define ns (parser->m_ns)
   598         -#define ns_triplets (parser->m_ns_triplets)
   599         -#define prologState (parser->m_prologState)
   600         -#define processor (parser->m_processor)
   601         -#define errorCode (parser->m_errorCode)
   602         -#define eventPtr (parser->m_eventPtr)
   603         -#define eventEndPtr (parser->m_eventEndPtr)
   604         -#define positionPtr (parser->m_positionPtr)
   605         -#define position (parser->m_position)
   606         -#define openInternalEntities (parser->m_openInternalEntities)
   607         -#define freeInternalEntities (parser->m_freeInternalEntities)
   608         -#define defaultExpandInternalEntities \
   609         -        (parser->m_defaultExpandInternalEntities)
   610         -#define tagLevel (parser->m_tagLevel)
   611         -#define buffer (parser->m_buffer)
   612         -#define bufferPtr (parser->m_bufferPtr)
   613         -#define bufferEnd (parser->m_bufferEnd)
   614         -#define parseEndByteIndex (parser->m_parseEndByteIndex)
   615         -#define parseEndPtr (parser->m_parseEndPtr)
   616         -#define bufferLim (parser->m_bufferLim)
   617         -#define dataBuf (parser->m_dataBuf)
   618         -#define dataBufEnd (parser->m_dataBufEnd)
   619         -#define _dtd (parser->m_dtd)
   620         -#define curBase (parser->m_curBase)
   621         -#define declEntity (parser->m_declEntity)
   622         -#define doctypeName (parser->m_doctypeName)
   623         -#define doctypeSysid (parser->m_doctypeSysid)
   624         -#define doctypePubid (parser->m_doctypePubid)
   625         -#define declAttributeType (parser->m_declAttributeType)
   626         -#define declNotationName (parser->m_declNotationName)
   627         -#define declNotationPublicId (parser->m_declNotationPublicId)
   628         -#define declElementType (parser->m_declElementType)
   629         -#define declAttributeId (parser->m_declAttributeId)
   630         -#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
   631         -#define declAttributeIsId (parser->m_declAttributeIsId)
   632         -#define freeTagList (parser->m_freeTagList)
   633         -#define freeBindingList (parser->m_freeBindingList)
   634         -#define inheritedBindings (parser->m_inheritedBindings)
   635         -#define tagStack (parser->m_tagStack)
   636         -#define atts (parser->m_atts)
   637         -#define attsSize (parser->m_attsSize)
   638         -#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
   639         -#define idAttIndex (parser->m_idAttIndex)
   640         -#define nsAtts (parser->m_nsAtts)
   641         -#define nsAttsVersion (parser->m_nsAttsVersion)
   642         -#define nsAttsPower (parser->m_nsAttsPower)
   643         -#define tempPool (parser->m_tempPool)
   644         -#define temp2Pool (parser->m_temp2Pool)
   645         -#define groupConnector (parser->m_groupConnector)
   646         -#define groupSize (parser->m_groupSize)
   647         -#define namespaceSeparator (parser->m_namespaceSeparator)
   648         -#define parentParser (parser->m_parentParser)
   649         -#define ps_parsing (parser->m_parsingStatus.parsing)
   650         -#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
   651         -#ifdef XML_DTD
   652         -#define isParamEntity (parser->m_isParamEntity)
   653         -#define useForeignDTD (parser->m_useForeignDTD)
   654         -#define paramEntityParsing (parser->m_paramEntityParsing)
   655         -#endif /* XML_DTD */
          647  +#define MALLOC(parser, s)      (parser->m_mem.malloc_fcn((s)))
          648  +#define REALLOC(parser, p, s)  (parser->m_mem.realloc_fcn((p),(s)))
          649  +#define FREE(parser, p)        (parser->m_mem.free_fcn((p)))
          650  +
   656    651   
   657    652   XML_Parser XMLCALL
   658    653   XML_ParserCreate(const XML_Char *encodingName)
   659    654   {
   660    655     return XML_ParserCreate_MM(encodingName, NULL, NULL);
   661    656   }
   662    657   
................................................................................
   666    661     XML_Char tmp[2];
   667    662     *tmp = nsSep;
   668    663     return XML_ParserCreate_MM(encodingName, NULL, tmp);
   669    664   }
   670    665   
   671    666   static const XML_Char implicitContext[] = {
   672    667     ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
   673         -  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, 
          668  +  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
   674    669     ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
   675    670     ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
   676    671     ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
   677    672     ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
   678    673   };
   679    674   
          675  +
          676  +/* To avoid warnings about unused functions: */
          677  +#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
          678  +
          679  +#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
          680  +
          681  +/* Obtain entropy on Linux 3.17+ */
          682  +static int
          683  +writeRandomBytes_getrandom_nonblock(void * target, size_t count) {
          684  +  int success = 0;  /* full count bytes written? */
          685  +  size_t bytesWrittenTotal = 0;
          686  +  const unsigned int getrandomFlags = GRND_NONBLOCK;
          687  +
          688  +  do {
          689  +    void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
          690  +    const size_t bytesToWrite = count - bytesWrittenTotal;
          691  +
          692  +    const int bytesWrittenMore =
          693  +#if defined(HAVE_GETRANDOM)
          694  +        getrandom(currentTarget, bytesToWrite, getrandomFlags);
          695  +#else
          696  +        syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
          697  +#endif
          698  +
          699  +    if (bytesWrittenMore > 0) {
          700  +      bytesWrittenTotal += bytesWrittenMore;
          701  +      if (bytesWrittenTotal >= count)
          702  +        success = 1;
          703  +    }
          704  +  } while (! success && (errno == EINTR));
          705  +
          706  +  return success;
          707  +}
          708  +
          709  +#endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
          710  +
          711  +
          712  +#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
          713  +
          714  +/* Extract entropy from /dev/urandom */
          715  +static int
          716  +writeRandomBytes_dev_urandom(void * target, size_t count) {
          717  +  int success = 0;  /* full count bytes written? */
          718  +  size_t bytesWrittenTotal = 0;
          719  +
          720  +  const int fd = open("/dev/urandom", O_RDONLY);
          721  +  if (fd < 0) {
          722  +    return 0;
          723  +  }
          724  +
          725  +  do {
          726  +    void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
          727  +    const size_t bytesToWrite = count - bytesWrittenTotal;
          728  +
          729  +    const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
          730  +
          731  +    if (bytesWrittenMore > 0) {
          732  +      bytesWrittenTotal += bytesWrittenMore;
          733  +      if (bytesWrittenTotal >= count)
          734  +        success = 1;
          735  +    }
          736  +  } while (! success && (errno == EINTR));
          737  +
          738  +  close(fd);
          739  +  return success;
          740  +}
          741  +
          742  +#endif  /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
          743  +
          744  +#endif  /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
          745  +
          746  +
          747  +#if defined(HAVE_ARC4RANDOM)
          748  +
          749  +static void
          750  +writeRandomBytes_arc4random(void * target, size_t count) {
          751  +  size_t bytesWrittenTotal = 0;
          752  +
          753  +  while (bytesWrittenTotal < count) {
          754  +    const uint32_t random32 = arc4random();
          755  +    size_t i = 0;
          756  +
          757  +    for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
          758  +        i++, bytesWrittenTotal++) {
          759  +      const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
          760  +      ((uint8_t *)target)[bytesWrittenTotal] = random8;
          761  +    }
          762  +  }
          763  +}
          764  +
          765  +#endif  /* defined(HAVE_ARC4RANDOM) */
          766  +
          767  +
          768  +#ifdef _WIN32
          769  +
          770  +typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
          771  +HMODULE _Expat_LoadLibrary(LPCTSTR filename);  /* see loadlibrary.c */
          772  +
          773  +/* Obtain entropy on Windows XP / Windows Server 2003 and later.
          774  + * Hint on RtlGenRandom and the following article from libsodium.
          775  + *
          776  + * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
          777  + * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
          778  + */
          779  +static int
          780  +writeRandomBytes_RtlGenRandom(void * target, size_t count) {
          781  +  int success = 0;  /* full count bytes written? */
          782  +  const HMODULE advapi32 = _Expat_LoadLibrary(TEXT("ADVAPI32.DLL"));
          783  +
          784  +  if (advapi32) {
          785  +    const RTLGENRANDOM_FUNC RtlGenRandom
          786  +        = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036");
          787  +    if (RtlGenRandom) {
          788  +      if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) {
          789  +        success = 1;
          790  +      }
          791  +    }
          792  +    FreeLibrary(advapi32);
          793  +  }
          794  +
          795  +  return success;
          796  +}
          797  +
          798  +#endif /* _WIN32 */
          799  +
          800  +
          801  +#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
          802  +
          803  +static unsigned long
          804  +gather_time_entropy(void)
          805  +{
          806  +#ifdef _WIN32
          807  +  FILETIME ft;
          808  +  GetSystemTimeAsFileTime(&ft); /* never fails */
          809  +  return ft.dwHighDateTime ^ ft.dwLowDateTime;
          810  +#else
          811  +  struct timeval tv;
          812  +  int gettimeofday_res;
          813  +
          814  +  gettimeofday_res = gettimeofday(&tv, NULL);
          815  +
          816  +#if defined(NDEBUG)
          817  +  (void)gettimeofday_res;
          818  +#else
          819  +  assert (gettimeofday_res == 0);
          820  +#endif  /* defined(NDEBUG) */
          821  +
          822  +  /* Microseconds time is <20 bits entropy */
          823  +  return tv.tv_usec;
          824  +#endif
          825  +}
          826  +
          827  +#endif  /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
          828  +
          829  +
          830  +static unsigned long
          831  +ENTROPY_DEBUG(const char * label, unsigned long entropy) {
          832  +  const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
          833  +  if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
          834  +    fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n",
          835  +        label,
          836  +        (int)sizeof(entropy) * 2, entropy,
          837  +        (unsigned long)sizeof(entropy));
          838  +  }
          839  +  return entropy;
          840  +}
          841  +
          842  +static unsigned long
          843  +generate_hash_secret_salt(XML_Parser parser)
          844  +{
          845  +  unsigned long entropy;
          846  +  (void)parser;
          847  +
          848  +  /* "Failproof" high quality providers: */
          849  +#if defined(HAVE_ARC4RANDOM_BUF)
          850  +  arc4random_buf(&entropy, sizeof(entropy));
          851  +  return ENTROPY_DEBUG("arc4random_buf", entropy);
          852  +#elif defined(HAVE_ARC4RANDOM)
          853  +  writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
          854  +  return ENTROPY_DEBUG("arc4random", entropy);
          855  +#else
          856  +  /* Try high quality providers first .. */
          857  +#ifdef _WIN32
          858  +  if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) {
          859  +    return ENTROPY_DEBUG("RtlGenRandom", entropy);
          860  +  }
          861  +#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
          862  +  if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
          863  +    return ENTROPY_DEBUG("getrandom", entropy);
          864  +  }
          865  +#endif
          866  +#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
          867  +  if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
          868  +    return ENTROPY_DEBUG("/dev/urandom", entropy);
          869  +  }
          870  +#endif  /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
          871  +  /* .. and self-made low quality for backup: */
          872  +
          873  +  /* Process ID is 0 bits entropy if attacker has local access */
          874  +  entropy = gather_time_entropy() ^ getpid();
          875  +
          876  +  /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
          877  +  if (sizeof(unsigned long) == 4) {
          878  +    return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
          879  +  } else {
          880  +    return ENTROPY_DEBUG("fallback(8)",
          881  +        entropy * (unsigned long)2305843009213693951ULL);
          882  +  }
          883  +#endif
          884  +}
          885  +
          886  +static unsigned long
          887  +get_hash_secret_salt(XML_Parser parser) {
          888  +  if (parser->m_parentParser != NULL)
          889  +    return get_hash_secret_salt(parser->m_parentParser);
          890  +  return parser->m_hash_secret_salt;
          891  +}
          892  +
          893  +static XML_Bool  /* only valid for root parser */
          894  +startParsing(XML_Parser parser)
          895  +{
          896  +    /* hash functions must be initialized before setContext() is called */
          897  +    if (parser->m_hash_secret_salt == 0)
          898  +      parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
          899  +    if (parser->m_ns) {
          900  +      /* implicit context only set for root parser, since child
          901  +         parsers (i.e. external entity parsers) will inherit it
          902  +      */
          903  +      return setContext(parser, implicitContext);
          904  +    }
          905  +    return XML_TRUE;
          906  +}
          907  +
   680    908   XML_Parser XMLCALL
   681    909   XML_ParserCreate_MM(const XML_Char *encodingName,
   682    910                       const XML_Memory_Handling_Suite *memsuite,
   683    911                       const XML_Char *nameSep)
   684    912   {
   685         -  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
   686         -  if (parser != NULL && ns) {
   687         -    /* implicit context only set for root parser, since child
   688         -       parsers (i.e. external entity parsers) will inherit it
   689         -    */
   690         -    if (!setContext(parser, implicitContext)) {
   691         -      XML_ParserFree(parser);
   692         -      return NULL;
   693         -    }
   694         -  }
   695         -  return parser;
          913  +  return parserCreate(encodingName, memsuite, nameSep, NULL);
   696    914   }
   697    915   
   698    916   static XML_Parser
   699    917   parserCreate(const XML_Char *encodingName,
   700    918                const XML_Memory_Handling_Suite *memsuite,
   701    919                const XML_Char *nameSep,
   702    920                DTD *dtd)
................................................................................
   724    942         mtemp->free_fcn = free;
   725    943       }
   726    944     }
   727    945   
   728    946     if (!parser)
   729    947       return parser;
   730    948   
   731         -  buffer = NULL;
   732         -  bufferLim = NULL;
   733         -
   734         -  attsSize = INIT_ATTS_SIZE;
   735         -  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
   736         -  if (atts == NULL) {
   737         -    FREE(parser);
   738         -    return NULL;
   739         -  }
   740         -  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
   741         -  if (dataBuf == NULL) {
   742         -    FREE(atts);
   743         -    FREE(parser);
   744         -    return NULL;
   745         -  }
   746         -  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
          949  +  parser->m_buffer = NULL;
          950  +  parser->m_bufferLim = NULL;
          951  +
          952  +  parser->m_attsSize = INIT_ATTS_SIZE;
          953  +  parser->m_atts = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
          954  +  if (parser->m_atts == NULL) {
          955  +    FREE(parser, parser);
          956  +    return NULL;
          957  +  }
          958  +#ifdef XML_ATTR_INFO
          959  +  parser->m_attInfo = (XML_AttrInfo*)MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo));
          960  +  if (parser->m_attInfo == NULL) {
          961  +    FREE(parser, parser->m_atts);
          962  +    FREE(parser, parser);
          963  +    return NULL;
          964  +  }
          965  +#endif
          966  +  parser->m_dataBuf = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
          967  +  if (parser->m_dataBuf == NULL) {
          968  +    FREE(parser, parser->m_atts);
          969  +#ifdef XML_ATTR_INFO
          970  +    FREE(parser, parser->m_attInfo);
          971  +#endif
          972  +    FREE(parser, parser);
          973  +    return NULL;
          974  +  }
          975  +  parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;
   747    976   
   748    977     if (dtd)
   749         -    _dtd = dtd;
   750         -  else {
   751         -    _dtd = dtdCreate(&parser->m_mem);
   752         -    if (_dtd == NULL) {
   753         -      FREE(dataBuf);
   754         -      FREE(atts);
   755         -      FREE(parser);
   756         -      return NULL;
   757         -    }
   758         -  }
   759         -
   760         -  freeBindingList = NULL;
   761         -  freeTagList = NULL;
   762         -  freeInternalEntities = NULL;
   763         -
   764         -  groupSize = 0;
   765         -  groupConnector = NULL;
   766         -
   767         -  unknownEncodingHandler = NULL;
   768         -  unknownEncodingHandlerData = NULL;
   769         -
   770         -  namespaceSeparator = ASCII_EXCL;
   771         -  ns = XML_FALSE;
   772         -  ns_triplets = XML_FALSE;
   773         -
   774         -  nsAtts = NULL;
   775         -  nsAttsVersion = 0;
   776         -  nsAttsPower = 0;
   777         -
   778         -  poolInit(&tempPool, &(parser->m_mem));
   779         -  poolInit(&temp2Pool, &(parser->m_mem));
          978  +    parser->m_dtd = dtd;
          979  +  else {
          980  +    parser->m_dtd = dtdCreate(&parser->m_mem);
          981  +    if (parser->m_dtd == NULL) {
          982  +      FREE(parser, parser->m_dataBuf);
          983  +      FREE(parser, parser->m_atts);
          984  +#ifdef XML_ATTR_INFO
          985  +      FREE(parser, parser->m_attInfo);
          986  +#endif
          987  +      FREE(parser, parser);
          988  +      return NULL;
          989  +    }
          990  +  }
          991  +
          992  +  parser->m_freeBindingList = NULL;
          993  +  parser->m_freeTagList = NULL;
          994  +  parser->m_freeInternalEntities = NULL;
          995  +
          996  +  parser->m_groupSize = 0;
          997  +  parser->m_groupConnector = NULL;
          998  +
          999  +  parser->m_unknownEncodingHandler = NULL;
         1000  +  parser->m_unknownEncodingHandlerData = NULL;
         1001  +
         1002  +  parser->m_namespaceSeparator = ASCII_EXCL;
         1003  +  parser->m_ns = XML_FALSE;
         1004  +  parser->m_ns_triplets = XML_FALSE;
         1005  +
         1006  +  parser->m_nsAtts = NULL;
         1007  +  parser->m_nsAttsVersion = 0;
         1008  +  parser->m_nsAttsPower = 0;
         1009  +
         1010  +  parser->m_protocolEncodingName = NULL;
         1011  +
         1012  +  poolInit(&parser->m_tempPool, &(parser->m_mem));
         1013  +  poolInit(&parser->m_temp2Pool, &(parser->m_mem));
   780   1014     parserInit(parser, encodingName);
   781   1015   
   782         -  if (encodingName && !protocolEncodingName) {
         1016  +  if (encodingName && !parser->m_protocolEncodingName) {
   783   1017       XML_ParserFree(parser);
   784   1018       return NULL;
   785   1019     }
   786   1020   
   787   1021     if (nameSep) {
   788         -    ns = XML_TRUE;
   789         -    internalEncoding = XmlGetInternalEncodingNS();
   790         -    namespaceSeparator = *nameSep;
         1022  +    parser->m_ns = XML_TRUE;
         1023  +    parser->m_internalEncoding = XmlGetInternalEncodingNS();
         1024  +    parser->m_namespaceSeparator = *nameSep;
   791   1025     }
   792   1026     else {
   793         -    internalEncoding = XmlGetInternalEncoding();
         1027  +    parser->m_internalEncoding = XmlGetInternalEncoding();
   794   1028     }
   795   1029   
   796   1030     return parser;
   797   1031   }
   798   1032   
   799   1033   static void
   800   1034   parserInit(XML_Parser parser, const XML_Char *encodingName)
   801   1035   {
   802         -  processor = prologInitProcessor;
   803         -  XmlPrologStateInit(&prologState);
   804         -  protocolEncodingName = (encodingName != NULL
   805         -                          ? poolCopyString(&tempPool, encodingName)
   806         -                          : NULL);
   807         -  curBase = NULL;
   808         -  XmlInitEncoding(&initEncoding, &encoding, 0);
   809         -  userData = NULL;
   810         -  handlerArg = NULL;
   811         -  startElementHandler = NULL;
   812         -  endElementHandler = NULL;
   813         -  characterDataHandler = NULL;
   814         -  processingInstructionHandler = NULL;
   815         -  commentHandler = NULL;
   816         -  startCdataSectionHandler = NULL;
   817         -  endCdataSectionHandler = NULL;
   818         -  defaultHandler = NULL;
   819         -  startDoctypeDeclHandler = NULL;
   820         -  endDoctypeDeclHandler = NULL;
   821         -  unparsedEntityDeclHandler = NULL;
   822         -  notationDeclHandler = NULL;
   823         -  startNamespaceDeclHandler = NULL;
   824         -  endNamespaceDeclHandler = NULL;
   825         -  notStandaloneHandler = NULL;
   826         -  externalEntityRefHandler = NULL;
   827         -  externalEntityRefHandlerArg = parser;
   828         -  skippedEntityHandler = NULL;
   829         -  elementDeclHandler = NULL;
   830         -  attlistDeclHandler = NULL;
   831         -  entityDeclHandler = NULL;
   832         -  xmlDeclHandler = NULL;
   833         -  bufferPtr = buffer;
   834         -  bufferEnd = buffer;
   835         -  parseEndByteIndex = 0;
   836         -  parseEndPtr = NULL;
   837         -  declElementType = NULL;
   838         -  declAttributeId = NULL;
   839         -  declEntity = NULL;
   840         -  doctypeName = NULL;
   841         -  doctypeSysid = NULL;
   842         -  doctypePubid = NULL;
   843         -  declAttributeType = NULL;
   844         -  declNotationName = NULL;
   845         -  declNotationPublicId = NULL;
   846         -  declAttributeIsCdata = XML_FALSE;
   847         -  declAttributeIsId = XML_FALSE;
   848         -  memset(&position, 0, sizeof(POSITION));
   849         -  errorCode = XML_ERROR_NONE;
   850         -  eventPtr = NULL;
   851         -  eventEndPtr = NULL;
   852         -  positionPtr = NULL;
   853         -  openInternalEntities = NULL;
   854         -  defaultExpandInternalEntities = XML_TRUE;
   855         -  tagLevel = 0;
   856         -  tagStack = NULL;
   857         -  inheritedBindings = NULL;
   858         -  nSpecifiedAtts = 0;
   859         -  unknownEncodingMem = NULL;
   860         -  unknownEncodingRelease = NULL;
   861         -  unknownEncodingData = NULL;
   862         -  parentParser = NULL;
   863         -  ps_parsing = XML_INITIALIZED;
   864         -#ifdef XML_DTD
   865         -  isParamEntity = XML_FALSE;
   866         -  useForeignDTD = XML_FALSE;
   867         -  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
   868         -#endif
   869         -}
   870         -
   871         -/* moves list of bindings to freeBindingList */
         1036  +  parser->m_processor = prologInitProcessor;
         1037  +  XmlPrologStateInit(&parser->m_prologState);
         1038  +  if (encodingName != NULL) {
         1039  +    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
         1040  +  }
         1041  +  parser->m_curBase = NULL;
         1042  +  XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
         1043  +  parser->m_userData = NULL;
         1044  +  parser->m_handlerArg = NULL;
         1045  +  parser->m_startElementHandler = NULL;
         1046  +  parser->m_endElementHandler = NULL;
         1047  +  parser->m_characterDataHandler = NULL;
         1048  +  parser->m_processingInstructionHandler = NULL;
         1049  +  parser->m_commentHandler = NULL;
         1050  +  parser->m_startCdataSectionHandler = NULL;
         1051  +  parser->m_endCdataSectionHandler = NULL;
         1052  +  parser->m_defaultHandler = NULL;
         1053  +  parser->m_startDoctypeDeclHandler = NULL;
         1054  +  parser->m_endDoctypeDeclHandler = NULL;
         1055  +  parser->m_unparsedEntityDeclHandler = NULL;
         1056  +  parser->m_notationDeclHandler = NULL;
         1057  +  parser->m_startNamespaceDeclHandler = NULL;
         1058  +  parser->m_endNamespaceDeclHandler = NULL;
         1059  +  parser->m_notStandaloneHandler = NULL;
         1060  +  parser->m_externalEntityRefHandler = NULL;
         1061  +  parser->m_externalEntityRefHandlerArg = parser;
         1062  +  parser->m_skippedEntityHandler = NULL;
         1063  +  parser->m_elementDeclHandler = NULL;
         1064  +  parser->m_attlistDeclHandler = NULL;
         1065  +  parser->m_entityDeclHandler = NULL;
         1066  +  parser->m_xmlDeclHandler = NULL;
         1067  +  parser->m_bufferPtr = parser->m_buffer;
         1068  +  parser->m_bufferEnd = parser->m_buffer;
         1069  +  parser->m_parseEndByteIndex = 0;
         1070  +  parser->m_parseEndPtr = NULL;
         1071  +  parser->m_declElementType = NULL;
         1072  +  parser->m_declAttributeId = NULL;
         1073  +  parser->m_declEntity = NULL;
         1074  +  parser->m_doctypeName = NULL;
         1075  +  parser->m_doctypeSysid = NULL;
         1076  +  parser->m_doctypePubid = NULL;
         1077  +  parser->m_declAttributeType = NULL;
         1078  +  parser->m_declNotationName = NULL;
         1079  +  parser->m_declNotationPublicId = NULL;
         1080  +  parser->m_declAttributeIsCdata = XML_FALSE;
         1081  +  parser->m_declAttributeIsId = XML_FALSE;
         1082  +  memset(&parser->m_position, 0, sizeof(POSITION));
         1083  +  parser->m_errorCode = XML_ERROR_NONE;
         1084  +  parser->m_eventPtr = NULL;
         1085  +  parser->m_eventEndPtr = NULL;
         1086  +  parser->m_positionPtr = NULL;
         1087  +  parser->m_openInternalEntities = NULL;
         1088  +  parser->m_defaultExpandInternalEntities = XML_TRUE;
         1089  +  parser->m_tagLevel = 0;
         1090  +  parser->m_tagStack = NULL;
         1091  +  parser->m_inheritedBindings = NULL;
         1092  +  parser->m_nSpecifiedAtts = 0;
         1093  +  parser->m_unknownEncodingMem = NULL;
         1094  +  parser->m_unknownEncodingRelease = NULL;
         1095  +  parser->m_unknownEncodingData = NULL;
         1096  +  parser->m_parentParser = NULL;
         1097  +  parser->m_parsingStatus.parsing = XML_INITIALIZED;
         1098  +#ifdef XML_DTD
         1099  +  parser->m_isParamEntity = XML_FALSE;
         1100  +  parser->m_useForeignDTD = XML_FALSE;
         1101  +  parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
         1102  +#endif
         1103  +  parser->m_hash_secret_salt = 0;
         1104  +}
         1105  +
         1106  +/* moves list of bindings to m_freeBindingList */
   872   1107   static void FASTCALL
   873   1108   moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
   874   1109   {
   875   1110     while (bindings) {
   876   1111       BINDING *b = bindings;
   877   1112       bindings = bindings->nextTagBinding;
   878         -    b->nextTagBinding = freeBindingList;
   879         -    freeBindingList = b;
         1113  +    b->nextTagBinding = parser->m_freeBindingList;
         1114  +    parser->m_freeBindingList = b;
   880   1115     }
   881   1116   }
   882   1117   
   883   1118   XML_Bool XMLCALL
   884   1119   XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
   885   1120   {
   886   1121     TAG *tStk;
   887   1122     OPEN_INTERNAL_ENTITY *openEntityList;
   888         -  if (parentParser)
         1123  +
         1124  +  if (parser == NULL)
         1125  +      return XML_FALSE;
         1126  +
         1127  +  if (parser->m_parentParser)
   889   1128       return XML_FALSE;
   890         -  /* move tagStack to freeTagList */
   891         -  tStk = tagStack;
         1129  +  /* move m_tagStack to m_freeTagList */
         1130  +  tStk = parser->m_tagStack;
   892   1131     while (tStk) {
   893   1132       TAG *tag = tStk;
   894   1133       tStk = tStk->parent;
   895         -    tag->parent = freeTagList;
         1134  +    tag->parent = parser->m_freeTagList;
   896   1135       moveToFreeBindingList(parser, tag->bindings);
   897   1136       tag->bindings = NULL;
   898         -    freeTagList = tag;
         1137  +    parser->m_freeTagList = tag;
   899   1138     }
   900         -  /* move openInternalEntities to freeInternalEntities */
   901         -  openEntityList = openInternalEntities;
         1139  +  /* move m_openInternalEntities to m_freeInternalEntities */
         1140  +  openEntityList = parser->m_openInternalEntities;
   902   1141     while (openEntityList) {
   903   1142       OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
   904   1143       openEntityList = openEntity->next;
   905         -    openEntity->next = freeInternalEntities;
   906         -    freeInternalEntities = openEntity;
         1144  +    openEntity->next = parser->m_freeInternalEntities;
         1145  +    parser->m_freeInternalEntities = openEntity;
   907   1146     }
   908         -  moveToFreeBindingList(parser, inheritedBindings);
   909         -  FREE(unknownEncodingMem);
   910         -  if (unknownEncodingRelease)
   911         -    unknownEncodingRelease(unknownEncodingData);
   912         -  poolClear(&tempPool);
   913         -  poolClear(&temp2Pool);
         1147  +  moveToFreeBindingList(parser, parser->m_inheritedBindings);
         1148  +  FREE(parser, parser->m_unknownEncodingMem);
         1149  +  if (parser->m_unknownEncodingRelease)
         1150  +    parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
         1151  +  poolClear(&parser->m_tempPool);
         1152  +  poolClear(&parser->m_temp2Pool);
         1153  +  FREE(parser, (void *)parser->m_protocolEncodingName);
         1154  +  parser->m_protocolEncodingName = NULL;
   914   1155     parserInit(parser, encodingName);
   915         -  dtdReset(_dtd, &parser->m_mem);
   916         -  return setContext(parser, implicitContext);
         1156  +  dtdReset(parser->m_dtd, &parser->m_mem);
         1157  +  return XML_TRUE;
   917   1158   }
   918   1159   
   919   1160   enum XML_Status XMLCALL
   920   1161   XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
   921   1162   {
         1163  +  if (parser == NULL)
         1164  +      return XML_STATUS_ERROR;
   922   1165     /* Block after XML_Parse()/XML_ParseBuffer() has been called.
   923   1166        XXX There's no way for the caller to determine which of the
   924   1167        XXX possible error cases caused the XML_STATUS_ERROR return.
   925   1168     */
   926         -  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
         1169  +  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
   927   1170       return XML_STATUS_ERROR;
         1171  +
         1172  +  /* Get rid of any previous encoding name */
         1173  +  FREE(parser, (void *)parser->m_protocolEncodingName);
         1174  +
   928   1175     if (encodingName == NULL)
   929         -    protocolEncodingName = NULL;
         1176  +    /* No new encoding name */
         1177  +    parser->m_protocolEncodingName = NULL;
   930   1178     else {
   931         -    protocolEncodingName = poolCopyString(&tempPool, encodingName);
   932         -    if (!protocolEncodingName)
         1179  +    /* Copy the new encoding name into allocated memory */
         1180  +    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
         1181  +    if (!parser->m_protocolEncodingName)
   933   1182         return XML_STATUS_ERROR;
   934   1183     }
   935   1184     return XML_STATUS_OK;
   936   1185   }
   937   1186   
   938   1187   XML_Parser XMLCALL
   939   1188   XML_ExternalEntityParserCreate(XML_Parser oldParser,
   940   1189                                  const XML_Char *context,
   941   1190                                  const XML_Char *encodingName)
   942   1191   {
   943   1192     XML_Parser parser = oldParser;
   944   1193     DTD *newDtd = NULL;
   945         -  DTD *oldDtd = _dtd;
   946         -  XML_StartElementHandler oldStartElementHandler = startElementHandler;
   947         -  XML_EndElementHandler oldEndElementHandler = endElementHandler;
   948         -  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
   949         -  XML_ProcessingInstructionHandler oldProcessingInstructionHandler
   950         -      = processingInstructionHandler;
   951         -  XML_CommentHandler oldCommentHandler = commentHandler;
   952         -  XML_StartCdataSectionHandler oldStartCdataSectionHandler
   953         -      = startCdataSectionHandler;
   954         -  XML_EndCdataSectionHandler oldEndCdataSectionHandler
   955         -      = endCdataSectionHandler;
   956         -  XML_DefaultHandler oldDefaultHandler = defaultHandler;
   957         -  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
   958         -      = unparsedEntityDeclHandler;
   959         -  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
   960         -  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
   961         -      = startNamespaceDeclHandler;
   962         -  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
   963         -      = endNamespaceDeclHandler;
   964         -  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
   965         -  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
   966         -      = externalEntityRefHandler;
   967         -  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
   968         -  XML_UnknownEncodingHandler oldUnknownEncodingHandler
   969         -      = unknownEncodingHandler;
   970         -  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
   971         -  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
   972         -  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
   973         -  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
   974         -  ELEMENT_TYPE * oldDeclElementType = declElementType;
   975         -
   976         -  void *oldUserData = userData;
   977         -  void *oldHandlerArg = handlerArg;
   978         -  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
   979         -  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
   980         -#ifdef XML_DTD
   981         -  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
   982         -  int oldInEntityValue = prologState.inEntityValue;
   983         -#endif
   984         -  XML_Bool oldns_triplets = ns_triplets;
         1194  +  DTD *oldDtd;
         1195  +  XML_StartElementHandler oldStartElementHandler;
         1196  +  XML_EndElementHandler oldEndElementHandler;
         1197  +  XML_CharacterDataHandler oldCharacterDataHandler;
         1198  +  XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
         1199  +  XML_CommentHandler oldCommentHandler;
         1200  +  XML_StartCdataSectionHandler oldStartCdataSectionHandler;
         1201  +  XML_EndCdataSectionHandler oldEndCdataSectionHandler;
         1202  +  XML_DefaultHandler oldDefaultHandler;
         1203  +  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
         1204  +  XML_NotationDeclHandler oldNotationDeclHandler;
         1205  +  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
         1206  +  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
         1207  +  XML_NotStandaloneHandler oldNotStandaloneHandler;
         1208  +  XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
         1209  +  XML_SkippedEntityHandler oldSkippedEntityHandler;
         1210  +  XML_UnknownEncodingHandler oldUnknownEncodingHandler;
         1211  +  XML_ElementDeclHandler oldElementDeclHandler;
         1212  +  XML_AttlistDeclHandler oldAttlistDeclHandler;
         1213  +  XML_EntityDeclHandler oldEntityDeclHandler;
         1214  +  XML_XmlDeclHandler oldXmlDeclHandler;
         1215  +  ELEMENT_TYPE * oldDeclElementType;
         1216  +
         1217  +  void *oldUserData;
         1218  +  void *oldHandlerArg;
         1219  +  XML_Bool oldDefaultExpandInternalEntities;
         1220  +  XML_Parser oldExternalEntityRefHandlerArg;
         1221  +#ifdef XML_DTD
         1222  +  enum XML_ParamEntityParsing oldParamEntityParsing;
         1223  +  int oldInEntityValue;
         1224  +#endif
         1225  +  XML_Bool oldns_triplets;
         1226  +  /* Note that the new parser shares the same hash secret as the old
         1227  +     parser, so that dtdCopy and copyEntityTable can lookup values
         1228  +     from hash tables associated with either parser without us having
         1229  +     to worry which hash secrets each table has.
         1230  +  */
         1231  +  unsigned long oldhash_secret_salt;
         1232  +
         1233  +  /* Validate the oldParser parameter before we pull everything out of it */
         1234  +  if (oldParser == NULL)
         1235  +    return NULL;
         1236  +
         1237  +  /* Stash the original parser contents on the stack */
         1238  +  oldDtd = parser->m_dtd;
         1239  +  oldStartElementHandler = parser->m_startElementHandler;
         1240  +  oldEndElementHandler = parser->m_endElementHandler;
         1241  +  oldCharacterDataHandler = parser->m_characterDataHandler;
         1242  +  oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
         1243  +  oldCommentHandler = parser->m_commentHandler;
         1244  +  oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
         1245  +  oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
         1246  +  oldDefaultHandler = parser->m_defaultHandler;
         1247  +  oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
         1248  +  oldNotationDeclHandler = parser->m_notationDeclHandler;
         1249  +  oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
         1250  +  oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
         1251  +  oldNotStandaloneHandler = parser->m_notStandaloneHandler;
         1252  +  oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
         1253  +  oldSkippedEntityHandler = parser->m_skippedEntityHandler;
         1254  +  oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
         1255  +  oldElementDeclHandler = parser->m_elementDeclHandler;
         1256  +  oldAttlistDeclHandler = parser->m_attlistDeclHandler;
         1257  +  oldEntityDeclHandler = parser->m_entityDeclHandler;
         1258  +  oldXmlDeclHandler = parser->m_xmlDeclHandler;
         1259  +  oldDeclElementType = parser->m_declElementType;
         1260  +
         1261  +  oldUserData = parser->m_userData;
         1262  +  oldHandlerArg = parser->m_handlerArg;
         1263  +  oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
         1264  +  oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
         1265  +#ifdef XML_DTD
         1266  +  oldParamEntityParsing = parser->m_paramEntityParsing;
         1267  +  oldInEntityValue = parser->m_prologState.inEntityValue;
         1268  +#endif
         1269  +  oldns_triplets = parser->m_ns_triplets;
         1270  +  /* Note that the new parser shares the same hash secret as the old
         1271  +     parser, so that dtdCopy and copyEntityTable can lookup values
         1272  +     from hash tables associated with either parser without us having
         1273  +     to worry which hash secrets each table has.
         1274  +  */
         1275  +  oldhash_secret_salt = parser->m_hash_secret_salt;
   985   1276   
   986   1277   #ifdef XML_DTD
   987   1278     if (!context)
   988   1279       newDtd = oldDtd;
   989   1280   #endif /* XML_DTD */
   990   1281   
   991   1282     /* Note that the magical uses of the pre-processor to make field
   992   1283        access look more like C++ require that `parser' be overwritten
   993   1284        here.  This makes this function more painful to follow than it
   994   1285        would be otherwise.
   995   1286     */
   996         -  if (ns) {
         1287  +  if (parser->m_ns) {
   997   1288       XML_Char tmp[2];
   998         -    *tmp = namespaceSeparator;
         1289  +    *tmp = parser->m_namespaceSeparator;
   999   1290       parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
  1000   1291     }
  1001   1292     else {
  1002   1293       parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
  1003   1294     }
  1004   1295   
  1005   1296     if (!parser)
  1006   1297       return NULL;
  1007   1298   
  1008         -  startElementHandler = oldStartElementHandler;
  1009         -  endElementHandler = oldEndElementHandler;
  1010         -  characterDataHandler = oldCharacterDataHandler;
  1011         -  processingInstructionHandler = oldProcessingInstructionHandler;
  1012         -  commentHandler = oldCommentHandler;
  1013         -  startCdataSectionHandler = oldStartCdataSectionHandler;
  1014         -  endCdataSectionHandler = oldEndCdataSectionHandler;
  1015         -  defaultHandler = oldDefaultHandler;
  1016         -  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
  1017         -  notationDeclHandler = oldNotationDeclHandler;
  1018         -  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
  1019         -  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
  1020         -  notStandaloneHandler = oldNotStandaloneHandler;
  1021         -  externalEntityRefHandler = oldExternalEntityRefHandler;
  1022         -  skippedEntityHandler = oldSkippedEntityHandler;
  1023         -  unknownEncodingHandler = oldUnknownEncodingHandler;
  1024         -  elementDeclHandler = oldElementDeclHandler;
  1025         -  attlistDeclHandler = oldAttlistDeclHandler;
  1026         -  entityDeclHandler = oldEntityDeclHandler;
  1027         -  xmlDeclHandler = oldXmlDeclHandler;
  1028         -  declElementType = oldDeclElementType;
  1029         -  userData = oldUserData;
         1299  +  parser->m_startElementHandler = oldStartElementHandler;
         1300  +  parser->m_endElementHandler = oldEndElementHandler;
         1301  +  parser->m_characterDataHandler = oldCharacterDataHandler;
         1302  +  parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
         1303  +  parser->m_commentHandler = oldCommentHandler;
         1304  +  parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
         1305  +  parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
         1306  +  parser->m_defaultHandler = oldDefaultHandler;
         1307  +  parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
         1308  +  parser->m_notationDeclHandler = oldNotationDeclHandler;
         1309  +  parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
         1310  +  parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
         1311  +  parser->m_notStandaloneHandler = oldNotStandaloneHandler;
         1312  +  parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
         1313  +  parser->m_skippedEntityHandler = oldSkippedEntityHandler;
         1314  +  parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
         1315  +  parser->m_elementDeclHandler = oldElementDeclHandler;
         1316  +  parser->m_attlistDeclHandler = oldAttlistDeclHandler;
         1317  +  parser->m_entityDeclHandler = oldEntityDeclHandler;
         1318  +  parser->m_xmlDeclHandler = oldXmlDeclHandler;
         1319  +  parser->m_declElementType = oldDeclElementType;
         1320  +  parser->m_userData = oldUserData;
  1030   1321     if (oldUserData == oldHandlerArg)
  1031         -    handlerArg = userData;
         1322  +    parser->m_handlerArg = parser->m_userData;
  1032   1323     else
  1033         -    handlerArg = parser;
         1324  +    parser->m_handlerArg = parser;
  1034   1325     if (oldExternalEntityRefHandlerArg != oldParser)
  1035         -    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
  1036         -  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
  1037         -  ns_triplets = oldns_triplets;
  1038         -  parentParser = oldParser;
         1326  +    parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
         1327  +  parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
         1328  +  parser->m_ns_triplets = oldns_triplets;
         1329  +  parser->m_hash_secret_salt = oldhash_secret_salt;
         1330  +  parser->m_parentParser = oldParser;
  1039   1331   #ifdef XML_DTD
  1040         -  paramEntityParsing = oldParamEntityParsing;
  1041         -  prologState.inEntityValue = oldInEntityValue;
         1332  +  parser->m_paramEntityParsing = oldParamEntityParsing;
         1333  +  parser->m_prologState.inEntityValue = oldInEntityValue;
  1042   1334     if (context) {
  1043   1335   #endif /* XML_DTD */
  1044         -    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
         1336  +    if (!dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
  1045   1337         || !setContext(parser, context)) {
  1046   1338         XML_ParserFree(parser);
  1047   1339         return NULL;
  1048   1340       }
  1049         -    processor = externalEntityInitProcessor;
         1341  +    parser->m_processor = externalEntityInitProcessor;
  1050   1342   #ifdef XML_DTD
  1051   1343     }
  1052   1344     else {
  1053         -    /* The DTD instance referenced by _dtd is shared between the document's
         1345  +    /* The DTD instance referenced by parser->m_dtd is shared between the document's
  1054   1346          root parser and external PE parsers, therefore one does not need to
  1055   1347          call setContext. In addition, one also *must* not call setContext,
  1056   1348          because this would overwrite existing prefix->binding pointers in
  1057         -       _dtd with ones that get destroyed with the external PE parser.
         1349  +       parser->m_dtd with ones that get destroyed with the external PE parser.
  1058   1350          This would leave those prefixes with dangling pointers.
  1059   1351       */
  1060         -    isParamEntity = XML_TRUE;
  1061         -    XmlPrologStateInitExternalEntity(&prologState);
  1062         -    processor = externalParEntInitProcessor;
         1352  +    parser->m_isParamEntity = XML_TRUE;
         1353  +    XmlPrologStateInitExternalEntity(&parser->m_prologState);
         1354  +    parser->m_processor = externalParEntInitProcessor;
  1063   1355     }
  1064   1356   #endif /* XML_DTD */
  1065   1357     return parser;
  1066   1358   }
  1067   1359   
  1068   1360   static void FASTCALL
  1069   1361   destroyBindings(BINDING *bindings, XML_Parser parser)
  1070   1362   {
  1071   1363     for (;;) {
  1072   1364       BINDING *b = bindings;
  1073   1365       if (!b)
  1074   1366         break;
  1075   1367       bindings = b->nextTagBinding;
  1076         -    FREE(b->uri);
  1077         -    FREE(b);
         1368  +    FREE(parser, b->uri);
         1369  +    FREE(parser, b);
  1078   1370     }
  1079   1371   }
  1080   1372   
  1081   1373   void XMLCALL
  1082   1374   XML_ParserFree(XML_Parser parser)
  1083   1375   {
  1084   1376     TAG *tagList;
  1085   1377     OPEN_INTERNAL_ENTITY *entityList;
  1086   1378     if (parser == NULL)
  1087   1379       return;
  1088         -  /* free tagStack and freeTagList */
  1089         -  tagList = tagStack;
         1380  +  /* free m_tagStack and m_freeTagList */
         1381  +  tagList = parser->m_tagStack;
  1090   1382     for (;;) {
  1091   1383       TAG *p;
  1092   1384       if (tagList == NULL) {
  1093         -      if (freeTagList == NULL)
         1385  +      if (parser->m_freeTagList == NULL)
  1094   1386           break;
  1095         -      tagList = freeTagList;
  1096         -      freeTagList = NULL;
         1387  +      tagList = parser->m_freeTagList;
         1388  +      parser->m_freeTagList = NULL;
  1097   1389       }
  1098   1390       p = tagList;
  1099   1391       tagList = tagList->parent;
  1100         -    FREE(p->buf);
         1392  +    FREE(parser, p->buf);
  1101   1393       destroyBindings(p->bindings, parser);
  1102         -    FREE(p);
         1394  +    FREE(parser, p);
  1103   1395     }
  1104         -  /* free openInternalEntities and freeInternalEntities */
  1105         -  entityList = openInternalEntities;
         1396  +  /* free m_openInternalEntities and m_freeInternalEntities */
         1397  +  entityList = parser->m_openInternalEntities;
  1106   1398     for (;;) {
  1107   1399       OPEN_INTERNAL_ENTITY *openEntity;
  1108   1400       if (entityList == NULL) {
  1109         -      if (freeInternalEntities == NULL)
         1401  +      if (parser->m_freeInternalEntities == NULL)
  1110   1402           break;
  1111         -      entityList = freeInternalEntities;
  1112         -      freeInternalEntities = NULL;
         1403  +      entityList = parser->m_freeInternalEntities;
         1404  +      parser->m_freeInternalEntities = NULL;
  1113   1405       }
  1114   1406       openEntity = entityList;
  1115   1407       entityList = entityList->next;
  1116         -    FREE(openEntity);
         1408  +    FREE(parser, openEntity);
  1117   1409     }
  1118   1410   
  1119         -  destroyBindings(freeBindingList, parser);
  1120         -  destroyBindings(inheritedBindings, parser);
  1121         -  poolDestroy(&tempPool);
  1122         -  poolDestroy(&temp2Pool);
         1411  +  destroyBindings(parser->m_freeBindingList, parser);
         1412  +  destroyBindings(parser->m_inheritedBindings, parser);
         1413  +  poolDestroy(&parser->m_tempPool);
         1414  +  poolDestroy(&parser->m_temp2Pool);
         1415  +  FREE(parser, (void *)parser->m_protocolEncodingName);
  1123   1416   #ifdef XML_DTD
  1124   1417     /* external parameter entity parsers share the DTD structure
  1125   1418        parser->m_dtd with the root parser, so we must not destroy it
  1126   1419     */
  1127         -  if (!isParamEntity && _dtd)
         1420  +  if (!parser->m_isParamEntity && parser->m_dtd)
  1128   1421   #else
  1129         -  if (_dtd)
         1422  +  if (parser->m_dtd)
  1130   1423   #endif /* XML_DTD */
  1131         -    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
  1132         -  FREE((void *)atts);
  1133         -  FREE(groupConnector);
  1134         -  FREE(buffer);
  1135         -  FREE(dataBuf);
  1136         -  FREE(nsAtts);
  1137         -  FREE(unknownEncodingMem);
  1138         -  if (unknownEncodingRelease)
  1139         -    unknownEncodingRelease(unknownEncodingData);
  1140         -  FREE(parser);
         1424  +    dtdDestroy(parser->m_dtd, (XML_Bool)!parser->m_parentParser, &parser->m_mem);
         1425  +  FREE(parser, (void *)parser->m_atts);
         1426  +#ifdef XML_ATTR_INFO
         1427  +  FREE(parser, (void *)parser->m_attInfo);
         1428  +#endif
         1429  +  FREE(parser, parser->m_groupConnector);
         1430  +  FREE(parser, parser->m_buffer);
         1431  +  FREE(parser, parser->m_dataBuf);
         1432  +  FREE(parser, parser->m_nsAtts);
         1433  +  FREE(parser, parser->m_unknownEncodingMem);
         1434  +  if (parser->m_unknownEncodingRelease)
         1435  +    parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
         1436  +  FREE(parser, parser);
  1141   1437   }
  1142   1438   
  1143   1439   void XMLCALL
  1144   1440   XML_UseParserAsHandlerArg(XML_Parser parser)
  1145   1441   {
  1146         -  handlerArg = parser;
         1442  +  if (parser != NULL)
         1443  +    parser->m_handlerArg = parser;
  1147   1444   }
  1148   1445   
  1149   1446   enum XML_Error XMLCALL
  1150   1447   XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
  1151   1448   {
         1449  +  if (parser == NULL)
         1450  +    return XML_ERROR_INVALID_ARGUMENT;
  1152   1451   #ifdef XML_DTD
  1153   1452     /* block after XML_Parse()/XML_ParseBuffer() has been called */
  1154         -  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
         1453  +  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
  1155   1454       return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
  1156         -  useForeignDTD = useDTD;
         1455  +  parser->m_useForeignDTD = useDTD;
  1157   1456     return XML_ERROR_NONE;
  1158   1457   #else
  1159   1458     return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
  1160   1459   #endif
  1161   1460   }
  1162   1461   
  1163   1462   void XMLCALL
  1164   1463   XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
  1165   1464   {
         1465  +  if (parser == NULL)
         1466  +    return;
  1166   1467     /* block after XML_Parse()/XML_ParseBuffer() has been called */
  1167         -  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
         1468  +  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
  1168   1469       return;
  1169         -  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
         1470  +  parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
  1170   1471   }
  1171   1472   
  1172   1473   void XMLCALL
  1173   1474   XML_SetUserData(XML_Parser parser, void *p)
  1174   1475   {
  1175         -  if (handlerArg == userData)
  1176         -    handlerArg = userData = p;
         1476  +  if (parser == NULL)
         1477  +    return;
         1478  +  if (parser->m_handlerArg == parser->m_userData)
         1479  +    parser->m_handlerArg = parser->m_userData = p;
  1177   1480     else
  1178         -    userData = p;
         1481  +    parser->m_userData = p;
  1179   1482   }
  1180   1483   
  1181   1484   enum XML_Status XMLCALL
  1182   1485   XML_SetBase(XML_Parser parser, const XML_Char *p)
  1183   1486   {
         1487  +  if (parser == NULL)
         1488  +    return XML_STATUS_ERROR;
  1184   1489     if (p) {
  1185         -    p = poolCopyString(&_dtd->pool, p);
         1490  +    p = poolCopyString(&parser->m_dtd->pool, p);
  1186   1491       if (!p)
  1187   1492         return XML_STATUS_ERROR;
  1188         -    curBase = p;
         1493  +    parser->m_curBase = p;
  1189   1494     }
  1190   1495     else
  1191         -    curBase = NULL;
         1496  +    parser->m_curBase = NULL;
  1192   1497     return XML_STATUS_OK;
  1193   1498   }
  1194   1499   
  1195   1500   const XML_Char * XMLCALL
  1196   1501   XML_GetBase(XML_Parser parser)
  1197   1502   {
  1198         -  return curBase;
         1503  +  if (parser == NULL)
         1504  +    return NULL;
         1505  +  return parser->m_curBase;
  1199   1506   }
  1200   1507   
  1201   1508   int XMLCALL
  1202   1509   XML_GetSpecifiedAttributeCount(XML_Parser parser)
  1203   1510   {
  1204         -  return nSpecifiedAtts;
         1511  +  if (parser == NULL)
         1512  +    return -1;
         1513  +  return parser->m_nSpecifiedAtts;
  1205   1514   }
  1206   1515   
  1207   1516   int XMLCALL
  1208   1517   XML_GetIdAttributeIndex(XML_Parser parser)
  1209   1518   {
  1210         -  return idAttIndex;
         1519  +  if (parser == NULL)
         1520  +    return -1;
         1521  +  return parser->m_idAttIndex;
  1211   1522   }
         1523  +
         1524  +#ifdef XML_ATTR_INFO
         1525  +const XML_AttrInfo * XMLCALL
         1526  +XML_GetAttributeInfo(XML_Parser parser)
         1527  +{
         1528  +  if (parser == NULL)
         1529  +    return NULL;
         1530  +  return parser->m_attInfo;
         1531  +}
         1532  +#endif
  1212   1533   
  1213   1534   void XMLCALL
  1214   1535   XML_SetElementHandler(XML_Parser parser,
  1215   1536                         XML_StartElementHandler start,
  1216   1537                         XML_EndElementHandler end)
  1217   1538   {
  1218         -  startElementHandler = start;
  1219         -  endElementHandler = end;
         1539  +  if (parser == NULL)
         1540  +    return;
         1541  +  parser->m_startElementHandler = start;
         1542  +  parser->m_endElementHandler = end;
  1220   1543   }
  1221   1544   
  1222   1545   void XMLCALL
  1223   1546   XML_SetStartElementHandler(XML_Parser parser,
  1224   1547                              XML_StartElementHandler start) {
  1225         -  startElementHandler = start;
         1548  +  if (parser != NULL)
         1549  +    parser->m_startElementHandler = start;
  1226   1550   }
  1227   1551   
  1228   1552   void XMLCALL
  1229   1553   XML_SetEndElementHandler(XML_Parser parser,
  1230   1554                            XML_EndElementHandler end) {
  1231         -  endElementHandler = end;
         1555  +  if (parser != NULL)
         1556  +    parser->m_endElementHandler = end;
  1232   1557   }
  1233   1558   
  1234   1559   void XMLCALL
  1235   1560   XML_SetCharacterDataHandler(XML_Parser parser,
  1236   1561                               XML_CharacterDataHandler handler)
  1237   1562   {
  1238         -  characterDataHandler = handler;
         1563  +  if (parser != NULL)
         1564  +    parser->m_characterDataHandler = handler;
  1239   1565   }
  1240   1566   
  1241   1567   void XMLCALL
  1242   1568   XML_SetProcessingInstructionHandler(XML_Parser parser,
  1243   1569                                       XML_ProcessingInstructionHandler handler)
  1244   1570   {
  1245         -  processingInstructionHandler = handler;
         1571  +  if (parser != NULL)
         1572  +    parser->m_processingInstructionHandler = handler;
  1246   1573   }
  1247   1574   
  1248   1575   void XMLCALL
  1249   1576   XML_SetCommentHandler(XML_Parser parser,
  1250   1577                         XML_CommentHandler handler)
  1251   1578   {
  1252         -  commentHandler = handler;
         1579  +  if (parser != NULL)
         1580  +    parser->m_commentHandler = handler;
  1253   1581   }
  1254   1582   
  1255   1583   void XMLCALL
  1256   1584   XML_SetCdataSectionHandler(XML_Parser parser,
  1257   1585                              XML_StartCdataSectionHandler start,
  1258   1586                              XML_EndCdataSectionHandler end)
  1259   1587   {
  1260         -  startCdataSectionHandler = start;
  1261         -  endCdataSectionHandler = end;
         1588  +  if (parser == NULL)
         1589  +    return;
         1590  +  parser->m_startCdataSectionHandler = start;
         1591  +  parser->m_endCdataSectionHandler = end;
  1262   1592   }
  1263   1593   
  1264   1594   void XMLCALL
  1265   1595   XML_SetStartCdataSectionHandler(XML_Parser parser,
  1266   1596                                   XML_StartCdataSectionHandler start) {
  1267         -  startCdataSectionHandler = start;
         1597  +  if (parser != NULL)
         1598  +    parser->m_startCdataSectionHandler = start;
  1268   1599   }
  1269   1600   
  1270   1601   void XMLCALL
  1271   1602   XML_SetEndCdataSectionHandler(XML_Parser parser,
  1272   1603                                 XML_EndCdataSectionHandler end) {
  1273         -  endCdataSectionHandler = end;
         1604  +  if (parser != NULL)
         1605  +    parser->m_endCdataSectionHandler = end;
  1274   1606   }
  1275   1607   
  1276   1608   void XMLCALL
  1277   1609   XML_SetDefaultHandler(XML_Parser parser,
  1278   1610                         XML_DefaultHandler handler)
  1279   1611   {
  1280         -  defaultHandler = handler;
  1281         -  defaultExpandInternalEntities = XML_FALSE;
         1612  +  if (parser == NULL)
         1613  +    return;
         1614  +  parser->m_defaultHandler = handler;
         1615  +  parser->m_defaultExpandInternalEntities = XML_FALSE;
  1282   1616   }
  1283   1617   
  1284   1618   void XMLCALL
  1285   1619   XML_SetDefaultHandlerExpand(XML_Parser parser,
  1286   1620                               XML_DefaultHandler handler)
  1287   1621   {
  1288         -  defaultHandler = handler;
  1289         -  defaultExpandInternalEntities = XML_TRUE;
         1622  +  if (parser == NULL)
         1623  +    return;
         1624  +  parser->m_defaultHandler = handler;
         1625  +  parser->m_defaultExpandInternalEntities = XML_TRUE;
  1290   1626   }
  1291   1627   
  1292   1628   void XMLCALL
  1293   1629   XML_SetDoctypeDeclHandler(XML_Parser parser,
  1294   1630                             XML_StartDoctypeDeclHandler start,
  1295   1631                             XML_EndDoctypeDeclHandler end)
  1296   1632   {
  1297         -  startDoctypeDeclHandler = start;
  1298         -  endDoctypeDeclHandler = end;
         1633  +  if (parser == NULL)
         1634  +    return;
         1635  +  parser->m_startDoctypeDeclHandler = start;
         1636  +  parser->m_endDoctypeDeclHandler = end;
  1299   1637   }
  1300   1638   
  1301   1639   void XMLCALL
  1302   1640   XML_SetStartDoctypeDeclHandler(XML_Parser parser,
  1303   1641                                  XML_StartDoctypeDeclHandler start) {
  1304         -  startDoctypeDeclHandler = start;
         1642  +  if (parser != NULL)
         1643  +    parser->m_startDoctypeDeclHandler = start;
  1305   1644   }
  1306   1645   
  1307   1646   void XMLCALL
  1308   1647   XML_SetEndDoctypeDeclHandler(XML_Parser parser,
  1309   1648                                XML_EndDoctypeDeclHandler end) {
  1310         -  endDoctypeDeclHandler = end;
         1649  +  if (parser != NULL)
         1650  +    parser->m_endDoctypeDeclHandler = end;
  1311   1651   }
  1312   1652   
  1313   1653   void XMLCALL
  1314   1654   XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
  1315   1655                                    XML_UnparsedEntityDeclHandler handler)
  1316   1656   {
  1317         -  unparsedEntityDeclHandler = handler;
         1657  +  if (parser != NULL)
         1658  +    parser->m_unparsedEntityDeclHandler = handler;
  1318   1659   }
  1319   1660   
  1320   1661   void XMLCALL
  1321   1662   XML_SetNotationDeclHandler(XML_Parser parser,
  1322   1663                              XML_NotationDeclHandler handler)
  1323   1664   {
  1324         -  notationDeclHandler = handler;
         1665  +  if (parser != NULL)
         1666  +    parser->m_notationDeclHandler = handler;
  1325   1667   }
  1326   1668   
  1327   1669   void XMLCALL
  1328   1670   XML_SetNamespaceDeclHandler(XML_Parser parser,
  1329   1671                               XML_StartNamespaceDeclHandler start,
  1330   1672                               XML_EndNamespaceDeclHandler end)
  1331   1673   {
  1332         -  startNamespaceDeclHandler = start;
  1333         -  endNamespaceDeclHandler = end;
         1674  +  if (parser == NULL)
         1675  +    return;
         1676  +  parser->m_startNamespaceDeclHandler = start;
         1677  +  parser->m_endNamespaceDeclHandler = end;
  1334   1678   }
  1335   1679   
  1336   1680   void XMLCALL
  1337   1681   XML_SetStartNamespaceDeclHandler(XML_Parser parser,
  1338   1682                                    XML_StartNamespaceDeclHandler start) {
  1339         -  startNamespaceDeclHandler = start;
         1683  +  if (parser != NULL)
         1684  +    parser->m_startNamespaceDeclHandler = start;
  1340   1685   }
  1341   1686   
  1342   1687   void XMLCALL
  1343   1688   XML_SetEndNamespaceDeclHandler(XML_Parser parser,
  1344   1689                                  XML_EndNamespaceDeclHandler end) {
  1345         -  endNamespaceDeclHandler = end;
         1690  +  if (parser != NULL)
         1691  +    parser->m_endNamespaceDeclHandler = end;
  1346   1692   }
  1347   1693   
  1348   1694   void XMLCALL
  1349   1695   XML_SetNotStandaloneHandler(XML_Parser parser,
  1350   1696                               XML_NotStandaloneHandler handler)
  1351   1697   {
  1352         -  notStandaloneHandler = handler;
         1698  +  if (parser != NULL)
         1699  +    parser->m_notStandaloneHandler = handler;
  1353   1700   }
  1354   1701   
  1355   1702   void XMLCALL
  1356   1703   XML_SetExternalEntityRefHandler(XML_Parser parser,
  1357   1704                                   XML_ExternalEntityRefHandler handler)
  1358   1705   {
  1359         -  externalEntityRefHandler = handler;
         1706  +  if (parser != NULL)
         1707  +    parser->m_externalEntityRefHandler = handler;
  1360   1708   }
  1361   1709   
  1362   1710   void XMLCALL
  1363   1711   XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
  1364   1712   {
         1713  +  if (parser == NULL)
         1714  +    return;
  1365   1715     if (arg)
  1366         -    externalEntityRefHandlerArg = (XML_Parser)arg;
         1716  +    parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
  1367   1717     else
  1368         -    externalEntityRefHandlerArg = parser;
         1718  +    parser->m_externalEntityRefHandlerArg = parser;
  1369   1719   }
  1370   1720   
  1371   1721   void XMLCALL
  1372   1722   XML_SetSkippedEntityHandler(XML_Parser parser,
  1373   1723                               XML_SkippedEntityHandler handler)
  1374   1724   {
  1375         -  skippedEntityHandler = handler;
         1725  +  if (parser != NULL)
         1726  +    parser->m_skippedEntityHandler = handler;
  1376   1727   }
  1377   1728   
  1378   1729   void XMLCALL
  1379   1730   XML_SetUnknownEncodingHandler(XML_Parser parser,
  1380   1731                                 XML_UnknownEncodingHandler handler,
  1381   1732                                 void *data)
  1382   1733   {
  1383         -  unknownEncodingHandler = handler;
  1384         -  unknownEncodingHandlerData = data;
         1734  +  if (parser == NULL)
         1735  +    return;
         1736  +  parser->m_unknownEncodingHandler = handler;
         1737  +  parser->m_unknownEncodingHandlerData = data;
  1385   1738   }
  1386   1739   
  1387   1740   void XMLCALL
  1388   1741   XML_SetElementDeclHandler(XML_Parser parser,
  1389   1742                             XML_ElementDeclHandler eldecl)
  1390   1743   {
  1391         -  elementDeclHandler = eldecl;
         1744  +  if (parser != NULL)
         1745  +    parser->m_elementDeclHandler = eldecl;
  1392   1746   }
  1393   1747   
  1394   1748   void XMLCALL
  1395   1749   XML_SetAttlistDeclHandler(XML_Parser parser,
  1396   1750                             XML_AttlistDeclHandler attdecl)
  1397   1751   {
  1398         -  attlistDeclHandler = attdecl;
         1752  +  if (parser != NULL)
         1753  +    parser->m_attlistDeclHandler = attdecl;
  1399   1754   }
  1400   1755   
  1401   1756   void XMLCALL
  1402   1757   XML_SetEntityDeclHandler(XML_Parser parser,
  1403   1758                            XML_EntityDeclHandler handler)
  1404   1759   {
  1405         -  entityDeclHandler = handler;
         1760  +  if (parser != NULL)
         1761  +    parser->m_entityDeclHandler = handler;
  1406   1762   }
  1407   1763   
  1408   1764   void XMLCALL
  1409   1765   XML_SetXmlDeclHandler(XML_Parser parser,
  1410   1766                         XML_XmlDeclHandler handler) {
  1411         -  xmlDeclHandler = handler;
         1767  +  if (parser != NULL)
         1768  +    parser->m_xmlDeclHandler = handler;
  1412   1769   }
  1413   1770   
  1414   1771   int XMLCALL
  1415   1772   XML_SetParamEntityParsing(XML_Parser parser,
  1416   1773                             enum XML_ParamEntityParsing peParsing)
  1417   1774   {
         1775  +  if (parser == NULL)
         1776  +    return 0;
  1418   1777     /* block after XML_Parse()/XML_ParseBuffer() has been called */
  1419         -  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
         1778  +  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
  1420   1779       return 0;
  1421   1780   #ifdef XML_DTD
  1422         -  paramEntityParsing = peParsing;
         1781  +  parser->m_paramEntityParsing = peParsing;
  1423   1782     return 1;
  1424   1783   #else
  1425   1784     return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
  1426   1785   #endif
  1427   1786   }
         1787  +
         1788  +int XMLCALL
         1789  +XML_SetHashSalt(XML_Parser parser,
         1790  +                unsigned long hash_salt)
         1791  +{
         1792  +  if (parser == NULL)
         1793  +    return 0;
         1794  +  if (parser->m_parentParser)
         1795  +    return XML_SetHashSalt(parser->m_parentParser, hash_salt);
         1796  +  /* block after XML_Parse()/XML_ParseBuffer() has been called */
         1797  +  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
         1798  +    return 0;
         1799  +  parser->m_hash_secret_salt = hash_salt;
         1800  +  return 1;
         1801  +}
  1428   1802   
  1429   1803   enum XML_Status XMLCALL
  1430   1804   XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
  1431   1805   {
  1432         -  switch (ps_parsing) {
         1806  +  if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
         1807  +    if (parser != NULL)
         1808  +      parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
         1809  +    return XML_STATUS_ERROR;
         1810  +  }
         1811  +  switch (parser->m_parsingStatus.parsing) {
  1433   1812     case XML_SUSPENDED:
  1434         -    errorCode = XML_ERROR_SUSPENDED;
         1813  +    parser->m_errorCode = XML_ERROR_SUSPENDED;
  1435   1814       return XML_STATUS_ERROR;
  1436   1815     case XML_FINISHED:
  1437         -    errorCode = XML_ERROR_FINISHED;
         1816  +    parser->m_errorCode = XML_ERROR_FINISHED;
  1438   1817       return XML_STATUS_ERROR;
         1818  +  case XML_INITIALIZED:
         1819  +    if (parser->m_parentParser == NULL && !startParsing(parser)) {
         1820  +      parser->m_errorCode = XML_ERROR_NO_MEMORY;
         1821  +      return XML_STATUS_ERROR;
         1822  +    }
  1439   1823     default:
  1440         -    ps_parsing = XML_PARSING;
         1824  +    parser->m_parsingStatus.parsing = XML_PARSING;
  1441   1825     }
  1442   1826   
  1443   1827     if (len == 0) {
  1444         -    ps_finalBuffer = (XML_Bool)isFinal;
         1828  +    parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
  1445   1829       if (!isFinal)
  1446   1830         return XML_STATUS_OK;
  1447         -    positionPtr = bufferPtr;
  1448         -    parseEndPtr = bufferEnd;
         1831  +    parser->m_positionPtr = parser->m_bufferPtr;
         1832  +    parser->m_parseEndPtr = parser->m_bufferEnd;
  1449   1833   
  1450   1834       /* If data are left over from last buffer, and we now know that these
  1451   1835          data are the final chunk of input, then we have to check them again
  1452   1836          to detect errors based on that fact.
  1453   1837       */
  1454         -    errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
         1838  +    parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
  1455   1839   
  1456         -    if (errorCode == XML_ERROR_NONE) {
  1457         -      switch (ps_parsing) {
         1840  +    if (parser->m_errorCode == XML_ERROR_NONE) {
         1841  +      switch (parser->m_parsingStatus.parsing) {
  1458   1842         case XML_SUSPENDED:
  1459         -        XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
  1460         -        positionPtr = bufferPtr;
         1843  +        /* It is hard to be certain, but it seems that this case
         1844  +         * cannot occur.  This code is cleaning up a previous parse
         1845  +         * with no new data (since len == 0).  Changing the parsing
         1846  +         * state requires getting to execute a handler function, and
         1847  +         * there doesn't seem to be an opportunity for that while in
         1848  +         * this circumstance.
         1849  +         *
         1850  +         * Given the uncertainty, we retain the code but exclude it
         1851  +         * from coverage tests.
         1852  +         *
         1853  +         * LCOV_EXCL_START
         1854  +         */
         1855  +        XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
         1856  +        parser->m_positionPtr = parser->m_bufferPtr;
  1461   1857           return XML_STATUS_SUSPENDED;
  1462         -      case XML_INITIALIZED: 
         1858  +        /* LCOV_EXCL_STOP */
         1859  +      case XML_INITIALIZED:
  1463   1860         case XML_PARSING:
  1464         -        ps_parsing = XML_FINISHED;
         1861  +        parser->m_parsingStatus.parsing = XML_FINISHED;
  1465   1862           /* fall through */
  1466   1863         default:
  1467   1864           return XML_STATUS_OK;
  1468   1865         }
  1469   1866       }
  1470         -    eventEndPtr = eventPtr;
  1471         -    processor = errorProcessor;
         1867  +    parser->m_eventEndPtr = parser->m_eventPtr;
         1868  +    parser->m_processor = errorProcessor;
  1472   1869       return XML_STATUS_ERROR;
  1473   1870     }
  1474   1871   #ifndef XML_CONTEXT_BYTES
  1475         -  else if (bufferPtr == bufferEnd) {
         1872  +  else if (parser->m_bufferPtr == parser->m_bufferEnd) {
  1476   1873       const char *end;
  1477   1874       int nLeftOver;
  1478         -    enum XML_Error result;
  1479         -    parseEndByteIndex += len;
  1480         -    positionPtr = s;
  1481         -    ps_finalBuffer = (XML_Bool)isFinal;
         1875  +    enum XML_Status result;
         1876  +    /* Detect overflow (a+b > MAX <==> b > MAX-a) */
         1877  +    if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
         1878  +       parser->m_errorCode = XML_ERROR_NO_MEMORY;
         1879  +       parser->m_eventPtr = parser->m_eventEndPtr = NULL;
         1880  +       parser->m_processor = errorProcessor;
         1881  +       return XML_STATUS_ERROR;
         1882  +    }
         1883  +    parser->m_parseEndByteIndex += len;
         1884  +    parser->m_positionPtr = s;
         1885  +    parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
  1482   1886   
  1483         -    errorCode = processor(parser, s, parseEndPtr = s + len, &end);
         1887  +    parser->m_errorCode = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
  1484   1888   
  1485         -    if (errorCode != XML_ERROR_NONE) {
  1486         -      eventEndPtr = eventPtr;
  1487         -      processor = errorProcessor;
         1889  +    if (parser->m_errorCode != XML_ERROR_NONE) {
         1890  +      parser->m_eventEndPtr = parser->m_eventPtr;
         1891  +      parser->m_processor = errorProcessor;
  1488   1892         return XML_STATUS_ERROR;
  1489   1893       }
  1490   1894       else {
  1491         -      switch (ps_parsing) {
         1895  +      switch (parser->m_parsingStatus.parsing) {
  1492   1896         case XML_SUSPENDED:
  1493   1897           result = XML_STATUS_SUSPENDED;
  1494   1898           break;
  1495   1899         case XML_INITIALIZED:
  1496   1900         case XML_PARSING:
  1497         -        result = XML_STATUS_OK;
  1498   1901           if (isFinal) {
  1499         -          ps_parsing = XML_FINISHED;
  1500         -          return result;
         1902  +          parser->m_parsingStatus.parsing = XML_FINISHED;
         1903  +          return XML_STATUS_OK;
  1501   1904           }
         1905  +      /* fall through */
         1906  +      default:
         1907  +        result = XML_STATUS_OK;
  1502   1908         }
  1503   1909       }
  1504   1910   
  1505         -    XmlUpdatePosition(encoding, positionPtr, end, &position);
         1911  +    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, &parser->m_position);
  1506   1912       nLeftOver = s + len - end;
  1507   1913       if (nLeftOver) {
  1508         -      if (buffer == NULL || nLeftOver > bufferLim - buffer) {
  1509         -        /* FIXME avoid integer overflow */
  1510         -        char *temp;
  1511         -        temp = (buffer == NULL
  1512         -                ? (char *)MALLOC(len * 2)
  1513         -                : (char *)REALLOC(buffer, len * 2));
         1914  +      if (parser->m_buffer == NULL || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
         1915  +        /* avoid _signed_ integer overflow */
         1916  +        char *temp = NULL;
         1917  +        const int bytesToAllocate = (int)((unsigned)len * 2U);
         1918  +        if (bytesToAllocate > 0) {
         1919  +          temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
         1920  +        }
  1514   1921           if (temp == NULL) {
  1515         -          errorCode = XML_ERROR_NO_MEMORY;
         1922  +          parser->m_errorCode = XML_ERROR_NO_MEMORY;
         1923  +          parser->m_eventPtr = parser->m_eventEndPtr = NULL;
         1924  +          parser->m_processor = errorProcessor;
  1516   1925             return XML_STATUS_ERROR;
  1517   1926           }
  1518         -        buffer = temp;
  1519         -        if (!buffer) {
  1520         -          errorCode = XML_ERROR_NO_MEMORY;
  1521         -          eventPtr = eventEndPtr = NULL;
  1522         -          processor = errorProcessor;
  1523         -          return XML_STATUS_ERROR;
  1524         -        }
  1525         -        bufferLim = buffer + len * 2;
         1927  +        parser->m_buffer = temp;
         1928  +        parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
  1526   1929         }
  1527         -      memcpy(buffer, end, nLeftOver);
         1930  +      memcpy(parser->m_buffer, end, nLeftOver);
  1528   1931       }
  1529         -    bufferPtr = buffer;
  1530         -    bufferEnd = buffer + nLeftOver;
  1531         -    positionPtr = bufferPtr;
  1532         -    parseEndPtr = bufferEnd;
  1533         -    eventPtr = bufferPtr;
  1534         -    eventEndPtr = bufferPtr;
         1932  +    parser->m_bufferPtr = parser->m_buffer;
         1933  +    parser->m_bufferEnd = parser->m_buffer + nLeftOver;
         1934  +    parser->m_positionPtr = parser->m_bufferPtr;
         1935  +    parser->m_parseEndPtr = parser->m_bufferEnd;
         1936  +    parser->m_eventPtr = parser->m_bufferPtr;
         1937  +    parser->m_eventEndPtr = parser->m_bufferPtr;
  1535   1938       return result;
  1536   1939     }
  1537   1940   #endif  /* not defined XML_CONTEXT_BYTES */
  1538   1941     else {
  1539   1942       void *buff = XML_GetBuffer(parser, len);
  1540   1943       if (buff == NULL)
  1541   1944         return XML_STATUS_ERROR;
................................................................................
  1548   1951   
  1549   1952   enum XML_Status XMLCALL
  1550   1953   XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
  1551   1954   {
  1552   1955     const char *start;
  1553   1956     enum XML_Status result = XML_STATUS_OK;
  1554   1957   
  1555         -  switch (ps_parsing) {
         1958  +  if (parser == NULL)
         1959  +    return XML_STATUS_ERROR;
         1960  +  switch (parser->m_parsingStatus.parsing) {
  1556   1961     case XML_SUSPENDED:
  1557         -    errorCode = XML_ERROR_SUSPENDED;
         1962  +    parser->m_errorCode = XML_ERROR_SUSPENDED;
  1558   1963       return XML_STATUS_ERROR;
  1559   1964     case XML_FINISHED:
  1560         -    errorCode = XML_ERROR_FINISHED;
         1965  +    parser->m_errorCode = XML_ERROR_FINISHED;
  1561   1966       return XML_STATUS_ERROR;
         1967  +  case XML_INITIALIZED:
         1968  +    if (parser->m_parentParser == NULL && !startParsing(parser)) {
         1969  +      parser->m_errorCode = XML_ERROR_NO_MEMORY;
         1970  +      return XML_STATUS_ERROR;
         1971  +    }
  1562   1972     default:
  1563         -    ps_parsing = XML_PARSING;
         1973  +    parser->m_parsingStatus.parsing = XML_PARSING;
  1564   1974     }
  1565   1975   
  1566         -  start = bufferPtr;
  1567         -  positionPtr = start;
  1568         -  bufferEnd += len;
  1569         -  parseEndPtr = bufferEnd;
  1570         -  parseEndByteIndex += len;
  1571         -  ps_finalBuffer = (XML_Bool)isFinal;
         1976  +  start = parser->m_bufferPtr;
         1977  +  parser->m_positionPtr = start;
         1978  +  parser->m_bufferEnd += len;
         1979  +  parser->m_parseEndPtr = parser->m_bufferEnd;
         1980  +  parser->m_parseEndByteIndex += len;
         1981  +  parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
  1572   1982   
  1573         -  errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
         1983  +  parser->m_errorCode = parser->m_processor(parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
  1574   1984   
  1575         -  if (errorCode != XML_ERROR_NONE) {
  1576         -    eventEndPtr = eventPtr;
  1577         -    processor = errorProcessor;
         1985  +  if (parser->m_errorCode != XML_ERROR_NONE) {
         1986  +    parser->m_eventEndPtr = parser->m_eventPtr;
         1987  +    parser->m_processor = errorProcessor;
  1578   1988       return XML_STATUS_ERROR;
  1579   1989     }
  1580   1990     else {
  1581         -    switch (ps_parsing) {
         1991  +    switch (parser->m_parsingStatus.parsing) {
  1582   1992       case XML_SUSPENDED:
  1583   1993         result = XML_STATUS_SUSPENDED;
  1584   1994         break;
  1585         -    case XML_INITIALIZED: 
         1995  +    case XML_INITIALIZED:
  1586   1996       case XML_PARSING:
  1587   1997         if (isFinal) {
  1588         -        ps_parsing = XML_FINISHED;
         1998  +        parser->m_parsingStatus.parsing = XML_FINISHED;
  1589   1999           return result;
  1590   2000         }
  1591   2001       default: ;  /* should not happen */
  1592   2002       }
  1593   2003     }
  1594   2004   
  1595         -  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
  1596         -  positionPtr = bufferPtr;
         2005  +  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
         2006  +  parser->m_positionPtr = parser->m_bufferPtr;
  1597   2007     return result;
  1598   2008   }
  1599   2009   
  1600   2010   void * XMLCALL
  1601   2011   XML_GetBuffer(XML_Parser parser, int len)
  1602   2012   {
  1603         -  switch (ps_parsing) {
         2013  +  if (parser == NULL)
         2014  +    return NULL;
         2015  +  if (len < 0) {
         2016  +    parser->m_errorCode = XML_ERROR_NO_MEMORY;
         2017  +    return NULL;
         2018  +  }
         2019  +  switch (parser->m_parsingStatus.parsing) {
  1604   2020     case XML_SUSPENDED:
  1605         -    errorCode = XML_ERROR_SUSPENDED;
         2021  +    parser->m_errorCode = XML_ERROR_SUSPENDED;
  1606   2022       return NULL;
  1607   2023     case XML_FINISHED:
  1608         -    errorCode = XML_ERROR_FINISHED;
         2024  +    parser->m_errorCode = XML_ERROR_FINISHED;
  1609   2025       return NULL;
  1610   2026     default: ;
  1611   2027     }
  1612   2028   
  1613         -  if (len > bufferLim - bufferEnd) {
  1614         -    /* FIXME avoid integer overflow */
  1615         -    int neededSize = len + (int)(bufferEnd - bufferPtr);
         2029  +  if (len > parser->m_bufferLim - parser->m_bufferEnd) {
         2030  +#ifdef XML_CONTEXT_BYTES
         2031  +    int keep;
         2032  +#endif  /* defined XML_CONTEXT_BYTES */
         2033  +    /* Do not invoke signed arithmetic overflow: */
         2034  +    int neededSize = (int) ((unsigned)len + (unsigned)(parser->m_bufferEnd - parser->m_bufferPtr));
         2035  +    if (neededSize < 0) {
         2036  +      parser->m_errorCode = XML_ERROR_NO_MEMORY;
         2037  +      return NULL;
         2038  +    }
  1616   2039   #ifdef XML_CONTEXT_BYTES
  1617         -    int keep = (int)(bufferPtr - buffer);
  1618         -
         2040  +    keep = (int)(parser->m_bufferPtr - parser->m_buffer);
  1619   2041       if (keep > XML_CONTEXT_BYTES)
  1620   2042         keep = XML_CONTEXT_BYTES;
  1621   2043       neededSize += keep;
  1622   2044   #endif  /* defined XML_CONTEXT_BYTES */
  1623         -    if (neededSize  <= bufferLim - buffer) {
         2045  +    if (neededSize  <= parser->m_bufferLim - parser->m_buffer) {
  1624   2046   #ifdef XML_CONTEXT_BYTES
  1625         -      if (keep < bufferPtr - buffer) {
  1626         -        int offset = (int)(bufferPtr - buffer) - keep;
  1627         -        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
  1628         -        bufferEnd -= offset;
  1629         -        bufferPtr -= offset;
         2047  +      if (keep < parser->m_bufferPtr - parser->m_buffer) {
         2048  +        int offset = (int)(parser->m_bufferPtr - parser->m_buffer) - keep;
         2049  +        memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep);
         2050  +        parser->m_bufferEnd -= offset;
         2051  +        parser->m_bufferPtr -= offset;
  1630   2052         }
  1631   2053   #else
  1632         -      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
  1633         -      bufferEnd = buffer + (bufferEnd - bufferPtr);
  1634         -      bufferPtr = buffer;
         2054  +      memmove(parser->m_buffer, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr);
         2055  +      parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr);
         2056  +      parser->m_bufferPtr = parser->m_buffer;
  1635   2057   #endif  /* not defined XML_CONTEXT_BYTES */
  1636   2058       }
  1637   2059       else {
  1638   2060         char *newBuf;
  1639         -      int bufferSize = (int)(bufferLim - bufferPtr);
         2061  +      int bufferSize = (int)(parser->m_bufferLim - parser->m_bufferPtr);
  1640   2062         if (bufferSize == 0)
  1641   2063           bufferSize = INIT_BUFFER_SIZE;
  1642   2064         do {
  1643         -        bufferSize *= 2;
  1644         -      } while (bufferSize < neededSize);
  1645         -      newBuf = (char *)MALLOC(bufferSize);
         2065  +        /* Do not invoke signed arithmetic overflow: */
         2066  +        bufferSize = (int) (2U * (unsigned) bufferSize);
         2067  +      } while (bufferSize < neededSize && bufferSize > 0);
         2068  +      if (bufferSize <= 0) {
         2069  +        parser->m_errorCode = XML_ERROR_NO_MEMORY;
         2070  +        return NULL;
         2071  +      }
         2072  +      newBuf = (char *)MALLOC(parser, bufferSize);
  1646   2073         if (newBuf == 0) {
  1647         -        errorCode = XML_ERROR_NO_MEMORY;
         2074  +        parser->m_errorCode = XML_ERROR_NO_MEMORY;
  1648   2075           return NULL;
  1649   2076         }
  1650         -      bufferLim = newBuf + bufferSize;
         2077  +      parser->m_bufferLim = newBuf + bufferSize;
  1651   2078   #ifdef XML_CONTEXT_BYTES
  1652         -      if (bufferPtr) {
  1653         -        int keep = (int)(bufferPtr - buffer);
         2079  +      if (parser->m_bufferPtr) {
         2080  +        int keep = (int)(parser->m_bufferPtr - parser->m_buffer);
  1654   2081           if (keep > XML_CONTEXT_BYTES)
  1655   2082             keep = XML_CONTEXT_BYTES;
  1656         -        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
  1657         -        FREE(buffer);
  1658         -        buffer = newBuf;
  1659         -        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
  1660         -        bufferPtr = buffer + keep;
         2083  +        memcpy(newBuf, &parser->m_bufferPtr[-keep], parser->m_bufferEnd - parser->m_bufferPtr + keep);
         2084  +        FREE(parser, parser->m_buffer);
         2085  +        parser->m_buffer = newBuf;
         2086  +        parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr) + keep;
         2087  +        parser->m_bufferPtr = parser->m_buffer + keep;
  1661   2088         }
  1662   2089         else {
  1663         -        bufferEnd = newBuf + (bufferEnd - bufferPtr);
  1664         -        bufferPtr = buffer = newBuf;
         2090  +        parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr);
         2091  +        parser->m_bufferPtr = parser->m_buffer = newBuf;
  1665   2092         }
  1666   2093   #else
  1667         -      if (bufferPtr) {
  1668         -        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
  1669         -        FREE(buffer);
         2094  +      if (parser->m_bufferPtr) {
         2095  +        memcpy(newBuf, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr);
         2096  +        FREE(parser, parser->m_buffer);
  1670   2097         }
  1671         -      bufferEnd = newBuf + (bufferEnd - bufferPtr);
  1672         -      bufferPtr = buffer = newBuf;
         2098  +      parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr);
         2099  +      parser->m_bufferPtr = parser->m_buffer = newBuf;
  1673   2100   #endif  /* not defined XML_CONTEXT_BYTES */
  1674   2101       }
         2102  +    parser->m_eventPtr = parser->m_eventEndPtr = NULL;
         2103  +    parser->m_positionPtr = NULL;
  1675   2104     }
  1676         -  return bufferEnd;
         2105  +  return parser->m_bufferEnd;
  1677   2106   }
  1678   2107   
  1679   2108   enum XML_Status XMLCALL
  1680   2109   XML_StopParser(XML_Parser parser, XML_Bool resumable)
  1681   2110   {
  1682         -  switch (ps_parsing) {
         2111  +  if (parser == NULL)
         2112  +    return XML_STATUS_ERROR;
         2113  +  switch (parser->m_parsingStatus.parsing) {
  1683   2114     case XML_SUSPENDED:
  1684   2115       if (resumable) {
  1685         -      errorCode = XML_ERROR_SUSPENDED;
         2116  +      parser->m_errorCode = XML_ERROR_SUSPENDED;
  1686   2117         return XML_STATUS_ERROR;
  1687   2118       }
  1688         -    ps_parsing = XML_FINISHED;
         2119  +    parser->m_parsingStatus.parsing = XML_FINISHED;
  1689   2120       break;
  1690   2121     case XML_FINISHED:
  1691         -    errorCode = XML_ERROR_FINISHED;
         2122  +    parser->m_errorCode = XML_ERROR_FINISHED;
  1692   2123       return XML_STATUS_ERROR;
  1693   2124     default:
  1694   2125       if (resumable) {
  1695   2126   #ifdef XML_DTD
  1696         -      if (isParamEntity) {
  1697         -        errorCode = XML_ERROR_SUSPEND_PE;
         2127  +      if (parser->m_isParamEntity) {
         2128  +        parser->m_errorCode = XML_ERROR_SUSPEND_PE;
  1698   2129           return XML_STATUS_ERROR;
  1699   2130         }
  1700   2131   #endif
  1701         -      ps_parsing = XML_SUSPENDED;
         2132  +      parser->m_parsingStatus.parsing = XML_SUSPENDED;
  1702   2133       }
  1703   2134       else
  1704         -      ps_parsing = XML_FINISHED;
         2135  +      parser->m_parsingStatus.parsing = XML_FINISHED;
  1705   2136     }
  1706   2137     return XML_STATUS_OK;
  1707   2138   }
  1708   2139   
  1709   2140   enum XML_Status XMLCALL
  1710   2141   XML_ResumeParser(XML_Parser parser)
  1711   2142   {
  1712   2143     enum XML_Status result = XML_STATUS_OK;
  1713   2144   
  1714         -  if (ps_parsing != XML_SUSPENDED) {
  1715         -    errorCode = XML_ERROR_NOT_SUSPENDED;
         2145  +  if (parser == NULL)
         2146  +    return XML_STATUS_ERROR;
         2147  +  if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
         2148  +    parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
  1716   2149       return XML_STATUS_ERROR;
  1717   2150     }
  1718         -  ps_parsing = XML_PARSING;
         2151  +  parser->m_parsingStatus.parsing = XML_PARSING;
  1719   2152   
  1720         -  errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
         2153  +  parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
  1721   2154   
  1722         -  if (errorCode != XML_ERROR_NONE) {
  1723         -    eventEndPtr = eventPtr;
  1724         -    processor = errorProcessor;
         2155  +  if (parser->m_errorCode != XML_ERROR_NONE) {
         2156  +    parser->m_eventEndPtr = parser->m_eventPtr;
         2157  +    parser->m_processor = errorProcessor;
  1725   2158       return XML_STATUS_ERROR;
  1726   2159     }
  1727   2160     else {
  1728         -    switch (ps_parsing) {
         2161  +    switch (parser->m_parsingStatus.parsing) {
  1729   2162       case XML_SUSPENDED:
  1730   2163         result = XML_STATUS_SUSPENDED;
  1731   2164         break;
  1732         -    case XML_INITIALIZED: 
         2165  +    case XML_INITIALIZED:
  1733   2166       case XML_PARSING:
  1734         -      if (ps_finalBuffer) {
  1735         -        ps_parsing = XML_FINISHED;
         2167  +      if (parser->m_parsingStatus.finalBuffer) {
         2168  +        parser->m_parsingStatus.parsing = XML_FINISHED;
  1736   2169           return result;
  1737   2170         }
  1738   2171       default: ;
  1739   2172       }
  1740   2173     }
  1741   2174   
  1742         -  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
  1743         -  positionPtr = bufferPtr;
         2175  +  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
         2176  +  parser->m_positionPtr = parser->m_bufferPtr;
  1744   2177     return result;
  1745   2178   }
  1746   2179   
  1747   2180   void XMLCALL
  1748   2181   XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
  1749   2182   {
         2183  +  if (parser == NULL)
         2184  +    return;
  1750   2185     assert(status != NULL);
  1751   2186     *status = parser->m_parsingStatus;
  1752   2187   }
  1753   2188   
  1754   2189   enum XML_Error XMLCALL
  1755   2190   XML_GetErrorCode(XML_Parser parser)
  1756   2191   {
  1757         -  return errorCode;
         2192  +  if (parser == NULL)
         2193  +    return XML_ERROR_INVALID_ARGUMENT;
         2194  +  return parser->m_errorCode;
  1758   2195   }
  1759   2196   
  1760   2197   XML_Index XMLCALL
  1761   2198   XML_GetCurrentByteIndex(XML_Parser parser)
  1762   2199   {
  1763         -  if (eventPtr)
  1764         -    return parseEndByteIndex - (parseEndPtr - eventPtr);
         2200  +  if (parser == NULL)
         2201  +    return -1;
         2202  +  if (parser->m_eventPtr)
         2203  +    return (XML_Index)(parser->m_parseEndByteIndex - (parser->m_parseEndPtr - parser->m_eventPtr));
  1765   2204     return -1;
  1766   2205   }
  1767   2206   
  1768   2207   int XMLCALL
  1769   2208   XML_GetCurrentByteCount(XML_Parser parser)
  1770   2209   {
  1771         -  if (eventEndPtr && eventPtr)
  1772         -    return (int)(eventEndPtr - eventPtr);
         2210  +  if (parser == NULL)
         2211  +    return 0;
         2212  +  if (parser->m_eventEndPtr && parser->m_eventPtr)
         2213  +    return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
  1773   2214     return 0;
  1774   2215   }
  1775   2216   
  1776   2217   const char * XMLCALL
  1777   2218   XML_GetInputContext(XML_Parser parser, int *offset, int *size)
  1778   2219   {
  1779   2220   #ifdef XML_CONTEXT_BYTES
  1780         -  if (eventPtr && buffer) {
  1781         -    *offset = (int)(eventPtr - buffer);
  1782         -    *size   = (int)(bufferEnd - buffer);
  1783         -    return buffer;
         2221  +  if (parser == NULL)
         2222  +    return NULL;
         2223  +  if (parser->m_eventPtr && parser->m_buffer) {
         2224  +    if (offset != NULL)
         2225  +      *offset = (int)(parser->m_eventPtr - parser->m_buffer);
         2226  +    if (size != NULL)
         2227  +      *size   = (int)(parser->m_bufferEnd - parser->m_buffer);
         2228  +    return parser->m_buffer;
  1784   2229     }
         2230  +#else
         2231  +  (void)parser;
         2232  +  (void)offset;
         2233  +  (void)size;
  1785   2234   #endif /* defined XML_CONTEXT_BYTES */
  1786   2235     return (char *) 0;
  1787   2236   }
  1788   2237   
  1789   2238   XML_Size XMLCALL
  1790   2239   XML_GetCurrentLineNumber(XML_Parser parser)
  1791   2240   {
  1792         -  if (eventPtr && eventPtr >= positionPtr) {
  1793         -    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
  1794         -    positionPtr = eventPtr;
         2241  +  if (parser == NULL)
         2242  +    return 0;
         2243  +  if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
         2244  +    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position);
         2245  +    parser->m_positionPtr = parser->m_eventPtr;
  1795   2246     }
  1796         -  return position.lineNumber + 1;
         2247  +  return parser->m_position.lineNumber + 1;
  1797   2248   }
  1798   2249   
  1799   2250   XML_Size XMLCALL
  1800   2251   XML_GetCurrentColumnNumber(XML_Parser parser)
  1801   2252   {
  1802         -  if (eventPtr && eventPtr >= positionPtr) {
  1803         -    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
  1804         -    positionPtr = eventPtr;
         2253  +  if (parser == NULL)
         2254  +    return 0;
         2255  +  if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
         2256  +    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position);
         2257  +    parser->m_positionPtr = parser->m_eventPtr;
  1805   2258     }
  1806         -  return position.columnNumber;
         2259  +  return parser->m_position.columnNumber;
  1807   2260   }
  1808   2261   
  1809   2262   void XMLCALL
  1810   2263   XML_FreeContentModel(XML_Parser parser, XML_Content *model)
  1811   2264   {
  1812         -  FREE(model);
         2265  +  if (parser != NULL)
         2266  +    FREE(parser, model);
  1813   2267   }
  1814   2268   
  1815   2269   void * XMLCALL
  1816   2270   XML_MemMalloc(XML_Parser parser, size_t size)
  1817   2271   {
  1818         -  return MALLOC(size);
         2272  +  if (parser == NULL)
         2273  +    return NULL;
         2274  +  return MALLOC(parser, size);
  1819   2275   }
  1820   2276   
  1821   2277   void * XMLCALL
  1822   2278   XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
  1823   2279   {
  1824         -  return REALLOC(ptr, size);
         2280  +  if (parser == NULL)
         2281  +    return NULL;
         2282  +  return REALLOC(parser, ptr, size);
  1825   2283   }
  1826   2284   
  1827   2285   void XMLCALL
  1828   2286   XML_MemFree(XML_Parser parser, void *ptr)
  1829   2287   {
  1830         -  FREE(ptr);
         2288  +  if (parser != NULL)
         2289  +    FREE(parser, ptr);
  1831   2290   }
  1832   2291   
  1833   2292   void XMLCALL
  1834   2293   XML_DefaultCurrent(XML_Parser parser)
  1835   2294   {
  1836         -  if (defaultHandler) {
  1837         -    if (openInternalEntities)
         2295  +  if (parser == NULL)
         2296  +    return;
         2297  +  if (parser->m_defaultHandler) {
         2298  +    if (parser->m_openInternalEntities)
  1838   2299         reportDefault(parser,
  1839         -                    internalEncoding,
  1840         -                    openInternalEntities->internalEventPtr,
  1841         -                    openInternalEntities->internalEventEndPtr);
         2300  +                    parser->m_internalEncoding,
         2301  +                    parser->m_openInternalEntities->internalEventPtr,
         2302  +                    parser->m_openInternalEntities->internalEventEndPtr);
  1842   2303       else
  1843         -      reportDefault(parser, encoding, eventPtr, eventEndPtr);
         2304  +      reportDefault(parser, parser->m_encoding, parser->m_eventPtr, parser->m_eventEndPtr);
  1844   2305     }
  1845   2306   }
  1846   2307   
  1847   2308   const XML_LChar * XMLCALL
  1848   2309   XML_ErrorString(enum XML_Error code)
  1849   2310   {
  1850         -  static const XML_LChar* const message[] = {
  1851         -    0,
  1852         -    XML_L("out of memory"),
  1853         -    XML_L("syntax error"),
  1854         -    XML_L("no element found"),
  1855         -    XML_L("not well-formed (invalid token)"),
  1856         -    XML_L("unclosed token"),
  1857         -    XML_L("partial character"),
  1858         -    XML_L("mismatched tag"),
  1859         -    XML_L("duplicate attribute"),
  1860         -    XML_L("junk after document element"),
  1861         -    XML_L("illegal parameter entity reference"),
  1862         -    XML_L("undefined entity"),
  1863         -    XML_L("recursive entity reference"),
  1864         -    XML_L("asynchronous entity"),
  1865         -    XML_L("reference to invalid character number"),
  1866         -    XML_L("reference to binary entity"),
  1867         -    XML_L("reference to external entity in attribute"),
  1868         -    XML_L("XML or text declaration not at start of entity"),
  1869         -    XML_L("unknown encoding"),
  1870         -    XML_L("encoding specified in XML declaration is incorrect"),
  1871         -    XML_L("unclosed CDATA section"),
  1872         -    XML_L("error in processing external entity reference"),
  1873         -    XML_L("document is not standalone"),
  1874         -    XML_L("unexpected parser state - please send a bug report"),
  1875         -    XML_L("entity declared in parameter entity"),
  1876         -    XML_L("requested feature requires XML_DTD support in Expat"),
  1877         -    XML_L("cannot change setting once parsing has begun"),
  1878         -    XML_L("unbound prefix"),
  1879         -    XML_L("must not undeclare prefix"),
  1880         -    XML_L("incomplete markup in parameter entity"),
  1881         -    XML_L("XML declaration not well-formed"),
  1882         -    XML_L("text declaration not well-formed"),
  1883         -    XML_L("illegal character(s) in public id"),
  1884         -    XML_L("parser suspended"),
  1885         -    XML_L("parser not suspended"),
  1886         -    XML_L("parsing aborted"),
  1887         -    XML_L("parsing finished"),
  1888         -    XML_L("cannot suspend in external parameter entity"),
  1889         -    XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
  1890         -    XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
  1891         -    XML_L("prefix must not be bound to one of the reserved namespace names")
  1892         -  };
  1893         -  if (code > 0 && code < sizeof(message)/sizeof(message[0]))
  1894         -    return message[code];
         2311  +  switch (code) {
         2312  +  case XML_ERROR_NONE:
         2313  +    return NULL;
         2314  +  case XML_ERROR_NO_MEMORY:
         2315  +    return XML_L("out of memory");
         2316  +  case XML_ERROR_SYNTAX:
         2317  +    return XML_L("syntax error");
         2318  +  case XML_ERROR_NO_ELEMENTS:
         2319  +    return XML_L("no element found");
         2320  +  case XML_ERROR_INVALID_TOKEN:
         2321  +    return XML_L("not well-formed (invalid token)");
         2322  +  case XML_ERROR_UNCLOSED_TOKEN:
         2323  +    return XML_L("unclosed token");
         2324  +  case XML_ERROR_PARTIAL_CHAR:
         2325  +    return XML_L("partial character");
         2326  +  case XML_ERROR_TAG_MISMATCH:
         2327  +    return XML_L("mismatched tag");
         2328  +  case XML_ERROR_DUPLICATE_ATTRIBUTE:
         2329  +    return XML_L("duplicate attribute");
         2330  +  case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
         2331  +    return XML_L("junk after document element");
         2332  +  case XML_ERROR_PARAM_ENTITY_REF:
         2333  +    return XML_L("illegal parameter entity reference");
         2334  +  case XML_ERROR_UNDEFINED_ENTITY:
         2335  +    return XML_L("undefined entity");
         2336  +  case XML_ERROR_RECURSIVE_ENTITY_REF:
         2337  +    return XML_L("recursive entity reference");
         2338  +  case XML_ERROR_ASYNC_ENTITY:
         2339  +    return XML_L("asynchronous entity");
         2340  +  case XML_ERROR_BAD_CHAR_REF:
         2341  +    return XML_L("reference to invalid character number");
         2342  +  case XML_ERROR_BINARY_ENTITY_REF:
         2343  +    return XML_L("reference to binary entity");
         2344  +  case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
         2345  +    return XML_L("reference to external entity in attribute");
         2346  +  case XML_ERROR_MISPLACED_XML_PI:
         2347  +    return XML_L("XML or text declaration not at start of entity");
         2348  +  case XML_ERROR_UNKNOWN_ENCODING:
         2349  +    return XML_L("unknown encoding");
         2350  +  case XML_ERROR_INCORRECT_ENCODING:
         2351  +    return XML_L("encoding specified in XML declaration is incorrect");
         2352  +  case XML_ERROR_UNCLOSED_CDATA_SECTION:
         2353  +    return XML_L("unclosed CDATA section");
         2354  +  case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
         2355  +    return XML_L("error in processing external entity reference");
         2356  +  case XML_ERROR_NOT_STANDALONE:
         2357  +    return XML_L("document is not standalone");
         2358  +  case XML_ERROR_UNEXPECTED_STATE:
         2359  +    return XML_L("unexpected parser state - please send a bug report");
         2360  +  case XML_ERROR_ENTITY_DECLARED_IN_PE:
         2361  +    return XML_L("entity declared in parameter entity");
         2362  +  case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
         2363  +    return XML_L("requested feature requires XML_DTD support in Expat");
         2364  +  case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
         2365  +    return XML_L("cannot change setting once parsing has begun");
         2366  +  /* Added in 1.95.7. */
         2367  +  case XML_ERROR_UNBOUND_PREFIX:
         2368  +    return XML_L("unbound prefix");
         2369  +  /* Added in 1.95.8. */
         2370  +  case XML_ERROR_UNDECLARING_PREFIX:
         2371  +    return XML_L("must not undeclare prefix");
         2372  +  case XML_ERROR_INCOMPLETE_PE:
         2373  +    return XML_L("incomplete markup in parameter entity");
         2374  +  case XML_ERROR_XML_DECL:
         2375  +    return XML_L("XML declaration not well-formed");
         2376  +  case XML_ERROR_TEXT_DECL:
         2377  +    return XML_L("text declaration not well-formed");
         2378  +  case XML_ERROR_PUBLICID:
         2379  +    return XML_L("illegal character(s) in public id");
         2380  +  case XML_ERROR_SUSPENDED:
         2381  +    return XML_L("parser suspended");
         2382  +  case XML_ERROR_NOT_SUSPENDED:
         2383  +    return XML_L("parser not suspended");
         2384  +  case XML_ERROR_ABORTED:
         2385  +    return XML_L("parsing aborted");
         2386  +  case XML_ERROR_FINISHED:
         2387  +    return XML_L("parsing finished");
         2388  +  case XML_ERROR_SUSPEND_PE:
         2389  +    return XML_L("cannot suspend in external parameter entity");
         2390  +  /* Added in 2.0.0. */
         2391  +  case XML_ERROR_RESERVED_PREFIX_XML:
         2392  +    return XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name");
         2393  +  case XML_ERROR_RESERVED_PREFIX_XMLNS:
         2394  +    return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
         2395  +  case XML_ERROR_RESERVED_NAMESPACE_URI:
         2396  +    return XML_L("prefix must not be bound to one of the reserved namespace names");
         2397  +  /* Added in 2.2.5. */
         2398  +  case XML_ERROR_INVALID_ARGUMENT:  /* Constant added in 2.2.1, already */
         2399  +    return XML_L("invalid argument");
         2400  +  }
  1895   2401     return NULL;
  1896   2402   }
  1897   2403   
  1898   2404   const XML_LChar * XMLCALL
  1899   2405   XML_ExpatVersion(void) {
  1900   2406   
  1901   2407     /* V1 is used to string-ize the version number. However, it would
................................................................................
  1952   2458       {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
  1953   2459   #endif
  1954   2460   #ifdef XML_NS
  1955   2461       {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
  1956   2462   #endif
  1957   2463   #ifdef XML_LARGE_SIZE
  1958   2464       {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
  1959         -#endif    
         2465  +#endif
         2466  +#ifdef XML_ATTR_INFO
         2467  +    {XML_FEATURE_ATTR_INFO,        XML_L("XML_ATTR_INFO"), 0},
         2468  +#endif
  1960   2469       {XML_FEATURE_END,              NULL, 0}
  1961   2470     };
  1962   2471   
  1963   2472     return features;
  1964   2473   }
  1965   2474   
  1966   2475   /* Initially tag->rawName always points into the parse buffer;
................................................................................
  1967   2476      for those TAG instances opened while the current parse buffer was
  1968   2477      processed, and not yet closed, we need to store tag->rawName in a more
  1969   2478      permanent location, since the parse buffer is about to be discarded.
  1970   2479   */
  1971   2480   static XML_Bool
  1972   2481   storeRawNames(XML_Parser parser)
  1973   2482   {
  1974         -  TAG *tag = tagStack;
         2483  +  TAG *tag = parser->m_tagStack;
  1975   2484     while (tag) {
  1976   2485       int bufSize;
  1977   2486       int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
  1978   2487       char *rawNameBuf = tag->buf + nameLen;
  1979         -    /* Stop if already stored.  Since tagStack is a stack, we can stop
         2488  +    /* Stop if already stored.  Since m_tagStack is a stack, we can stop
  1980   2489          at the first entry that has already been copied; everything
  1981   2490          below it in the stack is already been accounted for in a
  1982   2491          previous call to this function.
  1983   2492       */
  1984   2493       if (tag->rawName == rawNameBuf)
  1985   2494         break;
  1986   2495       /* For re-use purposes we need to ensure that the
  1987   2496          size of tag->buf is a multiple of sizeof(XML_Char).
  1988   2497       */
  1989   2498       bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
  1990   2499       if (bufSize > tag->bufEnd - tag->buf) {
  1991         -      char *temp = (char *)REALLOC(tag->buf, bufSize);
         2500  +      char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
  1992   2501         if (temp == NULL)
  1993   2502           return XML_FALSE;
  1994   2503         /* if tag->name.str points to tag->buf (only when namespace
  1995   2504            processing is off) then we have to update it
  1996   2505         */
  1997   2506         if (tag->name.str == (XML_Char *)tag->buf)
  1998   2507           tag->name.str = (XML_Char *)temp;
................................................................................
  2015   2524   
  2016   2525   static enum XML_Error PTRCALL
  2017   2526   contentProcessor(XML_Parser parser,
  2018   2527                    const char *start,
  2019   2528                    const char *end,
  2020   2529                    const char **endPtr)
  2021   2530   {
  2022         -  enum XML_Error result = doContent(parser, 0, encoding, start, end, 
  2023         -                                    endPtr, (XML_Bool)!ps_finalBuffer);
         2531  +  enum XML_Error result = doContent(parser, 0, parser->m_encoding, start, end,
         2532  +                                    endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  2024   2533     if (result == XML_ERROR_NONE) {
  2025   2534       if (!storeRawNames(parser))
  2026   2535         return XML_ERROR_NO_MEMORY;
  2027   2536     }
  2028   2537     return result;
  2029   2538   }
  2030   2539   
................................................................................
  2033   2542                               const char *start,
  2034   2543                               const char *end,
  2035   2544                               const char **endPtr)
  2036   2545   {
  2037   2546     enum XML_Error result = initializeEncoding(parser);
  2038   2547     if (result != XML_ERROR_NONE)
  2039   2548       return result;
  2040         -  processor = externalEntityInitProcessor2;
         2549  +  parser->m_processor = externalEntityInitProcessor2;
  2041   2550     return externalEntityInitProcessor2(parser, start, end, endPtr);
  2042   2551   }
  2043   2552   
  2044   2553   static enum XML_Error PTRCALL
  2045   2554   externalEntityInitProcessor2(XML_Parser parser,
  2046   2555                                const char *start,
  2047   2556                                const char *end,
  2048   2557                                const char **endPtr)
  2049   2558   {
  2050   2559     const char *next = start; /* XmlContentTok doesn't always set the last arg */
  2051         -  int tok = XmlContentTok(encoding, start, end, &next);
         2560  +  int tok = XmlContentTok(parser->m_encoding, start, end, &next);
  2052   2561     switch (tok) {
  2053   2562     case XML_TOK_BOM:
  2054   2563       /* If we are at the end of the buffer, this would cause the next stage,
  2055   2564          i.e. externalEntityInitProcessor3, to pass control directly to
  2056   2565          doContent (by detecting XML_TOK_NONE) without processing any xml text
  2057   2566          declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
  2058   2567       */
  2059         -    if (next == end && !ps_finalBuffer) {
         2568  +    if (next == end && !parser->m_parsingStatus.finalBuffer) {
  2060   2569         *endPtr = next;
  2061   2570         return XML_ERROR_NONE;
  2062   2571       }
  2063   2572       start = next;
  2064   2573       break;
  2065   2574     case XML_TOK_PARTIAL:
  2066         -    if (!ps_finalBuffer) {
         2575  +    if (!parser->m_parsingStatus.finalBuffer) {
  2067   2576         *endPtr = start;
  2068   2577         return XML_ERROR_NONE;
  2069   2578       }
  2070         -    eventPtr = start;
         2579  +    parser->m_eventPtr = start;
  2071   2580       return XML_ERROR_UNCLOSED_TOKEN;
  2072   2581     case XML_TOK_PARTIAL_CHAR:
  2073         -    if (!ps_finalBuffer) {
         2582  +    if (!parser->m_parsingStatus.finalBuffer) {
  2074   2583         *endPtr = start;
  2075   2584         return XML_ERROR_NONE;
  2076   2585       }
  2077         -    eventPtr = start;
         2586  +    parser->m_eventPtr = start;
  2078   2587       return XML_ERROR_PARTIAL_CHAR;
  2079   2588     }
  2080         -  processor = externalEntityInitProcessor3;
         2589  +  parser->m_processor = externalEntityInitProcessor3;
  2081   2590     return externalEntityInitProcessor3(parser, start, end, endPtr);
  2082   2591   }
  2083   2592   
  2084   2593   static enum XML_Error PTRCALL
  2085   2594   externalEntityInitProcessor3(XML_Parser parser,
  2086   2595                                const char *start,
  2087   2596                                const char *end,
  2088   2597                                const char **endPtr)
  2089   2598   {
  2090   2599     int tok;
  2091   2600     const char *next = start; /* XmlContentTok doesn't always set the last arg */
  2092         -  eventPtr = start;
  2093         -  tok = XmlContentTok(encoding, start, end, &next);
  2094         -  eventEndPtr = next;
         2601  +  parser->m_eventPtr = start;
         2602  +  tok = XmlContentTok(parser->m_encoding, start, end, &next);
         2603  +  parser->m_eventEndPtr = next;
  2095   2604   
  2096   2605     switch (tok) {
  2097   2606     case XML_TOK_XML_DECL:
  2098   2607       {
  2099   2608         enum XML_Error result;
  2100   2609         result = processXmlDecl(parser, 1, start, next);
  2101   2610         if (result != XML_ERROR_NONE)
  2102   2611           return result;
  2103         -      switch (ps_parsing) {
  2104         -      case XML_SUSPENDED: 
         2612  +      switch (parser->m_parsingStatus.parsing) {
         2613  +      case XML_SUSPENDED:
  2105   2614           *endPtr = next;
  2106   2615           return XML_ERROR_NONE;
  2107   2616         case XML_FINISHED:
  2108   2617           return XML_ERROR_ABORTED;
  2109   2618         default:
  2110   2619           start = next;
  2111   2620         }
  2112   2621       }
  2113   2622       break;
  2114   2623     case XML_TOK_PARTIAL:
  2115         -    if (!ps_finalBuffer) {
         2624  +    if (!parser->m_parsingStatus.finalBuffer) {
  2116   2625         *endPtr = start;
  2117   2626         return XML_ERROR_NONE;
  2118   2627       }
  2119   2628       return XML_ERROR_UNCLOSED_TOKEN;
  2120   2629     case XML_TOK_PARTIAL_CHAR:
  2121         -    if (!ps_finalBuffer) {
         2630  +    if (!parser->m_parsingStatus.finalBuffer) {
  2122   2631         *endPtr = start;
  2123   2632         return XML_ERROR_NONE;
  2124   2633       }
  2125   2634       return XML_ERROR_PARTIAL_CHAR;
  2126   2635     }
  2127         -  processor = externalEntityContentProcessor;
  2128         -  tagLevel = 1;
         2636  +  parser->m_processor = externalEntityContentProcessor;
         2637  +  parser->m_tagLevel = 1;
  2129   2638     return externalEntityContentProcessor(parser, start, end, endPtr);
  2130   2639   }
  2131   2640   
  2132   2641   static enum XML_Error PTRCALL
  2133   2642   externalEntityContentProcessor(XML_Parser parser,
  2134   2643                                  const char *start,
  2135   2644                                  const char *end,
  2136   2645                                  const char **endPtr)
  2137   2646   {
  2138         -  enum XML_Error result = doContent(parser, 1, encoding, start, end, 
  2139         -                                    endPtr, (XML_Bool)!ps_finalBuffer);
         2647  +  enum XML_Error result = doContent(parser, 1, parser->m_encoding, start, end,
         2648  +                                    endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  2140   2649     if (result == XML_ERROR_NONE) {
  2141   2650       if (!storeRawNames(parser))
  2142   2651         return XML_ERROR_NO_MEMORY;
  2143   2652     }
  2144   2653     return result;
  2145   2654   }
  2146   2655   
................................................................................
  2150   2659             const ENCODING *enc,
  2151   2660             const char *s,
  2152   2661             const char *end,
  2153   2662             const char **nextPtr,
  2154   2663             XML_Bool haveMore)
  2155   2664   {
  2156   2665     /* save one level of indirection */
  2157         -  DTD * const dtd = _dtd;  
         2666  +  DTD * const dtd = parser->m_dtd;
  2158   2667   
  2159   2668     const char **eventPP;
  2160   2669     const char **eventEndPP;
  2161         -  if (enc == encoding) {
  2162         -    eventPP = &eventPtr;
  2163         -    eventEndPP = &eventEndPtr;
         2670  +  if (enc == parser->m_encoding) {
         2671  +    eventPP = &parser->m_eventPtr;
         2672  +    eventEndPP = &parser->m_eventEndPtr;
  2164   2673     }
  2165   2674     else {
  2166         -    eventPP = &(openInternalEntities->internalEventPtr);
  2167         -    eventEndPP = &(openInternalEntities->internalEventEndPtr);
         2675  +    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
         2676  +    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
  2168   2677     }
  2169   2678     *eventPP = s;
  2170   2679   
  2171   2680     for (;;) {
  2172   2681       const char *next = s; /* XmlContentTok doesn't always set the last arg */
  2173   2682       int tok = XmlContentTok(enc, s, end, &next);
  2174   2683       *eventEndPP = next;
................................................................................
  2175   2684       switch (tok) {
  2176   2685       case XML_TOK_TRAILING_CR:
  2177   2686         if (haveMore) {
  2178   2687           *nextPtr = s;
  2179   2688           return XML_ERROR_NONE;
  2180   2689         }
  2181   2690         *eventEndPP = end;
  2182         -      if (characterDataHandler) {
         2691  +      if (parser->m_characterDataHandler) {
  2183   2692           XML_Char c = 0xA;
  2184         -        characterDataHandler(handlerArg, &c, 1);
         2693  +        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
  2185   2694         }
  2186         -      else if (defaultHandler)
         2695  +      else if (parser->m_defaultHandler)
  2187   2696           reportDefault(parser, enc, s, end);
  2188         -      /* We are at the end of the final buffer, should we check for 
  2189         -         XML_SUSPENDED, XML_FINISHED? 
         2697  +      /* We are at the end of the final buffer, should we check for
         2698  +         XML_SUSPENDED, XML_FINISHED?
  2190   2699         */
  2191   2700         if (startTagLevel == 0)
  2192   2701           return XML_ERROR_NO_ELEMENTS;
  2193         -      if (tagLevel != startTagLevel)
         2702  +      if (parser->m_tagLevel != startTagLevel)
  2194   2703           return XML_ERROR_ASYNC_ENTITY;
  2195   2704         *nextPtr = end;
  2196   2705         return XML_ERROR_NONE;
  2197   2706       case XML_TOK_NONE:
  2198   2707         if (haveMore) {
  2199   2708           *nextPtr = s;
  2200   2709           return XML_ERROR_NONE;
  2201   2710         }
  2202   2711         if (startTagLevel > 0) {
  2203         -        if (tagLevel != startTagLevel)
         2712  +        if (parser->m_tagLevel != startTagLevel)
  2204   2713             return XML_ERROR_ASYNC_ENTITY;
  2205   2714           *nextPtr = s;
  2206   2715           return XML_ERROR_NONE;
  2207   2716         }
  2208   2717         return XML_ERROR_NO_ELEMENTS;
  2209   2718       case XML_TOK_INVALID:
  2210   2719         *eventPP = next;
................................................................................
  2225   2734         {
  2226   2735           const XML_Char *name;
  2227   2736           ENTITY *entity;
  2228   2737           XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
  2229   2738                                                 s + enc->minBytesPerChar,
  2230   2739                                                 next - enc->minBytesPerChar);
  2231   2740           if (ch) {
  2232         -          if (characterDataHandler)
  2233         -            characterDataHandler(handlerArg, &ch, 1);
  2234         -          else if (defaultHandler)
         2741  +          if (parser->m_characterDataHandler)
         2742  +            parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
         2743  +          else if (parser->m_defaultHandler)
  2235   2744               reportDefault(parser, enc, s, next);
  2236   2745             break;
  2237   2746           }
  2238   2747           name = poolStoreString(&dtd->pool, enc,
  2239   2748                                   s + enc->minBytesPerChar,
  2240   2749                                   next - enc->minBytesPerChar);
  2241   2750           if (!name)
  2242   2751             return XML_ERROR_NO_MEMORY;
  2243         -        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
         2752  +        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
  2244   2753           poolDiscard(&dtd->pool);
  2245   2754           /* First, determine if a check for an existing declaration is needed;
  2246   2755              if yes, check that the entity exists, and that it is internal,
  2247   2756              otherwise call the skipped entity or default handler.
  2248   2757           */
  2249   2758           if (!dtd->hasParamEntityRefs || dtd->standalone) {
  2250   2759             if (!entity)
  2251   2760               return XML_ERROR_UNDEFINED_ENTITY;
  2252   2761             else if (!entity->is_internal)
  2253   2762               return XML_ERROR_ENTITY_DECLARED_IN_PE;
  2254   2763           }
  2255   2764           else if (!entity) {
  2256         -          if (skippedEntityHandler)
  2257         -            skippedEntityHandler(handlerArg, name, 0);
  2258         -          else if (defaultHandler)
         2765  +          if (parser->m_skippedEntityHandler)
         2766  +            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
         2767  +          else if (parser->m_defaultHandler)
  2259   2768               reportDefault(parser, enc, s, next);
  2260   2769             break;
  2261   2770           }
  2262   2771           if (entity->open)
  2263   2772             return XML_ERROR_RECURSIVE_ENTITY_REF;
  2264   2773           if (entity->notation)
  2265   2774             return XML_ERROR_BINARY_ENTITY_REF;
  2266   2775           if (entity->textPtr) {
  2267   2776             enum XML_Error result;
  2268         -          if (!defaultExpandInternalEntities) {
  2269         -            if (skippedEntityHandler)
  2270         -              skippedEntityHandler(handlerArg, entity->name, 0);
  2271         -            else if (defaultHandler)
         2777  +          if (!parser->m_defaultExpandInternalEntities) {
         2778  +            if (parser->m_skippedEntityHandler)
         2779  +              parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 0);
         2780  +            else if (parser->m_defaultHandler)
  2272   2781                 reportDefault(parser, enc, s, next);
  2273   2782               break;
  2274   2783             }
  2275   2784             result = processInternalEntity(parser, entity, XML_FALSE);
  2276   2785             if (result != XML_ERROR_NONE)
  2277   2786               return result;
  2278   2787           }
  2279         -        else if (externalEntityRefHandler) {
         2788  +        else if (parser->m_externalEntityRefHandler) {
  2280   2789             const XML_Char *context;
  2281   2790             entity->open = XML_TRUE;
  2282   2791             context = getContext(parser);
  2283   2792             entity->open = XML_FALSE;
  2284   2793             if (!context)
  2285   2794               return XML_ERROR_NO_MEMORY;
  2286         -          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
         2795  +          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
  2287   2796                                           context,
  2288   2797                                           entity->base,
  2289   2798                                           entity->systemId,
  2290   2799                                           entity->publicId))
  2291   2800               return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  2292         -          poolDiscard(&tempPool);
         2801  +          poolDiscard(&parser->m_tempPool);
  2293   2802           }
  2294         -        else if (defaultHandler)
         2803  +        else if (parser->m_defaultHandler)
  2295   2804             reportDefault(parser, enc, s, next);
  2296   2805           break;
  2297   2806         }
  2298   2807       case XML_TOK_START_TAG_NO_ATTS:
  2299   2808         /* fall through */
  2300   2809       case XML_TOK_START_TAG_WITH_ATTS:
  2301   2810         {
  2302   2811           TAG *tag;
  2303   2812           enum XML_Error result;
  2304   2813           XML_Char *toPtr;
  2305         -        if (freeTagList) {
  2306         -          tag = freeTagList;
  2307         -          freeTagList = freeTagList->parent;
         2814  +        if (parser->m_freeTagList) {
         2815  +          tag = parser->m_freeTagList;
         2816  +          parser->m_freeTagList = parser->m_freeTagList->parent;
  2308   2817           }
  2309   2818           else {
  2310         -          tag = (TAG *)MALLOC(sizeof(TAG));
         2819  +          tag = (TAG *)MALLOC(parser, sizeof(TAG));
  2311   2820             if (!tag)
  2312   2821               return XML_ERROR_NO_MEMORY;
  2313         -          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
         2822  +          tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
  2314   2823             if (!tag->buf) {
  2315         -            FREE(tag);
         2824  +            FREE(parser, tag);
  2316   2825               return XML_ERROR_NO_MEMORY;
  2317   2826             }
  2318   2827             tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
  2319   2828           }
  2320   2829           tag->bindings = NULL;
  2321         -        tag->parent = tagStack;
  2322         -        tagStack = tag;
         2830  +        tag->parent = parser->m_tagStack;
         2831  +        parser->m_tagStack = tag;
  2323   2832           tag->name.localPart = NULL;
  2324   2833           tag->name.prefix = NULL;
  2325   2834           tag->rawName = s + enc->minBytesPerChar;
  2326   2835           tag->rawNameLength = XmlNameLength(enc, tag->rawName);
  2327         -        ++tagLevel;
         2836  +        ++parser->m_tagLevel;
  2328   2837           {
  2329   2838             const char *rawNameEnd = tag->rawName + tag->rawNameLength;
  2330   2839             const char *fromPtr = tag->rawName;
  2331   2840             toPtr = (XML_Char *)tag->buf;
  2332   2841             for (;;) {
  2333   2842               int bufSize;
  2334   2843               int convLen;
  2335         -            XmlConvert(enc,
         2844  +            const enum XML_Convert_Result convert_res = XmlConvert(enc,
  2336   2845                          &fromPtr, rawNameEnd,
  2337   2846                          (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
  2338   2847               convLen = (int)(toPtr - (XML_Char *)tag->buf);
  2339         -            if (fromPtr == rawNameEnd) {
         2848  +            if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
  2340   2849                 tag->name.strLen = convLen;
  2341   2850                 break;
  2342   2851               }
  2343   2852               bufSize = (int)(tag->bufEnd - tag->buf) << 1;
  2344   2853               {
  2345         -              char *temp = (char *)REALLOC(tag->buf, bufSize);
         2854  +              char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
  2346   2855                 if (temp == NULL)
  2347   2856                   return XML_ERROR_NO_MEMORY;
  2348   2857                 tag->buf = temp;
  2349   2858                 tag->bufEnd = temp + bufSize;
  2350   2859                 toPtr = (XML_Char *)temp + convLen;
  2351   2860               }
  2352   2861             }
  2353   2862           }
  2354   2863           tag->name.str = (XML_Char *)tag->buf;
  2355   2864           *toPtr = XML_T('\0');
  2356   2865           result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
  2357   2866           if (result)
  2358   2867             return result;
  2359         -        if (startElementHandler)
  2360         -          startElementHandler(handlerArg, tag->name.str,
  2361         -                              (const XML_Char **)atts);
  2362         -        else if (defaultHandler)
         2868  +        if (parser->m_startElementHandler)
         2869  +          parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
         2870  +                              (const XML_Char **)parser->m_atts);
         2871  +        else if (parser->m_defaultHandler)
  2363   2872             reportDefault(parser, enc, s, next);
  2364         -        poolClear(&tempPool);
         2873  +        poolClear(&parser->m_tempPool);
  2365   2874           break;
  2366   2875         }
  2367   2876       case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
  2368   2877         /* fall through */
  2369   2878       case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
  2370   2879         {
  2371   2880           const char *rawName = s + enc->minBytesPerChar;
  2372   2881           enum XML_Error result;
  2373   2882           BINDING *bindings = NULL;
  2374   2883           XML_Bool noElmHandlers = XML_TRUE;
  2375   2884           TAG_NAME name;
  2376         -        name.str = poolStoreString(&tempPool, enc, rawName,
         2885  +        name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
  2377   2886                                      rawName + XmlNameLength(enc, rawName));
  2378   2887           if (!name.str)
  2379   2888             return XML_ERROR_NO_MEMORY;
  2380         -        poolFinish(&tempPool);
         2889  +        poolFinish(&parser->m_tempPool);
  2381   2890           result = storeAtts(parser, enc, s, &name, &bindings);
  2382         -        if (result)
         2891  +        if (result != XML_ERROR_NONE) {
         2892  +          freeBindings(parser, bindings);
  2383   2893             return result;
  2384         -        poolFinish(&tempPool);
  2385         -        if (startElementHandler) {
  2386         -          startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
         2894  +        }
         2895  +        poolFinish(&parser->m_tempPool);
         2896  +        if (parser->m_startElementHandler) {
         2897  +          parser->m_startElementHandler(parser->m_handlerArg, name.str, (const XML_Char **)parser->m_atts);
  2387   2898             noElmHandlers = XML_FALSE;
  2388   2899           }
  2389         -        if (endElementHandler) {
  2390         -          if (startElementHandler)
         2900  +        if (parser->m_endElementHandler) {
         2901  +          if (parser->m_startElementHandler)
  2391   2902               *eventPP = *eventEndPP;
  2392         -          endElementHandler(handlerArg, name.str);
         2903  +          parser->m_endElementHandler(parser->m_handlerArg, name.str);
  2393   2904             noElmHandlers = XML_FALSE;
  2394   2905           }
  2395         -        if (noElmHandlers && defaultHandler)
         2906  +        if (noElmHandlers && parser->m_defaultHandler)
  2396   2907             reportDefault(parser, enc, s, next);
  2397         -        poolClear(&tempPool);
  2398         -        while (bindings) {
  2399         -          BINDING *b = bindings;
  2400         -          if (endNamespaceDeclHandler)
  2401         -            endNamespaceDeclHandler(handlerArg, b->prefix->name);
  2402         -          bindings = bindings->nextTagBinding;
  2403         -          b->nextTagBinding = freeBindingList;
  2404         -          freeBindingList = b;
  2405         -          b->prefix->binding = b->prevPrefixBinding;
  2406         -        }
         2908  +        poolClear(&parser->m_tempPool);
         2909  +        freeBindings(parser, bindings);
  2407   2910         }
  2408         -      if (tagLevel == 0)
         2911  +      if ((parser->m_tagLevel == 0) &&
         2912  +          !((parser->m_parsingStatus.parsing == XML_FINISHED) || (parser->m_parsingStatus.parsing == XML_SUSPENDED))) {
  2409   2913           return epilogProcessor(parser, next, end, nextPtr);
         2914  +      }
  2410   2915         break;
  2411   2916       case XML_TOK_END_TAG:
  2412         -      if (tagLevel == startTagLevel)
         2917  +      if (parser->m_tagLevel == startTagLevel)
  2413   2918           return XML_ERROR_ASYNC_ENTITY;
  2414   2919         else {
  2415   2920           int len;
  2416   2921           const char *rawName;
  2417         -        TAG *tag = tagStack;
  2418         -        tagStack = tag->parent;
  2419         -        tag->parent = freeTagList;
  2420         -        freeTagList = tag;
         2922  +        TAG *tag = parser->m_tagStack;
         2923  +        parser->m_tagStack = tag->parent;
         2924  +        tag->parent = parser->m_freeTagList;
         2925  +        parser->m_freeTagList = tag;
  2421   2926           rawName = s + enc->minBytesPerChar*2;
  2422   2927           len = XmlNameLength(enc, rawName);
  2423   2928           if (len != tag->rawNameLength
  2424   2929               || memcmp(tag->rawName, rawName, len) != 0) {
  2425   2930             *eventPP = rawName;
  2426   2931             return XML_ERROR_TAG_MISMATCH;
  2427   2932           }
  2428         -        --tagLevel;
  2429         -        if (endElementHandler) {
         2933  +        --parser->m_tagLevel;
         2934  +        if (parser->m_endElementHandler) {
  2430   2935             const XML_Char *localPart;
  2431   2936             const XML_Char *prefix;
  2432   2937             XML_Char *uri;
  2433   2938             localPart = tag->name.localPart;
  2434         -          if (ns && localPart) {
         2939  +          if (parser->m_ns && localPart) {
  2435   2940               /* localPart and prefix may have been overwritten in
  2436   2941                  tag->name.str, since this points to the binding->uri
  2437   2942                  buffer which gets re-used; so we have to add them again
  2438   2943               */
  2439   2944               uri = (XML_Char *)tag->name.str + tag->name.uriLen;
  2440   2945               /* don't need to check for space - already done in storeAtts() */
  2441   2946               while (*localPart) *uri++ = *localPart++;
  2442   2947               prefix = (XML_Char *)tag->name.prefix;
  2443         -            if (ns_triplets && prefix) {
  2444         -              *uri++ = namespaceSeparator;
         2948  +            if (parser->m_ns_triplets && prefix) {
         2949  +              *uri++ = parser->m_namespaceSeparator;
  2445   2950                 while (*prefix) *uri++ = *prefix++;
  2446   2951                }
  2447   2952               *uri = XML_T('\0');
  2448   2953             }
  2449         -          endElementHandler(handlerArg, tag->name.str);
         2954  +          parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
  2450   2955           }
  2451         -        else if (defaultHandler)
         2956  +        else if (parser->m_defaultHandler)
  2452   2957             reportDefault(parser, enc, s, next);
  2453   2958           while (tag->bindings) {
  2454   2959             BINDING *b = tag->bindings;
  2455         -          if (endNamespaceDeclHandler)
  2456         -            endNamespaceDeclHandler(handlerArg, b->prefix->name);
         2960  +          if (parser->m_endNamespaceDeclHandler)
         2961  +            parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
  2457   2962             tag->bindings = tag->bindings->nextTagBinding;
  2458         -          b->nextTagBinding = freeBindingList;
  2459         -          freeBindingList = b;
         2963  +          b->nextTagBinding = parser->m_freeBindingList;
         2964  +          parser->m_freeBindingList = b;
  2460   2965             b->prefix->binding = b->prevPrefixBinding;
  2461   2966           }
  2462         -        if (tagLevel == 0)
         2967  +        if (parser->m_tagLevel == 0)
  2463   2968             return epilogProcessor(parser, next, end, nextPtr);
  2464   2969         }
  2465   2970         break;
  2466   2971       case XML_TOK_CHAR_REF:
  2467   2972         {
  2468   2973           int n = XmlCharRefNumber(enc, s);
  2469   2974           if (n < 0)
  2470   2975             return XML_ERROR_BAD_CHAR_REF;
  2471         -        if (characterDataHandler) {
         2976  +        if (parser->m_characterDataHandler) {
  2472   2977             XML_Char buf[XML_ENCODE_MAX];
  2473         -          characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
         2978  +          parser->m_characterDataHandler(parser->m_handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
  2474   2979           }
  2475         -        else if (defaultHandler)
         2980  +        else if (parser->m_defaultHandler)
  2476   2981             reportDefault(parser, enc, s, next);
  2477   2982         }
  2478   2983         break;
  2479   2984       case XML_TOK_XML_DECL:
  2480   2985         return XML_ERROR_MISPLACED_XML_PI;
  2481   2986       case XML_TOK_DATA_NEWLINE:
  2482         -      if (characterDataHandler) {
         2987  +      if (parser->m_characterDataHandler) {
  2483   2988           XML_Char c = 0xA;
  2484         -        characterDataHandler(handlerArg, &c, 1);
         2989  +        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
  2485   2990         }
  2486         -      else if (defaultHandler)
         2991  +      else if (parser->m_defaultHandler)
  2487   2992           reportDefault(parser, enc, s, next);
  2488   2993         break;
  2489   2994       case XML_TOK_CDATA_SECT_OPEN:
  2490   2995         {
  2491   2996           enum XML_Error result;
  2492         -        if (startCdataSectionHandler)
  2493         -          startCdataSectionHandler(handlerArg);
         2997  +        if (parser->m_startCdataSectionHandler)
         2998  +          parser->m_startCdataSectionHandler(parser->m_handlerArg);
  2494   2999   #if 0
  2495   3000           /* Suppose you doing a transformation on a document that involves
  2496   3001              changing only the character data.  You set up a defaultHandler
  2497   3002              and a characterDataHandler.  The defaultHandler simply copies
  2498   3003              characters through.  The characterDataHandler does the
  2499   3004              transformation and writes the characters out escaping them as
  2500   3005              necessary.  This case will fail to work if we leave out the
  2501   3006              following two lines (because & and < inside CDATA sections will
  2502   3007              be incorrectly escaped).
  2503   3008   
  2504   3009              However, now we have a start/endCdataSectionHandler, so it seems
  2505   3010              easier to let the user deal with this.
  2506   3011           */
  2507         -        else if (characterDataHandler)
  2508         -          characterDataHandler(handlerArg, dataBuf, 0);
         3012  +        else if (parser->m_characterDataHandler)
         3013  +          parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0);
  2509   3014   #endif
  2510         -        else if (defaultHandler)
         3015  +        else if (parser->m_defaultHandler)
  2511   3016             reportDefault(parser, enc, s, next);
  2512   3017           result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
  2513   3018           if (result != XML_ERROR_NONE)
  2514   3019             return result;
  2515   3020           else if (!next) {
  2516         -          processor = cdataSectionProcessor;
         3021  +          parser->m_processor = cdataSectionProcessor;
  2517   3022             return result;
  2518   3023           }
  2519   3024         }
  2520   3025         break;
  2521   3026       case XML_TOK_TRAILING_RSQB:
  2522   3027         if (haveMore) {
  2523   3028           *nextPtr = s;
  2524   3029           return XML_ERROR_NONE;
  2525   3030         }
  2526         -      if (characterDataHandler) {
         3031  +      if (parser->m_characterDataHandler) {
  2527   3032           if (MUST_CONVERT(enc, s)) {
  2528         -          ICHAR *dataPtr = (ICHAR *)dataBuf;
  2529         -          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
  2530         -          characterDataHandler(handlerArg, dataBuf,
  2531         -                               (int)(dataPtr - (ICHAR *)dataBuf));
         3033  +          ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
         3034  +          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
         3035  +          parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
         3036  +                               (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
  2532   3037           }
  2533   3038           else
  2534         -          characterDataHandler(handlerArg,
         3039  +          parser->m_characterDataHandler(parser->m_handlerArg,
  2535   3040                                  (XML_Char *)s,
  2536   3041                                  (int)((XML_Char *)end - (XML_Char *)s));
  2537   3042         }
  2538         -      else if (defaultHandler)
         3043  +      else if (parser->m_defaultHandler)
  2539   3044           reportDefault(parser, enc, s, end);
  2540         -      /* We are at the end of the final buffer, should we check for 
  2541         -         XML_SUSPENDED, XML_FINISHED? 
         3045  +      /* We are at the end of the final buffer, should we check for
         3046  +         XML_SUSPENDED, XML_FINISHED?
  2542   3047         */
  2543   3048         if (startTagLevel == 0) {
  2544   3049           *eventPP = end;
  2545   3050           return XML_ERROR_NO_ELEMENTS;
  2546   3051         }
  2547         -      if (tagLevel != startTagLevel) {
         3052  +      if (parser->m_tagLevel != startTagLevel) {
  2548   3053           *eventPP = end;
  2549   3054           return XML_ERROR_ASYNC_ENTITY;
  2550   3055         }
  2551   3056         *nextPtr = end;
  2552   3057         return XML_ERROR_NONE;
  2553         -    case XML_TOK_DATA_CHARS: 
         3058  +    case XML_TOK_DATA_CHARS:
  2554   3059         {
  2555         -        XML_CharacterDataHandler charDataHandler = characterDataHandler;
         3060  +        XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
  2556   3061           if (charDataHandler) {
  2557   3062             if (MUST_CONVERT(enc, s)) {
  2558   3063               for (;;) {
  2559         -              ICHAR *dataPtr = (ICHAR *)dataBuf;
  2560         -              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
         3064  +              ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
         3065  +              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
  2561   3066                 *eventEndPP = s;
  2562         -              charDataHandler(handlerArg, dataBuf,
  2563         -                              (int)(dataPtr - (ICHAR *)dataBuf));
  2564         -              if (s == next)
         3067  +              charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
         3068  +                              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
         3069  +              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
  2565   3070                   break;
  2566   3071                 *eventPP = s;
  2567   3072               }
  2568   3073             }
  2569   3074             else
  2570         -            charDataHandler(handlerArg,
         3075  +            charDataHandler(parser->m_handlerArg,
  2571   3076                               (XML_Char *)s,
  2572   3077                               (int)((XML_Char *)next - (XML_Char *)s));
  2573   3078           }
  2574         -        else if (defaultHandler)
         3079  +        else if (parser->m_defaultHandler)
  2575   3080             reportDefault(parser, enc, s, next);
  2576   3081         }
  2577   3082         break;
  2578   3083       case XML_TOK_PI:
  2579   3084         if (!reportProcessingInstruction(parser, enc, s, next))
  2580   3085           return XML_ERROR_NO_MEMORY;
  2581   3086         break;
  2582   3087       case XML_TOK_COMMENT:
  2583   3088         if (!reportComment(parser, enc, s, next))
  2584   3089           return XML_ERROR_NO_MEMORY;
  2585   3090         break;
  2586   3091       default:
  2587         -      if (defaultHandler)
         3092  +      /* All of the tokens produced by XmlContentTok() have their own
         3093  +       * explicit cases, so this default is not strictly necessary.
         3094  +       * However it is a useful safety net, so we retain the code and
         3095  +       * simply exclude it from the coverage tests.
         3096  +       *
         3097  +       * LCOV_EXCL_START
         3098  +       */
         3099  +      if (parser->m_defaultHandler)
  2588   3100           reportDefault(parser, enc, s, next);
  2589   3101         break;
         3102  +      /* LCOV_EXCL_STOP */
  2590   3103       }
  2591   3104       *eventPP = s = next;
  2592         -    switch (ps_parsing) {
  2593         -    case XML_SUSPENDED: 
         3105  +    switch (parser->m_parsingStatus.parsing) {
         3106  +    case XML_SUSPENDED:
  2594   3107         *nextPtr = next;
  2595   3108         return XML_ERROR_NONE;
  2596   3109       case XML_FINISHED:
  2597   3110         return XML_ERROR_ABORTED;
  2598   3111       default: ;
  2599   3112       }
  2600   3113     }
  2601   3114     /* not reached */
  2602   3115   }
         3116  +
         3117  +/* This function does not call free() on the allocated memory, merely
         3118  + * moving it to the parser's m_freeBindingList where it can be freed or
         3119  + * reused as appropriate.
         3120  + */
         3121  +static void
         3122  +freeBindings(XML_Parser parser, BINDING *bindings)
         3123  +{
         3124  +  while (bindings) {
         3125  +    BINDING *b = bindings;
         3126  +
         3127  +    /* m_startNamespaceDeclHandler will have been called for this
         3128  +     * binding in addBindings(), so call the end handler now.
         3129  +     */
         3130  +    if (parser->m_endNamespaceDeclHandler)
         3131  +        parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
         3132  +
         3133  +    bindings = bindings->nextTagBinding;
         3134  +    b->nextTagBinding = parser->m_freeBindingList;
         3135  +    parser->m_freeBindingList = b;
         3136  +    b->prefix->binding = b->prevPrefixBinding;
         3137  +  }
         3138  +}
  2603   3139   
  2604   3140   /* Precondition: all arguments must be non-NULL;
  2605   3141      Purpose:
  2606   3142      - normalize attributes
  2607   3143      - check attributes for well-formedness
  2608   3144      - generate namespace aware attribute names (URI, prefix)
  2609   3145      - build list of attributes for startElementHandler
................................................................................
  2612   3148      - generate namespace aware element name (URI, prefix)
  2613   3149   */
  2614   3150   static enum XML_Error
  2615   3151   storeAtts(XML_Parser parser, const ENCODING *enc,
  2616   3152             const char *attStr, TAG_NAME *tagNamePtr,
  2617   3153             BINDING **bindingsPtr)
  2618   3154   {
  2619         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         3155  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  2620   3156     ELEMENT_TYPE *elementType;
  2621   3157     int nDefaultAtts;
  2622   3158     const XML_Char **appAtts;   /* the attribute list for the application */
  2623   3159     int attIndex = 0;
  2624   3160     int prefixLen;
  2625   3161     int i;
  2626   3162     int n;
  2627   3163     XML_Char *uri;
  2628   3164     int nPrefixes = 0;
  2629   3165     BINDING *binding;
  2630   3166     const XML_Char *localPart;
  2631   3167   
  2632   3168     /* lookup the element type name */
  2633         -  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
         3169  +  elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
  2634   3170     if (!elementType) {
  2635   3171       const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
  2636   3172       if (!name)
  2637   3173         return XML_ERROR_NO_MEMORY;
  2638         -    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
         3174  +    elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
  2639   3175                                            sizeof(ELEMENT_TYPE));
  2640   3176       if (!elementType)
  2641   3177         return XML_ERROR_NO_MEMORY;
  2642         -    if (ns && !setElementTypePrefix(parser, elementType))
         3178  +    if (parser->m_ns && !setElementTypePrefix(parser, elementType))
  2643   3179         return XML_ERROR_NO_MEMORY;
  2644   3180     }
  2645   3181     nDefaultAtts = elementType->nDefaultAtts;
  2646   3182   
  2647   3183     /* get the attributes from the tokenizer */
  2648         -  n = XmlGetAttributes(enc, attStr, attsSize, atts);
  2649         -  if (n + nDefaultAtts > attsSize) {
  2650         -    int oldAttsSize = attsSize;
         3184  +  n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
         3185  +  if (n + nDefaultAtts > parser->m_attsSize) {
         3186  +    int oldAttsSize = parser->m_attsSize;
  2651   3187       ATTRIBUTE *temp;
  2652         -    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
  2653         -    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
  2654         -    if (temp == NULL)
         3188  +#ifdef XML_ATTR_INFO
         3189  +    XML_AttrInfo *temp2;
         3190  +#endif
         3191  +    parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
         3192  +    temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE));
         3193  +    if (temp == NULL) {
         3194  +      parser->m_attsSize = oldAttsSize;
         3195  +      return XML_ERROR_NO_MEMORY;
         3196  +    }
         3197  +    parser->m_atts = temp;
         3198  +#ifdef XML_ATTR_INFO
         3199  +    temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo));
         3200  +    if (temp2 == NULL) {
         3201  +      parser->m_attsSize = oldAttsSize;
  2655   3202         return XML_ERROR_NO_MEMORY;
  2656         -    atts = temp;
         3203  +    }
         3204  +    parser->m_attInfo = temp2;
         3205  +#endif
  2657   3206       if (n > oldAttsSize)
  2658         -      XmlGetAttributes(enc, attStr, n, atts);
         3207  +      XmlGetAttributes(enc, attStr, n, parser->m_atts);
  2659   3208     }
  2660   3209   
  2661         -  appAtts = (const XML_Char **)atts;
         3210  +  appAtts = (const XML_Char **)parser->m_atts;
  2662   3211     for (i = 0; i < n; i++) {
         3212  +    ATTRIBUTE *currAtt = &parser->m_atts[i];
         3213  +#ifdef XML_ATTR_INFO
         3214  +    XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
         3215  +#endif
  2663   3216       /* add the name and value to the attribute list */
  2664         -    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
  2665         -                                         atts[i].name
  2666         -                                         + XmlNameLength(enc, atts[i].name));
         3217  +    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
         3218  +                                         currAtt->name
         3219  +                                         + XmlNameLength(enc, currAtt->name));
  2667   3220       if (!attId)
  2668   3221         return XML_ERROR_NO_MEMORY;
         3222  +#ifdef XML_ATTR_INFO
         3223  +    currAttInfo->nameStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
         3224  +    currAttInfo->nameEnd = currAttInfo->nameStart +
         3225  +                           XmlNameLength(enc, currAtt->name);
         3226  +    currAttInfo->valueStart = parser->m_parseEndByteIndex -
         3227  +                            (parser->m_parseEndPtr - currAtt->valuePtr);
         3228  +    currAttInfo->valueEnd = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valueEnd);
         3229  +#endif
  2669   3230       /* Detect duplicate attributes by their QNames. This does not work when
  2670   3231          namespace processing is turned on and different prefixes for the same
  2671   3232          namespace are used. For this case we have a check further down.
  2672   3233       */
  2673   3234       if ((attId->name)[-1]) {
  2674         -      if (enc == encoding)
  2675         -        eventPtr = atts[i].name;
         3235  +      if (enc == parser->m_encoding)
         3236  +        parser->m_eventPtr = parser->m_atts[i].name;
  2676   3237         return XML_ERROR_DUPLICATE_ATTRIBUTE;
  2677   3238       }
  2678   3239       (attId->name)[-1] = 1;
  2679   3240       appAtts[attIndex++] = attId->name;
  2680         -    if (!atts[i].normalized) {
         3241  +    if (!parser->m_atts[i].normalized) {
  2681   3242         enum XML_Error result;
  2682   3243         XML_Bool isCdata = XML_TRUE;
  2683   3244   
  2684   3245         /* figure out whether declared as other than CDATA */
  2685   3246         if (attId->maybeTokenized) {
  2686   3247           int j;
  2687   3248           for (j = 0; j < nDefaultAtts; j++) {
................................................................................
  2690   3251               break;
  2691   3252             }
  2692   3253           }
  2693   3254         }
  2694   3255   
  2695   3256         /* normalize the attribute value */
  2696   3257         result = storeAttributeValue(parser, enc, isCdata,
  2697         -                                   atts[i].valuePtr, atts[i].valueEnd,
  2698         -                                   &tempPool);
         3258  +                                   parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd,
         3259  +                                   &parser->m_tempPool);
  2699   3260         if (result)
  2700   3261           return result;
  2701         -      appAtts[attIndex] = poolStart(&tempPool);
  2702         -      poolFinish(&tempPool);
         3262  +      appAtts[attIndex] = poolStart(&parser->m_tempPool);
         3263  +      poolFinish(&parser->m_tempPool);
  2703   3264       }
  2704   3265       else {
  2705   3266         /* the value did not need normalizing */
  2706         -      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
  2707         -                                          atts[i].valueEnd);
         3267  +      appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, parser->m_atts[i].valuePtr,
         3268  +                                          parser->m_atts[i].valueEnd);
  2708   3269         if (appAtts[attIndex] == 0)
  2709   3270           return XML_ERROR_NO_MEMORY;
  2710         -      poolFinish(&tempPool);
         3271  +      poolFinish(&parser->m_tempPool);
  2711   3272       }
  2712   3273       /* handle prefixed attribute names */
  2713   3274       if (attId->prefix) {
  2714   3275         if (attId->xmlns) {
  2715   3276           /* deal with namespace declarations here */
  2716   3277           enum XML_Error result = addBinding(parser, attId->prefix, attId,
  2717   3278                                              appAtts[attIndex], bindingsPtr);
................................................................................
  2727   3288         }
  2728   3289       }
  2729   3290       else
  2730   3291         attIndex++;
  2731   3292     }
  2732   3293   
  2733   3294     /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
  2734         -  nSpecifiedAtts = attIndex;
         3295  +  parser->m_nSpecifiedAtts = attIndex;
  2735   3296     if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
  2736   3297       for (i = 0; i < attIndex; i += 2)
  2737   3298         if (appAtts[i] == elementType->idAtt->name) {
  2738         -        idAttIndex = i;
         3299  +        parser->m_idAttIndex = i;
  2739   3300           break;
  2740   3301         }
  2741   3302     }
  2742   3303     else
  2743         -    idAttIndex = -1;
         3304  +    parser->m_idAttIndex = -1;
  2744   3305   
  2745   3306     /* do attribute defaulting */
  2746   3307     for (i = 0; i < nDefaultAtts; i++) {
  2747   3308       const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
  2748   3309       if (!(da->id->name)[-1] && da->value) {
  2749   3310         if (da->id->prefix) {
  2750   3311           if (da->id->xmlns) {
................................................................................
  2770   3331     appAtts[attIndex] = 0;
  2771   3332   
  2772   3333     /* expand prefixed attribute names, check for duplicates,
  2773   3334        and clear flags that say whether attributes were specified */
  2774   3335     i = 0;
  2775   3336     if (nPrefixes) {
  2776   3337       int j;  /* hash table index */
  2777         -    unsigned long version = nsAttsVersion;
  2778         -    int nsAttsSize = (int)1 << nsAttsPower;
         3338  +    unsigned long version = parser->m_nsAttsVersion;
         3339  +    int nsAttsSize = (int)1 << parser->m_nsAttsPower;
         3340  +    unsigned char oldNsAttsPower = parser->m_nsAttsPower;
  2779   3341       /* size of hash table must be at least 2 * (# of prefixed attributes) */
  2780         -    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
         3342  +    if ((nPrefixes << 1) >> parser->m_nsAttsPower) {  /* true for m_nsAttsPower = 0 */
  2781   3343         NS_ATT *temp;
  2782   3344         /* hash table size must also be a power of 2 and >= 8 */
  2783         -      while (nPrefixes >> nsAttsPower++);
  2784         -      if (nsAttsPower < 3)
  2785         -        nsAttsPower = 3;
  2786         -      nsAttsSize = (int)1 << nsAttsPower;
  2787         -      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
  2788         -      if (!temp)
         3345  +      while (nPrefixes >> parser->m_nsAttsPower++);
         3346  +      if (parser->m_nsAttsPower < 3)
         3347  +        parser->m_nsAttsPower = 3;
         3348  +      nsAttsSize = (int)1 << parser->m_nsAttsPower;
         3349  +      temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT));
         3350  +      if (!temp) {
         3351  +        /* Restore actual size of memory in m_nsAtts */
         3352  +        parser->m_nsAttsPower = oldNsAttsPower;
  2789   3353           return XML_ERROR_NO_MEMORY;
  2790         -      nsAtts = temp;
  2791         -      version = 0;  /* force re-initialization of nsAtts hash table */
         3354  +      }
         3355  +      parser->m_nsAtts = temp;
         3356  +      version = 0;  /* force re-initialization of m_nsAtts hash table */
  2792   3357       }
  2793         -    /* using a version flag saves us from initializing nsAtts every time */
         3358  +    /* using a version flag saves us from initializing m_nsAtts every time */
  2794   3359       if (!version) {  /* initialize version flags when version wraps around */
  2795   3360         version = INIT_ATTS_VERSION;
  2796   3361         for (j = nsAttsSize; j != 0; )
  2797         -        nsAtts[--j].version = version;
         3362  +        parser->m_nsAtts[--j].version = version;
  2798   3363       }
  2799         -    nsAttsVersion = --version;
         3364  +    parser->m_nsAttsVersion = --version;
  2800   3365   
  2801   3366       /* expand prefixed names and check for duplicates */
  2802   3367       for (; i < attIndex; i += 2) {
  2803   3368         const XML_Char *s = appAtts[i];
  2804   3369         if (s[-1] == 2) {  /* prefixed */
  2805   3370           ATTRIBUTE_ID *id;
  2806   3371           const BINDING *b;
  2807         -        unsigned long uriHash = 0;
         3372  +        unsigned long uriHash;
         3373  +        struct siphash sip_state;
         3374  +        struct sipkey sip_key;
         3375  +
         3376  +        copy_salt_to_sipkey(parser, &sip_key);
         3377  +        sip24_init(&sip_state, &sip_key);
         3378  +
  2808   3379           ((XML_Char *)s)[-1] = 0;  /* clear flag */
  2809         -        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
         3380  +        id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
         3381  +        if (!id || !id->prefix) {
         3382  +          /* This code is walking through the appAtts array, dealing
         3383  +           * with (in this case) a prefixed attribute name.  To be in
         3384  +           * the array, the attribute must have already been bound, so
         3385  +           * has to have passed through the hash table lookup once
         3386  +           * already.  That implies that an entry for it already
         3387  +           * exists, so the lookup above will return a pointer to
         3388  +           * already allocated memory.  There is no opportunaity for
         3389  +           * the allocator to fail, so the condition above cannot be
         3390  +           * fulfilled.
         3391  +           *
         3392  +           * Since it is difficult to be certain that the above
         3393  +           * analysis is complete, we retain the test and merely
         3394  +           * remove the code from coverage tests.
         3395  +           */
         3396  +          return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
         3397  +        }
  2810   3398           b = id->prefix->binding;
  2811   3399           if (!b)
  2812   3400             return XML_ERROR_UNBOUND_PREFIX;
  2813   3401   
  2814         -        /* as we expand the name we also calculate its hash value */
  2815   3402           for (j = 0; j < b->uriLen; j++) {
  2816   3403             const XML_Char c = b->uri[j];
  2817         -          if (!poolAppendChar(&tempPool, c))
         3404  +          if (!poolAppendChar(&parser->m_tempPool, c))
  2818   3405               return XML_ERROR_NO_MEMORY;
  2819         -          uriHash = CHAR_HASH(uriHash, c);
  2820   3406           }
         3407  +
         3408  +        sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
         3409  +
  2821   3410           while (*s++ != XML_T(ASCII_COLON))
  2822   3411             ;
         3412  +
         3413  +        sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
         3414  +
  2823   3415           do {  /* copies null terminator */
  2824         -          const XML_Char c = *s;
  2825         -          if (!poolAppendChar(&tempPool, *s))
         3416  +          if (!poolAppendChar(&parser->m_tempPool, *s))
  2826   3417               return XML_ERROR_NO_MEMORY;
  2827         -          uriHash = CHAR_HASH(uriHash, c);
  2828   3418           } while (*s++);
         3419  +
         3420  +        uriHash = (unsigned long)sip24_final(&sip_state);
  2829   3421   
  2830   3422           { /* Check hash table for duplicate of expanded name (uriName).
  2831         -             Derived from code in lookup(HASH_TABLE *table, ...).
         3423  +             Derived from code in lookup(parser, HASH_TABLE *table, ...).
  2832   3424             */
  2833   3425             unsigned char step = 0;
  2834   3426             unsigned long mask = nsAttsSize - 1;
  2835   3427             j = uriHash & mask;  /* index into hash table */
  2836         -          while (nsAtts[j].version == version) {
         3428  +          while (parser->m_nsAtts[j].version == version) {
  2837   3429               /* for speed we compare stored hash values first */
  2838         -            if (uriHash == nsAtts[j].hash) {
  2839         -              const XML_Char *s1 = poolStart(&tempPool);
  2840         -              const XML_Char *s2 = nsAtts[j].uriName;
         3430  +            if (uriHash == parser->m_nsAtts[j].hash) {
         3431  +              const XML_Char *s1 = poolStart(&parser->m_tempPool);
         3432  +              const XML_Char *s2 = parser->m_nsAtts[j].uriName;
  2841   3433                 /* s1 is null terminated, but not s2 */
  2842   3434                 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
  2843   3435                 if (*s1 == 0)
  2844   3436                   return XML_ERROR_DUPLICATE_ATTRIBUTE;
  2845   3437               }
  2846   3438               if (!step)
  2847         -              step = PROBE_STEP(uriHash, mask, nsAttsPower);
         3439  +              step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
  2848   3440               j < step ? (j += nsAttsSize - step) : (j -= step);
  2849   3441             }
  2850   3442           }
  2851   3443   
  2852         -        if (ns_triplets) {  /* append namespace separator and prefix */
  2853         -          tempPool.ptr[-1] = namespaceSeparator;
         3444  +        if (parser->m_ns_triplets) {  /* append namespace separator and prefix */
         3445  +          parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
  2854   3446             s = b->prefix->name;
  2855   3447             do {
  2856         -            if (!poolAppendChar(&tempPool, *s))
         3448  +            if (!poolAppendChar(&parser->m_tempPool, *s))
  2857   3449                 return XML_ERROR_NO_MEMORY;
  2858   3450             } while (*s++);
  2859   3451           }
  2860   3452   
  2861   3453           /* store expanded name in attribute list */
  2862         -        s = poolStart(&tempPool);
  2863         -        poolFinish(&tempPool);
         3454  +        s = poolStart(&parser->m_tempPool);
         3455  +        poolFinish(&parser->m_tempPool);
  2864   3456           appAtts[i] = s;
  2865   3457   
  2866   3458           /* fill empty slot with new version, uriName and hash value */
  2867         -        nsAtts[j].version = version;
  2868         -        nsAtts[j].hash = uriHash;
  2869         -        nsAtts[j].uriName = s;
         3459  +        parser->m_nsAtts[j].version = version;
         3460  +        parser->m_nsAtts[j].hash = uriHash;
         3461  +        parser->m_nsAtts[j].uriName = s;
  2870   3462   
  2871   3463           if (!--nPrefixes) {
  2872   3464             i += 2;
  2873   3465             break;
  2874   3466           }
  2875   3467         }
  2876   3468         else  /* not prefixed */
................................................................................
  2879   3471     }
  2880   3472     /* clear flags for the remaining attributes */
  2881   3473     for (; i < attIndex; i += 2)
  2882   3474       ((XML_Char *)(appAtts[i]))[-1] = 0;
  2883   3475     for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
  2884   3476       binding->attId->name[-1] = 0;
  2885   3477   
  2886         -  if (!ns)
         3478  +  if (!parser->m_ns)
  2887   3479       return XML_ERROR_NONE;
  2888   3480   
  2889   3481     /* expand the element type name */
  2890   3482     if (elementType->prefix) {
  2891   3483       binding = elementType->prefix->binding;
  2892   3484       if (!binding)
  2893   3485         return XML_ERROR_UNBOUND_PREFIX;
................................................................................
  2898   3490     else if (dtd->defaultPrefix.binding) {
  2899   3491       binding = dtd->defaultPrefix.binding;
  2900   3492       localPart = tagNamePtr->str;
  2901   3493     }
  2902   3494     else
  2903   3495       return XML_ERROR_NONE;
  2904   3496     prefixLen = 0;
  2905         -  if (ns_triplets && binding->prefix->name) {
         3497  +  if (parser->m_ns_triplets && binding->prefix->name) {
  2906   3498       for (; binding->prefix->name[prefixLen++];)
  2907   3499         ;  /* prefixLen includes null terminator */
  2908   3500     }
  2909   3501     tagNamePtr->localPart = localPart;
  2910   3502     tagNamePtr->uriLen = binding->uriLen;
  2911   3503     tagNamePtr->prefix = binding->prefix->name;
  2912   3504     tagNamePtr->prefixLen = prefixLen;
  2913   3505     for (i = 0; localPart[i++];)
  2914   3506       ;  /* i includes null terminator */
  2915   3507     n = i + binding->uriLen + prefixLen;
  2916   3508     if (n > binding->uriAlloc) {
  2917   3509       TAG *p;
  2918         -    uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
         3510  +    uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
  2919   3511       if (!uri)
  2920   3512         return XML_ERROR_NO_MEMORY;
  2921   3513       binding->uriAlloc = n + EXPAND_SPARE;
  2922   3514       memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
  2923         -    for (p = tagStack; p; p = p->parent)
         3515  +    for (p = parser->m_tagStack; p; p = p->parent)
  2924   3516         if (p->name.str == binding->uri)
  2925   3517           p->name.str = uri;
  2926         -    FREE(binding->uri);
         3518  +    FREE(parser, binding->uri);
  2927   3519       binding->uri = uri;
  2928   3520     }
  2929         -  /* if namespaceSeparator != '\0' then uri includes it already */
         3521  +  /* if m_namespaceSeparator != '\0' then uri includes it already */
  2930   3522     uri = binding->uri + binding->uriLen;
  2931   3523     memcpy(uri, localPart, i * sizeof(XML_Char));
  2932   3524     /* we always have a namespace separator between localPart and prefix */
  2933   3525     if (prefixLen) {
  2934   3526       uri += i - 1;
  2935         -    *uri = namespaceSeparator;  /* replace null terminator */
         3527  +    *uri = parser->m_namespaceSeparator;  /* replace null terminator */
  2936   3528       memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
  2937   3529     }
  2938   3530     tagNamePtr->str = binding->uri;
  2939   3531     return XML_ERROR_NONE;
  2940   3532   }
  2941   3533   
  2942   3534   /* addBinding() overwrites the value of prefix->binding without checking.
................................................................................
  2945   3537   static enum XML_Error
  2946   3538   addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
  2947   3539              const XML_Char *uri, BINDING **bindingsPtr)
  2948   3540   {
  2949   3541     static const XML_Char xmlNamespace[] = {
  2950   3542       ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
  2951   3543       ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
  2952         -    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, 
         3544  +    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
  2953   3545       ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
  2954   3546       ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
  2955   3547       ASCII_e, '\0'
  2956   3548     };
  2957         -  static const int xmlLen = 
         3549  +  static const int xmlLen =
  2958   3550       (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
  2959   3551     static const XML_Char xmlnsNamespace[] = {
  2960   3552       ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
  2961   3553       ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
  2962         -    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, 
  2963         -    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, 
         3554  +    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
         3555  +    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
  2964   3556       ASCII_SLASH, '\0'
  2965   3557     };
  2966         -  static const int xmlnsLen = 
         3558  +  static const int xmlnsLen =
  2967   3559       (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
  2968   3560   
  2969   3561     XML_Bool mustBeXML = XML_FALSE;
  2970   3562     XML_Bool isXML = XML_TRUE;
  2971   3563     XML_Bool isXMLNS = XML_TRUE;
  2972         -  
         3564  +
  2973   3565     BINDING *b;
  2974   3566     int len;
  2975   3567   
  2976   3568     /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
  2977   3569     if (*uri == XML_T('\0') && prefix->name)
  2978   3570       return XML_ERROR_UNDECLARING_PREFIX;
  2979   3571   
................................................................................
  2992   3584         mustBeXML = XML_TRUE;
  2993   3585     }
  2994   3586   
  2995   3587     for (len = 0; uri[len]; len++) {
  2996   3588       if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
  2997   3589         isXML = XML_FALSE;
  2998   3590   
  2999         -    if (!mustBeXML && isXMLNS 
         3591  +    if (!mustBeXML && isXMLNS
  3000   3592           && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
  3001   3593         isXMLNS = XML_FALSE;
  3002   3594     }
  3003   3595     isXML = isXML && len == xmlLen;
  3004   3596     isXMLNS = isXMLNS && len == xmlnsLen;
  3005   3597   
  3006   3598     if (mustBeXML != isXML)
  3007   3599       return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
  3008   3600                        : XML_ERROR_RESERVED_NAMESPACE_URI;
  3009   3601   
  3010   3602     if (isXMLNS)
  3011   3603       return XML_ERROR_RESERVED_NAMESPACE_URI;
  3012   3604   
  3013         -  if (namespaceSeparator)
         3605  +  if (parser->m_namespaceSeparator)
  3014   3606       len++;
  3015         -  if (freeBindingList) {
  3016         -    b = freeBindingList;
         3607  +  if (parser->m_freeBindingList) {
         3608  +    b = parser->m_freeBindingList;
  3017   3609       if (len > b->uriAlloc) {
  3018         -      XML_Char *temp = (XML_Char *)REALLOC(b->uri,
         3610  +      XML_Char *temp = (XML_Char *)REALLOC(parser, b->uri,
  3019   3611                             sizeof(XML_Char) * (len + EXPAND_SPARE));
  3020   3612         if (temp == NULL)
  3021   3613           return XML_ERROR_NO_MEMORY;
  3022   3614         b->uri = temp;
  3023   3615         b->uriAlloc = len + EXPAND_SPARE;
  3024   3616       }
  3025         -    freeBindingList = b->nextTagBinding;
         3617  +    parser->m_freeBindingList = b->nextTagBinding;
  3026   3618     }
  3027   3619     else {
  3028         -    b = (BINDING *)MALLOC(sizeof(BINDING));
         3620  +    b = (BINDING *)MALLOC(parser, sizeof(BINDING));
  3029   3621       if (!b)
  3030   3622         return XML_ERROR_NO_MEMORY;
  3031         -    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
         3623  +    b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
  3032   3624       if (!b->uri) {
  3033         -      FREE(b);
         3625  +      FREE(parser, b);
  3034   3626         return XML_ERROR_NO_MEMORY;
  3035   3627       }
  3036   3628       b->uriAlloc = len + EXPAND_SPARE;
  3037   3629     }
  3038   3630     b->uriLen = len;
  3039   3631     memcpy(b->uri, uri, len * sizeof(XML_Char));
  3040         -  if (namespaceSeparator)
  3041         -    b->uri[len - 1] = namespaceSeparator;
         3632  +  if (parser->m_namespaceSeparator)
         3633  +    b->uri[len - 1] = parser->m_namespaceSeparator;
  3042   3634     b->prefix = prefix;
  3043   3635     b->attId = attId;
  3044   3636     b->prevPrefixBinding = prefix->binding;
  3045   3637     /* NULL binding when default namespace undeclared */
  3046         -  if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
         3638  +  if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
  3047   3639       prefix->binding = NULL;
  3048   3640     else
  3049   3641       prefix->binding = b;
  3050   3642     b->nextTagBinding = *bindingsPtr;
  3051   3643     *bindingsPtr = b;
  3052   3644     /* if attId == NULL then we are not starting a namespace scope */
  3053         -  if (attId && startNamespaceDeclHandler)
  3054         -    startNamespaceDeclHandler(handlerArg, prefix->name,
         3645  +  if (attId && parser->m_startNamespaceDeclHandler)
         3646  +    parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
  3055   3647                                 prefix->binding ? uri : 0);
  3056   3648     return XML_ERROR_NONE;
  3057   3649   }
  3058   3650   
  3059   3651   /* The idea here is to avoid using stack for each CDATA section when
  3060   3652      the whole file is parsed with one call.
  3061   3653   */
  3062   3654   static enum XML_Error PTRCALL
  3063   3655   cdataSectionProcessor(XML_Parser parser,
  3064   3656                         const char *start,
  3065   3657                         const char *end,
  3066   3658                         const char **endPtr)
  3067   3659   {
  3068         -  enum XML_Error result = doCdataSection(parser, encoding, &start, end,
  3069         -                                         endPtr, (XML_Bool)!ps_finalBuffer);
         3660  +  enum XML_Error result = doCdataSection(parser, parser->m_encoding, &start, end,
         3661  +                                         endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  3070   3662     if (result != XML_ERROR_NONE)
  3071   3663       return result;
  3072   3664     if (start) {
  3073         -    if (parentParser) {  /* we are parsing an external entity */
  3074         -      processor = externalEntityContentProcessor;
         3665  +    if (parser->m_parentParser) {  /* we are parsing an external entity */
         3666  +      parser->m_processor = externalEntityContentProcessor;
  3075   3667         return externalEntityContentProcessor(parser, start, end, endPtr);
  3076   3668       }
  3077   3669       else {
  3078         -      processor = contentProcessor;
         3670  +      parser->m_processor = contentProcessor;
  3079   3671         return contentProcessor(parser, start, end, endPtr);
  3080   3672       }
  3081   3673     }
  3082   3674     return result;
  3083   3675   }
  3084   3676   
  3085   3677   /* startPtr gets set to non-null if the section is closed, and to null if
................................................................................
  3092   3684                  const char *end,
  3093   3685                  const char **nextPtr,
  3094   3686                  XML_Bool haveMore)
  3095   3687   {
  3096   3688     const char *s = *startPtr;
  3097   3689     const char **eventPP;
  3098   3690     const char **eventEndPP;
  3099         -  if (enc == encoding) {
  3100         -    eventPP = &eventPtr;
         3691  +  if (enc == parser->m_encoding) {
         3692  +    eventPP = &parser->m_eventPtr;
  3101   3693       *eventPP = s;
  3102         -    eventEndPP = &eventEndPtr;
         3694  +    eventEndPP = &parser->m_eventEndPtr;
  3103   3695     }
  3104   3696     else {
  3105         -    eventPP = &(openInternalEntities->internalEventPtr);
  3106         -    eventEndPP = &(openInternalEntities->internalEventEndPtr);
         3697  +    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
         3698  +    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
  3107   3699     }
  3108   3700     *eventPP = s;
  3109   3701     *startPtr = NULL;
  3110   3702   
  3111   3703     for (;;) {
  3112   3704       const char *next;
  3113   3705       int tok = XmlCdataSectionTok(enc, s, end, &next);
  3114   3706       *eventEndPP = next;
  3115   3707       switch (tok) {
  3116   3708       case XML_TOK_CDATA_SECT_CLOSE:
  3117         -      if (endCdataSectionHandler)
  3118         -        endCdataSectionHandler(handlerArg);
         3709  +      if (parser->m_endCdataSectionHandler)
         3710  +        parser->m_endCdataSectionHandler(parser->m_handlerArg);
  3119   3711   #if 0
  3120   3712         /* see comment under XML_TOK_CDATA_SECT_OPEN */
  3121         -      else if (characterDataHandler)
  3122         -        characterDataHandler(handlerArg, dataBuf, 0);
         3713  +      else if (parser->m_characterDataHandler)
         3714  +        parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0);
  3123   3715   #endif
  3124         -      else if (defaultHandler)
         3716  +      else if (parser->m_defaultHandler)
  3125   3717           reportDefault(parser, enc, s, next);
  3126   3718         *startPtr = next;
  3127   3719         *nextPtr = next;
  3128         -      if (ps_parsing == XML_FINISHED)
         3720  +      if (parser->m_parsingStatus.parsing == XML_FINISHED)
  3129   3721           return XML_ERROR_ABORTED;
  3130   3722         else
  3131   3723           return XML_ERROR_NONE;
  3132   3724       case XML_TOK_DATA_NEWLINE:
  3133         -      if (characterDataHandler) {
         3725  +      if (parser->m_characterDataHandler) {
  3134   3726           XML_Char c = 0xA;
  3135         -        characterDataHandler(handlerArg, &c, 1);
         3727  +        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
  3136   3728         }
  3137         -      else if (defaultHandler)
         3729  +      else if (parser->m_defaultHandler)
  3138   3730           reportDefault(parser, enc, s, next);
  3139   3731         break;
  3140   3732       case XML_TOK_DATA_CHARS:
  3141   3733         {
  3142         -        XML_CharacterDataHandler charDataHandler = characterDataHandler;
         3734  +        XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
  3143   3735           if (charDataHandler) {
  3144   3736             if (MUST_CONVERT(enc, s)) {
  3145   3737               for (;;) {
  3146         -              ICHAR *dataPtr = (ICHAR *)dataBuf;
  3147         -              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
         3738  +              ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
         3739  +              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
  3148   3740                 *eventEndPP = next;
  3149         -              charDataHandler(handlerArg, dataBuf,
  3150         -                              (int)(dataPtr - (ICHAR *)dataBuf));
  3151         -              if (s == next)
         3741  +              charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
         3742  +                              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
         3743  +              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
  3152   3744                   break;
  3153   3745                 *eventPP = s;
  3154   3746               }
  3155   3747             }
  3156   3748             else
  3157         -            charDataHandler(handlerArg,
         3749  +            charDataHandler(parser->m_handlerArg,
  3158   3750                               (XML_Char *)s,
  3159   3751                               (int)((XML_Char *)next - (XML_Char *)s));
  3160   3752           }
  3161         -        else if (defaultHandler)
         3753  +        else if (parser->m_defaultHandler)
  3162   3754             reportDefault(parser, enc, s, next);
  3163   3755         }
  3164   3756         break;
  3165   3757       case XML_TOK_INVALID:
  3166   3758         *eventPP = next;
  3167   3759         return XML_ERROR_INVALID_TOKEN;
  3168   3760       case XML_TOK_PARTIAL_CHAR:
................................................................................
  3175   3767       case XML_TOK_NONE:
  3176   3768         if (haveMore) {
  3177   3769           *nextPtr = s;
  3178   3770           return XML_ERROR_NONE;
  3179   3771         }
  3180   3772         return XML_ERROR_UNCLOSED_CDATA_SECTION;
  3181   3773       default:
         3774  +      /* Every token returned by XmlCdataSectionTok() has its own
         3775  +       * explicit case, so this default case will never be executed.
         3776  +       * We retain it as a safety net and exclude it from the coverage
         3777  +       * statistics.
         3778  +       *
         3779  +       * LCOV_EXCL_START
         3780  +      */
  3182   3781         *eventPP = next;
  3183   3782         return XML_ERROR_UNEXPECTED_STATE;
         3783  +      /* LCOV_EXCL_STOP */
  3184   3784       }
  3185   3785   
  3186   3786       *eventPP = s = next;
  3187         -    switch (ps_parsing) {
         3787  +    switch (parser->m_parsingStatus.parsing) {
  3188   3788       case XML_SUSPENDED:
  3189   3789         *nextPtr = next;
  3190   3790         return XML_ERROR_NONE;
  3191   3791       case XML_FINISHED:
  3192   3792         return XML_ERROR_ABORTED;
  3193   3793       default: ;
  3194   3794       }
................................................................................
  3203   3803   */
  3204   3804   static enum XML_Error PTRCALL
  3205   3805   ignoreSectionProcessor(XML_Parser parser,
  3206   3806                          const char *start,
  3207   3807                          const char *end,
  3208   3808                          const char **endPtr)
  3209   3809   {
  3210         -  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 
  3211         -                                          endPtr, (XML_Bool)!ps_finalBuffer);
         3810  +  enum XML_Error result = doIgnoreSection(parser, parser->m_encoding, &start, end,
         3811  +                                          endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  3212   3812     if (result != XML_ERROR_NONE)
  3213   3813       return result;
  3214   3814     if (start) {
  3215         -    processor = prologProcessor;
         3815  +    parser->m_processor = prologProcessor;
  3216   3816       return prologProcessor(parser, start, end, endPtr);
  3217   3817     }
  3218   3818     return result;
  3219   3819   }
  3220   3820   
  3221   3821   /* startPtr gets set to non-null is the section is closed, and to null
  3222   3822      if the section is not yet closed.
................................................................................
  3230   3830                   XML_Bool haveMore)
  3231   3831   {
  3232   3832     const char *next;
  3233   3833     int tok;
  3234   3834     const char *s = *startPtr;
  3235   3835     const char **eventPP;
  3236   3836     const char **eventEndPP;
  3237         -  if (enc == encoding) {
  3238         -    eventPP = &eventPtr;
         3837  +  if (enc == parser->m_encoding) {
         3838  +    eventPP = &parser->m_eventPtr;
  3239   3839       *eventPP = s;
  3240         -    eventEndPP = &eventEndPtr;
         3840  +    eventEndPP = &parser->m_eventEndPtr;
  3241   3841     }
  3242   3842     else {
  3243         -    eventPP = &(openInternalEntities->internalEventPtr);
  3244         -    eventEndPP = &(openInternalEntities->internalEventEndPtr);
         3843  +    /* It's not entirely clear, but it seems the following two lines
         3844  +     * of code cannot be executed.  The only occasions on which 'enc'
         3845  +     * is not 'encoding' are when this function is called
         3846  +     * from the internal entity processing, and IGNORE sections are an
         3847  +     * error in internal entities.
         3848  +     *
         3849  +     * Since it really isn't clear that this is true, we keep the code
         3850  +     * and just remove it from our coverage tests.
         3851  +     *
         3852  +     * LCOV_EXCL_START
         3853  +     */
         3854  +    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
         3855  +    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
         3856  +    /* LCOV_EXCL_STOP */
  3245   3857     }
  3246   3858     *eventPP = s;
  3247   3859     *startPtr = NULL;
  3248   3860     tok = XmlIgnoreSectionTok(enc, s, end, &next);
  3249   3861     *eventEndPP = next;
  3250   3862     switch (tok) {
  3251   3863     case XML_TOK_IGNORE_SECT:
  3252         -    if (defaultHandler)
         3864  +    if (parser->m_defaultHandler)
  3253   3865         reportDefault(parser, enc, s, next);
  3254   3866       *startPtr = next;
  3255   3867       *nextPtr = next;
  3256         -    if (ps_parsing == XML_FINISHED)
         3868  +    if (parser->m_parsingStatus.parsing == XML_FINISHED)
  3257   3869         return XML_ERROR_ABORTED;
  3258   3870       else
  3259   3871         return XML_ERROR_NONE;
  3260   3872     case XML_TOK_INVALID:
  3261   3873       *eventPP = next;
  3262   3874       return XML_ERROR_INVALID_TOKEN;
  3263   3875     case XML_TOK_PARTIAL_CHAR:
................................................................................
  3270   3882     case XML_TOK_NONE:
  3271   3883       if (haveMore) {
  3272   3884         *nextPtr = s;
  3273   3885         return XML_ERROR_NONE;
  3274   3886       }
  3275   3887       return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
  3276   3888     default:
         3889  +    /* All of the tokens that XmlIgnoreSectionTok() returns have
         3890  +     * explicit cases to handle them, so this default case is never
         3891  +     * executed.  We keep it as a safety net anyway, and remove it
         3892  +     * from our test coverage statistics.
         3893  +     *
         3894  +     * LCOV_EXCL_START
         3895  +     */
  3277   3896       *eventPP = next;
  3278   3897       return XML_ERROR_UNEXPECTED_STATE;
         3898  +    /* LCOV_EXCL_STOP */
  3279   3899     }
  3280   3900     /* not reached */
  3281   3901   }
  3282   3902   
  3283   3903   #endif /* XML_DTD */
  3284   3904   
  3285   3905   static enum XML_Error
  3286   3906   initializeEncoding(XML_Parser parser)
  3287   3907   {
  3288   3908     const char *s;
  3289   3909   #ifdef XML_UNICODE
  3290   3910     char encodingBuf[128];
  3291         -  if (!protocolEncodingName)
         3911  +  /* See comments abount `protoclEncodingName` in parserInit() */
         3912  +  if (!parser->m_protocolEncodingName)
  3292   3913       s = NULL;
  3293   3914     else {
  3294   3915       int i;
  3295         -    for (i = 0; protocolEncodingName[i]; i++) {
         3916  +    for (i = 0; parser->m_protocolEncodingName[i]; i++) {
  3296   3917         if (i == sizeof(encodingBuf) - 1
  3297         -          || (protocolEncodingName[i] & ~0x7f) != 0) {
         3918  +          || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
  3298   3919           encodingBuf[0] = '\0';
  3299   3920           break;
  3300   3921         }
  3301         -      encodingBuf[i] = (char)protocolEncodingName[i];
         3922  +      encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
  3302   3923       }
  3303   3924       encodingBuf[i] = '\0';
  3304   3925       s = encodingBuf;
  3305   3926     }
  3306   3927   #else
  3307         -  s = protocolEncodingName;
         3928  +  s = parser->m_protocolEncodingName;
  3308   3929   #endif
  3309         -  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
         3930  +  if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(&parser->m_initEncoding, &parser->m_encoding, s))
  3310   3931       return XML_ERROR_NONE;
  3311         -  return handleUnknownEncoding(parser, protocolEncodingName);
         3932  +  return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
  3312   3933   }
  3313   3934   
  3314   3935   static enum XML_Error
  3315   3936   processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
  3316   3937                  const char *s, const char *next)
  3317   3938   {
  3318   3939     const char *encodingName = NULL;
  3319   3940     const XML_Char *storedEncName = NULL;
  3320   3941     const ENCODING *newEncoding = NULL;
  3321   3942     const char *version = NULL;
  3322   3943     const char *versionend;
  3323   3944     const XML_Char *storedversion = NULL;
  3324   3945     int standalone = -1;
  3325         -  if (!(ns
         3946  +  if (!(parser->m_ns
  3326   3947           ? XmlParseXmlDeclNS
  3327   3948           : XmlParseXmlDecl)(isGeneralTextEntity,
  3328         -                           encoding,
         3949  +                           parser->m_encoding,
  3329   3950                              s,
  3330   3951                              next,
  3331         -                           &eventPtr,
         3952  +                           &parser->m_eventPtr,
  3332   3953                              &version,
  3333   3954                              &versionend,
  3334   3955                              &encodingName,
  3335   3956                              &newEncoding,
  3336   3957                              &standalone)) {
  3337   3958       if (isGeneralTextEntity)
  3338   3959         return XML_ERROR_TEXT_DECL;
  3339   3960       else
  3340   3961         return XML_ERROR_XML_DECL;
  3341   3962     }
  3342   3963     if (!isGeneralTextEntity && standalone == 1) {
  3343         -    _dtd->standalone = XML_TRUE;
         3964  +    parser->m_dtd->standalone = XML_TRUE;
  3344   3965   #ifdef XML_DTD
  3345         -    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
  3346         -      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
         3966  +    if (parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
         3967  +      parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
  3347   3968   #endif /* XML_DTD */
  3348   3969     }
  3349         -  if (xmlDeclHandler) {
         3970  +  if (parser->m_xmlDeclHandler) {
  3350   3971       if (encodingName != NULL) {
  3351         -      storedEncName = poolStoreString(&temp2Pool,
  3352         -                                      encoding,
         3972  +      storedEncName = poolStoreString(&parser->m_temp2Pool,
         3973  +                                      parser->m_encoding,
  3353   3974                                         encodingName,
  3354   3975                                         encodingName
  3355         -                                      + XmlNameLength(encoding, encodingName));
         3976  +                                      + XmlNameLength(parser->m_encoding, encodingName));
  3356   3977         if (!storedEncName)
  3357   3978                 return XML_ERROR_NO_MEMORY;
  3358         -      poolFinish(&temp2Pool);
         3979  +      poolFinish(&parser->m_temp2Pool);
  3359   3980       }
  3360   3981       if (version) {
  3361         -      storedversion = poolStoreString(&temp2Pool,
  3362         -                                      encoding,
         3982  +      storedversion = poolStoreString(&parser->m_temp2Pool,
         3983  +                                      parser->m_encoding,
  3363   3984                                         version,
  3364         -                                      versionend - encoding->minBytesPerChar);
         3985  +                                      versionend - parser->m_encoding->minBytesPerChar);
  3365   3986         if (!storedversion)
  3366   3987           return XML_ERROR_NO_MEMORY;
  3367   3988       }
  3368         -    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
         3989  +    parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, standalone);
  3369   3990     }
  3370         -  else if (defaultHandler)
  3371         -    reportDefault(parser, encoding, s, next);
  3372         -  if (protocolEncodingName == NULL) {
         3991  +  else if (parser->m_defaultHandler)
         3992  +    reportDefault(parser, parser->m_encoding, s, next);
         3993  +  if (parser->m_protocolEncodingName == NULL) {
  3373   3994       if (newEncoding) {
  3374         -      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
  3375         -        eventPtr = encodingName;
         3995  +      /* Check that the specified encoding does not conflict with what
         3996  +       * the parser has already deduced.  Do we have the same number
         3997  +       * of bytes in the smallest representation of a character?  If
         3998  +       * this is UTF-16, is it the same endianness?
         3999  +       */
         4000  +      if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
         4001  +          || (newEncoding->minBytesPerChar == 2 &&
         4002  +              newEncoding != parser->m_encoding)) {
         4003  +        parser->m_eventPtr = encodingName;
  3376   4004           return XML_ERROR_INCORRECT_ENCODING;
  3377   4005         }
  3378         -      encoding = newEncoding;
         4006  +      parser->m_encoding = newEncoding;
  3379   4007       }
  3380   4008       else if (encodingName) {
  3381   4009         enum XML_Error result;
  3382   4010         if (!storedEncName) {
  3383   4011           storedEncName = poolStoreString(
  3384         -          &temp2Pool, encoding, encodingName,
  3385         -          encodingName + XmlNameLength(encoding, encodingName));
         4012  +          &parser->m_temp2Pool, parser->m_encoding, encodingName,
         4013  +          encodingName + XmlNameLength(parser->m_encoding, encodingName));
  3386   4014           if (!storedEncName)
  3387   4015             return XML_ERROR_NO_MEMORY;
  3388   4016         }
  3389   4017         result = handleUnknownEncoding(parser, storedEncName);
  3390         -      poolClear(&temp2Pool);
         4018  +      poolClear(&parser->m_temp2Pool);
  3391   4019         if (result == XML_ERROR_UNKNOWN_ENCODING)
  3392         -        eventPtr = encodingName;
         4020  +        parser->m_eventPtr = encodingName;
  3393   4021         return result;
  3394   4022       }
  3395   4023     }
  3396   4024   
  3397   4025     if (storedEncName || storedversion)
  3398         -    poolClear(&temp2Pool);
         4026  +    poolClear(&parser->m_temp2Pool);
  3399   4027   
  3400   4028     return XML_ERROR_NONE;
  3401   4029   }
  3402   4030   
  3403   4031   static enum XML_Error
  3404   4032   handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
  3405   4033   {
  3406         -  if (unknownEncodingHandler) {
         4034  +  if (parser->m_unknownEncodingHandler) {
  3407   4035       XML_Encoding info;
  3408   4036       int i;
  3409   4037       for (i = 0; i < 256; i++)
  3410   4038         info.map[i] = -1;
  3411   4039       info.convert = NULL;
  3412   4040       info.data = NULL;
  3413   4041       info.release = NULL;
  3414         -    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
         4042  +    if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, encodingName,
  3415   4043                                  &info)) {
  3416   4044         ENCODING *enc;
  3417         -      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
  3418         -      if (!unknownEncodingMem) {
         4045  +      parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
         4046  +      if (!parser->m_unknownEncodingMem) {
  3419   4047           if (info.release)
  3420   4048             info.release(info.data);
  3421   4049           return XML_ERROR_NO_MEMORY;
  3422   4050         }
  3423         -      enc = (ns
         4051  +      enc = (parser->m_ns
  3424   4052                ? XmlInitUnknownEncodingNS
  3425         -             : XmlInitUnknownEncoding)(unknownEncodingMem,
         4053  +             : XmlInitUnknownEncoding)(parser->m_unknownEncodingMem,
  3426   4054                                          info.map,
  3427   4055                                          info.convert,
  3428   4056                                          info.data);
  3429   4057         if (enc) {
  3430         -        unknownEncodingData = info.data;
  3431         -        unknownEncodingRelease = info.release;
  3432         -        encoding = enc;
         4058  +        parser->m_unknownEncodingData = info.data;
         4059  +        parser->m_unknownEncodingRelease = info.release;
         4060  +        parser->m_encoding = enc;
  3433   4061           return XML_ERROR_NONE;
  3434   4062         }
  3435   4063       }
  3436   4064       if (info.release != NULL)
  3437   4065         info.release(info.data);
  3438   4066     }
  3439   4067     return XML_ERROR_UNKNOWN_ENCODING;
................................................................................
  3444   4072                       const char *s,
  3445   4073                       const char *end,
  3446   4074                       const char **nextPtr)
  3447   4075   {
  3448   4076     enum XML_Error result = initializeEncoding(parser);
  3449   4077     if (result != XML_ERROR_NONE)
  3450   4078       return result;
  3451         -  processor = prologProcessor;
         4079  +  parser->m_processor = prologProcessor;
  3452   4080     return prologProcessor(parser, s, end, nextPtr);
  3453   4081   }
  3454   4082   
  3455   4083   #ifdef XML_DTD
  3456   4084   
  3457   4085   static enum XML_Error PTRCALL
  3458   4086   externalParEntInitProcessor(XML_Parser parser,
................................................................................
  3462   4090   {
  3463   4091     enum XML_Error result = initializeEncoding(parser);
  3464   4092     if (result != XML_ERROR_NONE)
  3465   4093       return result;
  3466   4094   
  3467   4095     /* we know now that XML_Parse(Buffer) has been called,
  3468   4096        so we consider the external parameter entity read */
  3469         -  _dtd->paramEntityRead = XML_TRUE;
         4097  +  parser->m_dtd->paramEntityRead = XML_TRUE;
  3470   4098   
  3471         -  if (prologState.inEntityValue) {
  3472         -    processor = entityValueInitProcessor;
         4099  +  if (parser->m_prologState.inEntityValue) {
         4100  +    parser->m_processor = entityValueInitProcessor;
  3473   4101       return entityValueInitProcessor(parser, s, end, nextPtr);
  3474   4102     }
  3475   4103     else {
  3476         -    processor = externalParEntProcessor;
         4104  +    parser->m_processor = externalParEntProcessor;
  3477   4105       return externalParEntProcessor(parser, s, end, nextPtr);
  3478   4106     }
  3479   4107   }
  3480   4108   
  3481   4109   static enum XML_Error PTRCALL
  3482   4110   entityValueInitProcessor(XML_Parser parser,
  3483   4111                            const char *s,
  3484   4112                            const char *end,
  3485   4113                            const char **nextPtr)
  3486   4114   {
  3487   4115     int tok;
  3488   4116     const char *start = s;
  3489   4117     const char *next = start;
  3490         -  eventPtr = start;
         4118  +  parser->m_eventPtr = start;
  3491   4119   
  3492         -  for (;;) {  
  3493         -    tok = XmlPrologTok(encoding, start, end, &next);
  3494         -    eventEndPtr = next;
         4120  +  for (;;) {
         4121  +    tok = XmlPrologTok(parser->m_encoding, start, end, &next);
         4122  +    parser->m_eventEndPtr = next;
  3495   4123       if (tok <= 0) {
  3496         -      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
         4124  +      if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
  3497   4125           *nextPtr = s;
  3498   4126           return XML_ERROR_NONE;
  3499   4127         }
  3500   4128         switch (tok) {
  3501   4129         case XML_TOK_INVALID:
  3502   4130           return XML_ERROR_INVALID_TOKEN;
  3503   4131         case XML_TOK_PARTIAL:
................................................................................
  3505   4133         case XML_TOK_PARTIAL_CHAR:
  3506   4134           return XML_ERROR_PARTIAL_CHAR;
  3507   4135         case XML_TOK_NONE:   /* start == end */
  3508   4136         default:
  3509   4137           break;
  3510   4138         }
  3511   4139         /* found end of entity value - can store it now */
  3512         -      return storeEntityValue(parser, encoding, s, end);
         4140  +      return storeEntityValue(parser, parser->m_encoding, s, end);
  3513   4141       }
  3514   4142       else if (tok == XML_TOK_XML_DECL) {
  3515   4143         enum XML_Error result;
  3516   4144         result = processXmlDecl(parser, 0, start, next);
  3517   4145         if (result != XML_ERROR_NONE)
  3518   4146           return result;
  3519         -      switch (ps_parsing) {
  3520         -      case XML_SUSPENDED: 
  3521         -        *nextPtr = next;
  3522         -        return XML_ERROR_NONE;
  3523         -      case XML_FINISHED:
         4147  +      /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED.  For that
         4148  +       * to happen, a parameter entity parsing handler must have
         4149  +       * attempted to suspend the parser, which fails and raises an
         4150  +       * error.  The parser can be aborted, but can't be suspended.
         4151  +       */
         4152  +      if (parser->m_parsingStatus.parsing == XML_FINISHED)
  3524   4153           return XML_ERROR_ABORTED;
  3525         -      default:
  3526         -        *nextPtr = next;
  3527         -      }
         4154  +      *nextPtr = next;
  3528   4155         /* stop scanning for text declaration - we found one */
  3529         -      processor = entityValueProcessor;
         4156  +      parser->m_processor = entityValueProcessor;
  3530   4157         return entityValueProcessor(parser, next, end, nextPtr);
  3531   4158       }
  3532   4159       /* If we are at the end of the buffer, this would cause XmlPrologTok to
  3533   4160          return XML_TOK_NONE on the next call, which would then cause the
  3534   4161          function to exit with *nextPtr set to s - that is what we want for other
  3535   4162          tokens, but not for the BOM - we would rather like to skip it;
  3536   4163          then, when this routine is entered the next time, XmlPrologTok will
  3537   4164          return XML_TOK_INVALID, since the BOM is still in the buffer
  3538   4165       */
  3539         -    else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
         4166  +    else if (tok == XML_TOK_BOM && next == end && !parser->m_parsingStatus.finalBuffer) {
  3540   4167         *nextPtr = next;
  3541   4168         return XML_ERROR_NONE;
  3542   4169       }
         4170  +    /* If we get this token, we have the start of what might be a
         4171  +       normal tag, but not a declaration (i.e. it doesn't begin with
         4172  +       "<!").  In a DTD context, that isn't legal.
         4173  +    */
         4174  +    else if (tok == XML_TOK_INSTANCE_START) {
         4175  +      *nextPtr = next;
         4176  +      return XML_ERROR_SYNTAX;
         4177  +    }
  3543   4178       start = next;
  3544         -    eventPtr = start;
         4179  +    parser->m_eventPtr = start;
  3545   4180     }
  3546   4181   }
  3547   4182   
  3548   4183   static enum XML_Error PTRCALL
  3549   4184   externalParEntProcessor(XML_Parser parser,
  3550   4185                           const char *s,
  3551   4186                           const char *end,
  3552   4187                           const char **nextPtr)
  3553   4188   {
  3554   4189     const char *next = s;
  3555   4190     int tok;
  3556   4191   
  3557         -  tok = XmlPrologTok(encoding, s, end, &next);
         4192  +  tok = XmlPrologTok(parser->m_encoding, s, end, &next);
  3558   4193     if (tok <= 0) {
  3559         -    if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
         4194  +    if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
  3560   4195         *nextPtr = s;
  3561   4196         return XML_ERROR_NONE;
  3562   4197       }
  3563   4198       switch (tok) {
  3564   4199       case XML_TOK_INVALID:
  3565   4200         return XML_ERROR_INVALID_TOKEN;
  3566   4201       case XML_TOK_PARTIAL:
................................................................................
  3574   4209     }
  3575   4210     /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
  3576   4211        However, when parsing an external subset, doProlog will not accept a BOM
  3577   4212        as valid, and report a syntax error, so we have to skip the BOM
  3578   4213     */
  3579   4214     else if (tok == XML_TOK_BOM) {
  3580   4215       s = next;
  3581         -    tok = XmlPrologTok(encoding, s, end, &next);
         4216  +    tok = XmlPrologTok(parser->m_encoding, s, end, &next);
  3582   4217     }
  3583   4218   
  3584         -  processor = prologProcessor;
  3585         -  return doProlog(parser, encoding, s, end, tok, next, 
  3586         -                  nextPtr, (XML_Bool)!ps_finalBuffer);
         4219  +  parser->m_processor = prologProcessor;
         4220  +  return doProlog(parser, parser->m_encoding, s, end, tok, next,
         4221  +                  nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  3587   4222   }
  3588   4223   
  3589   4224   static enum XML_Error PTRCALL
  3590   4225   entityValueProcessor(XML_Parser parser,
  3591   4226                        const char *s,
  3592   4227                        const char *end,
  3593   4228                        const char **nextPtr)
  3594   4229   {
  3595   4230     const char *start = s;
  3596   4231     const char *next = s;
  3597         -  const ENCODING *enc = encoding;
         4232  +  const ENCODING *enc = parser->m_encoding;
  3598   4233     int tok;
  3599   4234   
  3600   4235     for (;;) {
  3601   4236       tok = XmlPrologTok(enc, start, end, &next);
  3602   4237       if (tok <= 0) {
  3603         -      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
         4238  +      if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
  3604   4239           *nextPtr = s;
  3605   4240           return XML_ERROR_NONE;
  3606   4241         }
  3607   4242         switch (tok) {
  3608   4243         case XML_TOK_INVALID:
  3609   4244           return XML_ERROR_INVALID_TOKEN;
  3610   4245         case XML_TOK_PARTIAL:
................................................................................
  3627   4262   static enum XML_Error PTRCALL
  3628   4263   prologProcessor(XML_Parser parser,
  3629   4264                   const char *s,
  3630   4265                   const char *end,
  3631   4266                   const char **nextPtr)
  3632   4267   {
  3633   4268     const char *next = s;
  3634         -  int tok = XmlPrologTok(encoding, s, end, &next);
  3635         -  return doProlog(parser, encoding, s, end, tok, next, 
  3636         -                  nextPtr, (XML_Bool)!ps_finalBuffer);
         4269  +  int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
         4270  +  return doProlog(parser, parser->m_encoding, s, end, tok, next,
         4271  +                  nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  3637   4272   }
  3638   4273   
  3639   4274   static enum XML_Error
  3640   4275   doProlog(XML_Parser parser,
  3641   4276            const ENCODING *enc,
  3642   4277            const char *s,
  3643   4278            const char *end,
................................................................................
  3645   4280            const char *next,
  3646   4281            const char **nextPtr,
  3647   4282            XML_Bool haveMore)
  3648   4283   {
  3649   4284   #ifdef XML_DTD
  3650   4285     static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
  3651   4286   #endif /* XML_DTD */
  3652         -  static const XML_Char atypeCDATA[] = 
         4287  +  static const XML_Char atypeCDATA[] =
  3653   4288         { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
  3654   4289     static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
  3655   4290     static const XML_Char atypeIDREF[] =
  3656   4291         { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
  3657   4292     static const XML_Char atypeIDREFS[] =
  3658   4293         { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
  3659   4294     static const XML_Char atypeENTITY[] =
................................................................................
  3666   4301         ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
  3667   4302     static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
  3668   4303         ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
  3669   4304     static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
  3670   4305     static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
  3671   4306   
  3672   4307     /* save one level of indirection */
  3673         -  DTD * const dtd = _dtd; 
         4308  +  DTD * const dtd = parser->m_dtd;
  3674   4309   
  3675   4310     const char **eventPP;
  3676   4311     const char **eventEndPP;
  3677   4312     enum XML_Content_Quant quant;
  3678   4313   
  3679         -  if (enc == encoding) {
  3680         -    eventPP = &eventPtr;
  3681         -    eventEndPP = &eventEndPtr;
         4314  +  if (enc == parser->m_encoding) {
         4315  +    eventPP = &parser->m_eventPtr;
         4316  +    eventEndPP = &parser->m_eventEndPtr;
  3682   4317     }
  3683   4318     else {
  3684         -    eventPP = &(openInternalEntities->internalEventPtr);
  3685         -    eventEndPP = &(openInternalEntities->internalEventEndPtr);
         4319  +    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
         4320  +    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
  3686   4321     }
  3687   4322   
  3688   4323     for (;;) {
  3689   4324       int role;
  3690   4325       XML_Bool handleDefault = XML_TRUE;
  3691   4326       *eventPP = s;
  3692   4327       *eventEndPP = next;
................................................................................
  3699   4334         case XML_TOK_INVALID:
  3700   4335           *eventPP = next;
  3701   4336           return XML_ERROR_INVALID_TOKEN;
  3702   4337         case XML_TOK_PARTIAL:
  3703   4338           return XML_ERROR_UNCLOSED_TOKEN;
  3704   4339         case XML_TOK_PARTIAL_CHAR:
  3705   4340           return XML_ERROR_PARTIAL_CHAR;
         4341  +      case -XML_TOK_PROLOG_S:
         4342  +        tok = -tok;
         4343  +        break;
  3706   4344         case XML_TOK_NONE:
  3707   4345   #ifdef XML_DTD
  3708   4346           /* for internal PE NOT referenced between declarations */
  3709         -        if (enc != encoding && !openInternalEntities->betweenDecl) {
         4347  +        if (enc != parser->m_encoding && !parser->m_openInternalEntities->betweenDecl) {
  3710   4348             *nextPtr = s;
  3711   4349             return XML_ERROR_NONE;
  3712   4350           }
  3713   4351           /* WFC: PE Between Declarations - must check that PE contains
  3714   4352              complete markup, not only for external PEs, but also for
  3715   4353              internal PEs if the reference occurs between declarations.
  3716   4354           */
  3717         -        if (isParamEntity || enc != encoding) {
  3718         -          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
         4355  +        if (parser->m_isParamEntity || enc != parser->m_encoding) {
         4356  +          if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
  3719   4357                 == XML_ROLE_ERROR)
  3720   4358               return XML_ERROR_INCOMPLETE_PE;
  3721   4359             *nextPtr = s;
  3722   4360             return XML_ERROR_NONE;
  3723   4361           }
  3724   4362   #endif /* XML_DTD */
  3725   4363           return XML_ERROR_NO_ELEMENTS;
  3726   4364         default:
  3727   4365           tok = -tok;
  3728   4366           next = end;
  3729   4367           break;
  3730   4368         }
  3731   4369       }
  3732         -    role = XmlTokenRole(&prologState, tok, s, next, enc);
         4370  +    role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
  3733   4371       switch (role) {
  3734   4372       case XML_ROLE_XML_DECL:
  3735   4373         {
  3736   4374           enum XML_Error result = processXmlDecl(parser, 0, s, next);
  3737   4375           if (result != XML_ERROR_NONE)
  3738   4376             return result;
  3739         -        enc = encoding;
         4377  +        enc = parser->m_encoding;
  3740   4378           handleDefault = XML_FALSE;
  3741   4379         }
  3742   4380         break;
  3743   4381       case XML_ROLE_DOCTYPE_NAME:
  3744         -      if (startDoctypeDeclHandler) {
  3745         -        doctypeName = poolStoreString(&tempPool, enc, s, next);
  3746         -        if (!doctypeName)
         4382  +      if (parser->m_startDoctypeDeclHandler) {
         4383  +        parser->m_doctypeName = poolStoreString(&parser->m_tempPool, enc, s, next);
         4384  +        if (!parser->m_doctypeName)
  3747   4385             return XML_ERROR_NO_MEMORY;
  3748         -        poolFinish(&tempPool);
  3749         -        doctypePubid = NULL;
         4386  +        poolFinish(&parser->m_tempPool);
         4387  +        parser->m_doctypePubid = NULL;
  3750   4388           handleDefault = XML_FALSE;
  3751   4389         }
  3752         -      doctypeSysid = NULL; /* always initialize to NULL */
         4390  +      parser->m_doctypeSysid = NULL; /* always initialize to NULL */
  3753   4391         break;
  3754   4392       case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
  3755         -      if (startDoctypeDeclHandler) {
  3756         -        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
  3757         -                                doctypePubid, 1);
  3758         -        doctypeName = NULL;
  3759         -        poolClear(&tempPool);
         4393  +      if (parser->m_startDoctypeDeclHandler) {
         4394  +        parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
         4395  +                                parser->m_doctypePubid, 1);
         4396  +        parser->m_doctypeName = NULL;
         4397  +        poolClear(&parser->m_tempPool);
  3760   4398           handleDefault = XML_FALSE;
  3761   4399         }
  3762   4400         break;
  3763   4401   #ifdef XML_DTD
  3764   4402       case XML_ROLE_TEXT_DECL:
  3765   4403         {
  3766   4404           enum XML_Error result = processXmlDecl(parser, 1, s, next);
  3767   4405           if (result != XML_ERROR_NONE)
  3768   4406             return result;
  3769         -        enc = encoding;
         4407  +        enc = parser->m_encoding;
  3770   4408           handleDefault = XML_FALSE;
  3771   4409         }
  3772   4410         break;
  3773   4411   #endif /* XML_DTD */
  3774   4412       case XML_ROLE_DOCTYPE_PUBLIC_ID:
  3775   4413   #ifdef XML_DTD
  3776         -      useForeignDTD = XML_FALSE;
  3777         -      declEntity = (ENTITY *)lookup(&dtd->paramEntities,
         4414  +      parser->m_useForeignDTD = XML_FALSE;
         4415  +      parser->m_declEntity = (ENTITY *)lookup(parser,
         4416  +                                    &dtd->paramEntities,
  3778   4417                                       externalSubsetName,
  3779   4418                                       sizeof(ENTITY));
  3780         -      if (!declEntity)
         4419  +      if (!parser->m_declEntity)
  3781   4420           return XML_ERROR_NO_MEMORY;
  3782   4421   #endif /* XML_DTD */
  3783   4422         dtd->hasParamEntityRefs = XML_TRUE;
  3784         -      if (startDoctypeDeclHandler) {
         4423  +      if (parser->m_startDoctypeDeclHandler) {
         4424  +        XML_Char *pubId;
  3785   4425           if (!XmlIsPublicId(enc, s, next, eventPP))
  3786   4426             return XML_ERROR_PUBLICID;
  3787         -        doctypePubid = poolStoreString(&tempPool, enc,
  3788         -                                       s + enc->minBytesPerChar,
  3789         -                                       next - enc->minBytesPerChar);
  3790         -        if (!doctypePubid)
         4427  +        pubId = poolStoreString(&parser->m_tempPool, enc,
         4428  +                                s + enc->minBytesPerChar,
         4429  +                                next - enc->minBytesPerChar);
         4430  +        if (!pubId)
  3791   4431             return XML_ERROR_NO_MEMORY;
  3792         -        normalizePublicId((XML_Char *)doctypePubid);
  3793         -        poolFinish(&tempPool);
         4432  +        normalizePublicId(pubId);
         4433  +        poolFinish(&parser->m_tempPool);
         4434  +        parser->m_doctypePubid = pubId;
  3794   4435           handleDefault = XML_FALSE;
  3795   4436           goto alreadyChecked;
  3796   4437         }
  3797   4438         /* fall through */
  3798   4439       case XML_ROLE_ENTITY_PUBLIC_ID:
  3799   4440         if (!XmlIsPublicId(enc, s, next, eventPP))
  3800   4441           return XML_ERROR_PUBLICID;
  3801   4442       alreadyChecked:
  3802         -      if (dtd->keepProcessing && declEntity) {
         4443  +      if (dtd->keepProcessing && parser->m_declEntity) {
  3803   4444           XML_Char *tem = poolStoreString(&dtd->pool,
  3804   4445                                           enc,
  3805   4446                                           s + enc->minBytesPerChar,
  3806   4447                                           next - enc->minBytesPerChar);
  3807   4448           if (!tem)
  3808   4449             return XML_ERROR_NO_MEMORY;
  3809   4450           normalizePublicId(tem);
  3810         -        declEntity->publicId = tem;
         4451  +        parser->m_declEntity->publicId = tem;
  3811   4452           poolFinish(&dtd->pool);
  3812         -        if (entityDeclHandler)
         4453  +        /* Don't suppress the default handler if we fell through from
         4454  +         * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
         4455  +         */
         4456  +        if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
  3813   4457             handleDefault = XML_FALSE;
  3814   4458         }
  3815   4459         break;
  3816   4460       case XML_ROLE_DOCTYPE_CLOSE:
  3817         -      if (doctypeName) {
  3818         -        startDoctypeDeclHandler(handlerArg, doctypeName,
  3819         -                                doctypeSysid, doctypePubid, 0);
  3820         -        poolClear(&tempPool);
         4461  +      if (parser->m_doctypeName) {
         4462  +        parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName,
         4463  +                                parser->m_doctypeSysid, parser->m_doctypePubid, 0);
         4464  +        poolClear(&parser->m_tempPool);
  3821   4465           handleDefault = XML_FALSE;
  3822   4466         }
  3823         -      /* doctypeSysid will be non-NULL in the case of a previous
  3824         -         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
         4467  +      /* parser->m_doctypeSysid will be non-NULL in the case of a previous
         4468  +         XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
  3825   4469            was not set, indicating an external subset
  3826   4470         */
  3827   4471   #ifdef XML_DTD
  3828         -      if (doctypeSysid || useForeignDTD) {
         4472  +      if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
  3829   4473           XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
  3830   4474           dtd->hasParamEntityRefs = XML_TRUE;
  3831         -        if (paramEntityParsing && externalEntityRefHandler) {
  3832         -          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
         4475  +        if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) {
         4476  +          ENTITY *entity = (ENTITY *)lookup(parser,
         4477  +                                            &dtd->paramEntities,
  3833   4478                                               externalSubsetName,
  3834   4479                                               sizeof(ENTITY));
  3835         -          if (!entity)
  3836         -            return XML_ERROR_NO_MEMORY;
  3837         -          if (useForeignDTD)
  3838         -            entity->base = curBase;
         4480  +          if (!entity) {
         4481  +            /* The external subset name "#" will have already been
         4482  +             * inserted into the hash table at the start of the
         4483  +             * external entity parsing, so no allocation will happen
         4484  +             * and lookup() cannot fail.
         4485  +             */
         4486  +            return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
         4487  +          }
         4488  +          if (parser->m_useForeignDTD)
         4489  +            entity->base = parser->m_curBase;
  3839   4490             dtd->paramEntityRead = XML_FALSE;
  3840         -          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
         4491  +          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
  3841   4492                                           0,
  3842   4493                                           entity->base,
  3843   4494                                           entity->systemId,
  3844   4495                                           entity->publicId))
  3845   4496               return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  3846   4497             if (dtd->paramEntityRead) {
  3847         -            if (!dtd->standalone && 
  3848         -                notStandaloneHandler && 
  3849         -                !notStandaloneHandler(handlerArg))
         4498  +            if (!dtd->standalone &&
         4499  +                parser->m_notStandaloneHandler &&
         4500  +                !parser->m_notStandaloneHandler(parser->m_handlerArg))
  3850   4501                 return XML_ERROR_NOT_STANDALONE;
  3851   4502             }
  3852   4503             /* if we didn't read the foreign DTD then this means that there
  3853   4504                is no external subset and we must reset dtd->hasParamEntityRefs
  3854   4505             */
  3855         -          else if (!doctypeSysid)
         4506  +          else if (!parser->m_doctypeSysid)
  3856   4507               dtd->hasParamEntityRefs = hadParamEntityRefs;
  3857   4508             /* end of DTD - no need to update dtd->keepProcessing */
  3858   4509           }
  3859         -        useForeignDTD = XML_FALSE;
         4510  +        parser->m_useForeignDTD = XML_FALSE;
  3860   4511         }
  3861   4512   #endif /* XML_DTD */
  3862         -      if (endDoctypeDeclHandler) {
  3863         -        endDoctypeDeclHandler(handlerArg);
         4513  +      if (parser->m_endDoctypeDeclHandler) {
         4514  +        parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
  3864   4515           handleDefault = XML_FALSE;
  3865   4516         }
  3866   4517         break;
  3867   4518       case XML_ROLE_INSTANCE_START:
  3868   4519   #ifdef XML_DTD
  3869   4520         /* if there is no DOCTYPE declaration then now is the
  3870   4521            last chance to read the foreign DTD
  3871   4522         */
  3872         -      if (useForeignDTD) {
         4523  +      if (parser->m_useForeignDTD) {
  3873   4524           XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
  3874   4525           dtd->hasParamEntityRefs = XML_TRUE;
  3875         -        if (paramEntityParsing && externalEntityRefHandler) {
  3876         -          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
         4526  +        if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) {
         4527  +          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
  3877   4528                                               externalSubsetName,
  3878   4529                                               sizeof(ENTITY));
  3879   4530             if (!entity)
  3880   4531               return XML_ERROR_NO_MEMORY;
  3881         -          entity->base = curBase;
         4532  +          entity->base = parser->m_curBase;
  3882   4533             dtd->paramEntityRead = XML_FALSE;
  3883         -          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
         4534  +          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
  3884   4535                                           0,
  3885   4536                                           entity->base,
  3886   4537                                           entity->systemId,
  3887   4538                                           entity->publicId))
  3888   4539               return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  3889   4540             if (dtd->paramEntityRead) {
  3890   4541               if (!dtd->standalone &&
  3891         -                notStandaloneHandler &&
  3892         -                !notStandaloneHandler(handlerArg))
         4542  +                parser->m_notStandaloneHandler &&
         4543  +                !parser->m_notStandaloneHandler(parser->m_handlerArg))
  3893   4544                 return XML_ERROR_NOT_STANDALONE;
  3894   4545             }
  3895   4546             /* if we didn't read the foreign DTD then this means that there
  3896   4547                is no external subset and we must reset dtd->hasParamEntityRefs
  3897   4548             */
  3898   4549             else
  3899   4550               dtd->hasParamEntityRefs = hadParamEntityRefs;
  3900   4551             /* end of DTD - no need to update dtd->keepProcessing */
  3901   4552           }
  3902   4553         }
  3903   4554   #endif /* XML_DTD */
  3904         -      processor = contentProcessor;
         4555  +      parser->m_processor = contentProcessor;
  3905   4556         return contentProcessor(parser, s, end, nextPtr);
  3906   4557       case XML_ROLE_ATTLIST_ELEMENT_NAME:
  3907         -      declElementType = getElementType(parser, enc, s, next);
  3908         -      if (!declElementType)
         4558  +      parser->m_declElementType = getElementType(parser, enc, s, next);
         4559  +      if (!parser->m_declElementType)
  3909   4560           return XML_ERROR_NO_MEMORY;
  3910   4561         goto checkAttListDeclHandler;
  3911   4562       case XML_ROLE_ATTRIBUTE_NAME:
  3912         -      declAttributeId = getAttributeId(parser, enc, s, next);
  3913         -      if (!declAttributeId)
         4563  +      parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
         4564  +      if (!parser->m_declAttributeId)
  3914   4565           return XML_ERROR_NO_MEMORY;
  3915         -      declAttributeIsCdata = XML_FALSE;
  3916         -      declAttributeType = NULL;
  3917         -      declAttributeIsId = XML_FALSE;
         4566  +      parser->m_declAttributeIsCdata = XML_FALSE;
         4567  +      parser->m_declAttributeType = NULL;
         4568  +      parser->m_declAttributeIsId = XML_FALSE;
  3918   4569         goto checkAttListDeclHandler;
  3919   4570       case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
  3920         -      declAttributeIsCdata = XML_TRUE;
  3921         -      declAttributeType = atypeCDATA;
         4571  +      parser->m_declAttributeIsCdata = XML_TRUE;
         4572  +      parser->m_declAttributeType = atypeCDATA;
  3922   4573         goto checkAttListDeclHandler;
  3923   4574       case XML_ROLE_ATTRIBUTE_TYPE_ID:
  3924         -      declAttributeIsId = XML_TRUE;
  3925         -      declAttributeType = atypeID;
         4575  +      parser->m_declAttributeIsId = XML_TRUE;
         4576  +      parser->m_declAttributeType = atypeID;
  3926   4577         goto checkAttListDeclHandler;
  3927   4578       case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
  3928         -      declAttributeType = atypeIDREF;
         4579  +      parser->m_declAttributeType = atypeIDREF;
  3929   4580         goto checkAttListDeclHandler;
  3930   4581       case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
  3931         -      declAttributeType = atypeIDREFS;
         4582  +      parser->m_declAttributeType = atypeIDREFS;
  3932   4583         goto checkAttListDeclHandler;
  3933   4584       case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
  3934         -      declAttributeType = atypeENTITY;
         4585  +      parser->m_declAttributeType = atypeENTITY;
  3935   4586         goto checkAttListDeclHandler;
  3936   4587       case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
  3937         -      declAttributeType = atypeENTITIES;
         4588  +      parser->m_declAttributeType = atypeENTITIES;
  3938   4589         goto checkAttListDeclHandler;
  3939   4590       case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
  3940         -      declAttributeType = atypeNMTOKEN;
         4591  +      parser->m_declAttributeType = atypeNMTOKEN;
  3941   4592         goto checkAttListDeclHandler;
  3942   4593       case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
  3943         -      declAttributeType = atypeNMTOKENS;
         4594  +      parser->m_declAttributeType = atypeNMTOKENS;
  3944   4595       checkAttListDeclHandler:
  3945         -      if (dtd->keepProcessing && attlistDeclHandler)
         4596  +      if (dtd->keepProcessing && parser->m_attlistDeclHandler)
  3946   4597           handleDefault = XML_FALSE;
  3947   4598         break;
  3948   4599       case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
  3949   4600       case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
  3950         -      if (dtd->keepProcessing && attlistDeclHandler) {
         4601  +      if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
  3951   4602           const XML_Char *prefix;
  3952         -        if (declAttributeType) {
         4603  +        if (parser->m_declAttributeType) {
  3953   4604             prefix = enumValueSep;
  3954   4605           }
  3955   4606           else {
  3956   4607             prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
  3957   4608                       ? notationPrefix
  3958   4609                       : enumValueStart);
  3959   4610           }
  3960         -        if (!poolAppendString(&tempPool, prefix))
         4611  +        if (!poolAppendString(&parser->m_tempPool, prefix))
  3961   4612             return XML_ERROR_NO_MEMORY;
  3962         -        if (!poolAppend(&tempPool, enc, s, next))
         4613  +        if (!poolAppend(&parser->m_tempPool, enc, s, next))
  3963   4614             return XML_ERROR_NO_MEMORY;
  3964         -        declAttributeType = tempPool.start;
         4615  +        parser->m_declAttributeType = parser->m_tempPool.start;
  3965   4616           handleDefault = XML_FALSE;
  3966   4617         }
  3967   4618         break;
  3968   4619       case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
  3969   4620       case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
  3970   4621         if (dtd->keepProcessing) {
  3971         -        if (!defineAttribute(declElementType, declAttributeId,
  3972         -                             declAttributeIsCdata, declAttributeIsId,
         4622  +        if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId,
         4623  +                             parser->m_declAttributeIsCdata, parser->m_declAttributeIsId,
  3973   4624                                0, parser))
  3974   4625             return XML_ERROR_NO_MEMORY;
  3975         -        if (attlistDeclHandler && declAttributeType) {
  3976         -          if (*declAttributeType == XML_T(ASCII_LPAREN)
  3977         -              || (*declAttributeType == XML_T(ASCII_N)
  3978         -                  && declAttributeType[1] == XML_T(ASCII_O))) {
         4626  +        if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
         4627  +          if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
         4628  +              || (*parser->m_declAttributeType == XML_T(ASCII_N)
         4629  +                  && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
  3979   4630               /* Enumerated or Notation type */
  3980         -            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
  3981         -                || !poolAppendChar(&tempPool, XML_T('\0')))
         4631  +            if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
         4632  +                || !poolAppendChar(&parser->m_tempPool, XML_T('\0')))
  3982   4633                 return XML_ERROR_NO_MEMORY;
  3983         -            declAttributeType = tempPool.start;
  3984         -            poolFinish(&tempPool);
         4634  +            parser->m_declAttributeType = parser->m_tempPool.start;
         4635  +            poolFinish(&parser->m_tempPool);
  3985   4636             }
  3986   4637             *eventEndPP = s;
  3987         -          attlistDeclHandler(handlerArg, declElementType->name,
  3988         -                             declAttributeId->name, declAttributeType,
         4638  +          parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name,
         4639  +                             parser->m_declAttributeId->name, parser->m_declAttributeType,
  3989   4640                                0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
  3990         -          poolClear(&tempPool);
         4641  +          poolClear(&parser->m_tempPool);
  3991   4642             handleDefault = XML_FALSE;
  3992   4643           }
  3993   4644         }
  3994   4645         break;
  3995   4646       case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
  3996   4647       case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
  3997   4648         if (dtd->keepProcessing) {
  3998   4649           const XML_Char *attVal;
  3999   4650           enum XML_Error result =
  4000         -          storeAttributeValue(parser, enc, declAttributeIsCdata,
         4651  +          storeAttributeValue(parser, enc, parser->m_declAttributeIsCdata,
  4001   4652                                 s + enc->minBytesPerChar,
  4002   4653                                 next - enc->minBytesPerChar,
  4003   4654                                 &dtd->pool);
  4004   4655           if (result)
  4005   4656             return result;
  4006   4657           attVal = poolStart(&dtd->pool);
  4007   4658           poolFinish(&dtd->pool);
  4008   4659           /* ID attributes aren't allowed to have a default */
  4009         -        if (!defineAttribute(declElementType, declAttributeId,
  4010         -                             declAttributeIsCdata, XML_FALSE, attVal, parser))
         4660  +        if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId,
         4661  +                             parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
  4011   4662             return XML_ERROR_NO_MEMORY;
  4012         -        if (attlistDeclHandler && declAttributeType) {
  4013         -          if (*declAttributeType == XML_T(ASCII_LPAREN)
  4014         -              || (*declAttributeType == XML_T(ASCII_N)
  4015         -                  && declAttributeType[1] == XML_T(ASCII_O))) {
         4663  +        if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
         4664  +          if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
         4665  +              || (*parser->m_declAttributeType == XML_T(ASCII_N)
         4666  +                  && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
  4016   4667               /* Enumerated or Notation type */
  4017         -            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
  4018         -                || !poolAppendChar(&tempPool, XML_T('\0')))
         4668  +            if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
         4669  +                || !poolAppendChar(&parser->m_tempPool, XML_T('\0')))
  4019   4670                 return XML_ERROR_NO_MEMORY;
  4020         -            declAttributeType = tempPool.start;
  4021         -            poolFinish(&tempPool);
         4671  +            parser->m_declAttributeType = parser->m_tempPool.start;
         4672  +            poolFinish(&parser->m_tempPool);
  4022   4673             }
  4023   4674             *eventEndPP = s;
  4024         -          attlistDeclHandler(handlerArg, declElementType->name,
  4025         -                             declAttributeId->name, declAttributeType,
         4675  +          parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name,
         4676  +                             parser->m_declAttributeId->name, parser->m_declAttributeType,
  4026   4677                                attVal,
  4027   4678                                role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
  4028         -          poolClear(&tempPool);
         4679  +          poolClear(&parser->m_tempPool);
  4029   4680             handleDefault = XML_FALSE;
  4030   4681           }
  4031   4682         }
  4032   4683         break;
  4033   4684       case XML_ROLE_ENTITY_VALUE:
  4034   4685         if (dtd->keepProcessing) {
  4035   4686           enum XML_Error result = storeEntityValue(parser, enc,
  4036   4687                                               s + enc->minBytesPerChar,
  4037   4688                                               next - enc->minBytesPerChar);
  4038         -        if (declEntity) {
  4039         -          declEntity->textPtr = poolStart(&dtd->entityValuePool);
  4040         -          declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
         4689  +        if (parser->m_declEntity) {
         4690  +          parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
         4691  +          parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
  4041   4692             poolFinish(&dtd->entityValuePool);
  4042         -          if (entityDeclHandler) {
         4693  +          if (parser->m_entityDeclHandler) {
  4043   4694               *eventEndPP = s;
  4044         -            entityDeclHandler(handlerArg,
  4045         -                              declEntity->name,
  4046         -                              declEntity->is_param,
  4047         -                              declEntity->textPtr,
  4048         -                              declEntity->textLen,
  4049         -                              curBase, 0, 0, 0);
         4695  +            parser->m_entityDeclHandler(parser->m_handlerArg,
         4696  +                              parser->m_declEntity->name,
         4697  +                              parser->m_declEntity->is_param,
         4698  +                              parser->m_declEntity->textPtr,
         4699  +                              parser->m_declEntity->textLen,
         4700  +                              parser->m_curBase, 0, 0, 0);
  4050   4701               handleDefault = XML_FALSE;
  4051   4702             }
  4052   4703           }
  4053   4704           else
  4054   4705             poolDiscard(&dtd->entityValuePool);
  4055   4706           if (result != XML_ERROR_NONE)
  4056   4707             return result;
  4057   4708         }
  4058   4709         break;
  4059   4710       case XML_ROLE_DOCTYPE_SYSTEM_ID:
  4060   4711   #ifdef XML_DTD
  4061         -      useForeignDTD = XML_FALSE;
         4712  +      parser->m_useForeignDTD = XML_FALSE;
  4062   4713   #endif /* XML_DTD */
  4063   4714         dtd->hasParamEntityRefs = XML_TRUE;
  4064         -      if (startDoctypeDeclHandler) {
  4065         -        doctypeSysid = poolStoreString(&tempPool, enc,
         4715  +      if (parser->m_startDoctypeDeclHandler) {
         4716  +        parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
  4066   4717                                          s + enc->minBytesPerChar,
  4067   4718                                          next - enc->minBytesPerChar);
  4068         -        if (doctypeSysid == NULL)
         4719  +        if (parser->m_doctypeSysid == NULL)
  4069   4720             return XML_ERROR_NO_MEMORY;
  4070         -        poolFinish(&tempPool);
         4721  +        poolFinish(&parser->m_tempPool);
  4071   4722           handleDefault = XML_FALSE;
  4072   4723         }
  4073   4724   #ifdef XML_DTD
  4074   4725         else
  4075         -        /* use externalSubsetName to make doctypeSysid non-NULL
  4076         -           for the case where no startDoctypeDeclHandler is set */
  4077         -        doctypeSysid = externalSubsetName;
         4726  +        /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
         4727  +           for the case where no parser->m_startDoctypeDeclHandler is set */
         4728  +        parser->m_doctypeSysid = externalSubsetName;
  4078   4729   #endif /* XML_DTD */
  4079   4730         if (!dtd->standalone
  4080   4731   #ifdef XML_DTD
  4081         -          && !paramEntityParsing
         4732  +          && !parser->m_paramEntityParsing
  4082   4733   #endif /* XML_DTD */
  4083         -          && notStandaloneHandler
  4084         -          && !notStandaloneHandler(handlerArg))
         4734  +          && parser->m_notStandaloneHandler
         4735  +          && !parser->m_notStandaloneHandler(parser->m_handlerArg))
  4085   4736           return XML_ERROR_NOT_STANDALONE;
  4086   4737   #ifndef XML_DTD
  4087   4738         break;
  4088   4739   #else /* XML_DTD */
  4089         -      if (!declEntity) {
  4090         -        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
         4740  +      if (!parser->m_declEntity) {
         4741  +        parser->m_declEntity = (ENTITY *)lookup(parser,
         4742  +                                      &dtd->paramEntities,
  4091   4743                                         externalSubsetName,
  4092   4744                                         sizeof(ENTITY));
  4093         -        if (!declEntity)
         4745  +        if (!parser->m_declEntity)
  4094   4746             return XML_ERROR_NO_MEMORY;
  4095         -        declEntity->publicId = NULL;
         4747  +        parser->m_declEntity->publicId = NULL;
  4096   4748         }
  4097   4749         /* fall through */
  4098   4750   #endif /* XML_DTD */
  4099   4751       case XML_ROLE_ENTITY_SYSTEM_ID:
  4100         -      if (dtd->keepProcessing && declEntity) {
  4101         -        declEntity->systemId = poolStoreString(&dtd->pool, enc,
         4752  +      if (dtd->keepProcessing && parser->m_declEntity) {
         4753  +        parser->m_declEntity->systemId = poolStoreString(&dtd->pool, enc,
  4102   4754                                                  s + enc->minBytesPerChar,
  4103   4755                                                  next - enc->minBytesPerChar);
  4104         -        if (!declEntity->systemId)
         4756  +        if (!parser->m_declEntity->systemId)
  4105   4757             return XML_ERROR_NO_MEMORY;
  4106         -        declEntity->base = curBase;
         4758  +        parser->m_declEntity->base = parser->m_curBase;
  4107   4759           poolFinish(&dtd->pool);
  4108         -        if (entityDeclHandler)
         4760  +        /* Don't suppress the default handler if we fell through from
         4761  +         * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
         4762  +         */
         4763  +        if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
  4109   4764             handleDefault = XML_FALSE;
  4110   4765         }
  4111   4766         break;
  4112   4767       case XML_ROLE_ENTITY_COMPLETE:
  4113         -      if (dtd->keepProcessing && declEntity && entityDeclHandler) {
         4768  +      if (dtd->keepProcessing && parser->m_declEntity && parser->m_entityDeclHandler) {
  4114   4769           *eventEndPP = s;
  4115         -        entityDeclHandler(handlerArg,
  4116         -                          declEntity->name,
  4117         -                          declEntity->is_param,
         4770  +        parser->m_entityDeclHandler(parser->m_handlerArg,
         4771  +                          parser->m_declEntity->name,
         4772  +                          parser->m_declEntity->is_param,
  4118   4773                             0,0,
  4119         -                          declEntity->base,
  4120         -                          declEntity->systemId,
  4121         -                          declEntity->publicId,
         4774  +                          parser->m_declEntity->base,
         4775  +                          parser->m_declEntity->systemId,
         4776  +                          parser->m_declEntity->publicId,
  4122   4777                             0);
  4123   4778           handleDefault = XML_FALSE;
  4124   4779         }
  4125   4780         break;
  4126   4781       case XML_ROLE_ENTITY_NOTATION_NAME:
  4127         -      if (dtd->keepProcessing && declEntity) {
  4128         -        declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
  4129         -        if (!declEntity->notation)
         4782  +      if (dtd->keepProcessing && parser->m_declEntity) {
         4783  +        parser->m_declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
         4784  +        if (!parser->m_declEntity->notation)
  4130   4785             return XML_ERROR_NO_MEMORY;
  4131   4786           poolFinish(&dtd->pool);
  4132         -        if (unparsedEntityDeclHandler) {
         4787  +        if (parser->m_unparsedEntityDeclHandler) {
  4133   4788             *eventEndPP = s;
  4134         -          unparsedEntityDeclHandler(handlerArg,
  4135         -                                    declEntity->name,
  4136         -                                    declEntity->base,
  4137         -                                    declEntity->systemId,
  4138         -                                    declEntity->publicId,
  4139         -                                    declEntity->notation);
         4789  +          parser->m_unparsedEntityDeclHandler(parser->m_handlerArg,
         4790  +                                    parser->m_declEntity->name,
         4791  +                                    parser->m_declEntity->base,
         4792  +                                    parser->m_declEntity->systemId,
         4793  +                                    parser->m_declEntity->publicId,
         4794  +                                    parser->m_declEntity->notation);
  4140   4795             handleDefault = XML_FALSE;
  4141   4796           }
  4142         -        else if (entityDeclHandler) {
         4797  +        else if (parser->m_entityDeclHandler) {
  4143   4798             *eventEndPP = s;
  4144         -          entityDeclHandler(handlerArg,
  4145         -                            declEntity->name,
         4799  +          parser->m_entityDeclHandler(parser->m_handlerArg,
         4800  +                            parser->m_declEntity->name,
  4146   4801                               0,0,0,
  4147         -                            declEntity->base,
  4148         -                            declEntity->systemId,
  4149         -                            declEntity->publicId,
  4150         -                            declEntity->notation);
         4802  +                            parser->m_declEntity->base,
         4803  +                            parser->m_declEntity->systemId,
         4804  +                            parser->m_declEntity->publicId,
         4805  +                            parser->m_declEntity->notation);
  4151   4806             handleDefault = XML_FALSE;
  4152   4807           }
  4153   4808         }
  4154   4809         break;
  4155   4810       case XML_ROLE_GENERAL_ENTITY_NAME:
  4156   4811         {
  4157   4812           if (XmlPredefinedEntityName(enc, s, next)) {
  4158         -          declEntity = NULL;
         4813  +          parser->m_declEntity = NULL;
  4159   4814             break;
  4160   4815           }
  4161   4816           if (dtd->keepProcessing) {
  4162   4817             const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
  4163   4818             if (!name)
  4164   4819               return XML_ERROR_NO_MEMORY;
  4165         -          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
         4820  +          parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
  4166   4821                                           sizeof(ENTITY));
  4167         -          if (!declEntity)
         4822  +          if (!parser->m_declEntity)
  4168   4823               return XML_ERROR_NO_MEMORY;
  4169         -          if (declEntity->name != name) {
         4824  +          if (parser->m_declEntity->name != name) {
  4170   4825               poolDiscard(&dtd->pool);
  4171         -            declEntity = NULL;
         4826  +            parser->m_declEntity = NULL;
  4172   4827             }
  4173   4828             else {
  4174   4829               poolFinish(&dtd->pool);
  4175         -            declEntity->publicId = NULL;
  4176         -            declEntity->is_param = XML_FALSE;
         4830  +            parser->m_declEntity->publicId = NULL;
         4831  +            parser->m_declEntity->is_param = XML_FALSE;
  4177   4832               /* if we have a parent parser or are reading an internal parameter
  4178   4833                  entity, then the entity declaration is not considered "internal"
  4179   4834               */
  4180         -            declEntity->is_internal = !(parentParser || openInternalEntities);
  4181         -            if (entityDeclHandler)
         4835  +            parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities);
         4836  +            if (parser->m_entityDeclHandler)
  4182   4837                 handleDefault = XML_FALSE;
  4183   4838             }
  4184   4839           }
  4185   4840           else {
  4186   4841             poolDiscard(&dtd->pool);
  4187         -          declEntity = NULL;
         4842  +          parser->m_declEntity = NULL;
  4188   4843           }
  4189   4844         }
  4190   4845         break;
  4191   4846       case XML_ROLE_PARAM_ENTITY_NAME:
  4192   4847   #ifdef XML_DTD
  4193   4848         if (dtd->keepProcessing) {
  4194   4849           const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
  4195   4850           if (!name)
  4196   4851             return XML_ERROR_NO_MEMORY;
  4197         -        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
         4852  +        parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
  4198   4853                                              name, sizeof(ENTITY));
  4199         -        if (!declEntity)
         4854  +        if (!parser->m_declEntity)
  4200   4855             return XML_ERROR_NO_MEMORY;
  4201         -        if (declEntity->name != name) {
         4856  +        if (parser->m_declEntity->name != name) {
  4202   4857             poolDiscard(&dtd->pool);
  4203         -          declEntity = NULL;
         4858  +          parser->m_declEntity = NULL;
  4204   4859           }
  4205   4860           else {
  4206   4861             poolFinish(&dtd->pool);
  4207         -          declEntity->publicId = NULL;
  4208         -          declEntity->is_param = XML_TRUE;
         4862  +          parser->m_declEntity->publicId = NULL;
         4863  +          parser->m_declEntity->is_param = XML_TRUE;
  4209   4864             /* if we have a parent parser or are reading an internal parameter
  4210   4865                entity, then the entity declaration is not considered "internal"
  4211   4866             */
  4212         -          declEntity->is_internal = !(parentParser || openInternalEntities);
  4213         -          if (entityDeclHandler)
         4867  +          parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities);
         4868  +          if (parser->m_entityDeclHandler)
  4214   4869               handleDefault = XML_FALSE;
  4215   4870           }
  4216   4871         }
  4217   4872         else {
  4218   4873           poolDiscard(&dtd->pool);
  4219         -        declEntity = NULL;
         4874  +        parser->m_declEntity = NULL;
  4220   4875         }
  4221   4876   #else /* not XML_DTD */
  4222         -      declEntity = NULL;
         4877  +      parser->m_declEntity = NULL;
  4223   4878   #endif /* XML_DTD */
  4224   4879         break;
  4225   4880       case XML_ROLE_NOTATION_NAME:
  4226         -      declNotationPublicId = NULL;
  4227         -      declNotationName = NULL;
  4228         -      if (notationDeclHandler) {
  4229         -        declNotationName = poolStoreString(&tempPool, enc, s, next);
  4230         -        if (!declNotationName)
         4881  +      parser->m_declNotationPublicId = NULL;
         4882  +      parser->m_declNotationName = NULL;
         4883  +      if (parser->m_notationDeclHandler) {
         4884  +        parser->m_declNotationName = poolStoreString(&parser->m_tempPool, enc, s, next);
         4885  +        if (!parser->m_declNotationName)
  4231   4886             return XML_ERROR_NO_MEMORY;
  4232         -        poolFinish(&tempPool);
         4887  +        poolFinish(&parser->m_tempPool);
  4233   4888           handleDefault = XML_FALSE;
  4234   4889         }
  4235   4890         break;
  4236   4891       case XML_ROLE_NOTATION_PUBLIC_ID:
  4237   4892         if (!XmlIsPublicId(enc, s, next, eventPP))
  4238   4893           return XML_ERROR_PUBLICID;
  4239         -      if (declNotationName) {  /* means notationDeclHandler != NULL */
  4240         -        XML_Char *tem = poolStoreString(&tempPool,
         4894  +      if (parser->m_declNotationName) {  /* means m_notationDeclHandler != NULL */
         4895  +        XML_Char *tem = poolStoreString(&parser->m_tempPool,
  4241   4896                                           enc,
  4242   4897                                           s + enc->minBytesPerChar,
  4243   4898                                           next - enc->minBytesPerChar);
  4244   4899           if (!tem)
  4245   4900             return XML_ERROR_NO_MEMORY;
  4246   4901           normalizePublicId(tem);
  4247         -        declNotationPublicId = tem;
  4248         -        poolFinish(&tempPool);
         4902  +        parser->m_declNotationPublicId = tem;
         4903  +        poolFinish(&parser->m_tempPool);
  4249   4904           handleDefault = XML_FALSE;
  4250   4905         }
  4251   4906         break;
  4252   4907       case XML_ROLE_NOTATION_SYSTEM_ID:
  4253         -      if (declNotationName && notationDeclHandler) {
         4908  +      if (parser->m_declNotationName && parser->m_notationDeclHandler) {
  4254   4909           const XML_Char *systemId
  4255         -          = poolStoreString(&tempPool, enc,
         4910  +          = poolStoreString(&parser->m_tempPool, enc,
  4256   4911                               s + enc->minBytesPerChar,
  4257   4912                               next - enc->minBytesPerChar);
  4258   4913           if (!systemId)
  4259   4914             return XML_ERROR_NO_MEMORY;
  4260   4915           *eventEndPP = s;
  4261         -        notationDeclHandler(handlerArg,
  4262         -                            declNotationName,
  4263         -                            curBase,
         4916  +        parser->m_notationDeclHandler(parser->m_handlerArg,
         4917  +                            parser->m_declNotationName,
         4918  +                            parser->m_curBase,
  4264   4919                               systemId,
  4265         -                            declNotationPublicId);
         4920  +                            parser->m_declNotationPublicId);
  4266   4921           handleDefault = XML_FALSE;
  4267   4922         }
  4268         -      poolClear(&tempPool);
         4923  +      poolClear(&parser->m_tempPool);
  4269   4924         break;
  4270   4925       case XML_ROLE_NOTATION_NO_SYSTEM_ID:
  4271         -      if (declNotationPublicId && notationDeclHandler) {
         4926  +      if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
  4272   4927           *eventEndPP = s;
  4273         -        notationDeclHandler(handlerArg,
  4274         -                            declNotationName,
  4275         -                            curBase,
         4928  +        parser->m_notationDeclHandler(parser->m_handlerArg,
         4929  +                            parser->m_declNotationName,
         4930  +                            parser->m_curBase,
  4276   4931                               0,
  4277         -                            declNotationPublicId);
         4932  +                            parser->m_declNotationPublicId);
  4278   4933           handleDefault = XML_FALSE;
  4279   4934         }
  4280         -      poolClear(&tempPool);
         4935  +      poolClear(&parser->m_tempPool);
  4281   4936         break;
  4282   4937       case XML_ROLE_ERROR:
  4283   4938         switch (tok) {
  4284   4939         case XML_TOK_PARAM_ENTITY_REF:
  4285   4940           /* PE references in internal subset are
  4286         -           not allowed within declarations. */  
         4941  +           not allowed within declarations. */
  4287   4942           return XML_ERROR_PARAM_ENTITY_REF;
  4288   4943         case XML_TOK_XML_DECL:
  4289   4944           return XML_ERROR_MISPLACED_XML_PI;
  4290   4945         default:
  4291   4946           return XML_ERROR_SYNTAX;
  4292   4947         }
  4293   4948   #ifdef XML_DTD
  4294   4949       case XML_ROLE_IGNORE_SECT:
  4295   4950         {
  4296   4951           enum XML_Error result;
  4297         -        if (defaultHandler)
         4952  +        if (parser->m_defaultHandler)
  4298   4953             reportDefault(parser, enc, s, next);
  4299   4954           handleDefault = XML_FALSE;
  4300   4955           result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
  4301   4956           if (result != XML_ERROR_NONE)
  4302   4957             return result;
  4303   4958           else if (!next) {
  4304         -          processor = ignoreSectionProcessor;
         4959  +          parser->m_processor = ignoreSectionProcessor;
  4305   4960             return result;
  4306   4961           }
  4307   4962         }
  4308   4963         break;
  4309   4964   #endif /* XML_DTD */
  4310   4965       case XML_ROLE_GROUP_OPEN:
  4311         -      if (prologState.level >= groupSize) {
  4312         -        if (groupSize) {
  4313         -          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
  4314         -          if (temp == NULL)
         4966  +      if (parser->m_prologState.level >= parser->m_groupSize) {
         4967  +        if (parser->m_groupSize) {
         4968  +          char *temp = (char *)REALLOC(parser, parser->m_groupConnector, parser->m_groupSize *= 2);
         4969  +          if (temp == NULL) {
         4970  +            parser->m_groupSize /= 2;
  4315   4971               return XML_ERROR_NO_MEMORY;
  4316         -          groupConnector = temp;
         4972  +          }
         4973  +          parser->m_groupConnector = temp;
  4317   4974             if (dtd->scaffIndex) {
  4318         -            int *temp = (int *)REALLOC(dtd->scaffIndex,
  4319         -                          groupSize * sizeof(int));
         4975  +            int *temp = (int *)REALLOC(parser, dtd->scaffIndex,
         4976  +                          parser->m_groupSize * sizeof(int));
  4320   4977               if (temp == NULL)
  4321   4978                 return XML_ERROR_NO_MEMORY;
  4322   4979               dtd->scaffIndex = temp;
  4323   4980             }
  4324   4981           }
  4325   4982           else {
  4326         -          groupConnector = (char *)MALLOC(groupSize = 32);
  4327         -          if (!groupConnector)
         4983  +          parser->m_groupConnector = (char *)MALLOC(parser, parser->m_groupSize = 32);
         4984  +          if (!parser->m_groupConnector) {
         4985  +            parser->m_groupSize = 0;
  4328   4986               return XML_ERROR_NO_MEMORY;
         4987  +          }
  4329   4988           }
  4330   4989         }
  4331         -      groupConnector[prologState.level] = 0;
         4990  +      parser->m_groupConnector[parser->m_prologState.level] = 0;
  4332   4991         if (dtd->in_eldecl) {
  4333   4992           int myindex = nextScaffoldPart(parser);
  4334   4993           if (myindex < 0)
  4335   4994             return XML_ERROR_NO_MEMORY;
  4336   4995           dtd->scaffIndex[dtd->scaffLevel] = myindex;
  4337   4996           dtd->scaffLevel++;
  4338   4997           dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
  4339         -        if (elementDeclHandler)
         4998  +        if (parser->m_elementDeclHandler)
  4340   4999             handleDefault = XML_FALSE;
  4341   5000         }
  4342   5001         break;
  4343   5002       case XML_ROLE_GROUP_SEQUENCE:
  4344         -      if (groupConnector[prologState.level] == ASCII_PIPE)
         5003  +      if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
  4345   5004           return XML_ERROR_SYNTAX;
  4346         -      groupConnector[prologState.level] = ASCII_COMMA;
  4347         -      if (dtd->in_eldecl && elementDeclHandler)
         5005  +      parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
         5006  +      if (dtd->in_eldecl && parser->m_elementDeclHandler)
  4348   5007           handleDefault = XML_FALSE;
  4349   5008         break;
  4350   5009       case XML_ROLE_GROUP_CHOICE:
  4351         -      if (groupConnector[prologState.level] == ASCII_COMMA)
         5010  +      if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
  4352   5011           return XML_ERROR_SYNTAX;
  4353   5012         if (dtd->in_eldecl
  4354         -          && !groupConnector[prologState.level]
         5013  +          && !parser->m_groupConnector[parser->m_prologState.level]
  4355   5014             && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
  4356   5015                 != XML_CTYPE_MIXED)
  4357   5016             ) {
  4358   5017           dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
  4359   5018               = XML_CTYPE_CHOICE;
  4360         -        if (elementDeclHandler)
         5019  +        if (parser->m_elementDeclHandler)
  4361   5020             handleDefault = XML_FALSE;
  4362   5021         }
  4363         -      groupConnector[prologState.level] = ASCII_PIPE;
         5022  +      parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
  4364   5023         break;
  4365   5024       case XML_ROLE_PARAM_ENTITY_REF:
  4366   5025   #ifdef XML_DTD
  4367   5026       case XML_ROLE_INNER_PARAM_ENTITY_REF:
  4368   5027         dtd->hasParamEntityRefs = XML_TRUE;
  4369         -      if (!paramEntityParsing)
         5028  +      if (!parser->m_paramEntityParsing)
  4370   5029           dtd->keepProcessing = dtd->standalone;
  4371   5030         else {
  4372   5031           const XML_Char *name;
  4373   5032           ENTITY *entity;
  4374   5033           name = poolStoreString(&dtd->pool, enc,
  4375   5034                                   s + enc->minBytesPerChar,
  4376   5035                                   next - enc->minBytesPerChar);
  4377   5036           if (!name)
  4378   5037             return XML_ERROR_NO_MEMORY;
  4379         -        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
         5038  +        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
  4380   5039           poolDiscard(&dtd->pool);
  4381   5040           /* first, determine if a check for an existing declaration is needed;
  4382   5041              if yes, check that the entity exists, and that it is internal,
  4383   5042              otherwise call the skipped entity handler
  4384   5043           */
  4385         -        if (prologState.documentEntity &&
         5044  +        if (parser->m_prologState.documentEntity &&
  4386   5045               (dtd->standalone
  4387         -             ? !openInternalEntities
         5046  +             ? !parser->m_openInternalEntities
  4388   5047                : !dtd->hasParamEntityRefs)) {
  4389   5048             if (!entity)
  4390   5049               return XML_ERROR_UNDEFINED_ENTITY;
  4391         -          else if (!entity->is_internal)
  4392         -            return XML_ERROR_ENTITY_DECLARED_IN_PE;
         5050  +          else if (!entity->is_internal) {
         5051  +            /* It's hard to exhaustively search the code to be sure,
         5052  +             * but there doesn't seem to be a way of executing the
         5053  +             * following line.  There are two cases:
         5054  +             *
         5055  +             * If 'standalone' is false, the DTD must have no
         5056  +             * parameter entities or we wouldn't have passed the outer
         5057  +             * 'if' statement.  That measn the only entity in the hash
         5058  +             * table is the external subset name "#" which cannot be
         5059  +             * given as a parameter entity name in XML syntax, so the
         5060  +             * lookup must have returned NULL and we don't even reach
         5061  +             * the test for an internal entity.
         5062  +             *
         5063  +             * If 'standalone' is true, it does not seem to be
         5064  +             * possible to create entities taking this code path that
         5065  +             * are not internal entities, so fail the test above.
         5066  +             *
         5067  +             * Because this analysis is very uncertain, the code is
         5068  +             * being left in place and merely removed from the
         5069  +             * coverage test statistics.
         5070  +             */
         5071  +            return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
         5072  +          }
  4393   5073           }
  4394   5074           else if (!entity) {
  4395   5075             dtd->keepProcessing = dtd->standalone;
  4396   5076             /* cannot report skipped entities in declarations */
  4397         -          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
  4398         -            skippedEntityHandler(handlerArg, name, 1);
         5077  +          if ((role == XML_ROLE_PARAM_ENTITY_REF) && parser->m_skippedEntityHandler) {
         5078  +            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
  4399   5079               handleDefault = XML_FALSE;
  4400   5080             }
  4401   5081             break;
  4402   5082           }
  4403   5083           if (entity->open)
  4404   5084             return XML_ERROR_RECURSIVE_ENTITY_REF;
  4405   5085           if (entity->textPtr) {
  4406   5086             enum XML_Error result;
  4407         -          XML_Bool betweenDecl = 
         5087  +          XML_Bool betweenDecl =
  4408   5088               (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
  4409   5089             result = processInternalEntity(parser, entity, betweenDecl);
  4410   5090             if (result != XML_ERROR_NONE)
  4411   5091               return result;
  4412   5092             handleDefault = XML_FALSE;
  4413   5093             break;
  4414   5094           }
  4415         -        if (externalEntityRefHandler) {
         5095  +        if (parser->m_externalEntityRefHandler) {
  4416   5096             dtd->paramEntityRead = XML_FALSE;
  4417   5097             entity->open = XML_TRUE;
  4418         -          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
         5098  +          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
  4419   5099                                           0,
  4420   5100                                           entity->base,
  4421   5101                                           entity->systemId,
  4422   5102                                           entity->publicId)) {
  4423   5103               entity->open = XML_FALSE;
  4424   5104               return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  4425   5105             }
................................................................................
  4433   5113           else {
  4434   5114             dtd->keepProcessing = dtd->standalone;
  4435   5115             break;
  4436   5116           }
  4437   5117         }
  4438   5118   #endif /* XML_DTD */
  4439   5119         if (!dtd->standalone &&
  4440         -          notStandaloneHandler &&
  4441         -          !notStandaloneHandler(handlerArg))
         5120  +          parser->m_notStandaloneHandler &&
         5121  +          !parser->m_notStandaloneHandler(parser->m_handlerArg))
  4442   5122           return XML_ERROR_NOT_STANDALONE;
  4443   5123         break;
  4444   5124   
  4445   5125       /* Element declaration stuff */
  4446   5126   
  4447   5127       case XML_ROLE_ELEMENT_NAME:
  4448         -      if (elementDeclHandler) {
  4449         -        declElementType = getElementType(parser, enc, s, next);
  4450         -        if (!declElementType)
         5128  +      if (parser->m_elementDeclHandler) {
         5129  +        parser->m_declElementType = getElementType(parser, enc, s, next);
         5130  +        if (!parser->m_declElementType)
  4451   5131             return XML_ERROR_NO_MEMORY;
  4452   5132           dtd->scaffLevel = 0;
  4453   5133           dtd->scaffCount = 0;
  4454   5134           dtd->in_eldecl = XML_TRUE;
  4455   5135           handleDefault = XML_FALSE;
  4456   5136         }
  4457   5137         break;
  4458   5138   
  4459   5139       case XML_ROLE_CONTENT_ANY:
  4460   5140       case XML_ROLE_CONTENT_EMPTY:
  4461   5141         if (dtd->in_eldecl) {
  4462         -        if (elementDeclHandler) {
  4463         -          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
         5142  +        if (parser->m_elementDeclHandler) {
         5143  +          XML_Content * content = (XML_Content *) MALLOC(parser, sizeof(XML_Content));
  4464   5144             if (!content)
  4465   5145               return XML_ERROR_NO_MEMORY;
  4466   5146             content->quant = XML_CQUANT_NONE;
  4467   5147             content->name = NULL;
  4468   5148             content->numchildren = 0;
  4469   5149             content->children = NULL;
  4470   5150             content->type = ((role == XML_ROLE_CONTENT_ANY) ?
  4471   5151                              XML_CTYPE_ANY :
  4472   5152                              XML_CTYPE_EMPTY);
  4473   5153             *eventEndPP = s;
  4474         -          elementDeclHandler(handlerArg, declElementType->name, content);
         5154  +          parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, content);
  4475   5155             handleDefault = XML_FALSE;
  4476   5156           }
  4477   5157           dtd->in_eldecl = XML_FALSE;
  4478   5158         }
  4479   5159         break;
  4480   5160   
  4481   5161       case XML_ROLE_CONTENT_PCDATA:
  4482   5162         if (dtd->in_eldecl) {
  4483   5163           dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
  4484   5164               = XML_CTYPE_MIXED;
  4485         -        if (elementDeclHandler)
         5165  +        if (parser->m_elementDeclHandler)
  4486   5166             handleDefault = XML_FALSE;
  4487   5167         }
  4488   5168         break;
  4489   5169   
  4490   5170       case XML_ROLE_CONTENT_ELEMENT:
  4491   5171         quant = XML_CQUANT_NONE;
  4492   5172         goto elementContent;
................................................................................
  4515   5195           if (!el)
  4516   5196             return XML_ERROR_NO_MEMORY;
  4517   5197           name = el->name;
  4518   5198           dtd->scaffold[myindex].name = name;
  4519   5199           nameLen = 0;
  4520   5200           for (; name[nameLen++]; );
  4521   5201           dtd->contentStringLen +=  nameLen;
  4522         -        if (elementDeclHandler)
         5202  +        if (parser->m_elementDeclHandler)
  4523   5203             handleDefault = XML_FALSE;
  4524   5204         }
  4525   5205         break;
  4526   5206   
  4527   5207       case XML_ROLE_GROUP_CLOSE:
  4528   5208         quant = XML_CQUANT_NONE;
  4529   5209         goto closeGroup;
................................................................................
  4533   5213       case XML_ROLE_GROUP_CLOSE_REP:
  4534   5214         quant = XML_CQUANT_REP;
  4535   5215         goto closeGroup;
  4536   5216       case XML_ROLE_GROUP_CLOSE_PLUS:
  4537   5217         quant = XML_CQUANT_PLUS;
  4538   5218       closeGroup:
  4539   5219         if (dtd->in_eldecl) {
  4540         -        if (elementDeclHandler)
         5220  +        if (parser->m_elementDeclHandler)
  4541   5221             handleDefault = XML_FALSE;
  4542   5222           dtd->scaffLevel--;
  4543   5223           dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
  4544   5224           if (dtd->scaffLevel == 0) {
  4545   5225             if (!handleDefault) {
  4546   5226               XML_Content *model = build_model(parser);
  4547   5227               if (!model)
  4548   5228                 return XML_ERROR_NO_MEMORY;
  4549   5229               *eventEndPP = s;
  4550         -            elementDeclHandler(handlerArg, declElementType->name, model);
         5230  +            parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, model);
  4551   5231             }
  4552   5232             dtd->in_eldecl = XML_FALSE;
  4553   5233             dtd->contentStringLen = 0;
  4554   5234           }
  4555   5235         }
  4556   5236         break;
  4557   5237         /* End element declaration stuff */
................................................................................
  4570   5250         switch (tok) {
  4571   5251         case XML_TOK_BOM:
  4572   5252           handleDefault = XML_FALSE;
  4573   5253           break;
  4574   5254         }
  4575   5255         break;
  4576   5256       case XML_ROLE_DOCTYPE_NONE:
  4577         -      if (startDoctypeDeclHandler)
         5257  +      if (parser->m_startDoctypeDeclHandler)
  4578   5258           handleDefault = XML_FALSE;
  4579   5259         break;
  4580   5260       case XML_ROLE_ENTITY_NONE:
  4581         -      if (dtd->keepProcessing && entityDeclHandler)
         5261  +      if (dtd->keepProcessing && parser->m_entityDeclHandler)
  4582   5262           handleDefault = XML_FALSE;
  4583   5263         break;
  4584   5264       case XML_ROLE_NOTATION_NONE:
  4585         -      if (notationDeclHandler)
         5265  +      if (parser->m_notationDeclHandler)
  4586   5266           handleDefault = XML_FALSE;
  4587   5267         break;
  4588   5268       case XML_ROLE_ATTLIST_NONE:
  4589         -      if (dtd->keepProcessing && attlistDeclHandler)
         5269  +      if (dtd->keepProcessing && parser->m_attlistDeclHandler)
  4590   5270           handleDefault = XML_FALSE;
  4591   5271         break;
  4592   5272       case XML_ROLE_ELEMENT_NONE:
  4593         -      if (elementDeclHandler)
         5273  +      if (parser->m_elementDeclHandler)
  4594   5274           handleDefault = XML_FALSE;
  4595   5275         break;
  4596   5276       } /* end of big switch */
  4597   5277   
  4598         -    if (handleDefault && defaultHandler)
         5278  +    if (handleDefault && parser->m_defaultHandler)
  4599   5279         reportDefault(parser, enc, s, next);
  4600   5280   
  4601         -    switch (ps_parsing) {
  4602         -    case XML_SUSPENDED: 
         5281  +    switch (parser->m_parsingStatus.parsing) {
         5282  +    case XML_SUSPENDED:
  4603   5283         *nextPtr = next;
  4604   5284         return XML_ERROR_NONE;
  4605   5285       case XML_FINISHED:
  4606   5286         return XML_ERROR_ABORTED;
  4607   5287       default:
  4608   5288         s = next;
  4609   5289         tok = XmlPrologTok(enc, s, end, &next);
................................................................................
  4614   5294   
  4615   5295   static enum XML_Error PTRCALL
  4616   5296   epilogProcessor(XML_Parser parser,
  4617   5297                   const char *s,
  4618   5298                   const char *end,
  4619   5299                   const char **nextPtr)
  4620   5300   {
  4621         -  processor = epilogProcessor;
  4622         -  eventPtr = s;
         5301  +  parser->m_processor = epilogProcessor;
         5302  +  parser->m_eventPtr = s;
  4623   5303     for (;;) {
  4624   5304       const char *next = NULL;
  4625         -    int tok = XmlPrologTok(encoding, s, end, &next);
  4626         -    eventEndPtr = next;
         5305  +    int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
         5306  +    parser->m_eventEndPtr = next;
  4627   5307       switch (tok) {
  4628   5308       /* report partial linebreak - it might be the last token */
  4629   5309       case -XML_TOK_PROLOG_S:
  4630         -      if (defaultHandler) {
  4631         -        reportDefault(parser, encoding, s, next);
  4632         -        if (ps_parsing == XML_FINISHED)
         5310  +      if (parser->m_defaultHandler) {
         5311  +        reportDefault(parser, parser->m_encoding, s, next);
         5312  +        if (parser->m_parsingStatus.parsing == XML_FINISHED)
  4633   5313             return XML_ERROR_ABORTED;
  4634   5314         }
  4635   5315         *nextPtr = next;
  4636   5316         return XML_ERROR_NONE;
  4637   5317       case XML_TOK_NONE:
  4638   5318         *nextPtr = s;
  4639   5319         return XML_ERROR_NONE;
  4640   5320       case XML_TOK_PROLOG_S:
  4641         -      if (defaultHandler)
  4642         -        reportDefault(parser, encoding, s, next);
         5321  +      if (parser->m_defaultHandler)
         5322  +        reportDefault(parser, parser->m_encoding, s, next);
  4643   5323         break;
  4644   5324       case XML_TOK_PI:
  4645         -      if (!reportProcessingInstruction(parser, encoding, s, next))
         5325  +      if (!reportProcessingInstruction(parser, parser->m_encoding, s, next))
  4646   5326           return XML_ERROR_NO_MEMORY;
  4647   5327         break;
  4648   5328       case XML_TOK_COMMENT:
  4649         -      if (!reportComment(parser, encoding, s, next))
         5329  +      if (!reportComment(parser, parser->m_encoding, s, next))
  4650   5330           return XML_ERROR_NO_MEMORY;
  4651   5331         break;
  4652   5332       case XML_TOK_INVALID:
  4653         -      eventPtr = next;
         5333  +      parser->m_eventPtr = next;
  4654   5334         return XML_ERROR_INVALID_TOKEN;
  4655   5335       case XML_TOK_PARTIAL:
  4656         -      if (!ps_finalBuffer) {
         5336  +      if (!parser->m_parsingStatus.finalBuffer) {
  4657   5337           *nextPtr = s;
  4658   5338           return XML_ERROR_NONE;
  4659   5339         }
  4660   5340         return XML_ERROR_UNCLOSED_TOKEN;
  4661   5341       case XML_TOK_PARTIAL_CHAR:
  4662         -      if (!ps_finalBuffer) {
         5342  +      if (!parser->m_parsingStatus.finalBuffer) {
  4663   5343           *nextPtr = s;
  4664   5344           return XML_ERROR_NONE;
  4665   5345         }
  4666   5346         return XML_ERROR_PARTIAL_CHAR;
  4667   5347       default:
  4668   5348         return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
  4669   5349       }
  4670         -    eventPtr = s = next;
  4671         -    switch (ps_parsing) {
  4672         -    case XML_SUSPENDED: 
         5350  +    parser->m_eventPtr = s = next;
         5351  +    switch (parser->m_parsingStatus.parsing) {
         5352  +    case XML_SUSPENDED:
  4673   5353         *nextPtr = next;
  4674   5354         return XML_ERROR_NONE;
  4675   5355       case XML_FINISHED:
  4676   5356         return XML_ERROR_ABORTED;
  4677   5357       default: ;
  4678   5358       }
  4679   5359     }
................................................................................
  4684   5364                         XML_Bool betweenDecl)
  4685   5365   {
  4686   5366     const char *textStart, *textEnd;
  4687   5367     const char *next;
  4688   5368     enum XML_Error result;
  4689   5369     OPEN_INTERNAL_ENTITY *openEntity;
  4690   5370   
  4691         -  if (freeInternalEntities) {
  4692         -    openEntity = freeInternalEntities;
  4693         -    freeInternalEntities = openEntity->next;
         5371  +  if (parser->m_freeInternalEntities) {
         5372  +    openEntity = parser->m_freeInternalEntities;
         5373  +    parser->m_freeInternalEntities = openEntity->next;
  4694   5374     }
  4695   5375     else {
  4696         -    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
         5376  +    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
  4697   5377       if (!openEntity)
  4698   5378         return XML_ERROR_NO_MEMORY;
  4699   5379     }
  4700   5380     entity->open = XML_TRUE;
  4701   5381     entity->processed = 0;
  4702         -  openEntity->next = openInternalEntities;
  4703         -  openInternalEntities = openEntity;
         5382  +  openEntity->next = parser->m_openInternalEntities;
         5383  +  parser->m_openInternalEntities = openEntity;
  4704   5384     openEntity->entity = entity;
  4705         -  openEntity->startTagLevel = tagLevel;
         5385  +  openEntity->startTagLevel = parser->m_tagLevel;
  4706   5386     openEntity->betweenDecl = betweenDecl;
  4707   5387     openEntity->internalEventPtr = NULL;
  4708   5388     openEntity->internalEventEndPtr = NULL;
  4709   5389     textStart = (char *)entity->textPtr;
  4710   5390     textEnd = (char *)(entity->textPtr + entity->textLen);
         5391  +  /* Set a safe default value in case 'next' does not get set */
         5392  +  next = textStart;
  4711   5393   
  4712   5394   #ifdef XML_DTD
  4713   5395     if (entity->is_param) {
  4714         -    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
  4715         -    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
         5396  +    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
         5397  +    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
  4716   5398                         next, &next, XML_FALSE);
  4717   5399     }
  4718         -  else 
         5400  +  else
  4719   5401   #endif /* XML_DTD */
  4720         -    result = doContent(parser, tagLevel, internalEncoding, textStart, 
         5402  +    result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, textStart,
  4721   5403                          textEnd, &next, XML_FALSE);
  4722   5404   
  4723   5405     if (result == XML_ERROR_NONE) {
  4724         -    if (textEnd != next && ps_parsing == XML_SUSPENDED) {
         5406  +    if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
  4725   5407         entity->processed = (int)(next - textStart);
  4726         -      processor = internalEntityProcessor;
         5408  +      parser->m_processor = internalEntityProcessor;
  4727   5409       }
  4728   5410       else {
  4729   5411         entity->open = XML_FALSE;
  4730         -      openInternalEntities = openEntity->next;
         5412  +      parser->m_openInternalEntities = openEntity->next;
  4731   5413         /* put openEntity back in list of free instances */
  4732         -      openEntity->next = freeInternalEntities;
  4733         -      freeInternalEntities = openEntity;
         5414  +      openEntity->next = parser->m_freeInternalEntities;
         5415  +      parser->m_freeInternalEntities = openEntity;
  4734   5416       }
  4735   5417     }
  4736   5418     return result;
  4737   5419   }
  4738   5420   
  4739   5421   static enum XML_Error PTRCALL
  4740   5422   internalEntityProcessor(XML_Parser parser,
................................................................................
  4742   5424                           const char *end,
  4743   5425                           const char **nextPtr)
  4744   5426   {
  4745   5427     ENTITY *entity;
  4746   5428     const char *textStart, *textEnd;
  4747   5429     const char *next;
  4748   5430     enum XML_Error result;
  4749         -  OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
         5431  +  OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
  4750   5432     if (!openEntity)
  4751   5433       return XML_ERROR_UNEXPECTED_STATE;
  4752   5434   
  4753   5435     entity = openEntity->entity;
  4754   5436     textStart = ((char *)entity->textPtr) + entity->processed;
  4755   5437     textEnd = (char *)(entity->textPtr + entity->textLen);
         5438  +  /* Set a safe default value in case 'next' does not get set */
         5439  +  next = textStart;
  4756   5440   
  4757   5441   #ifdef XML_DTD
  4758   5442     if (entity->is_param) {
  4759         -    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
  4760         -    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
         5443  +    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
         5444  +    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
  4761   5445                         next, &next, XML_FALSE);
  4762   5446     }
  4763   5447     else
  4764   5448   #endif /* XML_DTD */
  4765         -    result = doContent(parser, openEntity->startTagLevel, internalEncoding, 
  4766         -                       textStart, textEnd, &next, XML_FALSE);  
         5449  +    result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding,
         5450  +                       textStart, textEnd, &next, XML_FALSE);
  4767   5451   
  4768   5452     if (result != XML_ERROR_NONE)
  4769   5453       return result;
  4770         -  else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
         5454  +  else if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
  4771   5455       entity->processed = (int)(next - (char *)entity->textPtr);
  4772   5456       return result;
  4773   5457     }
  4774   5458     else {
  4775   5459       entity->open = XML_FALSE;
  4776         -    openInternalEntities = openEntity->next;
         5460  +    parser->m_openInternalEntities = openEntity->next;
  4777   5461       /* put openEntity back in list of free instances */
  4778         -    openEntity->next = freeInternalEntities;
  4779         -    freeInternalEntities = openEntity;
         5462  +    openEntity->next = parser->m_freeInternalEntities;
         5463  +    parser->m_freeInternalEntities = openEntity;
  4780   5464     }
  4781   5465   
  4782   5466   #ifdef XML_DTD
  4783   5467     if (entity->is_param) {
  4784   5468       int tok;
  4785         -    processor = prologProcessor;
  4786         -    tok = XmlPrologTok(encoding, s, end, &next);
  4787         -    return doProlog(parser, encoding, s, end, tok, next, nextPtr, 
  4788         -                    (XML_Bool)!ps_finalBuffer);
         5469  +    parser->m_processor = prologProcessor;
         5470  +    tok = XmlPrologTok(parser->m_encoding, s, end, &next);
         5471  +    return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
         5472  +                    (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  4789   5473     }
  4790   5474     else
  4791   5475   #endif /* XML_DTD */
  4792   5476     {
  4793         -    processor = contentProcessor;
         5477  +    parser->m_processor = contentProcessor;
  4794   5478       /* see externalEntityContentProcessor vs contentProcessor */
  4795         -    return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
  4796         -                     nextPtr, (XML_Bool)!ps_finalBuffer); 
  4797         -  }  
         5479  +    return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, s, end,
         5480  +                     nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
         5481  +  }
  4798   5482   }
  4799   5483   
  4800   5484   static enum XML_Error PTRCALL
  4801   5485   errorProcessor(XML_Parser parser,
  4802         -               const char *s,
  4803         -               const char *end,
  4804         -               const char **nextPtr)
         5486  +               const char *UNUSED_P(s),
         5487  +               const char *UNUSED_P(end),
         5488  +               const char **UNUSED_P(nextPtr))
  4805   5489   {
  4806         -  return errorCode;
         5490  +  return parser->m_errorCode;
  4807   5491   }
  4808   5492   
  4809   5493   static enum XML_Error
  4810   5494   storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
  4811   5495                       const char *ptr, const char *end,
  4812   5496                       STRING_POOL *pool)
  4813   5497   {
................................................................................
  4823   5507   }
  4824   5508   
  4825   5509   static enum XML_Error
  4826   5510   appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
  4827   5511                        const char *ptr, const char *end,
  4828   5512                        STRING_POOL *pool)
  4829   5513   {
  4830         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         5514  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  4831   5515     for (;;) {
  4832   5516       const char *next;
  4833   5517       int tok = XmlAttributeValueTok(enc, ptr, end, &next);
  4834   5518       switch (tok) {
  4835   5519       case XML_TOK_NONE:
  4836   5520         return XML_ERROR_NONE;
  4837   5521       case XML_TOK_INVALID:
  4838         -      if (enc == encoding)
  4839         -        eventPtr = next;
         5522  +      if (enc == parser->m_encoding)
         5523  +        parser->m_eventPtr = next;
  4840   5524         return XML_ERROR_INVALID_TOKEN;
  4841   5525       case XML_TOK_PARTIAL:
  4842         -      if (enc == encoding)
  4843         -        eventPtr = ptr;
         5526  +      if (enc == parser->m_encoding)
         5527  +        parser->m_eventPtr = ptr;
  4844   5528         return XML_ERROR_INVALID_TOKEN;
  4845   5529       case XML_TOK_CHAR_REF:
  4846   5530         {
  4847   5531           XML_Char buf[XML_ENCODE_MAX];
  4848   5532           int i;
  4849   5533           int n = XmlCharRefNumber(enc, ptr);
  4850   5534           if (n < 0) {
  4851         -          if (enc == encoding)
  4852         -            eventPtr = ptr;
         5535  +          if (enc == parser->m_encoding)
         5536  +            parser->m_eventPtr = ptr;
  4853   5537             return XML_ERROR_BAD_CHAR_REF;
  4854   5538           }
  4855   5539           if (!isCdata
  4856   5540               && n == 0x20 /* space */
  4857   5541               && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
  4858   5542             break;
  4859   5543           n = XmlEncode(n, (ICHAR *)buf);
  4860         -        if (!n) {
  4861         -          if (enc == encoding)
  4862         -            eventPtr = ptr;
  4863         -          return XML_ERROR_BAD_CHAR_REF;
  4864         -        }
         5544  +        /* The XmlEncode() functions can never return 0 here.  That
         5545  +         * error return happens if the code point passed in is either
         5546  +         * negative or greater than or equal to 0x110000.  The
         5547  +         * XmlCharRefNumber() functions will all return a number
         5548  +         * strictly less than 0x110000 or a negative value if an error
         5549  +         * occurred.  The negative value is intercepted above, so
         5550  +         * XmlEncode() is never passed a value it might return an
         5551  +         * error for.
         5552  +         */
  4865   5553           for (i = 0; i < n; i++) {
  4866   5554             if (!poolAppendChar(pool, buf[i]))
  4867   5555               return XML_ERROR_NO_MEMORY;
  4868   5556           }
  4869   5557         }
  4870   5558         break;
  4871   5559       case XML_TOK_DATA_CHARS:
................................................................................
  4891   5579                                                 ptr + enc->minBytesPerChar,
  4892   5580                                                 next - enc->minBytesPerChar);
  4893   5581           if (ch) {
  4894   5582             if (!poolAppendChar(pool, ch))
  4895   5583                   return XML_ERROR_NO_MEMORY;
  4896   5584             break;
  4897   5585           }
  4898         -        name = poolStoreString(&temp2Pool, enc,
         5586  +        name = poolStoreString(&parser->m_temp2Pool, enc,
  4899   5587                                  ptr + enc->minBytesPerChar,
  4900   5588                                  next - enc->minBytesPerChar);
  4901   5589           if (!name)
  4902   5590             return XML_ERROR_NO_MEMORY;
  4903         -        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
  4904         -        poolDiscard(&temp2Pool);
         5591  +        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
         5592  +        poolDiscard(&parser->m_temp2Pool);
  4905   5593           /* First, determine if a check for an existing declaration is needed;
  4906   5594              if yes, check that the entity exists, and that it is internal.
  4907   5595           */
  4908   5596           if (pool == &dtd->pool)  /* are we called from prolog? */
  4909   5597             checkEntityDecl =
  4910   5598   #ifdef XML_DTD
  4911         -              prologState.documentEntity &&
         5599  +              parser->m_prologState.documentEntity &&
  4912   5600   #endif /* XML_DTD */
  4913   5601                 (dtd->standalone
  4914         -               ? !openInternalEntities
         5602  +               ? !parser->m_openInternalEntities
  4915   5603                  : !dtd->hasParamEntityRefs);
  4916         -        else /* if (pool == &tempPool): we are called from content */
         5604  +        else /* if (pool == &parser->m_tempPool): we are called from content */
  4917   5605             checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
  4918   5606           if (checkEntityDecl) {
  4919   5607             if (!entity)
  4920   5608               return XML_ERROR_UNDEFINED_ENTITY;
  4921   5609             else if (!entity->is_internal)
  4922   5610               return XML_ERROR_ENTITY_DECLARED_IN_PE;
  4923   5611           }
  4924   5612           else if (!entity) {
  4925   5613             /* Cannot report skipped entity here - see comments on
  4926         -             skippedEntityHandler.
  4927         -          if (skippedEntityHandler)
  4928         -            skippedEntityHandler(handlerArg, name, 0);
         5614  +             parser->m_skippedEntityHandler.
         5615  +          if (parser->m_skippedEntityHandler)
         5616  +            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
  4929   5617             */
  4930   5618             /* Cannot call the default handler because this would be
  4931   5619                out of sync with the call to the startElementHandler.
  4932         -          if ((pool == &tempPool) && defaultHandler)
         5620  +          if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
  4933   5621               reportDefault(parser, enc, ptr, next);
  4934   5622             */
  4935   5623             break;
  4936   5624           }
  4937   5625           if (entity->open) {
  4938         -          if (enc == encoding)
  4939         -            eventPtr = ptr;
         5626  +          if (enc == parser->m_encoding) {
         5627  +            /* It does not appear that this line can be executed.
         5628  +             *
         5629  +             * The "if (entity->open)" check catches recursive entity
         5630  +             * definitions.  In order to be called with an open
         5631  +             * entity, it must have gone through this code before and
         5632  +             * been through the recursive call to
         5633  +             * appendAttributeValue() some lines below.  That call
         5634  +             * sets the local encoding ("enc") to the parser's
         5635  +             * internal encoding (internal_utf8 or internal_utf16),
         5636  +             * which can never be the same as the principle encoding.
         5637  +             * It doesn't appear there is another code path that gets
         5638  +             * here with entity->open being TRUE.
         5639  +             *
         5640  +             * Since it is not certain that this logic is watertight,
         5641  +             * we keep the line and merely exclude it from coverage
         5642  +             * tests.
         5643  +             */
         5644  +            parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
         5645  +          }
  4940   5646             return XML_ERROR_RECURSIVE_ENTITY_REF;
  4941   5647           }
  4942   5648           if (entity->notation) {
  4943         -          if (enc == encoding)
  4944         -            eventPtr = ptr;
         5649  +          if (enc == parser->m_encoding)
         5650  +            parser->m_eventPtr = ptr;
  4945   5651             return XML_ERROR_BINARY_ENTITY_REF;
  4946   5652           }
  4947   5653           if (!entity->textPtr) {
  4948         -          if (enc == encoding)
  4949         -            eventPtr = ptr;
  4950         -              return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
         5654  +          if (enc == parser->m_encoding)
         5655  +            parser->m_eventPtr = ptr;
         5656  +          return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
  4951   5657           }
  4952   5658           else {
  4953   5659             enum XML_Error result;
  4954   5660             const XML_Char *textEnd = entity->textPtr + entity->textLen;
  4955   5661             entity->open = XML_TRUE;
  4956         -          result = appendAttributeValue(parser, internalEncoding, isCdata,
         5662  +          result = appendAttributeValue(parser, parser->m_internalEncoding, isCdata,
  4957   5663                                           (char *)entity->textPtr,
  4958   5664                                           (char *)textEnd, pool);
  4959   5665             entity->open = XML_FALSE;
  4960   5666             if (result)
  4961   5667               return result;
  4962   5668           }
  4963   5669         }
  4964   5670         break;
  4965   5671       default:
  4966         -      if (enc == encoding)
  4967         -        eventPtr = ptr;
         5672  +      /* The only token returned by XmlAttributeValueTok() that does
         5673  +       * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
         5674  +       * Getting that would require an entity name to contain an
         5675  +       * incomplete XML character (e.g. \xE2\x82); however previous
         5676  +       * tokenisers will have already recognised and rejected such
         5677  +       * names before XmlAttributeValueTok() gets a look-in.  This
         5678  +       * default case should be retained as a safety net, but the code
         5679  +       * excluded from coverage tests.
         5680  +       *
         5681  +       * LCOV_EXCL_START
         5682  +       */
         5683  +      if (enc == parser->m_encoding)
         5684  +        parser->m_eventPtr = ptr;
  4968   5685         return XML_ERROR_UNEXPECTED_STATE;
         5686  +      /* LCOV_EXCL_STOP */
  4969   5687       }
  4970   5688       ptr = next;
  4971   5689     }
  4972   5690     /* not reached */
  4973   5691   }
  4974   5692   
  4975   5693   static enum XML_Error
  4976   5694   storeEntityValue(XML_Parser parser,
  4977   5695                    const ENCODING *enc,
  4978   5696                    const char *entityTextPtr,
  4979   5697                    const char *entityTextEnd)
  4980   5698   {
  4981         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         5699  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  4982   5700     STRING_POOL *pool = &(dtd->entityValuePool);
  4983   5701     enum XML_Error result = XML_ERROR_NONE;
  4984   5702   #ifdef XML_DTD
  4985         -  int oldInEntityValue = prologState.inEntityValue;
  4986         -  prologState.inEntityValue = 1;
         5703  +  int oldInEntityValue = parser->m_prologState.inEntityValue;
         5704  +  parser->m_prologState.inEntityValue = 1;
  4987   5705   #endif /* XML_DTD */
  4988   5706     /* never return Null for the value argument in EntityDeclHandler,
  4989   5707        since this would indicate an external entity; therefore we
  4990   5708        have to make sure that entityValuePool.start is not null */
  4991   5709     if (!pool->blocks) {
  4992   5710       if (!poolGrow(pool))
  4993   5711         return XML_ERROR_NO_MEMORY;
................................................................................
  4995   5713   
  4996   5714     for (;;) {
  4997   5715       const char *next;
  4998   5716       int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
  4999   5717       switch (tok) {
  5000   5718       case XML_TOK_PARAM_ENTITY_REF:
  5001   5719   #ifdef XML_DTD
  5002         -      if (isParamEntity || enc != encoding) {
         5720  +      if (parser->m_isParamEntity || enc != parser->m_encoding) {
  5003   5721           const XML_Char *name;
  5004   5722           ENTITY *entity;
  5005         -        name = poolStoreString(&tempPool, enc,
         5723  +        name = poolStoreString(&parser->m_tempPool, enc,
  5006   5724                                  entityTextPtr + enc->minBytesPerChar,
  5007   5725                                  next - enc->minBytesPerChar);
  5008   5726           if (!name) {
  5009   5727             result = XML_ERROR_NO_MEMORY;
  5010   5728             goto endEntityValue;
  5011   5729           }
  5012         -        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
  5013         -        poolDiscard(&tempPool);
         5730  +        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
         5731  +        poolDiscard(&parser->m_tempPool);
  5014   5732           if (!entity) {
  5015   5733             /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
  5016   5734             /* cannot report skipped entity here - see comments on
  5017         -             skippedEntityHandler
  5018         -          if (skippedEntityHandler)
  5019         -            skippedEntityHandler(handlerArg, name, 0);
         5735  +             parser->m_skippedEntityHandler
         5736  +          if (parser->m_skippedEntityHandler)
         5737  +            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
  5020   5738             */
  5021   5739             dtd->keepProcessing = dtd->standalone;
  5022   5740             goto endEntityValue;
  5023   5741           }
  5024   5742           if (entity->open) {
  5025         -          if (enc == encoding)
  5026         -            eventPtr = entityTextPtr;
         5743  +          if (enc == parser->m_encoding)
         5744  +            parser->m_eventPtr = entityTextPtr;
  5027   5745             result = XML_ERROR_RECURSIVE_ENTITY_REF;
  5028   5746             goto endEntityValue;
  5029   5747           }
  5030   5748           if (entity->systemId) {
  5031         -          if (externalEntityRefHandler) {
         5749  +          if (parser->m_externalEntityRefHandler) {
  5032   5750               dtd->paramEntityRead = XML_FALSE;
  5033   5751               entity->open = XML_TRUE;
  5034         -            if (!externalEntityRefHandler(externalEntityRefHandlerArg,
         5752  +            if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
  5035   5753                                             0,
  5036   5754                                             entity->base,
  5037   5755                                             entity->systemId,
  5038   5756                                             entity->publicId)) {
  5039   5757                 entity->open = XML_FALSE;
  5040   5758                 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  5041   5759                 goto endEntityValue;
................................................................................
  5046   5764             }
  5047   5765             else
  5048   5766               dtd->keepProcessing = dtd->standalone;
  5049   5767           }
  5050   5768           else {
  5051   5769             entity->open = XML_TRUE;
  5052   5770             result = storeEntityValue(parser,
  5053         -                                    internalEncoding,
         5771  +                                    parser->m_internalEncoding,
  5054   5772                                       (char *)entity->textPtr,
  5055   5773                                       (char *)(entity->textPtr
  5056   5774                                                + entity->textLen));
  5057   5775             entity->open = XML_FALSE;
  5058   5776             if (result)
  5059   5777               goto endEntityValue;
  5060   5778           }
  5061   5779           break;
  5062   5780         }
  5063   5781   #endif /* XML_DTD */
  5064   5782         /* In the internal subset, PE references are not legal
  5065   5783            within markup declarations, e.g entity values in this case. */
  5066         -      eventPtr = entityTextPtr;
         5784  +      parser->m_eventPtr = entityTextPtr;
  5067   5785         result = XML_ERROR_PARAM_ENTITY_REF;
  5068   5786         goto endEntityValue;
  5069   5787       case XML_TOK_NONE:
  5070   5788         result = XML_ERROR_NONE;
  5071   5789         goto endEntityValue;
  5072   5790       case XML_TOK_ENTITY_REF:
  5073   5791       case XML_TOK_DATA_CHARS:
................................................................................
  5088   5806         break;
  5089   5807       case XML_TOK_CHAR_REF:
  5090   5808         {
  5091   5809           XML_Char buf[XML_ENCODE_MAX];
  5092   5810           int i;
  5093   5811           int n = XmlCharRefNumber(enc, entityTextPtr);
  5094   5812           if (n < 0) {
  5095         -          if (enc == encoding)
  5096         -            eventPtr = entityTextPtr;
         5813  +          if (enc == parser->m_encoding)
         5814  +            parser->m_eventPtr = entityTextPtr;
  5097   5815             result = XML_ERROR_BAD_CHAR_REF;
  5098   5816             goto endEntityValue;
  5099   5817           }
  5100   5818           n = XmlEncode(n, (ICHAR *)buf);
  5101         -        if (!n) {
  5102         -          if (enc == encoding)
  5103         -            eventPtr = entityTextPtr;
  5104         -          result = XML_ERROR_BAD_CHAR_REF;
  5105         -          goto endEntityValue;
  5106         -        }
         5819  +        /* The XmlEncode() functions can never return 0 here.  That
         5820  +         * error return happens if the code point passed in is either
         5821  +         * negative or greater than or equal to 0x110000.  The
         5822  +         * XmlCharRefNumber() functions will all return a number
         5823  +         * strictly less than 0x110000 or a negative value if an error
         5824  +         * occurred.  The negative value is intercepted above, so
         5825  +         * XmlEncode() is never passed a value it might return an
         5826  +         * error for.
         5827  +         */
  5107   5828           for (i = 0; i < n; i++) {
  5108   5829             if (pool->end == pool->ptr && !poolGrow(pool)) {
  5109   5830               result = XML_ERROR_NO_MEMORY;
  5110   5831               goto endEntityValue;
  5111   5832             }
  5112   5833             *(pool->ptr)++ = buf[i];
  5113   5834           }
  5114   5835         }
  5115   5836         break;
  5116   5837       case XML_TOK_PARTIAL:
  5117         -      if (enc == encoding)
  5118         -        eventPtr = entityTextPtr;
         5838  +      if (enc == parser->m_encoding)
         5839  +        parser->m_eventPtr = entityTextPtr;
  5119   5840         result = XML_ERROR_INVALID_TOKEN;
  5120   5841         goto endEntityValue;
  5121   5842       case XML_TOK_INVALID:
  5122         -      if (enc == encoding)
  5123         -        eventPtr = next;
         5843  +      if (enc == parser->m_encoding)
         5844  +        parser->m_eventPtr = next;
  5124   5845         result = XML_ERROR_INVALID_TOKEN;
  5125   5846         goto endEntityValue;
  5126   5847       default:
  5127         -      if (enc == encoding)
  5128         -        eventPtr = entityTextPtr;
         5848  +      /* This default case should be unnecessary -- all the tokens
         5849  +       * that XmlEntityValueTok() can return have their own explicit
         5850  +       * cases -- but should be retained for safety.  We do however
         5851  +       * exclude it from the coverage statistics.
         5852  +       *
         5853  +       * LCOV_EXCL_START
         5854  +       */
         5855  +      if (enc == parser->m_encoding)
         5856  +        parser->m_eventPtr = entityTextPtr;
  5129   5857         result = XML_ERROR_UNEXPECTED_STATE;
  5130   5858         goto endEntityValue;
         5859  +      /* LCOV_EXCL_STOP */
  5131   5860       }
  5132   5861       entityTextPtr = next;
  5133   5862     }
  5134   5863   endEntityValue:
  5135   5864   #ifdef XML_DTD
  5136         -  prologState.inEntityValue = oldInEntityValue;
         5865  +  parser->m_prologState.inEntityValue = oldInEntityValue;
  5137   5866   #endif /* XML_DTD */
  5138   5867     return result;
  5139   5868   }
  5140   5869   
  5141   5870   static void FASTCALL
  5142   5871   normalizeLines(XML_Char *s)
  5143   5872   {
................................................................................
  5164   5893   static int
  5165   5894   reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
  5166   5895                               const char *start, const char *end)
  5167   5896   {
  5168   5897     const XML_Char *target;
  5169   5898     XML_Char *data;
  5170   5899     const char *tem;
  5171         -  if (!processingInstructionHandler) {
  5172         -    if (defaultHandler)
         5900  +  if (!parser->m_processingInstructionHandler) {
         5901  +    if (parser->m_defaultHandler)
  5173   5902         reportDefault(parser, enc, start, end);
  5174   5903       return 1;
  5175   5904     }
  5176   5905     start += enc->minBytesPerChar * 2;
  5177   5906     tem = start + XmlNameLength(enc, start);
  5178         -  target = poolStoreString(&tempPool, enc, start, tem);
         5907  +  target = poolStoreString(&parser->m_tempPool, enc, start, tem);
  5179   5908     if (!target)
  5180   5909       return 0;
  5181         -  poolFinish(&tempPool);
  5182         -  data = poolStoreString(&tempPool, enc,
         5910  +  poolFinish(&parser->m_tempPool);
         5911  +  data = poolStoreString(&parser->m_tempPool, enc,
  5183   5912                           XmlSkipS(enc, tem),
  5184   5913                           end - enc->minBytesPerChar*2);
  5185   5914     if (!data)
  5186   5915       return 0;
  5187   5916     normalizeLines(data);
  5188         -  processingInstructionHandler(handlerArg, target, data);
  5189         -  poolClear(&tempPool);
         5917  +  parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
         5918  +  poolClear(&parser->m_tempPool);
  5190   5919     return 1;
  5191   5920   }
  5192   5921   
  5193   5922   static int
  5194   5923   reportComment(XML_Parser parser, const ENCODING *enc,
  5195   5924                 const char *start, const char *end)
  5196   5925   {
  5197   5926     XML_Char *data;
  5198         -  if (!commentHandler) {
  5199         -    if (defaultHandler)
         5927  +  if (!parser->m_commentHandler) {
         5928  +    if (parser->m_defaultHandler)
  5200   5929         reportDefault(parser, enc, start, end);
  5201   5930       return 1;
  5202   5931     }
  5203         -  data = poolStoreString(&tempPool,
         5932  +  data = poolStoreString(&parser->m_tempPool,
  5204   5933                            enc,
  5205   5934                            start + enc->minBytesPerChar * 4,
  5206   5935                            end - enc->minBytesPerChar * 3);
  5207   5936     if (!data)
  5208   5937       return 0;
  5209   5938     normalizeLines(data);
  5210         -  commentHandler(handlerArg, data);
  5211         -  poolClear(&tempPool);
         5939  +  parser->m_commentHandler(parser->m_handlerArg, data);
         5940  +  poolClear(&parser->m_tempPool);
  5212   5941     return 1;
  5213   5942   }
  5214   5943   
  5215   5944   static void
  5216   5945   reportDefault(XML_Parser parser, const ENCODING *enc,
  5217   5946                 const char *s, const char *end)
  5218   5947   {
  5219   5948     if (MUST_CONVERT(enc, s)) {
         5949  +    enum XML_Convert_Result convert_res;
  5220   5950       const char **eventPP;
  5221   5951       const char **eventEndPP;
  5222         -    if (enc == encoding) {
  5223         -      eventPP = &eventPtr;
  5224         -      eventEndPP = &eventEndPtr;
         5952  +    if (enc == parser->m_encoding) {
         5953  +      eventPP = &parser->m_eventPtr;
         5954  +      eventEndPP = &parser->m_eventEndPtr;
  5225   5955       }
  5226   5956       else {
  5227         -      eventPP = &(openInternalEntities->internalEventPtr);
  5228         -      eventEndPP = &(openInternalEntities->internalEventEndPtr);
         5957  +      /* To get here, two things must be true; the parser must be
         5958  +       * using a character encoding that is not the same as the
         5959  +       * encoding passed in, and the encoding passed in must need
         5960  +       * conversion to the internal format (UTF-8 unless XML_UNICODE
         5961  +       * is defined).  The only occasions on which the encoding passed
         5962  +       * in is not the same as the parser's encoding are when it is
         5963  +       * the internal encoding (e.g. a previously defined parameter
         5964  +       * entity, already converted to internal format).  This by
         5965  +       * definition doesn't need conversion, so the whole branch never
         5966  +       * gets executed.
         5967  +       *
         5968  +       * For safety's sake we don't delete these lines and merely
         5969  +       * exclude them from coverage statistics.
         5970  +       *
         5971  +       * LCOV_EXCL_START
         5972  +       */
         5973  +      eventPP = &(parser->m_openInternalEntities->internalEventPtr);
         5974  +      eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
         5975  +      /* LCOV_EXCL_STOP */
  5229   5976       }
  5230   5977       do {
  5231         -      ICHAR *dataPtr = (ICHAR *)dataBuf;
  5232         -      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
         5978  +      ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
         5979  +      convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
  5233   5980         *eventEndPP = s;
  5234         -      defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
         5981  +      parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
  5235   5982         *eventPP = s;
  5236         -    } while (s != end);
         5983  +    } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
  5237   5984     }
  5238   5985     else
  5239         -    defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
         5986  +    parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
  5240   5987   }
  5241   5988   
  5242   5989   
  5243   5990   static int
  5244   5991   defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
  5245   5992                   XML_Bool isId, const XML_Char *value, XML_Parser parser)
  5246   5993   {
................................................................................
  5254   6001           return 1;
  5255   6002       if (isId && !type->idAtt && !attId->xmlns)
  5256   6003         type->idAtt = attId;
  5257   6004     }
  5258   6005     if (type->nDefaultAtts == type->allocDefaultAtts) {
  5259   6006       if (type->allocDefaultAtts == 0) {
  5260   6007         type->allocDefaultAtts = 8;
  5261         -      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
         6008  +      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(parser, type->allocDefaultAtts
  5262   6009                               * sizeof(DEFAULT_ATTRIBUTE));
  5263         -      if (!type->defaultAtts)
         6010  +      if (!type->defaultAtts) {
         6011  +        type->allocDefaultAtts = 0;
  5264   6012           return 0;
         6013  +      }
  5265   6014       }
  5266   6015       else {
  5267   6016         DEFAULT_ATTRIBUTE *temp;
  5268   6017         int count = type->allocDefaultAtts * 2;
  5269   6018         temp = (DEFAULT_ATTRIBUTE *)
  5270         -        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
         6019  +        REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
  5271   6020         if (temp == NULL)
  5272   6021           return 0;
  5273   6022         type->allocDefaultAtts = count;
  5274   6023         type->defaultAtts = temp;
  5275   6024       }
  5276   6025     }
  5277   6026     att = type->defaultAtts + type->nDefaultAtts;
................................................................................
  5283   6032     type->nDefaultAtts += 1;
  5284   6033     return 1;
  5285   6034   }
  5286   6035   
  5287   6036   static int
  5288   6037   setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
  5289   6038   {
  5290         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         6039  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  5291   6040     const XML_Char *name;
  5292   6041     for (name = elementType->name; *name; name++) {
  5293   6042       if (*name == XML_T(ASCII_COLON)) {
  5294   6043         PREFIX *prefix;
  5295   6044         const XML_Char *s;
  5296   6045         for (s = elementType->name; s != name; s++) {
  5297   6046           if (!poolAppendChar(&dtd->pool, *s))
  5298   6047             return 0;
  5299   6048         }
  5300   6049         if (!poolAppendChar(&dtd->pool, XML_T('\0')))
  5301   6050           return 0;
  5302         -      prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
         6051  +      prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
  5303   6052                                   sizeof(PREFIX));
  5304   6053         if (!prefix)
  5305   6054           return 0;
  5306   6055         if (prefix->name == poolStart(&dtd->pool))
  5307   6056           poolFinish(&dtd->pool);
  5308   6057         else
  5309   6058           poolDiscard(&dtd->pool);
................................................................................
  5314   6063     return 1;
  5315   6064   }
  5316   6065   
  5317   6066   static ATTRIBUTE_ID *
  5318   6067   getAttributeId(XML_Parser parser, const ENCODING *enc,
  5319   6068                  const char *start, const char *end)
  5320   6069   {
  5321         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         6070  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  5322   6071     ATTRIBUTE_ID *id;
  5323   6072     const XML_Char *name;
  5324   6073     if (!poolAppendChar(&dtd->pool, XML_T('\0')))
  5325   6074       return NULL;
  5326   6075     name = poolStoreString(&dtd->pool, enc, start, end);
  5327   6076     if (!name)
  5328   6077       return NULL;
  5329   6078     /* skip quotation mark - its storage will be re-used (like in name[-1]) */
  5330   6079     ++name;
  5331         -  id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
         6080  +  id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
  5332   6081     if (!id)
  5333   6082       return NULL;
  5334   6083     if (id->name != name)
  5335   6084       poolDiscard(&dtd->pool);
  5336   6085     else {
  5337   6086       poolFinish(&dtd->pool);
  5338         -    if (!ns)
         6087  +    if (!parser->m_ns)
  5339   6088         ;
  5340   6089       else if (name[0] == XML_T(ASCII_x)
  5341   6090           && name[1] == XML_T(ASCII_m)
  5342   6091           && name[2] == XML_T(ASCII_l)
  5343   6092           && name[3] == XML_T(ASCII_n)
  5344   6093           && name[4] == XML_T(ASCII_s)
  5345   6094           && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
  5346   6095         if (name[5] == XML_T('\0'))
  5347   6096           id->prefix = &dtd->defaultPrefix;
  5348   6097         else
  5349         -        id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
         6098  +        id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
  5350   6099         id->xmlns = XML_TRUE;
  5351   6100       }
  5352   6101       else {
  5353   6102         int i;
  5354   6103         for (i = 0; name[i]; i++) {
  5355   6104           /* attributes without prefix are *not* in the default namespace */
  5356   6105           if (name[i] == XML_T(ASCII_COLON)) {
................................................................................
  5357   6106             int j;
  5358   6107             for (j = 0; j < i; j++) {
  5359   6108               if (!poolAppendChar(&dtd->pool, name[j]))
  5360   6109                 return NULL;
  5361   6110             }
  5362   6111             if (!poolAppendChar(&dtd->pool, XML_T('\0')))
  5363   6112               return NULL;
  5364         -          id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
         6113  +          id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
  5365   6114                                           sizeof(PREFIX));
         6115  +          if (!id->prefix)
         6116  +            return NULL;
  5366   6117             if (id->prefix->name == poolStart(&dtd->pool))
  5367   6118               poolFinish(&dtd->pool);
  5368   6119             else
  5369   6120               poolDiscard(&dtd->pool);
  5370   6121             break;
  5371   6122           }
  5372   6123         }
................................................................................
  5376   6127   }
  5377   6128   
  5378   6129   #define CONTEXT_SEP XML_T(ASCII_FF)
  5379   6130   
  5380   6131   static const XML_Char *
  5381   6132   getContext(XML_Parser parser)
  5382   6133   {
  5383         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         6134  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  5384   6135     HASH_TABLE_ITER iter;
  5385   6136     XML_Bool needSep = XML_FALSE;
  5386   6137   
  5387   6138     if (dtd->defaultPrefix.binding) {
  5388   6139       int i;
  5389   6140       int len;
  5390         -    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
         6141  +    if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
  5391   6142         return NULL;
  5392   6143       len = dtd->defaultPrefix.binding->uriLen;
  5393         -    if (namespaceSeparator)
         6144  +    if (parser->m_namespaceSeparator)
  5394   6145         len--;
  5395         -    for (i = 0; i < len; i++)
  5396         -      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
  5397         -        return NULL;
         6146  +    for (i = 0; i < len; i++) {
         6147  +      if (!poolAppendChar(&parser->m_tempPool, dtd->defaultPrefix.binding->uri[i])) {
         6148  +        /* Because of memory caching, I don't believe this line can be
         6149  +         * executed.
         6150  +         *
         6151  +         * This is part of a loop copying the default prefix binding
         6152  +         * URI into the parser's temporary string pool.  Previously,
         6153  +         * that URI was copied into the same string pool, with a
         6154  +         * terminating NUL character, as part of setContext().  When
         6155  +         * the pool was cleared, that leaves a block definitely big
         6156  +         * enough to hold the URI on the free block list of the pool.
         6157  +         * The URI copy in getContext() therefore cannot run out of
         6158  +         * memory.
         6159  +         *
         6160  +         * If the pool is used between the setContext() and
         6161  +         * getContext() calls, the worst it can do is leave a bigger
         6162  +         * block on the front of the free list.  Given that this is
         6163  +         * all somewhat inobvious and program logic can be changed, we
         6164  +         * don't delete the line but we do exclude it from the test
         6165  +         * coverage statistics.
         6166  +         */
         6167  +        return NULL; /* LCOV_EXCL_LINE */
         6168  +      }
         6169  +    }
  5398   6170       needSep = XML_TRUE;
  5399   6171     }
  5400   6172   
  5401   6173     hashTableIterInit(&iter, &(dtd->prefixes));
  5402   6174     for (;;) {
  5403   6175       int i;
  5404   6176       int len;
  5405   6177       const XML_Char *s;
  5406   6178       PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
  5407   6179       if (!prefix)
  5408   6180         break;
  5409         -    if (!prefix->binding)
  5410         -      continue;
  5411         -    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
         6181  +    if (!prefix->binding) {
         6182  +      /* This test appears to be (justifiable) paranoia.  There does
         6183  +       * not seem to be a way of injecting a prefix without a binding
         6184  +       * that doesn't get errored long before this function is called.
         6185  +       * The test should remain for safety's sake, so we instead
         6186  +       * exclude the following line from the coverage statistics.
         6187  +       */
         6188  +      continue; /* LCOV_EXCL_LINE */
         6189  +    }
         6190  +    if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
  5412   6191         return NULL;
  5413   6192       for (s = prefix->name; *s; s++)
  5414         -      if (!poolAppendChar(&tempPool, *s))
         6193  +      if (!poolAppendChar(&parser->m_tempPool, *s))
  5415   6194           return NULL;
  5416         -    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
         6195  +    if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
  5417   6196         return NULL;
  5418   6197       len = prefix->binding->uriLen;
  5419         -    if (namespaceSeparator)
         6198  +    if (parser->m_namespaceSeparator)
  5420   6199         len--;
  5421   6200       for (i = 0; i < len; i++)
  5422         -      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
         6201  +      if (!poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
  5423   6202           return NULL;
  5424   6203       needSep = XML_TRUE;
  5425   6204     }
  5426   6205   
  5427   6206   
  5428   6207     hashTableIterInit(&iter, &(dtd->generalEntities));
  5429   6208     for (;;) {
  5430   6209       const XML_Char *s;
  5431   6210       ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
  5432   6211       if (!e)
  5433   6212         break;
  5434   6213       if (!e->open)
  5435   6214         continue;
  5436         -    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
         6215  +    if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
  5437   6216         return NULL;
  5438   6217       for (s = e->name; *s; s++)
  5439         -      if (!poolAppendChar(&tempPool, *s))
         6218  +      if (!poolAppendChar(&parser->m_tempPool, *s))
  5440   6219           return 0;
  5441   6220       needSep = XML_TRUE;
  5442   6221     }
  5443   6222   
  5444         -  if (!poolAppendChar(&tempPool, XML_T('\0')))
         6223  +  if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
  5445   6224       return NULL;
  5446         -  return tempPool.start;
         6225  +  return parser->m_tempPool.start;
  5447   6226   }
  5448   6227   
  5449   6228   static XML_Bool
  5450   6229   setContext(XML_Parser parser, const XML_Char *context)
  5451   6230   {
  5452         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         6231  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  5453   6232     const XML_Char *s = context;
  5454   6233   
  5455   6234     while (*context != XML_T('\0')) {
  5456   6235       if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
  5457   6236         ENTITY *e;
  5458         -      if (!poolAppendChar(&tempPool, XML_T('\0')))
         6237  +      if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
  5459   6238           return XML_FALSE;
  5460         -      e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
         6239  +      e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&parser->m_tempPool), 0);
  5461   6240         if (e)
  5462   6241           e->open = XML_TRUE;
  5463   6242         if (*s != XML_T('\0'))
  5464   6243           s++;
  5465   6244         context = s;
  5466         -      poolDiscard(&tempPool);
         6245  +      poolDiscard(&parser->m_tempPool);
  5467   6246       }
  5468   6247       else if (*s == XML_T(ASCII_EQUALS)) {
  5469   6248         PREFIX *prefix;
  5470         -      if (poolLength(&tempPool) == 0)
         6249  +      if (poolLength(&parser->m_tempPool) == 0)
  5471   6250           prefix = &dtd->defaultPrefix;
  5472   6251         else {
  5473         -        if (!poolAppendChar(&tempPool, XML_T('\0')))
         6252  +        if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
  5474   6253             return XML_FALSE;
  5475         -        prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
         6254  +        prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&parser->m_tempPool),
  5476   6255                                     sizeof(PREFIX));
  5477   6256           if (!prefix)
  5478   6257             return XML_FALSE;
  5479         -        if (prefix->name == poolStart(&tempPool)) {
         6258  +        if (prefix->name == poolStart(&parser->m_tempPool)) {
  5480   6259             prefix->name = poolCopyString(&dtd->pool, prefix->name);
  5481   6260             if (!prefix->name)
  5482   6261               return XML_FALSE;
  5483   6262           }
  5484         -        poolDiscard(&tempPool);
         6263  +        poolDiscard(&parser->m_tempPool);
  5485   6264         }
  5486   6265         for (context = s + 1;
  5487   6266              *context != CONTEXT_SEP && *context != XML_T('\0');
  5488   6267              context++)
  5489         -        if (!poolAppendChar(&tempPool, *context))
         6268  +        if (!poolAppendChar(&parser->m_tempPool, *context))
  5490   6269             return XML_FALSE;
  5491         -      if (!poolAppendChar(&tempPool, XML_T('\0')))
         6270  +      if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
  5492   6271           return XML_FALSE;
  5493         -      if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
  5494         -                     &inheritedBindings) != XML_ERROR_NONE)
         6272  +      if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
         6273  +                     &parser->m_inheritedBindings) != XML_ERROR_NONE)
  5495   6274           return XML_FALSE;
  5496         -      poolDiscard(&tempPool);
         6275  +      poolDiscard(&parser->m_tempPool);
  5497   6276         if (*context != XML_T('\0'))
  5498   6277           ++context;
  5499   6278         s = context;
  5500   6279       }
  5501   6280       else {
  5502         -      if (!poolAppendChar(&tempPool, *s))
         6281  +      if (!poolAppendChar(&parser->m_tempPool, *s))
  5503   6282           return XML_FALSE;
  5504   6283         s++;
  5505   6284       }
  5506   6285     }
  5507   6286     return XML_TRUE;
  5508   6287   }
  5509   6288   
................................................................................
  5632   6411     ms->free_fcn(p);
  5633   6412   }
  5634   6413   
  5635   6414   /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
  5636   6415      The new DTD has already been initialized.
  5637   6416   */
  5638   6417   static int
  5639         -dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
         6418  +dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
  5640   6419   {
  5641   6420     HASH_TABLE_ITER iter;
  5642   6421   
  5643   6422     /* Copy the prefix table. */
  5644   6423   
  5645   6424     hashTableIterInit(&iter, &(oldDtd->prefixes));
  5646   6425     for (;;) {
................................................................................
  5647   6426       const XML_Char *name;
  5648   6427       const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
  5649   6428       if (!oldP)
  5650   6429         break;
  5651   6430       name = poolCopyString(&(newDtd->pool), oldP->name);
  5652   6431       if (!name)
  5653   6432         return 0;
  5654         -    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
         6433  +    if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
  5655   6434         return 0;
  5656   6435     }
  5657   6436   
  5658   6437     hashTableIterInit(&iter, &(oldDtd->attributeIds));
  5659   6438   
  5660   6439     /* Copy the attribute id table. */
  5661   6440   
................................................................................
  5669   6448       /* Remember to allocate the scratch byte before the name. */
  5670   6449       if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
  5671   6450         return 0;
  5672   6451       name = poolCopyString(&(newDtd->pool), oldA->name);
  5673   6452       if (!name)
  5674   6453         return 0;
  5675   6454       ++name;
  5676         -    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
         6455  +    newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
  5677   6456                                     sizeof(ATTRIBUTE_ID));
  5678   6457       if (!newA)
  5679   6458         return 0;
  5680   6459       newA->maybeTokenized = oldA->maybeTokenized;
  5681   6460       if (oldA->prefix) {
  5682   6461         newA->xmlns = oldA->xmlns;
  5683   6462         if (oldA->prefix == &oldDtd->defaultPrefix)
  5684   6463           newA->prefix = &newDtd->defaultPrefix;
  5685   6464         else
  5686         -        newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
         6465  +        newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
  5687   6466                                           oldA->prefix->name, 0);
  5688   6467       }
  5689   6468     }
  5690   6469   
  5691   6470     /* Copy the element type table. */
  5692   6471   
  5693   6472     hashTableIterInit(&iter, &(oldDtd->elementTypes));
................................................................................
  5698   6477       const XML_Char *name;
  5699   6478       const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
  5700   6479       if (!oldE)
  5701   6480         break;
  5702   6481       name = poolCopyString(&(newDtd->pool), oldE->name);
  5703   6482       if (!name)
  5704   6483         return 0;
  5705         -    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
         6484  +    newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
  5706   6485                                     sizeof(ELEMENT_TYPE));
  5707   6486       if (!newE)
  5708   6487         return 0;
  5709   6488       if (oldE->nDefaultAtts) {
  5710   6489         newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
  5711   6490             ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
  5712   6491         if (!newE->defaultAtts) {
  5713         -        ms->free_fcn(newE);
  5714   6492           return 0;
  5715   6493         }
  5716   6494       }
  5717   6495       if (oldE->idAtt)
  5718   6496         newE->idAtt = (ATTRIBUTE_ID *)
  5719         -          lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
         6497  +          lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
  5720   6498       newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
  5721   6499       if (oldE->prefix)
  5722         -      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
         6500  +      newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
  5723   6501                                         oldE->prefix->name, 0);
  5724   6502       for (i = 0; i < newE->nDefaultAtts; i++) {
  5725   6503         newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
  5726         -          lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
         6504  +          lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
  5727   6505         newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
  5728   6506         if (oldE->defaultAtts[i].value) {
  5729   6507           newE->defaultAtts[i].value
  5730   6508               = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
  5731   6509           if (!newE->defaultAtts[i].value)
  5732   6510             return 0;
  5733   6511         }
  5734   6512         else
  5735   6513           newE->defaultAtts[i].value = NULL;
  5736   6514       }
  5737   6515     }
  5738   6516   
  5739   6517     /* Copy the entity tables. */
  5740         -  if (!copyEntityTable(&(newDtd->generalEntities),
         6518  +  if (!copyEntityTable(oldParser,
         6519  +                       &(newDtd->generalEntities),
  5741   6520                          &(newDtd->pool),
  5742   6521                          &(oldDtd->generalEntities)))
  5743   6522         return 0;
  5744   6523   
  5745   6524   #ifdef XML_DTD
  5746         -  if (!copyEntityTable(&(newDtd->paramEntities),
         6525  +  if (!copyEntityTable(oldParser,
         6526  +                       &(newDtd->paramEntities),
  5747   6527                          &(newDtd->pool),
  5748   6528                          &(oldDtd->paramEntities)))
  5749   6529         return 0;
  5750   6530     newDtd->paramEntityRead = oldDtd->paramEntityRead;
  5751   6531   #endif /* XML_DTD */
  5752   6532   
  5753   6533     newDtd->keepProcessing = oldDtd->keepProcessing;
................................................................................
  5762   6542     newDtd->scaffLevel = oldDtd->scaffLevel;
  5763   6543     newDtd->scaffIndex = oldDtd->scaffIndex;
  5764   6544   
  5765   6545     return 1;
  5766   6546   }  /* End dtdCopy */
  5767   6547   
  5768   6548   static int
  5769         -copyEntityTable(HASH_TABLE *newTable,
         6549  +copyEntityTable(XML_Parser oldParser,
         6550  +                HASH_TABLE *newTable,
  5770   6551                   STRING_POOL *newPool,
  5771   6552                   const HASH_TABLE *oldTable)
  5772   6553   {
  5773   6554     HASH_TABLE_ITER iter;
  5774   6555     const XML_Char *cachedOldBase = NULL;
  5775   6556     const XML_Char *cachedNewBase = NULL;
  5776   6557   
................................................................................
  5781   6562       const XML_Char *name;
  5782   6563       const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
  5783   6564       if (!oldE)
  5784   6565         break;
  5785   6566       name = poolCopyString(newPool, oldE->name);
  5786   6567       if (!name)
  5787   6568         return 0;
  5788         -    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
         6569  +    newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
  5789   6570       if (!newE)
  5790   6571         return 0;
  5791   6572       if (oldE->systemId) {
  5792   6573         const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
  5793   6574         if (!tem)
  5794   6575           return 0;
  5795   6576         newE->systemId = tem;
................................................................................
  5837   6618   keyeq(KEY s1, KEY s2)
  5838   6619   {
  5839   6620     for (; *s1 == *s2; s1++, s2++)
  5840   6621       if (*s1 == 0)
  5841   6622         return XML_TRUE;
  5842   6623     return XML_FALSE;
  5843   6624   }
         6625  +
         6626  +static size_t
         6627  +keylen(KEY s)
         6628  +{
         6629  +  size_t len = 0;
         6630  +  for (; *s; s++, len++);
         6631  +  return len;
         6632  +}
         6633  +
         6634  +static void
         6635  +copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)
         6636  +{
         6637  +  key->k[0] = 0;
         6638  +  key->k[1] = get_hash_secret_salt(parser);
         6639  +}
  5844   6640   
  5845   6641   static unsigned long FASTCALL
  5846         -hash(KEY s)
         6642  +hash(XML_Parser parser, KEY s)
  5847   6643   {
  5848         -  unsigned long h = 0;
  5849         -  while (*s)
  5850         -    h = CHAR_HASH(h, *s++);
  5851         -  return h;
         6644  +  struct siphash state;
         6645  +  struct sipkey key;
         6646  +  (void)sip_tobin;
         6647  +  (void)sip24_valid;
         6648  +  copy_salt_to_sipkey(parser, &key);
         6649  +  sip24_init(&state, &key);
         6650  +  sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
         6651  +  return (unsigned long)sip24_final(&state);
  5852   6652   }
  5853   6653   
  5854   6654   static NAMED *
  5855         -lookup(HASH_TABLE *table, KEY name, size_t createSize)
         6655  +lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
  5856   6656   {
  5857   6657     size_t i;
  5858   6658     if (table->size == 0) {
  5859   6659       size_t tsize;
  5860   6660       if (!createSize)
  5861   6661         return NULL;
  5862   6662       table->power = INIT_POWER;
................................................................................
  5865   6665       tsize = table->size * sizeof(NAMED *);
  5866   6666       table->v = (NAMED **)table->mem->malloc_fcn(tsize);
  5867   6667       if (!table->v) {
  5868   6668         table->size = 0;
  5869   6669         return NULL;
  5870   6670       }
  5871   6671       memset(table->v, 0, tsize);
  5872         -    i = hash(name) & ((unsigned long)table->size - 1);
         6672  +    i = hash(parser, name) & ((unsigned long)table->size - 1);
  5873   6673     }
  5874   6674     else {
  5875         -    unsigned long h = hash(name);
         6675  +    unsigned long h = hash(parser, name);
  5876   6676       unsigned long mask = (unsigned long)table->size - 1;
  5877   6677       unsigned char step = 0;
  5878   6678       i = h & mask;
  5879   6679       while (table->v[i]) {
  5880   6680         if (keyeq(name, table->v[i]->name))
  5881   6681           return table->v[i];
  5882   6682         if (!step)
................................................................................
  5894   6694         size_t tsize = newSize * sizeof(NAMED *);
  5895   6695         NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
  5896   6696         if (!newV)
  5897   6697           return NULL;
  5898   6698         memset(newV, 0, tsize);
  5899   6699         for (i = 0; i < table->size; i++)
  5900   6700           if (table->v[i]) {
  5901         -          unsigned long newHash = hash(table->v[i]->name);
         6701  +          unsigned long newHash = hash(parser, table->v[i]->name);
  5902   6702             size_t j = newHash & newMask;
  5903   6703             step = 0;
  5904   6704             while (newV[j]) {
  5905   6705               if (!step)
  5906   6706                 step = PROBE_STEP(newHash, newMask, newPower);
  5907   6707               j < step ? (j += newSize - step) : (j -= step);
  5908   6708             }
................................................................................
  6029   6829   static XML_Char *
  6030   6830   poolAppend(STRING_POOL *pool, const ENCODING *enc,
  6031   6831              const char *ptr, const char *end)
  6032   6832   {
  6033   6833     if (!pool->ptr && !poolGrow(pool))
  6034   6834       return NULL;
  6035   6835     for (;;) {
  6036         -    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
  6037         -    if (ptr == end)
         6836  +    const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
         6837  +    if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
  6038   6838         break;
  6039   6839       if (!poolGrow(pool))
  6040   6840         return NULL;
  6041   6841     }
  6042   6842     return pool->start;
  6043   6843   }
  6044   6844   
................................................................................
  6053   6853     poolFinish(pool);
  6054   6854     return s;
  6055   6855   }
  6056   6856   
  6057   6857   static const XML_Char *
  6058   6858   poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
  6059   6859   {
  6060         -  if (!pool->ptr && !poolGrow(pool))
  6061         -    return NULL;
         6860  +  if (!pool->ptr && !poolGrow(pool)) {
         6861  +    /* The following line is unreachable given the current usage of
         6862  +     * poolCopyStringN().  Currently it is called from exactly one
         6863  +     * place to copy the text of a simple general entity.  By that
         6864  +     * point, the name of the entity is already stored in the pool, so
         6865  +     * pool->ptr cannot be NULL.
         6866  +     *
         6867  +     * If poolCopyStringN() is used elsewhere as it well might be,
         6868  +     * this line may well become executable again.  Regardless, this
         6869  +     * sort of check shouldn't be removed lightly, so we just exclude
         6870  +     * it from the coverage statistics.
         6871  +     */
         6872  +    return NULL; /* LCOV_EXCL_LINE */
         6873  +  }
  6062   6874     for (; n > 0; --n, s++) {
  6063   6875       if (!poolAppendChar(pool, *s))
  6064   6876         return NULL;
  6065   6877     }
  6066   6878     s = pool->start;
  6067   6879     poolFinish(pool);
  6068   6880     return s;
................................................................................
  6086   6898     if (!poolAppend(pool, enc, ptr, end))
  6087   6899       return NULL;
  6088   6900     if (pool->ptr == pool->end && !poolGrow(pool))
  6089   6901       return NULL;
  6090   6902     *(pool->ptr)++ = 0;
  6091   6903     return pool->start;
  6092   6904   }
         6905  +
         6906  +static size_t
         6907  +poolBytesToAllocateFor(int blockSize)
         6908  +{
         6909  +  /* Unprotected math would be:
         6910  +  ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
         6911  +  **
         6912  +  ** Detect overflow, avoiding _signed_ overflow undefined behavior
         6913  +  ** For a + b * c we check b * c in isolation first, so that addition of a
         6914  +  ** on top has no chance of making us accept a small non-negative number
         6915  +  */
         6916  +  const size_t stretch = sizeof(XML_Char);  /* can be 4 bytes */
         6917  +
         6918  +  if (blockSize <= 0)
         6919  +    return 0;
         6920  +
         6921  +  if (blockSize > (int)(INT_MAX / stretch))
         6922  +    return 0;
         6923  +
         6924  +  {
         6925  +    const int stretchedBlockSize = blockSize * (int)stretch;
         6926  +    const int bytesToAllocate = (int)(
         6927  +        offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
         6928  +    if (bytesToAllocate < 0)
         6929  +      return 0;
         6930  +
         6931  +    return (size_t)bytesToAllocate;
         6932  +  }
         6933  +}
  6093   6934   
  6094   6935   static XML_Bool FASTCALL
  6095   6936   poolGrow(STRING_POOL *pool)
  6096   6937   {
  6097   6938     if (pool->freeBlocks) {
  6098   6939       if (pool->start == 0) {
  6099   6940         pool->blocks = pool->freeBlocks;
................................................................................
  6114   6955         pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
  6115   6956         pool->start = pool->blocks->s;
  6116   6957         pool->end = pool->start + pool->blocks->size;
  6117   6958         return XML_TRUE;
  6118   6959       }
  6119   6960     }
  6120   6961     if (pool->blocks && pool->start == pool->blocks->s) {
  6121         -    int blockSize = (int)(pool->end - pool->start)*2;
  6122         -    pool->blocks = (BLOCK *)
  6123         -      pool->mem->realloc_fcn(pool->blocks,
  6124         -                             (offsetof(BLOCK, s)
  6125         -                              + blockSize * sizeof(XML_Char)));
  6126         -    if (pool->blocks == NULL)
         6962  +    BLOCK *temp;
         6963  +    int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
         6964  +    size_t bytesToAllocate;
         6965  +
         6966  +    /* NOTE: Needs to be calculated prior to calling `realloc`
         6967  +             to avoid dangling pointers: */
         6968  +    const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
         6969  +
         6970  +    if (blockSize < 0) {
         6971  +      /* This condition traps a situation where either more than
         6972  +       * INT_MAX/2 bytes have already been allocated.  This isn't
         6973  +       * readily testable, since it is unlikely that an average
         6974  +       * machine will have that much memory, so we exclude it from the
         6975  +       * coverage statistics.
         6976  +       */
         6977  +      return XML_FALSE; /* LCOV_EXCL_LINE */
         6978  +    }
         6979  +
         6980  +    bytesToAllocate = poolBytesToAllocateFor(blockSize);
         6981  +    if (bytesToAllocate == 0)
         6982  +      return XML_FALSE;
         6983  +
         6984  +    temp = (BLOCK *)
         6985  +      pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);
         6986  +    if (temp == NULL)
  6127   6987         return XML_FALSE;
         6988  +    pool->blocks = temp;
  6128   6989       pool->blocks->size = blockSize;
  6129         -    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
         6990  +    pool->ptr = pool->blocks->s + offsetInsideBlock;
  6130   6991       pool->start = pool->blocks->s;
  6131   6992       pool->end = pool->start + blockSize;
  6132   6993     }
  6133   6994     else {
  6134   6995       BLOCK *tem;
  6135   6996       int blockSize = (int)(pool->end - pool->start);
         6997  +    size_t bytesToAllocate;
         6998  +
         6999  +    if (blockSize < 0) {
         7000  +      /* This condition traps a situation where either more than
         7001  +       * INT_MAX bytes have already been allocated (which is prevented
         7002  +       * by various pieces of program logic, not least this one, never
         7003  +       * mind the unlikelihood of actually having that much memory) or
         7004  +       * the pool control fields have been corrupted (which could
         7005  +       * conceivably happen in an extremely buggy user handler
         7006  +       * function).  Either way it isn't readily testable, so we
         7007  +       * exclude it from the coverage statistics.
         7008  +       */
         7009  +      return XML_FALSE;  /* LCOV_EXCL_LINE */
         7010  +    }
         7011  +
  6136   7012       if (blockSize < INIT_BLOCK_SIZE)
  6137   7013         blockSize = INIT_BLOCK_SIZE;
  6138         -    else
         7014  +    else {
         7015  +      /* Detect overflow, avoiding _signed_ overflow undefined behavior */
         7016  +      if ((int)((unsigned)blockSize * 2U) < 0) {
         7017  +        return XML_FALSE;
         7018  +      }
  6139   7019         blockSize *= 2;
  6140         -    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
  6141         -                                        + blockSize * sizeof(XML_Char));
         7020  +    }
         7021  +
         7022  +    bytesToAllocate = poolBytesToAllocateFor(blockSize);
         7023  +    if (bytesToAllocate == 0)
         7024  +      return XML_FALSE;
         7025  +
         7026  +    tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
  6142   7027       if (!tem)
  6143   7028         return XML_FALSE;
  6144   7029       tem->size = blockSize;
  6145   7030       tem->next = pool->blocks;
  6146   7031       pool->blocks = tem;
  6147   7032       if (pool->ptr != pool->start)
  6148   7033         memcpy(tem->s, pool->start,
................................................................................
  6153   7038     }
  6154   7039     return XML_TRUE;
  6155   7040   }
  6156   7041   
  6157   7042   static int FASTCALL
  6158   7043   nextScaffoldPart(XML_Parser parser)
  6159   7044   {
  6160         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         7045  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  6161   7046     CONTENT_SCAFFOLD * me;
  6162   7047     int next;
  6163   7048   
  6164   7049     if (!dtd->scaffIndex) {
  6165         -    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
         7050  +    dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
  6166   7051       if (!dtd->scaffIndex)
  6167   7052         return -1;
  6168   7053       dtd->scaffIndex[0] = 0;
  6169   7054     }
  6170   7055   
  6171   7056     if (dtd->scaffCount >= dtd->scaffSize) {
  6172   7057       CONTENT_SCAFFOLD *temp;
  6173   7058       if (dtd->scaffold) {
  6174   7059         temp = (CONTENT_SCAFFOLD *)
  6175         -        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
         7060  +        REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
  6176   7061         if (temp == NULL)
  6177   7062           return -1;
  6178   7063         dtd->scaffSize *= 2;
  6179   7064       }
  6180   7065       else {
  6181         -      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
         7066  +      temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
  6182   7067                                           * sizeof(CONTENT_SCAFFOLD));
  6183   7068         if (temp == NULL)
  6184   7069           return -1;
  6185   7070         dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
  6186   7071       }
  6187   7072       dtd->scaffold = temp;
  6188   7073     }
................................................................................
  6205   7090   static void
  6206   7091   build_node(XML_Parser parser,
  6207   7092              int src_node,
  6208   7093              XML_Content *dest,
  6209   7094              XML_Content **contpos,
  6210   7095              XML_Char **strpos)
  6211   7096   {
  6212         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         7097  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  6213   7098     dest->type = dtd->scaffold[src_node].type;
  6214   7099     dest->quant = dtd->scaffold[src_node].quant;
  6215   7100     if (dest->type == XML_CTYPE_NAME) {
  6216   7101       const XML_Char *src;
  6217   7102       dest->name = *strpos;
  6218   7103       src = dtd->scaffold[src_node].name;
  6219   7104       for (;;) {
................................................................................
  6239   7124       dest->name = NULL;
  6240   7125     }
  6241   7126   }
  6242   7127   
  6243   7128   static XML_Content *
  6244   7129   build_model (XML_Parser parser)
  6245   7130   {
  6246         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         7131  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  6247   7132     XML_Content *ret;
  6248   7133     XML_Content *cpos;
  6249   7134     XML_Char * str;
  6250   7135     int allocsize = (dtd->scaffCount * sizeof(XML_Content)
  6251   7136                      + (dtd->contentStringLen * sizeof(XML_Char)));
  6252   7137   
  6253         -  ret = (XML_Content *)MALLOC(allocsize);
         7138  +  ret = (XML_Content *)MALLOC(parser, allocsize);
  6254   7139     if (!ret)
  6255   7140       return NULL;
  6256   7141   
  6257   7142     str =  (XML_Char *) (&ret[dtd->scaffCount]);
  6258   7143     cpos = &ret[1];
  6259   7144   
  6260   7145     build_node(parser, 0, ret, &cpos, &str);
................................................................................
  6263   7148   
  6264   7149   static ELEMENT_TYPE *
  6265   7150   getElementType(XML_Parser parser,
  6266   7151                  const ENCODING *enc,
  6267   7152                  const char *ptr,
  6268   7153                  const char *end)
  6269   7154   {
  6270         -  DTD * const dtd = _dtd;  /* save one level of indirection */
         7155  +  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  6271   7156     const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
  6272   7157     ELEMENT_TYPE *ret;
  6273   7158   
  6274   7159     if (!name)
  6275   7160       return NULL;
  6276         -  ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
         7161  +  ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
  6277   7162     if (!ret)
  6278   7163       return NULL;
  6279   7164     if (ret->name != name)
  6280   7165       poolDiscard(&dtd->pool);
  6281   7166     else {
  6282   7167       poolFinish(&dtd->pool);
  6283   7168       if (!setElementTypePrefix(parser, ret))
  6284   7169         return NULL;
  6285   7170     }
  6286   7171     return ret;
  6287   7172   }
         7173  +
         7174  +static XML_Char *
         7175  +copyString(const XML_Char *s,
         7176  +           const XML_Memory_Handling_Suite *memsuite)
         7177  +{
         7178  +    int charsRequired = 0;
         7179  +    XML_Char *result;
         7180  +
         7181  +    /* First determine how long the string is */
         7182  +    while (s[charsRequired] != 0) {
         7183  +      charsRequired++;
         7184  +    }
         7185  +    /* Include the terminator */
         7186  +    charsRequired++;
         7187  +
         7188  +    /* Now allocate space for the copy */
         7189  +    result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
         7190  +    if (result == NULL)
         7191  +        return NULL;
         7192  +    /* Copy the original into place */
         7193  +    memcpy(result, s, charsRequired * sizeof(XML_Char));
         7194  +    return result;
         7195  +}

Changes to expat/xmlrole.c.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   #include <stddef.h>
     6     34   
     7         -#ifdef COMPILED_FROM_DSP
           35  +#ifdef _WIN32
     8     36   #include "winconfig.h"
     9         -#elif defined(MACOS_CLASSIC)
    10         -#include "macconfig.h"
    11         -#elif defined(__amigaos4__)
    12         -#include "amigaconfig.h"
    13         -#elif defined(__WATCOMC__)
    14         -#include "watcomconfig.h"
    15     37   #else
    16     38   #ifdef HAVE_EXPAT_CONFIG_H
    17     39   #include <expat_config.h>
    18     40   #endif
    19         -#endif /* ndef COMPILED_FROM_DSP */
           41  +#endif /* ndef _WIN32 */
    20     42   
    21     43   #include "expat_external.h"
    22     44   #include "internal.h"
    23     45   #include "xmlrole.h"
    24     46   #include "ascii.h"
    25     47   
    26     48   /* Doesn't check:
................................................................................
   172    194     case XML_TOK_PROLOG_S:
   173    195       return XML_ROLE_NONE;
   174    196     case XML_TOK_PI:
   175    197       return XML_ROLE_PI;
   176    198     case XML_TOK_COMMENT:
   177    199       return XML_ROLE_COMMENT;
   178    200     case XML_TOK_BOM:
   179         -    return XML_ROLE_NONE;
          201  +    /* This case can never arise.  To reach this role function, the
          202  +     * parse must have passed through prolog0 and therefore have had
          203  +     * some form of input, even if only a space.  At that point, a
          204  +     * byte order mark is no longer a valid character (though
          205  +     * technically it should be interpreted as a non-breaking space),
          206  +     * so will be rejected by the tokenizing stages.
          207  +     */
          208  +    return XML_ROLE_NONE; /* LCOV_EXCL_LINE */
   180    209     case XML_TOK_DECL_OPEN:
   181    210       if (!XmlNameMatchesAscii(enc,
   182    211                                ptr + 2 * MIN_BYTES_PER_CHAR(enc),
   183    212                                end,
   184    213                                KW_DOCTYPE))
   185    214         break;
   186    215       state->handler = doctype0;
................................................................................
   191    220     }
   192    221     return common(state, tok);
   193    222   }
   194    223   
   195    224   static int PTRCALL
   196    225   prolog2(PROLOG_STATE *state,
   197    226           int tok,
   198         -        const char *ptr,
   199         -        const char *end,
   200         -        const ENCODING *enc)
          227  +        const char *UNUSED_P(ptr),
          228  +        const char *UNUSED_P(end),
          229  +        const ENCODING *UNUSED_P(enc))
   201    230   {
   202    231     switch (tok) {
   203    232     case XML_TOK_PROLOG_S:
   204    233       return XML_ROLE_NONE;
   205    234     case XML_TOK_PI:
   206    235       return XML_ROLE_PI;
   207    236     case XML_TOK_COMMENT:
................................................................................
   212    241     }
   213    242     return common(state, tok);
   214    243   }
   215    244   
   216    245   static int PTRCALL
   217    246   doctype0(PROLOG_STATE *state,
   218    247            int tok,
   219         -         const char *ptr,
   220         -         const char *end,
   221         -         const ENCODING *enc)
          248  +         const char *UNUSED_P(ptr),
          249  +         const char *UNUSED_P(end),
          250  +         const ENCODING *UNUSED_P(enc))
   222    251   {
   223    252     switch (tok) {
   224    253     case XML_TOK_PROLOG_S:
   225    254       return XML_ROLE_DOCTYPE_NONE;
   226    255     case XML_TOK_NAME:
   227    256     case XML_TOK_PREFIXED_NAME:
   228    257       state->handler = doctype1;
................................................................................
   260    289     }
   261    290     return common(state, tok);
   262    291   }
   263    292   
   264    293   static int PTRCALL
   265    294   doctype2(PROLOG_STATE *state,
   266    295            int tok,
   267         -         const char *ptr,
   268         -         const char *end,
   269         -         const ENCODING *enc)
          296  +         const char *UNUSED_P(ptr),
          297  +         const char *UNUSED_P(end),
          298  +         const ENCODING *UNUSED_P(enc))
   270    299   {
   271    300     switch (tok) {
   272    301     case XML_TOK_PROLOG_S:
   273    302       return XML_ROLE_DOCTYPE_NONE;
   274    303     case XML_TOK_LITERAL:
   275    304       state->handler = doctype3;
   276    305       return XML_ROLE_DOCTYPE_PUBLIC_ID;
................................................................................
   277    306     }
   278    307     return common(state, tok);
   279    308   }
   280    309   
   281    310   static int PTRCALL
   282    311   doctype3(PROLOG_STATE *state,
   283    312            int tok,
   284         -         const char *ptr,
   285         -         const char *end,
   286         -         const ENCODING *enc)
          313  +         const char *UNUSED_P(ptr),
          314  +         const char *UNUSED_P(end),
          315  +         const ENCODING *UNUSED_P(enc))
   287    316   {
   288    317     switch (tok) {
   289    318     case XML_TOK_PROLOG_S:
   290    319       return XML_ROLE_DOCTYPE_NONE;
   291    320     case XML_TOK_LITERAL:
   292    321       state->handler = doctype4;
   293    322       return XML_ROLE_DOCTYPE_SYSTEM_ID;
................................................................................
   294    323     }
   295    324     return common(state, tok);
   296    325   }
   297    326   
   298    327   static int PTRCALL
   299    328   doctype4(PROLOG_STATE *state,
   300    329            int tok,
   301         -         const char *ptr,
   302         -         const char *end,
   303         -         const ENCODING *enc)
          330  +         const char *UNUSED_P(ptr),
          331  +         const char *UNUSED_P(end),
          332  +         const ENCODING *UNUSED_P(enc))
   304    333   {
   305    334     switch (tok) {
   306    335     case XML_TOK_PROLOG_S:
   307    336       return XML_ROLE_DOCTYPE_NONE;
   308    337     case XML_TOK_OPEN_BRACKET:
   309    338       state->handler = internalSubset;
   310    339       return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
................................................................................
   314    343     }
   315    344     return common(state, tok);
   316    345   }
   317    346   
   318    347   static int PTRCALL
   319    348   doctype5(PROLOG_STATE *state,
   320    349            int tok,
   321         -         const char *ptr,
   322         -         const char *end,
   323         -         const ENCODING *enc)
          350  +         const char *UNUSED_P(ptr),
          351  +         const char *UNUSED_P(end),
          352  +         const ENCODING *UNUSED_P(enc))
   324    353   {
   325    354     switch (tok) {
   326    355     case XML_TOK_PROLOG_S:
   327    356       return XML_ROLE_DOCTYPE_NONE;
   328    357     case XML_TOK_DECL_CLOSE:
   329    358       state->handler = prolog2;
   330    359       return XML_ROLE_DOCTYPE_CLOSE;
................................................................................
   433    462   }
   434    463   
   435    464   #endif /* XML_DTD */
   436    465   
   437    466   static int PTRCALL
   438    467   entity0(PROLOG_STATE *state,
   439    468           int tok,
   440         -        const char *ptr,
   441         -        const char *end,
   442         -        const ENCODING *enc)
          469  +        const char *UNUSED_P(ptr),
          470  +        const char *UNUSED_P(end),
          471  +        const ENCODING *UNUSED_P(enc))
   443    472   {
   444    473     switch (tok) {
   445    474     case XML_TOK_PROLOG_S:
   446    475       return XML_ROLE_ENTITY_NONE;
   447    476     case XML_TOK_PERCENT:
   448    477       state->handler = entity1;
   449    478       return XML_ROLE_ENTITY_NONE;
................................................................................
   453    482     }
   454    483     return common(state, tok);
   455    484   }
   456    485   
   457    486   static int PTRCALL
   458    487   entity1(PROLOG_STATE *state,
   459    488           int tok,
   460         -        const char *ptr,
   461         -        const char *end,
   462         -        const ENCODING *enc)
          489  +        const char *UNUSED_P(ptr),
          490  +        const char *UNUSED_P(end),
          491  +        const ENCODING *UNUSED_P(enc))
   463    492   {
   464    493     switch (tok) {
   465    494     case XML_TOK_PROLOG_S:
   466    495       return XML_ROLE_ENTITY_NONE;
   467    496     case XML_TOK_NAME:
   468    497       state->handler = entity7;
   469    498       return XML_ROLE_PARAM_ENTITY_NAME;
................................................................................
   498    527     }
   499    528     return common(state, tok);
   500    529   }
   501    530   
   502    531   static int PTRCALL
   503    532   entity3(PROLOG_STATE *state,
   504    533           int tok,
   505         -        const char *ptr,
   506         -        const char *end,
   507         -        const ENCODING *enc)
          534  +        const char *UNUSED_P(ptr),
          535  +        const char *UNUSED_P(end),
          536  +        const ENCODING *UNUSED_P(enc))
   508    537   {
   509    538     switch (tok) {
   510    539     case XML_TOK_PROLOG_S:
   511    540       return XML_ROLE_ENTITY_NONE;
   512    541     case XML_TOK_LITERAL:
   513    542       state->handler = entity4;
   514    543       return XML_ROLE_ENTITY_PUBLIC_ID;
................................................................................
   515    544     }
   516    545     return common(state, tok);
   517    546   }
   518    547   
   519    548   static int PTRCALL
   520    549   entity4(PROLOG_STATE *state,
   521    550           int tok,
   522         -        const char *ptr,
   523         -        const char *end,
   524         -        const ENCODING *enc)
          551  +        const char *UNUSED_P(ptr),
          552  +        const char *UNUSED_P(end),
          553  +        const ENCODING *UNUSED_P(enc))
   525    554   {
   526    555     switch (tok) {
   527    556     case XML_TOK_PROLOG_S:
   528    557       return XML_ROLE_ENTITY_NONE;
   529    558     case XML_TOK_LITERAL:
   530    559       state->handler = entity5;
   531    560       return XML_ROLE_ENTITY_SYSTEM_ID;
................................................................................
   555    584     }
   556    585     return common(state, tok);
   557    586   }
   558    587   
   559    588   static int PTRCALL
   560    589   entity6(PROLOG_STATE *state,
   561    590           int tok,
   562         -        const char *ptr,
   563         -        const char *end,
   564         -        const ENCODING *enc)
          591  +        const char *UNUSED_P(ptr),
          592  +        const char *UNUSED_P(end),
          593  +        const ENCODING *UNUSED_P(enc))
   565    594   {
   566    595     switch (tok) {
   567    596     case XML_TOK_PROLOG_S:
   568    597       return XML_ROLE_ENTITY_NONE;
   569    598     case XML_TOK_NAME:
   570    599       state->handler = declClose;
   571    600       state->role_none = XML_ROLE_ENTITY_NONE;
................................................................................
   601    630     }
   602    631     return common(state, tok);
   603    632   }
   604    633   
   605    634   static int PTRCALL
   606    635   entity8(PROLOG_STATE *state,
   607    636           int tok,
   608         -        const char *ptr,
   609         -        const char *end,
   610         -        const ENCODING *enc)
          637  +        const char *UNUSED_P(ptr),
          638  +        const char *UNUSED_P(end),
          639  +        const ENCODING *UNUSED_P(enc))
   611    640   {
   612    641     switch (tok) {
   613    642     case XML_TOK_PROLOG_S:
   614    643       return XML_ROLE_ENTITY_NONE;
   615    644     case XML_TOK_LITERAL:
   616    645       state->handler = entity9;
   617    646       return XML_ROLE_ENTITY_PUBLIC_ID;
................................................................................
   618    647     }
   619    648     return common(state, tok);
   620    649   }
   621    650   
   622    651   static int PTRCALL
   623    652   entity9(PROLOG_STATE *state,
   624    653           int tok,
   625         -        const char *ptr,
   626         -        const char *end,
   627         -        const ENCODING *enc)
          654  +        const char *UNUSED_P(ptr),
          655  +        const char *UNUSED_P(end),
          656  +        const ENCODING *UNUSED_P(enc))
   628    657   {
   629    658     switch (tok) {
   630    659     case XML_TOK_PROLOG_S:
   631    660       return XML_ROLE_ENTITY_NONE;
   632    661     case XML_TOK_LITERAL:
   633    662       state->handler = entity10;
   634    663       return XML_ROLE_ENTITY_SYSTEM_ID;
................................................................................
   635    664     }
   636    665     return common(state, tok);
   637    666   }
   638    667   
   639    668   static int PTRCALL
   640    669   entity10(PROLOG_STATE *state,
   641    670            int tok,
   642         -         const char *ptr,
   643         -         const char *end,
   644         -         const ENCODING *enc)
          671  +         const char *UNUSED_P(ptr),
          672  +         const char *UNUSED_P(end),
          673  +         const ENCODING *UNUSED_P(enc))
   645    674   {
   646    675     switch (tok) {
   647    676     case XML_TOK_PROLOG_S:
   648    677       return XML_ROLE_ENTITY_NONE;
   649    678     case XML_TOK_DECL_CLOSE:
   650    679       setTopLevel(state);
   651    680       return XML_ROLE_ENTITY_COMPLETE;
................................................................................
   652    681     }
   653    682     return common(state, tok);
   654    683   }
   655    684   
   656    685   static int PTRCALL
   657    686   notation0(PROLOG_STATE *state,
   658    687             int tok,
   659         -          const char *ptr,
   660         -          const char *end,
   661         -          const ENCODING *enc)
          688  +          const char *UNUSED_P(ptr),
          689  +          const char *UNUSED_P(end),
          690  +          const ENCODING *UNUSED_P(enc))
   662    691   {
   663    692     switch (tok) {
   664    693     case XML_TOK_PROLOG_S:
   665    694       return XML_ROLE_NOTATION_NONE;
   666    695     case XML_TOK_NAME:
   667    696       state->handler = notation1;
   668    697       return XML_ROLE_NOTATION_NAME;
................................................................................
   693    722     }
   694    723     return common(state, tok);
   695    724   }
   696    725   
   697    726   static int PTRCALL
   698    727   notation2(PROLOG_STATE *state,
   699    728             int tok,
   700         -          const char *ptr,
   701         -          const char *end,
   702         -          const ENCODING *enc)
          729  +          const char *UNUSED_P(ptr),
          730  +          const char *UNUSED_P(end),
          731  +          const ENCODING *UNUSED_P(enc))
   703    732   {
   704    733     switch (tok) {
   705    734     case XML_TOK_PROLOG_S:
   706    735       return XML_ROLE_NOTATION_NONE;
   707    736     case XML_TOK_LITERAL:
   708    737       state->handler = notation4;
   709    738       return XML_ROLE_NOTATION_PUBLIC_ID;
................................................................................
   710    739     }
   711    740     return common(state, tok);
   712    741   }
   713    742   
   714    743   static int PTRCALL
   715    744   notation3(PROLOG_STATE *state,
   716    745             int tok,
   717         -          const char *ptr,
   718         -          const char *end,
   719         -          const ENCODING *enc)
          746  +          const char *UNUSED_P(ptr),
          747  +          const char *UNUSED_P(end),
          748  +          const ENCODING *UNUSED_P(enc))
   720    749   {
   721    750     switch (tok) {
   722    751     case XML_TOK_PROLOG_S:
   723    752       return XML_ROLE_NOTATION_NONE;
   724    753     case XML_TOK_LITERAL:
   725    754       state->handler = declClose;
   726    755       state->role_none = XML_ROLE_NOTATION_NONE;
................................................................................
   728    757     }
   729    758     return common(state, tok);
   730    759   }
   731    760   
   732    761   static int PTRCALL
   733    762   notation4(PROLOG_STATE *state,
   734    763             int tok,
   735         -          const char *ptr,
   736         -          const char *end,
   737         -          const ENCODING *enc)
          764  +          const char *UNUSED_P(ptr),
          765  +          const char *UNUSED_P(end),
          766  +          const ENCODING *UNUSED_P(enc))
   738    767   {
   739    768     switch (tok) {
   740    769     case XML_TOK_PROLOG_S:
   741    770       return XML_ROLE_NOTATION_NONE;
   742    771     case XML_TOK_LITERAL:
   743    772       state->handler = declClose;
   744    773       state->role_none = XML_ROLE_NOTATION_NONE;
................................................................................
   749    778     }
   750    779     return common(state, tok);
   751    780   }
   752    781   
   753    782   static int PTRCALL
   754    783   attlist0(PROLOG_STATE *state,
   755    784            int tok,
   756         -         const char *ptr,
   757         -         const char *end,
   758         -         const ENCODING *enc)
          785  +         const char *UNUSED_P(ptr),
          786  +         const char *UNUSED_P(end),
          787  +         const ENCODING *UNUSED_P(enc))
   759    788   {
   760    789     switch (tok) {
   761    790     case XML_TOK_PROLOG_S:
   762    791       return XML_ROLE_ATTLIST_NONE;
   763    792     case XML_TOK_NAME:
   764    793     case XML_TOK_PREFIXED_NAME:
   765    794       state->handler = attlist1;
................................................................................
   767    796     }
   768    797     return common(state, tok);
   769    798   }
   770    799   
   771    800   static int PTRCALL
   772    801   attlist1(PROLOG_STATE *state,
   773    802            int tok,
   774         -         const char *ptr,
   775         -         const char *end,
   776         -         const ENCODING *enc)
          803  +         const char *UNUSED_P(ptr),
          804  +         const char *UNUSED_P(end),
          805  +         const ENCODING *UNUSED_P(enc))
   777    806   {
   778    807     switch (tok) {
   779    808     case XML_TOK_PROLOG_S:
   780    809       return XML_ROLE_ATTLIST_NONE;
   781    810     case XML_TOK_DECL_CLOSE:
   782    811       setTopLevel(state);
   783    812       return XML_ROLE_ATTLIST_NONE;
................................................................................
   829    858     }
   830    859     return common(state, tok);
   831    860   }
   832    861   
   833    862   static int PTRCALL
   834    863   attlist3(PROLOG_STATE *state,
   835    864            int tok,
   836         -         const char *ptr,
   837         -         const char *end,
   838         -         const ENCODING *enc)
          865  +         const char *UNUSED_P(ptr),
          866  +         const char *UNUSED_P(end),
          867  +         const ENCODING *UNUSED_P(enc))
   839    868   {
   840    869     switch (tok) {
   841    870     case XML_TOK_PROLOG_S:
   842    871       return XML_ROLE_ATTLIST_NONE;
   843    872     case XML_TOK_NMTOKEN:
   844    873     case XML_TOK_NAME:
   845    874     case XML_TOK_PREFIXED_NAME:
................................................................................
   848    877     }
   849    878     return common(state, tok);
   850    879   }
   851    880   
   852    881   static int PTRCALL
   853    882   attlist4(PROLOG_STATE *state,
   854    883            int tok,
   855         -         const char *ptr,
   856         -         const char *end,
   857         -         const ENCODING *enc)
          884  +         const char *UNUSED_P(ptr),
          885  +         const char *UNUSED_P(end),
          886  +         const ENCODING *UNUSED_P(enc))
   858    887   {
   859    888     switch (tok) {
   860    889     case XML_TOK_PROLOG_S:
   861    890       return XML_ROLE_ATTLIST_NONE;
   862    891     case XML_TOK_CLOSE_PAREN:
   863    892       state->handler = attlist8;
   864    893       return XML_ROLE_ATTLIST_NONE;
................................................................................
   868    897     }
   869    898     return common(state, tok);
   870    899   }
   871    900   
   872    901   static int PTRCALL
   873    902   attlist5(PROLOG_STATE *state,
   874    903            int tok,
   875         -         const char *ptr,
   876         -         const char *end,
   877         -         const ENCODING *enc)
          904  +         const char *UNUSED_P(ptr),
          905  +         const char *UNUSED_P(end),
          906  +         const ENCODING *UNUSED_P(enc))
   878    907   {
   879    908     switch (tok) {
   880    909     case XML_TOK_PROLOG_S:
   881    910       return XML_ROLE_ATTLIST_NONE;
   882    911     case XML_TOK_OPEN_PAREN:
   883    912       state->handler = attlist6;
   884    913       return XML_ROLE_ATTLIST_NONE;
................................................................................
   885    914     }
   886    915     return common(state, tok);
   887    916   }
   888    917   
   889    918   static int PTRCALL
   890    919   attlist6(PROLOG_STATE *state,
   891    920            int tok,
   892         -         const char *ptr,
   893         -         const char *end,
   894         -         const ENCODING *enc)
          921  +         const char *UNUSED_P(ptr),
          922  +         const char *UNUSED_P(end),
          923  +         const ENCODING *UNUSED_P(enc))
   895    924   {
   896    925     switch (tok) {
   897    926     case XML_TOK_PROLOG_S:
   898    927       return XML_ROLE_ATTLIST_NONE;
   899    928     case XML_TOK_NAME:
   900    929       state->handler = attlist7;
   901    930       return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
................................................................................
   902    931     }
   903    932     return common(state, tok);
   904    933   }
   905    934   
   906    935   static int PTRCALL
   907    936   attlist7(PROLOG_STATE *state,
   908    937            int tok,
   909         -         const char *ptr,
   910         -         const char *end,
   911         -         const ENCODING *enc)
          938  +         const char *UNUSED_P(ptr),
          939  +         const char *UNUSED_P(end),
          940  +         const ENCODING *UNUSED_P(enc))
   912    941   {
   913    942     switch (tok) {
   914    943     case XML_TOK_PROLOG_S:
   915    944       return XML_ROLE_ATTLIST_NONE;
   916    945     case XML_TOK_CLOSE_PAREN:
   917    946       state->handler = attlist8;
   918    947       return XML_ROLE_ATTLIST_NONE;
................................................................................
   963    992     }
   964    993     return common(state, tok);
   965    994   }
   966    995   
   967    996   static int PTRCALL
   968    997   attlist9(PROLOG_STATE *state,
   969    998            int tok,
   970         -         const char *ptr,
   971         -         const char *end,
   972         -         const ENCODING *enc)
          999  +         const char *UNUSED_P(ptr),
         1000  +         const char *UNUSED_P(end),
         1001  +         const ENCODING *UNUSED_P(enc))
   973   1002   {
   974   1003     switch (tok) {
   975   1004     case XML_TOK_PROLOG_S:
   976   1005       return XML_ROLE_ATTLIST_NONE;
   977   1006     case XML_TOK_LITERAL:
   978   1007       state->handler = attlist1;
   979   1008       return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
................................................................................
   980   1009     }
   981   1010     return common(state, tok);
   982   1011   }
   983   1012   
   984   1013   static int PTRCALL
   985   1014   element0(PROLOG_STATE *state,
   986   1015            int tok,
   987         -         const char *ptr,
   988         -         const char *end,
   989         -         const ENCODING *enc)
         1016  +         const char *UNUSED_P(ptr),
         1017  +         const char *UNUSED_P(end),
         1018  +         const ENCODING *UNUSED_P(enc))
   990   1019   {
   991   1020     switch (tok) {
   992   1021     case XML_TOK_PROLOG_S:
   993   1022       return XML_ROLE_ELEMENT_NONE;
   994   1023     case XML_TOK_NAME:
   995   1024     case XML_TOK_PREFIXED_NAME:
   996   1025       state->handler = element1;
................................................................................
  1068   1097     }
  1069   1098     return common(state, tok);
  1070   1099   }
  1071   1100   
  1072   1101   static int PTRCALL
  1073   1102   element3(PROLOG_STATE *state,
  1074   1103            int tok,
  1075         -         const char *ptr,
  1076         -         const char *end,
  1077         -         const ENCODING *enc)
         1104  +         const char *UNUSED_P(ptr),
         1105  +         const char *UNUSED_P(end),
         1106  +         const ENCODING *UNUSED_P(enc))
  1078   1107   {
  1079   1108     switch (tok) {
  1080   1109     case XML_TOK_PROLOG_S:
  1081   1110       return XML_ROLE_ELEMENT_NONE;
  1082   1111     case XML_TOK_CLOSE_PAREN:
  1083   1112       state->handler = declClose;
  1084   1113       state->role_none = XML_ROLE_ELEMENT_NONE;
................................................................................
  1093   1122     }
  1094   1123     return common(state, tok);
  1095   1124   }
  1096   1125   
  1097   1126   static int PTRCALL
  1098   1127   element4(PROLOG_STATE *state,
  1099   1128            int tok,
  1100         -         const char *ptr,
  1101         -         const char *end,
  1102         -         const ENCODING *enc)
         1129  +         const char *UNUSED_P(ptr),
         1130  +         const char *UNUSED_P(end),
         1131  +         const ENCODING *UNUSED_P(enc))
  1103   1132   {
  1104   1133     switch (tok) {
  1105   1134     case XML_TOK_PROLOG_S:
  1106   1135       return XML_ROLE_ELEMENT_NONE;
  1107   1136     case XML_TOK_NAME:
  1108   1137     case XML_TOK_PREFIXED_NAME:
  1109   1138       state->handler = element5;
................................................................................
  1111   1140     }
  1112   1141     return common(state, tok);
  1113   1142   }
  1114   1143   
  1115   1144   static int PTRCALL
  1116   1145   element5(PROLOG_STATE *state,
  1117   1146            int tok,
  1118         -         const char *ptr,
  1119         -         const char *end,
  1120         -         const ENCODING *enc)
         1147  +         const char *UNUSED_P(ptr),
         1148  +         const char *UNUSED_P(end),
         1149  +         const ENCODING *UNUSED_P(enc))
  1121   1150   {
  1122   1151     switch (tok) {
  1123   1152     case XML_TOK_PROLOG_S:
  1124   1153       return XML_ROLE_ELEMENT_NONE;
  1125   1154     case XML_TOK_CLOSE_PAREN_ASTERISK:
  1126   1155       state->handler = declClose;
  1127   1156       state->role_none = XML_ROLE_ELEMENT_NONE;
................................................................................
  1132   1161     }
  1133   1162     return common(state, tok);
  1134   1163   }
  1135   1164   
  1136   1165   static int PTRCALL
  1137   1166   element6(PROLOG_STATE *state,
  1138   1167            int tok,
  1139         -         const char *ptr,
  1140         -         const char *end,
  1141         -         const ENCODING *enc)
         1168  +         const char *UNUSED_P(ptr),
         1169  +         const char *UNUSED_P(end),
         1170  +         const ENCODING *UNUSED_P(enc))
  1142   1171   {
  1143   1172     switch (tok) {
  1144   1173     case XML_TOK_PROLOG_S:
  1145   1174       return XML_ROLE_ELEMENT_NONE;
  1146   1175     case XML_TOK_OPEN_PAREN:
  1147   1176       state->level += 1;
  1148   1177       return XML_ROLE_GROUP_OPEN;
................................................................................
  1162   1191     }
  1163   1192     return common(state, tok);
  1164   1193   }
  1165   1194   
  1166   1195   static int PTRCALL
  1167   1196   element7(PROLOG_STATE *state,
  1168   1197            int tok,
  1169         -         const char *ptr,
  1170         -         const char *end,
  1171         -         const ENCODING *enc)
         1198  +         const char *UNUSED_P(ptr),
         1199  +         const char *UNUSED_P(end),
         1200  +         const ENCODING *UNUSED_P(enc))
  1172   1201   {
  1173   1202     switch (tok) {
  1174   1203     case XML_TOK_PROLOG_S:
  1175   1204       return XML_ROLE_ELEMENT_NONE;
  1176   1205     case XML_TOK_CLOSE_PAREN:
  1177   1206       state->level -= 1;
  1178   1207       if (state->level == 0) {
................................................................................
  1236   1265     }
  1237   1266     return common(state, tok);
  1238   1267   }
  1239   1268   
  1240   1269   static int PTRCALL
  1241   1270   condSect1(PROLOG_STATE *state,
  1242   1271             int tok,
  1243         -          const char *ptr,
  1244         -          const char *end,
  1245         -          const ENCODING *enc)
         1272  +          const char *UNUSED_P(ptr),
         1273  +          const char *UNUSED_P(end),
         1274  +          const ENCODING *UNUSED_P(enc))
  1246   1275   {
  1247   1276     switch (tok) {
  1248   1277     case XML_TOK_PROLOG_S:
  1249   1278       return XML_ROLE_NONE;
  1250   1279     case XML_TOK_OPEN_BRACKET:
  1251   1280       state->handler = externalSubset1;
  1252   1281       state->includeLevel += 1;
................................................................................
  1254   1283     }
  1255   1284     return common(state, tok);
  1256   1285   }
  1257   1286   
  1258   1287   static int PTRCALL
  1259   1288   condSect2(PROLOG_STATE *state,
  1260   1289             int tok,
  1261         -          const char *ptr,
  1262         -          const char *end,
  1263         -          const ENCODING *enc)
         1290  +          const char *UNUSED_P(ptr),
         1291  +          const char *UNUSED_P(end),
         1292  +          const ENCODING *UNUSED_P(enc))
  1264   1293   {
  1265   1294     switch (tok) {
  1266   1295     case XML_TOK_PROLOG_S:
  1267   1296       return XML_ROLE_NONE;
  1268   1297     case XML_TOK_OPEN_BRACKET:
  1269   1298       state->handler = externalSubset1;
  1270   1299       return XML_ROLE_IGNORE_SECT;
................................................................................
  1273   1302   }
  1274   1303   
  1275   1304   #endif /* XML_DTD */
  1276   1305   
  1277   1306   static int PTRCALL
  1278   1307   declClose(PROLOG_STATE *state,
  1279   1308             int tok,
  1280         -          const char *ptr,
  1281         -          const char *end,
  1282         -          const ENCODING *enc)
         1309  +          const char *UNUSED_P(ptr),
         1310  +          const char *UNUSED_P(end),
         1311  +          const ENCODING *UNUSED_P(enc))
  1283   1312   {
  1284   1313     switch (tok) {
  1285   1314     case XML_TOK_PROLOG_S:
  1286   1315       return state->role_none;
  1287   1316     case XML_TOK_DECL_CLOSE:
  1288   1317       setTopLevel(state);
  1289   1318       return state->role_none;
  1290   1319     }
  1291   1320     return common(state, tok);
  1292   1321   }
  1293   1322   
         1323  +/* This function will only be invoked if the internal logic of the
         1324  + * parser has broken down.  It is used in two cases:
         1325  + *
         1326  + * 1: When the XML prolog has been finished.  At this point the
         1327  + * processor (the parser level above these role handlers) should
         1328  + * switch from prologProcessor to contentProcessor and reinitialise
         1329  + * the handler function.
         1330  + *
         1331  + * 2: When an error has been detected (via common() below).  At this
         1332  + * point again the processor should be switched to errorProcessor,
         1333  + * which will never call a handler.
         1334  + *
         1335  + * The result of this is that error() can only be called if the
         1336  + * processor switch failed to happen, which is an internal error and
         1337  + * therefore we shouldn't be able to provoke it simply by using the
         1338  + * library.  It is a necessary backstop, however, so we merely exclude
         1339  + * it from the coverage statistics.
         1340  + *
         1341  + * LCOV_EXCL_START
         1342  + */
  1294   1343   static int PTRCALL
  1295         -error(PROLOG_STATE *state,
  1296         -      int tok,
  1297         -      const char *ptr,
  1298         -      const char *end,
  1299         -      const ENCODING *enc)
         1344  +error(PROLOG_STATE *UNUSED_P(state),
         1345  +      int UNUSED_P(tok),
         1346  +      const char *UNUSED_P(ptr),
         1347  +      const char *UNUSED_P(end),
         1348  +      const ENCODING *UNUSED_P(enc))
  1300   1349   {
  1301   1350     return XML_ROLE_NONE;
  1302   1351   }
         1352  +/* LCOV_EXCL_STOP */
  1303   1353   
  1304   1354   static int FASTCALL
  1305   1355   common(PROLOG_STATE *state, int tok)
  1306   1356   {
  1307   1357   #ifdef XML_DTD
  1308   1358     if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
  1309   1359       return XML_ROLE_INNER_PARAM_ENTITY_REF;

Changes to expat/xmlrole.h.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   #ifndef XmlRole_INCLUDED
     6     34   #define XmlRole_INCLUDED 1
     7     35   
     8     36   #ifdef __VMS
     9     37   /*      0        1         2         3      0        1         2         3

Changes to expat/xmltok.c.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   #include <stddef.h>
           34  +#include <string.h>  /* memcpy */
     6     35   
     7         -#ifdef COMPILED_FROM_DSP
           36  +#if defined(_MSC_VER) && (_MSC_VER <= 1700)
           37  +  /* for vs2012/11.0/1700 and earlier Visual Studio compilers */
           38  +# define bool   int
           39  +# define false  0
           40  +# define true   1
           41  +#else
           42  +# include <stdbool.h>
           43  +#endif
           44  +
           45  +
           46  +#ifdef _WIN32
     8     47   #include "winconfig.h"
     9         -#elif defined(MACOS_CLASSIC)
    10         -#include "macconfig.h"
    11         -#elif defined(__amigaos4__)
    12         -#include "amigaconfig.h"
    13         -#elif defined(__WATCOMC__)
    14         -#include "watcomconfig.h"
    15     48   #else
    16     49   #ifdef HAVE_EXPAT_CONFIG_H
    17     50   #include <expat_config.h>
    18     51   #endif
    19         -#endif /* ndef COMPILED_FROM_DSP */
           52  +#endif /* ndef _WIN32 */
    20     53   
    21     54   #include "expat_external.h"
    22     55   #include "internal.h"
    23     56   #include "xmltok.h"
    24     57   #include "nametab.h"
    25     58   
    26     59   #ifdef XML_DTD
................................................................................
    29     62   #define IGNORE_SECTION_TOK_VTABLE /* as nothing */
    30     63   #endif
    31     64   
    32     65   #define VTABLE1 \
    33     66     { PREFIX(prologTok), PREFIX(contentTok), \
    34     67       PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
    35     68     { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
    36         -  PREFIX(sameName), \
    37     69     PREFIX(nameMatchesAscii), \
    38     70     PREFIX(nameLength), \
    39     71     PREFIX(skipS), \
    40     72     PREFIX(getAtts), \
    41     73     PREFIX(charRefNumber), \
    42     74     PREFIX(predefinedEntityName), \
    43     75     PREFIX(updatePosition), \
    44     76     PREFIX(isPublicId)
    45     77   
    46     78   #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
    47     79   
    48     80   #define UCS2_GET_NAMING(pages, hi, lo) \
    49         -   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
           81  +   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F)))
    50     82   
    51     83   /* A 2 byte UTF-8 representation splits the characters 11 bits between
    52     84      the bottom 5 and 6 bits of the bytes.  We need 8 bits to index into
    53     85      pages, 3 bits to add to that index and 5 bits to generate the mask.
    54     86   */
    55     87   #define UTF8_GET_NAMING2(pages, byte) \
    56     88       (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
    57     89                         + ((((byte)[0]) & 3) << 1) \
    58     90                         + ((((byte)[1]) >> 5) & 1)] \
    59         -         & (1 << (((byte)[1]) & 0x1F)))
           91  +         & (1u << (((byte)[1]) & 0x1F)))
    60     92   
    61     93   /* A 3 byte UTF-8 representation splits the characters 16 bits between
    62     94      the bottom 4, 6 and 6 bits of the bytes.  We need 8 bits to index
    63     95      into pages, 3 bits to add to that index and 5 bits to generate the
    64     96      mask.
    65     97   */
    66     98   #define UTF8_GET_NAMING3(pages, byte) \
    67     99     (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
    68    100                                + ((((byte)[1]) >> 2) & 0xF)] \
    69    101                          << 3) \
    70    102                         + ((((byte)[1]) & 3) << 1) \
    71    103                         + ((((byte)[2]) >> 5) & 1)] \
    72         -         & (1 << (((byte)[2]) & 0x1F)))
          104  +         & (1u << (((byte)[2]) & 0x1F)))
    73    105   
    74    106   #define UTF8_GET_NAMING(pages, p, n) \
    75    107     ((n) == 2 \
    76    108     ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
    77    109     : ((n) == 3 \
    78    110        ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
    79    111        : 0))
................................................................................
   118    150       (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
   119    151       : \
   120    152       ((p)[1] & 0x80) == 0 \
   121    153       || \
   122    154       ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
   123    155   
   124    156   static int PTRFASTCALL
   125         -isNever(const ENCODING *enc, const char *p)
          157  +isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p))
   126    158   {
   127    159     return 0;
   128    160   }
   129    161   
   130    162   static int PTRFASTCALL
   131         -utf8_isName2(const ENCODING *enc, const char *p)
          163  +utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p)
   132    164   {
   133    165     return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
   134    166   }
   135    167   
   136    168   static int PTRFASTCALL
   137         -utf8_isName3(const ENCODING *enc, const char *p)
          169  +utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p)
   138    170   {
   139    171     return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
   140    172   }
   141    173   
   142    174   #define utf8_isName4 isNever
   143    175   
   144    176   static int PTRFASTCALL
   145         -utf8_isNmstrt2(const ENCODING *enc, const char *p)
          177  +utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p)
   146    178   {
   147    179     return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
   148    180   }
   149    181   
   150    182   static int PTRFASTCALL
   151         -utf8_isNmstrt3(const ENCODING *enc, const char *p)
          183  +utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p)
   152    184   {
   153    185     return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
   154    186   }
   155    187   
   156    188   #define utf8_isNmstrt4 isNever
   157    189   
   158    190   static int PTRFASTCALL
   159         -utf8_isInvalid2(const ENCODING *enc, const char *p)
          191  +utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p)
   160    192   {
   161    193     return UTF8_INVALID2((const unsigned char *)p);
   162    194   }
   163    195   
   164    196   static int PTRFASTCALL
   165         -utf8_isInvalid3(const ENCODING *enc, const char *p)
          197  +utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p)
   166    198   {
   167    199     return UTF8_INVALID3((const unsigned char *)p);
   168    200   }
   169    201   
   170    202   static int PTRFASTCALL
   171         -utf8_isInvalid4(const ENCODING *enc, const char *p)
          203  +utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p)
   172    204   {
   173    205     return UTF8_INVALID4((const unsigned char *)p);
   174    206   }
   175    207   
   176    208   struct normal_encoding {
   177    209     ENCODING enc;
   178    210     unsigned char type[256];
................................................................................
   218    250    E ## isNmstrt2, \
   219    251    E ## isNmstrt3, \
   220    252    E ## isNmstrt4, \
   221    253    E ## isInvalid2, \
   222    254    E ## isInvalid3, \
   223    255    E ## isInvalid4
   224    256   
          257  +#define NULL_VTABLE \
          258  + /* isName2 */ NULL, \
          259  + /* isName3 */ NULL, \
          260  + /* isName4 */ NULL, \
          261  + /* isNmstrt2 */ NULL, \
          262  + /* isNmstrt3 */ NULL, \
          263  + /* isNmstrt4 */ NULL, \
          264  + /* isInvalid2 */ NULL, \
          265  + /* isInvalid3 */ NULL, \
          266  + /* isInvalid4 */ NULL
          267  +
   225    268   static int FASTCALL checkCharRefNumber(int);
   226    269   
   227    270   #include "xmltok_impl.h"
   228    271   #include "ascii.h"
   229    272   
   230    273   #ifdef XML_MIN_SIZE
   231    274   #define sb_isNameMin isNever
................................................................................
   314    357   enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
   315    358     UTF8_cval1 = 0x00,
   316    359     UTF8_cval2 = 0xc0,
   317    360     UTF8_cval3 = 0xe0,
   318    361     UTF8_cval4 = 0xf0
   319    362   };
   320    363   
   321         -static void PTRCALL
   322         -utf8_toUtf8(const ENCODING *enc,
          364  +void
          365  +_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef)
          366  +{
          367  +  const char * fromLim = *fromLimRef;
          368  +  size_t walked = 0;
          369  +  for (; fromLim > from; fromLim--, walked++) {
          370  +    const unsigned char prev = (unsigned char)fromLim[-1];
          371  +    if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
          372  +      if (walked + 1 >= 4) {
          373  +        fromLim += 4 - 1;
          374  +        break;
          375  +      } else {
          376  +        walked = 0;
          377  +      }
          378  +    } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
          379  +      if (walked + 1 >= 3) {
          380  +        fromLim += 3 - 1;
          381  +        break;
          382  +      } else {
          383  +        walked = 0;
          384  +      }
          385  +    } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
          386  +      if (walked + 1 >= 2) {
          387  +        fromLim += 2 - 1;
          388  +        break;
          389  +      } else {
          390  +        walked = 0;
          391  +      }
          392  +    } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
          393  +      break;
          394  +    }
          395  +  }
          396  +  *fromLimRef = fromLim;
          397  +}
          398  +
          399  +static enum XML_Convert_Result PTRCALL
          400  +utf8_toUtf8(const ENCODING *UNUSED_P(enc),
   323    401               const char **fromP, const char *fromLim,
   324    402               char **toP, const char *toLim)
   325    403   {
   326         -  char *to;
   327         -  const char *from;
   328         -  if (fromLim - *fromP > toLim - *toP) {
   329         -    /* Avoid copying partial characters. */
   330         -    for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
   331         -      if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
   332         -        break;
   333         -  }
   334         -  for (to = *toP, from = *fromP; from != fromLim; from++, to++)
   335         -    *to = *from;
   336         -  *fromP = from;
   337         -  *toP = to;
   338         -}
   339         -
   340         -static void PTRCALL
          404  +  bool input_incomplete = false;
          405  +  bool output_exhausted = false;
          406  +
          407  +  /* Avoid copying partial characters (due to limited space). */
          408  +  const ptrdiff_t bytesAvailable = fromLim - *fromP;
          409  +  const ptrdiff_t bytesStorable = toLim - *toP;
          410  +  if (bytesAvailable > bytesStorable) {
          411  +    fromLim = *fromP + bytesStorable;
          412  +    output_exhausted = true;
          413  +  }
          414  +
          415  +  /* Avoid copying partial characters (from incomplete input). */
          416  +  {
          417  +    const char * const fromLimBefore = fromLim;
          418  +    _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim);
          419  +    if (fromLim < fromLimBefore) {
          420  +      input_incomplete = true;
          421  +    }
          422  +  }
          423  +
          424  +  {
          425  +    const ptrdiff_t bytesToCopy = fromLim - *fromP;
          426  +    memcpy(*toP, *fromP, bytesToCopy);
          427  +    *fromP += bytesToCopy;
          428  +    *toP += bytesToCopy;
          429  +  }
          430  +
          431  +  if (output_exhausted)  /* needs to go first */
          432  +    return XML_CONVERT_OUTPUT_EXHAUSTED;
          433  +  else if (input_incomplete)
          434  +    return XML_CONVERT_INPUT_INCOMPLETE;
          435  +  else
          436  +    return XML_CONVERT_COMPLETED;
          437  +}
          438  +
          439  +static enum XML_Convert_Result PTRCALL
   341    440   utf8_toUtf16(const ENCODING *enc,
   342    441                const char **fromP, const char *fromLim,
   343    442                unsigned short **toP, const unsigned short *toLim)
   344    443   {
          444  +  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
   345    445     unsigned short *to = *toP;
   346    446     const char *from = *fromP;
   347         -  while (from != fromLim && to != toLim) {
          447  +  while (from < fromLim && to < toLim) {
   348    448       switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
   349    449       case BT_LEAD2:
          450  +      if (fromLim - from < 2) {
          451  +        res = XML_CONVERT_INPUT_INCOMPLETE;
          452  +        goto after;
          453  +      }
   350    454         *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
   351    455         from += 2;
   352    456         break;
   353    457       case BT_LEAD3:
          458  +      if (fromLim - from < 3) {
          459  +        res = XML_CONVERT_INPUT_INCOMPLETE;
          460  +        goto after;
          461  +      }
   354    462         *to++ = (unsigned short)(((from[0] & 0xf) << 12)
   355    463                                  | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
   356    464         from += 3;
   357    465         break;
   358    466       case BT_LEAD4:
   359    467         {
   360    468           unsigned long n;
   361         -        if (to + 1 == toLim)
          469  +        if (toLim - to < 2) {
          470  +          res = XML_CONVERT_OUTPUT_EXHAUSTED;
          471  +          goto after;
          472  +        }
          473  +        if (fromLim - from < 4) {
          474  +          res = XML_CONVERT_INPUT_INCOMPLETE;
   362    475             goto after;
          476  +        }
   363    477           n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
   364    478               | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
   365    479           n -= 0x10000;
   366    480           to[0] = (unsigned short)((n >> 10) | 0xD800);
   367    481           to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
   368    482           to += 2;
   369    483           from += 4;
................................................................................
   370    484         }
   371    485         break;
   372    486       default:
   373    487         *to++ = *from++;
   374    488         break;
   375    489       }
   376    490     }
          491  +  if (from < fromLim)
          492  +    res = XML_CONVERT_OUTPUT_EXHAUSTED;
   377    493   after:
   378    494     *fromP = from;
   379    495     *toP = to;
          496  +  return res;
   380    497   }
   381    498   
   382    499   #ifdef XML_NS
   383    500   static const struct normal_encoding utf8_encoding_ns = {
   384    501     { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
   385    502     {
   386    503   #include "asciitab.h"
................................................................................
   421    538   #include "iasciitab.h"
   422    539   #undef BT_COLON
   423    540   #include "utf8tab.h"
   424    541     },
   425    542     STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
   426    543   };
   427    544   
   428         -static void PTRCALL
   429         -latin1_toUtf8(const ENCODING *enc,
          545  +static enum XML_Convert_Result PTRCALL
          546  +latin1_toUtf8(const ENCODING *UNUSED_P(enc),
   430    547                 const char **fromP, const char *fromLim,
   431    548                 char **toP, const char *toLim)
   432    549   {
   433    550     for (;;) {
   434    551       unsigned char c;
   435    552       if (*fromP == fromLim)
   436         -      break;
          553  +      return XML_CONVERT_COMPLETED;
   437    554       c = (unsigned char)**fromP;
   438    555       if (c & 0x80) {
   439    556         if (toLim - *toP < 2)
   440         -        break;
          557  +        return XML_CONVERT_OUTPUT_EXHAUSTED;
   441    558         *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
   442    559         *(*toP)++ = (char)((c & 0x3f) | 0x80);
   443    560         (*fromP)++;
   444    561       }
   445    562       else {
   446    563         if (*toP == toLim)
   447         -        break;
          564  +        return XML_CONVERT_OUTPUT_EXHAUSTED;
   448    565         *(*toP)++ = *(*fromP)++;
   449    566       }
   450    567     }
   451    568   }
   452    569   
   453         -static void PTRCALL
   454         -latin1_toUtf16(const ENCODING *enc,
          570  +static enum XML_Convert_Result PTRCALL
          571  +latin1_toUtf16(const ENCODING *UNUSED_P(enc),
   455    572                  const char **fromP, const char *fromLim,
   456    573                  unsigned short **toP, const unsigned short *toLim)
   457    574   {
   458         -  while (*fromP != fromLim && *toP != toLim)
          575  +  while (*fromP < fromLim && *toP < toLim)
   459    576       *(*toP)++ = (unsigned char)*(*fromP)++;
          577  +
          578  +  if ((*toP == toLim) && (*fromP < fromLim))
          579  +    return XML_CONVERT_OUTPUT_EXHAUSTED;
          580  +  else
          581  +    return XML_CONVERT_COMPLETED;
   460    582   }
   461    583   
   462    584   #ifdef XML_NS
   463    585   
   464    586   static const struct normal_encoding latin1_encoding_ns = {
   465    587     { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
   466    588     {
   467    589   #include "asciitab.h"
   468    590   #include "latin1tab.h"
   469    591     },
   470         -  STANDARD_VTABLE(sb_)
          592  +  STANDARD_VTABLE(sb_) NULL_VTABLE
   471    593   };
   472    594   
   473    595   #endif
   474    596   
   475    597   static const struct normal_encoding latin1_encoding = {
   476    598     { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
   477    599     {
   478    600   #define BT_COLON BT_NMSTRT
   479    601   #include "asciitab.h"
   480    602   #undef BT_COLON
   481    603   #include "latin1tab.h"
   482    604     },
   483         -  STANDARD_VTABLE(sb_)
          605  +  STANDARD_VTABLE(sb_) NULL_VTABLE
   484    606   };
   485    607   
   486         -static void PTRCALL
   487         -ascii_toUtf8(const ENCODING *enc,
          608  +static enum XML_Convert_Result PTRCALL
          609  +ascii_toUtf8(const ENCODING *UNUSED_P(enc),
   488    610                const char **fromP, const char *fromLim,
   489    611                char **toP, const char *toLim)
   490    612   {
   491         -  while (*fromP != fromLim && *toP != toLim)
          613  +  while (*fromP < fromLim && *toP < toLim)
   492    614       *(*toP)++ = *(*fromP)++;
          615  +
          616  +  if ((*toP == toLim) && (*fromP < fromLim))
          617  +    return XML_CONVERT_OUTPUT_EXHAUSTED;
          618  +  else
          619  +    return XML_CONVERT_COMPLETED;
   493    620   }
   494    621   
   495    622   #ifdef XML_NS
   496    623   
   497    624   static const struct normal_encoding ascii_encoding_ns = {
   498    625     { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
   499    626     {
   500    627   #include "asciitab.h"
   501    628   /* BT_NONXML == 0 */
   502    629     },
   503         -  STANDARD_VTABLE(sb_)
          630  +  STANDARD_VTABLE(sb_) NULL_VTABLE
   504    631   };
   505    632   
   506    633   #endif
   507    634   
   508    635   static const struct normal_encoding ascii_encoding = {
   509    636     { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
   510    637     {
   511    638   #define BT_COLON BT_NMSTRT
   512    639   #include "asciitab.h"
   513    640   #undef BT_COLON
   514    641   /* BT_NONXML == 0 */
   515    642     },
   516         -  STANDARD_VTABLE(sb_)
          643  +  STANDARD_VTABLE(sb_) NULL_VTABLE
   517    644   };
   518    645   
   519    646   static int PTRFASTCALL
   520    647   unicode_byte_type(char hi, char lo)
   521    648   {
   522    649     switch ((unsigned char)hi) {
   523    650     case 0xD8: case 0xD9: case 0xDA: case 0xDB:
................................................................................
   532    659       }
   533    660       break;
   534    661     }
   535    662     return BT_NONASCII;
   536    663   }
   537    664   
   538    665   #define DEFINE_UTF16_TO_UTF8(E) \
   539         -static void  PTRCALL \
   540         -E ## toUtf8(const ENCODING *enc, \
          666  +static enum XML_Convert_Result  PTRCALL \
          667  +E ## toUtf8(const ENCODING *UNUSED_P(enc), \
   541    668               const char **fromP, const char *fromLim, \
   542    669               char **toP, const char *toLim) \
   543    670   { \
   544         -  const char *from; \
   545         -  for (from = *fromP; from != fromLim; from += 2) { \
          671  +  const char *from = *fromP; \
          672  +  fromLim = from + (((fromLim - from) >> 1) << 1);  /* shrink to even */ \
          673  +  for (; from < fromLim; from += 2) { \
   546    674       int plane; \
   547    675       unsigned char lo2; \
   548    676       unsigned char lo = GET_LO(from); \
   549    677       unsigned char hi = GET_HI(from); \
   550    678       switch (hi) { \
   551    679       case 0: \
   552    680         if (lo < 0x80) { \
   553    681           if (*toP == toLim) { \
   554    682             *fromP = from; \
   555         -          return; \
          683  +          return XML_CONVERT_OUTPUT_EXHAUSTED; \
   556    684           } \
   557    685           *(*toP)++ = lo; \
   558    686           break; \
   559    687         } \
   560    688         /* fall through */ \
   561    689       case 0x1: case 0x2: case 0x3: \
   562    690       case 0x4: case 0x5: case 0x6: case 0x7: \
   563    691         if (toLim -  *toP < 2) { \
   564    692           *fromP = from; \
   565         -        return; \
          693  +        return XML_CONVERT_OUTPUT_EXHAUSTED; \
   566    694         } \
   567    695         *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
   568    696         *(*toP)++ = ((lo & 0x3f) | 0x80); \
   569    697         break; \
   570    698       default: \
   571    699         if (toLim -  *toP < 3)  { \
   572    700           *fromP = from; \
   573         -        return; \
          701  +        return XML_CONVERT_OUTPUT_EXHAUSTED; \
   574    702         } \
   575    703         /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
   576    704         *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
   577    705         *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
   578    706         *(*toP)++ = ((lo & 0x3f) | 0x80); \
   579    707         break; \
   580    708       case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
   581    709         if (toLim -  *toP < 4) { \
   582    710           *fromP = from; \
   583         -        return; \
          711  +        return XML_CONVERT_OUTPUT_EXHAUSTED; \
          712  +      } \
          713  +      if (fromLim - from < 4) { \
          714  +        *fromP = from; \
          715  +        return XML_CONVERT_INPUT_INCOMPLETE; \
   584    716         } \
   585    717         plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
   586    718         *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
   587    719         *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
   588    720         from += 2; \
   589    721         lo2 = GET_LO(from); \
   590    722         *(*toP)++ = (((lo & 0x3) << 4) \
................................................................................
   592    724                      | (lo2 >> 6) \
   593    725                      | 0x80); \
   594    726         *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
   595    727         break; \
   596    728       } \
   597    729     } \
   598    730     *fromP = from; \
          731  +  if (from < fromLim) \
          732  +    return XML_CONVERT_INPUT_INCOMPLETE; \
          733  +  else \
          734  +    return XML_CONVERT_COMPLETED; \
   599    735   }
   600    736   
   601    737   #define DEFINE_UTF16_TO_UTF16(E) \
   602         -static void  PTRCALL \
   603         -E ## toUtf16(const ENCODING *enc, \
          738  +static enum XML_Convert_Result  PTRCALL \
          739  +E ## toUtf16(const ENCODING *UNUSED_P(enc), \
   604    740                const char **fromP, const char *fromLim, \
   605    741                unsigned short **toP, const unsigned short *toLim) \
   606    742   { \
          743  +  enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
          744  +  fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1);  /* shrink to even */ \
   607    745     /* Avoid copying first half only of surrogate */ \
   608    746     if (fromLim - *fromP > ((toLim - *toP) << 1) \
   609         -      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
          747  +      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
   610    748       fromLim -= 2; \
   611         -  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
          749  +    res = XML_CONVERT_INPUT_INCOMPLETE; \
          750  +  } \
          751  +  for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
   612    752       *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
          753  +  if ((*toP == toLim) && (*fromP < fromLim)) \
          754  +    return XML_CONVERT_OUTPUT_EXHAUSTED; \
          755  +  else \
          756  +    return res; \
   613    757   }
   614    758   
   615    759   #define SET2(ptr, ch) \
   616    760     (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
   617    761   #define GET_LO(ptr) ((unsigned char)(ptr)[0])
   618    762   #define GET_HI(ptr) ((unsigned char)(ptr)[1])
   619    763   
................................................................................
   722    866       0
   723    867   #endif
   724    868     },
   725    869     {
   726    870   #include "asciitab.h"
   727    871   #include "latin1tab.h"
   728    872     },
   729         -  STANDARD_VTABLE(little2_)
          873  +  STANDARD_VTABLE(little2_) NULL_VTABLE
   730    874   };
   731    875   
   732    876   #endif
   733    877   
   734    878   static const struct normal_encoding little2_encoding = {
   735    879     { VTABLE, 2, 0,
   736    880   #if BYTEORDER == 1234
................................................................................
   741    885     },
   742    886     {
   743    887   #define BT_COLON BT_NMSTRT
   744    888   #include "asciitab.h"
   745    889   #undef BT_COLON
   746    890   #include "latin1tab.h"
   747    891     },
   748         -  STANDARD_VTABLE(little2_)
          892  +  STANDARD_VTABLE(little2_) NULL_VTABLE
   749    893   };
   750    894   
   751    895   #if BYTEORDER != 4321
   752    896   
   753    897   #ifdef XML_NS
   754    898   
   755    899   static const struct normal_encoding internal_little2_encoding_ns = {
   756    900     { VTABLE, 2, 0, 1 },
   757    901     {
   758    902   #include "iasciitab.h"
   759    903   #include "latin1tab.h"
   760    904     },
   761         -  STANDARD_VTABLE(little2_)
          905  +  STANDARD_VTABLE(little2_) NULL_VTABLE
   762    906   };
   763    907   
   764    908   #endif
   765    909   
   766    910   static const struct normal_encoding internal_little2_encoding = {
   767    911     { VTABLE, 2, 0, 1 },
   768    912     {
   769    913   #define BT_COLON BT_NMSTRT
   770    914   #include "iasciitab.h"
   771    915   #undef BT_COLON
   772    916   #include "latin1tab.h"
   773    917     },
   774         -  STANDARD_VTABLE(little2_)
          918  +  STANDARD_VTABLE(little2_) NULL_VTABLE
   775    919   };
   776    920   
   777    921   #endif
   778    922   
   779    923   
   780    924   #define BIG2_BYTE_TYPE(enc, p) \
   781    925    ((p)[0] == 0 \
................................................................................
   863   1007     0
   864   1008   #endif
   865   1009     },
   866   1010     {
   867   1011   #include "asciitab.h"
   868   1012   #include "latin1tab.h"
   869   1013     },
   870         -  STANDARD_VTABLE(big2_)
         1014  +  STANDARD_VTABLE(big2_) NULL_VTABLE
   871   1015   };
   872   1016   
   873   1017   #endif
   874   1018   
   875   1019   static const struct normal_encoding big2_encoding = {
   876   1020     { VTABLE, 2, 0,
   877   1021   #if BYTEORDER == 4321
................................................................................
   882   1026     },
   883   1027     {
   884   1028   #define BT_COLON BT_NMSTRT
   885   1029   #include "asciitab.h"
   886   1030   #undef BT_COLON
   887   1031   #include "latin1tab.h"
   888   1032     },
   889         -  STANDARD_VTABLE(big2_)
         1033  +  STANDARD_VTABLE(big2_) NULL_VTABLE
   890   1034   };
   891   1035   
   892   1036   #if BYTEORDER != 1234
   893   1037   
   894   1038   #ifdef XML_NS
   895   1039   
   896   1040   static const struct normal_encoding internal_big2_encoding_ns = {
   897   1041     { VTABLE, 2, 0, 1 },
   898   1042     {
   899   1043   #include "iasciitab.h"
   900   1044   #include "latin1tab.h"
   901   1045     },
   902         -  STANDARD_VTABLE(big2_)
         1046  +  STANDARD_VTABLE(big2_) NULL_VTABLE
   903   1047   };
   904   1048   
   905   1049   #endif
   906   1050   
   907   1051   static const struct normal_encoding internal_big2_encoding = {
   908   1052     { VTABLE, 2, 0, 1 },
   909   1053     {
   910   1054   #define BT_COLON BT_NMSTRT
   911   1055   #include "iasciitab.h"
   912   1056   #undef BT_COLON
   913   1057   #include "latin1tab.h"
   914   1058     },
   915         -  STANDARD_VTABLE(big2_)
         1059  +  STANDARD_VTABLE(big2_) NULL_VTABLE
   916   1060   };
   917   1061   
   918   1062   #endif
   919   1063   
   920   1064   #undef PREFIX
   921   1065   
   922   1066   static int FASTCALL
................................................................................
   924   1068   {
   925   1069     for (;;) {
   926   1070       char c1 = *s1++;
   927   1071       char c2 = *s2++;
   928   1072       if (ASCII_a <= c1 && c1 <= ASCII_z)
   929   1073         c1 += ASCII_A - ASCII_a;
   930   1074       if (ASCII_a <= c2 && c2 <= ASCII_z)
   931         -      c2 += ASCII_A - ASCII_a;
         1075  +      /* The following line will never get executed.  streqci() is
         1076  +       * only called from two places, both of which guarantee to put
         1077  +       * upper-case strings into s2.
         1078  +       */
         1079  +      c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
   932   1080       if (c1 != c2)
   933   1081         return 0;
   934   1082       if (!c1)
   935   1083         break;
   936   1084     }
   937   1085     return 1;
   938   1086   }
   939   1087   
   940   1088   static void PTRCALL
   941         -initUpdatePosition(const ENCODING *enc, const char *ptr,
         1089  +initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr,
   942   1090                      const char *end, POSITION *pos)
   943   1091   {
   944   1092     normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
   945   1093   }
   946   1094   
   947   1095   static int
   948   1096   toAscii(const ENCODING *enc, const char *ptr, const char *end)
................................................................................
  1196   1344       /* minN is minimum legal resulting value for N byte sequence */
  1197   1345       min2 = 0x80,
  1198   1346       min3 = 0x800,
  1199   1347       min4 = 0x10000
  1200   1348     };
  1201   1349   
  1202   1350     if (c < 0)
  1203         -    return 0;
         1351  +    return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */
  1204   1352     if (c < min2) {
  1205   1353       buf[0] = (char)(c | UTF8_cval1);
  1206   1354       return 1;
  1207   1355     }
  1208   1356     if (c < min3) {
  1209   1357       buf[0] = (char)((c >> 6) | UTF8_cval2);
  1210   1358       buf[1] = (char)((c & 0x3f) | 0x80);
................................................................................
  1219   1367     if (c < 0x110000) {
  1220   1368       buf[0] = (char)((c >> 18) | UTF8_cval4);
  1221   1369       buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
  1222   1370       buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
  1223   1371       buf[3] = (char)((c & 0x3f) | 0x80);
  1224   1372       return 4;
  1225   1373     }
  1226         -  return 0;
         1374  +  return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
  1227   1375   }
  1228   1376   
  1229   1377   int FASTCALL
  1230   1378   XmlUtf16Encode(int charNum, unsigned short *buf)
  1231   1379   {
  1232   1380     if (charNum < 0)
  1233   1381       return 0;
................................................................................
  1284   1432   unknown_isInvalid(const ENCODING *enc, const char *p)
  1285   1433   {
  1286   1434     const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
  1287   1435     int c = uenc->convert(uenc->userData, p);
  1288   1436     return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
  1289   1437   }
  1290   1438   
  1291         -static void PTRCALL
         1439  +static enum XML_Convert_Result PTRCALL
  1292   1440   unknown_toUtf8(const ENCODING *enc,
  1293   1441                  const char **fromP, const char *fromLim,
  1294   1442                  char **toP, const char *toLim)
  1295   1443   {
  1296   1444     const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
  1297   1445     char buf[XML_UTF8_ENCODE_MAX];
  1298   1446     for (;;) {
  1299   1447       const char *utf8;
  1300   1448       int n;
  1301   1449       if (*fromP == fromLim)
  1302         -      break;
         1450  +      return XML_CONVERT_COMPLETED;
  1303   1451       utf8 = uenc->utf8[(unsigned char)**fromP];
  1304   1452       n = *utf8++;
  1305   1453       if (n == 0) {
  1306   1454         int c = uenc->convert(uenc->userData, *fromP);
  1307   1455         n = XmlUtf8Encode(c, buf);
  1308   1456         if (n > toLim - *toP)
  1309         -        break;
         1457  +        return XML_CONVERT_OUTPUT_EXHAUSTED;
  1310   1458         utf8 = buf;
  1311   1459         *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
  1312   1460                    - (BT_LEAD2 - 2));
  1313   1461       }
  1314   1462       else {
  1315   1463         if (n > toLim - *toP)
  1316         -        break;
         1464  +        return XML_CONVERT_OUTPUT_EXHAUSTED;
  1317   1465         (*fromP)++;
  1318   1466       }
  1319         -    do {
  1320         -      *(*toP)++ = *utf8++;
  1321         -    } while (--n != 0);
         1467  +    memcpy(*toP, utf8, n);
         1468  +    *toP += n;
  1322   1469     }
  1323   1470   }
  1324   1471   
  1325         -static void PTRCALL
         1472  +static enum XML_Convert_Result PTRCALL
  1326   1473   unknown_toUtf16(const ENCODING *enc,
  1327   1474                   const char **fromP, const char *fromLim,
  1328   1475                   unsigned short **toP, const unsigned short *toLim)
  1329   1476   {
  1330   1477     const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
  1331         -  while (*fromP != fromLim && *toP != toLim) {
         1478  +  while (*fromP < fromLim && *toP < toLim) {
  1332   1479       unsigned short c = uenc->utf16[(unsigned char)**fromP];
  1333   1480       if (c == 0) {
  1334   1481         c = (unsigned short)
  1335   1482             uenc->convert(uenc->userData, *fromP);
  1336   1483         *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
  1337   1484                    - (BT_LEAD2 - 2));
  1338   1485       }
  1339   1486       else
  1340   1487         (*fromP)++;
  1341   1488       *(*toP)++ = c;
  1342   1489     }
         1490  +
         1491  +  if ((*toP == toLim) && (*fromP < fromLim))
         1492  +    return XML_CONVERT_OUTPUT_EXHAUSTED;
         1493  +  else
         1494  +    return XML_CONVERT_COMPLETED;
  1343   1495   }
  1344   1496   
  1345   1497   ENCODING *
  1346   1498   XmlInitUnknownEncoding(void *mem,
  1347   1499                          int *table,
  1348         -                       CONVERTER convert, 
         1500  +                       CONVERTER convert,
  1349   1501                          void *userData)
  1350   1502   {
  1351   1503     int i;
  1352   1504     struct unknown_encoding *e = (struct unknown_encoding *)mem;
  1353   1505     for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
  1354   1506       ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
  1355   1507     for (i = 0; i < 128; i++)
................................................................................
  1364   1516         /* This shouldn't really get used. */
  1365   1517         e->utf16[i] = 0xFFFF;
  1366   1518         e->utf8[i][0] = 1;
  1367   1519         e->utf8[i][1] = 0;
  1368   1520       }
  1369   1521       else if (c < 0) {
  1370   1522         if (c < -4)
         1523  +        return 0;
         1524  +      /* Multi-byte sequences need a converter function */
         1525  +      if (!convert)
  1371   1526           return 0;
  1372   1527         e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
  1373   1528         e->utf8[i][0] = 0;
  1374   1529         e->utf16[i] = 0;
  1375   1530       }
  1376   1531       else if (c < 0x80) {
  1377   1532         if (latin1_encoding.type[c] != BT_OTHER
................................................................................
  1499   1654            int state,
  1500   1655            const char *ptr,
  1501   1656            const char *end,
  1502   1657            const char **nextTokPtr)
  1503   1658   {
  1504   1659     const ENCODING **encPtr;
  1505   1660   
  1506         -  if (ptr == end)
         1661  +  if (ptr >= end)
  1507   1662       return XML_TOK_NONE;
  1508   1663     encPtr = enc->encPtr;
  1509   1664     if (ptr + 1 == end) {
  1510   1665       /* only a single byte available for auto-detection */
  1511   1666   #ifndef XML_DTD /* FIXME */
  1512   1667       /* a well-formed document entity must have more than one byte */
  1513   1668       if (state != XML_CONTENT_STATE)
................................................................................
  1635   1790   
  1636   1791   #undef NS
  1637   1792   #undef ns
  1638   1793   
  1639   1794   ENCODING *
  1640   1795   XmlInitUnknownEncodingNS(void *mem,
  1641   1796                            int *table,
  1642         -                         CONVERTER convert, 
         1797  +                         CONVERTER convert,
  1643   1798                            void *userData)
  1644   1799   {
  1645   1800     ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
  1646   1801     if (enc)
  1647   1802       ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
  1648   1803     return enc;
  1649   1804   }
  1650   1805   
  1651   1806   #endif /* XML_NS */

Changes to expat/xmltok.h.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/*
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5     33   #ifndef XmlTok_INCLUDED
     6     34   #define XmlTok_INCLUDED 1
     7     35   
     8     36   #ifdef __cplusplus
     9     37   extern "C" {
................................................................................
   125    153   struct encoding;
   126    154   typedef struct encoding ENCODING;
   127    155   
   128    156   typedef int (PTRCALL *SCANNER)(const ENCODING *,
   129    157                                  const char *,
   130    158                                  const char *,
   131    159                                  const char **);
          160  +
          161  +enum XML_Convert_Result {
          162  +  XML_CONVERT_COMPLETED = 0,
          163  +  XML_CONVERT_INPUT_INCOMPLETE = 1,
          164  +  XML_CONVERT_OUTPUT_EXHAUSTED = 2  /* and therefore potentially input remaining as well */
          165  +};
   132    166   
   133    167   struct encoding {
   134    168     SCANNER scanners[XML_N_STATES];
   135    169     SCANNER literalScanners[XML_N_LITERAL_TYPES];
   136         -  int (PTRCALL *sameName)(const ENCODING *,
   137         -                          const char *,
   138         -                          const char *);
   139    170     int (PTRCALL *nameMatchesAscii)(const ENCODING *,
   140    171                                     const char *,
   141    172                                     const char *,
   142    173                                     const char *);
   143    174     int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
   144    175     const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
   145    176     int (PTRCALL *getAtts)(const ENCODING *enc,
................................................................................
   154    185                                    const char *ptr,
   155    186                                    const char *end,
   156    187                                    POSITION *);
   157    188     int (PTRCALL *isPublicId)(const ENCODING *enc,
   158    189                               const char *ptr,
   159    190                               const char *end,
   160    191                               const char **badPtr);
   161         -  void (PTRCALL *utf8Convert)(const ENCODING *enc,
          192  +  enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
   162    193                                 const char **fromP,
   163    194                                 const char *fromLim,
   164    195                                 char **toP,
   165    196                                 const char *toLim);
   166         -  void (PTRCALL *utf16Convert)(const ENCODING *enc,
          197  +  enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
   167    198                                  const char **fromP,
   168    199                                  const char *fromLim,
   169    200                                  unsigned short **toP,
   170    201                                  const unsigned short *toLim);
   171    202     int minBytesPerChar;
   172    203     char isUtf8;
   173    204     char isUtf16;
................................................................................
   222    253   
   223    254   #define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
   224    255      XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
   225    256   
   226    257   #define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
   227    258      XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
   228    259   
   229         -#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
   230         -
   231    260   #define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
   232    261     (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
   233    262   
   234    263   #define XmlNameLength(enc, ptr) \
   235    264     (((enc)->nameLength)(enc, ptr))
   236    265   
   237    266   #define XmlSkipS(enc, ptr) \

Changes to expat/xmltok_impl.c.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/* This file is included!
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5         -/* This file is included! */
     6     33   #ifdef XML_TOK_IMPL_C
     7     34   
     8     35   #ifndef IS_INVALID_CHAR
     9     36   #define IS_INVALID_CHAR(enc, ptr, n) (0)
    10     37   #endif
    11     38   
    12     39   #define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
................................................................................
    82    109     CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
    83    110     CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
    84    111     CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
    85    112   
    86    113   #ifndef PREFIX
    87    114   #define PREFIX(ident) ident
    88    115   #endif
          116  +
          117  +
          118  +#define HAS_CHARS(enc, ptr, end, count) \
          119  +    (end - ptr >= count * MINBPC(enc))
          120  +
          121  +#define HAS_CHAR(enc, ptr, end) \
          122  +    HAS_CHARS(enc, ptr, end, 1)
          123  +
          124  +#define REQUIRE_CHARS(enc, ptr, end, count) \
          125  +    { \
          126  +      if (! HAS_CHARS(enc, ptr, end, count)) { \
          127  +        return XML_TOK_PARTIAL; \
          128  +      } \
          129  +    }
          130  +
          131  +#define REQUIRE_CHAR(enc, ptr, end) \
          132  +    REQUIRE_CHARS(enc, ptr, end, 1)
          133  +
    89    134   
    90    135   /* ptr points to character following "<!-" */
    91    136   
    92    137   static int PTRCALL
    93    138   PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
    94    139                       const char *end, const char **nextTokPtr)
    95    140   {
    96         -  if (ptr != end) {
          141  +  if (HAS_CHAR(enc, ptr, end)) {
    97    142       if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
    98    143         *nextTokPtr = ptr;
    99    144         return XML_TOK_INVALID;
   100    145       }
   101    146       ptr += MINBPC(enc);
   102         -    while (ptr != end) {
          147  +    while (HAS_CHAR(enc, ptr, end)) {
   103    148         switch (BYTE_TYPE(enc, ptr)) {
   104    149         INVALID_CASES(ptr, nextTokPtr)
   105    150         case BT_MINUS:
   106         -        if ((ptr += MINBPC(enc)) == end)
   107         -          return XML_TOK_PARTIAL;
          151  +        ptr += MINBPC(enc);
          152  +        REQUIRE_CHAR(enc, ptr, end);
   108    153           if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
   109         -          if ((ptr += MINBPC(enc)) == end)
   110         -            return XML_TOK_PARTIAL;
          154  +          ptr += MINBPC(enc);
          155  +          REQUIRE_CHAR(enc, ptr, end);
   111    156             if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
   112    157               *nextTokPtr = ptr;
   113    158               return XML_TOK_INVALID;
   114    159             }
   115    160             *nextTokPtr = ptr + MINBPC(enc);
   116    161             return XML_TOK_COMMENT;
   117    162           }
................................................................................
   127    172   
   128    173   /* ptr points to character following "<!" */
   129    174   
   130    175   static int PTRCALL
   131    176   PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
   132    177                    const char *end, const char **nextTokPtr)
   133    178   {
   134         -  if (ptr == end)
   135         -    return XML_TOK_PARTIAL;
          179  +  REQUIRE_CHAR(enc, ptr, end);
   136    180     switch (BYTE_TYPE(enc, ptr)) {
   137    181     case BT_MINUS:
   138    182       return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
   139    183     case BT_LSQB:
   140    184       *nextTokPtr = ptr + MINBPC(enc);
   141    185       return XML_TOK_COND_SECT_OPEN;
   142    186     case BT_NMSTRT:
................................................................................
   143    187     case BT_HEX:
   144    188       ptr += MINBPC(enc);
   145    189       break;
   146    190     default:
   147    191       *nextTokPtr = ptr;
   148    192       return XML_TOK_INVALID;
   149    193     }
   150         -  while (ptr != end) {
          194  +  while (HAS_CHAR(enc, ptr, end)) {
   151    195       switch (BYTE_TYPE(enc, ptr)) {
   152    196       case BT_PERCNT:
   153         -      if (ptr + MINBPC(enc) == end)
   154         -        return XML_TOK_PARTIAL;
          197  +      REQUIRE_CHARS(enc, ptr, end, 2);
   155    198         /* don't allow <!ENTITY% foo "whatever"> */
   156    199         switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
   157    200         case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
   158    201           *nextTokPtr = ptr;
   159    202           return XML_TOK_INVALID;
   160    203         }
   161    204         /* fall through */
................................................................................
   171    214         return XML_TOK_INVALID;
   172    215       }
   173    216     }
   174    217     return XML_TOK_PARTIAL;
   175    218   }
   176    219   
   177    220   static int PTRCALL
   178         -PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
          221  +PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr,
   179    222                         const char *end, int *tokPtr)
   180    223   {
   181    224     int upper = 0;
   182    225     *tokPtr = XML_TOK_PI;
   183    226     if (end - ptr != MINBPC(enc)*3)
   184    227       return 1;
   185    228     switch (BYTE_TO_ASCII(enc, ptr)) {
................................................................................
   221    264   
   222    265   static int PTRCALL
   223    266   PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
   224    267                  const char *end, const char **nextTokPtr)
   225    268   {
   226    269     int tok;
   227    270     const char *target = ptr;
   228         -  if (ptr == end)
   229         -    return XML_TOK_PARTIAL;
          271  +  REQUIRE_CHAR(enc, ptr, end);
   230    272     switch (BYTE_TYPE(enc, ptr)) {
   231    273     CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   232    274     default:
   233    275       *nextTokPtr = ptr;
   234    276       return XML_TOK_INVALID;
   235    277     }
   236         -  while (ptr != end) {
          278  +  while (HAS_CHAR(enc, ptr, end)) {
   237    279       switch (BYTE_TYPE(enc, ptr)) {
   238    280       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
   239    281       case BT_S: case BT_CR: case BT_LF:
   240    282         if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
   241    283           *nextTokPtr = ptr;
   242    284           return XML_TOK_INVALID;
   243    285         }
   244    286         ptr += MINBPC(enc);
   245         -      while (ptr != end) {
          287  +      while (HAS_CHAR(enc, ptr, end)) {
   246    288           switch (BYTE_TYPE(enc, ptr)) {
   247    289           INVALID_CASES(ptr, nextTokPtr)
   248    290           case BT_QUEST:
   249    291             ptr += MINBPC(enc);
   250         -          if (ptr == end)
   251         -            return XML_TOK_PARTIAL;
          292  +          REQUIRE_CHAR(enc, ptr, end);
   252    293             if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
   253    294               *nextTokPtr = ptr + MINBPC(enc);
   254    295               return tok;
   255    296             }
   256    297             break;
   257    298           default:
   258    299             ptr += MINBPC(enc);
................................................................................
   262    303         return XML_TOK_PARTIAL;
   263    304       case BT_QUEST:
   264    305         if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
   265    306           *nextTokPtr = ptr;
   266    307           return XML_TOK_INVALID;
   267    308         }
   268    309         ptr += MINBPC(enc);
   269         -      if (ptr == end)
   270         -        return XML_TOK_PARTIAL;
          310  +      REQUIRE_CHAR(enc, ptr, end);
   271    311         if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
   272    312           *nextTokPtr = ptr + MINBPC(enc);
   273    313           return tok;
   274    314         }
   275    315         /* fall through */
   276    316       default:
   277    317         *nextTokPtr = ptr;
................................................................................
   278    318         return XML_TOK_INVALID;
   279    319       }
   280    320     }
   281    321     return XML_TOK_PARTIAL;
   282    322   }
   283    323   
   284    324   static int PTRCALL
   285         -PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
          325  +PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr,
   286    326                            const char *end, const char **nextTokPtr)
   287    327   {
   288    328     static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
   289    329                                        ASCII_T, ASCII_A, ASCII_LSQB };
   290    330     int i;
   291    331     /* CDATA[ */
   292         -  if (end - ptr < 6 * MINBPC(enc))
   293         -    return XML_TOK_PARTIAL;
          332  +  REQUIRE_CHARS(enc, ptr, end, 6);
   294    333     for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
   295    334       if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
   296    335         *nextTokPtr = ptr;
   297    336         return XML_TOK_INVALID;
   298    337       }
   299    338     }
   300    339     *nextTokPtr = ptr;
................................................................................
   301    340     return XML_TOK_CDATA_SECT_OPEN;
   302    341   }
   303    342   
   304    343   static int PTRCALL
   305    344   PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
   306    345                           const char *end, const char **nextTokPtr)
   307    346   {
   308         -  if (ptr == end)
          347  +  if (ptr >= end)
   309    348       return XML_TOK_NONE;
   310    349     if (MINBPC(enc) > 1) {
   311    350       size_t n = end - ptr;
   312    351       if (n & (MINBPC(enc) - 1)) {
   313    352         n &= ~(MINBPC(enc) - 1);
   314    353         if (n == 0)
   315    354           return XML_TOK_PARTIAL;
   316    355         end = ptr + n;
   317    356       }
   318    357     }
   319    358     switch (BYTE_TYPE(enc, ptr)) {
   320    359     case BT_RSQB:
   321    360       ptr += MINBPC(enc);
   322         -    if (ptr == end)
   323         -      return XML_TOK_PARTIAL;
          361  +    REQUIRE_CHAR(enc, ptr, end);
   324    362       if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
   325    363         break;
   326    364       ptr += MINBPC(enc);
   327         -    if (ptr == end)
   328         -      return XML_TOK_PARTIAL;
          365  +    REQUIRE_CHAR(enc, ptr, end);
   329    366       if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
   330    367         ptr -= MINBPC(enc);
   331    368         break;
   332    369       }
   333    370       *nextTokPtr = ptr + MINBPC(enc);
   334    371       return XML_TOK_CDATA_SECT_CLOSE;
   335    372     case BT_CR:
   336    373       ptr += MINBPC(enc);
   337         -    if (ptr == end)
   338         -      return XML_TOK_PARTIAL;
          374  +    REQUIRE_CHAR(enc, ptr, end);
   339    375       if (BYTE_TYPE(enc, ptr) == BT_LF)
   340    376         ptr += MINBPC(enc);
   341    377       *nextTokPtr = ptr;
   342    378       return XML_TOK_DATA_NEWLINE;
   343    379     case BT_LF:
   344    380       *nextTokPtr = ptr + MINBPC(enc);
   345    381       return XML_TOK_DATA_NEWLINE;
   346    382     INVALID_CASES(ptr, nextTokPtr)
   347    383     default:
   348    384       ptr += MINBPC(enc);
   349    385       break;
   350    386     }
   351         -  while (ptr != end) {
          387  +  while (HAS_CHAR(enc, ptr, end)) {
   352    388       switch (BYTE_TYPE(enc, ptr)) {
   353    389   #define LEAD_CASE(n) \
   354    390       case BT_LEAD ## n: \
   355    391         if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
   356    392           *nextTokPtr = ptr; \
   357    393           return XML_TOK_DATA_CHARS; \
   358    394         } \
................................................................................
   379    415   
   380    416   /* ptr points to character following "</" */
   381    417   
   382    418   static int PTRCALL
   383    419   PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
   384    420                      const char *end, const char **nextTokPtr)
   385    421   {
   386         -  if (ptr == end)
   387         -    return XML_TOK_PARTIAL;
          422  +  REQUIRE_CHAR(enc, ptr, end);
   388    423     switch (BYTE_TYPE(enc, ptr)) {
   389    424     CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   390    425     default:
   391    426       *nextTokPtr = ptr;
   392    427       return XML_TOK_INVALID;
   393    428     }
   394         -  while (ptr != end) {
          429  +  while (HAS_CHAR(enc, ptr, end)) {
   395    430       switch (BYTE_TYPE(enc, ptr)) {
   396    431       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
   397    432       case BT_S: case BT_CR: case BT_LF:
   398         -      for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
          433  +      for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
   399    434           switch (BYTE_TYPE(enc, ptr)) {
   400    435           case BT_S: case BT_CR: case BT_LF:
   401    436             break;
   402    437           case BT_GT:
   403    438             *nextTokPtr = ptr + MINBPC(enc);
   404    439             return XML_TOK_END_TAG;
   405    440           default:
................................................................................
   428    463   
   429    464   /* ptr points to character following "&#X" */
   430    465   
   431    466   static int PTRCALL
   432    467   PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
   433    468                          const char *end, const char **nextTokPtr)
   434    469   {
   435         -  if (ptr != end) {
          470  +  if (HAS_CHAR(enc, ptr, end)) {
   436    471       switch (BYTE_TYPE(enc, ptr)) {
   437    472       case BT_DIGIT:
   438    473       case BT_HEX:
   439    474         break;
   440    475       default:
   441    476         *nextTokPtr = ptr;
   442    477         return XML_TOK_INVALID;
   443    478       }
   444         -    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
          479  +    for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
   445    480         switch (BYTE_TYPE(enc, ptr)) {
   446    481         case BT_DIGIT:
   447    482         case BT_HEX:
   448    483           break;
   449    484         case BT_SEMI:
   450    485           *nextTokPtr = ptr + MINBPC(enc);
   451    486           return XML_TOK_CHAR_REF;
................................................................................
   460    495   
   461    496   /* ptr points to character following "&#" */
   462    497   
   463    498   static int PTRCALL
   464    499   PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
   465    500                       const char *end, const char **nextTokPtr)
   466    501   {
   467         -  if (ptr != end) {
          502  +  if (HAS_CHAR(enc, ptr, end)) {
   468    503       if (CHAR_MATCHES(enc, ptr, ASCII_x))
   469    504         return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
   470    505       switch (BYTE_TYPE(enc, ptr)) {
   471    506       case BT_DIGIT:
   472    507         break;
   473    508       default:
   474    509         *nextTokPtr = ptr;
   475    510         return XML_TOK_INVALID;
   476    511       }
   477         -    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
          512  +    for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
   478    513         switch (BYTE_TYPE(enc, ptr)) {
   479    514         case BT_DIGIT:
   480    515           break;
   481    516         case BT_SEMI:
   482    517           *nextTokPtr = ptr + MINBPC(enc);
   483    518           return XML_TOK_CHAR_REF;
   484    519         default:
................................................................................
   492    527   
   493    528   /* ptr points to character following "&" */
   494    529   
   495    530   static int PTRCALL
   496    531   PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
   497    532                   const char **nextTokPtr)
   498    533   {
   499         -  if (ptr == end)
   500         -    return XML_TOK_PARTIAL;
          534  +  REQUIRE_CHAR(enc, ptr, end);
   501    535     switch (BYTE_TYPE(enc, ptr)) {
   502    536     CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   503    537     case BT_NUM:
   504    538       return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
   505    539     default:
   506    540       *nextTokPtr = ptr;
   507    541       return XML_TOK_INVALID;
   508    542     }
   509         -  while (ptr != end) {
          543  +  while (HAS_CHAR(enc, ptr, end)) {
   510    544       switch (BYTE_TYPE(enc, ptr)) {
   511    545       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
   512    546       case BT_SEMI:
   513    547         *nextTokPtr = ptr + MINBPC(enc);
   514    548         return XML_TOK_ENTITY_REF;
   515    549       default:
   516    550         *nextTokPtr = ptr;
................................................................................
   525    559   static int PTRCALL
   526    560   PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
   527    561                    const char **nextTokPtr)
   528    562   {
   529    563   #ifdef XML_NS
   530    564     int hadColon = 0;
   531    565   #endif
   532         -  while (ptr != end) {
          566  +  while (HAS_CHAR(enc, ptr, end)) {
   533    567       switch (BYTE_TYPE(enc, ptr)) {
   534    568       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
   535    569   #ifdef XML_NS
   536    570       case BT_COLON:
   537    571         if (hadColon) {
   538    572           *nextTokPtr = ptr;
   539    573           return XML_TOK_INVALID;
   540    574         }
   541    575         hadColon = 1;
   542    576         ptr += MINBPC(enc);
   543         -      if (ptr == end)
   544         -        return XML_TOK_PARTIAL;
          577  +      REQUIRE_CHAR(enc, ptr, end);
   545    578         switch (BYTE_TYPE(enc, ptr)) {
   546    579         CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   547    580         default:
   548    581           *nextTokPtr = ptr;
   549    582           return XML_TOK_INVALID;
   550    583         }
   551    584         break;
   552    585   #endif
   553    586       case BT_S: case BT_CR: case BT_LF:
   554    587         for (;;) {
   555    588           int t;
   556    589   
   557    590           ptr += MINBPC(enc);
   558         -        if (ptr == end)
   559         -          return XML_TOK_PARTIAL;
          591  +        REQUIRE_CHAR(enc, ptr, end);
   560    592           t = BYTE_TYPE(enc, ptr);
   561    593           if (t == BT_EQUALS)
   562    594             break;
   563    595           switch (t) {
   564    596           case BT_S:
   565    597           case BT_LF:
   566    598           case BT_CR:
................................................................................
   575    607         {
   576    608           int open;
   577    609   #ifdef XML_NS
   578    610           hadColon = 0;
   579    611   #endif
   580    612           for (;;) {
   581    613             ptr += MINBPC(enc);
   582         -          if (ptr == end)
   583         -            return XML_TOK_PARTIAL;
          614  +          REQUIRE_CHAR(enc, ptr, end);
   584    615             open = BYTE_TYPE(enc, ptr);
   585    616             if (open == BT_QUOT || open == BT_APOS)
   586    617               break;
   587    618             switch (open) {
   588    619             case BT_S:
   589    620             case BT_LF:
   590    621             case BT_CR:
................................................................................
   594    625               return XML_TOK_INVALID;
   595    626             }
   596    627           }
   597    628           ptr += MINBPC(enc);
   598    629           /* in attribute value */
   599    630           for (;;) {
   600    631             int t;
   601         -          if (ptr == end)
   602         -            return XML_TOK_PARTIAL;
          632  +          REQUIRE_CHAR(enc, ptr, end);
   603    633             t = BYTE_TYPE(enc, ptr);
   604    634             if (t == open)
   605    635               break;
   606    636             switch (t) {
   607    637             INVALID_CASES(ptr, nextTokPtr)
   608    638             case BT_AMP:
   609    639               {
................................................................................
   620    650               return XML_TOK_INVALID;
   621    651             default:
   622    652               ptr += MINBPC(enc);
   623    653               break;
   624    654             }
   625    655           }
   626    656           ptr += MINBPC(enc);
   627         -        if (ptr == end)
   628         -          return XML_TOK_PARTIAL;
          657  +        REQUIRE_CHAR(enc, ptr, end);
   629    658           switch (BYTE_TYPE(enc, ptr)) {
   630    659           case BT_S:
   631    660           case BT_CR:
   632    661           case BT_LF:
   633    662             break;
   634    663           case BT_SOL:
   635    664             goto sol;
................................................................................
   638    667           default:
   639    668             *nextTokPtr = ptr;
   640    669             return XML_TOK_INVALID;
   641    670           }
   642    671           /* ptr points to closing quote */
   643    672           for (;;) {
   644    673             ptr += MINBPC(enc);
   645         -          if (ptr == end)
   646         -            return XML_TOK_PARTIAL;
          674  +          REQUIRE_CHAR(enc, ptr, end);
   647    675             switch (BYTE_TYPE(enc, ptr)) {
   648    676             CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   649    677             case BT_S: case BT_CR: case BT_LF:
   650    678               continue;
   651    679             case BT_GT:
   652    680             gt:
   653    681               *nextTokPtr = ptr + MINBPC(enc);
   654    682               return XML_TOK_START_TAG_WITH_ATTS;
   655    683             case BT_SOL:
   656    684             sol:
   657    685               ptr += MINBPC(enc);
   658         -            if (ptr == end)
   659         -              return XML_TOK_PARTIAL;
          686  +            REQUIRE_CHAR(enc, ptr, end);
   660    687               if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
   661    688                 *nextTokPtr = ptr;
   662    689                 return XML_TOK_INVALID;
   663    690               }
   664    691               *nextTokPtr = ptr + MINBPC(enc);
   665    692               return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
   666    693             default:
................................................................................
   684    711   static int PTRCALL
   685    712   PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
   686    713                  const char **nextTokPtr)
   687    714   {
   688    715   #ifdef XML_NS
   689    716     int hadColon;
   690    717   #endif
   691         -  if (ptr == end)
   692         -    return XML_TOK_PARTIAL;
          718  +  REQUIRE_CHAR(enc, ptr, end);
   693    719     switch (BYTE_TYPE(enc, ptr)) {
   694    720     CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   695    721     case BT_EXCL:
   696         -    if ((ptr += MINBPC(enc)) == end)
   697         -      return XML_TOK_PARTIAL;
          722  +    ptr += MINBPC(enc);
          723  +    REQUIRE_CHAR(enc, ptr, end);
   698    724       switch (BYTE_TYPE(enc, ptr)) {
   699    725       case BT_MINUS:
   700    726         return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
   701    727       case BT_LSQB:
   702    728         return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
   703    729                                         end, nextTokPtr);
   704    730       }
................................................................................
   712    738       *nextTokPtr = ptr;
   713    739       return XML_TOK_INVALID;
   714    740     }
   715    741   #ifdef XML_NS
   716    742     hadColon = 0;
   717    743   #endif
   718    744     /* we have a start-tag */
   719         -  while (ptr != end) {
          745  +  while (HAS_CHAR(enc, ptr, end)) {
   720    746       switch (BYTE_TYPE(enc, ptr)) {
   721    747       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
   722    748   #ifdef XML_NS
   723    749       case BT_COLON:
   724    750         if (hadColon) {
   725    751           *nextTokPtr = ptr;
   726    752           return XML_TOK_INVALID;
   727    753         }
   728    754         hadColon = 1;
   729    755         ptr += MINBPC(enc);
   730         -      if (ptr == end)
   731         -        return XML_TOK_PARTIAL;
          756  +      REQUIRE_CHAR(enc, ptr, end);
   732    757         switch (BYTE_TYPE(enc, ptr)) {
   733    758         CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   734    759         default:
   735    760           *nextTokPtr = ptr;
   736    761           return XML_TOK_INVALID;
   737    762         }
   738    763         break;
   739    764   #endif
   740    765       case BT_S: case BT_CR: case BT_LF:
   741    766         {
   742    767           ptr += MINBPC(enc);
   743         -        while (ptr != end) {
          768  +        while (HAS_CHAR(enc, ptr, end)) {
   744    769             switch (BYTE_TYPE(enc, ptr)) {
   745    770             CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   746    771             case BT_GT:
   747    772               goto gt;
   748    773             case BT_SOL:
   749    774               goto sol;
   750    775             case BT_S: case BT_CR: case BT_LF:
................................................................................
   761    786       case BT_GT:
   762    787       gt:
   763    788         *nextTokPtr = ptr + MINBPC(enc);
   764    789         return XML_TOK_START_TAG_NO_ATTS;
   765    790       case BT_SOL:
   766    791       sol:
   767    792         ptr += MINBPC(enc);
   768         -      if (ptr == end)
   769         -        return XML_TOK_PARTIAL;
          793  +      REQUIRE_CHAR(enc, ptr, end);
   770    794         if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
   771    795           *nextTokPtr = ptr;
   772    796           return XML_TOK_INVALID;
   773    797         }
   774    798         *nextTokPtr = ptr + MINBPC(enc);
   775    799         return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
   776    800       default:
................................................................................
   781    805     return XML_TOK_PARTIAL;
   782    806   }
   783    807   
   784    808   static int PTRCALL
   785    809   PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
   786    810                      const char **nextTokPtr)
   787    811   {
   788         -  if (ptr == end)
          812  +  if (ptr >= end)
   789    813       return XML_TOK_NONE;
   790    814     if (MINBPC(enc) > 1) {
   791    815       size_t n = end - ptr;
   792    816       if (n & (MINBPC(enc) - 1)) {
   793    817         n &= ~(MINBPC(enc) - 1);
   794    818         if (n == 0)
   795    819           return XML_TOK_PARTIAL;
................................................................................
   799    823     switch (BYTE_TYPE(enc, ptr)) {
   800    824     case BT_LT:
   801    825       return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
   802    826     case BT_AMP:
   803    827       return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
   804    828     case BT_CR:
   805    829       ptr += MINBPC(enc);
   806         -    if (ptr == end)
          830  +    if (! HAS_CHAR(enc, ptr, end))
   807    831         return XML_TOK_TRAILING_CR;
   808    832       if (BYTE_TYPE(enc, ptr) == BT_LF)
   809    833         ptr += MINBPC(enc);
   810    834       *nextTokPtr = ptr;
   811    835       return XML_TOK_DATA_NEWLINE;
   812    836     case BT_LF:
   813    837       *nextTokPtr = ptr + MINBPC(enc);
   814    838       return XML_TOK_DATA_NEWLINE;
   815    839     case BT_RSQB:
   816    840       ptr += MINBPC(enc);
   817         -    if (ptr == end)
          841  +    if (! HAS_CHAR(enc, ptr, end))
   818    842         return XML_TOK_TRAILING_RSQB;
   819    843       if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
   820    844         break;
   821    845       ptr += MINBPC(enc);
   822         -    if (ptr == end)
          846  +    if (! HAS_CHAR(enc, ptr, end))
   823    847         return XML_TOK_TRAILING_RSQB;
   824    848       if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
   825    849         ptr -= MINBPC(enc);
   826    850         break;
   827    851       }
   828    852       *nextTokPtr = ptr;
   829    853       return XML_TOK_INVALID;
   830    854     INVALID_CASES(ptr, nextTokPtr)
   831    855     default:
   832    856       ptr += MINBPC(enc);
   833    857       break;
   834    858     }
   835         -  while (ptr != end) {
          859  +  while (HAS_CHAR(enc, ptr, end)) {
   836    860       switch (BYTE_TYPE(enc, ptr)) {
   837    861   #define LEAD_CASE(n) \
   838    862       case BT_LEAD ## n: \
   839    863         if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
   840    864           *nextTokPtr = ptr; \
   841    865           return XML_TOK_DATA_CHARS; \
   842    866         } \
   843    867         ptr += n; \
   844    868         break;
   845    869       LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
   846    870   #undef LEAD_CASE
   847    871       case BT_RSQB:
   848         -      if (ptr + MINBPC(enc) != end) {
          872  +      if (HAS_CHARS(enc, ptr, end, 2)) {
   849    873            if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
   850    874              ptr += MINBPC(enc);
   851    875              break;
   852    876            }
   853         -         if (ptr + 2*MINBPC(enc) != end) {
          877  +         if (HAS_CHARS(enc, ptr, end, 3)) {
   854    878              if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
   855    879                ptr += MINBPC(enc);
   856    880                break;
   857    881              }
   858    882              *nextTokPtr = ptr + 2*MINBPC(enc);
   859    883              return XML_TOK_INVALID;
   860    884            }
................................................................................
   880    904   
   881    905   /* ptr points to character following "%" */
   882    906   
   883    907   static int PTRCALL
   884    908   PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
   885    909                       const char **nextTokPtr)
   886    910   {
   887         -  if (ptr == end)
   888         -    return -XML_TOK_PERCENT;
          911  +  REQUIRE_CHAR(enc, ptr, end);
   889    912     switch (BYTE_TYPE(enc, ptr)) {
   890    913     CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   891    914     case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
   892    915       *nextTokPtr = ptr;
   893    916       return XML_TOK_PERCENT;
   894    917     default:
   895    918       *nextTokPtr = ptr;
   896    919       return XML_TOK_INVALID;
   897    920     }
   898         -  while (ptr != end) {
          921  +  while (HAS_CHAR(enc, ptr, end)) {
   899    922       switch (BYTE_TYPE(enc, ptr)) {
   900    923       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
   901    924       case BT_SEMI:
   902    925         *nextTokPtr = ptr + MINBPC(enc);
   903    926         return XML_TOK_PARAM_ENTITY_REF;
   904    927       default:
   905    928         *nextTokPtr = ptr;
................................................................................
   909    932     return XML_TOK_PARTIAL;
   910    933   }
   911    934   
   912    935   static int PTRCALL
   913    936   PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
   914    937                         const char **nextTokPtr)
   915    938   {
   916         -  if (ptr == end)
   917         -    return XML_TOK_PARTIAL;
          939  +  REQUIRE_CHAR(enc, ptr, end);
   918    940     switch (BYTE_TYPE(enc, ptr)) {
   919    941     CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   920    942     default:
   921    943       *nextTokPtr = ptr;
   922    944       return XML_TOK_INVALID;
   923    945     }
   924         -  while (ptr != end) {
          946  +  while (HAS_CHAR(enc, ptr, end)) {
   925    947       switch (BYTE_TYPE(enc, ptr)) {
   926    948       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
   927    949       case BT_CR: case BT_LF: case BT_S:
   928    950       case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
   929    951         *nextTokPtr = ptr;
   930    952         return XML_TOK_POUND_NAME;
   931    953       default:
................................................................................
   937    959   }
   938    960   
   939    961   static int PTRCALL
   940    962   PREFIX(scanLit)(int open, const ENCODING *enc,
   941    963                   const char *ptr, const char *end,
   942    964                   const char **nextTokPtr)
   943    965   {
   944         -  while (ptr != end) {
          966  +  while (HAS_CHAR(enc, ptr, end)) {
   945    967       int t = BYTE_TYPE(enc, ptr);
   946    968       switch (t) {
   947    969       INVALID_CASES(ptr, nextTokPtr)
   948    970       case BT_QUOT:
   949    971       case BT_APOS:
   950    972         ptr += MINBPC(enc);
   951    973         if (t != open)
   952    974           break;
   953         -      if (ptr == end)
          975  +      if (! HAS_CHAR(enc, ptr, end))
   954    976           return -XML_TOK_LITERAL;
   955    977         *nextTokPtr = ptr;
   956    978         switch (BYTE_TYPE(enc, ptr)) {
   957    979         case BT_S: case BT_CR: case BT_LF:
   958    980         case BT_GT: case BT_PERCNT: case BT_LSQB:
   959    981           return XML_TOK_LITERAL;
   960    982         default:
................................................................................
   969    991   }
   970    992   
   971    993   static int PTRCALL
   972    994   PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
   973    995                     const char **nextTokPtr)
   974    996   {
   975    997     int tok;
   976         -  if (ptr == end)
          998  +  if (ptr >= end)
   977    999       return XML_TOK_NONE;
   978   1000     if (MINBPC(enc) > 1) {
   979   1001       size_t n = end - ptr;
   980   1002       if (n & (MINBPC(enc) - 1)) {
   981   1003         n &= ~(MINBPC(enc) - 1);
   982   1004         if (n == 0)
   983   1005           return XML_TOK_PARTIAL;
................................................................................
   988   1010     case BT_QUOT:
   989   1011       return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
   990   1012     case BT_APOS:
   991   1013       return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
   992   1014     case BT_LT:
   993   1015       {
   994   1016         ptr += MINBPC(enc);
   995         -      if (ptr == end)
   996         -        return XML_TOK_PARTIAL;
         1017  +      REQUIRE_CHAR(enc, ptr, end);
   997   1018         switch (BYTE_TYPE(enc, ptr)) {
   998   1019         case BT_EXCL:
   999   1020           return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  1000   1021         case BT_QUEST:
  1001   1022           return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
  1002   1023         case BT_NMSTRT:
  1003   1024         case BT_HEX:
................................................................................
  1017   1038         /* indicate that this might be part of a CR/LF pair */
  1018   1039         return -XML_TOK_PROLOG_S;
  1019   1040       }
  1020   1041       /* fall through */
  1021   1042     case BT_S: case BT_LF:
  1022   1043       for (;;) {
  1023   1044         ptr += MINBPC(enc);
  1024         -      if (ptr == end)
         1045  +      if (! HAS_CHAR(enc, ptr, end))
  1025   1046           break;
  1026   1047         switch (BYTE_TYPE(enc, ptr)) {
  1027   1048         case BT_S: case BT_LF:
  1028   1049           break;
  1029   1050         case BT_CR:
  1030   1051           /* don't split CR/LF pair */
  1031   1052           if (ptr + MINBPC(enc) != end)
................................................................................
  1044   1065       *nextTokPtr = ptr + MINBPC(enc);
  1045   1066       return XML_TOK_COMMA;
  1046   1067     case BT_LSQB:
  1047   1068       *nextTokPtr = ptr + MINBPC(enc);
  1048   1069       return XML_TOK_OPEN_BRACKET;
  1049   1070     case BT_RSQB:
  1050   1071       ptr += MINBPC(enc);
  1051         -    if (ptr == end)
         1072  +    if (! HAS_CHAR(enc, ptr, end))
  1052   1073         return -XML_TOK_CLOSE_BRACKET;
  1053   1074       if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
  1054         -      if (ptr + MINBPC(enc) == end)
  1055         -        return XML_TOK_PARTIAL;
         1075  +      REQUIRE_CHARS(enc, ptr, end, 2);
  1056   1076         if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
  1057   1077           *nextTokPtr = ptr + 2*MINBPC(enc);
  1058   1078           return XML_TOK_COND_SECT_CLOSE;
  1059   1079         }
  1060   1080       }
  1061   1081       *nextTokPtr = ptr;
  1062   1082       return XML_TOK_CLOSE_BRACKET;
  1063   1083     case BT_LPAR:
  1064   1084       *nextTokPtr = ptr + MINBPC(enc);
  1065   1085       return XML_TOK_OPEN_PAREN;
  1066   1086     case BT_RPAR:
  1067   1087       ptr += MINBPC(enc);
  1068         -    if (ptr == end)
         1088  +    if (! HAS_CHAR(enc, ptr, end))
  1069   1089         return -XML_TOK_CLOSE_PAREN;
  1070   1090       switch (BYTE_TYPE(enc, ptr)) {
  1071   1091       case BT_AST:
  1072   1092         *nextTokPtr = ptr + MINBPC(enc);
  1073   1093         return XML_TOK_CLOSE_PAREN_ASTERISK;
  1074   1094       case BT_QUEST:
  1075   1095         *nextTokPtr = ptr + MINBPC(enc);
................................................................................
  1137   1157         break;
  1138   1158       }
  1139   1159       /* fall through */
  1140   1160     default:
  1141   1161       *nextTokPtr = ptr;
  1142   1162       return XML_TOK_INVALID;
  1143   1163     }
  1144         -  while (ptr != end) {
         1164  +  while (HAS_CHAR(enc, ptr, end)) {
  1145   1165       switch (BYTE_TYPE(enc, ptr)) {
  1146   1166       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
  1147   1167       case BT_GT: case BT_RPAR: case BT_COMMA:
  1148   1168       case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
  1149   1169       case BT_S: case BT_CR: case BT_LF:
  1150   1170         *nextTokPtr = ptr;
  1151   1171         return tok;
  1152   1172   #ifdef XML_NS
  1153   1173       case BT_COLON:
  1154   1174         ptr += MINBPC(enc);
  1155   1175         switch (tok) {
  1156   1176         case XML_TOK_NAME:
  1157         -        if (ptr == end)
  1158         -          return XML_TOK_PARTIAL;
         1177  +        REQUIRE_CHAR(enc, ptr, end);
  1159   1178           tok = XML_TOK_PREFIXED_NAME;
  1160   1179           switch (BYTE_TYPE(enc, ptr)) {
  1161   1180           CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
  1162   1181           default:
  1163   1182             tok = XML_TOK_NMTOKEN;
  1164   1183             break;
  1165   1184           }
................................................................................
  1200   1219   }
  1201   1220   
  1202   1221   static int PTRCALL
  1203   1222   PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
  1204   1223                             const char *end, const char **nextTokPtr)
  1205   1224   {
  1206   1225     const char *start;
  1207         -  if (ptr == end)
         1226  +  if (ptr >= end)
  1208   1227       return XML_TOK_NONE;
         1228  +  else if (! HAS_CHAR(enc, ptr, end)) {
         1229  +    /* This line cannot be executed.  The incoming data has already
         1230  +     * been tokenized once, so incomplete characters like this have
         1231  +     * already been eliminated from the input.  Retaining the paranoia
         1232  +     * check is still valuable, however.
         1233  +     */
         1234  +    return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
         1235  +  }
  1209   1236     start = ptr;
  1210         -  while (ptr != end) {
         1237  +  while (HAS_CHAR(enc, ptr, end)) {
  1211   1238       switch (BYTE_TYPE(enc, ptr)) {
  1212   1239   #define LEAD_CASE(n) \
  1213   1240       case BT_LEAD ## n: ptr += n; break;
  1214   1241       LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
  1215   1242   #undef LEAD_CASE
  1216   1243       case BT_AMP:
  1217   1244         if (ptr == start)
................................................................................
  1228   1255           return XML_TOK_DATA_NEWLINE;
  1229   1256         }
  1230   1257         *nextTokPtr = ptr;
  1231   1258         return XML_TOK_DATA_CHARS;
  1232   1259       case BT_CR:
  1233   1260         if (ptr == start) {
  1234   1261           ptr += MINBPC(enc);
  1235         -        if (ptr == end)
         1262  +        if (! HAS_CHAR(enc, ptr, end))
  1236   1263             return XML_TOK_TRAILING_CR;
  1237   1264           if (BYTE_TYPE(enc, ptr) == BT_LF)
  1238   1265             ptr += MINBPC(enc);
  1239   1266           *nextTokPtr = ptr;
  1240   1267           return XML_TOK_DATA_NEWLINE;
  1241   1268         }
  1242   1269         *nextTokPtr = ptr;
................................................................................
  1258   1285   }
  1259   1286   
  1260   1287   static int PTRCALL
  1261   1288   PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
  1262   1289                          const char *end, const char **nextTokPtr)
  1263   1290   {
  1264   1291     const char *start;
  1265         -  if (ptr == end)
         1292  +  if (ptr >= end)
  1266   1293       return XML_TOK_NONE;
         1294  +  else if (! HAS_CHAR(enc, ptr, end)) {
         1295  +    /* This line cannot be executed.  The incoming data has already
         1296  +     * been tokenized once, so incomplete characters like this have
         1297  +     * already been eliminated from the input.  Retaining the paranoia
         1298  +     * check is still valuable, however.
         1299  +     */
         1300  +    return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
         1301  +  }
  1267   1302     start = ptr;
  1268         -  while (ptr != end) {
         1303  +  while (HAS_CHAR(enc, ptr, end)) {
  1269   1304       switch (BYTE_TYPE(enc, ptr)) {
  1270   1305   #define LEAD_CASE(n) \
  1271   1306       case BT_LEAD ## n: ptr += n; break;
  1272   1307       LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
  1273   1308   #undef LEAD_CASE
  1274   1309       case BT_AMP:
  1275   1310         if (ptr == start)
................................................................................
  1290   1325           return XML_TOK_DATA_NEWLINE;
  1291   1326         }
  1292   1327         *nextTokPtr = ptr;
  1293   1328         return XML_TOK_DATA_CHARS;
  1294   1329       case BT_CR:
  1295   1330         if (ptr == start) {
  1296   1331           ptr += MINBPC(enc);
  1297         -        if (ptr == end)
         1332  +        if (! HAS_CHAR(enc, ptr, end))
  1298   1333             return XML_TOK_TRAILING_CR;
  1299   1334           if (BYTE_TYPE(enc, ptr) == BT_LF)
  1300   1335             ptr += MINBPC(enc);
  1301   1336           *nextTokPtr = ptr;
  1302   1337           return XML_TOK_DATA_NEWLINE;
  1303   1338         }
  1304   1339         *nextTokPtr = ptr;
................................................................................
  1322   1357     if (MINBPC(enc) > 1) {
  1323   1358       size_t n = end - ptr;
  1324   1359       if (n & (MINBPC(enc) - 1)) {
  1325   1360         n &= ~(MINBPC(enc) - 1);
  1326   1361         end = ptr + n;
  1327   1362       }
  1328   1363     }
  1329         -  while (ptr != end) {
         1364  +  while (HAS_CHAR(enc, ptr, end)) {
  1330   1365       switch (BYTE_TYPE(enc, ptr)) {
  1331   1366       INVALID_CASES(ptr, nextTokPtr)
  1332   1367       case BT_LT:
  1333         -      if ((ptr += MINBPC(enc)) == end)
  1334         -        return XML_TOK_PARTIAL;
         1368  +      ptr += MINBPC(enc);
         1369  +      REQUIRE_CHAR(enc, ptr, end);
  1335   1370         if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
  1336         -        if ((ptr += MINBPC(enc)) == end)
  1337         -          return XML_TOK_PARTIAL;
         1371  +        ptr += MINBPC(enc);
         1372  +        REQUIRE_CHAR(enc, ptr, end);
  1338   1373           if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
  1339   1374             ++level;
  1340   1375             ptr += MINBPC(enc);
  1341   1376           }
  1342   1377         }
  1343   1378         break;
  1344   1379       case BT_RSQB:
  1345         -      if ((ptr += MINBPC(enc)) == end)
  1346         -        return XML_TOK_PARTIAL;
         1380  +      ptr += MINBPC(enc);
         1381  +      REQUIRE_CHAR(enc, ptr, end);
  1347   1382         if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
  1348         -        if ((ptr += MINBPC(enc)) == end)
  1349         -          return XML_TOK_PARTIAL;
         1383  +        ptr += MINBPC(enc);
         1384  +        REQUIRE_CHAR(enc, ptr, end);
  1350   1385           if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
  1351   1386             ptr += MINBPC(enc);
  1352   1387             if (level == 0) {
  1353   1388               *nextTokPtr = ptr;
  1354   1389               return XML_TOK_IGNORE_SECT;
  1355   1390             }
  1356   1391             --level;
................................................................................
  1369   1404   
  1370   1405   static int PTRCALL
  1371   1406   PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
  1372   1407                      const char **badPtr)
  1373   1408   {
  1374   1409     ptr += MINBPC(enc);
  1375   1410     end -= MINBPC(enc);
  1376         -  for (; ptr != end; ptr += MINBPC(enc)) {
         1411  +  for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
  1377   1412       switch (BYTE_TYPE(enc, ptr)) {
  1378   1413       case BT_DIGIT:
  1379   1414       case BT_HEX:
  1380   1415       case BT_MINUS:
  1381   1416       case BT_APOS:
  1382   1417       case BT_LPAR:
  1383   1418       case BT_RPAR:
................................................................................
  1517   1552         break;
  1518   1553       }
  1519   1554     }
  1520   1555     /* not reached */
  1521   1556   }
  1522   1557   
  1523   1558   static int PTRFASTCALL
  1524         -PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
         1559  +PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
  1525   1560   {
  1526   1561     int result = 0;
  1527   1562     /* skip &# */
  1528   1563     ptr += 2*MINBPC(enc);
  1529   1564     if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
  1530   1565       for (ptr += MINBPC(enc);
  1531   1566            !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
................................................................................
  1561   1596           return -1;
  1562   1597       }
  1563   1598     }
  1564   1599     return checkCharRefNumber(result);
  1565   1600   }
  1566   1601   
  1567   1602   static int PTRCALL
  1568         -PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
         1603  +PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
  1569   1604                                const char *end)
  1570   1605   {
  1571   1606     switch ((end - ptr)/MINBPC(enc)) {
  1572   1607     case 2:
  1573   1608       if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
  1574   1609         switch (BYTE_TO_ASCII(enc, ptr)) {
  1575   1610         case ASCII_l:
................................................................................
  1615   1650         break;
  1616   1651       }
  1617   1652     }
  1618   1653     return 0;
  1619   1654   }
  1620   1655   
  1621   1656   static int PTRCALL
  1622         -PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
  1623         -{
  1624         -  for (;;) {
  1625         -    switch (BYTE_TYPE(enc, ptr1)) {
  1626         -#define LEAD_CASE(n) \
  1627         -    case BT_LEAD ## n: \
  1628         -      if (*ptr1++ != *ptr2++) \
  1629         -        return 0;
  1630         -    LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
  1631         -#undef LEAD_CASE
  1632         -      /* fall through */
  1633         -      if (*ptr1++ != *ptr2++)
  1634         -        return 0;
  1635         -      break;
  1636         -    case BT_NONASCII:
  1637         -    case BT_NMSTRT:
  1638         -#ifdef XML_NS
  1639         -    case BT_COLON:
  1640         -#endif
  1641         -    case BT_HEX:
  1642         -    case BT_DIGIT:
  1643         -    case BT_NAME:
  1644         -    case BT_MINUS:
  1645         -      if (*ptr2++ != *ptr1++)
  1646         -        return 0;
  1647         -      if (MINBPC(enc) > 1) {
  1648         -        if (*ptr2++ != *ptr1++)
  1649         -          return 0;
  1650         -        if (MINBPC(enc) > 2) {
  1651         -          if (*ptr2++ != *ptr1++)
  1652         -            return 0;
  1653         -          if (MINBPC(enc) > 3) {
  1654         -            if (*ptr2++ != *ptr1++)
  1655         -              return 0;
  1656         -          }
  1657         -        }
  1658         -      }
  1659         -      break;
  1660         -    default:
  1661         -      if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
  1662         -        return 1;
  1663         -      switch (BYTE_TYPE(enc, ptr2)) {
  1664         -      case BT_LEAD2:
  1665         -      case BT_LEAD3:
  1666         -      case BT_LEAD4:
  1667         -      case BT_NONASCII:
  1668         -      case BT_NMSTRT:
  1669         -#ifdef XML_NS
  1670         -      case BT_COLON:
  1671         -#endif
  1672         -      case BT_HEX:
  1673         -      case BT_DIGIT:
  1674         -      case BT_NAME:
  1675         -      case BT_MINUS:
  1676         -        return 0;
  1677         -      default:
  1678         -        return 1;
  1679         -      }
  1680         -    }
  1681         -  }
  1682         -  /* not reached */
  1683         -}
  1684         -
  1685         -static int PTRCALL
  1686         -PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
         1657  +PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
  1687   1658                            const char *end1, const char *ptr2)
  1688   1659   {
  1689   1660     for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
  1690         -    if (ptr1 == end1)
  1691         -      return 0;
         1661  +    if (end1 - ptr1 < MINBPC(enc)) {
         1662  +      /* This line cannot be executed.  THe incoming data has already
         1663  +       * been tokenized once, so imcomplete characters like this have
         1664  +       * already been eliminated from the input.  Retaining the
         1665  +       * paranoia check is still valuable, however.
         1666  +       */
         1667  +      return 0; /* LCOV_EXCL_LINE */
         1668  +    }
  1692   1669       if (!CHAR_MATCHES(enc, ptr1, *ptr2))
  1693   1670         return 0;
  1694   1671     }
  1695   1672     return ptr1 == end1;
  1696   1673   }
  1697   1674   
  1698   1675   static int PTRFASTCALL
................................................................................
  1740   1717   
  1741   1718   static void PTRCALL
  1742   1719   PREFIX(updatePosition)(const ENCODING *enc,
  1743   1720                          const char *ptr,
  1744   1721                          const char *end,
  1745   1722                          POSITION *pos)
  1746   1723   {
  1747         -  while (ptr < end) {
         1724  +  while (HAS_CHAR(enc, ptr, end)) {
  1748   1725       switch (BYTE_TYPE(enc, ptr)) {
  1749   1726   #define LEAD_CASE(n) \
  1750   1727       case BT_LEAD ## n: \
  1751   1728         ptr += n; \
  1752   1729         break;
  1753   1730       LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
  1754   1731   #undef LEAD_CASE
................................................................................
  1756   1733         pos->columnNumber = (XML_Size)-1;
  1757   1734         pos->lineNumber++;
  1758   1735         ptr += MINBPC(enc);
  1759   1736         break;
  1760   1737       case BT_CR:
  1761   1738         pos->lineNumber++;
  1762   1739         ptr += MINBPC(enc);
  1763         -      if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
         1740  +      if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF)
  1764   1741           ptr += MINBPC(enc);
  1765   1742         pos->columnNumber = (XML_Size)-1;
  1766   1743         break;
  1767   1744       default:
  1768   1745         ptr += MINBPC(enc);
  1769   1746         break;
  1770   1747       }

Changes to expat/xmltok_impl.h.

     1      1   /*
     2         -Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     3         -See the file COPYING for copying permission.
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     4     31   */
     5     32   
     6     33   enum {
     7     34     BT_NONXML,
     8     35     BT_MALFORM,
     9     36     BT_LT,
    10     37     BT_AMP,

Changes to expat/xmltok_ns.c.

     1         -/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
     2         -   See the file COPYING for copying permission.
            1  +/* This file is included!
            2  +                            __  __            _
            3  +                         ___\ \/ /_ __   __ _| |_
            4  +                        / _ \\  /| '_ \ / _` | __|
            5  +                       |  __//  \| |_) | (_| | |_
            6  +                        \___/_/\_\ .__/ \__,_|\__|
            7  +                                 |_| XML parser
            8  +
            9  +   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
           10  +   Copyright (c) 2000-2017 Expat development team
           11  +   Licensed under the MIT license:
           12  +
           13  +   Permission is  hereby granted,  free of charge,  to any  person obtaining
           14  +   a  copy  of  this  software   and  associated  documentation  files  (the
           15  +   "Software"),  to  deal in  the  Software  without restriction,  including
           16  +   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
           17  +   distribute, sublicense, and/or sell copies of the Software, and to permit
           18  +   persons  to whom  the Software  is  furnished to  do so,  subject to  the
           19  +   following conditions:
           20  +
           21  +   The above copyright  notice and this permission notice  shall be included
           22  +   in all copies or substantial portions of the Software.
           23  +
           24  +   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
           25  +   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
           26  +   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
           27  +   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
           28  +   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
           29  +   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
           30  +   USE OR OTHER DEALINGS IN THE SOFTWARE.
     3     31   */
     4     32   
     5         -/* This file is included! */
     6     33   #ifdef XML_TOK_NS_C
     7     34   
     8     35   const ENCODING *
     9     36   NS(XmlGetUtf8InternalEncoding)(void)
    10     37   {
    11     38     return &ns(internal_utf8_encoding).enc;
    12     39   }

Changes to extensions/example/Makefile.in.

     3      3   #	This file is a Makefile for Sample TEA Extension.  If it has the name
     4      4   #	"Makefile.in" then it is a template for a Makefile;  to generate the
     5      5   #	actual Makefile, run "./configure", which is a configuration script
     6      6   #	generated by the "autoconf" program (constructs like "@foo@" will get
     7      7   #	replaced in the actual Makefile.
     8      8   #
     9      9   # Copyright (c) 1999 Scriptics Corporation.
    10         -# Copyright (c) 2002 ActiveState SRL.
           10  +# Copyright (c) 2002-2005 ActiveState Corporation.
    11     11   #
    12     12   # See the file "license.terms" for information on usage and redistribution
    13     13   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    14         -#
    15         -# RCS: @(#) $Id$
    16     14   
    17     15   #========================================================================
    18         -# Edit the following few lines when writing a new extension
           16  +# Add additional lines to handle any additional AC_SUBST cases that
           17  +# have been added in a customized configure script.
           18  +#========================================================================
           19  +
           20  +#SAMPLE_NEW_VAR	= @SAMPLE_NEW_VAR@
           21  +
           22  +#========================================================================
           23  +# Nothing of the variables below this line should need to be changed.
           24  +# Please check the TARGETS section below to make sure the make targets
           25  +# are correct.
    19     26   #========================================================================
    20     27   
    21     28   #========================================================================
    22         -# Enumerate the names of the source files included in this package.
           29  +# The names of the source files is defined in the configure script.
           30  +# The object files are used for linking into the final library.
    23     31   # This will be used when a dist target is added to the Makefile.
    24         -# EXTRA_SOURCES will be replaced by WIN_SOURCES or UNIX_SOURCES, as is
    25         -# appropriate for your platform.  It is not important to specify the
    26         -# directory, as long as it is the $(srcdir) or in the generic, win or
    27         -# unix subdirectory.
    28         -#========================================================================
    29         -
    30         -EXAMPLE_SOURCES    = example.c
    31         -
    32         -WIN_SOURCES	= 
    33         -UNIX_SOURCES    =
    34         -
    35         -#========================================================================
    36         -# Identify the object files.  This replaces .c with .$(OBJEXT) for all
    37         -# the named source files.   These objects are created and linked into the
    38         -# final library.  In these do not correspond directly to the source files
    39         -# above, you will need to enumerate the object files here.
    40         -# Normally we would use $(OBJEXT), but certain make executables won't do
    41         -# the extra macro in a macro conversion properly.
    42         -#
    43         -# "sample_LIB_FILE" refers to the library (dynamic or static as per
           32  +# It is not important to specify the directory, as long as it is the
           33  +# $(srcdir) or in the generic, win or unix subdirectory.
           34  +#========================================================================
           35  +
           36  +PKG_SOURCES	= @PKG_SOURCES@
           37  +PKG_OBJECTS	= @PKG_OBJECTS@
           38  +
           39  +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
           40  +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
           41  +
           42  +#========================================================================
           43  +# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
           44  +# this package that need to be installed, if any.
           45  +#========================================================================
           46  +
           47  +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
           48  +
           49  +#========================================================================
           50  +# This is a list of public header files to be installed, if any.
           51  +#========================================================================
           52  +
           53  +PKG_HEADERS	= @PKG_HEADERS@
           54  +
           55  +#========================================================================
           56  +# "PKG_LIB_FILE" refers to the library (dynamic or static as per
    44     57   # configuration options) composed of the named objects.
    45     58   #========================================================================
    46     59   
    47         -example_OBJECTS		= $(EXAMPLE_SOURCES:.c=.@OBJEXT@)
    48         -example_LIB_FILE	= @example_LIB_FILE@
           60  +PKG_LIB_FILE	= @PKG_LIB_FILE@
           61  +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
    49     62   
    50         -#========================================================================
    51         -# RUNTIME_SOURCES identifies Tcl runtime files that are associated with
    52         -# this package that need to be installed, if any.
    53         -#========================================================================
    54         -
    55         -#RUNTIME_SOURCES = example.tcl
    56         -
    57         -#========================================================================
    58         -# This is a list of header files to be installed
    59         -#========================================================================
    60         -
    61         -GENERIC_HDRS	= 
    62         -
    63         -#========================================================================
    64         -# Add additional lines to handle any additional AC_SUBST cases that
    65         -# have been added to the configure script.
    66         -#========================================================================
    67         -
    68         -# nothing so far
    69         -
    70         -#========================================================================
    71         -# Nothing of the variables below this line need to be changed.  Please
    72         -# check the TARGETS section below to make sure the make targets are
    73         -# correct.
    74         -#========================================================================
    75         -
    76         -#========================================================================
    77         -# The variable "$(PACKAGE)_LIB_FILE" is the parameterized name of the
    78         -# library that we are building.
    79         -#========================================================================
    80         -
    81         -lib_BINARIES	= $($(PACKAGE)_LIB_FILE) $($(PACKAGE)stub_LIB_FILE)
           63  +lib_BINARIES	= $(PKG_LIB_FILE)
    82     64   BINARIES	= $(lib_BINARIES)
    83     65   
    84     66   SHELL		= @SHELL@
    85     67   
    86     68   srcdir		= @srcdir@
    87     69   prefix		= @prefix@
    88     70   exec_prefix	= @exec_prefix@
    89     71   
    90     72   bindir		= @bindir@
    91     73   libdir		= @libdir@
           74  +includedir	= @includedir@
           75  +datarootdir	= @datarootdir@
    92     76   datadir		= @datadir@
    93     77   mandir		= @mandir@
    94         -includedir	= @includedir@
    95     78   
    96     79   DESTDIR		=
    97     80   
    98         -PKG_DIR		= $(PACKAGE)$(VERSION)
           81  +PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
    99     82   pkgdatadir	= $(datadir)/$(PKG_DIR)
   100     83   pkglibdir	= $(libdir)/$(PKG_DIR)
   101     84   pkgincludedir	= $(includedir)/$(PKG_DIR)
   102     85   
   103     86   top_builddir	= .
   104     87   
   105         -INSTALL		= @INSTALL@
   106         -INSTALL_PROGRAM	= @INSTALL_PROGRAM@
   107         -INSTALL_DATA	= @INSTALL_DATA@
   108         -INSTALL_SCRIPT	= @INSTALL_SCRIPT@
           88  +INSTALL_OPTIONS =
           89  +INSTALL		= $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS}
           90  +INSTALL_DATA_DIR = ${INSTALL} -d -m 755
           91  +INSTALL_PROGRAM	= ${INSTALL} -m 555
           92  +INSTALL_DATA	= ${INSTALL} -m 444
           93  +INSTALL_SCRIPT	= ${INSTALL_PROGRAM}
           94  +INSTALL_LIBRARY	= ${INSTALL_DATA}
   109     95   
   110         -PACKAGE		= @PACKAGE@
   111         -VERSION		= @VERSION@
           96  +PACKAGE_NAME	= @PACKAGE_NAME@
           97  +PACKAGE_VERSION	= @PACKAGE_VERSION@
   112     98   CC		= @CC@
   113         -CFLAGS_DEBUG	= @CFLAGS_DEBUG@
   114     99   CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
   115         -CFLAGS_OPTIMIZE	= @CFLAGS_OPTIMIZE@
   116         -CLEANFILES	= @CLEANFILES@
          100  +CFLAGS_WARNING	= @CFLAGS_WARNING@
   117    101   EXEEXT		= @EXEEXT@
   118         -LDFLAGS_DEBUG	= @LDFLAGS_DEBUG@
   119    102   LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
   120         -LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@
   121    103   MAKE_LIB	= @MAKE_LIB@
   122         -MAKE_STUB_LIB	= @MAKE_STUB_LIB@
   123    104   MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
   124    105   MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
          106  +MAKE_STUB_LIB	= @MAKE_STUB_LIB@
   125    107   OBJEXT		= @OBJEXT@
   126    108   RANLIB		= @RANLIB@
          109  +RANLIB_STUB	= @RANLIB_STUB@
   127    110   SHLIB_CFLAGS	= @SHLIB_CFLAGS@
   128    111   SHLIB_LD	= @SHLIB_LD@
   129         -SHLIB_LDFLAGS	= @SHLIB_LDFLAGS@
   130    112   SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
   131    113   STLIB_LD	= @STLIB_LD@
   132         -TCL_DEFS	= @TCL_DEFS@
          114  +#TCL_DEFS	= @TCL_DEFS@
   133    115   TCL_BIN_DIR	= @TCL_BIN_DIR@
   134    116   TCL_SRC_DIR	= @TCL_SRC_DIR@
          117  +#TK_BIN_DIR	= @TK_BIN_DIR@
          118  +#TK_SRC_DIR	= @TK_SRC_DIR@
   135    119   
   136         -# This is necessary for packages that use private Tcl headers
   137         -#TCL_TOP_DIR_NATIVE	= @TCL_TOP_DIR_NATIVE@
   138         -
   139         -#========================================================================
   140         -# This is needed so we can link the custom shell
   141         -#========================================================================
   142         -
   143         -TCL_LIBS	= @TCL_LIBS@
   144         -TCL_LIB_SPEC	= @TCL_LIB_SPEC@
          120  +# Not used, but retained for reference of what libs Tcl required
          121  +#TCL_LIBS	= @TCL_LIBS@
   145    122   
   146    123   #========================================================================
   147    124   # TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
   148    125   # package without installing.  The other environment variables allow us
   149    126   # to test against an uninstalled Tcl.  Add special env vars that you
   150    127   # require for testing here (like TCLX_LIBRARY).
   151    128   #========================================================================
   152    129   
   153    130   EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
   154         -TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
   155         -		  LD_LIBRARY_PATH="$(EXTRA_PATH):$(LD_LIBRARY_PATH)" \
   156         -		  LIBPATH="$(EXTRA_PATH):${LIBPATH}" \
   157         -		  SHLIB_PATH="$(EXTRA_PATH):${SHLIB_PATH}" \
          131  +#EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
          132  +TCLLIBPATH	= $(top_builddir)
          133  +TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
          134  +PKG_ENV		= @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
   158    135   		  PATH="$(EXTRA_PATH):$(PATH)" \
   159         -		  TCLLIBPATH="$(top_builddir)"
          136  +		  TCLLIBPATH="$(TCLLIBPATH)"
          137  +
   160    138   TCLSH_PROG	= @TCLSH_PROG@
   161         -TCLSH		= $(TCLSH_ENV) $(TCLSH_PROG)
          139  +TCLSH		= $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
          140  +
          141  +#WISH_ENV	= TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
          142  +#WISH_PROG	= @WISH_PROG@
          143  +#WISH		= $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
          144  +
   162    145   SHARED_BUILD	= @SHARED_BUILD@
   163    146   
   164         -INCLUDES	= @TCL_INCLUDES@ @EXAMPLE_INCLUDES@
          147  +INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
          148  +#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
   165    149   
   166         -EXTRA_CFLAGS	= $(MEM_DEBUG_FLAGS) @EXTRA_CFLAGS@
          150  +PKG_CFLAGS	= @PKG_CFLAGS@
   167    151   
   168         -DEFS		= $(TCL_DEFS) @DEFS@ $(EXTRA_CFLAGS)
          152  +# TCL_DEFS is not strictly need here, but if you remove it, then you
          153  +# must make sure that configure.in checks for the necessary components
          154  +# that your library may use.  TCL_DEFS can actually be a problem if
          155  +# you do not compile with a similar machine setup as the Tcl core was
          156  +# compiled with.
          157  +#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
          158  +DEFS		= @DEFS@ $(PKG_CFLAGS)
   169    159   
   170         -CONFIG_CLEAN_FILES = Makefile
          160  +# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
          161  +CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
          162  +CLEANFILES	= @CLEANFILES@
   171    163   
   172    164   CPPFLAGS	= @CPPFLAGS@
   173         -LIBS		= @LIBS@ @TDOM_BUILD_STUB_LIB_SPEC@
   174         -AR		= ar
   175         -
   176         -CFLAGS		= @CFLAGS@ -DUSE_TDOM_STUBS=1
          165  +LIBS		= @PKG_LIBS@ @LIBS@
          166  +AR		= @AR@
          167  +CFLAGS		= @CFLAGS@
   177    168   COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
          169  +
          170  +.SUFFIXES: .c .$(OBJEXT)
   178    171   
   179    172   #========================================================================
   180    173   # Start of user-definable TARGETS section
   181    174   #========================================================================
   182    175   
   183    176   #========================================================================
   184    177   # TEA TARGETS.  Please note that the "libraries:" target refers to platform
   185         -# independent files, and the "binaries:" target inclues executable programs and
          178  +# independent files, and the "binaries:" target includes executable programs and
   186    179   # platform-dependent libraries.  Modify these targets so that they install
   187    180   # the various pieces of your package.  The make and install rules
   188    181   # for the BINARIES that you specified above have already been done.
   189    182   #========================================================================
   190    183   
   191    184   all: binaries libraries doc
   192    185   
................................................................................
   193    186   #========================================================================
   194    187   # The binaries target builds executable programs, Windows .dll's, unix
   195    188   # shared/static libraries, and any other platform-dependent files.
   196    189   # The list of targets to build for "binaries:" is specified at the top
   197    190   # of the Makefile, in the "BINARIES" variable.
   198    191   #========================================================================
   199    192   
   200         -binaries: $(BINARIES) pkgIndex.tcl-hand
          193  +binaries: $(BINARIES)
   201    194   
   202    195   libraries:
   203    196   
          197  +#========================================================================
          198  +# Your doc target should differentiate from doc builds (by the developer)
          199  +# and doc installs (see install-doc), which just install the docs on the
          200  +# end user machine when building from source.
          201  +#========================================================================
          202  +
   204    203   doc:
          204  +	@echo "If you have documentation to create, place the commands to"
          205  +	@echo "build the docs in the 'doc:' target.  For example:"
          206  +	@echo "        xml2nroff sample.xml > sample.n"
          207  +	@echo "        xml2html sample.xml > sample.html"
   205    208   
   206         -install: all install-binaries
          209  +install: all install-binaries install-libraries install-doc
   207    210   
   208         -install-binaries: binaries install-lib-binaries
   209         -	@if test "x$(SHARED_BUILD)" = "x1"; then \
   210         -	    $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
   211         -	fi
          211  +install-binaries: binaries install-lib-binaries install-bin-binaries
   212    212   
   213    213   #========================================================================
   214    214   # This rule installs platform-independent files, such as header files.
          215  +# The list=...; for p in $$list handles the empty list case x-platform.
   215    216   #========================================================================
   216    217   
   217    218   install-libraries: libraries
   218         -	@mkdir -p $(DESTDIR)$(includedir)
          219  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir)
   219    220   	@echo "Installing header files in $(DESTDIR)$(includedir)"
   220         -	@if test "x$(GENERIC_HDRS)" != "x"; then \
   221         -	  for i in $(GENERIC_HDRS) ; do \
   222         -	    echo " $(INSTALL_DATA) $$i" ; \
   223         -	      $(INSTALL_DATA) $$i $(DESTDIR)$(includedir) ; \
   224         -	  done;
   225         -	fi
          221  +	@list='$(PKG_HEADERS)'; for i in $$list; do \
          222  +	    echo "Installing $(srcdir)/$$i" ; \
          223  +	    $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
          224  +	done;
   226    225   
   227    226   #========================================================================
   228    227   # Install documentation.  Unix manpages should go in the $(mandir)
   229    228   # directory.
   230    229   #========================================================================
   231    230   
   232    231   install-doc: doc
   233         -	@mkdir -p $(DESTDIR)$(mandir)/mann
          232  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
   234    233   	@echo "Installing documentation in $(DESTDIR)$(mandir)"
   235         -	@for i in $(srcdir)/doc/*.n; do \
   236         -	  echo " $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann/`basename $$i`"; \
   237         -	    rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
   238         -	      $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
          234  +	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
          235  +	    echo "Installing $$i"; \
          236  +	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
   239    237   	done
   240    238   
   241    239   test: binaries libraries
   242    240   	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
   243    241   
   244    242   shell: binaries libraries
   245    243   	@$(TCLSH) $(SCRIPT)
   246    244   
   247    245   gdb:
   248    246   	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
   249    247   
          248  +VALGRINDARGS =	--tool=memcheck --num-callers=8 --leak-resolution=high \
          249  +		--leak-check=yes --show-reachable=yes -v
          250  +
          251  +valgrind: binaries libraries
          252  +	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
          253  +		`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
          254  +
          255  +valgrindshell: binaries libraries
          256  +	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
          257  +
   250    258   depend:
   251    259   
   252    260   #========================================================================
   253         -# $($(PACKAGE)_LIB_FILE) should be listed as part of the BINARIES variable
          261  +# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
   254    262   # mentioned above.  That will ensure that this target is built when you
   255    263   # run "make binaries".
   256    264   #
   257         -# The $($(PACKAGE)_OBJECTS) objects are created and linked into the final
          265  +# The $(PKG_OBJECTS) objects are created and linked into the final
   258    266   # library.  In most cases these object files will correspond to the
   259    267   # source files above.
   260    268   #========================================================================
   261    269   
   262         -$($(PACKAGE)stub_LIB_FILE): $($(PACKAGE)stub_OBJECTS)
   263         -	-rm -f $($(PACKAGE)stub_LIB_FILE)
          270  +$(PKG_LIB_FILE): $(PKG_OBJECTS)
          271  +	-rm -f $(PKG_LIB_FILE)
          272  +	${MAKE_LIB}
          273  +	$(RANLIB) $(PKG_LIB_FILE)
          274  +
          275  +$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
          276  +	-rm -f $(PKG_STUB_LIB_FILE)
   264    277   	${MAKE_STUB_LIB}
   265         -	$(RANLIB) $($(PACKAGE)stub_LIB_FILE)
   266         -
   267         -$($(PACKAGE)_LIB_FILE): $($(PACKAGE)_OBJECTS)
   268         -	-rm -f $($(PACKAGE)_LIB_FILE)
   269         -	${MAKE_LIB}
   270         -	$(RANLIB) $($(PACKAGE)_LIB_FILE)
          278  +	$(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
   271    279   
   272    280   #========================================================================
   273    281   # We need to enumerate the list of .c to .o lines here.
   274    282   #
   275    283   # In the following lines, $(srcdir) refers to the toplevel directory
   276    284   # containing your extension.  If your sources are in a subdirectory,
   277    285   # you will have to modify the paths to reflect this:
................................................................................
   280    288   # 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
   281    289   #
   282    290   # Setting the VPATH variable to a list of paths will cause the makefile
   283    291   # to look into these paths when resolving .c to .obj dependencies.
   284    292   # As necessary, add $(srcdir):$(srcdir)/compat:....
   285    293   #========================================================================
   286    294   
   287         -VPATH = $(srcdir)/generic:$(srcdir)/expat:$(srcdir)/unix:$(srcdir)/win
          295  +VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx
   288    296   
   289         -.c.$(OBJEXT):
          297  +.c.@OBJEXT@:
   290    298   	$(COMPILE) -c `@CYGPATH@ $<` -o $@
   291    299   
   292         -#========================================================================
   293         -# Create the pkgIndex.tcl file.
   294         -# It is usually easiest to let Tcl do this for you with pkg_mkIndex, but
   295         -# you may find that you need to customize the package.  If so, either
   296         -# modify the -hand version, or create a pkgIndex.tcl.in file and have
   297         -# the configure script output the pkgIndex.tcl by editing configure.in.
   298         -#========================================================================
   299         -
   300         -# pkgIndex.tcl:
   301         -# 	@(echo pkg_mkIndex . $($(PACKAGE)_LIB_FILE) \; exit; ) | $(TCLSH)
   302         -
   303         -pkgIndex.tcl-hand:
   304         -	@(echo 'package ifneeded $(PACKAGE) $(VERSION) \
   305         -        "load [file join $$dir $($(PACKAGE)_LIB_FILE)]"'\
   306         -	) > pkgIndex.tcl
   307         -
   308    300   #========================================================================
   309    301   # Distribution creation
   310    302   # You may need to tweak this target to make it work correctly.
   311    303   #========================================================================
   312    304   
   313    305   #COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
   314         -COMPRESS	= gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
          306  +COMPRESS	= tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
   315    307   DIST_ROOT	= /tmp/dist
   316    308   DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)
   317    309   
   318    310   dist-clean:
   319    311   	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
   320    312   
   321    313   dist: dist-clean
   322    314   	mkdir -p $(DIST_DIR)
   323    315   	cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
   324         -	  $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
   325         -	  $(DIST_DIR)/
          316  +		$(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
          317  +		$(DIST_DIR)/
   326    318   	chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
   327    319   	chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
   328    320   
   329         -	cp -p $(srcdir)/*.[ch] $(DIST_DIR)/
          321  +	for i in $(srcdir)/*.[ch]; do \
          322  +	    if [ -f $$i ]; then \
          323  +		cp -p $$i $(DIST_DIR)/ ; \
          324  +	    fi; \
          325  +	done;
   330    326   
   331    327   	mkdir $(DIST_DIR)/tclconfig
   332    328   	cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
   333         -	  $(DIST_DIR)/tclconfig/
          329  +		$(DIST_DIR)/tclconfig/
   334    330   	chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
   335    331   	chmod +x $(DIST_DIR)/tclconfig/install-sh
   336    332   
   337         -	list='doc generic tests unix win expat lib apps encodings xe'; \
          333  +	list='demos doc generic library mac tests unix win'; \
   338    334   	for p in $$list; do \
   339         -	  if test -d $(srcdir)/$$p ; then \
   340         -	    mkdir $(DIST_DIR)/$$p; \
   341         -	    cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
   342         -	  fi; \
          335  +	    if test -d $(srcdir)/$$p ; then \
          336  +		mkdir $(DIST_DIR)/$$p; \
          337  +		cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
          338  +	    fi; \
   343    339   	done
   344    340   
   345    341   	(cd $(DIST_ROOT); $(COMPRESS);)
   346    342   
   347    343   #========================================================================
   348    344   # End of user-definable section
   349    345   #========================================================================
   350    346   
   351    347   #========================================================================
   352    348   # Don't modify the file to clean here.  Instead, set the "CLEANFILES"
   353    349   # variable in configure.in
   354    350   #========================================================================
   355    351   
   356         -clean:  
          352  +clean:
   357    353   	-test -z "$(BINARIES)" || rm -f $(BINARIES)
   358    354   	-rm -f *.$(OBJEXT) core *.core
   359    355   	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
   360    356   
   361    357   distclean: clean
   362    358   	-rm -f *.tab.c
   363    359   	-rm -f $(CONFIG_CLEAN_FILES)
................................................................................
   370    366   # Library files go into the lib directory.
   371    367   # In addition, this will generate the pkgIndex.tcl
   372    368   # file in the install location (assuming it can find a usable tclsh shell)
   373    369   #
   374    370   # You should not have to modify this target.
   375    371   #========================================================================
   376    372   
   377         -install-lib-binaries:
   378         -	@echo "Installing library files in $(pkglibdir)"
   379         -	@mkdir -p $(DESTDIR)$(pkglibdir)
          373  +install-lib-binaries: binaries
          374  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)
   380    375   	@list='$(lib_BINARIES)'; for p in $$list; do \
   381    376   	  if test -f $$p; then \
   382         -	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
   383         -	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
   384         -	    echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
   385         -	    $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
          377  +	    echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
          378  +	    $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
          379  +	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
          380  +	    if test "x$$stub" = "xstub"; then \
          381  +		echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
          382  +		$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
          383  +	    else \
          384  +		echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
          385  +		$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
          386  +	    fi; \
   386    387   	    ext=`echo $$p|sed -e "s/.*\.//"`; \
   387    388   	    if test "x$$ext" = "xdll"; then \
   388    389   		lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
   389    390   		if test -f $$lib; then \
   390    391   		    echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
   391    392   	            $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
   392    393   		fi; \
   393    394   	    fi; \
   394    395   	  fi; \
   395    396   	done
   396         -	@list='$(RUNTIME_SOURCES)'; for p in $$list; do \
   397         -	  if test -f $(srcdir)/lib/$$p; then \
   398         -	    echo " $(INSTALL_DATA) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
   399         -	    $(INSTALL_DATA) $(srcdir)/lib/$$p $(DESTDIR)$(pkglibdir)/$$p; \
          397  +	@list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
          398  +	  if test -f $(srcdir)/$$p; then \
          399  +	    destp=`basename $$p`; \
          400  +	    echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
          401  +	    $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
   400    402   	  fi; \
   401    403   	done
          404  +	@if test "x$(SHARED_BUILD)" = "x1"; then \
          405  +	    echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
          406  +	    $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
          407  +	fi
   402    408   
   403    409   #========================================================================
   404    410   # Install binary executables (e.g. .exe files and dependent .dll files)
   405    411   # This is for files that must go in the bin directory (located next to
   406    412   # wish and tclsh), like dependent .dll files on Windows.
   407    413   #
   408    414   # You should not have to modify this target, except to define bin_BINARIES
   409    415   # above if necessary.
   410    416   #========================================================================
   411    417   
   412         -# install-bin-binaries:
   413         -# 	@echo "Installing executables in $(DESTDIR)$(bindir)"
   414         -# 	@mkdir -p $(DESTDIR)$(bindir)
   415         -# 	@list='$(bin_BINARIES)'; for p in $$list; do \
   416         -# 	  if test -f $$p; then \
   417         -# 	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
   418         -# 	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
   419         -# 	  fi; \
   420         -# 	done
   421         -
   422         -.SUFFIXES: .c .$(OBJEXT)
          418  +install-bin-binaries: binaries
          419  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir)
          420  +	@list='$(bin_BINARIES)'; for p in $$list; do \
          421  +	  if test -f $$p; then \
          422  +	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
          423  +	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
          424  +	  fi; \
          425  +	done
   423    426   
   424    427   Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
   425    428   	cd $(top_builddir) \
   426    429   	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
   427    430   
   428    431   uninstall-binaries:
   429    432   	list='$(lib_BINARIES)'; for p in $$list; do \
   430    433   	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
   431    434   	done
   432         -	list='$(RUNTIME_SOURCES)'; for p in $$list; do \
          435  +	list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
          436  +	  p=`basename $$p`; \
   433    437   	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
   434    438   	done
   435    439   	list='$(bin_BINARIES)'; for p in $$list; do \
   436    440   	  rm -f $(DESTDIR)$(bindir)/$$p; \
   437    441   	done
   438    442   
   439    443   .PHONY: all binaries clean depend distclean doc install libraries test
   440    444   
   441    445   # Tell versions [3.59,3.63) of GNU make to not export all variables.
   442    446   # Otherwise a system limit (for SysV at least) may be exceeded.
   443    447   .NOEXPORT:

Changes to extensions/example/configure.

more than 10,000 changes

Changes to extensions/example/configure.in.

     1      1   #!/bin/bash -norc
     2      2   dnl	This file is an input file used by the GNU "autoconf" program to
     3      3   dnl	generate the file "configure", which is run during Tcl installation
     4      4   dnl	to configure the system for the local environment.
     5         -#
     6         -# RCS: @(#) $Id$
     7      5   
     8      6   #-----------------------------------------------------------------------
     9      7   # Sample configure.in for Tcl Extensions.  The only places you should
    10      8   # need to modify this file are marked by the string __CHANGE__
    11      9   #-----------------------------------------------------------------------
    12     10   
    13     11   #-----------------------------------------------------------------------
    14     12   # __CHANGE__
    15         -# This very first macro is used to verify that the configure script can 
    16         -# find the sources.  The argument to AC_INIT should be a unique filename
    17         -# for this package, and can be a relative path, such as:
           13  +# Set your package name and version numbers here.
    18     14   #
    19         -# AC_INIT(generic/tcl.h)
           15  +# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
           16  +# set as provided.  These will also be added as -D defs in your Makefile
           17  +# so you can encode the package version directly into the source files.
           18  +# This will also define a special symbol for Windows (BUILD_sample in
           19  +# this case) so that we create the export library with the dll.
    20     20   #-----------------------------------------------------------------------
    21     21   
    22         -AC_INIT(example.c)
    23         -
    24         -AC_CONFIG_AUX_DIR(../../tclconfig)
    25         -CONFIGDIR=${srcdir}/../../tclconfig
    26         -AC_SUBST(CONFIGDIR)
    27         -
    28         -#----------------------------------------------------------------------
    29         -# __CHANGE__
    30         -# Set your package name and version numbers here.  The NODOT_VERSION is
    31         -# required for constructing the library name on systems that don't like
    32         -# dots in library names (Windows).  The VERSION variable is used on the
    33         -# other systems.
    34         -#----------------------------------------------------------------------
    35         -
    36         -PACKAGE=example
    37         -
    38         -MAJOR_VERSION=1
    39         -MINOR_VERSION=0
    40         -PATCHLEVEL=0
    41         -
    42         -VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${PATCHLEVEL}
    43         -NODOT_VERSION=${MAJOR_VERSION}${MINOR_VERSION}${PATCHLEVEL}
    44         -
    45         -AC_SUBST(PACKAGE)
    46         -AC_SUBST(VERSION)
    47         -
    48         -# This package name must be replaced statically for AC_SUBST to work
    49         -AC_SUBST(example_LIB_FILE)
    50         -
    51         -#--------------------------------------------------------------------
    52         -# We put this here so that you can compile with -DVERSION="1.2" to
    53         -# encode the package version directly into the source files.
    54         -#--------------------------------------------------------------------
    55         -
    56         -eval AC_DEFINE_UNQUOTED(VERSION, "${VERSION}")
           22  +AC_INIT([example], [1.0])
    57     23   
    58     24   #--------------------------------------------------------------------
    59     25   # Call TEA_INIT as the first TEA_ macro to set up initial vars.
    60         -# This will define a ${TEA_PLATFORM} variable == "unix" or "windows".
           26  +# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
           27  +# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
    61     28   #--------------------------------------------------------------------
    62     29   
    63         -TEA_INIT
           30  +TEA_INIT([3.10])
           31  +
           32  +AC_CONFIG_AUX_DIR(../../tclconfig)
    64     33   
    65     34   #--------------------------------------------------------------------
    66     35   # Load the tclConfig.sh file
    67     36   #--------------------------------------------------------------------
    68     37   
    69     38   TEA_PATH_TCLCONFIG
    70     39   TEA_LOAD_TCLCONFIG
    71     40   
    72         -#--------------------------------------------------------------------
    73         -# Load the tdomConfig.sh file
    74         -#--------------------------------------------------------------------
    75         -if test "${TEA_PLATFORM}" = "windows" ; then
    76         -    TDOM_BIN_DIR=../../win
    77         -else
    78         -    TDOM_BIN_DIR=../../unix
    79         -fi
    80         -TDOM_LOAD_CONFIG
    81         -
    82     41   #--------------------------------------------------------------------
    83     42   # Load the tkConfig.sh file if necessary (Tk extension)
    84     43   #--------------------------------------------------------------------
    85     44   
    86     45   #TEA_PATH_TKCONFIG
    87     46   #TEA_LOAD_TKCONFIG
    88     47   
................................................................................
    92     51   #-----------------------------------------------------------------------
    93     52   
    94     53   TEA_PREFIX
    95     54   
    96     55   #-----------------------------------------------------------------------
    97     56   # Standard compiler checks.
    98     57   # This sets up CC by using the CC env var, or looks for gcc otherwise.
    99         -# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
   100         -# the basic setup necessary to compile executables.
           58  +# This also calls AC_PROG_CC and a few others to create the basic setup
           59  +# necessary to compile executables.
   101     60   #-----------------------------------------------------------------------
   102     61   
   103     62   TEA_SETUP_COMPILER
           63  +
           64  +#--------------------------------------------------------------------
           65  +# Load the tdomConfig.sh file
           66  +#--------------------------------------------------------------------
           67  +
           68  +TDOM_PATH_CONFIG
           69  +TDOM_LOAD_CONFIG
           70  +
           71  +#-----------------------------------------------------------------------
           72  +# __CHANGE__
           73  +# Specify the C source files to compile in TEA_ADD_SOURCES,
           74  +# public headers that need to be installed in TEA_ADD_HEADERS,
           75  +# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
           76  +# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
           77  +# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
           78  +# and PKG_TCL_SOURCES.
           79  +#-----------------------------------------------------------------------
           80  +
           81  +TEA_ADD_SOURCES([example.c])
           82  +TEA_ADD_HEADERS([])
           83  +TEA_ADD_INCLUDES([-I${srcdir}/../../generic -I${srcdir}/../../expat])
           84  +TEA_ADD_LIBS([${TDOM_STUB_LIB_SPEC}])
           85  +TEA_ADD_CFLAGS([-DUSE_TDOM_STUBS=1])
           86  +TEA_ADD_STUB_SOURCES([])
           87  +TEA_ADD_TCL_SOURCES([])
           88  +
           89  +#--------------------------------------------------------------------
           90  +# __CHANGE__
           91  +#
           92  +# You can add more files to clean if your extension creates any extra
           93  +# files by extending CLEANFILES.
           94  +# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
           95  +# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
           96  +#
           97  +# A few miscellaneous platform-specific items:
           98  +# TEA_ADD_* any platform specific compiler/build info here.
           99  +#--------------------------------------------------------------------
          100  +
          101  +#CLEANFILES="$CLEANFILES pkgIndex.tcl"
          102  +if test "${TEA_PLATFORM}" = "windows" ; then
          103  +    # Ensure no empty if clauses
          104  +    :
          105  +    #TEA_ADD_SOURCES([win/winFile.c])
          106  +    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
          107  +else
          108  +    # Ensure no empty else clauses
          109  +    :
          110  +    #TEA_ADD_SOURCES([unix/unixFile.c])
          111  +    #TEA_ADD_LIBS([-lsuperfly])
          112  +fi
   104    113   
   105    114   #--------------------------------------------------------------------
   106    115   # __CHANGE__
   107    116   # Choose which headers you need.  Extension authors should try very
   108    117   # hard to only rely on the Tcl public header files.  Internal headers
   109    118   # contain private data structures and are subject to change without
   110    119   # notice.
................................................................................
   112    121   #--------------------------------------------------------------------
   113    122   
   114    123   TEA_PUBLIC_TCL_HEADERS
   115    124   #TEA_PRIVATE_TCL_HEADERS
   116    125   
   117    126   #TEA_PUBLIC_TK_HEADERS
   118    127   #TEA_PRIVATE_TK_HEADERS
   119         -
   120         -#--------------------------------------------------------------------
   121         -# __CHANGE__
   122         -# A few miscellaneous platform-specific items:
   123         -#
   124         -# Define a special symbol for Windows (BUILD_sample in this case) so
   125         -# that we create the export library with the dll.  See sha1.h on how
   126         -# to use this.
   127         -#
   128         -# Windows creates a few extra files that need to be cleaned up.
   129         -# You can add more files to clean if your extension creates any extra
   130         -# files.
   131         -#
   132         -# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
   133         -# These will be appended to the current set of compiler flags for
   134         -# your system.
   135         -#--------------------------------------------------------------------
   136         -
   137         -if test "${TEA_PLATFORM}" = "windows" ; then
   138         -    AC_DEFINE(BUILD_example)
   139         -    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
   140         -    EXTRA_SOURCES='$(WIN_SOURCES)'
   141         -else
   142         -    CLEANFILES="pkgIndex.tcl"
   143         -    EXTRA_SOURCES='$(UNIX_SOURCES)'
   144         -fi
   145         -AC_SUBST(CLEANFILES)
   146         -AC_SUBST(EXTRA_SOURCES)
          128  +#TEA_PATH_X
   147    129   
   148    130   #--------------------------------------------------------------------
   149    131   # Check whether --enable-threads or --disable-threads was given.
          132  +# This auto-enables if Tcl was compiled threaded.
   150    133   #--------------------------------------------------------------------
   151    134   
   152    135   TEA_ENABLE_THREADS
   153    136   
   154    137   #--------------------------------------------------------------------
   155    138   # The statement below defines a collection of symbols related to
   156    139   # building as a shared library instead of a static library.
................................................................................
   168    151   
   169    152   #--------------------------------------------------------------------
   170    153   # Set the default compiler switches based on the --enable-symbols option.
   171    154   #--------------------------------------------------------------------
   172    155   
   173    156   TEA_ENABLE_SYMBOLS
   174    157   
   175         -if test "${SHARED_BUILD}" = "1" ; then
   176         -    CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING} ${SHLIB_CFLAGS}'
   177         -else
   178         -    CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING}'
   179         -fi
   180         -AC_SUBST(SHARED_BUILD)
   181         -
   182    158   #--------------------------------------------------------------------
   183    159   # Everyone should be linking against the Tcl stub library.  If you
   184    160   # can't for some reason, remove this definition.  If you aren't using
   185    161   # stubs, you also need to modify the SHLIB_LD_LIBS setting below to
   186    162   # link against the non-stubbed Tcl library.  Add Tk too if necessary.
   187    163   #--------------------------------------------------------------------
   188    164   
   189         -AC_DEFINE(USE_TCL_STUBS)
   190         -#AC_DEFINE(USE_TK_STUBS)
          165  +AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
          166  +#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
   191    167   
   192    168   #--------------------------------------------------------------------
   193    169   # This macro generates a line to use when building a library.  It
   194    170   # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
   195    171   # and TEA_LOAD_TCLCONFIG macros above.
   196         -# For tDOM we always build both, static and shared libraries
   197    172   #--------------------------------------------------------------------
   198    173   
   199    174   TEA_MAKE_LIB
   200    175   
   201    176   #--------------------------------------------------------------------
   202         -# __CHANGE__
   203         -# Add platform libs to LIBS or SHLIB_LD_LIBS as necessary.
   204         -#--------------------------------------------------------------------
   205         -
   206         -#LIBS="${LIBS} --lsuperfly"
   207         -
   208         -#--------------------------------------------------------------------
   209         -# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
   210         -# file during the install process.  Don't run the TCLSH_PROG through
   211         -# ${CYGPATH} because it's being used directly by make.
   212         -# Require that we use a tclsh shell version 8.2 or later since earlier
   213         -# versions have bugs in the pkg_mkIndex routine.
   214         -# Add WISH as well if this is a Tk extension.
          177  +# Determine the name of the tclsh and/or wish executables in the
          178  +# Tcl and Tk build directories or the location they were installed
          179  +# into. These paths are used to support running test cases only,
          180  +# the Makefile should not be making use of these paths to generate
          181  +# a pkgIndex.tcl file or anything else at extension build time.
   215    182   #--------------------------------------------------------------------
   216    183   
   217    184   TEA_PROG_TCLSH
   218    185   #TEA_PROG_WISH
   219    186   
   220         -#--------------------------------------------------------------------
   221         -# Add some private include directories
   222         -#--------------------------------------------------------------------
   223         -
   224         -EXAMPLE_INCLUDES="-I${srcdir}/../../generic -I${srcdir}/../../expat"
   225         -AC_SUBST(EXAMPLE_INCLUDES)
   226         -
   227    187   #--------------------------------------------------------------------
   228    188   # Finally, substitute all of the various values into the Makefile.
   229    189   # You may alternatively have a special pkgIndex.tcl.in or other files
   230    190   # which require substituting th AC variables in.  Include these here.
   231    191   #--------------------------------------------------------------------
   232    192   
   233         -AC_OUTPUT([Makefile])
          193  +AC_OUTPUT([Makefile pkgIndex.tcl])

Changes to extensions/example/example.c.

     1      1   
     2         -#include <tcl.h>
            2  +#include <tdom.h>
     3      3   #include <string.h>
     4         -#include <expat.h>
     5         -#include <tclexpat.h>
     6      4   
     7      5   /*
     8      6    * Beginning with 8.4, Tcl API is CONST'ified
     9      7    */
    10      8   #if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3)
    11      9   # define CONST84
    12     10   #endif
    13     11   
           12  +extern char *Tdom_InitStubs (Tcl_Interp *interp, char *version, int exact);
    14     13   
    15     14   typedef struct simpleCounter 
    16     15   {
    17     16       int elementCounter;
    18     17   } simpleCounter;
    19     18   
    20     19   static char example_usage[] = 
................................................................................
   131    130   int
   132    131   TclExampleObjCmd(dummy, interp, objc, objv)
   133    132        ClientData dummy;
   134    133        Tcl_Interp *interp;
   135    134        int objc;
   136    135        Tcl_Obj *CONST objv[];
   137    136   {
   138         -    char          *method;
   139    137       CHandlerSet   *handlerSet;
   140    138       int            methodIndex, result;
   141    139       simpleCounter *counter;
   142    140       
   143    141   
   144    142       static CONST84 char *exampleMethods[] = {
   145    143           "enable", "getresult", "remove",
................................................................................
   155    153       }
   156    154   
   157    155       if (!CheckExpatParserObj (interp, objv[1])) {
   158    156           Tcl_SetResult (interp, "First argument has to be a expat parser object", NULL);
   159    157           return TCL_ERROR;
   160    158       }
   161    159   
   162         -    method = Tcl_GetStringFromObj (objv[2], NULL);
   163    160       if (Tcl_GetIndexFromObj (interp, objv[2], exampleMethods, "method", 0,
   164    161                                &methodIndex) != TCL_OK)
   165    162       {
   166    163           Tcl_SetResult (interp, example_usage, NULL);
   167    164           return TCL_ERROR;
   168    165       }
   169    166   
................................................................................
   231    228    *----------------------------------------------------------------------------
   232    229    */
   233    230   
   234    231   int
   235    232   Example_Init (interp)
   236    233       Tcl_Interp *interp;
   237    234   {
   238         -    Tcl_PkgRequire (interp, "expat", "2.0", 0);
          235  +#ifdef USE_TCL_STUBS
          236  +    if (Tcl_InitStubs(interp, "8", 0) == NULL) {
          237  +        return TCL_ERROR;
          238  +    }
          239  +#endif
          240  +#ifdef USE_TDOM_STUBS
          241  +    if (Tdom_InitStubs(interp, "0.8", 0) == NULL) {
          242  +        return TCL_ERROR;
          243  +    }
          244  +#endif
          245  +    Tcl_PkgRequire (interp, "tdom", "0.8.0", 0);
   239    246       Tcl_CreateObjCommand (interp, "example", TclExampleObjCmd, NULL, NULL );
   240    247       Tcl_PkgProvide (interp, "example", "1.0");
          248  +    return TCL_OK;
   241    249   }
   242    250   

Changes to extensions/example/exampletest.tcl.

     1      1   #!tclsh
     2      2   
     3         -load ../../unix/libtdom0.7.5.so
     4         -load ./libexample1.0.0.so
            3  +load ../../unix/libtdom0.8.3.so
            4  +load ./libexample1.0.so
     5      5   
     6      6   set counter1 0
     7      7   set counter2 0
     8      8   
     9      9   proc eh1 {args} {
    10     10       global counter1
    11     11   

Changes to extensions/tdomhtml/configure.

     1      1   #! /bin/sh
     2         -
     3      2   # Guess values for system-dependent variables and create Makefiles.
     4         -# Generated automatically using autoconf version 2.13 
     5         -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
            3  +# Generated by GNU Autoconf 2.69.
            4  +#
            5  +#
            6  +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
            7  +#
     6      8   #
     7      9   # This configure script is free software; the Free Software Foundation
     8     10   # gives unlimited permission to copy, distribute and modify it.
     9         -
    10         -# Defaults:
    11         -ac_help=
           11  +## -------------------- ##
           12  +## M4sh Initialization. ##
           13  +## -------------------- ##
           14  +
           15  +# Be more Bourne compatible
           16  +DUALCASE=1; export DUALCASE # for MKS sh
           17  +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
           18  +  emulate sh
           19  +  NULLCMD=:
           20  +  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
           21  +  # is contrary to our usage.  Disable this feature.
           22  +  alias -g '${1+"$@"}'='"$@"'
           23  +  setopt NO_GLOB_SUBST
           24  +else
           25  +  case `(set -o) 2>/dev/null` in #(
           26  +  *posix*) :
           27  +    set -o posix ;; #(
           28  +  *) :
           29  +     ;;
           30  +esac
           31  +fi
           32  +
           33  +
           34  +as_nl='
           35  +'
           36  +export as_nl
           37  +# Printing a long string crashes Solaris 7 /usr/bin/printf.
           38  +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
           39  +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
           40  +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
           41  +# Prefer a ksh shell builtin over an external printf program on Solaris,
           42  +# but without wasting forks for bash or zsh.
           43  +if test -z "$BASH_VERSION$ZSH_VERSION" \
           44  +    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
           45  +  as_echo='print -r --'
           46  +  as_echo_n='print -rn --'
           47  +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
           48  +  as_echo='printf %s\n'
           49  +  as_echo_n='printf %s'
           50  +else
           51  +  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
           52  +    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
           53  +    as_echo_n='/usr/ucb/echo -n'
           54  +  else
           55  +    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
           56  +    as_echo_n_body='eval
           57  +      arg=$1;
           58  +      case $arg in #(
           59  +      *"$as_nl"*)
           60  +	expr "X$arg" : "X\\(.*\\)$as_nl";
           61  +	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
           62  +      esac;
           63  +      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
           64  +    '
           65  +    export as_echo_n_body
           66  +    as_echo_n='sh -c $as_echo_n_body as_echo'
           67  +  fi
           68  +  export as_echo_body
           69  +  as_echo='sh -c $as_echo_body as_echo'
           70  +fi
           71  +
           72  +# The user is always right.
           73  +if test "${PATH_SEPARATOR+set}" != set; then
           74  +  PATH_SEPARATOR=:
           75  +  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
           76  +    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
           77  +      PATH_SEPARATOR=';'
           78  +  }
           79  +fi
           80  +
           81  +
           82  +# IFS
           83  +# We need space, tab and new line, in precisely that order.  Quoting is
           84  +# there to prevent editors from complaining about space-tab.
           85  +# (If _AS_PATH_WALK were called with IFS unset, it would disable word
           86  +# splitting by setting IFS to empty value.)
           87  +IFS=" ""	$as_nl"
           88  +
           89  +# Find who we are.  Look in the path if we contain no directory separator.
           90  +as_myself=
           91  +case $0 in #((
           92  +  *[\\/]* ) as_myself=$0 ;;
           93  +  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
           94  +for as_dir in $PATH
           95  +do
           96  +  IFS=$as_save_IFS
           97  +  test -z "$as_dir" && as_dir=.
           98  +    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
           99  +  done
          100  +IFS=$as_save_IFS
          101  +
          102  +     ;;
          103  +esac
          104  +# We did not find ourselves, most probably we were run as `sh COMMAND'
          105  +# in which case we are not to be found in the path.
          106  +if test "x$as_myself" = x; then
          107  +  as_myself=$0
          108  +fi
          109  +if test ! -f "$as_myself"; then
          110  +  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
          111  +  exit 1
          112  +fi
          113  +
          114  +# Unset variables that we do not need and which cause bugs (e.g. in
          115  +# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
          116  +# suppresses any "Segmentation fault" message there.  '((' could
          117  +# trigger a bug in pdksh 5.2.14.
          118  +for as_var in BASH_ENV ENV MAIL MAILPATH
          119  +do eval test x\${$as_var+set} = xset \
          120  +  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
          121  +done
          122  +PS1='$ '
          123  +PS2='> '
          124  +PS4='+ '
          125  +
          126  +# NLS nuisances.
          127  +LC_ALL=C
          128  +export LC_ALL
          129  +LANGUAGE=C
          130  +export LANGUAGE
          131  +
          132  +# CDPATH.
          133  +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
          134  +
          135  +# Use a proper internal environment variable to ensure we don't fall
          136  +  # into an infinite loop, continuously re-executing ourselves.
          137  +  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
          138  +    _as_can_reexec=no; export _as_can_reexec;
          139  +    # We cannot yet assume a decent shell, so we have to provide a
          140  +# neutralization value for shells without unset; and this also
          141  +# works around shells that cannot unset nonexistent variables.
          142  +# Preserve -v and -x to the replacement shell.
          143  +BASH_ENV=/dev/null
          144  +ENV=/dev/null
          145  +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
          146  +case $- in # ((((
          147  +  *v*x* | *x*v* ) as_opts=-vx ;;
          148  +  *v* ) as_opts=-v ;;
          149  +  *x* ) as_opts=-x ;;
          150  +  * ) as_opts= ;;
          151  +esac
          152  +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
          153  +# Admittedly, this is quite paranoid, since all the known shells bail
          154  +# out after a failed `exec'.
          155  +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
          156  +as_fn_exit 255
          157  +  fi
          158  +  # We don't want this to propagate to other subprocesses.
          159  +          { _as_can_reexec=; unset _as_can_reexec;}
          160  +if test "x$CONFIG_SHELL" = x; then
          161  +  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
          162  +  emulate sh
          163  +  NULLCMD=:
          164  +  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
          165  +  # is contrary to our usage.  Disable this feature.
          166  +  alias -g '\${1+\"\$@\"}'='\"\$@\"'
          167  +  setopt NO_GLOB_SUBST
          168  +else
          169  +  case \`(set -o) 2>/dev/null\` in #(
          170  +  *posix*) :
          171  +    set -o posix ;; #(
          172  +  *) :
          173  +     ;;
          174  +esac
          175  +fi
          176  +"
          177  +  as_required="as_fn_return () { (exit \$1); }
          178  +as_fn_success () { as_fn_return 0; }
          179  +as_fn_failure () { as_fn_return 1; }
          180  +as_fn_ret_success () { return 0; }
          181  +as_fn_ret_failure () { return 1; }
          182  +
          183  +exitcode=0
          184  +as_fn_success || { exitcode=1; echo as_fn_success failed.; }
          185  +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
          186  +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
          187  +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
          188  +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
          189  +
          190  +else
          191  +  exitcode=1; echo positional parameters were not saved.
          192  +fi
          193  +test x\$exitcode = x0 || exit 1
          194  +test -x / || exit 1"
          195  +  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
          196  +  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
          197  +  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
          198  +  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
          199  +  if (eval "$as_required") 2>/dev/null; then :
          200  +  as_have_required=yes
          201  +else
          202  +  as_have_required=no
          203  +fi
          204  +  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
          205  +
          206  +else
          207  +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
          208  +as_found=false
          209  +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
          210  +do
          211  +  IFS=$as_save_IFS
          212  +  test -z "$as_dir" && as_dir=.
          213  +  as_found=:
          214  +  case $as_dir in #(
          215  +	 /*)
          216  +	   for as_base in sh bash ksh sh5; do
          217  +	     # Try only shells that exist, to save several forks.
          218  +	     as_shell=$as_dir/$as_base
          219  +	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
          220  +		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
          221  +  CONFIG_SHELL=$as_shell as_have_required=yes
          222  +		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
          223  +  break 2
          224  +fi
          225  +fi
          226  +	   done;;
          227  +       esac
          228  +  as_found=false
          229  +done
          230  +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
          231  +	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
          232  +  CONFIG_SHELL=$SHELL as_have_required=yes
          233  +fi; }
          234  +IFS=$as_save_IFS
          235  +
          236  +
          237  +      if test "x$CONFIG_SHELL" != x; then :
          238  +  export CONFIG_SHELL
          239  +             # We cannot yet assume a decent shell, so we have to provide a
          240  +# neutralization value for shells without unset; and this also
          241  +# works around shells that cannot unset nonexistent variables.
          242  +# Preserve -v and -x to the replacement shell.
          243  +BASH_ENV=/dev/null
          244  +ENV=/dev/null
          245  +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
          246  +case $- in # ((((
          247  +  *v*x* | *x*v* ) as_opts=-vx ;;
          248  +  *v* ) as_opts=-v ;;
          249  +  *x* ) as_opts=-x ;;
          250  +  * ) as_opts= ;;
          251  +esac
          252  +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
          253  +# Admittedly, this is quite paranoid, since all the known shells bail
          254  +# out after a failed `exec'.
          255  +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
          256  +exit 255
          257  +fi
          258  +
          259  +    if test x$as_have_required = xno; then :
          260  +  $as_echo "$0: This script requires a shell more modern than all"
          261  +  $as_echo "$0: the shells that I found on your system."
          262  +  if test x${ZSH_VERSION+set} = xset ; then
          263  +    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
          264  +    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
          265  +  else
          266  +    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
          267  +$0: including any error possibly output before this
          268  +$0: message. Then install a modern shell, or manually run
          269  +$0: the script under such a shell if you do have one."
          270  +  fi
          271  +  exit 1
          272  +fi
          273  +fi
          274  +fi
          275  +SHELL=${CONFIG_SHELL-/bin/sh}
          276  +export SHELL
          277  +# Unset more variables known to interfere with behavior of common tools.
          278  +CLICOLOR_FORCE= GREP_OPTIONS=
          279  +unset CLICOLOR_FORCE GREP_OPTIONS
          280  +
          281  +## --------------------- ##
          282  +## M4sh Shell Functions. ##
          283  +## --------------------- ##
          284  +# as_fn_unset VAR
          285  +# ---------------
          286  +# Portably unset VAR.
          287  +as_fn_unset ()
          288  +{
          289  +  { eval $1=; unset $1;}
          290  +}
          291  +as_unset=as_fn_unset
          292  +
          293  +# as_fn_set_status STATUS
          294  +# -----------------------
          295  +# Set $? to STATUS, without forking.
          296  +as_fn_set_status ()
          297  +{
          298  +  return $1
          299  +} # as_fn_set_status
          300  +
          301  +# as_fn_exit STATUS
          302  +# -----------------
          303  +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
          304  +as_fn_exit ()
          305  +{
          306  +  set +e
          307  +  as_fn_set_status $1
          308  +  exit $1
          309  +} # as_fn_exit
          310  +
          311  +# as_fn_mkdir_p
          312  +# -------------
          313  +# Create "$as_dir" as a directory, including parents if necessary.
          314  +as_fn_mkdir_p ()
          315  +{
          316  +
          317  +  case $as_dir in #(
          318  +  -*) as_dir=./$as_dir;;
          319  +  esac
          320  +  test -d "$as_dir" || eval $as_mkdir_p || {
          321  +    as_dirs=
          322  +    while :; do
          323  +      case $as_dir in #(
          324  +      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
          325  +      *) as_qdir=$as_dir;;
          326  +      esac
          327  +      as_dirs="'$as_qdir' $as_dirs"
          328  +      as_dir=`$as_dirname -- "$as_dir" ||
          329  +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
          330  +	 X"$as_dir" : 'X\(//\)[^/]' \| \
          331  +	 X"$as_dir" : 'X\(//\)$' \| \
          332  +	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
          333  +$as_echo X"$as_dir" |
          334  +    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
          335  +	    s//\1/
          336  +	    q
          337  +	  }
          338  +	  /^X\(\/\/\)[^/].*/{
          339  +	    s//\1/
          340  +	    q
          341  +	  }
          342  +	  /^X\(\/\/\)$/{
          343  +	    s//\1/
          344  +	    q
          345  +	  }
          346  +	  /^X\(\/\).*/{
          347  +	    s//\1/
          348  +	    q
          349  +	  }
          350  +	  s/.*/./; q'`
          351  +      test -d "$as_dir" && break
          352  +    done
          353  +    test -z "$as_dirs" || eval "mkdir $as_dirs"
          354  +  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
          355  +
          356  +
          357  +} # as_fn_mkdir_p
          358  +
          359  +# as_fn_executable_p FILE
          360  +# -----------------------
          361  +# Test if FILE is an executable regular file.
          362  +as_fn_executable_p ()
          363  +{
          364  +  test -f "$1" && test -x "$1"
          365  +} # as_fn_executable_p
          366  +# as_fn_append VAR VALUE
          367  +# ----------------------
          368  +# Append the text in VALUE to the end of the definition contained in VAR. Take
          369  +# advantage of any shell optimizations that allow amortized linear growth over
          370  +# repeated appends, instead of the typical quadratic growth present in naive
          371  +# implementations.
          372  +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
          373  +  eval 'as_fn_append ()
          374  +  {
          375  +    eval $1+=\$2
          376  +  }'
          377  +else
          378  +  as_fn_append ()
          379  +  {
          380  +    eval $1=\$$1\$2
          381  +  }
          382  +fi # as_fn_append
          383  +
          384  +# as_fn_arith ARG...
          385  +# ------------------
          386  +# Perform arithmetic evaluation on the ARGs, and store the result in the
          387  +# global $as_val. Take advantage of shells that can avoid forks. The arguments
          388  +# must be portable across $(()) and expr.
          389  +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
          390  +  eval 'as_fn_arith ()
          391  +  {
          392  +    as_val=$(( $* ))
          393  +  }'
          394  +else
          395  +  as_fn_arith ()
          396  +  {
          397  +    as_val=`expr "$@" || test $? -eq 1`
          398  +  }
          399  +fi # as_fn_arith
          400  +
          401  +
          402  +# as_fn_error STATUS ERROR [LINENO LOG_FD]
          403  +# ----------------------------------------
          404  +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
          405  +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
          406  +# script with STATUS, using 1 if that was 0.
          407  +as_fn_error ()
          408  +{
          409  +  as_status=$1; test $as_status -eq 0 && as_status=1
          410  +  if test "$4"; then
          411  +    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
          412  +    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
          413  +  fi
          414  +  $as_echo "$as_me: error: $2" >&2
          415  +  as_fn_exit $as_status
          416  +} # as_fn_error
          417  +
          418  +if expr a : '\(a\)' >/dev/null 2>&1 &&
          419  +   test "X`expr 00001 : '.*\(...\)'`" = X001; then
          420  +  as_expr=expr
          421  +else
          422  +  as_expr=false
          423  +fi
          424  +
          425  +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
          426  +  as_basename=basename
          427  +else
          428  +  as_basename=false
          429  +fi
          430  +
          431  +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
          432  +  as_dirname=dirname
          433  +else
          434  +  as_dirname=false
          435  +fi
          436  +
          437  +as_me=`$as_basename -- "$0" ||
          438  +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
          439  +	 X"$0" : 'X\(//\)$' \| \
          440  +	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
          441  +$as_echo X/"$0" |
          442  +    sed '/^.*\/\([^/][^/]*\)\/*$/{
          443  +	    s//\1/
          444  +	    q
          445  +	  }
          446  +	  /^X\/\(\/\/\)$/{
          447  +	    s//\1/
          448  +	    q
          449  +	  }
          450  +	  /^X\/\(\/\).*/{
          451  +	    s//\1/
          452  +	    q
          453  +	  }
          454  +	  s/.*/./; q'`
          455  +
          456  +# Avoid depending upon Character Ranges.
          457  +as_cr_letters='abcdefghijklmnopqrstuvwxyz'
          458  +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
          459  +as_cr_Letters=$as_cr_letters$as_cr_LETTERS
          460  +as_cr_digits='0123456789'
          461  +as_cr_alnum=$as_cr_Letters$as_cr_digits
          462  +
          463  +
          464  +  as_lineno_1=$LINENO as_lineno_1a=$LINENO
          465  +  as_lineno_2=$LINENO as_lineno_2a=$LINENO
          466  +  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
          467  +  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
          468  +  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
          469  +  sed -n '
          470  +    p
          471  +    /[$]LINENO/=
          472  +  ' <$as_myself |
          473  +    sed '
          474  +      s/[$]LINENO.*/&-/
          475  +      t lineno
          476  +      b
          477  +      :lineno
          478  +      N
          479  +      :loop
          480  +      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
          481  +      t loop
          482  +      s/-\n.*//
          483  +    ' >$as_me.lineno &&
          484  +  chmod +x "$as_me.lineno" ||
          485  +    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
          486  +
          487  +  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
          488  +  # already done that, so ensure we don't try to do so again and fall
          489  +  # in an infinite loop.  This has already happened in practice.
          490  +  _as_can_reexec=no; export _as_can_reexec
          491  +  # Don't try to exec as it changes $[0], causing all sort of problems
          492  +  # (the dirname of $[0] is not the place where we might find the
          493  +  # original and so on.  Autoconf is especially sensitive to this).
          494  +  . "./$as_me.lineno"
          495  +  # Exit status is that of the last command.
          496  +  exit
          497  +}
          498  +
          499  +ECHO_C= ECHO_N= ECHO_T=
          500  +case `echo -n x` in #(((((
          501  +-n*)
          502  +  case `echo 'xy\c'` in
          503  +  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
          504  +  xy)  ECHO_C='\c';;
          505  +  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
          506  +       ECHO_T='	';;
          507  +  esac;;
          508  +*)
          509  +  ECHO_N='-n';;
          510  +esac
          511  +
          512  +rm -f conf$$ conf$$.exe conf$$.file
          513  +if test -d conf$$.dir; then
          514  +  rm -f conf$$.dir/conf$$.file
          515  +else
          516  +  rm -f conf$$.dir
          517  +  mkdir conf$$.dir 2>/dev/null
          518  +fi
          519  +if (echo >conf$$.file) 2>/dev/null; then
          520  +  if ln -s conf$$.file conf$$ 2>/dev/null; then
          521  +    as_ln_s='ln -s'
          522  +    # ... but there are two gotchas:
          523  +    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
          524  +    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
          525  +    # In both cases, we have to default to `cp -pR'.
          526  +    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
          527  +      as_ln_s='cp -pR'
          528  +  elif ln conf$$.file conf$$ 2>/dev/null; then
          529  +    as_ln_s=ln
          530  +  else
          531  +    as_ln_s='cp -pR'
          532  +  fi
          533  +else
          534  +  as_ln_s='cp -pR'
          535  +fi
          536  +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
          537  +rmdir conf$$.dir 2>/dev/null
          538  +
          539  +if mkdir -p . 2>/dev/null; then
          540  +  as_mkdir_p='mkdir -p "$as_dir"'
          541  +else
          542  +  test -d ./-p && rmdir ./-p
          543  +  as_mkdir_p=false
          544  +fi
          545  +
          546  +as_test_x='test -x'
          547  +as_executable_p=as_fn_executable_p
          548  +
          549  +# Sed expression to map a string onto a valid CPP name.
          550  +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
          551  +
          552  +# Sed expression to map a string onto a valid variable name.
          553  +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
          554  +
          555  +
          556  +test -n "$DJDIR" || exec 7<&0 </dev/null
          557  +exec 6>&1
          558  +
          559  +# Name of the host.
          560  +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
          561  +# so uname gets run too.
          562  +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
          563  +
          564  +#
          565  +# Initializations.
          566  +#
    12    567   ac_default_prefix=/usr/local
    13         -# Any additions from configure.in:
          568  +ac_clean_files=
          569  +ac_config_libobj_dir=.
          570  +LIBOBJS=
          571  +cross_compiling=no
          572  +subdirs=
          573  +MFLAGS=
          574  +MAKEFLAGS=
          575  +
          576  +# Identity of this package.
          577  +PACKAGE_NAME=
          578  +PACKAGE_TARNAME=
          579  +PACKAGE_VERSION=
          580  +PACKAGE_STRING=
          581  +PACKAGE_BUGREPORT=
          582  +PACKAGE_URL=
          583  +
          584  +ac_unique_file="tdomhtml.tcl"
          585  +ac_subst_vars='LTLIBOBJS
          586  +LIBOBJS
          587  +EXTRA_SOURCES
          588  +CLEANFILES
          589  +INSTALL_DATA
          590  +INSTALL_SCRIPT
          591  +INSTALL_PROGRAM
          592  +VERSION
          593  +PACKAGE
          594  +CONFIGDIR
          595  +target_alias
          596  +host_alias
          597  +build_alias
          598  +LIBS
          599  +ECHO_T
          600  +ECHO_N
          601  +ECHO_C
          602  +DEFS
          603  +mandir
          604  +localedir
          605  +libdir
          606  +psdir
          607  +pdfdir
          608  +dvidir
          609  +htmldir
          610  +infodir
          611  +docdir
          612  +oldincludedir
          613  +includedir
          614  +localstatedir
          615  +sharedstatedir
          616  +sysconfdir
          617  +datadir
          618  +datarootdir
          619  +libexecdir
          620  +sbindir
          621  +bindir
          622  +program_transform_name
          623  +prefix
          624  +exec_prefix
          625  +PACKAGE_URL
          626  +PACKAGE_BUGREPORT
          627  +PACKAGE_STRING
          628  +PACKAGE_VERSION
          629  +PACKAGE_TARNAME
          630  +PACKAGE_NAME
          631  +PATH_SEPARATOR
          632  +SHELL'
          633  +ac_subst_files=''
          634  +ac_user_opts='
          635  +enable_option_checking
          636  +'
          637  +      ac_precious_vars='build_alias
          638  +host_alias
          639  +target_alias'
          640  +
    14    641   
    15    642   # Initialize some variables set by options.
          643  +ac_init_help=
          644  +ac_init_version=false
          645  +ac_unrecognized_opts=
          646  +ac_unrecognized_sep=
    16    647   # The variables have the same names as the options, with
    17    648   # dashes changed to underlines.
    18         -build=NONE
    19         -cache_file=./config.cache
          649  +cache_file=/dev/null
    20    650   exec_prefix=NONE
    21         -host=NONE
    22    651   no_create=
    23         -nonopt=NONE
    24    652   no_recursion=
    25    653   prefix=NONE
    26    654   program_prefix=NONE
    27    655   program_suffix=NONE
    28    656   program_transform_name=s,x,x,
    29    657   silent=
    30    658   site=
    31    659   srcdir=
    32         -target=NONE
    33    660   verbose=
    34    661   x_includes=NONE
    35    662   x_libraries=NONE
          663  +
          664  +# Installation directory options.
          665  +# These are left unexpanded so users can "make install exec_prefix=/foo"
          666  +# and all the variables that are supposed to be based on exec_prefix
          667  +# by default will actually change.
          668  +# Use braces instead of parens because sh, perl, etc. also accept them.
          669  +# (The list follows the same order as the GNU Coding Standards.)
    36    670   bindir='${exec_prefix}/bin'
    37    671   sbindir='${exec_prefix}/sbin'
    38    672   libexecdir='${exec_prefix}/libexec'
    39         -datadir='${prefix}/share'
          673  +datarootdir='${prefix}/share'
          674  +datadir='${datarootdir}'
    40    675   sysconfdir='${prefix}/etc'
    41    676   sharedstatedir='${prefix}/com'
    42    677   localstatedir='${prefix}/var'
    43         -libdir='${exec_prefix}/lib'
    44    678   includedir='${prefix}/include'
    45    679   oldincludedir='/usr/include'
    46         -infodir='${prefix}/info'
    47         -mandir='${prefix}/man'
    48         -
    49         -# Initialize some other variables.
    50         -subdirs=
    51         -MFLAGS= MAKEFLAGS=
    52         -SHELL=${CONFIG_SHELL-/bin/sh}
    53         -# Maximum number of lines to put in a shell here document.
    54         -ac_max_here_lines=12
          680  +docdir='${datarootdir}/doc/${PACKAGE}'
          681  +infodir='${datarootdir}/info'
          682  +htmldir='${docdir}'
          683  +dvidir='${docdir}'
          684  +pdfdir='${docdir}'
          685  +psdir='${docdir}'
          686  +libdir='${exec_prefix}/lib'
          687  +localedir='${datarootdir}/locale'
          688  +mandir='${datarootdir}/man'
    55    689   
    56    690   ac_prev=
          691  +ac_dashdash=
    57    692   for ac_option
    58    693   do
    59         -
    60    694     # If the previous option needs an argument, assign it.
    61    695     if test -n "$ac_prev"; then
    62         -    eval "$ac_prev=\$ac_option"
          696  +    eval $ac_prev=\$ac_option
    63    697       ac_prev=
    64    698       continue
    65    699     fi
    66    700   
    67         -  case "$ac_option" in
    68         -  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
    69         -  *) ac_optarg= ;;
          701  +  case $ac_option in
          702  +  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
          703  +  *=)   ac_optarg= ;;
          704  +  *)    ac_optarg=yes ;;
    70    705     esac
    71    706   
    72    707     # Accept the important Cygnus configure options, so we can diagnose typos.
    73    708   
    74         -  case "$ac_option" in
          709  +  case $ac_dashdash$ac_option in
          710  +  --)
          711  +    ac_dashdash=yes ;;
    75    712   
    76    713     -bindir | --bindir | --bindi | --bind | --bin | --bi)
    77    714       ac_prev=bindir ;;
    78    715     -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
    79         -    bindir="$ac_optarg" ;;
          716  +    bindir=$ac_optarg ;;
    80    717   
    81    718     -build | --build | --buil | --bui | --bu)
    82         -    ac_prev=build ;;
          719  +    ac_prev=build_alias ;;
    83    720     -build=* | --build=* | --buil=* | --bui=* | --bu=*)
    84         -    build="$ac_optarg" ;;
          721  +    build_alias=$ac_optarg ;;
    85    722   
    86    723     -cache-file | --cache-file | --cache-fil | --cache-fi \
    87    724     | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
    88    725       ac_prev=cache_file ;;
    89    726     -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
    90    727     | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
    91         -    cache_file="$ac_optarg" ;;
          728  +    cache_file=$ac_optarg ;;
    92    729   
    93         -  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
          730  +  --config-cache | -C)
          731  +    cache_file=config.cache ;;
          732  +
          733  +  -datadir | --datadir | --datadi | --datad)
    94    734       ac_prev=datadir ;;
    95         -  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
    96         -  | --da=*)
    97         -    datadir="$ac_optarg" ;;
          735  +  -datadir=* | --datadir=* | --datadi=* | --datad=*)
          736  +    datadir=$ac_optarg ;;
          737  +
          738  +  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
          739  +  | --dataroo | --dataro | --datar)
          740  +    ac_prev=datarootdir ;;
          741  +  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
          742  +  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
          743  +    datarootdir=$ac_optarg ;;
    98    744   
    99    745     -disable-* | --disable-*)
   100         -    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
          746  +    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
   101    747       # Reject names that are not valid shell variable names.
   102         -    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
   103         -      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
   104         -    fi
   105         -    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
   106         -    eval "enable_${ac_feature}=no" ;;
          748  +    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
          749  +      as_fn_error $? "invalid feature name: $ac_useropt"
          750  +    ac_useropt_orig=$ac_useropt
          751  +    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
          752  +    case $ac_user_opts in
          753  +      *"
          754  +"enable_$ac_useropt"
          755  +"*) ;;
          756  +      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
          757  +	 ac_unrecognized_sep=', ';;
          758  +    esac
          759  +    eval enable_$ac_useropt=no ;;
          760  +
          761  +  -docdir | --docdir | --docdi | --doc | --do)
          762  +    ac_prev=docdir ;;
          763  +  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
          764  +    docdir=$ac_optarg ;;
          765  +
          766  +  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
          767  +    ac_prev=dvidir ;;
          768  +  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
          769  +    dvidir=$ac_optarg ;;
   107    770   
   108    771     -enable-* | --enable-*)
   109         -    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
          772  +    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
   110    773       # Reject names that are not valid shell variable names.
   111         -    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
   112         -      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
   113         -    fi
   114         -    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
   115         -    case "$ac_option" in
   116         -      *=*) ;;
   117         -      *) ac_optarg=yes ;;
          774  +    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
          775  +      as_fn_error $? "invalid feature name: $ac_useropt"
          776  +    ac_useropt_orig=$ac_useropt
          777  +    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
          778  +    case $ac_user_opts in
          779  +      *"
          780  +"enable_$ac_useropt"
          781  +"*) ;;
          782  +      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
          783  +	 ac_unrecognized_sep=', ';;
   118    784       esac
   119         -    eval "enable_${ac_feature}='$ac_optarg'" ;;
          785  +    eval enable_$ac_useropt=\$ac_optarg ;;
   120    786   
   121    787     -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
   122    788     | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
   123    789     | --exec | --exe | --ex)
   124    790       ac_prev=exec_prefix ;;
   125    791     -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
   126    792     | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
   127    793     | --exec=* | --exe=* | --ex=*)
   128         -    exec_prefix="$ac_optarg" ;;
          794  +    exec_prefix=$ac_optarg ;;
   129    795   
   130    796     -gas | --gas | --ga | --g)
   131    797       # Obsolete; use --with-gas.
   132    798       with_gas=yes ;;
   133    799   
   134         -  -help | --help | --hel | --he)
   135         -    # Omit some internal or obsolete options to make the list less imposing.
   136         -    # This message is too long to be a string in the A/UX 3.1 sh.
   137         -    cat << EOF
   138         -Usage: configure [options] [host]
   139         -Options: [defaults in brackets after descriptions]
   140         -Configuration:
   141         -  --cache-file=FILE       cache test results in FILE
   142         -  --help                  print this message
   143         -  --no-create             do not create output files
   144         -  --quiet, --silent       do not print \`checking...' messages
   145         -  --version               print the version of autoconf that created configure
   146         -Directory and file names:
   147         -  --prefix=PREFIX         install architecture-independent files in PREFIX
   148         -                          [$ac_default_prefix]
   149         -  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
   150         -                          [same as prefix]
   151         -  --bindir=DIR            user executables in DIR [EPREFIX/bin]
   152         -  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
   153         -  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
   154         -  --datadir=DIR           read-only architecture-independent data in DIR
   155         -                          [PREFIX/share]
   156         -  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
   157         -  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
   158         -                          [PREFIX/com]
   159         -  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
   160         -  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
   161         -  --includedir=DIR        C header files in DIR [PREFIX/include]
   162         -  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
   163         -  --infodir=DIR           info documentation in DIR [PREFIX/info]
   164         -  --mandir=DIR            man documentation in DIR [PREFIX/man]
   165         -  --srcdir=DIR            find the sources in DIR [configure dir or ..]
   166         -  --program-prefix=PREFIX prepend PREFIX to installed program names
   167         -  --program-suffix=SUFFIX append SUFFIX to installed program names
   168         -  --program-transform-name=PROGRAM
   169         -                          run sed PROGRAM on installed program names
   170         -EOF
   171         -    cat << EOF
   172         -Host type:
   173         -  --build=BUILD           configure for building on BUILD [BUILD=HOST]
   174         -  --host=HOST             configure for HOST [guessed]
   175         -  --target=TARGET         configure for TARGET [TARGET=HOST]
   176         -Features and packages:
   177         -  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   178         -  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   179         -  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   180         -  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   181         -  --x-includes=DIR        X include files are in DIR
   182         -  --x-libraries=DIR       X library files are in DIR
   183         -EOF
   184         -    if test -n "$ac_help"; then
   185         -      echo "--enable and --with options recognized:$ac_help"
   186         -    fi
   187         -    exit 0 ;;
          800  +  -help | --help | --hel | --he | -h)
          801  +    ac_init_help=long ;;
          802  +  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
          803  +    ac_init_help=recursive ;;
          804  +  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
          805  +    ac_init_help=short ;;
   188    806   
   189    807     -host | --host | --hos | --ho)
   190         -    ac_prev=host ;;
          808  +    ac_prev=host_alias ;;
   191    809     -host=* | --host=* | --hos=* | --ho=*)
   192         -    host="$ac_optarg" ;;
          810  +    host_alias=$ac_optarg ;;
          811  +
          812  +  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
          813  +    ac_prev=htmldir ;;
          814  +  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
          815  +  | --ht=*)
          816  +    htmldir=$ac_optarg ;;
   193    817   
   194    818     -includedir | --includedir | --includedi | --included | --include \
   195    819     | --includ | --inclu | --incl | --inc)
   196    820       ac_prev=includedir ;;
   197    821     -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
   198    822     | --includ=* | --inclu=* | --incl=* | --inc=*)
   199         -    includedir="$ac_optarg" ;;
          823  +    includedir=$ac_optarg ;;
   200    824   
   201    825     -infodir | --infodir | --infodi | --infod | --info | --inf)
   202    826       ac_prev=infodir ;;
   203    827     -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
   204         -    infodir="$ac_optarg" ;;
          828  +    infodir=$ac_optarg ;;
   205    829   
   206    830     -libdir | --libdir | --libdi | --libd)
   207    831       ac_prev=libdir ;;
   208    832     -libdir=* | --libdir=* | --libdi=* | --libd=*)
   209         -    libdir="$ac_optarg" ;;
          833  +    libdir=$ac_optarg ;;
   210    834   
   211    835     -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
   212    836     | --libexe | --libex | --libe)
   213    837       ac_prev=libexecdir ;;
   214    838     -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
   215    839     | --libexe=* | --libex=* | --libe=*)
   216         -    libexecdir="$ac_optarg" ;;
          840  +    libexecdir=$ac_optarg ;;
          841  +
          842  +  -localedir | --localedir | --localedi | --localed | --locale)
          843  +    ac_prev=localedir ;;
          844  +  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
          845  +    localedir=$ac_optarg ;;
   217    846   
   218    847     -localstatedir | --localstatedir | --localstatedi | --localstated \
   219         -  | --localstate | --localstat | --localsta | --localst \
   220         -  | --locals | --local | --loca | --loc | --lo)
          848  +  | --localstate | --localstat | --localsta | --localst | --locals)
   221    849       ac_prev=localstatedir ;;
   222    850     -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
   223         -  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
   224         -  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
   225         -    localstatedir="$ac_optarg" ;;
          851  +  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
          852  +    localstatedir=$ac_optarg ;;
   226    853   
   227    854     -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
   228    855       ac_prev=mandir ;;
   229    856     -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
   230         -    mandir="$ac_optarg" ;;
          857  +    mandir=$ac_optarg ;;
   231    858   
   232    859     -nfp | --nfp | --nf)
   233    860       # Obsolete; use --without-fp.
   234    861       with_fp=no ;;
   235    862   
   236    863     -no-create | --no-create | --no-creat | --no-crea | --no-cre \
   237         -  | --no-cr | --no-c)
          864  +  | --no-cr | --no-c | -n)
   238    865       no_create=yes ;;
   239    866   
   240    867     -no-recursion | --no-recursion | --no-recursio | --no-recursi \
   241    868     | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
   242    869       no_recursion=yes ;;
   243    870   
   244    871     -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
   245    872     | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
   246    873     | --oldin | --oldi | --old | --ol | --o)
   247    874       ac_prev=oldincludedir ;;
   248    875     -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
   249    876     | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
   250    877     | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
   251         -    oldincludedir="$ac_optarg" ;;
          878  +    oldincludedir=$ac_optarg ;;
   252    879   
   253    880     -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
   254    881       ac_prev=prefix ;;
   255    882     -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
   256         -    prefix="$ac_optarg" ;;
          883  +    prefix=$ac_optarg ;;
   257    884   
   258    885     -program-prefix | --program-prefix | --program-prefi | --program-pref \
   259    886     | --program-pre | --program-pr | --program-p)
   260    887       ac_prev=program_prefix ;;
   261    888     -program-prefix=* | --program-prefix=* | --program-prefi=* \
   262    889     | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
   263         -    program_prefix="$ac_optarg" ;;
          890  +    program_prefix=$ac_optarg ;;
   264    891   
   265    892     -program-suffix | --program-suffix | --program-suffi | --program-suff \
   266    893     | --program-suf | --program-su | --program-s)
   267    894       ac_prev=program_suffix ;;
   268    895     -program-suffix=* | --program-suffix=* | --program-suffi=* \
   269    896     | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
   270         -    program_suffix="$ac_optarg" ;;
          897  +    program_suffix=$ac_optarg ;;
   271    898   
   272    899     -program-transform-name | --program-transform-name \
   273    900     | --program-transform-nam | --program-transform-na \
   274    901     | --program-transform-n | --program-transform- \
   275    902     | --program-transform | --program-transfor \
   276    903     | --program-transfo | --program-transf \
   277    904     | --program-trans | --program-tran \
................................................................................
   280    907     -program-transform-name=* | --program-transform-name=* \
   281    908     | --program-transform-nam=* | --program-transform-na=* \
   282    909     | --program-transform-n=* | --program-transform-=* \
   283    910     | --program-transform=* | --program-transfor=* \
   284    911     | --program-transfo=* | --program-transf=* \
   285    912     | --program-trans=* | --program-tran=* \
   286    913     | --progr-tra=* | --program-tr=* | --program-t=*)
   287         -    program_transform_name="$ac_optarg" ;;
          914  +    program_transform_name=$ac_optarg ;;
          915  +
          916  +  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
          917  +    ac_prev=pdfdir ;;
          918  +  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
          919  +    pdfdir=$ac_optarg ;;
          920  +
          921  +  -psdir | --psdir | --psdi | --psd | --ps)
          922  +    ac_prev=psdir ;;
          923  +  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
          924  +    psdir=$ac_optarg ;;
   288    925   
   289    926     -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   290    927     | -silent | --silent | --silen | --sile | --sil)
   291    928       silent=yes ;;
   292    929   
   293    930     -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
   294    931       ac_prev=sbindir ;;
   295    932     -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
   296    933     | --sbi=* | --sb=*)
   297         -    sbindir="$ac_optarg" ;;
          934  +    sbindir=$ac_optarg ;;
   298    935   
   299    936     -sharedstatedir | --sharedstatedir | --sharedstatedi \
   300    937     | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
   301    938     | --sharedst | --shareds | --shared | --share | --shar \
   302    939     | --sha | --sh)
   303    940       ac_prev=sharedstatedir ;;
   304    941     -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
   305    942     | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
   306    943     | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
   307    944     | --sha=* | --sh=*)
   308         -    sharedstatedir="$ac_optarg" ;;
          945  +    sharedstatedir=$ac_optarg ;;
   309    946   
   310    947     -site | --site | --sit)
   311    948       ac_prev=site ;;
   312    949     -site=* | --site=* | --sit=*)
   313         -    site="$ac_optarg" ;;
          950  +    site=$ac_optarg ;;
   314    951   
   315    952     -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
   316    953       ac_prev=srcdir ;;
   317    954     -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
   318         -    srcdir="$ac_optarg" ;;
          955  +    srcdir=$ac_optarg ;;
   319    956   
   320    957     -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
   321    958     | --syscon | --sysco | --sysc | --sys | --sy)
   322    959       ac_prev=sysconfdir ;;
   323    960     -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
   324    961     | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
   325         -    sysconfdir="$ac_optarg" ;;
          962  +    sysconfdir=$ac_optarg ;;
   326    963   
   327    964     -target | --target | --targe | --targ | --tar | --ta | --t)
   328         -    ac_prev=target ;;
          965  +    ac_prev=target_alias ;;
   329    966     -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
   330         -    target="$ac_optarg" ;;
          967  +    target_alias=$ac_optarg ;;
   331    968   
   332    969     -v | -verbose | --verbose | --verbos | --verbo | --verb)
   333    970       verbose=yes ;;
   334    971   
   335         -  -version | --version | --versio | --versi | --vers)
   336         -    echo "configure generated by autoconf version 2.13"
   337         -    exit 0 ;;
          972  +  -version | --version | --versio | --versi | --vers | -V)
          973  +    ac_init_version=: ;;
   338    974   
   339    975     -with-* | --with-*)
   340         -    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
          976  +    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
   341    977       # Reject names that are not valid shell variable names.
   342         -    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
   343         -      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
   344         -    fi
   345         -    ac_package=`echo $ac_package| sed 's/-/_/g'`
   346         -    case "$ac_option" in
   347         -      *=*) ;;
   348         -      *) ac_optarg=yes ;;
          978  +    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
          979  +      as_fn_error $? "invalid package name: $ac_useropt"
          980  +    ac_useropt_orig=$ac_useropt
          981  +    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
          982  +    case $ac_user_opts in
          983  +      *"
          984  +"with_$ac_useropt"
          985  +"*) ;;
          986  +      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
          987  +	 ac_unrecognized_sep=', ';;
   349    988       esac
   350         -    eval "with_${ac_package}='$ac_optarg'" ;;
          989  +    eval with_$ac_useropt=\$ac_optarg ;;
   351    990   
   352    991     -without-* | --without-*)
   353         -    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
          992  +    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
   354    993       # Reject names that are not valid shell variable names.
   355         -    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
   356         -      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
   357         -    fi
   358         -    ac_package=`echo $ac_package| sed 's/-/_/g'`
   359         -    eval "with_${ac_package}=no" ;;
          994  +    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
          995  +      as_fn_error $? "invalid package name: $ac_useropt"
          996  +    ac_useropt_orig=$ac_useropt
          997  +    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
          998  +    case $ac_user_opts in
          999  +      *"
         1000  +"with_$ac_useropt"
         1001  +"*) ;;
         1002  +      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
         1003  +	 ac_unrecognized_sep=', ';;
         1004  +    esac
         1005  +    eval with_$ac_useropt=no ;;
   360   1006   
   361   1007     --x)
   362   1008       # Obsolete; use --with-x.
   363   1009       with_x=yes ;;
   364   1010   
   365   1011     -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
   366   1012     | --x-incl | --x-inc | --x-in | --x-i)
   367   1013       ac_prev=x_includes ;;
   368   1014     -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
   369   1015     | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
   370         -    x_includes="$ac_optarg" ;;
         1016  +    x_includes=$ac_optarg ;;
   371   1017   
   372   1018     -x-libraries | --x-libraries | --x-librarie | --x-librari \
   373   1019     | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
   374   1020       ac_prev=x_libraries ;;
   375   1021     -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
   376   1022     | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
   377         -    x_libraries="$ac_optarg" ;;
         1023  +    x_libraries=$ac_optarg ;;
   378   1024   
   379         -  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
         1025  +  -*) as_fn_error $? "unrecognized option: \`$ac_option'
         1026  +Try \`$0 --help' for more information"
   380   1027       ;;
   381   1028   
         1029  +  *=*)
         1030  +    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
         1031  +    # Reject names that are not valid shell variable names.
         1032  +    case $ac_envvar in #(
         1033  +      '' | [0-9]* | *[!_$as_cr_alnum]* )
         1034  +      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
         1035  +    esac
         1036  +    eval $ac_envvar=\$ac_optarg
         1037  +    export $ac_envvar ;;
         1038  +
   382   1039     *)
   383         -    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
   384         -      echo "configure: warning: $ac_option: invalid host type" 1>&2
   385         -    fi
   386         -    if test "x$nonopt" != xNONE; then
   387         -      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
   388         -    fi
   389         -    nonopt="$ac_option"
         1040  +    # FIXME: should be removed in autoconf 3.0.
         1041  +    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
         1042  +    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
         1043  +      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
         1044  +    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
   390   1045       ;;
   391   1046   
   392   1047     esac
   393   1048   done
   394   1049   
   395   1050   if test -n "$ac_prev"; then
   396         -  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
   397         -fi
   398         -
   399         -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
   400         -
   401         -# File descriptor usage:
   402         -# 0 standard input
   403         -# 1 file creation
   404         -# 2 errors and warnings
   405         -# 3 some systems may open it to /dev/tty
   406         -# 4 used on the Kubota Titan
   407         -# 6 checking for... messages and results
   408         -# 5 compiler messages saved in config.log
   409         -if test "$silent" = yes; then
   410         -  exec 6>/dev/null
   411         -else
   412         -  exec 6>&1
   413         -fi
   414         -exec 5>./config.log
   415         -
   416         -echo "\
   417         -This file contains any messages produced by compilers while
   418         -running configure, to aid debugging if configure makes a mistake.
   419         -" 1>&5
   420         -
   421         -# Strip out --no-create and --no-recursion so they do not pile up.
   422         -# Also quote any args containing shell metacharacters.
   423         -ac_configure_args=
   424         -for ac_arg
         1051  +  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
         1052  +  as_fn_error $? "missing argument to $ac_option"
         1053  +fi
         1054  +
         1055  +if test -n "$ac_unrecognized_opts"; then
         1056  +  case $enable_option_checking in
         1057  +    no) ;;
         1058  +    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
         1059  +    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
         1060  +  esac
         1061  +fi
         1062  +
         1063  +# Check all directory arguments for consistency.
         1064  +for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
         1065  +		datadir sysconfdir sharedstatedir localstatedir includedir \
         1066  +		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
         1067  +		libdir localedir mandir
   425   1068   do
   426         -  case "$ac_arg" in
   427         -  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
   428         -  | --no-cr | --no-c) ;;
   429         -  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
   430         -  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
   431         -  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
   432         -  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
   433         -  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
   434         -  esac
   435         -done
   436         -
   437         -# NLS nuisances.
   438         -# Only set these to C if already set.  These must not be set unconditionally
   439         -# because not all systems understand e.g. LANG=C (notably SCO).
   440         -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
   441         -# Non-C LC_CTYPE values break the ctype check.
   442         -if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
   443         -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
   444         -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
   445         -if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
   446         -
   447         -# confdefs.h avoids OS command line length limits that DEFS can exceed.
   448         -rm -rf conftest* confdefs.h
   449         -# AIX cpp loses on an empty file, so make sure it contains at least a newline.
   450         -echo > confdefs.h
   451         -
   452         -# A filename unique to this package, relative to the directory that
   453         -# configure is in, which we can look for to find out if srcdir is correct.
   454         -ac_unique_file=tdomhtml.tcl
         1069  +  eval ac_val=\$$ac_var
         1070  +  # Remove trailing slashes.
         1071  +  case $ac_val in
         1072  +    */ )
         1073  +      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
         1074  +      eval $ac_var=\$ac_val;;
         1075  +  esac
         1076  +  # Be sure to have absolute directory names.
         1077  +  case $ac_val in
         1078  +    [\\/$]* | ?:[\\/]* )  continue;;
         1079  +    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
         1080  +  esac
         1081  +  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
         1082  +done
         1083  +
         1084  +# There might be people who depend on the old broken behavior: `$host'
         1085  +# used to hold the argument of --host etc.
         1086  +# FIXME: To remove some day.
         1087  +build=$build_alias
         1088  +host=$host_alias
         1089  +target=$target_alias
         1090  +
         1091  +# FIXME: To remove some day.
         1092  +if test "x$host_alias" != x; then
         1093  +  if test "x$build_alias" = x; then
         1094  +    cross_compiling=maybe
         1095  +  elif test "x$build_alias" != "x$host_alias"; then
         1096  +    cross_compiling=yes
         1097  +  fi
         1098  +fi
         1099  +
         1100  +ac_tool_prefix=
         1101  +test -n "$host_alias" && ac_tool_prefix=$host_alias-
         1102  +
         1103  +test "$silent" = yes && exec 6>/dev/null
         1104  +
         1105  +
         1106  +ac_pwd=`pwd` && test -n "$ac_pwd" &&
         1107  +ac_ls_di=`ls -di .` &&
         1108  +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
         1109  +  as_fn_error $? "working directory cannot be determined"
         1110  +test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
         1111  +  as_fn_error $? "pwd does not report name of working directory"
         1112  +
   455   1113   
   456   1114   # Find the source files, if location was not specified.
   457   1115   if test -z "$srcdir"; then
   458   1116     ac_srcdir_defaulted=yes
   459         -  # Try the directory containing this script, then its parent.
   460         -  ac_prog=$0
   461         -  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
   462         -  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
         1117  +  # Try the directory containing this script, then the parent directory.
         1118  +  ac_confdir=`$as_dirname -- "$as_myself" ||
         1119  +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         1120  +	 X"$as_myself" : 'X\(//\)[^/]' \| \
         1121  +	 X"$as_myself" : 'X\(//\)$' \| \
         1122  +	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
         1123  +$as_echo X"$as_myself" |
         1124  +    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
         1125  +	    s//\1/
         1126  +	    q
         1127  +	  }
         1128  +	  /^X\(\/\/\)[^/].*/{
         1129  +	    s//\1/
         1130  +	    q
         1131  +	  }
         1132  +	  /^X\(\/\/\)$/{
         1133  +	    s//\1/
         1134  +	    q
         1135  +	  }
         1136  +	  /^X\(\/\).*/{
         1137  +	    s//\1/
         1138  +	    q
         1139  +	  }
         1140  +	  s/.*/./; q'`
   463   1141     srcdir=$ac_confdir
   464         -  if test ! -r $srcdir/$ac_unique_file; then
         1142  +  if test ! -r "$srcdir/$ac_unique_file"; then
   465   1143       srcdir=..
   466   1144     fi
   467   1145   else
   468   1146     ac_srcdir_defaulted=no
   469   1147   fi
   470         -if test ! -r $srcdir/$ac_unique_file; then
   471         -  if test "$ac_srcdir_defaulted" = yes; then
   472         -    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
   473         -  else
   474         -    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
   475         -  fi
   476         -fi
   477         -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
   478         -
   479         -# Prefer explicitly selected file to automatically selected ones.
   480         -if test -z "$CONFIG_SITE"; then
   481         -  if test "x$prefix" != xNONE; then
   482         -    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
   483         -  else
   484         -    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
   485         -  fi
   486         -fi
   487         -for ac_site_file in $CONFIG_SITE; do
   488         -  if test -r "$ac_site_file"; then
   489         -    echo "loading site script $ac_site_file"
   490         -    . "$ac_site_file"
         1148  +if test ! -r "$srcdir/$ac_unique_file"; then
         1149  +  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
         1150  +  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
         1151  +fi
         1152  +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
         1153  +ac_abs_confdir=`(
         1154  +	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
         1155  +	pwd)`
         1156  +# When building in place, set srcdir=.
         1157  +if test "$ac_abs_confdir" = "$ac_pwd"; then
         1158  +  srcdir=.
         1159  +fi
         1160  +# Remove unnecessary trailing slashes from srcdir.
         1161  +# Double slashes in file names in object file debugging info
         1162  +# mess up M-x gdb in Emacs.
         1163  +case $srcdir in
         1164  +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
         1165  +esac
         1166  +for ac_var in $ac_precious_vars; do
         1167  +  eval ac_env_${ac_var}_set=\${${ac_var}+set}
         1168  +  eval ac_env_${ac_var}_value=\$${ac_var}
         1169  +  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
         1170  +  eval ac_cv_env_${ac_var}_value=\$${ac_var}
         1171  +done
         1172  +
         1173  +#
         1174  +# Report the --help message.
         1175  +#
         1176  +if test "$ac_init_help" = "long"; then
         1177  +  # Omit some internal or obsolete options to make the list less imposing.
         1178  +  # This message is too long to be a string in the A/UX 3.1 sh.
         1179  +  cat <<_ACEOF
         1180  +\`configure' configures this package to adapt to many kinds of systems.
         1181  +
         1182  +Usage: $0 [OPTION]... [VAR=VALUE]...
         1183  +
         1184  +To assign environment variables (e.g., CC, CFLAGS...), specify them as
         1185  +VAR=VALUE.  See below for descriptions of some of the useful variables.
         1186  +
         1187  +Defaults for the options are specified in brackets.
         1188  +
         1189  +Configuration:
         1190  +  -h, --help              display this help and exit
         1191  +      --help=short        display options specific to this package
         1192  +      --help=recursive    display the short help of all the included packages
         1193  +  -V, --version           display version information and exit
         1194  +  -q, --quiet, --silent   do not print \`checking ...' messages
         1195  +      --cache-file=FILE   cache test results in FILE [disabled]
         1196  +  -C, --config-cache      alias for \`--cache-file=config.cache'
         1197  +  -n, --no-create         do not create output files
         1198  +      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
         1199  +
         1200  +Installation directories:
         1201  +  --prefix=PREFIX         install architecture-independent files in PREFIX
         1202  +                          [$ac_default_prefix]
         1203  +  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
         1204  +                          [PREFIX]
         1205  +
         1206  +By default, \`make install' will install all the files in
         1207  +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
         1208  +an installation prefix other than \`$ac_default_prefix' using \`--prefix',
         1209  +for instance \`--prefix=\$HOME'.
         1210  +
         1211  +For better control, use the options below.
         1212  +
         1213  +Fine tuning of the installation directories:
         1214  +  --bindir=DIR            user executables [EPREFIX/bin]
         1215  +  --sbindir=DIR           system admin executables [EPREFIX/sbin]
         1216  +  --libexecdir=DIR        program executables [EPREFIX/libexec]
         1217  +  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
         1218  +  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
         1219  +  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
         1220  +  --libdir=DIR            object code libraries [EPREFIX/lib]
         1221  +  --includedir=DIR        C header files [PREFIX/include]
         1222  +  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
         1223  +  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
         1224  +  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
         1225  +  --infodir=DIR           info documentation [DATAROOTDIR/info]
         1226  +  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
         1227  +  --mandir=DIR            man documentation [DATAROOTDIR/man]
         1228  +  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
         1229  +  --htmldir=DIR           html documentation [DOCDIR]
         1230  +  --dvidir=DIR            dvi documentation [DOCDIR]
         1231  +  --pdfdir=DIR            pdf documentation [DOCDIR]
         1232  +  --psdir=DIR             ps documentation [DOCDIR]
         1233  +_ACEOF
         1234  +
         1235  +  cat <<\_ACEOF
         1236  +_ACEOF
         1237  +fi
         1238  +
         1239  +if test -n "$ac_init_help"; then
         1240  +
         1241  +  cat <<\_ACEOF
         1242  +
         1243  +Report bugs to the package provider.
         1244  +_ACEOF
         1245  +ac_status=$?
         1246  +fi
         1247  +
         1248  +if test "$ac_init_help" = "recursive"; then
         1249  +  # If there are subdirs, report their specific --help.
         1250  +  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
         1251  +    test -d "$ac_dir" ||
         1252  +      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
         1253  +      continue
         1254  +    ac_builddir=.
         1255  +
         1256  +case "$ac_dir" in
         1257  +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
         1258  +*)
         1259  +  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
         1260  +  # A ".." for each directory in $ac_dir_suffix.
         1261  +  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
         1262  +  case $ac_top_builddir_sub in
         1263  +  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
         1264  +  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
         1265  +  esac ;;
         1266  +esac
         1267  +ac_abs_top_builddir=$ac_pwd
         1268  +ac_abs_builddir=$ac_pwd$ac_dir_suffix
         1269  +# for backward compatibility:
         1270  +ac_top_builddir=$ac_top_build_prefix
         1271  +
         1272  +case $srcdir in
         1273  +  .)  # We are building in place.
         1274  +    ac_srcdir=.
         1275  +    ac_top_srcdir=$ac_top_builddir_sub
         1276  +    ac_abs_top_srcdir=$ac_pwd ;;
         1277  +  [\\/]* | ?:[\\/]* )  # Absolute name.
         1278  +    ac_srcdir=$srcdir$ac_dir_suffix;
         1279  +    ac_top_srcdir=$srcdir
         1280  +    ac_abs_top_srcdir=$srcdir ;;
         1281  +  *) # Relative name.
         1282  +    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
         1283  +    ac_top_srcdir=$ac_top_build_prefix$srcdir
         1284  +    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
         1285  +esac
         1286  +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
         1287  +
         1288  +    cd "$ac_dir" || { ac_status=$?; continue; }
         1289  +    # Check for guested configure.
         1290  +    if test -f "$ac_srcdir/configure.gnu"; then
         1291  +      echo &&
         1292  +      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
         1293  +    elif test -f "$ac_srcdir/configure"; then
         1294  +      echo &&
         1295  +      $SHELL "$ac_srcdir/configure" --help=recursive
         1296  +    else
         1297  +      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
         1298  +    fi || ac_status=$?
         1299  +    cd "$ac_pwd" || { ac_status=$?; break; }
         1300  +  done
         1301  +fi
         1302  +
         1303  +test -n "$ac_init_help" && exit $ac_status
         1304  +if $ac_init_version; then
         1305  +  cat <<\_ACEOF
         1306  +configure
         1307  +generated by GNU Autoconf 2.69
         1308  +
         1309  +Copyright (C) 2012 Free Software Foundation, Inc.
         1310  +This configure script is free software; the Free Software Foundation
         1311  +gives unlimited permission to copy, distribute and modify it.
         1312  +_ACEOF
         1313  +  exit
         1314  +fi
         1315  +
         1316  +## ------------------------ ##
         1317  +## Autoconf initialization. ##
         1318  +## ------------------------ ##
         1319  +cat >config.log <<_ACEOF
         1320  +This file contains any messages produced by compilers while
         1321  +running configure, to aid debugging if configure makes a mistake.
         1322  +
         1323  +It was created by $as_me, which was
         1324  +generated by GNU Autoconf 2.69.  Invocation command line was
         1325  +
         1326  +  $ $0 $@
         1327  +
         1328  +_ACEOF
         1329  +exec 5>>config.log
         1330  +{
         1331  +cat <<_ASUNAME
         1332  +## --------- ##
         1333  +## Platform. ##
         1334  +## --------- ##
         1335  +
         1336  +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
         1337  +uname -m = `(uname -m) 2>/dev/null || echo unknown`
         1338  +uname -r = `(uname -r) 2>/dev/null || echo unknown`
         1339  +uname -s = `(uname -s) 2>/dev/null || echo unknown`
         1340  +uname -v = `(uname -v) 2>/dev/null || echo unknown`
         1341  +
         1342  +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
         1343  +/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
         1344  +
         1345  +/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
         1346  +/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
         1347  +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
         1348  +/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
         1349  +/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
         1350  +/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
         1351  +/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
         1352  +
         1353  +_ASUNAME
         1354  +
         1355  +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
         1356  +for as_dir in $PATH
         1357  +do
         1358  +  IFS=$as_save_IFS
         1359  +  test -z "$as_dir" && as_dir=.
         1360  +    $as_echo "PATH: $as_dir"
         1361  +  done
         1362  +IFS=$as_save_IFS
         1363  +
         1364  +} >&5
         1365  +
         1366  +cat >&5 <<_ACEOF
         1367  +
         1368  +
         1369  +## ----------- ##
         1370  +## Core tests. ##
         1371  +## ----------- ##
         1372  +
         1373  +_ACEOF
         1374  +
         1375  +
         1376  +# Keep a trace of the command line.
         1377  +# Strip out --no-create and --no-recursion so they do not pile up.
         1378  +# Strip out --silent because we don't want to record it for future runs.
         1379  +# Also quote any args containing shell meta-characters.
         1380  +# Make two passes to allow for proper duplicate-argument suppression.
         1381  +ac_configure_args=
         1382  +ac_configure_args0=
         1383  +ac_configure_args1=
         1384  +ac_must_keep_next=false
         1385  +for ac_pass in 1 2
         1386  +do
         1387  +  for ac_arg
         1388  +  do
         1389  +    case $ac_arg in
         1390  +    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
         1391  +    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
         1392  +    | -silent | --silent | --silen | --sile | --sil)
         1393  +      continue ;;
         1394  +    *\'*)
         1395  +      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
         1396  +    esac
         1397  +    case $ac_pass in
         1398  +    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
         1399  +    2)
         1400  +      as_fn_append ac_configure_args1 " '$ac_arg'"
         1401  +      if test $ac_must_keep_next = true; then
         1402  +	ac_must_keep_next=false # Got value, back to normal.
         1403  +      else
         1404  +	case $ac_arg in
         1405  +	  *=* | --config-cache | -C | -disable-* | --disable-* \
         1406  +	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
         1407  +	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
         1408  +	  | -with-* | --with-* | -without-* | --without-* | --x)
         1409  +	    case "$ac_configure_args0 " in
         1410  +	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
         1411  +	    esac
         1412  +	    ;;
         1413  +	  -* ) ac_must_keep_next=true ;;
         1414  +	esac
         1415  +      fi
         1416  +      as_fn_append ac_configure_args " '$ac_arg'"
         1417  +      ;;
         1418  +    esac
         1419  +  done
         1420  +done
         1421  +{ ac_configure_args0=; unset ac_configure_args0;}
         1422  +{ ac_configure_args1=; unset ac_configure_args1;}
         1423  +
         1424  +# When interrupted or exit'd, cleanup temporary files, and complete
         1425  +# config.log.  We remove comments because anyway the quotes in there
         1426  +# would cause problems or look ugly.
         1427  +# WARNING: Use '\'' to represent an apostrophe within the trap.
         1428  +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
         1429  +trap 'exit_status=$?
         1430  +  # Save into config.log some information that might help in debugging.
         1431  +  {
         1432  +    echo
         1433  +
         1434  +    $as_echo "## ---------------- ##
         1435  +## Cache variables. ##
         1436  +## ---------------- ##"
         1437  +    echo
         1438  +    # The following way of writing the cache mishandles newlines in values,
         1439  +(
         1440  +  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
         1441  +    eval ac_val=\$$ac_var
         1442  +    case $ac_val in #(
         1443  +    *${as_nl}*)
         1444  +      case $ac_var in #(
         1445  +      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
         1446  +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
         1447  +      esac
         1448  +      case $ac_var in #(
         1449  +      _ | IFS | as_nl) ;; #(
         1450  +      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
         1451  +      *) { eval $ac_var=; unset $ac_var;} ;;
         1452  +      esac ;;
         1453  +    esac
         1454  +  done
         1455  +  (set) 2>&1 |
         1456  +    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
         1457  +    *${as_nl}ac_space=\ *)
         1458  +      sed -n \
         1459  +	"s/'\''/'\''\\\\'\'''\''/g;
         1460  +	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
         1461  +      ;; #(
         1462  +    *)
         1463  +      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
         1464  +      ;;
         1465  +    esac |
         1466  +    sort
         1467  +)
         1468  +    echo
         1469  +
         1470  +    $as_echo "## ----------------- ##
         1471  +## Output variables. ##
         1472  +## ----------------- ##"
         1473  +    echo
         1474  +    for ac_var in $ac_subst_vars
         1475  +    do
         1476  +      eval ac_val=\$$ac_var
         1477  +      case $ac_val in
         1478  +      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
         1479  +      esac
         1480  +      $as_echo "$ac_var='\''$ac_val'\''"
         1481  +    done | sort
         1482  +    echo
         1483  +
         1484  +    if test -n "$ac_subst_files"; then
         1485  +      $as_echo "## ------------------- ##
         1486  +## File substitutions. ##
         1487  +## ------------------- ##"
         1488  +      echo
         1489  +      for ac_var in $ac_subst_files
         1490  +      do
         1491  +	eval ac_val=\$$ac_var
         1492  +	case $ac_val in
         1493  +	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
         1494  +	esac
         1495  +	$as_echo "$ac_var='\''$ac_val'\''"
         1496  +      done | sort
         1497  +      echo
         1498  +    fi
         1499  +
         1500  +    if test -s confdefs.h; then
         1501  +      $as_echo "## ----------- ##
         1502  +## confdefs.h. ##
         1503  +## ----------- ##"
         1504  +      echo
         1505  +      cat confdefs.h
         1506  +      echo
         1507  +    fi
         1508  +    test "$ac_signal" != 0 &&
         1509  +      $as_echo "$as_me: caught signal $ac_signal"
         1510  +    $as_echo "$as_me: exit $exit_status"
         1511  +  } >&5
         1512  +  rm -f core *.core core.conftest.* &&
         1513  +    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
         1514  +    exit $exit_status
         1515  +' 0
         1516  +for ac_signal in 1 2 13 15; do
         1517  +  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
         1518  +done
         1519  +ac_signal=0
         1520  +
         1521  +# confdefs.h avoids OS command line length limits that DEFS can exceed.
         1522  +rm -f -r conftest* confdefs.h
         1523  +
         1524  +$as_echo "/* confdefs.h */" > confdefs.h
         1525  +
         1526  +# Predefined preprocessor variables.
         1527  +
         1528  +cat >>confdefs.h <<_ACEOF
         1529  +#define PACKAGE_NAME "$PACKAGE_NAME"
         1530  +_ACEOF
         1531  +
         1532  +cat >>confdefs.h <<_ACEOF
         1533  +#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
         1534  +_ACEOF
         1535  +
         1536  +cat >>confdefs.h <<_ACEOF
         1537  +#define PACKAGE_VERSION "$PACKAGE_VERSION"
         1538  +_ACEOF
         1539  +
         1540  +cat >>confdefs.h <<_ACEOF
         1541  +#define PACKAGE_STRING "$PACKAGE_STRING"
         1542  +_ACEOF
         1543  +
         1544  +cat >>confdefs.h <<_ACEOF
         1545  +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
         1546  +_ACEOF
         1547  +
         1548  +cat >>confdefs.h <<_ACEOF
         1549  +#define PACKAGE_URL "$PACKAGE_URL"
         1550  +_ACEOF
         1551  +
         1552  +
         1553  +# Let the site file select an alternate cache file if it wants to.
         1554  +# Prefer an explicitly selected file to automatically selected ones.
         1555  +ac_site_file1=NONE
         1556  +ac_site_file2=NONE
         1557  +if test -n "$CONFIG_SITE"; then
         1558  +  # We do not want a PATH search for config.site.
         1559  +  case $CONFIG_SITE in #((
         1560  +    -*)  ac_site_file1=./$CONFIG_SITE;;
         1561  +    */*) ac_site_file1=$CONFIG_SITE;;
         1562  +    *)   ac_site_file1=./$CONFIG_SITE;;
         1563  +  esac
         1564  +elif test "x$prefix" != xNONE; then
         1565  +  ac_site_file1=$prefix/share/config.site
         1566  +  ac_site_file2=$prefix/etc/config.site
         1567  +else
         1568  +  ac_site_file1=$ac_default_prefix/share/config.site
         1569  +  ac_site_file2=$ac_default_prefix/etc/config.site
         1570  +fi
         1571  +for ac_site_file in "$ac_site_file1" "$ac_site_file2"
         1572  +do
         1573  +  test "x$ac_site_file" = xNONE && continue
         1574  +  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
         1575  +    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
         1576  +$as_echo "$as_me: loading site script $ac_site_file" >&6;}
         1577  +    sed 's/^/| /' "$ac_site_file" >&5
         1578  +    . "$ac_site_file" \
         1579  +      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
         1580  +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
         1581  +as_fn_error $? "failed to load site script $ac_site_file
         1582  +See \`config.log' for more details" "$LINENO" 5; }
   491   1583     fi
   492   1584   done
   493   1585   
   494   1586   if test -r "$cache_file"; then
   495         -  echo "loading cache $cache_file"
   496         -  . $cache_file
   497         -else
   498         -  echo "creating cache $cache_file"
   499         -  > $cache_file
   500         -fi
         1587  +  # Some versions of bash will fail to source /dev/null (special files
         1588  +  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
         1589  +  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
         1590  +    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
         1591  +$as_echo "$as_me: loading cache $cache_file" >&6;}
         1592  +    case $cache_file in
         1593  +      [\\/]* | ?:[\\/]* ) . "$cache_file";;
         1594  +      *)                      . "./$cache_file";;
         1595  +    esac
         1596  +  fi
         1597  +else
         1598  +  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
         1599  +$as_echo "$as_me: creating cache $cache_file" >&6;}
         1600  +  >$cache_file
         1601  +fi
         1602  +
         1603  +# Check that the precious variables saved in the cache have kept the same
         1604  +# value.
         1605  +ac_cache_corrupted=false
         1606  +for ac_var in $ac_precious_vars; do
         1607  +  eval ac_old_set=\$ac_cv_env_${ac_var}_set
         1608  +  eval ac_new_set=\$ac_env_${ac_var}_set
         1609  +  eval ac_old_val=\$ac_cv_env_${ac_var}_value
         1610  +  eval ac_new_val=\$ac_env_${ac_var}_value
         1611  +  case $ac_old_set,$ac_new_set in
         1612  +    set,)
         1613  +      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
         1614  +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
         1615  +      ac_cache_corrupted=: ;;
         1616  +    ,set)
         1617  +      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
         1618  +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
         1619  +      ac_cache_corrupted=: ;;
         1620  +    ,);;
         1621  +    *)
         1622  +      if test "x$ac_old_val" != "x$ac_new_val"; then
         1623  +	# differences in whitespace do not lead to failure.
         1624  +	ac_old_val_w=`echo x $ac_old_val`
         1625  +	ac_new_val_w=`echo x $ac_new_val`
         1626  +	if test "$ac_old_val_w" != "$ac_new_val_w"; then
         1627  +	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
         1628  +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
         1629  +	  ac_cache_corrupted=:
         1630  +	else
         1631  +	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
         1632  +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
         1633  +	  eval $ac_var=\$ac_old_val
         1634  +	fi
         1635  +	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
         1636  +$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
         1637  +	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
         1638  +$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
         1639  +      fi;;
         1640  +  esac
         1641  +  # Pass precious variables to config.status.
         1642  +  if test "$ac_new_set" = set; then
         1643  +    case $ac_new_val in
         1644  +    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
         1645  +    *) ac_arg=$ac_var=$ac_new_val ;;
         1646  +    esac
         1647  +    case " $ac_configure_args " in
         1648  +      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
         1649  +      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
         1650  +    esac
         1651  +  fi
         1652  +done
         1653  +if $ac_cache_corrupted; then
         1654  +  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
         1655  +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
         1656  +  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
         1657  +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
         1658  +  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
         1659  +fi
         1660  +## -------------------- ##
         1661  +## Main body of script. ##
         1662  +## -------------------- ##
   501   1663   
   502   1664   ac_ext=c
   503         -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
   504   1665   ac_cpp='$CPP $CPPFLAGS'
   505         -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
   506         -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
   507         -cross_compiling=$ac_cv_prog_cc_cross
   508         -
   509         -ac_exeext=
   510         -ac_objext=o
   511         -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
   512         -  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
   513         -  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
   514         -    ac_n= ac_c='
   515         -' ac_t='	'
   516         -  else
   517         -    ac_n=-n ac_c= ac_t=
   518         -  fi
   519         -else
   520         -  ac_n= ac_c='\c' ac_t=
   521         -fi
         1666  +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
         1667  +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
         1668  +ac_compiler_gnu=$ac_cv_c_compiler_gnu
   522   1669   
   523   1670   
   524   1671   
   525   1672   ac_aux_dir=
   526         -for ac_dir in ../../tclconfig $srcdir/../../tclconfig; do
   527         -  if test -f $ac_dir/install-sh; then
         1673  +for ac_dir in ../../tclconfig "$srcdir"/../../tclconfig; do
         1674  +  if test -f "$ac_dir/install-sh"; then
   528   1675       ac_aux_dir=$ac_dir
   529   1676       ac_install_sh="$ac_aux_dir/install-sh -c"
   530   1677       break
   531         -  elif test -f $ac_dir/install.sh; then
         1678  +  elif test -f "$ac_dir/install.sh"; then
   532   1679       ac_aux_dir=$ac_dir
   533   1680       ac_install_sh="$ac_aux_dir/install.sh -c"
   534   1681       break
         1682  +  elif test -f "$ac_dir/shtool"; then
         1683  +    ac_aux_dir=$ac_dir
         1684  +    ac_install_sh="$ac_aux_dir/shtool install -c"
         1685  +    break
   535   1686     fi
   536   1687   done
   537   1688   if test -z "$ac_aux_dir"; then
   538         -  { echo "configure: error: can not find install-sh or install.sh in ../../tclconfig $srcdir/../../tclconfig" 1>&2; exit 1; }
         1689  +  as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../../tclconfig \"$srcdir\"/../../tclconfig" "$LINENO" 5
   539   1690   fi
   540         -ac_config_guess=$ac_aux_dir/config.guess
   541         -ac_config_sub=$ac_aux_dir/config.sub
   542         -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
         1691  +
         1692  +# These three variables are undocumented and unsupported,
         1693  +# and are intended to be withdrawn in a future Autoconf release.
         1694  +# They can cause serious problems if a builder's source tree is in a directory
         1695  +# whose full name contains unusual characters.
         1696  +ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
         1697  +ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
         1698  +ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
         1699  +
   543   1700   
   544   1701   CONFIGDIR=${srcdir}/../../tclconfig
   545   1702   
   546   1703   
   547   1704   #----------------------------------------------------------------------
   548   1705   # __CHANGE__
   549   1706   # Set your package name and version numbers here.  The NODOT_VERSION is
................................................................................
   565   1722   
   566   1723   
   567   1724   #--------------------------------------------------------------------
   568   1725   # We put this here so that you can compile with -DVERSION="1.2" to
   569   1726   # encode the package version directly into the source files.
   570   1727   #--------------------------------------------------------------------
   571   1728   
   572         -eval cat >> confdefs.h <<EOF
         1729  +eval cat >>confdefs.h <<_ACEOF
   573   1730   #define VERSION "${VERSION}"
   574         -EOF
         1731  +_ACEOF
   575   1732   
   576   1733   
   577   1734   #--------------------------------------------------------------------
   578   1735   # Call TEA_INIT as the first TEA_ macro to set up initial vars.
   579   1736   # This will define a ${TEA_PLATFORM} variable == "unix" or "windows".
   580   1737   #--------------------------------------------------------------------
   581   1738   
................................................................................
   615   1772   # Find a good install program.  We prefer a C program (faster),
   616   1773   # so one script is as good as another.  But avoid the broken or
   617   1774   # incompatible versions:
   618   1775   # SysV /etc/install, /usr/sbin/install
   619   1776   # SunOS /usr/etc/install
   620   1777   # IRIX /sbin/install
   621   1778   # AIX /bin/install
         1779  +# AmigaOS /C/install, which installs bootblocks on floppy discs
   622   1780   # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
   623   1781   # AFS /usr/afsws/bin/install, which mishandles nonexistent args
   624   1782   # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
         1783  +# OS/2's system install, which has a completely different semantic
   625   1784   # ./install, which can be erroneously created by make from ./install.sh.
   626         -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
   627         -echo "configure:628: checking for a BSD compatible install" >&5
         1785  +# Reject install programs that cannot install multiple files.
         1786  +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
         1787  +$as_echo_n "checking for a BSD-compatible install... " >&6; }
   628   1788   if test -z "$INSTALL"; then
   629         -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   630         -  echo $ac_n "(cached) $ac_c" 1>&6
         1789  +if ${ac_cv_path_install+:} false; then :
         1790  +  $as_echo_n "(cached) " >&6
   631   1791   else
   632         -    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
   633         -  for ac_dir in $PATH; do
         1792  +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
         1793  +for as_dir in $PATH
         1794  +do
         1795  +  IFS=$as_save_IFS
         1796  +  test -z "$as_dir" && as_dir=.
   634   1797       # Account for people who put trailing slashes in PATH elements.
   635         -    case "$ac_dir/" in
   636         -    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
   637         -    *)
   638         -      # OSF1 and SCO ODT 3.0 have their own names for install.
   639         -      # Don't use installbsd from OSF since it installs stuff as root
   640         -      # by default.
   641         -      for ac_prog in ginstall scoinst install; do
   642         -        if test -f $ac_dir/$ac_prog; then
         1798  +case $as_dir/ in #((
         1799  +  ./ | .// | /[cC]/* | \
         1800  +  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
         1801  +  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
         1802  +  /usr/ucb/* ) ;;
         1803  +  *)
         1804  +    # OSF1 and SCO ODT 3.0 have their own names for install.
         1805  +    # Don't use installbsd from OSF since it installs stuff as root
         1806  +    # by default.
         1807  +    for ac_prog in ginstall scoinst install; do
         1808  +      for ac_exec_ext in '' $ac_executable_extensions; do
         1809  +	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
   643   1810   	  if test $ac_prog = install &&
   644         -            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
         1811  +	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
   645   1812   	    # AIX install.  It has an incompatible calling convention.
   646   1813   	    :
         1814  +	  elif test $ac_prog = install &&
         1815  +	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
         1816  +	    # program-specific install script used by HP pwplus--don't use.
         1817  +	    :
   647   1818   	  else
   648         -	    ac_cv_path_install="$ac_dir/$ac_prog -c"
   649         -	    break 2
         1819  +	    rm -rf conftest.one conftest.two conftest.dir
         1820  +	    echo one > conftest.one
         1821  +	    echo two > conftest.two
         1822  +	    mkdir conftest.dir
         1823  +	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
         1824  +	      test -s conftest.one && test -s conftest.two &&
         1825  +	      test -s conftest.dir/conftest.one &&
         1826  +	      test -s conftest.dir/conftest.two
         1827  +	    then
         1828  +	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
         1829  +	      break 3
         1830  +	    fi
   650   1831   	  fi
   651   1832   	fi
   652   1833         done
   653         -      ;;
   654         -    esac
         1834  +    done
         1835  +    ;;
         1836  +esac
         1837  +
   655   1838     done
   656         -  IFS="$ac_save_IFS"
         1839  +IFS=$as_save_IFS
         1840  +
         1841  +rm -rf conftest.one conftest.two conftest.dir
   657   1842   
   658   1843   fi
   659   1844     if test "${ac_cv_path_install+set}" = set; then
   660         -    INSTALL="$ac_cv_path_install"
         1845  +    INSTALL=$ac_cv_path_install
   661   1846     else
   662         -    # As a last resort, use the slow shell script.  We don't cache a
   663         -    # path for INSTALL within a source directory, because that will
         1847  +    # As a last resort, use the slow shell script.  Don't cache a
         1848  +    # value for INSTALL within a source directory, because that will
   664   1849       # break other packages using the cache if that directory is
   665         -    # removed, or if the path is relative.
   666         -    INSTALL="$ac_install_sh"
         1850  +    # removed, or if the value is a relative name.
         1851  +    INSTALL=$ac_install_sh
   667   1852     fi
   668   1853   fi
   669         -echo "$ac_t""$INSTALL" 1>&6
         1854  +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
         1855  +$as_echo "$INSTALL" >&6; }
   670   1856   
   671   1857   # Use test -z because SunOS4 sh mishandles braces in ${var-val}.
   672   1858   # It thinks the first close brace ends the variable substitution.
   673   1859   test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
   674   1860   
   675         -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
         1861  +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
   676   1862   
   677   1863   test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
   678   1864   
   679   1865   
   680   1866   #--------------------------------------------------------------------
   681   1867   # __CHANGE__
   682   1868   # Choose which headers you need.  Extension authors should try very
................................................................................
   779   1965   
   780   1966   #--------------------------------------------------------------------
   781   1967   # Finally, substitute all of the various values into the Makefile.
   782   1968   # You may alternatively have a special pkgIndex.tcl.in or other files
   783   1969   # which require substituting th AC variables in.  Include these here.
   784   1970   #--------------------------------------------------------------------
   785   1971   
   786         -trap '' 1 2 15
   787         -cat > confcache <<\EOF
         1972  +ac_config_files="$ac_config_files Makefile pkgIndex.tcl"
         1973  +
         1974  +cat >confcache <<\_ACEOF
   788   1975   # This file is a shell script that caches the results of configure
   789   1976   # tests run on this system so they can be shared between configure
   790         -# scripts and configure runs.  It is not useful on other systems.
   791         -# If it contains results you don't want to keep, you may remove or edit it.
         1977  +# scripts and configure runs, see configure's option --config-cache.
         1978  +# It is not useful on other systems.  If it contains results you don't
         1979  +# want to keep, you may remove or edit it.
   792   1980   #
   793         -# By default, configure uses ./config.cache as the cache file,
   794         -# creating it if it does not exist already.  You can give configure
   795         -# the --cache-file=FILE option to use a different cache file; that is
   796         -# what configure does when it calls configure scripts in
   797         -# subdirectories, so they share the cache.
   798         -# Giving --cache-file=/dev/null disables caching, for debugging configure.
   799         -# config.status only pays attention to the cache file if you give it the
   800         -# --recheck option to rerun configure.
         1981  +# config.status only pays attention to the cache file if you give it
         1982  +# the --recheck option to rerun configure.
   801   1983   #
   802         -EOF
         1984  +# `ac_cv_env_foo' variables (set or unset) will be overridden when
         1985  +# loading this file, other *unset* `ac_cv_foo' will be assigned the
         1986  +# following values.
         1987  +
         1988  +_ACEOF
         1989  +
   803   1990   # The following way of writing the cache mishandles newlines in values,
   804   1991   # but we know of no workaround that is simple, portable, and efficient.
   805         -# So, don't put newlines in cache variables' values.
         1992  +# So, we kill variables containing newlines.
   806   1993   # Ultrix sh set writes to stderr and can't be redirected directly,
   807   1994   # and sets the high bit in the cache file unless we assign to the vars.
   808         -(set) 2>&1 |
   809         -  case `(ac_space=' '; set | grep ac_space) 2>&1` in
   810         -  *ac_space=\ *)
   811         -    # `set' does not quote correctly, so add quotes (double-quote substitution
   812         -    # turns \\\\ into \\, and sed turns \\ into \).
   813         -    sed -n \
   814         -      -e "s/'/'\\\\''/g" \
   815         -      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
   816         -    ;;
   817         -  *)
   818         -    # `set' quotes correctly as required by POSIX, so do not add quotes.
   819         -    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
   820         -    ;;
   821         -  esac >> confcache
   822         -if cmp -s $cache_file confcache; then
   823         -  :
   824         -else
   825         -  if test -w $cache_file; then
   826         -    echo "updating cache $cache_file"
   827         -    cat confcache > $cache_file
         1995  +(
         1996  +  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
         1997  +    eval ac_val=\$$ac_var
         1998  +    case $ac_val in #(
         1999  +    *${as_nl}*)
         2000  +      case $ac_var in #(
         2001  +      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
         2002  +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
         2003  +      esac
         2004  +      case $ac_var in #(
         2005  +      _ | IFS | as_nl) ;; #(
         2006  +      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
         2007  +      *) { eval $ac_var=; unset $ac_var;} ;;
         2008  +      esac ;;
         2009  +    esac
         2010  +  done
         2011  +
         2012  +  (set) 2>&1 |
         2013  +    case $as_nl`(ac_space=' '; set) 2>&1` in #(
         2014  +    *${as_nl}ac_space=\ *)
         2015  +      # `set' does not quote correctly, so add quotes: double-quote
         2016  +      # substitution turns \\\\ into \\, and sed turns \\ into \.
         2017  +      sed -n \
         2018  +	"s/'/'\\\\''/g;
         2019  +	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
         2020  +      ;; #(
         2021  +    *)
         2022  +      # `set' quotes correctly as required by POSIX, so do not add quotes.
         2023  +      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
         2024  +      ;;
         2025  +    esac |
         2026  +    sort
         2027  +) |
         2028  +  sed '
         2029  +     /^ac_cv_env_/b end
         2030  +     t clear
         2031  +     :clear
         2032  +     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
         2033  +     t end
         2034  +     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
         2035  +     :end' >>confcache
         2036  +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
         2037  +  if test -w "$cache_file"; then
         2038  +    if test "x$cache_file" != "x/dev/null"; then
         2039  +      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
         2040  +$as_echo "$as_me: updating cache $cache_file" >&6;}
         2041  +      if test ! -f "$cache_file" || test -h "$cache_file"; then
         2042  +	cat confcache >"$cache_file"
         2043  +      else
         2044  +        case $cache_file in #(
         2045  +        */* | ?:*)
         2046  +	  mv -f confcache "$cache_file"$$ &&
         2047  +	  mv -f "$cache_file"$$ "$cache_file" ;; #(
         2048  +        *)
         2049  +	  mv -f confcache "$cache_file" ;;
         2050  +	esac
         2051  +      fi
         2052  +    fi
   828   2053     else
   829         -    echo "not updating unwritable cache $cache_file"
         2054  +    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
         2055  +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
   830   2056     fi
   831   2057   fi
   832   2058   rm -f confcache
   833   2059   
   834         -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
   835         -
   836   2060   test "x$prefix" = xNONE && prefix=$ac_default_prefix
   837   2061   # Let make expand exec_prefix.
   838   2062   test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
   839   2063   
   840         -# Any assignment to VPATH causes Sun make to only execute
   841         -# the first set of double-colon rules, so remove it if not needed.
   842         -# If there is a colon in the path, we need to keep it.
   843         -if test "x$srcdir" = x.; then
   844         -  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
   845         -fi
   846         -
   847         -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
   848         -
   849   2064   # Transform confdefs.h into DEFS.
   850   2065   # Protect against shell expansion while executing Makefile rules.
   851   2066   # Protect against Makefile macro expansion.
   852         -cat > conftest.defs <<\EOF
   853         -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
   854         -s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
   855         -s%\[%\\&%g
   856         -s%\]%\\&%g
   857         -s%\$%$$%g
   858         -EOF
   859         -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
   860         -rm -f conftest.defs
   861         -
   862         -
   863         -# Without the "./", some shells look in PATH for config.status.
   864         -: ${CONFIG_STATUS=./config.status}
   865         -
   866         -echo creating $CONFIG_STATUS
   867         -rm -f $CONFIG_STATUS
   868         -cat > $CONFIG_STATUS <<EOF
   869         -#! /bin/sh
   870         -# Generated automatically by configure.
   871         -# Run this file to recreate the current configuration.
   872         -# This directory was configured as follows,
   873         -# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
   874         -#
   875         -# $0 $ac_configure_args
   876         -#
         2067  +#
         2068  +# If the first sed substitution is executed (which looks for macros that
         2069  +# take arguments), then branch to the quote section.  Otherwise,
         2070  +# look for a macro that doesn't take arguments.
         2071  +ac_script='
         2072  +:mline
         2073  +/\\$/{
         2074  + N
         2075  + s,\\\n,,
         2076  + b mline
         2077  +}
         2078  +t clear
         2079  +:clear
         2080  +s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
         2081  +t quote
         2082  +s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
         2083  +t quote
         2084  +b any
         2085  +:quote
         2086  +s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
         2087  +s/\[/\\&/g
         2088  +s/\]/\\&/g
         2089  +s/\$/$$/g
         2090  +H
         2091  +:any
         2092  +${
         2093  +	g
         2094  +	s/^\n//
         2095  +	s/\n/ /g
         2096  +	p
         2097  +}
         2098  +'
         2099  +DEFS=`sed -n "$ac_script" confdefs.h`
         2100  +
         2101  +
         2102  +ac_libobjs=
         2103  +ac_ltlibobjs=
         2104  +U=
         2105  +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
         2106  +  # 1. Remove the extension, and $U if already installed.
         2107  +  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
         2108  +  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
         2109  +  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
         2110  +  #    will be set to the directory where LIBOBJS objects are built.
         2111  +  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
         2112  +  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
         2113  +done
         2114  +LIBOBJS=$ac_libobjs
         2115  +
         2116  +LTLIBOBJS=$ac_ltlibobjs
         2117  +
         2118  +
         2119  +
         2120  +: "${CONFIG_STATUS=./config.status}"
         2121  +ac_write_fail=0
         2122  +ac_clean_files_save=$ac_clean_files
         2123  +ac_clean_files="$ac_clean_files $CONFIG_STATUS"
         2124  +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
         2125  +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
         2126  +as_write_fail=0
         2127  +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
         2128  +#! $SHELL
         2129  +# Generated by $as_me.
         2130  +# Run this file to recreate the current configuration.
   877   2131   # Compiler output produced by configure, useful for debugging
   878         -# configure, is in ./config.log if it exists.
   879         -
   880         -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
   881         -for ac_option
         2132  +# configure, is in config.log if it exists.
         2133  +
         2134  +debug=false
         2135  +ac_cs_recheck=false
         2136  +ac_cs_silent=false
         2137  +
         2138  +SHELL=\${CONFIG_SHELL-$SHELL}
         2139  +export SHELL
         2140  +_ASEOF
         2141  +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
         2142  +## -------------------- ##
         2143  +## M4sh Initialization. ##
         2144  +## -------------------- ##
         2145  +
         2146  +# Be more Bourne compatible
         2147  +DUALCASE=1; export DUALCASE # for MKS sh
         2148  +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
         2149  +  emulate sh
         2150  +  NULLCMD=:
         2151  +  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
         2152  +  # is contrary to our usage.  Disable this feature.
         2153  +  alias -g '${1+"$@"}'='"$@"'
         2154  +  setopt NO_GLOB_SUBST
         2155  +else
         2156  +  case `(set -o) 2>/dev/null` in #(
         2157  +  *posix*) :
         2158  +    set -o posix ;; #(
         2159  +  *) :
         2160  +     ;;
         2161  +esac
         2162  +fi
         2163  +
         2164  +
         2165  +as_nl='
         2166  +'
         2167  +export as_nl
         2168  +# Printing a long string crashes Solaris 7 /usr/bin/printf.
         2169  +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
         2170  +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
         2171  +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
         2172  +# Prefer a ksh shell builtin over an external printf program on Solaris,
         2173  +# but without wasting forks for bash or zsh.
         2174  +if test -z "$BASH_VERSION$ZSH_VERSION" \
         2175  +    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
         2176  +  as_echo='print -r --'
         2177  +  as_echo_n='print -rn --'
         2178  +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
         2179  +  as_echo='printf %s\n'
         2180  +  as_echo_n='printf %s'
         2181  +else
         2182  +  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
         2183  +    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
         2184  +    as_echo_n='/usr/ucb/echo -n'
         2185  +  else
         2186  +    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
         2187  +    as_echo_n_body='eval
         2188  +      arg=$1;
         2189  +      case $arg in #(
         2190  +      *"$as_nl"*)
         2191  +	expr "X$arg" : "X\\(.*\\)$as_nl";
         2192  +	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
         2193  +      esac;
         2194  +      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
         2195  +    '
         2196  +    export as_echo_n_body
         2197  +    as_echo_n='sh -c $as_echo_n_body as_echo'
         2198  +  fi
         2199  +  export as_echo_body
         2200  +  as_echo='sh -c $as_echo_body as_echo'
         2201  +fi
         2202  +
         2203  +# The user is always right.
         2204  +if test "${PATH_SEPARATOR+set}" != set; then
         2205  +  PATH_SEPARATOR=:
         2206  +  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
         2207  +    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
         2208  +      PATH_SEPARATOR=';'
         2209  +  }
         2210  +fi
         2211  +
         2212  +
         2213  +# IFS
         2214  +# We need space, tab and new line, in precisely that order.  Quoting is
         2215  +# there to prevent editors from complaining about space-tab.
         2216  +# (If _AS_PATH_WALK were called with IFS unset, it would disable word
         2217  +# splitting by setting IFS to empty value.)
         2218  +IFS=" ""	$as_nl"
         2219  +
         2220  +# Find who we are.  Look in the path if we contain no directory separator.
         2221  +as_myself=
         2222  +case $0 in #((
         2223  +  *[\\/]* ) as_myself=$0 ;;
         2224  +  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
         2225  +for as_dir in $PATH
         2226  +do
         2227  +  IFS=$as_save_IFS
         2228  +  test -z "$as_dir" && as_dir=.
         2229  +    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
         2230  +  done
         2231  +IFS=$as_save_IFS
         2232  +
         2233  +     ;;
         2234  +esac
         2235  +# We did not find ourselves, most probably we were run as `sh COMMAND'
         2236  +# in which case we are not to be found in the path.
         2237  +if test "x$as_myself" = x; then
         2238  +  as_myself=$0
         2239  +fi
         2240  +if test ! -f "$as_myself"; then
         2241  +  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
         2242  +  exit 1
         2243  +fi
         2244  +
         2245  +# Unset variables that we do not need and which cause bugs (e.g. in
         2246  +# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
         2247  +# suppresses any "Segmentation fault" message there.  '((' could
         2248  +# trigger a bug in pdksh 5.2.14.
         2249  +for as_var in BASH_ENV ENV MAIL MAILPATH
         2250  +do eval test x\${$as_var+set} = xset \
         2251  +  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
         2252  +done
         2253  +PS1='$ '
         2254  +PS2='> '
         2255  +PS4='+ '
         2256  +
         2257  +# NLS nuisances.
         2258  +LC_ALL=C
         2259  +export LC_ALL
         2260  +LANGUAGE=C
         2261  +export LANGUAGE
         2262  +
         2263  +# CDPATH.
         2264  +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
         2265  +
         2266  +
         2267  +# as_fn_error STATUS ERROR [LINENO LOG_FD]
         2268  +# ----------------------------------------
         2269  +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
         2270  +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
         2271  +# script with STATUS, using 1 if that was 0.
         2272  +as_fn_error ()
         2273  +{
         2274  +  as_status=$1; test $as_status -eq 0 && as_status=1
         2275  +  if test "$4"; then
         2276  +    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
         2277  +    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
         2278  +  fi
         2279  +  $as_echo "$as_me: error: $2" >&2
         2280  +  as_fn_exit $as_status
         2281  +} # as_fn_error
         2282  +
         2283  +
         2284  +# as_fn_set_status STATUS
         2285  +# -----------------------
         2286  +# Set $? to STATUS, without forking.
         2287  +as_fn_set_status ()
         2288  +{
         2289  +  return $1
         2290  +} # as_fn_set_status
         2291  +
         2292  +# as_fn_exit STATUS
         2293  +# -----------------
         2294  +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
         2295  +as_fn_exit ()
         2296  +{
         2297  +  set +e
         2298  +  as_fn_set_status $1
         2299  +  exit $1
         2300  +} # as_fn_exit
         2301  +
         2302  +# as_fn_unset VAR
         2303  +# ---------------
         2304  +# Portably unset VAR.
         2305  +as_fn_unset ()
         2306  +{
         2307  +  { eval $1=; unset $1;}
         2308  +}
         2309  +as_unset=as_fn_unset
         2310  +# as_fn_append VAR VALUE
         2311  +# ----------------------
         2312  +# Append the text in VALUE to the end of the definition contained in VAR. Take
         2313  +# advantage of any shell optimizations that allow amortized linear growth over
         2314  +# repeated appends, instead of the typical quadratic growth present in naive
         2315  +# implementations.
         2316  +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
         2317  +  eval 'as_fn_append ()
         2318  +  {
         2319  +    eval $1+=\$2
         2320  +  }'
         2321  +else
         2322  +  as_fn_append ()
         2323  +  {
         2324  +    eval $1=\$$1\$2
         2325  +  }
         2326  +fi # as_fn_append
         2327  +
         2328  +# as_fn_arith ARG...
         2329  +# ------------------
         2330  +# Perform arithmetic evaluation on the ARGs, and store the result in the
         2331  +# global $as_val. Take advantage of shells that can avoid forks. The arguments
         2332  +# must be portable across $(()) and expr.
         2333  +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
         2334  +  eval 'as_fn_arith ()
         2335  +  {
         2336  +    as_val=$(( $* ))
         2337  +  }'
         2338  +else
         2339  +  as_fn_arith ()
         2340  +  {
         2341  +    as_val=`expr "$@" || test $? -eq 1`
         2342  +  }
         2343  +fi # as_fn_arith
         2344  +
         2345  +
         2346  +if expr a : '\(a\)' >/dev/null 2>&1 &&
         2347  +   test "X`expr 00001 : '.*\(...\)'`" = X001; then
         2348  +  as_expr=expr
         2349  +else
         2350  +  as_expr=false
         2351  +fi
         2352  +
         2353  +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
         2354  +  as_basename=basename
         2355  +else
         2356  +  as_basename=false
         2357  +fi
         2358  +
         2359  +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
         2360  +  as_dirname=dirname
         2361  +else
         2362  +  as_dirname=false
         2363  +fi
         2364  +
         2365  +as_me=`$as_basename -- "$0" ||
         2366  +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         2367  +	 X"$0" : 'X\(//\)$' \| \
         2368  +	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
         2369  +$as_echo X/"$0" |
         2370  +    sed '/^.*\/\([^/][^/]*\)\/*$/{
         2371  +	    s//\1/
         2372  +	    q
         2373  +	  }
         2374  +	  /^X\/\(\/\/\)$/{
         2375  +	    s//\1/
         2376  +	    q
         2377  +	  }
         2378  +	  /^X\/\(\/\).*/{
         2379  +	    s//\1/
         2380  +	    q
         2381  +	  }
         2382  +	  s/.*/./; q'`
         2383  +
         2384  +# Avoid depending upon Character Ranges.
         2385  +as_cr_letters='abcdefghijklmnopqrstuvwxyz'
         2386  +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
         2387  +as_cr_Letters=$as_cr_letters$as_cr_LETTERS
         2388  +as_cr_digits='0123456789'
         2389  +as_cr_alnum=$as_cr_Letters$as_cr_digits
         2390  +
         2391  +ECHO_C= ECHO_N= ECHO_T=
         2392  +case `echo -n x` in #(((((
         2393  +-n*)
         2394  +  case `echo 'xy\c'` in
         2395  +  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
         2396  +  xy)  ECHO_C='\c';;
         2397  +  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
         2398  +       ECHO_T='	';;
         2399  +  esac;;
         2400  +*)
         2401  +  ECHO_N='-n';;
         2402  +esac
         2403  +
         2404  +rm -f conf$$ conf$$.exe conf$$.file
         2405  +if test -d conf$$.dir; then
         2406  +  rm -f conf$$.dir/conf$$.file
         2407  +else
         2408  +  rm -f conf$$.dir
         2409  +  mkdir conf$$.dir 2>/dev/null
         2410  +fi
         2411  +if (echo >conf$$.file) 2>/dev/null; then
         2412  +  if ln -s conf$$.file conf$$ 2>/dev/null; then
         2413  +    as_ln_s='ln -s'
         2414  +    # ... but there are two gotchas:
         2415  +    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
         2416  +    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
         2417  +    # In both cases, we have to default to `cp -pR'.
         2418  +    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
         2419  +      as_ln_s='cp -pR'
         2420  +  elif ln conf$$.file conf$$ 2>/dev/null; then
         2421  +    as_ln_s=ln
         2422  +  else
         2423  +    as_ln_s='cp -pR'
         2424  +  fi
         2425  +else
         2426  +  as_ln_s='cp -pR'
         2427  +fi
         2428  +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
         2429  +rmdir conf$$.dir 2>/dev/null
         2430  +
         2431  +
         2432  +# as_fn_mkdir_p
         2433  +# -------------
         2434  +# Create "$as_dir" as a directory, including parents if necessary.
         2435  +as_fn_mkdir_p ()
         2436  +{
         2437  +
         2438  +  case $as_dir in #(
         2439  +  -*) as_dir=./$as_dir;;
         2440  +  esac
         2441  +  test -d "$as_dir" || eval $as_mkdir_p || {
         2442  +    as_dirs=
         2443  +    while :; do
         2444  +      case $as_dir in #(
         2445  +      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
         2446  +      *) as_qdir=$as_dir;;
         2447  +      esac
         2448  +      as_dirs="'$as_qdir' $as_dirs"
         2449  +      as_dir=`$as_dirname -- "$as_dir" ||
         2450  +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         2451  +	 X"$as_dir" : 'X\(//\)[^/]' \| \
         2452  +	 X"$as_dir" : 'X\(//\)$' \| \
         2453  +	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
         2454  +$as_echo X"$as_dir" |
         2455  +    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
         2456  +	    s//\1/
         2457  +	    q
         2458  +	  }
         2459  +	  /^X\(\/\/\)[^/].*/{
         2460  +	    s//\1/
         2461  +	    q
         2462  +	  }
         2463  +	  /^X\(\/\/\)$/{
         2464  +	    s//\1/
         2465  +	    q
         2466  +	  }
         2467  +	  /^X\(\/\).*/{
         2468  +	    s//\1/
         2469  +	    q
         2470  +	  }
         2471  +	  s/.*/./; q'`
         2472  +      test -d "$as_dir" && break
         2473  +    done
         2474  +    test -z "$as_dirs" || eval "mkdir $as_dirs"
         2475  +  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
         2476  +
         2477  +
         2478  +} # as_fn_mkdir_p
         2479  +if mkdir -p . 2>/dev/null; then
         2480  +  as_mkdir_p='mkdir -p "$as_dir"'
         2481  +else
         2482  +  test -d ./-p && rmdir ./-p
         2483  +  as_mkdir_p=false
         2484  +fi
         2485  +
         2486  +
         2487  +# as_fn_executable_p FILE
         2488  +# -----------------------
         2489  +# Test if FILE is an executable regular file.
         2490  +as_fn_executable_p ()
         2491  +{
         2492  +  test -f "$1" && test -x "$1"
         2493  +} # as_fn_executable_p
         2494  +as_test_x='test -x'
         2495  +as_executable_p=as_fn_executable_p
         2496  +
         2497  +# Sed expression to map a string onto a valid CPP name.
         2498  +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
         2499  +
         2500  +# Sed expression to map a string onto a valid variable name.
         2501  +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
         2502  +
         2503  +
         2504  +exec 6>&1
         2505  +## ----------------------------------- ##
         2506  +## Main body of $CONFIG_STATUS script. ##
         2507  +## ----------------------------------- ##
         2508  +_ASEOF
         2509  +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
         2510  +
         2511  +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
         2512  +# Save the log message, to keep $0 and so on meaningful, and to
         2513  +# report actual input values of CONFIG_FILES etc. instead of their
         2514  +# values after options handling.
         2515  +ac_log="
         2516  +This file was extended by $as_me, which was
         2517  +generated by GNU Autoconf 2.69.  Invocation command line was
         2518  +
         2519  +  CONFIG_FILES    = $CONFIG_FILES
         2520  +  CONFIG_HEADERS  = $CONFIG_HEADERS
         2521  +  CONFIG_LINKS    = $CONFIG_LINKS
         2522  +  CONFIG_COMMANDS = $CONFIG_COMMANDS
         2523  +  $ $0 $@
         2524  +
         2525  +on `(hostname || uname -n) 2>/dev/null | sed 1q`
         2526  +"
         2527  +
         2528  +_ACEOF
         2529  +
         2530  +case $ac_config_files in *"
         2531  +"*) set x $ac_config_files; shift; ac_config_files=$*;;
         2532  +esac
         2533  +
         2534  +
         2535  +
         2536  +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
         2537  +# Files that config.status was made for.
         2538  +config_files="$ac_config_files"
         2539  +
         2540  +_ACEOF
         2541  +
         2542  +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
         2543  +ac_cs_usage="\
         2544  +\`$as_me' instantiates files and other configuration actions
         2545  +from templates according to the current configuration.  Unless the files
         2546  +and actions are specified as TAGs, all are instantiated by default.
         2547  +
         2548  +Usage: $0 [OPTION]... [TAG]...
         2549  +
         2550  +  -h, --help       print this help, then exit
         2551  +  -V, --version    print version number and configuration settings, then exit
         2552  +      --config     print configuration, then exit
         2553  +  -q, --quiet, --silent
         2554  +                   do not print progress messages
         2555  +  -d, --debug      don't remove temporary files
         2556  +      --recheck    update $as_me by reconfiguring in the same conditions
         2557  +      --file=FILE[:TEMPLATE]
         2558  +                   instantiate the configuration file FILE
         2559  +
         2560  +Configuration files:
         2561  +$config_files
         2562  +
         2563  +Report bugs to the package provider."
         2564  +
         2565  +_ACEOF
         2566  +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
         2567  +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
         2568  +ac_cs_version="\\
         2569  +config.status
         2570  +configured by $0, generated by GNU Autoconf 2.69,
         2571  +  with options \\"\$ac_cs_config\\"
         2572  +
         2573  +Copyright (C) 2012 Free Software Foundation, Inc.
         2574  +This config.status script is free software; the Free Software Foundation
         2575  +gives unlimited permission to copy, distribute and modify it."
         2576  +
         2577  +ac_pwd='$ac_pwd'
         2578  +srcdir='$srcdir'
         2579  +INSTALL='$INSTALL'
         2580  +test -n "\$AWK" || AWK=awk
         2581  +_ACEOF
         2582  +
         2583  +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
         2584  +# The default lists apply if the user does not specify any file.
         2585  +ac_need_defaults=:
         2586  +while test $# != 0
   882   2587   do
   883         -  case "\$ac_option" in
         2588  +  case $1 in
         2589  +  --*=?*)
         2590  +    ac_option=`expr "X$1" : 'X\([^=]*\)='`
         2591  +    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
         2592  +    ac_shift=:
         2593  +    ;;
         2594  +  --*=)
         2595  +    ac_option=`expr "X$1" : 'X\([^=]*\)='`
         2596  +    ac_optarg=
         2597  +    ac_shift=:
         2598  +    ;;
         2599  +  *)
         2600  +    ac_option=$1
         2601  +    ac_optarg=$2
         2602  +    ac_shift=shift
         2603  +    ;;
         2604  +  esac
         2605  +
         2606  +  case $ac_option in
         2607  +  # Handling of the options.
   884   2608     -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
   885         -    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
   886         -    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
   887         -  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
   888         -    echo "$CONFIG_STATUS generated by autoconf version 2.13"
   889         -    exit 0 ;;
   890         -  -help | --help | --hel | --he | --h)
   891         -    echo "\$ac_cs_usage"; exit 0 ;;
   892         -  *) echo "\$ac_cs_usage"; exit 1 ;;
         2609  +    ac_cs_recheck=: ;;
         2610  +  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
         2611  +    $as_echo "$ac_cs_version"; exit ;;
         2612  +  --config | --confi | --conf | --con | --co | --c )
         2613  +    $as_echo "$ac_cs_config"; exit ;;
         2614  +  --debug | --debu | --deb | --de | --d | -d )
         2615  +    debug=: ;;
         2616  +  --file | --fil | --fi | --f )
         2617  +    $ac_shift
         2618  +    case $ac_optarg in
         2619  +    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
         2620  +    '') as_fn_error $? "missing file argument" ;;
         2621  +    esac
         2622  +    as_fn_append CONFIG_FILES " '$ac_optarg'"
         2623  +    ac_need_defaults=false;;
         2624  +  --he | --h |  --help | --hel | -h )
         2625  +    $as_echo "$ac_cs_usage"; exit ;;
         2626  +  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
         2627  +  | -silent | --silent | --silen | --sile | --sil | --si | --s)
         2628  +    ac_cs_silent=: ;;
         2629  +
         2630  +  # This is an error.
         2631  +  -*) as_fn_error $? "unrecognized option: \`$1'
         2632  +Try \`$0 --help' for more information." ;;
         2633  +
         2634  +  *) as_fn_append ac_config_targets " $1"
         2635  +     ac_need_defaults=false ;;
         2636  +
         2637  +  esac
         2638  +  shift
         2639  +done
         2640  +
         2641  +ac_configure_extra_args=
         2642  +
         2643  +if $ac_cs_silent; then
         2644  +  exec 6>/dev/null
         2645  +  ac_configure_extra_args="$ac_configure_extra_args --silent"
         2646  +fi
         2647  +
         2648  +_ACEOF
         2649  +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
         2650  +if \$ac_cs_recheck; then
         2651  +  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
         2652  +  shift
         2653  +  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
         2654  +  CONFIG_SHELL='$SHELL'
         2655  +  export CONFIG_SHELL
         2656  +  exec "\$@"
         2657  +fi
         2658  +
         2659  +_ACEOF
         2660  +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
         2661  +exec 5>>config.log
         2662  +{
         2663  +  echo
         2664  +  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
         2665  +## Running $as_me. ##
         2666  +_ASBOX
         2667  +  $as_echo "$ac_log"
         2668  +} >&5
         2669  +
         2670  +_ACEOF
         2671  +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
         2672  +_ACEOF
         2673  +
         2674  +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
         2675  +
         2676  +# Handling of arguments.
         2677  +for ac_config_target in $ac_config_targets
         2678  +do
         2679  +  case $ac_config_target in
         2680  +    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
         2681  +    "pkgIndex.tcl") CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;;
         2682  +
         2683  +  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   893   2684     esac
   894   2685   done
   895   2686   
   896         -ac_given_srcdir=$srcdir
   897         -ac_given_INSTALL="$INSTALL"
   898         -
   899         -trap 'rm -fr `echo "Makefile pkgIndex.tcl" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
   900         -EOF
   901         -cat >> $CONFIG_STATUS <<EOF
   902         -
   903         -# Protect against being on the right side of a sed subst in config.status.
   904         -sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
   905         - s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
   906         -$ac_vpsub
   907         -$extrasub
   908         -s%@SHELL@%$SHELL%g
   909         -s%@CFLAGS@%$CFLAGS%g
   910         -s%@CPPFLAGS@%$CPPFLAGS%g
   911         -s%@CXXFLAGS@%$CXXFLAGS%g
   912         -s%@FFLAGS@%$FFLAGS%g
   913         -s%@DEFS@%$DEFS%g
   914         -s%@LDFLAGS@%$LDFLAGS%g
   915         -s%@LIBS@%$LIBS%g
   916         -s%@exec_prefix@%$exec_prefix%g
   917         -s%@prefix@%$prefix%g
   918         -s%@program_transform_name@%$program_transform_name%g
   919         -s%@bindir@%$bindir%g
   920         -s%@sbindir@%$sbindir%g
   921         -s%@libexecdir@%$libexecdir%g
   922         -s%@datadir@%$datadir%g
   923         -s%@sysconfdir@%$sysconfdir%g
   924         -s%@sharedstatedir@%$sharedstatedir%g
   925         -s%@localstatedir@%$localstatedir%g
   926         -s%@libdir@%$libdir%g
   927         -s%@includedir@%$includedir%g
   928         -s%@oldincludedir@%$oldincludedir%g
   929         -s%@infodir@%$infodir%g
   930         -s%@mandir@%$mandir%g
   931         -s%@CONFIGDIR@%$CONFIGDIR%g
   932         -s%@PACKAGE@%$PACKAGE%g
   933         -s%@VERSION@%$VERSION%g
   934         -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
   935         -s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
   936         -s%@INSTALL_DATA@%$INSTALL_DATA%g
   937         -s%@CLEANFILES@%$CLEANFILES%g
   938         -s%@EXTRA_SOURCES@%$EXTRA_SOURCES%g
   939         -
   940         -CEOF
   941         -EOF
   942         -
   943         -cat >> $CONFIG_STATUS <<\EOF
   944         -
   945         -# Split the substitutions into bite-sized pieces for seds with
   946         -# small command number limits, like on Digital OSF/1 and HP-UX.
   947         -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
   948         -ac_file=1 # Number of current file.
   949         -ac_beg=1 # First line for current file.
   950         -ac_end=$ac_max_sed_cmds # Line after last line for current file.
   951         -ac_more_lines=:
   952         -ac_sed_cmds=""
   953         -while $ac_more_lines; do
   954         -  if test $ac_beg -gt 1; then
   955         -    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
         2687  +
         2688  +# If the user did not use the arguments to specify the items to instantiate,
         2689  +# then the envvar interface is used.  Set only those that are not.
         2690  +# We use the long form for the default assignment because of an extremely
         2691  +# bizarre bug on SunOS 4.1.3.
         2692  +if $ac_need_defaults; then
         2693  +  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
         2694  +fi
         2695  +
         2696  +# Have a temporary directory for convenience.  Make it in the build tree
         2697  +# simply because there is no reason against having it here, and in addition,
         2698  +# creating and moving files from /tmp can sometimes cause problems.
         2699  +# Hook for its removal unless debugging.
         2700  +# Note that there is a small window in which the directory will not be cleaned:
         2701  +# after its creation but before its name has been assigned to `$tmp'.
         2702  +$debug ||
         2703  +{
         2704  +  tmp= ac_tmp=
         2705  +  trap 'exit_status=$?
         2706  +  : "${ac_tmp:=$tmp}"
         2707  +  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
         2708  +' 0
         2709  +  trap 'as_fn_exit 1' 1 2 13 15
         2710  +}
         2711  +# Create a (secure) tmp directory for tmp files.
         2712  +
         2713  +{
         2714  +  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
         2715  +  test -d "$tmp"
         2716  +}  ||
         2717  +{
         2718  +  tmp=./conf$$-$RANDOM
         2719  +  (umask 077 && mkdir "$tmp")
         2720  +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
         2721  +ac_tmp=$tmp
         2722  +
         2723  +# Set up the scripts for CONFIG_FILES section.
         2724  +# No need to generate them if there are no CONFIG_FILES.
         2725  +# This happens for instance with `./config.status config.h'.
         2726  +if test -n "$CONFIG_FILES"; then
         2727  +
         2728  +
         2729  +ac_cr=`echo X | tr X '\015'`
         2730  +# On cygwin, bash can eat \r inside `` if the user requested igncr.
         2731  +# But we know of no other shell where ac_cr would be empty at this
         2732  +# point, so we can use a bashism as a fallback.
         2733  +if test "x$ac_cr" = x; then
         2734  +  eval ac_cr=\$\'\\r\'
         2735  +fi
         2736  +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
         2737  +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
         2738  +  ac_cs_awk_cr='\\r'
         2739  +else
         2740  +  ac_cs_awk_cr=$ac_cr
         2741  +fi
         2742  +
         2743  +echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
         2744  +_ACEOF
         2745  +
         2746  +
         2747  +{
         2748  +  echo "cat >conf$$subs.awk <<_ACEOF" &&
         2749  +  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
         2750  +  echo "_ACEOF"
         2751  +} >conf$$subs.sh ||
         2752  +  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
         2753  +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
         2754  +ac_delim='%!_!# '
         2755  +for ac_last_try in false false false false false :; do
         2756  +  . ./conf$$subs.sh ||
         2757  +    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
         2758  +
         2759  +  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
         2760  +  if test $ac_delim_n = $ac_delim_num; then
         2761  +    break
         2762  +  elif $ac_last_try; then
         2763  +    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
   956   2764     else
   957         -    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
   958         -  fi
   959         -  if test ! -s conftest.s$ac_file; then
   960         -    ac_more_lines=false
   961         -    rm -f conftest.s$ac_file
   962         -  else
   963         -    if test -z "$ac_sed_cmds"; then
   964         -      ac_sed_cmds="sed -f conftest.s$ac_file"
   965         -    else
   966         -      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
   967         -    fi
   968         -    ac_file=`expr $ac_file + 1`
   969         -    ac_beg=$ac_end
   970         -    ac_end=`expr $ac_end + $ac_max_sed_cmds`
         2765  +    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   971   2766     fi
   972   2767   done
   973         -if test -z "$ac_sed_cmds"; then
   974         -  ac_sed_cmds=cat
         2768  +rm -f conf$$subs.sh
         2769  +
         2770  +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
         2771  +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
         2772  +_ACEOF
         2773  +sed -n '
         2774  +h
         2775  +s/^/S["/; s/!.*/"]=/
         2776  +p
         2777  +g
         2778  +s/^[^!]*!//
         2779  +:repl
         2780  +t repl
         2781  +s/'"$ac_delim"'$//
         2782  +t delim
         2783  +:nl
         2784  +h
         2785  +s/\(.\{148\}\)..*/\1/
         2786  +t more1
         2787  +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
         2788  +p
         2789  +n
         2790  +b repl
         2791  +:more1
         2792  +s/["\\]/\\&/g; s/^/"/; s/$/"\\/
         2793  +p
         2794  +g
         2795  +s/.\{148\}//
         2796  +t nl
         2797  +:delim
         2798  +h
         2799  +s/\(.\{148\}\)..*/\1/
         2800  +t more2
         2801  +s/["\\]/\\&/g; s/^/"/; s/$/"/
         2802  +p
         2803  +b
         2804  +:more2
         2805  +s/["\\]/\\&/g; s/^/"/; s/$/"\\/
         2806  +p
         2807  +g
         2808  +s/.\{148\}//
         2809  +t delim
         2810  +' <conf$$subs.awk | sed '
         2811  +/^[^""]/{
         2812  +  N
         2813  +  s/\n//
         2814  +}
         2815  +' >>$CONFIG_STATUS || ac_write_fail=1
         2816  +rm -f conf$$subs.awk
         2817  +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
         2818  +_ACAWK
         2819  +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
         2820  +  for (key in S) S_is_set[key] = 1
         2821  +  FS = ""
         2822  +
         2823  +}
         2824  +{
         2825  +  line = $ 0
         2826  +  nfields = split(line, field, "@")
         2827  +  substed = 0
         2828  +  len = length(field[1])
         2829  +  for (i = 2; i < nfields; i++) {
         2830  +    key = field[i]
         2831  +    keylen = length(key)
         2832  +    if (S_is_set[key]) {
         2833  +      value = S[key]
         2834  +      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
         2835  +      len += length(value) + length(field[++i])
         2836  +      substed = 1
         2837  +    } else
         2838  +      len += 1 + keylen
         2839  +  }
         2840  +
         2841  +  print line
         2842  +}
         2843  +
         2844  +_ACAWK
         2845  +_ACEOF
         2846  +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
         2847  +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
         2848  +  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
         2849  +else
         2850  +  cat
         2851  +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
         2852  +  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
         2853  +_ACEOF
         2854  +
         2855  +# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
         2856  +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
         2857  +# trailing colons and then remove the whole line if VPATH becomes empty
         2858  +# (actually we leave an empty line to preserve line numbers).
         2859  +if test "x$srcdir" = x.; then
         2860  +  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
         2861  +h
         2862  +s///
         2863  +s/^/:/
         2864  +s/[	 ]*$/:/
         2865  +s/:\$(srcdir):/:/g
         2866  +s/:\${srcdir}:/:/g
         2867  +s/:@srcdir@:/:/g
         2868  +s/^:*//
         2869  +s/:*$//
         2870  +x
         2871  +s/\(=[	 ]*\).*/\1/
         2872  +G
         2873  +s/\n//
         2874  +s/^[^=]*=[	 ]*$//
         2875  +}'
   975   2876   fi
   976         -EOF
   977         -
   978         -cat >> $CONFIG_STATUS <<EOF
   979         -
   980         -CONFIG_FILES=\${CONFIG_FILES-"Makefile pkgIndex.tcl"}
   981         -EOF
   982         -cat >> $CONFIG_STATUS <<\EOF
   983         -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
   984         -  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
   985         -  case "$ac_file" in
   986         -  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
   987         -       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
   988         -  *) ac_file_in="${ac_file}.in" ;;
         2877  +
         2878  +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
         2879  +fi # test -n "$CONFIG_FILES"
         2880  +
         2881  +
         2882  +eval set X "  :F $CONFIG_FILES      "
         2883  +shift
         2884  +for ac_tag
         2885  +do
         2886  +  case $ac_tag in
         2887  +  :[FHLC]) ac_mode=$ac_tag; continue;;
         2888  +  esac
         2889  +  case $ac_mode$ac_tag in
         2890  +  :[FHL]*:*);;
         2891  +  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
         2892  +  :[FH]-) ac_tag=-:-;;
         2893  +  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
         2894  +  esac
         2895  +  ac_save_IFS=$IFS
         2896  +  IFS=:
         2897  +  set x $ac_tag
         2898  +  IFS=$ac_save_IFS
         2899  +  shift
         2900  +  ac_file=$1
         2901  +  shift
         2902  +
         2903  +  case $ac_mode in
         2904  +  :L) ac_source=$1;;
         2905  +  :[FH])
         2906  +    ac_file_inputs=
         2907  +    for ac_f
         2908  +    do
         2909  +      case $ac_f in
         2910  +      -) ac_f="$ac_tmp/stdin";;
         2911  +      *) # Look for the file first in the build tree, then in the source tree
         2912  +	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
         2913  +	 # because $ac_f cannot contain `:'.
         2914  +	 test -f "$ac_f" ||
         2915  +	   case $ac_f in
         2916  +	   [\\/$]*) false;;
         2917  +	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
         2918  +	   esac ||
         2919  +	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
         2920  +      esac
         2921  +      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
         2922  +      as_fn_append ac_file_inputs " '$ac_f'"
         2923  +    done
         2924  +
         2925  +    # Let's still pretend it is `configure' which instantiates (i.e., don't
         2926  +    # use $as_me), people would be surprised to read:
         2927  +    #    /* config.h.  Generated by config.status.  */
         2928  +    configure_input='Generated from '`
         2929  +	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
         2930  +	`' by configure.'
         2931  +    if test x"$ac_file" != x-; then
         2932  +      configure_input="$ac_file.  $configure_input"
         2933  +      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
         2934  +$as_echo "$as_me: creating $ac_file" >&6;}
         2935  +    fi
         2936  +    # Neutralize special characters interpreted by sed in replacement strings.
         2937  +    case $configure_input in #(
         2938  +    *\&* | *\|* | *\\* )
         2939  +       ac_sed_conf_input=`$as_echo "$configure_input" |
         2940  +       sed 's/[\\\\&|]/\\\\&/g'`;; #(
         2941  +    *) ac_sed_conf_input=$configure_input;;
         2942  +    esac
         2943  +
         2944  +    case $ac_tag in
         2945  +    *:-:* | *:-) cat >"$ac_tmp/stdin" \
         2946  +      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
         2947  +    esac
         2948  +    ;;
         2949  +  esac
         2950  +
         2951  +  ac_dir=`$as_dirname -- "$ac_file" ||
         2952  +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         2953  +	 X"$ac_file" : 'X\(//\)[^/]' \| \
         2954  +	 X"$ac_file" : 'X\(//\)$' \| \
         2955  +	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
         2956  +$as_echo X"$ac_file" |
         2957  +    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
         2958  +	    s//\1/
         2959  +	    q
         2960  +	  }
         2961  +	  /^X\(\/\/\)[^/].*/{
         2962  +	    s//\1/
         2963  +	    q
         2964  +	  }
         2965  +	  /^X\(\/\/\)$/{
         2966  +	    s//\1/
         2967  +	    q
         2968  +	  }
         2969  +	  /^X\(\/\).*/{
         2970  +	    s//\1/
         2971  +	    q
         2972  +	  }
         2973  +	  s/.*/./; q'`
         2974  +  as_dir="$ac_dir"; as_fn_mkdir_p
         2975  +  ac_builddir=.
         2976  +
         2977  +case "$ac_dir" in
         2978  +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
         2979  +*)
         2980  +  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
         2981  +  # A ".." for each directory in $ac_dir_suffix.
         2982  +  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
         2983  +  case $ac_top_builddir_sub in
         2984  +  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
         2985  +  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
         2986  +  esac ;;
         2987  +esac
         2988  +ac_abs_top_builddir=$ac_pwd
         2989  +ac_abs_builddir=$ac_pwd$ac_dir_suffix
         2990  +# for backward compatibility:
         2991  +ac_top_builddir=$ac_top_build_prefix
         2992  +
         2993  +case $srcdir in
         2994  +  .)  # We are building in place.
         2995  +    ac_srcdir=.
         2996  +    ac_top_srcdir=$ac_top_builddir_sub
         2997  +    ac_abs_top_srcdir=$ac_pwd ;;
         2998  +  [\\/]* | ?:[\\/]* )  # Absolute name.
         2999  +    ac_srcdir=$srcdir$ac_dir_suffix;
         3000  +    ac_top_srcdir=$srcdir
         3001  +    ac_abs_top_srcdir=$srcdir ;;
         3002  +  *) # Relative name.
         3003  +    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
         3004  +    ac_top_srcdir=$ac_top_build_prefix$srcdir
         3005  +    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
         3006  +esac
         3007  +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
         3008  +
         3009  +
         3010  +  case $ac_mode in
         3011  +  :F)
         3012  +  #
         3013  +  # CONFIG_FILE
         3014  +  #
         3015  +
         3016  +  case $INSTALL in
         3017  +  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
         3018  +  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
   989   3019     esac
         3020  +_ACEOF
         3021  +
         3022  +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
         3023  +# If the template does not know about datarootdir, expand it.
         3024  +# FIXME: This hack should be removed a few years after 2.60.
         3025  +ac_datarootdir_hack=; ac_datarootdir_seen=
         3026  +ac_sed_dataroot='
         3027  +/datarootdir/ {
         3028  +  p
         3029  +  q
         3030  +}
         3031  +/@datadir@/p
         3032  +/@docdir@/p
         3033  +/@infodir@/p
         3034  +/@localedir@/p
         3035  +/@mandir@/p'
         3036  +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
         3037  +*datarootdir*) ac_datarootdir_seen=yes;;
         3038  +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
         3039  +  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
         3040  +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
         3041  +_ACEOF
         3042  +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
         3043  +  ac_datarootdir_hack='
         3044  +  s&@datadir@&$datadir&g
         3045  +  s&@docdir@&$docdir&g
         3046  +  s&@infodir@&$infodir&g
         3047  +  s&@localedir@&$localedir&g
         3048  +  s&@mandir@&$mandir&g
         3049  +  s&\\\${datarootdir}&$datarootdir&g' ;;
         3050  +esac
         3051  +_ACEOF
         3052  +
         3053  +# Neutralize VPATH when `$srcdir' = `.'.
         3054  +# Shell code in configure.ac might set extrasub.
         3055  +# FIXME: do we really want to maintain this feature?
         3056  +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
         3057  +ac_sed_extra="$ac_vpsub
         3058  +$extrasub
         3059  +_ACEOF
         3060  +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
         3061  +:t
         3062  +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
         3063  +s|@configure_input@|$ac_sed_conf_input|;t t
         3064  +s&@top_builddir@&$ac_top_builddir_sub&;t t
         3065  +s&@top_build_prefix@&$ac_top_build_prefix&;t t
         3066  +s&@srcdir@&$ac_srcdir&;t t
         3067  +s&@abs_srcdir@&$ac_abs_srcdir&;t t
         3068  +s&@top_srcdir@&$ac_top_srcdir&;t t
         3069  +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
         3070  +s&@builddir@&$ac_builddir&;t t
         3071  +s&@abs_builddir@&$ac_abs_builddir&;t t
         3072  +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
         3073  +s&@INSTALL@&$ac_INSTALL&;t t
         3074  +$ac_datarootdir_hack
         3075  +"
         3076  +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
         3077  +  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
   990   3078   
   991         -  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
         3079  +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
         3080  +  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
         3081  +  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
         3082  +      "$ac_tmp/out"`; test -z "$ac_out"; } &&
         3083  +  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
         3084  +which seems to be undefined.  Please make sure it is defined" >&5
         3085  +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
         3086  +which seems to be undefined.  Please make sure it is defined" >&2;}
   992   3087   
   993         -  # Remove last slash and all that follows it.  Not all systems have dirname.
   994         -  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
   995         -  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
   996         -    # The file is in a subdirectory.
   997         -    test ! -d "$ac_dir" && mkdir "$ac_dir"
   998         -    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
   999         -    # A "../" for each directory in $ac_dir_suffix.
  1000         -    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
  1001         -  else
  1002         -    ac_dir_suffix= ac_dots=
  1003         -  fi
         3088  +  rm -f "$ac_tmp/stdin"
         3089  +  case $ac_file in
         3090  +  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
         3091  +  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
         3092  +  esac \
         3093  +  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
         3094  + ;;
         3095  +
  1004   3096   
  1005         -  case "$ac_given_srcdir" in
  1006         -  .)  srcdir=.
  1007         -      if test -z "$ac_dots"; then top_srcdir=.
  1008         -      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
  1009         -  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
  1010         -  *) # Relative path.
  1011         -    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
  1012         -    top_srcdir="$ac_dots$ac_given_srcdir" ;;
         3097  +
  1013   3098     esac
  1014   3099   
  1015         -  case "$ac_given_INSTALL" in
  1016         -  [/$]*) INSTALL="$ac_given_INSTALL" ;;
  1017         -  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
  1018         -  esac
         3100  +done # for ac_tag
         3101  +
         3102  +
         3103  +as_fn_exit 0
         3104  +_ACEOF
         3105  +ac_clean_files=$ac_clean_files_save
  1019   3106   
  1020         -  echo creating "$ac_file"
  1021         -  rm -f "$ac_file"
  1022         -  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
  1023         -  case "$ac_file" in
  1024         -  *Makefile*) ac_comsub="1i\\
  1025         -# $configure_input" ;;
  1026         -  *) ac_comsub= ;;
  1027         -  esac
         3107  +test $ac_write_fail = 0 ||
         3108  +  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
         3109  +
  1028   3110   
  1029         -  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
  1030         -  sed -e "$ac_comsub
  1031         -s%@configure_input@%$configure_input%g
  1032         -s%@srcdir@%$srcdir%g
  1033         -s%@top_srcdir@%$top_srcdir%g
  1034         -s%@INSTALL@%$INSTALL%g
  1035         -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
  1036         -fi; done
  1037         -rm -f conftest.s*
  1038         -
  1039         -EOF
  1040         -cat >> $CONFIG_STATUS <<EOF
  1041         -
  1042         -EOF
  1043         -cat >> $CONFIG_STATUS <<\EOF
  1044         -
  1045         -exit 0
  1046         -EOF
  1047         -chmod +x $CONFIG_STATUS
  1048         -rm -fr confdefs* $ac_clean_files
  1049         -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
         3111  +# configure is writing to config.log, and then calls config.status.
         3112  +# config.status does its own redirection, appending to config.log.
         3113  +# Unfortunately, on DOS this fails, as config.log is still kept open
         3114  +# by configure, so config.status won't be able to write to it; its
         3115  +# output is simply discarded.  So we exec the FD to /dev/null,
         3116  +# effectively closing config.log, so it can be properly (re)opened and
         3117  +# appended to by config.status.  When coming back to configure, we
         3118  +# need to make the FD available again.
         3119  +if test "$no_create" != yes; then
         3120  +  ac_cs_success=:
         3121  +  ac_config_status_args=
         3122  +  test "$silent" = yes &&
         3123  +    ac_config_status_args="$ac_config_status_args --quiet"
         3124  +  exec 5>/dev/null
         3125  +  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
         3126  +  exec 5>>config.log
         3127  +  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
         3128  +  # would make configure fail if this is the last instruction.
         3129  +  $ac_cs_success || as_fn_exit 1
         3130  +fi
         3131  +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
         3132  +  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
         3133  +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
         3134  +fi
  1050   3135   

Changes to extensions/tdomhtml/configure.in.

     1      1   #!/bin/bash -norc
     2      2   dnl	This file is an input file used by the GNU "autoconf" program to
     3      3   dnl	generate the file "configure", which is run during Tcl installation
     4      4   dnl	to configure the system for the local environment.
     5         -#
     6         -# RCS: @(#) $Id$
     7      5   
     8      6   #-----------------------------------------------------------------------
     9      7   # Sample configure.in for Tcl Extensions.  The only places you should
    10      8   # need to modify this file are marked by the string __CHANGE__
    11      9   #-----------------------------------------------------------------------
    12     10   
    13     11   #-----------------------------------------------------------------------

Changes to extensions/tdomhtml/tdomhtml.tcl.

   170    170       }
   171    171   
   172    172       foreach nodecmd $elementNodeCmd {
   173    173           dom createNodeCmd elementNode $nodecmd
   174    174       }
   175    175   
   176    176       #
   177         -    # Miscelaneous commands. Not part of HTML specs but needed 
          177  +    # Miscellaneous commands. Not part of HTML specs but needed 
   178    178       # for generation of special DOM nodes.
   179    179       #
   180    180   
   181    181       variable textNodeCmd t
   182    182       dom createNodeCmd textNode $textNodeCmd
   183    183   
   184    184       variable commentNodeCmd c

Added extensions/tdomhtml/win/makefile.vc.

            1  +# Simple makefile for pure Tcl package
            2  +
            3  +PROJECT    = tdomhtml
            4  +DOTVERSION = 0.1.0
            5  +VERSION    = $(DOTVERSION:.=)
            6  +
            7  +CPY	= echo y | xcopy /i >NUL
            8  +
            9  +!ifndef INSTALLDIR
           10  +### Assume the normal default.
           11  +_INSTALLDIR	= C:\Program Files\Tcl\lib
           12  +!else
           13  +### Fix the path separators.
           14  +_INSTALLDIR	= $(INSTALLDIR:/=\)\lib
           15  +!endif
           16  +
           17  +
           18  +PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
           19  +DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
           20  +SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
           21  +
           22  +all:
           23  +	@echo This is a pure Tcl package. Just run 'make /f makefile.vc install INSTALLDIR=path\to\tcl\root'
           24  +
           25  +install: install-libraries
           26  +
           27  +install-libraries:
           28  +	@if not exist $(SCRIPT_INSTALL_DIR)\nul mkdir $(SCRIPT_INSTALL_DIR)
           29  +	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
           30  +        $(CPY) ..\tdomhtml.tcl "$(SCRIPT_INSTALL_DIR)" >NUL
           31  +        @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
           32  +        @type << >"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
           33  +    package ifneeded tdomhtml $(DOTVERSION) "set _V_ $(DOTVERSION); source [list [file join $$dir tdomhtml.tcl]]"
           34  +<<
           35  +
           36  +install-docs:
           37  +#	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
           38  +#	@if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"

Changes to extensions/tnc/Makefile.in.

     7      7   #	replaced in the actual Makefile.
     8      8   #
     9      9   # Copyright (c) 1999 Scriptics Corporation.
    10     10   # Copyright (c) 2002-2005 ActiveState Corporation.
    11     11   #
    12     12   # See the file "license.terms" for information on usage and redistribution
    13     13   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    14         -#
    15         -# RCS: @(#) $Id$
    16     14   
    17     15   #========================================================================
    18     16   # Add additional lines to handle any additional AC_SUBST cases that
    19     17   # have been added in a customized configure script.
    20     18   #========================================================================
    21     19   
    22     20   #SAMPLE_NEW_VAR	= @SAMPLE_NEW_VAR@
................................................................................
    69     67   
    70     68   srcdir		= @srcdir@
    71     69   prefix		= @prefix@
    72     70   exec_prefix	= @exec_prefix@
    73     71   
    74     72   bindir		= @bindir@
    75     73   libdir		= @libdir@
           74  +includedir	= @includedir@
           75  +datarootdir	= @datarootdir@
    76     76   datadir		= @datadir@
    77     77   mandir		= @mandir@
    78         -includedir	= @includedir@
    79     78   
    80     79   DESTDIR		=
    81     80   
    82     81   PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
    83     82   pkgdatadir	= $(datadir)/$(PKG_DIR)
    84     83   pkglibdir	= $(libdir)/$(PKG_DIR)
    85     84   pkgincludedir	= $(includedir)/$(PKG_DIR)
    86     85   
    87     86   top_builddir	= .
    88     87   
    89         -INSTALL		= @INSTALL@
    90         -INSTALL_PROGRAM	= @INSTALL_PROGRAM@
    91         -INSTALL_DATA	= @INSTALL_DATA@
    92         -INSTALL_SCRIPT	= @INSTALL_SCRIPT@
           88  +INSTALL_OPTIONS =
           89  +INSTALL		= $(SHELL) $(srcdir)/../../tclconfig/install-sh -c ${INSTALL_OPTIONS}
           90  +INSTALL_DATA_DIR = ${INSTALL} -d -m 755
           91  +INSTALL_PROGRAM	= ${INSTALL} -m 555
           92  +INSTALL_DATA	= ${INSTALL} -m 444
           93  +INSTALL_SCRIPT	= ${INSTALL_PROGRAM}
           94  +INSTALL_LIBRARY	= ${INSTALL_DATA}
    93     95   
    94     96   PACKAGE_NAME	= @PACKAGE_NAME@
    95     97   PACKAGE_VERSION	= @PACKAGE_VERSION@
    96     98   CC		= @CC@
    97     99   CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
    98    100   CFLAGS_WARNING	= @CFLAGS_WARNING@
    99         -CLEANFILES	= @CLEANFILES@
   100    101   EXEEXT		= @EXEEXT@
   101    102   LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
   102    103   MAKE_LIB	= @MAKE_LIB@
   103    104   MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
   104    105   MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
   105    106   MAKE_STUB_LIB	= @MAKE_STUB_LIB@
   106    107   OBJEXT		= @OBJEXT@
................................................................................
   125    126   # to test against an uninstalled Tcl.  Add special env vars that you
   126    127   # require for testing here (like TCLX_LIBRARY).
   127    128   #========================================================================
   128    129   
   129    130   EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
   130    131   #EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
   131    132   TCLLIBPATH	= $(top_builddir)
   132         -TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
   133         -		  @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
          133  +TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
          134  +PKG_ENV		= @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
   134    135   		  PATH="$(EXTRA_PATH):$(PATH)" \
   135    136   		  TCLLIBPATH="$(TCLLIBPATH)"
   136         -#		  TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
   137    137   
   138    138   TCLSH_PROG	= @TCLSH_PROG@
   139         -TCLSH   	= $(TCLSH_ENV) $(TCLSH_PROG)
          139  +TCLSH		= $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
   140    140   
          141  +#WISH_ENV	= TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
   141    142   #WISH_PROG	= @WISH_PROG@
   142         -#WISH   	= $(TCLSH_ENV) $(WISH_PROG)
   143         -
          143  +#WISH		= $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
   144    144   
   145    145   SHARED_BUILD	= @SHARED_BUILD@
   146    146   
   147    147   INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
   148    148   #INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
   149    149   
   150    150   PKG_CFLAGS	= @PKG_CFLAGS@
................................................................................
   153    153   # must make sure that configure.in checks for the necessary components
   154    154   # that your library may use.  TCL_DEFS can actually be a problem if
   155    155   # you do not compile with a similar machine setup as the Tcl core was
   156    156   # compiled with.
   157    157   #DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
   158    158   DEFS		= @DEFS@ $(PKG_CFLAGS)
   159    159   
   160         -CONFIG_CLEAN_FILES = Makefile
          160  +# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
          161  +CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
          162  +CLEANFILES	= @CLEANFILES@
   161    163   
   162    164   CPPFLAGS	= @CPPFLAGS@
   163    165   LIBS		= @PKG_LIBS@ @LIBS@
   164    166   AR		= @AR@
   165    167   CFLAGS		= @CFLAGS@
   166    168   COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
          169  +
          170  +.SUFFIXES: .c .$(OBJEXT)
   167    171   
   168    172   #========================================================================
   169    173   # Start of user-definable TARGETS section
   170    174   #========================================================================
   171    175   
   172    176   #========================================================================
   173    177   # TEA TARGETS.  Please note that the "libraries:" target refers to platform
   174         -# independent files, and the "binaries:" target inclues executable programs and
          178  +# independent files, and the "binaries:" target includes executable programs and
   175    179   # platform-dependent libraries.  Modify these targets so that they install
   176    180   # the various pieces of your package.  The make and install rules
   177    181   # for the BINARIES that you specified above have already been done.
   178    182   #========================================================================
   179    183   
   180         -all: binaries libraries doc
          184  +all: binaries libraries
   181    185   
   182    186   #========================================================================
   183    187   # The binaries target builds executable programs, Windows .dll's, unix
   184    188   # shared/static libraries, and any other platform-dependent files.
   185    189   # The list of targets to build for "binaries:" is specified at the top
   186    190   # of the Makefile, in the "BINARIES" variable.
   187    191   #========================================================================
   188    192   
   189         -binaries: $(BINARIES)
          193  +binaries: $(BINARIES) pkgIndex.tcl-hand
   190    194   
   191    195   libraries:
   192         -
   193    196   
   194    197   #========================================================================
   195    198   # Your doc target should differentiate from doc builds (by the developer)
   196    199   # and doc installs (see install-doc), which just install the docs on the
   197    200   # end user machine when building from source.
   198    201   #========================================================================
   199    202   
................................................................................
   205    208   
   206    209   #========================================================================
   207    210   # This rule installs platform-independent files, such as header files.
   208    211   # The list=...; for p in $$list handles the empty list case x-platform.
   209    212   #========================================================================
   210    213   
   211    214   install-libraries: libraries
   212         -	@mkdir -p $(DESTDIR)$(includedir)
   213         -	@echo "Installing header files in $(DESTDIR)$(includedir)"
   214         -	@list='$(PKG_HEADERS)'; for i in $$list; do \
   215         -	    echo "Installing $(srcdir)/$$i" ; \
   216         -	    $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
   217         -	done;
          215  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir)
   218    216   
   219    217   #========================================================================
   220    218   # Install documentation.  Unix manpages should go in the $(mandir)
   221    219   # directory.
   222    220   #========================================================================
   223    221   
   224    222   install-doc: doc
   225         -	@mkdir -p $(DESTDIR)$(mandir)/mann
          223  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
   226    224   	@echo "Installing documentation in $(DESTDIR)$(mandir)"
   227    225   	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
   228    226   	    echo "Installing $$i"; \
   229         -	    rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
   230    227   	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
   231    228   	done
   232    229   
   233    230   test: binaries libraries
   234    231   	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
   235    232   
   236    233   shell: binaries libraries
   237    234   	@$(TCLSH) $(SCRIPT)
   238    235   
   239    236   gdb:
   240    237   	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
          238  +
          239  +VALGRINDARGS =	--tool=memcheck --num-callers=8 --leak-resolution=high \
          240  +		--leak-check=yes --show-reachable=yes -v
          241  +
          242  +valgrind: binaries libraries
          243  +	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
          244  +		`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
          245  +
          246  +valgrindshell: binaries libraries
          247  +	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
   241    248   
   242    249   depend:
   243    250   
   244    251   #========================================================================
   245    252   # $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
   246    253   # mentioned above.  That will ensure that this target is built when you
   247    254   # run "make binaries".
................................................................................
   272    279   # 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
   273    280   #
   274    281   # Setting the VPATH variable to a list of paths will cause the makefile
   275    282   # to look into these paths when resolving .c to .obj dependencies.
   276    283   # As necessary, add $(srcdir):$(srcdir)/compat:....
   277    284   #========================================================================
   278    285   
   279         -VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win
          286  +VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx
   280    287   
   281    288   .c.@OBJEXT@:
   282    289   	$(COMPILE) -c `@CYGPATH@ $<` -o $@
          290  +
          291  +#========================================================================
          292  +# Create the pkgIndex.tcl file.
          293  +#========================================================================
          294  +
          295  +pkgIndex.tcl-hand:
          296  +	@(echo 'package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
          297  +	"package require tdom;\
          298  +	 load [list [file join $$dir $(PKG_LIB_FILE)]];"'\
          299  +	) > pkgIndex.tcl
   283    300   
   284    301   #========================================================================
   285    302   # Distribution creation
   286    303   # You may need to tweak this target to make it work correctly.
   287    304   #========================================================================
   288    305   
   289    306   #COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
   290         -COMPRESS	= gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
          307  +COMPRESS	= tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
   291    308   DIST_ROOT	= /tmp/dist
   292    309   DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)
   293    310   
   294    311   dist-clean:
   295    312   	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
   296    313   
   297    314   dist: dist-clean
................................................................................
   329    346   #========================================================================
   330    347   
   331    348   #========================================================================
   332    349   # Don't modify the file to clean here.  Instead, set the "CLEANFILES"
   333    350   # variable in configure.in
   334    351   #========================================================================
   335    352   
   336         -clean:  
          353  +clean:
   337    354   	-test -z "$(BINARIES)" || rm -f $(BINARIES)
   338    355   	-rm -f *.$(OBJEXT) core *.core
   339    356   	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
   340    357   
   341    358   distclean: clean
   342    359   	-rm -f *.tab.c
   343    360   	-rm -f $(CONFIG_CLEAN_FILES)
................................................................................
   351    368   # In addition, this will generate the pkgIndex.tcl
   352    369   # file in the install location (assuming it can find a usable tclsh shell)
   353    370   #
   354    371   # You should not have to modify this target.
   355    372   #========================================================================
   356    373   
   357    374   install-lib-binaries: binaries
   358         -	@mkdir -p $(DESTDIR)$(pkglibdir)
          375  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)
   359    376   	@list='$(lib_BINARIES)'; for p in $$list; do \
   360    377   	  if test -f $$p; then \
   361         -	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
   362         -	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
          378  +	    echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
          379  +	    $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
   363    380   	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
   364    381   	    if test "x$$stub" = "xstub"; then \
   365    382   		echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
   366    383   		$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
   367    384   	    else \
   368    385   		echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
   369    386   		$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
................................................................................
   396    413   # wish and tclsh), like dependent .dll files on Windows.
   397    414   #
   398    415   # You should not have to modify this target, except to define bin_BINARIES
   399    416   # above if necessary.
   400    417   #========================================================================
   401    418   
   402    419   install-bin-binaries: binaries
   403         -	@mkdir -p $(DESTDIR)$(bindir)
          420  +	@$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir)
   404    421   	@list='$(bin_BINARIES)'; for p in $$list; do \
   405    422   	  if test -f $$p; then \
   406    423   	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
   407    424   	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
   408    425   	  fi; \
   409    426   	done
   410    427   
   411         -.SUFFIXES: .c .$(OBJEXT)
   412         -
   413    428   Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
   414    429   	cd $(top_builddir) \
   415    430   	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
   416    431   
   417    432   uninstall-binaries:
   418    433   	list='$(lib_BINARIES)'; for p in $$list; do \
   419    434   	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \

Changes to extensions/tnc/configure.

more than 10,000 changes

Changes to extensions/tnc/configure.in.

     1      1   #!/bin/bash -norc
     2      2   dnl	This file is an input file used by the GNU "autoconf" program to
     3      3   dnl	generate the file "configure", which is run during Tcl installation
     4      4   dnl	to configure the system for the local environment.
     5         -#
     6         -# RCS: @(#) $Id$
     7      5   
     8      6   #-----------------------------------------------------------------------
     9      7   # Sample configure.in for Tcl Extensions.  The only places you should
    10      8   # need to modify this file are marked by the string __CHANGE__
    11      9   #-----------------------------------------------------------------------
    12     10   
    13     11   #-----------------------------------------------------------------------
................................................................................
    23     21   
    24     22   #--------------------------------------------------------------------
    25     23   # Call TEA_INIT as the first TEA_ macro to set up initial vars.
    26     24   # This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
    27     25   # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
    28     26   #--------------------------------------------------------------------
    29     27   
    30         -TEA_INIT([3.6])
           28  +TEA_INIT([3.10])
    31     29   
    32     30   AC_CONFIG_AUX_DIR(../../tclconfig)
    33     31   
    34     32   #--------------------------------------------------------------------
    35     33   # Load the tclConfig.sh file
    36     34   #--------------------------------------------------------------------
    37     35   
................................................................................
    77     75   # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
    78     76   # and PKG_TCL_SOURCES.
    79     77   #-----------------------------------------------------------------------
    80     78   
    81     79   TEA_ADD_SOURCES([tnc.c])
    82     80   TEA_ADD_HEADERS([])
    83     81   TEA_ADD_INCLUDES([-I${srcdir}/../../generic -I${srcdir}/../../expat])
           82  +TEA_ADD_LIBS([${TDOM_STUB_LIB_SPEC}])
    84     83   TEA_ADD_CFLAGS([-DUSE_TDOM_STUBS=1])
    85     84   TEA_ADD_STUB_SOURCES([])
    86     85   TEA_ADD_TCL_SOURCES([])
    87     86   
    88         -# See https://sourceforge.net/tracker/index.php?func=detail&aid=1636345&group_id=10894&atid=110894
    89         -if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
    90         -    TEA_ADD_LIBS([\"`${CYGPATH} ${TDOM_STUB_LIB_PATH}`\"])
    91         -else
    92         -    TEA_ADD_LIBS([${TDOM_STUB_LIB_SPEC}])
    93         -fi
    94         -
    95     87   #--------------------------------------------------------------------
    96     88   # __CHANGE__
    97     89   # A few miscellaneous platform-specific items:
    98     90   #
    99     91   # Define a special symbol for Windows (BUILD_sample in this case) so
   100     92   # that we create the export library with the dll.
   101     93   #
................................................................................
   103     95   # You can add more files to clean if your extension creates any extra
   104     96   # files.
   105     97   #
   106     98   # TEA_ADD_* any platform specific compiler/build info here.
   107     99   #--------------------------------------------------------------------
   108    100   
   109    101   if test "${TEA_PLATFORM}" = "windows" ; then
   110         -    AC_DEFINE(BUILD_tnc, 1, [Build windows export dll])
          102  +    #AC_DEFINE(BUILD_tnc, 1, [Build windows export dll])
   111    103       CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
   112    104       #TEA_ADD_SOURCES([win/winFile.c])
   113    105       #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
   114    106   else
   115    107       CLEANFILES="pkgIndex.tcl"
   116    108       #TEA_ADD_SOURCES([unix/unixFile.c])
   117    109       #TEA_ADD_LIBS([-lsuperfly])

Changes to extensions/tnc/install-sh.

     1      1   #!/bin/sh
     2         -
     3         -#
     4      2   # install - install a program, script, or datafile
     5         -# This comes from X11R5; it is not part of GNU.
            3  +
            4  +scriptversion=2011-04-20.01; # UTC
            5  +
            6  +# This originates from X11R5 (mit/util/scripts/install.sh), which was
            7  +# later released in X11R6 (xc/config/util/install.sh) with the
            8  +# following copyright and license.
            9  +#
           10  +# Copyright (C) 1994 X Consortium
           11  +#
           12  +# Permission is hereby granted, free of charge, to any person obtaining a copy
           13  +# of this software and associated documentation files (the "Software"), to
           14  +# deal in the Software without restriction, including without limitation the
           15  +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
           16  +# sell copies of the Software, and to permit persons to whom the Software is
           17  +# furnished to do so, subject to the following conditions:
           18  +#
           19  +# The above copyright notice and this permission notice shall be included in
           20  +# all copies or substantial portions of the Software.
           21  +#
           22  +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
           23  +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
           24  +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
           25  +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
           26  +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
           27  +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
           28  +#
           29  +# Except as contained in this notice, the name of the X Consortium shall not
           30  +# be used in advertising or otherwise to promote the sale, use or other deal-
           31  +# ings in this Software without prior written authorization from the X Consor-
           32  +# tium.
           33  +#
           34  +#
           35  +# FSF changes to this file are in the public domain.
     6     36   #
     7         -# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
           37  +# Calling this script install-sh is preferred over install.sh, to prevent
           38  +# `make' implicit rules from creating a file called install from it
           39  +# when there is no Makefile.
     8     40   #
     9     41   # This script is compatible with the BSD install script, but was written
    10     42   # from scratch.
    11         -#
    12     43   
           44  +nl='
           45  +'
           46  +IFS=" ""	$nl"
    13     47   
    14     48   # set DOITPROG to echo to test this script
    15     49   
    16     50   # Don't use :- since 4.3BSD and earlier shells don't like it.
    17         -doit="${DOITPROG-}"
    18         -
    19         -
    20         -# put in absolute paths if you don't have them in your path; or use env. vars.
    21         -
    22         -mvprog="${MVPROG-mv}"
    23         -cpprog="${CPPROG-cp}"
    24         -chmodprog="${CHMODPROG-chmod}"
    25         -chownprog="${CHOWNPROG-chown}"
    26         -chgrpprog="${CHGRPPROG-chgrp}"
    27         -stripprog="${STRIPPROG-strip}"
    28         -rmprog="${RMPROG-rm}"
    29         -
    30         -instcmd="$mvprog"
    31         -chmodcmd=""
    32         -chowncmd=""
    33         -chgrpcmd=""
    34         -stripcmd=""
           51  +doit=${DOITPROG-}
           52  +if test -z "$doit"; then
           53  +  doit_exec=exec
           54  +else
           55  +  doit_exec=$doit
           56  +fi
           57  +
           58  +# Put in absolute file names if you don't have them in your path;
           59  +# or use environment vars.
           60  +
           61  +chgrpprog=${CHGRPPROG-chgrp}
           62  +chmodprog=${CHMODPROG-chmod}
           63  +chownprog=${CHOWNPROG-chown}
           64  +cmpprog=${CMPPROG-cmp}
           65  +cpprog=${CPPROG-cp}
           66  +mkdirprog=${MKDIRPROG-mkdir}
           67  +mvprog=${MVPROG-mv}
           68  +rmprog=${RMPROG-rm}
           69  +stripprog=${STRIPPROG-strip}
           70  +
           71  +posix_glob='?'
           72  +initialize_posix_glob='
           73  +  test "$posix_glob" != "?" || {
           74  +    if (set -f) 2>/dev/null; then
           75  +      posix_glob=
           76  +    else
           77  +      posix_glob=:
           78  +    fi
           79  +  }
           80  +'
           81  +
           82  +posix_mkdir=
           83  +
           84  +# Desired mode of installed file.
           85  +mode=0755
           86  +
           87  +chgrpcmd=
           88  +chmodcmd=$chmodprog
           89  +chowncmd=
           90  +mvcmd=$mvprog
    35     91   rmcmd="$rmprog -f"
    36         -mvcmd="$mvprog"
    37         -src=""
    38         -dst=""
    39         -
    40         -while [ x"$1" != x ]; do
    41         -    case $1 in
    42         -	-c) instcmd="$cpprog"
    43         -	    shift
    44         -	    continue;;
    45         -
    46         -	-m) chmodcmd="$chmodprog $2"
    47         -	    shift
    48         -	    shift
    49         -	    continue;;
    50         -
    51         -	-o) chowncmd="$chownprog $2"
    52         -	    shift
    53         -	    shift
    54         -	    continue;;
    55         -
    56         -	-g) chgrpcmd="$chgrpprog $2"
    57         -	    shift
    58         -	    shift
    59         -	    continue;;
    60         -
    61         -	-s) stripcmd="$stripprog"
    62         -	    shift
    63         -	    continue;;
    64         -
    65         -	*)  if [ x"$src" = x ]
    66         -	    then
    67         -		src=$1
    68         -	    else
    69         -		dst=$1
    70         -	    fi
    71         -	    shift
    72         -	    continue;;
    73         -    esac
           92  +stripcmd=
           93  +
           94  +src=
           95  +dst=
           96  +dir_arg=
           97  +dst_arg=
           98  +
           99  +copy_on_change=false
          100  +no_target_directory=
          101  +
          102  +usage="\
          103  +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
          104  +   or: $0 [OPTION]... SRCFILES... DIRECTORY
          105  +   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
          106  +   or: $0 [OPTION]... -d DIRECTORIES...
          107  +
          108  +In the 1st form, copy SRCFILE to DSTFILE.
          109  +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
          110  +In the 4th, create DIRECTORIES.
          111  +
          112  +Options:
          113  +     --help     display this help and exit.
          114  +     --version  display version info and exit.
          115  +
          116  +  -c            (ignored)
          117  +  -C            install only if different (preserve the last data modification time)
          118  +  -d            create directories instead of installing files.
          119  +  -g GROUP      $chgrpprog installed files to GROUP.
          120  +  -m MODE       $chmodprog installed files to MODE.
          121  +  -o USER       $chownprog installed files to USER.
          122  +  -s            $stripprog installed files.
          123  +  -S            $stripprog installed files.
          124  +  -t DIRECTORY  install into DIRECTORY.
          125  +  -T            report an error if DSTFILE is a directory.
          126  +
          127  +Environment variables override the default commands:
          128  +  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
          129  +  RMPROG STRIPPROG
          130  +"
          131  +
          132  +while test $# -ne 0; do
          133  +  case $1 in
          134  +    -c) ;;
          135  +
          136  +    -C) copy_on_change=true;;
          137  +
          138  +    -d) dir_arg=true;;
          139  +
          140  +    -g) chgrpcmd="$chgrpprog $2"
          141  +	shift;;
          142  +
          143  +    --help) echo "$usage"; exit $?;;
          144  +
          145  +    -m) mode=$2
          146  +	case $mode in
          147  +	  *' '* | *'	'* | *'
          148  +'*	  | *'*'* | *'?'* | *'['*)
          149  +	    echo "$0: invalid mode: $mode" >&2
          150  +	    exit 1;;
          151  +	esac
          152  +	shift;;
          153  +
          154  +    -o) chowncmd="$chownprog $2"
          155  +	shift;;
          156  +
          157  +    -s) stripcmd=$stripprog;;
          158  +
          159  +    -S) stripcmd="$stripprog $2"
          160  +	shift;;
          161  +
          162  +    -t) dst_arg=$2
          163  +	shift;;
          164  +
          165  +    -T) no_target_directory=true;;
          166  +
          167  +    --version) echo "$0 $scriptversion"; exit $?;;
          168  +
          169  +    --)	shift
          170  +	break;;
          171  +
          172  +    -*)	echo "$0: invalid option: $1" >&2
          173  +	exit 1;;
          174  +
          175  +    *)  break;;
          176  +  esac
          177  +  shift
    74    178   done
    75    179   
    76         -if [ x"$src" = x ]
    77         -then
    78         -	echo "install:  no input file specified"
    79         -	exit 1
          180  +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
          181  +  # When -d is used, all remaining arguments are directories to create.
          182  +  # When -t is used, the destination is already specified.
          183  +  # Otherwise, the last argument is the destination.  Remove it from $@.
          184  +  for arg
          185  +  do
          186  +    if test -n "$dst_arg"; then
          187  +      # $@ is not empty: it contains at least $arg.
          188  +      set fnord "$@" "$dst_arg"
          189  +      shift # fnord
          190  +    fi
          191  +    shift # arg
          192  +    dst_arg=$arg
          193  +  done
          194  +fi
          195  +
          196  +if test $# -eq 0; then
          197  +  if test -z "$dir_arg"; then
          198  +    echo "$0: no input file specified." >&2
          199  +    exit 1
          200  +  fi
          201  +  # It's OK to call `install-sh -d' without argument.
          202  +  # This can happen when creating conditional directories.
          203  +  exit 0
          204  +fi
          205  +
          206  +if test -z "$dir_arg"; then
          207  +  do_exit='(exit $ret); exit $ret'
          208  +  trap "ret=129; $do_exit" 1
          209  +  trap "ret=130; $do_exit" 2
          210  +  trap "ret=141; $do_exit" 13
          211  +  trap "ret=143; $do_exit" 15
          212  +
          213  +  # Set umask so as not to create temps with too-generous modes.
          214  +  # However, 'strip' requires both read and write access to temps.
          215  +  case $mode in
          216  +    # Optimize common cases.
          217  +    *644) cp_umask=133;;
          218  +    *755) cp_umask=22;;
          219  +
          220  +    *[0-7])
          221  +      if test -z "$stripcmd"; then
          222  +	u_plus_rw=
          223  +      else
          224  +	u_plus_rw='% 200'
          225  +      fi
          226  +      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
          227  +    *)
          228  +      if test -z "$stripcmd"; then
          229  +	u_plus_rw=
          230  +      else
          231  +	u_plus_rw=,u+rw
          232  +      fi
          233  +      cp_umask=$mode$u_plus_rw;;
          234  +  esac
    80    235   fi
    81    236   
    82         -if [ x"$dst" = x ]
    83         -then
    84         -	echo "install:  no destination specified"
          237  +for src
          238  +do
          239  +  # Protect names starting with `-'.
          240  +  case $src in
          241  +    -*) src=./$src;;
          242  +  esac
          243  +
          244  +  if test -n "$dir_arg"; then
          245  +    dst=$src
          246  +    dstdir=$dst
          247  +    test -d "$dstdir"
          248  +    dstdir_status=$?
          249  +  else
          250  +
          251  +    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
          252  +    # might cause directories to be created, which would be especially bad
          253  +    # if $src (and thus $dsttmp) contains '*'.
          254  +    if test ! -f "$src" && test ! -d "$src"; then
          255  +      echo "$0: $src does not exist." >&2
          256  +      exit 1
          257  +    fi
          258  +
          259  +    if test -z "$dst_arg"; then
          260  +      echo "$0: no destination specified." >&2
          261  +      exit 1
          262  +    fi
          263  +
          264  +    dst=$dst_arg
          265  +    # Protect names starting with `-'.
          266  +    case $dst in
          267  +      -*) dst=./$dst;;
          268  +    esac
          269  +
          270  +    # If destination is a directory, append the input filename; won't work
          271  +    # if double slashes aren't ignored.
          272  +    if test -d "$dst"; then
          273  +      if test -n "$no_target_directory"; then
          274  +	echo "$0: $dst_arg: Is a directory" >&2
    85    275   	exit 1
    86         -fi
          276  +      fi
          277  +      dstdir=$dst
          278  +      dst=$dstdir/`basename "$src"`
          279  +      dstdir_status=0
          280  +    else
          281  +      # Prefer dirname, but fall back on a substitute if dirname fails.
          282  +      dstdir=`
          283  +	(dirname "$dst") 2>/dev/null ||
          284  +	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
          285  +	     X"$dst" : 'X\(//\)[^/]' \| \
          286  +	     X"$dst" : 'X\(//\)$' \| \
          287  +	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
          288  +	echo X"$dst" |
          289  +	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
          290  +		   s//\1/
          291  +		   q
          292  +		 }
          293  +		 /^X\(\/\/\)[^/].*/{
          294  +		   s//\1/
          295  +		   q
          296  +		 }
          297  +		 /^X\(\/\/\)$/{
          298  +		   s//\1/
          299  +		   q
          300  +		 }
          301  +		 /^X\(\/\).*/{
          302  +		   s//\1/
          303  +		   q
          304  +		 }
          305  +		 s/.*/./; q'
          306  +      `
          307  +
          308  +      test -d "$dstdir"
          309  +      dstdir_status=$?
          310  +    fi
          311  +  fi
          312  +
          313  +  obsolete_mkdir_used=false
          314  +
          315  +  if test $dstdir_status != 0; then
          316  +    case $posix_mkdir in
          317  +      '')
          318  +	# Create intermediate dirs using mode 755 as modified by the umask.
          319  +	# This is like FreeBSD 'install' as of 1997-10-28.
          320  +	umask=`umask`
          321  +	case $stripcmd.$umask in
          322  +	  # Optimize common cases.
          323  +	  *[2367][2367]) mkdir_umask=$umask;;
          324  +	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
          325  +
          326  +	  *[0-7])
          327  +	    mkdir_umask=`expr $umask + 22 \
          328  +	      - $umask % 100 % 40 + $umask % 20 \
          329  +	      - $umask % 10 % 4 + $umask % 2
          330  +	    `;;
          331  +	  *) mkdir_umask=$umask,go-w;;
          332  +	esac
          333  +
          334  +	# With -d, create the new directory with the user-specified mode.
          335  +	# Otherwise, rely on $mkdir_umask.
          336  +	if test -n "$dir_arg"; then
          337  +	  mkdir_mode=-m$mode
          338  +	else
          339  +	  mkdir_mode=
          340  +	fi
          341  +
          342  +	posix_mkdir=false
          343  +	case $umask in
          344  +	  *[123567][0-7][0-7])
          345  +	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
          346  +	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
          347  +	    ;;
          348  +	  *)
          349  +	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
          350  +	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
          351  +
          352  +	    if (umask $mkdir_umask &&
          353  +		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
          354  +	    then
          355  +	      if test -z "$dir_arg" || {
          356  +		   # Check for POSIX incompatibilities with -m.
          357  +		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
          358  +		   # other-writeable bit of parent directory when it shouldn't.
          359  +		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
          360  +		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
          361  +		   case $ls_ld_tmpdir in
          362  +		     d????-?r-*) different_mode=700;;
          363  +		     d????-?--*) different_mode=755;;
          364  +		     *) false;;
          365  +		   esac &&
          366  +		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
          367  +		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
          368  +		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
          369  +		   }
          370  +		 }
          371  +	      then posix_mkdir=:
          372  +	      fi
          373  +	      rmdir "$tmpdir/d" "$tmpdir"
          374  +	    else
          375  +	      # Remove any dirs left behind by ancient mkdir implementations.
          376  +	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
          377  +	    fi
          378  +	    trap '' 0;;
          379  +	esac;;
          380  +    esac
          381  +
          382  +    if
          383  +      $posix_mkdir && (
          384  +	umask $mkdir_umask &&
          385  +	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
          386  +      )
          387  +    then :
          388  +    else
          389  +
          390  +      # The umask is ridiculous, or mkdir does not conform to POSIX,
          391  +      # or it failed possibly due to a race condition.  Create the
          392  +      # directory the slow way, step by step, checking for races as we go.
          393  +
          394  +      case $dstdir in
          395  +	/*) prefix='/';;
          396  +	-*) prefix='./';;
          397  +	*)  prefix='';;
          398  +      esac
          399  +
          400  +      eval "$initialize_posix_glob"
          401  +
          402  +      oIFS=$IFS
          403  +      IFS=/
          404  +      $posix_glob set -f
          405  +      set fnord $dstdir
          406  +      shift
          407  +      $posix_glob set +f
          408  +      IFS=$oIFS
          409  +
          410  +      prefixes=
          411  +
          412  +      for d
          413  +      do
          414  +	test -z "$d" && continue
          415  +
          416  +	prefix=$prefix$d
          417  +	if test -d "$prefix"; then
          418  +	  prefixes=
          419  +	else
          420  +	  if $posix_mkdir; then
          421  +	    (umask=$mkdir_umask &&
          422  +	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
          423  +	    # Don't fail if two instances are running concurrently.
          424  +	    test -d "$prefix" || exit 1
          425  +	  else
          426  +	    case $prefix in
          427  +	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
          428  +	      *) qprefix=$prefix;;
          429  +	    esac
          430  +	    prefixes="$prefixes '$qprefix'"
          431  +	  fi
          432  +	fi
          433  +	prefix=$prefix/
          434  +      done
          435  +
          436  +      if test -n "$prefixes"; then
          437  +	# Don't fail if two instances are running concurrently.
          438  +	(umask $mkdir_umask &&
          439  +	 eval "\$doit_exec \$mkdirprog $prefixes") ||
          440  +	  test -d "$dstdir" || exit 1
          441  +	obsolete_mkdir_used=true
          442  +      fi
          443  +    fi
          444  +  fi
          445  +
          446  +  if test -n "$dir_arg"; then
          447  +    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
          448  +    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
          449  +    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
          450  +      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
          451  +  else
          452  +
          453  +    # Make a couple of temp file names in the proper directory.
          454  +    dsttmp=$dstdir/_inst.$$_
          455  +    rmtmp=$dstdir/_rm.$$_
          456  +
          457  +    # Trap to clean up those temp files at exit.
          458  +    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
          459  +
          460  +    # Copy the file name to the temp name.
          461  +    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
          462  +
          463  +    # and set any options; do chmod last to preserve setuid bits.
          464  +    #
          465  +    # If any of these fail, we abort the whole thing.  If we want to
          466  +    # ignore errors from any of these, just make sure not to ignore
          467  +    # errors from the above "$doit $cpprog $src $dsttmp" command.
          468  +    #
          469  +    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
          470  +    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
          471  +    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
          472  +    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
          473  +
          474  +    # If -C, don't bother to copy if it wouldn't change the file.
          475  +    if $copy_on_change &&
          476  +       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
          477  +       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
          478  +
          479  +       eval "$initialize_posix_glob" &&
          480  +       $posix_glob set -f &&
          481  +       set X $old && old=:$2:$4:$5:$6 &&
          482  +       set X $new && new=:$2:$4:$5:$6 &&
          483  +       $posix_glob set +f &&
    87    484   
          485  +       test "$old" = "$new" &&
          486  +       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
          487  +    then
          488  +      rm -f "$dsttmp"
          489  +    else
          490  +      # Rename the file to the real destination.
          491  +      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
    88    492   
    89         -# If destination is a directory, append the input filename; if your system
    90         -# does not like double slashes in filenames, you may need to add some logic
          493  +      # The rename failed, perhaps because mv can't rename something else
          494  +      # to itself, or perhaps because mv is so ancient that it does not
          495  +      # support -f.
          496  +      {
          497  +	# Now remove or move aside any old file at destination location.
          498  +	# We try this two ways since rm can't unlink itself on some
          499  +	# systems and the destination file might be busy for other
          500  +	# reasons.  In this case, the final cleanup might fail but the new
          501  +	# file should still install successfully.
          502  +	{
          503  +	  test ! -f "$dst" ||
          504  +	  $doit $rmcmd -f "$dst" 2>/dev/null ||
          505  +	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
          506  +	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
          507  +	  } ||
          508  +	  { echo "$0: cannot unlink or rename $dst" >&2
          509  +	    (exit 1); exit 1
          510  +	  }
          511  +	} &&
    91    512   
    92         -if [ -d $dst ]
    93         -then
    94         -	dst="$dst"/`basename $src`
    95         -fi
          513  +	# Now rename the file to the real destination.
          514  +	$doit $mvcmd "$dsttmp" "$dst"
          515  +      }
          516  +    fi || exit 1
    96    517   
    97         -# Make a temp file name in the proper directory.
    98         -
    99         -dstdir=`dirname $dst`
   100         -dsttmp=$dstdir/#inst.$$#
   101         -
   102         -# Move or copy the file name to the temp name
          518  +    trap '' 0
          519  +  fi
          520  +done
   103    521   
   104         -$doit $instcmd $src $dsttmp
   105         -
   106         -# and set any options; do chmod last to preserve setuid bits
   107         -
   108         -if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
   109         -if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
   110         -if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
   111         -if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
   112         -
   113         -# Now rename the file to the real destination.
   114         -
   115         -$doit $rmcmd $dst
   116         -$doit $mvcmd $dsttmp $dst
   117         -
   118         -
   119         -exit 0
          522  +# Local variables:
          523  +# eval: (add-hook 'write-file-hooks 'time-stamp)
          524  +# time-stamp-start: "scriptversion="
          525  +# time-stamp-format: "%:y-%02m-%02d.%02H"
          526  +# time-stamp-time-zone: "UTC"
          527  +# time-stamp-end: "; # UTC"
          528  +# End:

Deleted extensions/tnc/makefile.vc.

     1         -#----------------------------------------------------------------------------
     2         -#   This is derivated from the tcl8.3 win makefile and surely not
     3         -#   perfect. It works for me. 
     4         -#   rolf ade, 2001 (rolf@pointsman.de)
     5         -#   
     6         -#
     7         -#
     8         -#   Project directories
     9         -#
    10         -#   ROOT   = top of source tree
    11         -#
    12         -#   TOOLS32 = location of VC++ 32-bit development tools.
    13         -#
    14         -#   INSTALLDIR = where the install- targets should copy the binaries and
    15         -#                support files
    16         -#
    17         -#----------------------------------------------------------------------------
    18         -
    19         -!if "$(MSVCDIR)" == ""
    20         -MSG = ^
    21         -You'll need to run vcvars32.bat from Developer Studio, first, to setup^
    22         -the environment.
    23         -!error $(MSG)
    24         -!endif
    25         -
    26         -
    27         -#          VC++ 2.0 header files are broken, so you need to use the
    28         -#          ones that come with the developer network CD's, or later
    29         -#          versions of VC++.
    30         -#
    31         -# INSTALLDIR = where the install- targets should copy the binaries and
    32         -#          support files
    33         -#
    34         -
    35         -# Set this to the appropriate value of /MACHINE: for your platform
    36         -MACHINE                = IX86
    37         -ROOT           = ..\..
    38         -INSTALLDIR     = c:\Progra~1\Tcl
    39         -
    40         -TOOLS32        = $(MSVCDIR)
    41         -TOOLS32_rc     = $(MSVCDIR)\..\common\MSDev98
    42         -
    43         -# Uncomment the following line to compile with thread support
    44         -#THREADDEFINES = -DTCL_THREADS=1
    45         -
    46         -# Set NODEBUG to 0 to compile with symbols
    47         -NODEBUG = 1
    48         -
    49         -# The following defines can be used to control the amount of debugging
    50         -# code that is added to the compilation.
    51         -#
    52         -#      -DTCL_MEM_DEBUG         Enables the debugging memory allocator.
    53         -#      -DTCL_COMPILE_DEBUG     Enables byte compilation logging.
    54         -#      -DTCL_COMPILE_STATS     Enables byte compilation statistics gathering.
    55         -#      -DUSE_TCLALLOC=0        Disables the Tcl memory allocator in favor
    56         -#                              of the native malloc implementation.  This is
    57         -#
    58         -# DEBUGDEFINES = -DTCL_MEM_DEBUG -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
    59         -# DEBUGDEFINES = -DUSE_TCLALLOC=0
    60         -
    61         -
    62         -#-------------------------------------------------------------------------
    63         -#
    64         -#   Do not modify below this line
    65         -#
    66         -#-------------------------------------------------------------------------
    67         -
    68         -NAMEPREFIX = libtnc
    69         -STUBPREFIX = $(NAMEPREFIX)stub
    70         -DOTVERSION = 0.3
    71         -PACKAGE_VERSION = \"0.3.0\"
    72         -VERSION = \"0.3\"
    73         -W32VERSION = 03
    74         -TDOMVER = 082
    75         -
    76         -BINROOT         = .
    77         -!IF "$(NODEBUG)" == "1"
    78         -TMPDIRNAME      =
    79         -DBGX            =
    80         -!ELSE
    81         -TMPDIRNAME      = Debug
    82         -DBGX            = d
    83         -!ENDIF
    84         -TMPDIR          = $(BINROOT)
    85         -OUTDIRNAME      = $(TMPDIRNAME)
    86         -OUTDIR          = $(TMPDIR)
    87         -TOP_DIR         = $(BINROOT)\..
    88         -
    89         -TNCLIB         = $(OUTDIR)\$(NAMEPREFIX)$(W32VERSION)$(DBGX).lib
    90         -TNCDLLNAME     = $(NAMEPREFIX)$(W32VERSION)$(DBGX).dll
    91         -TNCDLL         = $(OUTDIR)\$(TNCDLLNAME)
    92         -
    93         -# MKDIR           = .\mkd.bat
    94         -RM              = del
    95         -
    96         -LIB_INSTALL_DIR        = $(INSTALLDIR)\lib
    97         -BIN_INSTALL_DIR        = $(INSTALLDIR)\bin
    98         -SCRIPT_INSTALL_DIR     = $(INSTALLDIR)\lib\tcl$(DOTVERSION)
    99         -INCLUDE_INSTALL_DIR    = $(INSTALLDIR)\include
   100         -
   101         -
   102         -TNCOBJS = $(TMPDIR)\tnc.obj
   103         -
   104         -cc32           = "$(TOOLS32)\bin\cl.exe"
   105         -link32         = "$(TOOLS32)\bin\link.exe"
   106         -rc32           = "$(TOOLS32_rc)\bin\rc.exe"
   107         -include32      = -I"$(TOOLS32)\include"
   108         -libpath32      = /LIBPATH:"$(TOOLS32)\lib"
   109         -tcllibpath     = /LIBPATH:"$(INSTALLDIR)\lib"
   110         -tdomlibpath    = /LIBPATH:"$(ROOT)\win\Release"
   111         -lib32          = "$(TOOLS32)\bin\lib.exe"
   112         -
   113         -TNCDIR         = $(ROOT)\extensions\tnc
   114         -GENERICDIR     = $(ROOT)\generic
   115         -EXPATINCDIR    = $(ROOT)\expat
   116         -TCLINCDIR      = $(INSTALLDIR)\Include
   117         -
   118         -TCL_INCLUDES   = -I"$(TNCDIR)" -I"$(GENERICDIR)" -I"$(EXPATINCDIR)" -I"$(TCLINCDIR)"
   119         -TCL_DEFINES    = $(DEBUGDEFINES) $(THREADDEFINES)
   120         -
   121         -#-------------------------------------------------------------------------
   122         -#
   123         -#   Compile flags
   124         -#
   125         -#-------------------------------------------------------------------------
   126         -
   127         -!IF "$(NODEBUG)" == "1"
   128         -# This cranks the optimization level to maximize speed
   129         -cdebug = -O2 -Gs -GD
   130         -!ELSE
   131         -!IF "$(MACHINE)" == "IA64"
   132         -cdebug = -Od -Zi
   133         -!ELSE
   134         -cdebug = -Z7 -Od
   135         -!ENDIF
   136         -!ENDIF
   137         -
   138         -# declarations common to all compiler options
   139         -cflags = -c -nologo -Fp$(TMPDIR)\ -YX -DXML_DTD -DXML_NS -DUSE_TCL_STUBS -DUSE_TDOM_STUBS -DVERSION=$(VERSION) -DPACKAGE_VERSION=$(PACKAGE_VERSION)
   140         -cvarsdll = -MD$(DBGX)
   141         -
   142         -TCL_CFLAGS     = $(cdebug) $(cflags) $(cvarsdll) $(include32) \
   143         -                       $(TCL_INCLUDES) $(TCL_DEFINES)
   144         -CON_CFLAGS     = $(cdebug) $(cflags) $(include32) -DCONSOLE
   145         -
   146         -#-------------------------------------------------------------------------
   147         -#
   148         -#   Link flags
   149         -#
   150         -#-------------------------------------------------------------------------
   151         -
   152         -!IF "$(NODEBUG)" == "1"
   153         -ldebug = /RELEASE
   154         -!ELSE
   155         -ldebug = -debug:full -debugtype:cv
   156         -!ENDIF
   157         -
   158         -# declarations common to all linker options
   159         -lflags = /NODEFAULTLIB /NOLOGO /MACHINE:$(MACHINE) $(libpath32) $(tcllibpath) $(tdomlibpath) 
   160         -
   161         -# declarations for use on Intel i386, i486, and Pentium systems
   162         -DLLENTRY = @12
   163         -dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll
   164         -
   165         -
   166         -conlflags = $(lflags) -subsystem:console -entry:mainCRTStartup
   167         -guilflags = $(lflags) -subsystem:windows -entry:WinMainCRTStartup
   168         -
   169         -libc = libc$(DBGX).lib oldnames.lib
   170         -libcdll = msvcrt$(DBGX).lib oldnames.lib
   171         -
   172         -baselibs   = kernel32.lib $(optlibs) advapi32.lib user32.lib tclstub84$(DBGX).lib tdomstub$(TDOMVER).lib 
   173         -winlibs     = $(baselibs) gdi32.lib comdlg32.lib winspool.lib
   174         -
   175         -
   176         -guilibs     = $(libc) $(winlibs)
   177         -conlibs     = $(libc) $(baselibs)
   178         -guilibsdll  = $(libcdll) $(winlibs)
   179         -conlibsdll  = $(libcdll) $(baselibs)
   180         -
   181         -#-------------------------------------------------------------------------
   182         -#
   183         -#   Project specific targets
   184         -#
   185         -#-------------------------------------------------------------------------
   186         -
   187         -release:   setup dlls
   188         -dlls:      setup $(TNCDLL)
   189         -all:       setup dlls $(CAT32)
   190         -
   191         -setup:
   192         -#      @$(MKDIR) $(TMPDIR)
   193         -#      @$(MKDIR) $(OUTDIR)
   194         -
   195         -$(TNCLIB): $(TNCDLL)
   196         -
   197         -$(TNCDLL): $(TNCOBJS)
   198         -       $(link32) $(ldebug) $(dlllflags) \
   199         -               -out:$@ $(guilibsdll) @<<
   200         -$(TNCOBJS)
   201         -<<
   202         -
   203         -#-------------------------------------------------------------------------
   204         -#   Implicit rules
   205         -#-------------------------------------------------------------------------
   206         -
   207         -{$(TNCDIR)}.c{$(TMPDIR)}.obj:
   208         -    $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<
   209         -
   210         -clean:
   211         -       -@$(RM) $(OUTDIR)\*.exp 2>nul
   212         -       -@$(RM) $(OUTDIR)\*.lib 2>nul
   213         -       -@$(RM) $(OUTDIR)\*.dll 2>nul
   214         -       -@$(RM) $(TMPDIR)\*.pch 2>nul
   215         -       -@$(RM) $(TMPDIR)\*.obj 2>nul
   216         -       -@$(RM) $(TMPDIR)\*.ilk 2>nul
   217         -       -@$(RM) $(TMPDIR)\*.pdb 2>nul

Changes to extensions/tnc/tests/loadtnc.tcl.

            1  +catch {load ../../../unix/libtdom0.9.1.so}
            2  +catch {load ../libtnc0.3.0.so}
            3  +catch {load ../../unix/libtdom0.9.1.so}
            4  +catch {load libtnc0.3.0.so}
     1      5   # loadtnc.tcl --
     2      6   #
     3      7   # This file is [source]d by all.tcl and all test files, to ensure, that
     4      8   # the tcltest package and the lastest tnc build is present.
     5      9   
     6     10   if {[lsearch [namespace children] ::tcltest] == -1} {
     7     11       if {$tcl_version < 8.2} {
................................................................................
    11     15       } else {
    12     16           package require tcltest
    13     17           namespace import ::tcltest::*
    14     18       }
    15     19   }
    16     20   
    17     21   if {[catch {package present tdom}]} {
    18         -    package require tdom 0.7.5
           22  +    package require tdom
    19     23   }
    20     24   
    21         -if {[catch {package require tnc 0.3}]} {
    22         -    load [file join [file dir [info script]] .. libtnc0.3.0.so]
           25  +if {[catch {package require tnc}]} {
           26  +    package require tnc
    23     27   }
    24     28   

Changes to extensions/tnc/tests/tnc.test.

   130    130       <!ELEMENT b EMPTY>
   131    131   ]>
   132    132   <!-- This not well-formed document doesn't have a root element -->}} errMsg]
   133    133       $parser free
   134    134       set result
   135    135   } {1}
   136    136   
          137  +test tnc-2.7 {not valid document} {
          138  +    set parser [expat]
          139  +    tnc $parser enable
          140  +    set result [catch {$parser parse {<!DOCTYPE root [
          141  +    <!ELEMENT root (a,b)>
          142  +    <!ELEMENT a (#PCDATA)>
          143  +    <!ELEMENT b EMPTY>
          144  +]>
          145  +<root><a>text</a></root>}} errMsg]
          146  +    $parser free
          147  +    set errMsg
          148  +} {Validation error at line 6, character 17: Element can not end here (required element(s) missing).}
          149  +
          150  +proc 2.8-resolver {base systemId publicId} {
          151  +    switch $publicId {
          152  +        "-//W3C//DTD Specification V2.0//EN" {
          153  +            set fd [open [file join [file dir [info script]] \
          154  +                              ../../../tests/data/xmlspec-v20.dtd]]
          155  +            set xmlspec [read $fd]
          156  +            close $fd
          157  +            return [list "string" "" $xmlspec]
          158  +        }
          159  +        default {
          160  +            puts stderr "Unexpected systemId '$systemId'"
          161  +            return ""
          162  +        }
          163  +    }
          164  +}
          165  +
          166  +test tnc-2.8 {Validate REC-xslt-19991116.xml} {
          167  +    set ::tDOM::extRefHandlerDebug 1
          168  +    set parser [expat -externalentitycommand 2.8-resolver  \
          169  +                    -paramentityparsing always]
          170  +    tnc $parser enable
          171  +    $parser parsefile [file join [file dir [info script]] \
          172  +                           ../../../tests/data/REC-xslt-19991116.xml] 
          173  +    $parser free
          174  +} {}
          175  +
          176  +test tnc-2.9 {check #PCDATA only element} {
          177  +    set parser [expat]
          178  +    tnc $parser enable
          179  +    set result [catch {$parser parse {<!DOCTYPE root [
          180  +    <!ELEMENT root (a,b)>
          181  +    <!ELEMENT a (#PCDATA)>
          182  +    <!ELEMENT b EMPTY>
          183  +]>
          184  +<root><a>text<b/>text</a><b/></root>}} errMsg]
          185  +    $parser free
          186  +    set errMsg
          187  +} {Validation error at line 6, character 13: Element is not allowed here.}
          188  +
   137    189   test tnc-3.1 {validate cmd} {
   138    190       set parser [expat]
   139    191       tnc $parser enable
   140    192       set result [catch {$parser parse $xml}]
   141    193       set validator [tnc $parser getValidateCmd]
   142    194       rename $validator {}
   143    195       $parser free

Changes to extensions/tnc/tnc.c.

     5      5   
     6      6      Copyright (c) 2001-2003 Rolf Ade */
     7      7   
     8      8   #include <tdom.h>
     9      9   #include <string.h>
    10     10   #include <stdlib.h>
    11     11   
    12         -/*
    13         - * Beginning with 8.4, Tcl API is CONST'ified
    14         - */
    15         -#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3)
    16         -# define CONST84
    17         -#endif
    18         -
    19     12   #ifndef TCL_THREADS
    20     13   # define TDomThreaded(x)
    21     14   #else
    22     15   # define TDomThreaded(x) x
    23     16   #endif
    24     17   
    25         -/* The inital stack sizes must be at least 1 */
           18  +/* The initial stack sizes must be at least 1 */
    26     19   #define TNC_INITCONTENTSTACKSIZE 512
    27     20   
    28     21   /*----------------------------------------------------------------------------
    29     22   |   local globals
    30     23   |
    31     24   \---------------------------------------------------------------------------*/
    32     25   /* Counter to generate unique validateCmd names */
................................................................................
    64     57       int           alreadymatched;
    65     58   } TNC_ContentStack;
    66     59   
    67     60   
    68     61   typedef struct TNC_data
    69     62   {
    70     63       char             *doctypeName;            /* From DOCTYPE declaration */
    71         -    int               ignoreWhiteCDATAs;      /* Flag: white space allowed in 
           64  +    int               skipWhiteCDATAs;        /* Flag: white space allowed in 
    72     65                                                    current content model? */
    73     66       int               ignorePCDATA;           /* Flag: currently mixed content
    74     67                                                    model? */
    75     68       Tcl_HashTable    *tagNames;               /* Hash table of all ELEMENT
    76     69                                                    declarations of the DTD.
    77     70                                                    Element name is the key.
    78     71                                                    While parsing, entry points
................................................................................
    85     78                                                    the elemAttInfo pointer of
    86     79                                                    the current element here for
    87     80                                                    DOM validation, to avoid two
    88     81                                                    element name lookups. */
    89     82       int               elemContentsRewriten;   /* Signals, if the tagNames
    90     83                                                    entries point to
    91     84                                                    TNC_Contents */
    92         -    int               status;                 /* While used with expat obj:
           85  +    int               dtdstatus;                 /* While used with expat obj:
    93     86                                                    1 after successful parsed
    94     87                                                    DTD, 0 otherwise.
    95     88                                                    For validateCmd used for
    96     89                                                    error report during
    97     90                                                    validation: 0 OK, 1 validation
    98     91                                                    error. */
    99     92       int               idCheck;                /* Flag: check IDREF resolution*/
................................................................................
   177    170       TNC_ERROR_UNKNOWN_ELEMENT,
   178    171       TNC_ERROR_EMPTY_ELEMENT,
   179    172       TNC_ERROR_DISALLOWED_PCDATA,
   180    173       TNC_ERROR_DISALLOWED_CDATA,
   181    174       TNC_ERROR_NO_DOCTYPE_DECL,
   182    175       TNC_ERROR_WRONG_ROOT_ELEMENT,
   183    176       TNC_ERROR_NO_ATTRIBUTES,
   184         -    TNC_ERROR_UNKOWN_ATTRIBUTE,
          177  +    TNC_ERROR_UNKNOWN_ATTRIBUTE,
   185    178       TNC_ERROR_WRONG_FIXED_ATTVALUE,
   186    179       TNC_ERROR_MISSING_REQUIRED_ATTRIBUTE,
   187    180       TNC_ERROR_MORE_THAN_ONE_ID_ATT,
   188    181       TNC_ERROR_ID_ATT_DEFAULT,
   189    182       TNC_ERROR_DUPLICATE_ID_VALUE,
   190         -    TNC_ERROR_UNKOWN_ID_REFERRED,
          183  +    TNC_ERROR_UNKNOWN_ID_REFERRED,
   191    184       TNC_ERROR_ENTITY_ATTRIBUTE,
   192    185       TNC_ERROR_ENTITIES_ATTRIBUTE,
   193    186       TNC_ERROR_ATT_ENTITY_DEFAULT_MUST_BE_DECLARED,
   194    187       TNC_ERROR_NOTATION_REQUIRED,
   195    188       TNC_ERROR_NOTATION_MUST_BE_DECLARED,
   196    189       TNC_ERROR_IMPOSSIBLE_DEFAULT,
   197    190       TNC_ERROR_ENUM_ATT_WRONG_VALUE,
................................................................................
   266    259   
   267    260   #define SetBooleanResult(i) Tcl_ResetResult(interp); \
   268    261                        Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (i))
   269    262   
   270    263   extern char *Tdom_InitStubs (Tcl_Interp *interp, char *version, int exact);
   271    264   
   272    265   static void
   273         -signalNotValid (userData, code)
   274         -    void        *userData;
   275         -    int          code;
          266  +signalNotValid (
          267  +    void        *userData,
          268  +    int          code
          269  +)
   276    270   {
   277    271       TNC_Data *tncdata = (TNC_Data *) userData;
   278    272       TclGenExpatInfo *expat;
   279    273       char s[1000];
   280    274   
   281    275       if (tncdata->expatObj) {
   282    276           expat = GetExpatInfo (tncdata->interp, tncdata->expatObj);
................................................................................
   284    278                    XML_GetCurrentLineNumber (expat->parser),
   285    279                    XML_GetCurrentColumnNumber (expat->parser),
   286    280                    TNC_ErrorString (code));
   287    281           expat->status = TCL_ERROR;
   288    282           expat->result = Tcl_NewStringObj (s, -1);
   289    283           Tcl_IncrRefCount (expat->result);
   290    284       } else {
   291         -        tncdata->status = 1;
          285  +        tncdata->dtdstatus = 1;
   292    286           Tcl_SetResult (tncdata->interp, (char *)TNC_ErrorString (code),
   293    287                          TCL_VOLATILE);
   294    288       }
   295    289   }
   296    290   
   297    291   /*
   298    292    *----------------------------------------------------------------------------
................................................................................
   340    334    * Side effects:
   341    335    *	Stores the doctype Name in the TNC_data.
   342    336    *
   343    337    *----------------------------------------------------------------------------
   344    338    */
   345    339   
   346    340   void
   347         -TncStartDoctypeDeclHandler (userData, doctypeName, sysid, pubid, has_internal_subset)
   348         -    void       *userData;
   349         -    const char *doctypeName;
   350         -    const char *sysid;
   351         -    const char *pubid;
   352         -    int         has_internal_subset;
          341  +TncStartDoctypeDeclHandler (
          342  +    void       *userData,
          343  +    const char *doctypeName,
          344  +    const char *sysid,
          345  +    const char *pubid,
          346  +    int         has_internal_subset
          347  +)
   353    348   {
   354    349       TNC_Data *tncdata = (TNC_Data *) userData;
   355    350   
   356    351   #ifdef TNC_DEBUG
   357    352       printf ("TncStartDoctypeDeclHandler start\n");
   358    353   #endif
   359    354       tncdata->doctypeName = tdomstrdup (doctypeName);
................................................................................
   373    368    * Side effects:
   374    369    *	Frees memory.
   375    370    *
   376    371    *----------------------------------------------------------------------------
   377    372    */
   378    373   
   379    374   static void
   380         -TncFreeTncModel (tmodel)
   381         -    TNC_Content *tmodel;
          375  +TncFreeTncModel (
          376  +    TNC_Content *tmodel
          377  +)
   382    378   {
   383    379       unsigned int i;
   384    380   
   385    381       if (tmodel->children) {
   386    382           for (i = 0; i < tmodel->numchildren; i++) {
   387    383               TncFreeTncModel (&tmodel->children[i]);
   388    384           }
................................................................................
   405    401    * Side effects:
   406    402    *	Allocates memory for the TNC_Content models.
   407    403    *
   408    404    *----------------------------------------------------------------------------
   409    405    */
   410    406   
   411    407   static void
   412         -TncRewriteModel (emodel, tmodel, tagNames)
   413         -    XML_Content   *emodel;
   414         -    TNC_Content   *tmodel;
   415         -    Tcl_HashTable *tagNames;
          408  +TncRewriteModel (
          409  +    XML_Content   *emodel,
          410  +    TNC_Content   *tmodel,
          411  +    Tcl_HashTable *tagNames
          412  +)
   416    413   {
   417    414       Tcl_HashEntry *entryPtr;
   418    415       unsigned int i;
   419    416   
   420    417       tmodel->type = emodel->type;
   421    418       tmodel->quant = emodel->quant;
   422    419       tmodel->numchildren = emodel->numchildren;
................................................................................
   481    478    *	Rewrites the XML_Content models to TNC_Content
   482    479    *      models.
   483    480    *
   484    481    *----------------------------------------------------------------------------
   485    482    */
   486    483   
   487    484   void
   488         -TncEndDoctypeDeclHandler (userData)
   489         -    void *userData;
          485  +TncEndDoctypeDeclHandler (
          486  +    void *userData
          487  +)
   490    488   {
   491    489       TNC_Data *tncdata = (TNC_Data *) userData;
   492    490       Tcl_HashEntry *entryPtr, *ePtr1;
   493    491       Tcl_HashSearch search;
   494    492       XML_Content   *emodel;
   495    493       TNC_Content   *tmodel = NULL;
   496    494       char *elementName;
................................................................................
   536    534           if (!Tcl_GetHashValue (entryPtr)) {
   537    535               signalNotValid (userData,
   538    536                               TNC_ERROR_ATT_ENTITY_DEFAULT_MUST_BE_DECLARED);
   539    537               return;
   540    538           }
   541    539           entryPtr = Tcl_NextHashEntry (&search);
   542    540       }
   543         -    tncdata->status = 1;
          541  +    tncdata->dtdstatus = 1;
   544    542   }
   545    543   
   546    544   
   547    545   /*
   548    546    *----------------------------------------------------------------------------
   549    547    *
   550    548    * TncEntityDeclHandler --
................................................................................
   558    556    *	Stores either the name of the entity and
   559    557    *      type information in a lookup table.
   560    558    *
   561    559    *----------------------------------------------------------------------------
   562    560    */
   563    561   
   564    562   void
   565         -TncEntityDeclHandler (userData, entityName, is_parameter_entity, value,
   566         -                       value_length, base, systemId, publicId, notationName)
   567         -    void *userData;
   568         -    const char *entityName;
   569         -    int is_parameter_entity;
   570         -    const char *value;
   571         -    int value_length;
   572         -    const char *base;
   573         -    const char *systemId;
   574         -    const char *publicId;
   575         -    const char *notationName;
          563  +TncEntityDeclHandler (
          564  +    void *userData,
          565  +    const char *entityName,
          566  +    int is_parameter_entity,
          567  +    const char *value,
          568  +    int value_length,
          569  +    const char *base,
          570  +    const char *systemId,
          571  +    const char *publicId,
          572  +    const char *notationName
          573  +)
   576    574   {
   577    575       TNC_Data *tncdata = (TNC_Data *) userData;
   578         -    Tcl_HashEntry *entryPtr, *entryPtr1;
          576  +    Tcl_HashEntry *entryPtr;
   579    577       int newPtr;
   580    578       TNC_EntityInfo *entityInfo;
   581    579   
   582    580   
   583         -    /* expat collects entity definitions internaly by himself. So this is
          581  +    /* expat collects entity definitions internaly by itself. So this is
   584    582          maybe superfluous, if it possible to access the expat internal
   585         -       represention. To study this is left to the reader. */
          583  +       representation. To study this is left to the reader. */
   586    584   
   587    585       if (is_parameter_entity) return;
   588    586       entryPtr = Tcl_CreateHashEntry (tncdata->entityDecls, entityName, &newPtr);
   589    587       /* multiple declaration of the same entity are allowed; first
   590    588          definition wins (rec. 4.2) */
   591    589       if (!newPtr) {
   592    590           /* Eventually, an attribute declaration with type ENTITY or ENTITIES
   593    591              has used this (up to the attribute declaration undeclared) ENTITY
   594         -           within his default value. In this case, the hash value have to
          592  +           within his default value. In this case, the hash value has to
   595    593              be NULL and the entity must be a unparsed entity. */
   596    594           if (!Tcl_GetHashValue (entryPtr)) {
   597    595               if (notationName == NULL) {
   598    596                   signalNotValid (userData,
   599    597                                   TNC_ERROR_ATT_ENTITY_DEFAULT_MUST_BE_DECLARED);
   600    598                   return;
   601    599               }
................................................................................
   602    600               newPtr = 1;
   603    601           }
   604    602       }
   605    603       if (newPtr) {
   606    604           entityInfo = (TNC_EntityInfo *) MALLOC (sizeof (TNC_EntityInfo));
   607    605           if (notationName != NULL) {
   608    606               entityInfo->is_notation = 1;
   609         -            entryPtr1 = Tcl_CreateHashEntry (tncdata->notationDecls,
   610         -                                             notationName, &newPtr);
          607  +            Tcl_CreateHashEntry (tncdata->notationDecls,
          608  +                                 notationName, &newPtr);
   611    609               entityInfo->notationName = tdomstrdup (notationName);
   612    610           }
   613    611           else {
   614    612               entityInfo->is_notation = 0;
   615    613           }
   616    614           Tcl_SetHashValue (entryPtr, entityInfo);
   617    615       }
................................................................................
   631    629    *	Stores the notationName in the notationDecls table with value
   632    630    *      one.
   633    631    *
   634    632    *----------------------------------------------------------------------------
   635    633    */
   636    634   
   637    635   void
   638         -TncNotationDeclHandler (userData, notationName, base, systemId, publicId)
   639         -    void       *userData;
   640         -    const char *notationName;
   641         -    const char *base;
   642         -    const char *systemId;
   643         -    const char *publicId;
          636  +TncNotationDeclHandler (
          637  +    void       *userData,
          638  +    const char *notationName,
          639  +    const char *base,
          640  +    const char *systemId,
          641  +    const char *publicId
          642  +)
   644    643   {
   645    644       TNC_Data *tncdata = (TNC_Data *) userData;
   646    645       Tcl_HashEntry *entryPtr;
   647    646       int newPtr;
   648    647   
   649    648       entryPtr = Tcl_CreateHashEntry (tncdata->notationDecls,
   650    649                                       notationName,
................................................................................
   670    669    * Side effects:
   671    670    *	Stores the tag name of the element in a lookup table.
   672    671    *
   673    672    *----------------------------------------------------------------------------
   674    673    */
   675    674   
   676    675   void
   677         -TncElementDeclCommand (userData, name, model)
   678         -    void *userData;
   679         -    const char *name;
   680         -    XML_Content *model;
          676  +TncElementDeclCommand (
          677  +    void *userData,
          678  +    const char *name,
          679  +    XML_Content *model
          680  +)
   681    681   {
   682    682       TNC_Data *tncdata = (TNC_Data *) userData;
   683    683       Tcl_HashEntry *entryPtr;
   684    684       int newPtr;
   685    685       unsigned int i, j;
   686    686   
   687    687       entryPtr = Tcl_CreateHashEntry (tncdata->tagNames, name, &newPtr);
................................................................................
   727    727    * Side effects:
   728    728    *	Stores the tag name of the element in a lookup table.
   729    729    *
   730    730    *----------------------------------------------------------------------------
   731    731    */
   732    732   
   733    733   void
   734         -TncAttDeclCommand (userData, elname, attname, att_type, dflt, isrequired)
   735         -    void       *userData;
   736         -    const char *elname;
   737         -    const char *attname;
   738         -    const char *att_type;
   739         -    const char *dflt;
   740         -    int         isrequired;
          734  +TncAttDeclCommand (
          735  +    void       *userData,
          736  +    const char *elname,
          737  +    const char *attname,
          738  +    const char *att_type,
          739  +    const char *dflt,
          740  +    int         isrequired
          741  +)
   741    742   {
   742    743       TNC_Data *tncdata = (TNC_Data *) userData;
   743    744       Tcl_HashEntry *entryPtr, *entryPtr1;
   744    745       Tcl_HashTable *elemAtts;
   745    746       TNC_ElemAttInfo *elemAttInfo;
   746    747       TNC_AttDecl *attDecl;
   747    748       TNC_EntityInfo *entityInfo;
................................................................................
  1146   1147    *	Eventually pushes data to the contentStack (even in
  1147   1148    *      recurive calls).
  1148   1149    *
  1149   1150    *----------------------------------------------------------------------------
  1150   1151    */
  1151   1152   
  1152   1153   static int
  1153         -TncProbeElement (nameId, tncdata)
  1154         -    TNC_NameId *nameId;
  1155         -    TNC_Data   *tncdata;
         1154  +TncProbeElement (
         1155  +    TNC_NameId *nameId,
         1156  +    TNC_Data   *tncdata
         1157  +)
  1156   1158   {
  1157   1159       TNC_ContentStack *stackelm;
  1158   1160       TNC_Content *activeModel;
  1159   1161       int myStackPtr, zeroMatchPossible, result;
  1160   1162       unsigned int i, seqstartindex;
  1161   1163   
  1162   1164   #ifdef TNC_DEBUG
................................................................................
  1213   1215               if (stackelm->model->quant == XML_CQUANT_NONE ||
  1214   1216                   stackelm->model->quant == XML_CQUANT_OPT) {
  1215   1217                   /*The child cp's type SEQ or CHOICE keep track by
  1216   1218                     themselve about if they are repeated. Because we are
  1217   1219                     here, they don't.  Since the current cp has already
  1218   1220                     matched and isn't multiple, the current cp as a whole
  1219   1221                     is done.  But no contradiction detected, so return
  1220         -                  "search futher" */
         1222  +                  "search further" */
  1221   1223                   return -1;
  1222   1224               }
  1223   1225           }
  1224   1226   
  1225   1227           /* If one of the alternatives within the CHOICE cp is quant
  1226   1228              REP or OPT, it isn't a contradition to the document structure,
  1227   1229              if the cp doesn't match, even if it is quant
................................................................................
  1289   1291                      have a candidat for "zero match". */
  1290   1292                   if (result == -1) {
  1291   1293                       zeroMatchPossible = 1;
  1292   1294                   }
  1293   1295                   tncdata->contentStackPtr--;
  1294   1296               }
  1295   1297           }
  1296         -        /* OK, nobody has claimed a match. Question is: try futher or is
         1298  +        /* OK, nobody has claimed a match. Question is: try further or is
  1297   1299              this a document structure error. */
  1298   1300           if (zeroMatchPossible ||
  1299   1301               stackelm->alreadymatched ||
  1300   1302               stackelm->model->quant == XML_CQUANT_REP ||
  1301   1303               stackelm->model->quant == XML_CQUANT_OPT) {
  1302   1304               return -1;
  1303   1305           }
................................................................................
  1388   1390                       break;
  1389   1391                   }
  1390   1392               }
  1391   1393           }
  1392   1394           if (!stackelm->alreadymatched) {
  1393   1395               if (zeroMatchPossible) {
  1394   1396                   /* The stackelm hasn't matched, but don't have to
  1395         -                   after all.  Return try futher */
         1397  +                   after all.  Return try further */
  1396   1398                   return -1;
  1397   1399               } else {
  1398   1400                   /* No previous match, but at least one child is
  1399   1401                      necessary. Return depends of the quant of the
  1400   1402                      entire seq */
  1401   1403                   if (stackelm->model->quant == XML_CQUANT_NONE ||
  1402   1404                       stackelm->model->quant == XML_CQUANT_PLUS) {
................................................................................
  1416   1418                      child later. Error in document structure. */
  1417   1419                   return 0;
  1418   1420               } else {
  1419   1421                   /* OK, SEQ has matched befor. But after the last match, there
  1420   1422                      where no required (quant NONE or PLUS) childs. */
  1421   1423                   if (stackelm->model->quant == XML_CQUANT_NONE ||
  1422   1424                       stackelm->model->quant == XML_CQUANT_OPT) {
  1423         -                    /* The entire seq isn't multiple. Just look futher. */
         1425  +                    /* The entire seq isn't multiple. Just look further. */
  1424   1426                       return -1;
  1425   1427                   }
  1426   1428               }
  1427   1429           }
  1428   1430           /* The last untreated case is alreadymatched true,
  1429   1431              zeroMatchPossible (of the rest of the seq childs after the
  1430   1432              last match) true and the entire seq may be
  1431   1433              multiple. Therefore start again with activeChild = 0, to
  1432   1434              see, if the current nameId starts a repeated match of the
  1433         -           seq.  By the way: zeroMatchPossible still has inital value
  1434         -           1, therefor no second initaliation is needed */
         1435  +           seq.  By the way: zeroMatchPossible still has initial value
         1436  +           1, therefor no second initialiation is needed */
  1435   1437           for (i = 0; i < seqstartindex; i++) {
  1436   1438               if ((&stackelm->model->children[i])->type == XML_CTYPE_NAME) {
  1437   1439                   if ((&stackelm->model->children[i])->nameId == nameId) {
  1438   1440   #ifdef TNC_DEBUG
  1439   1441                       printf ("-->matched! child Nr. %d\n",i);
  1440   1442   #endif
  1441   1443                       (&tncdata->contentStack[myStackPtr])->activeChild = i;
................................................................................
  1481   1483           }
  1482   1484           /* seq doesn't match again and every seq child from the very first
  1483   1485              up to (not including) the last match aren't required. This last
  1484   1486              fact may be nice to know, but after all since the entire seq have
  1485   1487              matched already ... */
  1486   1488           return -1;
  1487   1489       case XML_CTYPE_NAME:
  1488         -        /* NAME type dosen't occur at top level of a content model and is
         1490  +        /* NAME type doesn't occur at top level of a content model and is
  1489   1491              handled in some "shotcut" way directly in the CHOICE and SEQ cases.
  1490   1492              It's only here to pacify gcc -Wall. */
  1491   1493           printf ("error!!! - in TncProbeElement: XML_CTYPE_NAME shouldn't reached in any case.\n");
  1492   1494       default:
  1493   1495           printf ("error!!! - in TncProbeElement: unknown content type: %d\n",
  1494   1496                   stackelm->model->type);
  1495   1497       }
................................................................................
  1513   1515    * Side effects:
  1514   1516    *	Eventually increments the required attributes counter.
  1515   1517    *
  1516   1518    *----------------------------------------------------------------------------
  1517   1519    */
  1518   1520   
  1519   1521   static int
  1520         -TncProbeAttribute (userData, elemAtts, attrName, attrValue, nrOfreq)
  1521         -    void *userData;
  1522         -    Tcl_HashTable *elemAtts;
  1523         -    char *attrName;
  1524         -    char *attrValue;
  1525         -    int *nrOfreq;
         1522  +TncProbeAttribute (
         1523  +    void *userData,
         1524  +    Tcl_HashTable *elemAtts,
         1525  +    char *attrName,
         1526  +    char *attrValue,
         1527  +    int *nrOfreq
         1528  +)
  1526   1529   {
  1527   1530       TNC_Data *tncdata = (TNC_Data *) userData;
  1528   1531       Tcl_HashEntry *entryPtr;
  1529   1532       TNC_AttDecl *attDecl;
  1530   1533       char *pc, *copy, save;
  1531   1534       int clen, i, start, hnew;
  1532   1535       TNC_EntityInfo *entityInfo;
  1533   1536   
  1534   1537       entryPtr = Tcl_FindHashEntry (elemAtts, attrName);
  1535   1538       if (!entryPtr) {
  1536         -        signalNotValid (userData, TNC_ERROR_UNKOWN_ATTRIBUTE);
         1539  +        signalNotValid (userData, TNC_ERROR_UNKNOWN_ATTRIBUTE);
  1537   1540           return 0;
  1538   1541       }
  1539   1542       /* NOTE: attribute uniqueness per element is a wellformed
  1540   1543                  constrain and therefor done by expat. */
  1541   1544       attDecl = (TNC_AttDecl *) Tcl_GetHashValue (entryPtr);
  1542   1545       switch (attDecl->att_type) {
  1543   1546       case TNC_ATTTYPE_CDATA:
................................................................................
  1769   1772    * Side effects:
  1770   1773    *	Eventually signals application error.
  1771   1774    *
  1772   1775    *----------------------------------------------------------------------------
  1773   1776    */
  1774   1777   
  1775   1778   void
  1776         -TncElementStartCommand (userData, name, atts)
  1777         -    void *userData;
  1778         -    const char *name;
  1779         -    const char **atts;
         1779  +TncElementStartCommand (
         1780  +    void *userData,
         1781  +    const char *name,
         1782  +    const char **atts
         1783  +)
  1780   1784   {
  1781   1785       TNC_Data *tncdata = (TNC_Data *) userData;
  1782   1786       Tcl_HashEntry *entryPtr;
  1783   1787       Tcl_HashTable *elemAtts;
  1784   1788       const char **atPtr;
  1785   1789       TNC_ElemAttInfo *elemAttInfo;
  1786   1790       TNC_Content *model;
................................................................................
  1791   1795   #endif
  1792   1796   
  1793   1797       /* If the document doesn't have a doctype declaration, but the
  1794   1798          user have used the -useForeignDTD 1 feature, the collected
  1795   1799          data out of the provided DTD isn't postprocessed by 
  1796   1800          TncElementStartCommand. We do this now.
  1797   1801          NOTE: Since there wasn't a doctype declaration, there is no
  1798         -       information avaliable which element is expected to be the
         1802  +       information available which element is expected to be the
  1799   1803          document element. Eventually it would be desirable, to set
  1800   1804          this somehow. For now, this means, that every valid subtree
  1801   1805          of the given DTD information is accepted.  */
  1802   1806       if (!tncdata->contentStackPtr && !tncdata->elemContentsRewriten) {
  1803   1807           TncEndDoctypeDeclHandler (userData);
  1804   1808           acceptNoDoctype = 1;
  1805   1809       }
................................................................................
  1810   1814           return;
  1811   1815       }
  1812   1816       model = (TNC_Content *) Tcl_GetHashValue (entryPtr);
  1813   1817   
  1814   1818       switch (model->type) {
  1815   1819       case XML_CTYPE_MIXED:
  1816   1820       case XML_CTYPE_ANY:
  1817         -        tncdata->ignoreWhiteCDATAs = 1;
         1821  +        tncdata->skipWhiteCDATAs = 1;
  1818   1822           tncdata->ignorePCDATA = 1;
  1819   1823           break;
  1820   1824       case XML_CTYPE_EMPTY:
  1821         -        tncdata->ignoreWhiteCDATAs = 0;
         1825  +        tncdata->skipWhiteCDATAs = 0;
  1822   1826           break;
  1823   1827       case XML_CTYPE_CHOICE:
  1824   1828       case XML_CTYPE_SEQ:
  1825         -        tncdata->ignoreWhiteCDATAs = 1;
         1829  +        tncdata->skipWhiteCDATAs = 1;
  1826   1830           tncdata->ignorePCDATA = 0;
  1827   1831           break;
  1828   1832       case XML_CTYPE_NAME:
  1829   1833           break;
  1830   1834       }
  1831   1835   
  1832   1836       if (tncdata->contentStackPtr) {
................................................................................
  1932   1936    *	Let the contentStackPtr point to the last current content
  1933   1937    *      model before the element had started.
  1934   1938    *
  1935   1939    *----------------------------------------------------------------------------
  1936   1940    */
  1937   1941   
  1938   1942   static int
  1939         -TncProbeElementEnd (tncdata)
  1940         -    TNC_Data *tncdata;
         1943  +TncProbeElementEnd (
         1944  +    TNC_Data *tncdata
         1945  +)
  1941   1946   {
  1942   1947       TNC_ContentStack stackelm;
  1943   1948       unsigned int i;
  1944   1949       int zeroMatchPossible, seqstartindex;
  1945   1950   
  1946   1951       stackelm = tncdata->contentStack[tncdata->contentStackPtr - 1];
  1947   1952       switch (stackelm.model->type) {
................................................................................
  2043   2048                       tncdata->contentStackPtr--;
  2044   2049                       return 0;
  2045   2050                   }
  2046   2051               }
  2047   2052           }
  2048   2053           return 1;
  2049   2054       case XML_CTYPE_NAME:
  2050         -        /* NAME type dosen't occur at top level of a content model and is
         2055  +        /* NAME type doesn't occur at top level of a content model and is
  2051   2056              handled in some "shotcut" way directly in the CHOICE and SEQ cases.
  2052   2057              It's only here to pacify gcc -Wall. */
  2053   2058           fprintf (stderr, "error!!! - in TncProbeElementEnd: XML_CTYPE_NAME "
  2054   2059                    "shouldn't be reached in any case.\n");
  2055   2060       default:
  2056   2061           fprintf (stderr, "error!!! - in TncProbeElementEnd: unknown content "
  2057   2062                    "type: %d\n", stackelm.model->type);
................................................................................
  2076   2081    * Side effects:
  2077   2082    *	Eventually signals application error.
  2078   2083    *
  2079   2084    *----------------------------------------------------------------------------
  2080   2085    */
  2081   2086   
  2082   2087   void
  2083         -TncElementEndCommand (userData, name)
  2084         -    void       *userData;
  2085         -    const char *name;
         2088  +TncElementEndCommand (
         2089  +    void       *userData,
         2090  +    const char *name
         2091  +)
  2086   2092   {
  2087   2093       TNC_Data *tncdata = (TNC_Data *) userData;
  2088   2094       Tcl_HashEntry *entryPtr;
  2089   2095       Tcl_HashSearch search;
  2090   2096   
  2091   2097   #ifdef TNC_DEBUG
  2092   2098       printf ("TncElementEndCommand start\n");
  2093   2099       printContentStack (tncdata);
  2094   2100   #endif
  2095   2101       while (1) {
  2096         -        if (!TncProbeElementEnd (tncdata, 0)) {
         2102  +        if (!TncProbeElementEnd (tncdata)) {
  2097   2103               signalNotValid (userData, TNC_ERROR_ELEMENT_CAN_NOT_END_HERE);
  2098   2104               return;
  2099   2105           }
  2100   2106           if (tncdata->contentStack[tncdata->contentStackPtr - 1].deep == 0) {
  2101   2107               break;
  2102   2108           }
  2103   2109           tncdata->contentStackPtr--;
................................................................................
  2108   2114       printf ("after removing ended element from the stack\n");
  2109   2115       printContentStack (tncdata);
  2110   2116   #endif
  2111   2117       if (tncdata->contentStackPtr) {
  2112   2118           switch ((&tncdata->contentStack[tncdata->contentStackPtr - 1])->model->type) {
  2113   2119           case XML_CTYPE_MIXED:
  2114   2120           case XML_CTYPE_ANY:
  2115         -            tncdata->ignoreWhiteCDATAs = 1;
         2121  +            tncdata->skipWhiteCDATAs = 1;
  2116   2122               tncdata->ignorePCDATA = 1;
  2117   2123               break;
  2118   2124           case XML_CTYPE_EMPTY:
  2119         -            tncdata->ignoreWhiteCDATAs = 0;
         2125  +            tncdata->skipWhiteCDATAs = 0;
  2120   2126               break;
  2121   2127           case XML_CTYPE_CHOICE:
  2122   2128           case XML_CTYPE_SEQ:
  2123   2129           case XML_CTYPE_NAME:
  2124         -            tncdata->ignoreWhiteCDATAs = 1;
         2130  +            tncdata->skipWhiteCDATAs = 1;
  2125   2131               tncdata->ignorePCDATA = 0;
  2126   2132               break;
  2127   2133           }
  2128   2134       } else {
  2129   2135           /* This means, the root element is closed,
  2130   2136              therefor the place to check, if every IDREF points
  2131   2137              to a ID. */
................................................................................
  2135   2141                    entryPtr = Tcl_NextHashEntry (&search)) {
  2136   2142   #ifdef TNC_DEBUG
  2137   2143                   printf ("check id value %s\n",
  2138   2144                           Tcl_GetHashKey (tncdata->ids, entryPtr));
  2139   2145                   printf ("value %p\n", Tcl_GetHashValue (entryPtr));
  2140   2146   #endif
  2141   2147                   if (!Tcl_GetHashValue (entryPtr)) {
  2142         -                    signalNotValid (userData, TNC_ERROR_UNKOWN_ID_REFERRED);
         2148  +                    signalNotValid (userData, TNC_ERROR_UNKNOWN_ID_REFERRED);
  2143   2149                   return;
  2144   2150                   }
  2145   2151               }
  2146   2152           }
  2147   2153       }
  2148   2154   }
  2149   2155   
................................................................................
  2161   2167    * Side effects:
  2162   2168    *	Eventually signals application error.
  2163   2169    *
  2164   2170    *----------------------------------------------------------------------------
  2165   2171    */
  2166   2172   
  2167   2173   void
  2168         -TncCharacterdataCommand (userData, data, len)
  2169         -    void       *userData;
  2170         -    const char *data;
  2171         -    int         len;
         2174  +TncCharacterdataCommand (
         2175  +    void       *userData,
         2176  +    const char *data,
         2177  +    int         len
         2178  +)
  2172   2179   {
  2173   2180       TNC_Data *tncdata = (TNC_Data *) userData;
  2174   2181       int i;
  2175   2182       char *pc;
  2176   2183   
  2177         -    if (!tncdata->ignoreWhiteCDATAs && len > 0) {
         2184  +    if (!tncdata->skipWhiteCDATAs && len > 0) {
  2178   2185           signalNotValid (userData, TNC_ERROR_EMPTY_ELEMENT);
  2179   2186           return;
  2180   2187       }
  2181   2188       if (!tncdata->ignorePCDATA) {
  2182   2189           for (i = 0, pc = (char*)data; i < len; i++, pc++) {
  2183   2190               if ( (*pc == ' ')  ||
  2184   2191                    (*pc == '\n') ||
................................................................................
  2206   2213    * Side effects:
  2207   2214    *	Eventually signals application error.
  2208   2215    *
  2209   2216    *----------------------------------------------------------------------------
  2210   2217    */
  2211   2218   
  2212   2219   void
  2213         -TncStartCdataSectionHandler (userData)
  2214         -    void *userData;
         2220  +TncStartCdataSectionHandler (
         2221  +    void *userData
         2222  +)
  2215   2223   {
  2216   2224       TNC_Data *tncdata = (TNC_Data *) userData;
  2217   2225   
  2218   2226       if (!tncdata->ignorePCDATA) {
  2219   2227           signalNotValid (userData, TNC_ERROR_DISALLOWED_CDATA);
  2220   2228       }
  2221   2229   }
................................................................................
  2297   2305       )
  2298   2306   {
  2299   2307       domNode       *child;
  2300   2308   
  2301   2309       switch (node->nodeType) {
  2302   2310       case ELEMENT_NODE:
  2303   2311           TncElementStartCommand (tncdata, node->nodeName, NULL);
  2304         -        if (tncdata->status) return 0;
         2312  +        if (tncdata->dtdstatus) return 0;
  2305   2313           if (!validateNodeAttributes (tncdata, tncdata->elemAttInfo, node)) 
  2306   2314               return 0;
  2307   2315           if (node->firstChild) {
  2308   2316               child = node->firstChild;
  2309   2317               while (child) {
  2310   2318                   if (!validateTree (tncdata, child)) return 0;
  2311   2319                   child = child->nextSibling;
  2312   2320               }
  2313   2321           }
  2314   2322           TncElementEndCommand (tncdata, node->nodeName);
  2315         -        if (tncdata->status) return 0;
         2323  +        if (tncdata->dtdstatus) return 0;
  2316   2324           break;
  2317   2325       case TEXT_NODE:
  2318   2326       case CDATA_SECTION_NODE:
  2319   2327           TncCharacterdataCommand (tncdata, ((domTextNode*)node)->nodeValue, 
  2320   2328                                    ((domTextNode*)node)->valueLength);
  2321         -        if (tncdata->status) return 0;
         2329  +        if (tncdata->dtdstatus) return 0;
  2322   2330           break;
  2323   2331       case COMMENT_NODE:
  2324   2332       case PROCESSING_INSTRUCTION_NODE:
  2325   2333           break;
  2326   2334       default:
  2327   2335           signalNotValid (tncdata, TNC_ERROR_UNKNOWN_NODE_TYPE);
  2328   2336           return 0;
................................................................................
  2349   2357    */
  2350   2358   
  2351   2359   static int
  2352   2360   tnc_ValidateObjCmd (
  2353   2361       ClientData  clientData,
  2354   2362       Tcl_Interp *interp,
  2355   2363       int         objc,
  2356         -    Tcl_Obj    *CONST objv[]
         2364  +    Tcl_Obj    *const objv[]
  2357   2365       )
  2358   2366   {
  2359   2367       TNC_Data        *tncdata = (TNC_Data*) clientData;
  2360   2368       int              methodIndex, result = 1;
  2361   2369       domNode         *node;
  2362   2370       char            *errMsg = NULL;
  2363   2371       Tcl_HashEntry   *entryPtr;
  2364   2372       TNC_Content     *model;
  2365   2373       
  2366         -    static CONST84 char *validateMethods[] = {
         2374  +    static const char *validateMethods[] = {
  2367   2375           "validateTree",   "validateDocument", "validateAttributes",
  2368   2376           "delete",
  2369   2377           NULL
  2370   2378       };
  2371   2379       enum validateMethod {
  2372   2380           m_validateTree, m_validateDocument, m_validateAttributes,
  2373   2381           m_delete
................................................................................
  2394   2402           node = tcldom_getNodeFromName (
  2395   2403               interp, Tcl_GetStringFromObj(objv[2], NULL), &errMsg
  2396   2404               );
  2397   2405           if (!node || (node->nodeType != ELEMENT_NODE)) {
  2398   2406               SetResult ("The validateTree method needs a domNode as argument.");
  2399   2407               return TCL_ERROR;
  2400   2408           }
  2401         -        tncdata->status = 0;
         2409  +        tncdata->dtdstatus = 0;
  2402   2410           tncdata->idCheck = 0;
  2403   2411           if (tncdata->ids->numEntries) {
  2404   2412               Tcl_DeleteHashTable (tncdata->ids);
  2405   2413               Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
  2406   2414           }
  2407   2415           tncdata->contentStackPtr = 0;
  2408   2416           Tcl_ResetResult (interp);
................................................................................
  2460   2468                                       "couldn't save msg in variable", -1);
  2461   2469                       return TCL_ERROR;
  2462   2470                   }
  2463   2471               }
  2464   2472               SetBooleanResult (0);
  2465   2473               return TCL_OK;
  2466   2474           }
  2467         -        tncdata->status = 0;
         2475  +        tncdata->dtdstatus = 0;
  2468   2476           tncdata->idCheck = 1;
  2469   2477           if (tncdata->ids->numEntries) {
  2470   2478               Tcl_DeleteHashTable (tncdata->ids);
  2471   2479               Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
  2472   2480           }
  2473   2481           tncdata->contentStackPtr = 0;
  2474   2482           Tcl_ResetResult (interp);
................................................................................
  2513   2521                       return TCL_ERROR;
  2514   2522                   }
  2515   2523               }
  2516   2524               SetBooleanResult (0);
  2517   2525               return TCL_OK;
  2518   2526           }
  2519   2527           model = (TNC_Content *) Tcl_GetHashValue (entryPtr);
  2520         -        tncdata->status = 0;
         2528  +        tncdata->dtdstatus = 0;
  2521   2529           tncdata->idCheck = 0;
  2522   2530           if (tncdata->ids->numEntries) {
  2523   2531               Tcl_DeleteHashTable (tncdata->ids);
  2524   2532               Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
  2525   2533           }
  2526   2534           Tcl_ResetResult (interp);
  2527   2535           result = validateNodeAttributes (tncdata, model->attInfo, node);
................................................................................
  2566   2574    *	None.
  2567   2575    *
  2568   2576    * Side effects:
  2569   2577    *	Frees memory.
  2570   2578    *
  2571   2579    *---------------------------------------------------------------------------- */
  2572   2580   static void
  2573         -FreeTncData (tncdata)
  2574         -    TNC_Data *tncdata;
         2581  +FreeTncData (
         2582  +    TNC_Data *tncdata
         2583  +)
  2575   2584   {
  2576   2585       Tcl_HashEntry *entryPtr, *attentryPtr;
  2577   2586       Tcl_HashSearch search, attsearch;
  2578   2587       TNC_Content *model;
  2579   2588       TNC_ElemAttInfo *elemAttInfo;
  2580   2589       TNC_EntityInfo *entityInfo;
  2581   2590       TNC_AttDecl *attDecl;
................................................................................
  2654   2663    * Side effects:
  2655   2664    *	Resets the "userData" of the C handler set parser extension.
  2656   2665    *
  2657   2666    *----------------------------------------------------------------------------
  2658   2667    */
  2659   2668   
  2660   2669   void
  2661         -TncResetProc (interp, userData)
  2662         -    Tcl_Interp *interp;
  2663         -    void *userData;
         2670  +TncResetProc (
         2671  +    Tcl_Interp *interp,
         2672  +    void *userData
         2673  +)
  2664   2674   {
  2665   2675       TNC_Data *tncdata = (TNC_Data *) userData;
  2666   2676   
  2667   2677       FreeTncData (tncdata);
  2668   2678       Tcl_InitHashTable (tncdata->tagNames, TCL_STRING_KEYS);
  2669   2679       tncdata->elemContentsRewriten = 0;
  2670         -    tncdata->status = 0;
         2680  +    tncdata->dtdstatus = 0;
  2671   2681       tncdata->idCheck = 1;
  2672   2682       Tcl_InitHashTable (tncdata->attDefsTables, TCL_STRING_KEYS);
  2673   2683       Tcl_InitHashTable (tncdata->entityDecls, TCL_STRING_KEYS);
  2674   2684       Tcl_InitHashTable (tncdata->notationDecls, TCL_STRING_KEYS);
  2675   2685       Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
  2676   2686       tncdata->doctypeName = NULL;
  2677         -    tncdata->ignoreWhiteCDATAs = 1;
         2687  +    tncdata->skipWhiteCDATAs = 1;
  2678   2688       tncdata->ignorePCDATA = 0;
  2679   2689       tncdata->contentStackPtr = 0;
  2680   2690   }
  2681   2691   
  2682   2692   /*
  2683   2693    *----------------------------------------------------------------------------
  2684   2694    *
................................................................................
  2703   2713   {
  2704   2714       TNC_Data *tncdata;
  2705   2715       
  2706   2716       tncdata = (TNC_Data *) MALLOC (sizeof (TNC_Data));
  2707   2717       tncdata->tagNames = (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
  2708   2718       Tcl_InitHashTable (tncdata->tagNames, TCL_STRING_KEYS);
  2709   2719       tncdata->elemContentsRewriten = 0;
  2710         -    tncdata->status = 0;
         2720  +    tncdata->dtdstatus = 0;
  2711   2721       tncdata->idCheck = 1;
  2712   2722       tncdata->attDefsTables = 
  2713   2723           (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
  2714   2724       Tcl_InitHashTable (tncdata->attDefsTables, TCL_STRING_KEYS);
  2715   2725       tncdata->entityDecls = 
  2716   2726           (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
  2717   2727       Tcl_InitHashTable (tncdata->entityDecls, TCL_STRING_KEYS);
................................................................................
  2719   2729           (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
  2720   2730       Tcl_InitHashTable (tncdata->notationDecls, TCL_STRING_KEYS);
  2721   2731       tncdata->ids = (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
  2722   2732       Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
  2723   2733       tncdata->doctypeName = NULL;
  2724   2734       tncdata->interp = interp;
  2725   2735       tncdata->expatObj = expatObj;
  2726         -    tncdata->ignoreWhiteCDATAs = 1;
         2736  +    tncdata->skipWhiteCDATAs = 1;
  2727   2737       tncdata->ignorePCDATA = 0;
  2728   2738       tncdata->contentStack = (TNC_ContentStack *)
  2729   2739           MALLOC (sizeof (TNC_ContentStack) * TNC_INITCONTENTSTACKSIZE);
  2730   2740       tncdata->contentStackSize = TNC_INITCONTENTSTACKSIZE;
  2731   2741       tncdata->contentStackPtr = 0;
  2732   2742       
  2733   2743       return tncdata;
................................................................................
  2747   2757    * Side effects:
  2748   2758    *	C handler set specific userData gets free'd.
  2749   2759    *
  2750   2760    *----------------------------------------------------------------------------
  2751   2761    */
  2752   2762   
  2753   2763   void
  2754         -TncFreeProc (interp, userData)
  2755         -    Tcl_Interp *interp;
  2756         -    void *userData;
         2764  +TncFreeProc (
         2765  +    Tcl_Interp *interp,
         2766  +    void *userData
         2767  +)
  2757   2768   {
  2758   2769       TNC_Data *tncdata = (TNC_Data *) userData;
  2759   2770   
  2760   2771       FreeTncData (tncdata);
  2761   2772       FREE ((char *) tncdata->tagNames);
  2762   2773       FREE ((char *) tncdata->attDefsTables);
  2763   2774       FREE ((char *) tncdata->entityDecls);
................................................................................
  2813   2824    */
  2814   2825   
  2815   2826   int
  2816   2827   TclTncObjCmd(dummy, interp, objc, objv)
  2817   2828        ClientData dummy;
  2818   2829        Tcl_Interp *interp;
  2819   2830        int objc;
  2820         -     Tcl_Obj *CONST objv[];
         2831  +     Tcl_Obj *const objv[];
  2821   2832   {
  2822         -    char          *method, *cmdName, s[20];
         2833  +    char          *cmdName, s[20];
  2823   2834       CHandlerSet   *handlerSet;
  2824   2835       int            methodIndex, result;
  2825   2836       TNC_Data      *tncdata;
  2826   2837   
  2827         -    static CONST84 char *tncMethods[] = {
         2838  +    static const char *tncMethods[] = {
  2828   2839           "enable",  "remove", "getValidateCmd",
  2829   2840           NULL
  2830   2841       };
  2831   2842       enum tncMethod {
  2832   2843           m_enable, m_remove, m_getValidateCmd
  2833   2844       };
  2834   2845   
  2835   2846       if (!CheckExpatParserObj (interp, objv[1])) {
  2836   2847           SetResult ("First argument has to be a expat parser object");
  2837   2848           return TCL_ERROR;
  2838   2849       }
  2839   2850   
  2840         -    method = Tcl_GetStringFromObj (objv[2], NULL);
  2841   2851       if (Tcl_GetIndexFromObj (interp, objv[2], tncMethods, "method", 0,
  2842   2852                                &methodIndex) != TCL_OK)
  2843   2853       {
  2844   2854           return TCL_ERROR;
  2845   2855       }
  2846   2856   
  2847   2857       switch ((enum tncMethod) methodIndex) {
................................................................................
  2901   2911           }
  2902   2912           handlerSet = CHandlerSetGet (interp, objv[1], "tnc");
  2903   2913           if (!handlerSet) {
  2904   2914               SetResult("expat parser obj hasn't a C handler set named \"tnc\"");
  2905   2915               return TCL_ERROR;
  2906   2916           }
  2907   2917           tncdata = (TNC_Data *) handlerSet->userData;
  2908         -        if (!tncdata->status) {
         2918  +        if (!tncdata->dtdstatus) {
  2909   2919               SetResult ("No complete and error free DTD data available.");
  2910   2920               return TCL_ERROR;
  2911   2921           }
  2912   2922           /* After we finished, the validator structure is its own command,
  2913   2923              there isn't a parser cmd anymore. */
  2914   2924           tncdata->expatObj = NULL;
  2915         -        tncdata->status = 0;
         2925  +        tncdata->dtdstatus = 0;
  2916   2926           handlerSet->userData = createTncData (interp, objv[1]);
  2917   2927           if (objc == 4) {
  2918   2928               cmdName = Tcl_GetStringFromObj (objv[3], NULL);
  2919   2929           } else {
  2920   2930               FindUniqueCmdName (interp, s);
  2921   2931               cmdName = s;
  2922   2932           }
................................................................................
  2950   2960    *
  2951   2961    * Side effects:
  2952   2962    *	Defines "tnc" enhancement command for expat parser obj
  2953   2963    *
  2954   2964    *----------------------------------------------------------------------------
  2955   2965    */
  2956   2966   
  2957         -#if defined(_MSC_VER)
         2967  +#if defined(_MSC_VER) || defined(__MINGW32__) 
  2958   2968   #  undef TCL_STORAGE_CLASS
  2959   2969   #  define TCL_STORAGE_CLASS DLLEXPORT
  2960   2970   #endif
  2961   2971   
  2962   2972   EXTERN int
  2963   2973   Tnc_Init (interp)
  2964   2974       Tcl_Interp *interp;
................................................................................
  2969   2979       }
  2970   2980   #endif
  2971   2981   #ifdef USE_TDOM_STUBS
  2972   2982       if (Tdom_InitStubs(interp, "0.8", 0) == NULL) {
  2973   2983           return TCL_ERROR;
  2974   2984       }
  2975   2985   #endif
  2976         -    Tcl_PkgRequire (interp, "tdom", "0.8.0", 0);
         2986  +    Tcl_PkgRequire (interp, "tdom", NULL, 0);
  2977   2987       Tcl_CreateObjCommand (interp, "tnc", TclTncObjCmd, NULL, NULL );
  2978   2988       Tcl_PkgProvide (interp, "tnc", PACKAGE_VERSION);
  2979   2989       return TCL_OK;
  2980   2990   }
  2981   2991   

Added extensions/tnc/win/makefile.vc.

            1  +#------------------------------------------------------------- -*- makefile -*-
            2  +#
            3  +# Makefile for tnc
            4  +#
            5  +# Basic build, test and install
            6  +#   nmake /f makefile.vc INSTALLDIR=c:\tcl
            7  +#   nmake /f makefile.vc INSTALLDIR=c:\tcl test
            8  +#   nmake /f makefile.vc INSTALLDIR=c:\tcl install
            9  +#
           10  +# For other build options (debug, static etc.),
           11  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
           12  +# detailed documentation.
           13  +# 
           14  +# See the file "license.terms" for information on usage and redistribution
           15  +# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
           16  +#
           17  +#------------------------------------------------------------------------------
           18  +
           19  +
           20  +PROJECT = tnc
           21  +!include "rules-ext.vc"
           22  +
           23  +PRJ_OBJS = $(TMP_DIR)\tnc.obj
           24  +
           25  +!if [echo TDOM_DOTVERSION = \> versions.vc] \
           26  +   || [nmakehlp -V ..\..\..\configure.in ^[tdom^] >> versions.vc]
           27  +!error *** Could not figure out tdom version.
           28  +!endif
           29  +!include versions.vc
           30  +TDOMVER             = $(TDOM_DOTVERSION:.=)
           31  +
           32  +# tdom root
           33  +TDOMROOT            = ..\..\..
           34  +
           35  +PRJ_DEFINES = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE \
           36  +	-DHAVE_MEMMOVE=1 -DXML_DTD=1 -DXML_NS=1 -DTDOM_NO_UNKNOWN_CMD=1 \
           37  +!if !$(STATIC_BUILD)
           38  +	-DUSE_TDOM_STUBS
           39  +!endif
           40  +
           41  +TDOMLIBPATH    = "$(TDOMROOT)\win\$(BUILDDIRTOP)"
           42  +
           43  +PRJ_INCLUDES = -I$(TDOMROOT)\generic -I$(TDOMROOT)\expat
           44  +
           45  +TNCDIR         = $(TDOMROOT)\extensions\tnc
           46  +
           47  +!if !$(STATIC_BUILD)
           48  +PRJ_LIBS  = $(TDOMLIBPATH)\tdomstub$(TDOMVER).lib
           49  +!endif
           50  +
           51  +!include "$(_RULESDIR)\targets.vc"
           52  +pkgindex: default-pkgindex
           53  +

Added extensions/tnc/win/nmakehlp.c.

            1  +/*
            2  + * ----------------------------------------------------------------------------
            3  + * nmakehlp.c --
            4  + *
            5  + *	This is used to fix limitations within nmake and the environment.
            6  + *
            7  + * Copyright (c) 2002 by David Gravereaux.
            8  + * Copyright (c) 2006 by Pat Thoyts
            9  + *
           10  + * See the file "license.terms" for information on usage and redistribution of
           11  + * this file, and for a DISCLAIMER OF ALL WARRANTIES.
           12  + * ----------------------------------------------------------------------------
           13  + */
           14  +
           15  +#define _CRT_SECURE_NO_DEPRECATE
           16  +#include <windows.h>
           17  +#define NO_SHLWAPI_GDI
           18  +#define NO_SHLWAPI_STREAM
           19  +#define NO_SHLWAPI_REG
           20  +#include <shlwapi.h>
           21  +#pragma comment (lib, "user32.lib")
           22  +#pragma comment (lib, "kernel32.lib")
           23  +#pragma comment (lib, "shlwapi.lib")
           24  +#include <stdio.h>
           25  +#include <math.h>
           26  +
           27  +/*
           28  + * This library is required for x64 builds with _some_ versions of MSVC
           29  + */
           30  +#if defined(_M_IA64) || defined(_M_AMD64)
           31  +#if _MSC_VER >= 1400 && _MSC_VER < 1500
           32  +#pragma comment(lib, "bufferoverflowU")
           33  +#endif
           34  +#endif
           35  +
           36  +/* ISO hack for dumb VC++ */
           37  +#ifdef _MSC_VER
           38  +#define   snprintf	_snprintf
           39  +#endif
           40  +
           41  +
           42  +/* protos */
           43  +
           44  +static int CheckForCompilerFeature(const char *option);
           45  +static int CheckForLinkerFeature(const char **options, int count);
           46  +static int IsIn(const char *string, const char *substring);
           47  +static int SubstituteFile(const char *substs, const char *filename);
           48  +static int QualifyPath(const char *path);
           49  +static int LocateDependency(const char *keyfile);
           50  +static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
           51  +static DWORD WINAPI ReadFromPipe(LPVOID args);
           52  +
           53  +/* globals */
           54  +
           55  +#define CHUNK	25
           56  +#define STATICBUFFERSIZE    1000
           57  +typedef struct {
           58  +    HANDLE pipe;
           59  +    char buffer[STATICBUFFERSIZE];
           60  +} pipeinfo;
           61  +
           62  +pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
           63  +pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
           64  +
           65  +/*
           66  + * exitcodes: 0 == no, 1 == yes, 2 == error
           67  + */
           68  +
           69  +int
           70  +main(
           71  +    int argc,
           72  +    char *argv[])
           73  +{
           74  +    char msg[300];
           75  +    DWORD dwWritten;
           76  +    int chars;
           77  +    char *s;
           78  +
           79  +    /*
           80  +     * Make sure children (cl.exe and link.exe) are kept quiet.
           81  +     */
           82  +
           83  +    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
           84  +
           85  +    /*
           86  +     * Make sure the compiler and linker aren't effected by the outside world.
           87  +     */
           88  +
           89  +    SetEnvironmentVariable("CL", "");
           90  +    SetEnvironmentVariable("LINK", "");
           91  +
           92  +    if (argc > 1 && *argv[1] == '-') {
           93  +	switch (*(argv[1]+1)) {
           94  +	case 'c':
           95  +	    if (argc != 3) {
           96  +		chars = snprintf(msg, sizeof(msg) - 1,
           97  +		        "usage: %s -c <compiler option>\n"
           98  +			"Tests for whether cl.exe supports an option\n"
           99  +			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
          100  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          101  +			&dwWritten, NULL);
          102  +		return 2;
          103  +	    }
          104  +	    return CheckForCompilerFeature(argv[2]);
          105  +	case 'l':
          106  +	    if (argc < 3) {
          107  +		chars = snprintf(msg, sizeof(msg) - 1,
          108  +	       		"usage: %s -l <linker option> ?<mandatory option> ...?\n"
          109  +			"Tests for whether link.exe supports an option\n"
          110  +			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
          111  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          112  +			&dwWritten, NULL);
          113  +		return 2;
          114  +	    }
          115  +	    return CheckForLinkerFeature(&argv[2], argc-2);
          116  +	case 'f':
          117  +	    if (argc == 2) {
          118  +		chars = snprintf(msg, sizeof(msg) - 1,
          119  +			"usage: %s -f <string> <substring>\n"
          120  +			"Find a substring within another\n"
          121  +			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
          122  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          123  +			&dwWritten, NULL);
          124  +		return 2;
          125  +	    } else if (argc == 3) {
          126  +		/*
          127  +		 * If the string is blank, there is no match.
          128  +		 */
          129  +
          130  +		return 0;
          131  +	    } else {
          132  +		return IsIn(argv[2], argv[3]);
          133  +	    }
          134  +	case 's':
          135  +	    if (argc == 2) {
          136  +		chars = snprintf(msg, sizeof(msg) - 1,
          137  +			"usage: %s -s <substitutions file> <file>\n"
          138  +			"Perform a set of string map type substutitions on a file\n"
          139  +			"exitcodes: 0\n",
          140  +			argv[0]);
          141  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          142  +			&dwWritten, NULL);
          143  +		return 2;
          144  +	    }
          145  +	    return SubstituteFile(argv[2], argv[3]);
          146  +	case 'V':
          147  +	    if (argc != 4) {
          148  +		chars = snprintf(msg, sizeof(msg) - 1,
          149  +		    "usage: %s -V filename matchstring\n"
          150  +		    "Extract a version from a file:\n"
          151  +		    "eg: pkgIndex.tcl \"package ifneeded http\"",
          152  +		    argv[0]);
          153  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          154  +		    &dwWritten, NULL);
          155  +		return 0;
          156  +	    }
          157  +	    s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
          158  +	    if (s && *s) {
          159  +		printf("%s\n", s);
          160  +		return 0;
          161  +	    } else
          162  +		return 1; /* Version not found. Return non-0 exit code */
          163  +
          164  +	case 'Q':
          165  +	    if (argc != 3) {
          166  +		chars = snprintf(msg, sizeof(msg) - 1,
          167  +		    "usage: %s -Q path\n"
          168  +		    "Emit the fully qualified path\n"
          169  +		    "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
          170  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          171  +		    &dwWritten, NULL);
          172  +		return 2;
          173  +	    }
          174  +	    return QualifyPath(argv[2]);
          175  +
          176  +	case 'L':
          177  +	    if (argc != 3) {
          178  +		chars = snprintf(msg, sizeof(msg) - 1,
          179  +		    "usage: %s -L keypath\n"
          180  +		    "Emit the fully qualified path of directory containing keypath\n"
          181  +		    "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
          182  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          183  +		    &dwWritten, NULL);
          184  +		return 2;
          185  +	    }
          186  +	    return LocateDependency(argv[2]);
          187  +	}
          188  +    }
          189  +    chars = snprintf(msg, sizeof(msg) - 1,
          190  +	    "usage: %s -c|-f|-l|-Q|-s|-V ...\n"
          191  +	    "This is a little helper app to equalize shell differences between WinNT and\n"
          192  +	    "Win9x and get nmake.exe to accomplish its job.\n",
          193  +	    argv[0]);
          194  +    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
          195  +    return 2;
          196  +}
          197  +
          198  +static int
          199  +CheckForCompilerFeature(
          200  +    const char *option)
          201  +{
          202  +    STARTUPINFO si;
          203  +    PROCESS_INFORMATION pi;
          204  +    SECURITY_ATTRIBUTES sa;
          205  +    DWORD threadID;
          206  +    char msg[300];
          207  +    BOOL ok;
          208  +    HANDLE hProcess, h, pipeThreads[2];
          209  +    char cmdline[100];
          210  +
          211  +    hProcess = GetCurrentProcess();
          212  +
          213  +    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
          214  +    ZeroMemory(&si, sizeof(STARTUPINFO));
          215  +    si.cb = sizeof(STARTUPINFO);
          216  +    si.dwFlags   = STARTF_USESTDHANDLES;
          217  +    si.hStdInput = INVALID_HANDLE_VALUE;
          218  +
          219  +    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
          220  +    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
          221  +    sa.lpSecurityDescriptor = NULL;
          222  +    sa.bInheritHandle = FALSE;
          223  +
          224  +    /*
          225  +     * Create a non-inheritible pipe.
          226  +     */
          227  +
          228  +    CreatePipe(&Out.pipe, &h, &sa, 0);
          229  +
          230  +    /*
          231  +     * Dupe the write side, make it inheritible, and close the original.
          232  +     */
          233  +
          234  +    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
          235  +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          236  +
          237  +    /*
          238  +     * Same as above, but for the error side.
          239  +     */
          240  +
          241  +    CreatePipe(&Err.pipe, &h, &sa, 0);
          242  +    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
          243  +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          244  +
          245  +    /*
          246  +     * Base command line.
          247  +     */
          248  +
          249  +    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
          250  +
          251  +    /*
          252  +     * Append our option for testing
          253  +     */
          254  +
          255  +    lstrcat(cmdline, option);
          256  +
          257  +    /*
          258  +     * Filename to compile, which exists, but is nothing and empty.
          259  +     */
          260  +
          261  +    lstrcat(cmdline, " .\\nul");
          262  +
          263  +    ok = CreateProcess(
          264  +	    NULL,	    /* Module name. */
          265  +	    cmdline,	    /* Command line. */
          266  +	    NULL,	    /* Process handle not inheritable. */
          267  +	    NULL,	    /* Thread handle not inheritable. */
          268  +	    TRUE,	    /* yes, inherit handles. */
          269  +	    DETACHED_PROCESS, /* No console for you. */
          270  +	    NULL,	    /* Use parent's environment block. */
          271  +	    NULL,	    /* Use parent's starting directory. */
          272  +	    &si,	    /* Pointer to STARTUPINFO structure. */
          273  +	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */
          274  +
          275  +    if (!ok) {
          276  +	DWORD err = GetLastError();
          277  +	int chars = snprintf(msg, sizeof(msg) - 1,
          278  +		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
          279  +
          280  +	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
          281  +		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
          282  +		(300-chars), 0);
          283  +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
          284  +	return 2;
          285  +    }
          286  +
          287  +    /*
          288  +     * Close our references to the write handles that have now been inherited.
          289  +     */
          290  +
          291  +    CloseHandle(si.hStdOutput);
          292  +    CloseHandle(si.hStdError);
          293  +
          294  +    WaitForInputIdle(pi.hProcess, 5000);
          295  +    CloseHandle(pi.hThread);
          296  +
          297  +    /*
          298  +     * Start the pipe reader threads.
          299  +     */
          300  +
          301  +    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
          302  +    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
          303  +
          304  +    /*
          305  +     * Block waiting for the process to end.
          306  +     */
          307  +
          308  +    WaitForSingleObject(pi.hProcess, INFINITE);
          309  +    CloseHandle(pi.hProcess);
          310  +
          311  +    /*
          312  +     * Wait for our pipe to get done reading, should it be a little slow.
          313  +     */
          314  +
          315  +    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
          316  +    CloseHandle(pipeThreads[0]);
          317  +    CloseHandle(pipeThreads[1]);
          318  +
          319  +    /*
          320  +     * Look for the commandline warning code in both streams.
          321  +     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
          322  +     */
          323  +
          324  +    return !(strstr(Out.buffer, "D4002") != NULL
          325  +             || strstr(Err.buffer, "D4002") != NULL
          326  +             || strstr(Out.buffer, "D9002") != NULL
          327  +             || strstr(Err.buffer, "D9002") != NULL
          328  +             || strstr(Out.buffer, "D2021") != NULL
          329  +             || strstr(Err.buffer, "D2021") != NULL);
          330  +}
          331  +
          332  +static int
          333  +CheckForLinkerFeature(
          334  +    const char **options,
          335  +    int count)
          336  +{
          337  +    STARTUPINFO si;
          338  +    PROCESS_INFORMATION pi;
          339  +    SECURITY_ATTRIBUTES sa;
          340  +    DWORD threadID;
          341  +    char msg[300];
          342  +    BOOL ok;
          343  +    HANDLE hProcess, h, pipeThreads[2];
          344  +    int i;
          345  +    char cmdline[255];
          346  +
          347  +    hProcess = GetCurrentProcess();
          348  +
          349  +    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
          350  +    ZeroMemory(&si, sizeof(STARTUPINFO));
          351  +    si.cb = sizeof(STARTUPINFO);
          352  +    si.dwFlags   = STARTF_USESTDHANDLES;
          353  +    si.hStdInput = INVALID_HANDLE_VALUE;
          354  +
          355  +    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
          356  +    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
          357  +    sa.lpSecurityDescriptor = NULL;
          358  +    sa.bInheritHandle = TRUE;
          359  +
          360  +    /*
          361  +     * Create a non-inheritible pipe.
          362  +     */
          363  +
          364  +    CreatePipe(&Out.pipe, &h, &sa, 0);
          365  +
          366  +    /*
          367  +     * Dupe the write side, make it inheritible, and close the original.
          368  +     */
          369  +
          370  +    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
          371  +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          372  +
          373  +    /*
          374  +     * Same as above, but for the error side.
          375  +     */
          376  +
          377  +    CreatePipe(&Err.pipe, &h, &sa, 0);
          378  +    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
          379  +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
          380  +
          381  +    /*
          382  +     * Base command line.
          383  +     */
          384  +
          385  +    lstrcpy(cmdline, "link.exe -nologo ");
          386  +
          387  +    /*
          388  +     * Append our option for testing.
          389  +     */
          390  +
          391  +    for (i = 0; i < count; i++) {
          392  +	lstrcat(cmdline, " \"");
          393  +	lstrcat(cmdline, options[i]);
          394  +	lstrcat(cmdline, "\"");
          395  +    }
          396  +
          397  +    ok = CreateProcess(
          398  +	    NULL,	    /* Module name. */
          399  +	    cmdline,	    /* Command line. */
          400  +	    NULL,	    /* Process handle not inheritable. */
          401  +	    NULL,	    /* Thread handle not inheritable. */
          402  +	    TRUE,	    /* yes, inherit handles. */
          403  +	    DETACHED_PROCESS, /* No console for you. */
          404  +	    NULL,	    /* Use parent's environment block. */
          405  +	    NULL,	    /* Use parent's starting directory. */
          406  +	    &si,	    /* Pointer to STARTUPINFO structure. */
          407  +	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */
          408  +
          409  +    if (!ok) {
          410  +	DWORD err = GetLastError();
          411  +	int chars = snprintf(msg, sizeof(msg) - 1,
          412  +		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
          413  +
          414  +	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
          415  +		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
          416  +		(300-chars), 0);
          417  +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
          418  +	return 2;
          419  +    }
          420  +
          421  +    /*
          422  +     * Close our references to the write handles that have now been inherited.
          423  +     */
          424  +
          425  +    CloseHandle(si.hStdOutput);
          426  +    CloseHandle(si.hStdError);
          427  +
          428  +    WaitForInputIdle(pi.hProcess, 5000);
          429  +    CloseHandle(pi.hThread);
          430  +
          431  +    /*
          432  +     * Start the pipe reader threads.
          433  +     */
          434  +
          435  +    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
          436  +    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
          437  +
          438  +    /*
          439  +     * Block waiting for the process to end.
          440  +     */
          441  +
          442  +    WaitForSingleObject(pi.hProcess, INFINITE);
          443  +    CloseHandle(pi.hProcess);
          444  +
          445  +    /*
          446  +     * Wait for our pipe to get done reading, should it be a little slow.
          447  +     */
          448  +
          449  +    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
          450  +    CloseHandle(pipeThreads[0]);
          451  +    CloseHandle(pipeThreads[1]);
          452  +
          453  +    /*
          454  +     * Look for the commandline warning code in the stderr stream.
          455  +     */
          456  +
          457  +    return !(strstr(Out.buffer, "LNK1117") != NULL ||
          458  +	    strstr(Err.buffer, "LNK1117") != NULL ||
          459  +	    strstr(Out.buffer, "LNK4044") != NULL ||
          460  +	    strstr(Err.buffer, "LNK4044") != NULL ||
          461  +	    strstr(Out.buffer, "LNK4224") != NULL ||
          462  +	    strstr(Err.buffer, "LNK4224") != NULL);
          463  +}
          464  +
          465  +static DWORD WINAPI
          466  +ReadFromPipe(
          467  +    LPVOID args)
          468  +{
          469  +    pipeinfo *pi = (pipeinfo *) args;
          470  +    char *lastBuf = pi->buffer;
          471  +    DWORD dwRead;
          472  +    BOOL ok;
          473  +
          474  +  again:
          475  +    if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
          476  +	CloseHandle(pi->pipe);
          477  +	return (DWORD)-1;
          478  +    }
          479  +    ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
          480  +    if (!ok || dwRead == 0) {
          481  +	CloseHandle(pi->pipe);
          482  +	return 0;
          483  +    }
          484  +    lastBuf += dwRead;
          485  +    goto again;
          486  +
          487  +    return 0;  /* makes the compiler happy */
          488  +}
          489  +
          490  +static int
          491  +IsIn(
          492  +    const char *string,
          493  +    const char *substring)
          494  +{
          495  +    return (strstr(string, substring) != NULL);
          496  +}
          497  +
          498  +/*
          499  + * GetVersionFromFile --
          500  + * 	Looks for a match string in a file and then returns the version
          501  + * 	following the match where a version is anything acceptable to
          502  + * 	package provide or package ifneeded.
          503  + */
          504  +
          505  +static const char *
          506  +GetVersionFromFile(
          507  +    const char *filename,
          508  +    const char *match,
          509  +    int numdots)
          510  +{
          511  +    size_t cbBuffer = 100;
          512  +    static char szBuffer[100];
          513  +    char *szResult = NULL;
          514  +    FILE *fp = fopen(filename, "rt");
          515  +
          516  +    if (fp != NULL) {
          517  +	/*
          518  +	 * Read data until we see our match string.
          519  +	 */
          520  +
          521  +	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
          522  +	    LPSTR p, q;
          523  +
          524  +	    p = strstr(szBuffer, match);
          525  +	    if (p != NULL) {
          526  +		/*
          527  +		 * Skip to first digit after the match.
          528  +		 */
          529  +
          530  +		p += strlen(match);
          531  +		while (*p && !isdigit(*p)) {
          532  +		    ++p;
          533  +		}
          534  +
          535  +		/*
          536  +		 * Find ending whitespace.
          537  +		 */
          538  +
          539  +		q = p;
          540  +		while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q)
          541  +			    && (!strchr("ab", q[-1])) || --numdots))) {
          542  +		    ++q;
          543  +		}
          544  +
          545  +		memcpy(szBuffer, p, q - p);
          546  +		szBuffer[q-p] = 0;
          547  +		szResult = szBuffer;
          548  +		break;
          549  +	    }
          550  +	}
          551  +	fclose(fp);
          552  +    }
          553  +    return szResult;
          554  +}
          555  +
          556  +/*
          557  + * List helpers for the SubstituteFile function
          558  + */
          559  +
          560  +typedef struct list_item_t {
          561  +    struct list_item_t *nextPtr;
          562  +    char * key;
          563  +    char * value;
          564  +} list_item_t;
          565  +
          566  +/* insert a list item into the list (list may be null) */
          567  +static list_item_t *
          568  +list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
          569  +{
          570  +    list_item_t *itemPtr = malloc(sizeof(list_item_t));
          571  +    if (itemPtr) {
          572  +	itemPtr->key = strdup(key);
          573  +	itemPtr->value = strdup(value);
          574  +	itemPtr->nextPtr = NULL;
          575  +
          576  +	while(*listPtrPtr) {
          577  +	    listPtrPtr = &(*listPtrPtr)->nextPtr;
          578  +	}
          579  +	*listPtrPtr = itemPtr;
          580  +    }
          581  +    return itemPtr;
          582  +}
          583  +
          584  +static void
          585  +list_free(list_item_t **listPtrPtr)
          586  +{
          587  +    list_item_t *tmpPtr, *listPtr = *listPtrPtr;
          588  +    while (listPtr) {
          589  +	tmpPtr = listPtr;
          590  +	listPtr = listPtr->nextPtr;
          591  +	free(tmpPtr->key);
          592  +	free(tmpPtr->value);
          593  +	free(tmpPtr);
          594  +    }
          595  +}
          596  +
          597  +/*
          598  + * SubstituteFile --
          599  + *	As windows doesn't provide anything useful like sed and it's unreliable
          600  + *	to use the tclsh you are building against (consider x-platform builds -
          601  + *	eg compiling AMD64 target from IX86) we provide a simple substitution
          602  + *	option here to handle autoconf style substitutions.
          603  + *	The substitution file is whitespace and line delimited. The file should
          604  + *	consist of lines matching the regular expression:
          605  + *	  \s*\S+\s+\S*$
          606  + *
          607  + *	Usage is something like:
          608  + *	  nmakehlp -S << $** > $@
          609  + *        @PACKAGE_NAME@ $(PACKAGE_NAME)
          610  + *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
          611  + *        <<
          612  + */
          613  +
          614  +static int
          615  +SubstituteFile(
          616  +    const char *substitutions,
          617  +    const char *filename)
          618  +{
          619  +    size_t cbBuffer = 1024;
          620  +    static char szBuffer[1024], szCopy[1024];
          621  +    char *szResult = NULL;
          622  +    list_item_t *substPtr = NULL;
          623  +    FILE *fp, *sp;
          624  +
          625  +    fp = fopen(filename, "rt");
          626  +    if (fp != NULL) {
          627  +
          628  +	/*
          629  +	 * Build a list of substutitions from the first filename
          630  +	 */
          631  +
          632  +	sp = fopen(substitutions, "rt");
          633  +	if (sp != NULL) {
          634  +	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
          635  +		unsigned char *ks, *ke, *vs, *ve;
          636  +		ks = (unsigned char*)szBuffer;
          637  +		while (ks && *ks && isspace(*ks)) ++ks;
          638  +		ke = ks;
          639  +		while (ke && *ke && !isspace(*ke)) ++ke;
          640  +		vs = ke;
          641  +		while (vs && *vs && isspace(*vs)) ++vs;
          642  +		ve = vs;
          643  +		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
          644  +		*ke = 0, *ve = 0;
          645  +		list_insert(&substPtr, (char*)ks, (char*)vs);
          646  +	    }
          647  +	    fclose(sp);
          648  +	}
          649  +
          650  +	/* debug: dump the list */
          651  +#ifdef _DEBUG
          652  +	{
          653  +	    int n = 0;
          654  +	    list_item_t *p = NULL;
          655  +	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
          656  +		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
          657  +	    }
          658  +	}
          659  +#endif
          660  +
          661  +	/*
          662  +	 * Run the substitutions over each line of the input
          663  +	 */
          664  +
          665  +	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
          666  +	    list_item_t *p = NULL;
          667  +	    for (p = substPtr; p != NULL; p = p->nextPtr) {
          668  +		char *m = strstr(szBuffer, p->key);
          669  +		if (m) {
          670  +		    char *cp, *op, *sp;
          671  +		    cp = szCopy;
          672  +		    op = szBuffer;
          673  +		    while (op != m) *cp++ = *op++;
          674  +		    sp = p->value;
          675  +		    while (sp && *sp) *cp++ = *sp++;
          676  +		    op += strlen(p->key);
          677  +		    while (*op) *cp++ = *op++;
          678  +		    *cp = 0;
          679  +		    memcpy(szBuffer, szCopy, sizeof(szCopy));
          680  +		}
          681  +	    }
          682  +	    printf(szBuffer);
          683  +	}
          684  +
          685  +	list_free(&substPtr);
          686  +    }
          687  +    fclose(fp);
          688  +    return 0;
          689  +}
          690  +
          691  +/*
          692  + * QualifyPath --
          693  + *
          694  + *	This composes the current working directory with a provided path
          695  + *	and returns the fully qualified and normalized path.
          696  + *	Mostly needed to setup paths for testing.
          697  + */
          698  +
          699  +static int
          700  +QualifyPath(
          701  +    const char *szPath)
          702  +{
          703  +    char szCwd[MAX_PATH + 1];
          704  +    char szTmp[MAX_PATH + 1];
          705  +    char *p;
          706  +    GetCurrentDirectory(MAX_PATH, szCwd);
          707  +    while ((p = strchr(szPath, '/')) && *p)
          708  +	*p = '\\';
          709  +    PathCombine(szTmp, szCwd, szPath);
          710  +    PathCanonicalize(szCwd, szTmp);
          711  +    printf("%s\n", szCwd);
          712  +    return 0;
          713  +}
          714  +
          715  +/*
          716  + * Implements LocateDependency for a single directory. See that command
          717  + * for an explanation.
          718  + * Returns 0 if found after printing the directory.
          719  + * Returns 1 if not found but no errors.
          720  + * Returns 2 on any kind of error
          721  + * Basically, these are used as exit codes for the process.
          722  + */
          723  +static int LocateDependencyHelper(const char *dir, const char *keypath)
          724  +{
          725  +    HANDLE hSearch;
          726  +    char path[MAX_PATH+1];
          727  +    int dirlen, keylen, ret;
          728  +    WIN32_FIND_DATA finfo;
          729  +
          730  +    if (dir == NULL || keypath == NULL)
          731  +	return 2; /* Have no real error reporting mechanism into nmake */
          732  +    dirlen = strlen(dir);
          733  +    if ((dirlen + 3) > sizeof(path))
          734  +	return 2;
          735  +    strncpy(path, dir, dirlen);
          736  +    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
          737  +    keylen = strlen(keypath);
          738  +
          739  +#if 0 /* This function is not available in Visual C++ 6 */
          740  +    /*
          741  +     * Use numerics 0 -> FindExInfoStandard,
          742  +     * 1 -> FindExSearchLimitToDirectories, 
          743  +     * as these are not defined in Visual C++ 6
          744  +     */
          745  +    hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
          746  +#else
          747  +    hSearch = FindFirstFile(path, &finfo);
          748  +#endif
          749  +    if (hSearch == INVALID_HANDLE_VALUE)
          750  +	return 1; /* Not found */
          751  +
          752  +    /* Loop through all subdirs checking if the keypath is under there */
          753  +    ret = 1; /* Assume not found */
          754  +    do {
          755  +	int sublen;
          756  +	/*
          757  +	 * We need to check it is a directory despite the 
          758  +	 * FindExSearchLimitToDirectories in the above call. See SDK docs
          759  +	 */
          760  +	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
          761  +	    continue;
          762  +	sublen = strlen(finfo.cFileName);
          763  +	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
          764  +	    continue;		/* Path does not fit, assume not matched */
          765  +	strncpy(path+dirlen+1, finfo.cFileName, sublen);
          766  +	path[dirlen+1+sublen] = '\\';
          767  +	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
          768  +	if (PathFileExists(path)) {
          769  +	    /* Found a match, print to stdout */
          770  +	    path[dirlen+1+sublen] = '\0';
          771  +	    QualifyPath(path);
          772  +	    ret = 0;
          773  +	    break;
          774  +	}
          775  +    } while (FindNextFile(hSearch, &finfo));
          776  +    FindClose(hSearch);
          777  +    return ret;
          778  +}
          779  +
          780  +/*
          781  + * LocateDependency --
          782  + *
          783  + *	Locates a dependency for a package.
          784  + *        keypath - a relative path within the package directory
          785  + *          that is used to confirm it is the correct directory.
          786  + *	The search path for the package directory is currently only
          787  + *      the parent and grandparent of the current working directory.
          788  + *      If found, the command prints 
          789  + *         name_DIRPATH=<full path of located directory>
          790  + *      and returns 0. If not found, does not print anything and returns 1.
          791  + */
          792  +static int LocateDependency(const char *keypath)
          793  +{
          794  +    int i, ret;
          795  +    static char *paths[] = {"..", "..\\..", "..\\..\\.."};
          796  +    
          797  +    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
          798  +	ret = LocateDependencyHelper(paths[i], keypath);
          799  +	if (ret == 0)
          800  +	    return ret;
          801  +    }
          802  +    return ret;
          803  +}
          804  +
          805  +
          806  +/*
          807  + * Local variables:
          808  + *   mode: c
          809  + *   c-basic-offset: 4
          810  + *   fill-column: 78
          811  + *   indent-tabs-mode: t
          812  + *   tab-width: 8
          813  + * End:
          814  + */

Added extensions/tnc/win/rules-ext.vc.

            1  +# This file should only be included in makefiles for Tcl extensions,
            2  +# NOT in the makefile for Tcl itself.
            3  +
            4  +!ifndef _RULES_EXT_VC
            5  +
            6  +# We need to run from the directory the parent makefile is located in.
            7  +# nmake does not tell us what makefile was used to invoke it so parent
            8  +# makefile has to set the MAKEFILEVC macro or we just make a guess and
            9  +# warn if we think that is not the case.
           10  +!if "$(MAKEFILEVC)" == ""
           11  +
           12  +!if exist("$(PROJECT).vc")
           13  +MAKEFILEVC = $(PROJECT).vc
           14  +!elseif exist("makefile.vc")
           15  +MAKEFILEVC = makefile.vc
           16  +!endif
           17  +!endif # "$(MAKEFILEVC)" == ""
           18  +
           19  +!if !exist("$(MAKEFILEVC)")
           20  +MSG = ^
           21  +You must run nmake from the directory containing the project makefile.^
           22  +If you are doing that and getting this message, set the MAKEFILEVC^
           23  +macro to the name of the project makefile.
           24  +!message WARNING: $(MSG)
           25  +!endif
           26  +
           27  +!if "$(PROJECT)" == "tcl"
           28  +!error The rules-ext.vc file is not intended for Tcl itself.
           29  +!endif
           30  +
           31  +# We extract version numbers using the nmakehlp program. For now use
           32  +# the local copy of nmakehlp. Once we locate Tcl, we will use that
           33  +# one if it is newer.
           34  +!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
           35  +!endif
           36  +
           37  +# First locate the Tcl directory that we are working with.
           38  +!ifdef TCLDIR
           39  +
           40  +_RULESDIR = $(TCLDIR:/=\)
           41  +
           42  +!else
           43  +
           44  +# If an installation path is specified, that is also the Tcl directory.
           45  +# Also Tk never builds against an installed Tcl, it needs Tcl sources
           46  +!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
           47  +_RULESDIR=$(INSTALLDIR:/=\)
           48  +!else
           49  +# Locate Tcl sources
           50  +!if [echo _RULESDIR = \> nmakehlp.out] \
           51  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
           52  +_RULESDIR = ..\..\tcl
           53  +!else
           54  +!include nmakehlp.out
           55  +!endif
           56  +
           57  +!endif # defined(INSTALLDIR)....
           58  +
           59  +!endif # ifndef TCLDIR
           60  +
           61  +# Now look for the targets.vc file under the Tcl root. Note we check this
           62  +# file and not rules.vc because the latter also exists on older systems.
           63  +!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
           64  +_RULESDIR = $(_RULESDIR)\lib\nmake
           65  +!elseif exist("$(_RULESDIR)\win\targets.vc")   # Building against Tcl sources
           66  +_RULESDIR = $(_RULESDIR)\win
           67  +!else
           68  +# If we have not located Tcl's targets file, most likely we are compiling
           69  +# against an older version of Tcl and so must use our own support files.
           70  +_RULESDIR = .
           71  +!endif
           72  +
           73  +!if "$(_RULESDIR)" != "."
           74  +# Potentially using Tcl's support files. If this extension has its own
           75  +# nmake support files, need to compare the versions and pick newer.
           76  +
           77  +!if exist("rules.vc") # The extension has its own copy
           78  +
           79  +!if [echo TCL_RULES_MAJOR = \> versions.vc] \
           80  +   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
           81  +!endif
           82  +!if [echo TCL_RULES_MINOR = \>> versions.vc] \
           83  +   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
           84  +!endif
           85  +
           86  +!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
           87  +   && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
           88  +!endif
           89  +!if [echo OUR_RULES_MINOR = \>> versions.vc] \
           90  +   && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
           91  +!endif
           92  +!include versions.vc
           93  +# We have a newer version of the support files, use them
           94  +!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
           95  +_RULESDIR = .
           96  +!endif
           97  +
           98  +!endif # if exist("rules.vc")
           99  +
          100  +!endif # if $(_RULESDIR) != "."
          101  +
          102  +# Let rules.vc know what copy of nmakehlp.c to use.
          103  +NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
          104  +
          105  +# Get rid of our internal defines before calling rules.vc
          106  +!undef TCL_RULES_MAJOR
          107  +!undef TCL_RULES_MINOR
          108  +!undef OUR_RULES_MAJOR
          109  +!undef OUR_RULES_MINOR
          110  +
          111  +!if exist("$(_RULESDIR)\rules.vc")
          112  +!message *** Using $(_RULESDIR)\rules.vc
          113  +!include "$(_RULESDIR)\rules.vc"
          114  +!else
          115  +!error *** Could not locate rules.vc in $(_RULESDIR)
          116  +!endif
          117  +
          118  +!endif # _RULES_EXT_VC

Added extensions/tnc/win/rules.vc.

            1  +#------------------------------------------------------------- -*- makefile -*-
            2  +# rules.vc --
            3  +#
            4  +# Part of the nmake based build system for Tcl and its extensions.
            5  +# This file does all the hard work in terms of parsing build options,
            6  +# compiler switches, defining common targets and macros. The Tcl makefile
            7  +# directly includes this. Extensions include it via "rules-ext.vc".
            8  +#
            9  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
           10  +# detailed documentation.
           11  +#
           12  +# See the file "license.terms" for information on usage and redistribution
           13  +# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
           14  +#
           15  +# Copyright (c) 2001-2003 David Gravereaux.
           16  +# Copyright (c) 2003-2008 Patrick Thoyts
           17  +# Copyright (c) 2017      Ashok P. Nadkarni
           18  +#------------------------------------------------------------------------------
           19  +
           20  +!ifndef _RULES_VC
           21  +_RULES_VC = 1
           22  +
           23  +# The following macros define the version of the rules.vc nmake build system
           24  +# For modifications that are not backward-compatible, you *must* change
           25  +# the major version.
           26  +RULES_VERSION_MAJOR = 1
           27  +RULES_VERSION_MINOR = 1
           28  +
           29  +# The PROJECT macro must be defined by parent makefile.
           30  +!if "$(PROJECT)" == ""
           31  +!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
           32  +!endif
           33  +
           34  +!if "$(PRJ_PACKAGE_TCLNAME)" == ""
           35  +PRJ_PACKAGE_TCLNAME = $(PROJECT)
           36  +!endif
           37  +
           38  +# Also special case Tcl and Tk to save some typing later
           39  +DOING_TCL = 0
           40  +DOING_TK  = 0
           41  +!if "$(PROJECT)" == "tcl"
           42  +DOING_TCL = 1
           43  +!elseif "$(PROJECT)" == "tk"
           44  +DOING_TK = 1
           45  +!endif
           46  +
           47  +!ifndef NEED_TK
           48  +# Backwards compatibility
           49  +!ifdef PROJECT_REQUIRES_TK
           50  +NEED_TK = $(PROJECT_REQUIRES_TK)
           51  +!else
           52  +NEED_TK = 0
           53  +!endif
           54  +!endif
           55  +
           56  +!ifndef NEED_TCL_SOURCE
           57  +NEED_TCL_SOURCE = 0
           58  +!endif
           59  +
           60  +!ifdef NEED_TK_SOURCE
           61  +!if $(NEED_TK_SOURCE)
           62  +NEED_TK = 1
           63  +!endif
           64  +!else
           65  +NEED_TK_SOURCE = 0
           66  +!endif
           67  +
           68  +################################################################
           69  +# Nmake is a pretty weak environment in syntax and capabilities
           70  +# so this file is necessarily verbose. It's broken down into
           71  +# the following parts.
           72  +#
           73  +# 0. Sanity check that compiler environment is set up and initialize
           74  +#    any built-in settings from the parent makefile
           75  +# 1. First define the external tools used for compiling, copying etc.
           76  +#    as this is independent of everything else.
           77  +# 2. Figure out our build structure in terms of the directory, whether
           78  +#    we are building Tcl or an extension, etc.
           79  +# 3. Determine the compiler and linker versions
           80  +# 4. Build the nmakehlp helper application
           81  +# 5. Determine the supported compiler options and features
           82  +# 6. Parse the OPTS macro value for user-specified build configuration
           83  +# 7. Parse the STATS macro value for statistics instrumentation
           84  +# 8. Parse the CHECKS macro for additional compilation checks
           85  +# 9. Extract Tcl, and possibly Tk, version numbers from the headers
           86  +# 10. Based on this selected configuration, construct the output
           87  +#     directory and file paths
           88  +# 11. Construct the paths where the package is to be installed
           89  +# 12. Set up the actual options passed to compiler and linker based
           90  +#     on the information gathered above.
           91  +# 13. Define some standard build targets and implicit rules. These may
           92  +#     be optionally disabled by the parent makefile.
           93  +# 14. (For extensions only.) Compare the configuration of the target
           94  +#     Tcl and the extensions and warn against discrepancies.
           95  +#
           96  +# One final note about the macro names used. They are as they are
           97  +# for historical reasons. We would like legacy extensions to
           98  +# continue to work with this make include file so be wary of
           99  +# changing them for consistency or clarity.
          100  +
          101  +# 0. Sanity check compiler environment
          102  +
          103  +# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
          104  +# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
          105  +
          106  +!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
          107  +MSG = ^
          108  +Visual C++ compiler environment not initialized.
          109  +!error $(MSG)
          110  +!endif
          111  +
          112  +# We need to run from the directory the parent makefile is located in.
          113  +# nmake does not tell us what makefile was used to invoke it so parent
          114  +# makefile has to set the MAKEFILEVC macro or we just make a guess and
          115  +# warn if we think that is not the case.
          116  +!if "$(MAKEFILEVC)" == ""
          117  +
          118  +!if exist("$(PROJECT).vc")
          119  +MAKEFILEVC = $(PROJECT).vc
          120  +!elseif exist("makefile.vc")
          121  +MAKEFILEVC = makefile.vc
          122  +!endif
          123  +!endif # "$(MAKEFILEVC)" == ""
          124  +
          125  +!if !exist("$(MAKEFILEVC)")
          126  +MSG = ^
          127  +You must run nmake from the directory containing the project makefile.^
          128  +If you are doing that and getting this message, set the MAKEFILEVC^
          129  +macro to the name of the project makefile.
          130  +!message WARNING: $(MSG)
          131  +!endif
          132  +
          133  +
          134  +################################################################
          135  +# 1. Define external programs being used
          136  +
          137  +#----------------------------------------------------------
          138  +# Set the proper copy method to avoid overwrite questions
          139  +# to the user when copying files and selecting the right
          140  +# "delete all" method.
          141  +#----------------------------------------------------------
          142  +
          143  +RMDIR	= rmdir /S /Q
          144  +CPY	= xcopy /i /y >NUL
          145  +CPYDIR  = xcopy /e /i /y >NUL
          146  +COPY	= copy /y >NUL
          147  +MKDIR   = mkdir
          148  +
          149  +######################################################################
          150  +# 2. Figure out our build environment in terms of what we're building.
          151  +#
          152  +# (a) Tcl itself
          153  +# (b) Tk
          154  +# (c) a Tcl extension using libraries/includes from an *installed* Tcl
          155  +# (d) a Tcl extension using libraries/includes from Tcl source directory
          156  +#
          157  +# This last is needed because some extensions still need
          158  +# some Tcl interfaces that are not publicly exposed.
          159  +#
          160  +# The fragment will set the following macros:
          161  +# ROOT - root of this module sources
          162  +# COMPATDIR - source directory that holds compatibility sources
          163  +# DOCDIR - source directory containing documentation files
          164  +# GENERICDIR - platform-independent source directory
          165  +# WINDIR - Windows-specific source directory
          166  +# TESTDIR - directory containing test files
          167  +# TOOLSDIR - directory containing build tools
          168  +# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
          169  +#    when building Tcl itself.
          170  +# _INSTALLDIR - native form of the installation path. For Tcl
          171  +#    this will be the root of the Tcl installation. For extensions
          172  +#    this will be the lib directory under the root.
          173  +# TCLINSTALL  - set to 1 if _TCLDIR refers to
          174  +#    headers and libraries from an installed Tcl, and 0 if built against
          175  +#    Tcl sources. Not set when building Tcl itself. Yes, not very well
          176  +#    named.
          177  +# _TCL_H - native path to the tcl.h file
          178  +#
          179  +# If Tk is involved, also sets the following
          180  +# _TKDIR - native form Tk installation OR Tk source. Not set if building
          181  +#    Tk itself.
          182  +# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
          183  +# _TK_H - native path to the tk.h file
          184  +
          185  +# Root directory for sources and assumed subdirectories
          186  +ROOT = $(MAKEDIR)\..
          187  +# The following paths CANNOT have spaces in them as they appear on the
          188  +# left side of implicit rules.
          189  +!ifndef COMPATDIR
          190  +COMPATDIR	= $(ROOT)\compat
          191  +!endif
          192  +!ifndef DOCDIR
          193  +DOCDIR		= $(ROOT)\doc
          194  +!endif
          195  +!ifndef GENERICDIR
          196  +GENERICDIR	= $(ROOT)\generic
          197  +!endif
          198  +!ifndef TOOLSDIR
          199  +TOOLSDIR	= $(ROOT)\tools
          200  +!endif
          201  +!ifndef TESTDIR
          202  +TESTDIR	= $(ROOT)\tests
          203  +!endif
          204  +!ifndef LIBDIR
          205  +!if exist("$(ROOT)\library")
          206  +LIBDIR          = $(ROOT)\library
          207  +!else
          208  +LIBDIR          = $(ROOT)\lib
          209  +!endif
          210  +!endif
          211  +!ifndef DEMODIR
          212  +!if exist("$(LIBDIR)\demos")
          213  +DEMODIR		= $(LIBDIR)\demos
          214  +!else
          215  +DEMODIR		= $(ROOT)\demos
          216  +!endif
          217  +!endif # ifndef DEMODIR
          218  +# Do NOT enclose WINDIR in a !ifndef because Windows always defines
          219  +# WINDIR env var to point to c:\windows!
          220  +# TBD - This is a potentially dangerous conflict, rename WINDIR to
          221  +# something else
          222  +WINDIR		= $(ROOT)\win
          223  +
          224  +!ifndef RCDIR
          225  +!if exist("$(WINDIR)\rc")
          226  +RCDIR           = $(WINDIR)\rc
          227  +!else
          228  +RCDIR           = $(WINDIR)
          229  +!endif
          230  +!endif
          231  +RCDIR = $(RCDIR:/=\)
          232  +
          233  +# The target directory where the built packages and binaries will be installed.
          234  +# INSTALLDIR is the (optional) path specified by the user.
          235  +# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
          236  +!ifdef INSTALLDIR
          237  +### Fix the path separators.
          238  +_INSTALLDIR	= $(INSTALLDIR:/=\)
          239  +!else
          240  +### Assume the normal default.
          241  +_INSTALLDIR	= $(HOMEDRIVE)\Tcl
          242  +!endif
          243  +
          244  +!if $(DOING_TCL)
          245  +
          246  +# BEGIN Case 2(a) - Building Tcl itself
          247  +
          248  +# Only need to define _TCL_H
          249  +_TCL_H = ..\generic\tcl.h
          250  +
          251  +# END Case 2(a) - Building Tcl itself
          252  +
          253  +!elseif $(DOING_TK)
          254  +
          255  +# BEGIN Case 2(b) - Building Tk
          256  +
          257  +TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
          258  +!if "$(TCLDIR)" == ""
          259  +!if [echo TCLDIR = \> nmakehlp.out] \
          260  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
          261  +!error *** Could not locate Tcl source directory.
          262  +!endif
          263  +!include nmakehlp.out
          264  +!endif # TCLDIR == ""
          265  +
          266  +_TCLDIR	= $(TCLDIR:/=\)
          267  +_TCL_H  = $(_TCLDIR)\generic\tcl.h
          268  +!if !exist("$(_TCL_H)")
          269  +!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
          270  +!endif
          271  +
          272  +_TK_H = ..\generic\tk.h
          273  +
          274  +# END Case 2(b) - Building Tk
          275  +
          276  +!else
          277  +
          278  +# BEGIN Case 2(c) or (d) - Building an extension other than Tk
          279  +
          280  +# If command line has specified Tcl location through TCLDIR, use it
          281  +# else default to the INSTALLDIR setting
          282  +!if "$(TCLDIR)" != ""
          283  +
          284  +_TCLDIR	= $(TCLDIR:/=\)
          285  +!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
          286  +TCLINSTALL	= 1
          287  +_TCL_H          = $(_TCLDIR)\include\tcl.h
          288  +!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
          289  +TCLINSTALL	= 0
          290  +_TCL_H          = $(_TCLDIR)\generic\tcl.h
          291  +!endif
          292  +
          293  +!else  #  # Case 2(c) for extensions with TCLDIR undefined
          294  +
          295  +# Need to locate Tcl depending on whether it needs Tcl source or not.
          296  +# If we don't, check the INSTALLDIR for an installed Tcl first
          297  +
          298  +!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
          299  +
          300  +TCLINSTALL	= 1
          301  +TCLDIR          = $(_INSTALLDIR)\..
          302  +# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
          303  +# later so the \.. accounts for the /lib
          304  +_TCLDIR		= $(_INSTALLDIR)\..
          305  +_TCL_H          = $(_TCLDIR)\include\tcl.h
          306  +
          307  +!else # exist(...) && ! $(NEED_TCL_SOURCE)
          308  +
          309  +!if [echo _TCLDIR = \> nmakehlp.out] \
          310  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
          311  +!error *** Could not locate Tcl source directory.
          312  +!endif
          313  +!include nmakehlp.out
          314  +TCLINSTALL      = 0
          315  +TCLDIR         = $(_TCLDIR)
          316  +_TCL_H          = $(_TCLDIR)\generic\tcl.h
          317  +
          318  +!endif # exist(...) && ! $(NEED_TCL_SOURCE)
          319  +
          320  +!endif # TCLDIR
          321  +
          322  +!ifndef _TCL_H
          323  +MSG =^
          324  +Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
          325  +!error $(MSG)
          326  +!endif
          327  +
          328  +# Now do the same to locate Tk headers and libs if project requires Tk
          329  +!if $(NEED_TK)
          330  +
          331  +!if "$(TKDIR)" != ""
          332  +
          333  +_TKDIR = $(TKDIR:/=\)
          334  +!if exist("$(_TKDIR)\include\tk.h")
          335  +TKINSTALL      = 1
          336  +_TK_H          = $(_TKDIR)\include\tk.h
          337  +!elseif exist("$(_TKDIR)\generic\tk.h")
          338  +TKINSTALL      = 0
          339  +_TK_H          = $(_TKDIR)\generic\tk.h
          340  +!endif
          341  +
          342  +!else # TKDIR not defined
          343  +
          344  +# Need to locate Tcl depending on whether it needs Tcl source or not.
          345  +# If we don't, check the INSTALLDIR for an installed Tcl first
          346  +
          347  +!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          348  +
          349  +TKINSTALL      = 1
          350  +# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
          351  +# later so the \.. accounts for the /lib
          352  +_TKDIR         = $(_INSTALLDIR)\..
          353  +_TK_H          = $(_TKDIR)\include\tk.h
          354  +TKDIR          = $(_TKDIR)
          355  +
          356  +!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          357  +
          358  +!if [echo _TKDIR = \> nmakehlp.out] \
          359  +   || [nmakehlp -L generic\tk.h >> nmakehlp.out]
          360  +!error *** Could not locate Tk source directory.
          361  +!endif
          362  +!include nmakehlp.out
          363  +TKINSTALL      = 0
          364  +TKDIR          = $(_TKDIR)
          365  +_TK_H          = $(_TKDIR)\generic\tk.h
          366  +
          367  +!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          368  +
          369  +!endif # TKDIR
          370  +
          371  +!ifndef _TK_H
          372  +MSG =^
          373  +Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
          374  +!error $(MSG)
          375  +!endif
          376  +
          377  +!endif # NEED_TK
          378  +
          379  +!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
          380  +MSG = ^
          381  +*** Warning: This extension requires the source distribution of Tcl.^
          382  +*** Please set the TCLDIR macro to point to the Tcl sources.
          383  +!error $(MSG)
          384  +!endif
          385  +
          386  +!if $(NEED_TK_SOURCE)
          387  +!if $(TKINSTALL)
          388  +MSG = ^
          389  +*** Warning: This extension requires the source distribution of Tk.^
          390  +*** Please set the TKDIR macro to point to the Tk sources.
          391  +!error $(MSG)
          392  +!endif
          393  +!endif
          394  +
          395  +
          396  +# If INSTALLDIR set to Tcl installation root dir then reset to the
          397  +# lib dir for installing extensions 
          398  +!if exist("$(_INSTALLDIR)\include\tcl.h")
          399  +_INSTALLDIR=$(_INSTALLDIR)\lib
          400  +!endif
          401  +
          402  +# END Case 2(c) or (d) - Building an extension
          403  +!endif # if $(DOING_TCL)
          404  +
          405  +################################################################
          406  +# 3. Determine compiler version and architecture
          407  +# In this section, we figure out the compiler version and the
          408  +# architecture for which we are building. This sets the
          409  +# following macros:
          410  +# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
          411  +#     This is also printed by the compiler in dotted form 19.10 etc.
          412  +# VCVER - the "marketing version", for example Visual C++ 6 for internal
          413  +#     compiler version 1200. This is kept only for legacy reasons as it
          414  +#     does not make sense for recent Microsoft compilers. Only used for
          415  +#     output directory names.
          416  +# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
          417  +# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
          418  +# MACHINE - same as $(ARCH) - legacy
          419  +# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
          420  +# CFG_ENCODING - set to an character encoding.
          421  +#   TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
          422  +#   see where it is used
          423  +
          424  +cc32		= $(CC)   # built-in default.
          425  +link32		= link
          426  +lib32		= lib
          427  +rc32		= $(RC)   # built-in default.
          428  +
          429  +#----------------------------------------------------------------
          430  +# Figure out the compiler architecture and version by writing
          431  +# the C macros to a file, preprocessing them with the C
          432  +# preprocessor and reading back the created file
          433  +
          434  +_HASH=^#
          435  +_VC_MANIFEST_EMBED_EXE=
          436  +_VC_MANIFEST_EMBED_DLL=
          437  +VCVER=0
          438  +!if ![echo VCVERSION=_MSC_VER > vercl.x] \
          439  +    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
          440  +    && ![echo ARCH=IX86 >> vercl.x] \
          441  +    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
          442  +    && ![echo ARCH=AMD64 >> vercl.x] \
          443  +    && ![echo $(_HASH)endif >> vercl.x] \
          444  +    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
          445  +!include vercl.i
          446  +!if $(VCVERSION) < 1900
          447  +!if ![echo VCVER= ^\> vercl.vc] \
          448  +    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
          449  +!include vercl.vc
          450  +!endif
          451  +!else
          452  +# The simple calculation above does not apply to new Visual Studio releases
          453  +# Keep the compiler version in its native form.
          454  +VCVER = $(VCVERSION)
          455  +!endif
          456  +!endif
          457  +
          458  +!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
          459  +!endif
          460  +
          461  +#----------------------------------------------------------------
          462  +# The MACHINE macro is used by legacy makefiles so set it as well
          463  +!ifdef MACHINE
          464  +!if "$(MACHINE)" == "x86"
          465  +!undef MACHINE
          466  +MACHINE = IX86
          467  +!elseif "$(MACHINE)" == "x64"
          468  +!undef MACHINE
          469  +MACHINE = AMD64
          470  +!endif
          471  +!if "$(MACHINE)" != "$(ARCH)"
          472  +!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
          473  +!endif
          474  +!else
          475  +MACHINE=$(ARCH)
          476  +!endif
          477  +
          478  +#------------------------------------------------------------
          479  +# Figure out the *host* architecture by reading the registry
          480  +
          481  +!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
          482  +NATIVE_ARCH=IX86
          483  +!else
          484  +NATIVE_ARCH=AMD64
          485  +!endif
          486  +
          487  +# Since MSVC8 we must deal with manifest resources.
          488  +!if $(VCVERSION) >= 1400
          489  +_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
          490  +_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
          491  +!endif
          492  +
          493  +!ifndef CFG_ENCODING
          494  +CFG_ENCODING	= \"cp1252\"
          495  +!endif
          496  +
          497  +################################################################
          498  +# 4. Build the nmakehlp program
          499  +# This is a helper app we need to overcome nmake's limiting
          500  +# environment. We will call out to it to get various bits of
          501  +# information about supported compiler options etc.
          502  +#
          503  +# Tcl itself will always use the nmakehlp.c program which is
          504  +# in its own source. This is the "master" copy and kept updated.
          505  +#
          506  +# Extensions built against an installed Tcl will use the installed
          507  +# copy of Tcl's nmakehlp.c if there is one and their own version
          508  +# otherwise. In the latter case, they would also be using their own
          509  +# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
          510  +# or rules.vc.
          511  +#
          512  +# Extensions built against Tcl sources will use the one from the Tcl source.
          513  +#
          514  +# When building an extension using a sufficiently new version of Tcl,
          515  +# rules-ext.vc will define NMAKEHLPC appropriately to point to the
          516  +# copy of nmakehlp.c to be used.
          517  +
          518  +!ifndef NMAKEHLPC
          519  +# Default to the one in the current directory (the extension's own nmakehlp.c)
          520  +NMAKEHLPC = nmakehlp.c
          521  +
          522  +!if !$(DOING_TCL)
          523  +!if $(TCLINSTALL)
          524  +!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
          525  +NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
          526  +!endif
          527  +!else # ! $(TCLINSTALL)
          528  +!if exist("$(_TCLDIR)\win\nmakehlp.c")
          529  +NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
          530  +!endif
          531  +!endif # $(TCLINSTALL)
          532  +!endif # !$(DOING_TCL)
          533  +
          534  +!endif # NMAKEHLPC
          535  +
          536  +# We always build nmakehlp even if it exists since we do not know
          537  +# what source it was built from.
          538  +!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
          539  +!endif
          540  +
          541  +################################################################
          542  +# 5. Test for compiler features
          543  +# Visual C++ compiler options have changed over the years. Check
          544  +# which options are supported by the compiler in use.
          545  +#
          546  +# The following macros are set:
          547  +# OPTIMIZATIONS - the compiler flags to be used for optimized builds
          548  +# DEBUGFLAGS - the compiler flags to be used for debug builds
          549  +# LINKERFLAGS - Flags passed to the linker 
          550  +#
          551  +# Note that these are the compiler settings *available*, not those
          552  +# that will be *used*. The latter depends on the OPTS macro settings
          553  +# which we have not yet parsed.
          554  +#
          555  +# Also note that some of the flags in OPTIMIZATIONS are not really
          556  +# related to optimization. They are placed there only for legacy reasons
          557  +# as some extensions expect them to be included in that macro.
          558  +
          559  +# -Op improves float consistency. Note only needed for older compilers
          560  +# Newer compilers do not need or support this option.
          561  +!if [nmakehlp -c -Op]
          562  +FPOPTS  = -Op
          563  +!endif
          564  +
          565  +# Strict floating point semantics - present in newer compilers in lieu of -Op
          566  +!if [nmakehlp -c -fp:strict]
          567  +FPOPTS  = $(FPOPTS) -fp:strict
          568  +!endif
          569  +
          570  +!if "$(MACHINE)" == "IX86"
          571  +### test for pentium errata
          572  +!if [nmakehlp -c -QI0f]
          573  +!message *** Compiler has 'Pentium 0x0f fix'
          574  +FPOPTS  = $(FPOPTS) -QI0f
          575  +!else
          576  +!message *** Compiler does not have 'Pentium 0x0f fix'
          577  +!endif
          578  +!endif
          579  +
          580  +### test for optimizations
          581  +# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
          582  +# documentation. Note we do NOT want /Gs as that inserts a _chkstk
          583  +# stack probe at *every* function entry, not just those with more than
          584  +# a page of stack allocation resulting in a performance hit.  However,
          585  +# /O2 documentation is misleading as its stack probes are simply the
          586  +# default page size locals allocation probes and not what is implied
          587  +# by an explicit /Gs option.
          588  +
          589  +OPTIMIZATIONS = $(FPOPTS)
          590  +
          591  +!if [nmakehlp -c -O2]
          592  +OPTIMIZING = 1
          593  +OPTIMIZATIONS   = $(OPTIMIZATIONS) -O2
          594  +!else
          595  +# Legacy, really. All modern compilers support this
          596  +!message *** Compiler does not have 'Optimizations'
          597  +OPTIMIZING = 0
          598  +!endif
          599  +
          600  +# Checks for buffer overflows in local arrays
          601  +!if [nmakehlp -c -GS]
          602  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
          603  +!endif
          604  +
          605  +# Link time optimization. Note that this option (potentially) makes
          606  +# generated libraries only usable by the specific VC++ version that
          607  +# created it. Requires /LTCG linker option
          608  +!if [nmakehlp -c -GL]
          609  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
          610  +CC_GL_OPT_ENABLED = 1
          611  +!else
          612  +# In newer compilers -GL and -YX are incompatible.
          613  +!if [nmakehlp -c -YX]
          614  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
          615  +!endif
          616  +!endif # [nmakehlp -c -GL]
          617  +
          618  +DEBUGFLAGS     = $(FPOPTS)
          619  +
          620  +# Run time error checks. Not available or valid in a release, non-debug build
          621  +# RTC is for modern compilers, -GZ is legacy
          622  +!if [nmakehlp -c -RTC1]
          623  +DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
          624  +!elseif [nmakehlp -c -GZ]
          625  +DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
          626  +!endif
          627  +
          628  +#----------------------------------------------------------------
          629  +# Linker flags
          630  +
          631  +# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
          632  +# if the linker supports a specific option. Without these flags link will
          633  +# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
          634  +# They are not passed through to the actual application / extension
          635  +# link rules.
          636  +!ifndef LINKER_TESTFLAGS
          637  +LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
          638  +!endif
          639  +
          640  +LINKERFLAGS     =
          641  +
          642  +# If compiler has enabled link time optimization, linker must too with -ltcg
          643  +!ifdef CC_GL_OPT_ENABLED
          644  +!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
          645  +LINKERFLAGS     = $(LINKERFLAGS) -ltcg
          646  +!endif
          647  +!endif
          648  +
          649  +########################################################################
          650  +# 6. Parse the OPTS macro to work out the requested build configuration.
          651  +# Based on this, we will construct the actual switches to be passed to the
          652  +# compiler and linker using the macros defined in the previous section.
          653  +# The following macros are defined by this section based on OPTS
          654  +# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
          655  +#                1 -> build as a static library and shell
          656  +# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
          657  +# DEBUG - 1 -> debug build, 0 -> release builds
          658  +# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
          659  +# PROFILE - 1 -> generate profiling info, 0 -> no profiling
          660  +# PGO     - 1 -> profile based optimization, 0 -> no
          661  +# MSVCRT  - 1 -> link to dynamic C runtime even when building static Tcl build
          662  +#           0 -> link to static C runtime for static Tcl build.
          663  +#           Does not impact shared Tcl builds (STATIC_BUILD == 0)
          664  +# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
          665  +#           in the Tcl shell. 0 -> keep them as shared libraries
          666  +#           Does not impact shared Tcl builds.
          667  +# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
          668  +#           0 -> Use the non-thread allocator.
          669  +# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
          670  +#           C runtime, 0 -> use the debug C runtime.
          671  +# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
          672  +# CONFIG_CHECK - 1 -> check current build configuration against Tcl
          673  +#           configuration (ignored for Tcl itself)
          674  +# Further, LINKERFLAGS are modified based on above.
          675  +
          676  +# Default values for all the above
          677  +STATIC_BUILD	= 0
          678  +TCL_THREADS	= 1
          679  +DEBUG		= 0
          680  +SYMBOLS		= 0
          681  +PROFILE		= 0
          682  +PGO		= 0
          683  +MSVCRT		= 1
          684  +TCL_USE_STATIC_PACKAGES	= 0
          685  +USE_THREAD_ALLOC = 1
          686  +UNCHECKED	= 0
          687  +CONFIG_CHECK    = 1
          688  +!if $(DOING_TCL)
          689  +USE_STUBS       = 0
          690  +!else
          691  +USE_STUBS       = 1
          692  +!endif
          693  +
          694  +# If OPTS is not empty AND does not contain "none" which turns off all OPTS
          695  +# set the above macros based on OPTS content
          696  +!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
          697  +
          698  +# OPTS are specified, parse them
          699  +
          700  +!if [nmakehlp -f $(OPTS) "static"]
          701  +!message *** Doing static
          702  +STATIC_BUILD	= 1
          703  +!endif
          704  +
          705  +!if [nmakehlp -f $(OPTS) "nostubs"]
          706  +!message *** Not using stubs
          707  +USE_STUBS	= 0
          708  +!endif
          709  +
          710  +!if [nmakehlp -f $(OPTS) "nomsvcrt"]
          711  +!message *** Doing nomsvcrt
          712  +MSVCRT		= 0
          713  +!else
          714  +!if [nmakehlp -f $(OPTS) "msvcrt"]
          715  +!message *** Doing msvcrt
          716  +MSVCRT		= 1
          717  +!else
          718  +!if !$(STATIC_BUILD)
          719  +MSVCRT		= 1
          720  +!else
          721  +MSVCRT		= 0
          722  +!endif
          723  +!endif
          724  +!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
          725  +
          726  +!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
          727  +!message *** Doing staticpkg
          728  +TCL_USE_STATIC_PACKAGES	= 1
          729  +!else
          730  +TCL_USE_STATIC_PACKAGES	= 0
          731  +!endif
          732  +
          733  +!if [nmakehlp -f $(OPTS) "nothreads"]
          734  +!message *** Compile explicitly for non-threaded Tcl
          735  +TCL_THREADS	= 0
          736  +USE_THREAD_ALLOC= 0
          737  +!else
          738  +TCL_THREADS	= 1
          739  +USE_THREAD_ALLOC= 1
          740  +!endif
          741  +
          742  +!if [nmakehlp -f $(OPTS) "symbols"]
          743  +!message *** Doing symbols
          744  +DEBUG		= 1
          745  +!else
          746  +DEBUG		= 0
          747  +!endif
          748  +
          749  +!if [nmakehlp -f $(OPTS) "pdbs"]
          750  +!message *** Doing pdbs
          751  +SYMBOLS		= 1
          752  +!else
          753  +SYMBOLS		= 0
          754  +!endif
          755  +
          756  +!if [nmakehlp -f $(OPTS) "profile"]
          757  +!message *** Doing profile
          758  +PROFILE		= 1
          759  +!else
          760  +PROFILE		= 0
          761  +!endif
          762  +
          763  +!if [nmakehlp -f $(OPTS) "pgi"]
          764  +!message *** Doing profile guided optimization instrumentation
          765  +PGO		= 1
          766  +!elseif [nmakehlp -f $(OPTS) "pgo"]
          767  +!message *** Doing profile guided optimization
          768  +PGO		= 2
          769  +!else
          770  +PGO		= 0
          771  +!endif
          772  +
          773  +!if [nmakehlp -f $(OPTS) "loimpact"]
          774  +!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
          775  +!endif
          776  +
          777  +# TBD - should get rid of this option
          778  +!if [nmakehlp -f $(OPTS) "thrdalloc"]
          779  +!message *** Doing thrdalloc
          780  +USE_THREAD_ALLOC = 1
          781  +!endif
          782  +
          783  +!if [nmakehlp -f $(OPTS) "tclalloc"]
          784  +USE_THREAD_ALLOC = 0
          785  +!endif
          786  +
          787  +!if [nmakehlp -f $(OPTS) "unchecked"]
          788  +!message *** Doing unchecked
          789  +UNCHECKED = 1
          790  +!else
          791  +UNCHECKED = 0
          792  +!endif
          793  +
          794  +!if [nmakehlp -f $(OPTS) "noconfigcheck"]
          795  +CONFIG_CHECK = 1
          796  +!else
          797  +CONFIG_CHECK = 0
          798  +!endif
          799  +
          800  +!endif # "$(OPTS)" != ""  && ... parsing of OPTS
          801  +
          802  +# Set linker flags based on above
          803  +
          804  +!if $(PGO) > 1
          805  +!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
          806  +LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
          807  +!else
          808  +MSG=^
          809  +This compiler does not support profile guided optimization.
          810  +!error $(MSG)
          811  +!endif
          812  +!elseif $(PGO) > 0
          813  +!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
          814  +LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
          815  +!else
          816  +MSG=^
          817  +This compiler does not support profile guided optimization.
          818  +!error $(MSG)
          819  +!endif
          820  +!endif
          821  +
          822  +################################################################
          823  +# 7. Parse the STATS macro to configure code instrumentation
          824  +# The following macros are set by this section:
          825  +# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
          826  +#                 0 -> disables
          827  +# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
          828  +#                     0 -> disables
          829  +
          830  +# Default both are off
          831  +TCL_MEM_DEBUG	    = 0
          832  +TCL_COMPILE_DEBUG   = 0
          833  +
          834  +!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
          835  +
          836  +!if [nmakehlp -f $(STATS) "memdbg"]
          837  +!message *** Doing memdbg
          838  +TCL_MEM_DEBUG	    = 1
          839  +!else
          840  +TCL_MEM_DEBUG	    = 0
          841  +!endif
          842  +
          843  +!if [nmakehlp -f $(STATS) "compdbg"]
          844  +!message *** Doing compdbg
          845  +TCL_COMPILE_DEBUG   = 1
          846  +!else
          847  +TCL_COMPILE_DEBUG   = 0
          848  +!endif
          849  +
          850  +!endif
          851  +
          852  +####################################################################
          853  +# 8. Parse the CHECKS macro to configure additional compiler checks
          854  +# The following macros are set by this section:
          855  +# WARNINGS - compiler switches that control the warnings level
          856  +# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
          857  +#                     0 -> enable deprecated functions
          858  +
          859  +# Defaults - Permit deprecated functions and warning level 3
          860  +TCL_NO_DEPRECATED	    = 0
          861  +WARNINGS		    = -W3
          862  +
          863  +!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
          864  +
          865  +!if [nmakehlp -f $(CHECKS) "nodep"]
          866  +!message *** Doing nodep check
          867  +TCL_NO_DEPRECATED	    = 1
          868  +!endif
          869  +
          870  +!if [nmakehlp -f $(CHECKS) "fullwarn"]
          871  +!message *** Doing full warnings check
          872  +WARNINGS		    = -W4
          873  +!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
          874  +LINKERFLAGS		    = $(LINKERFLAGS) -warn:3
          875  +!endif
          876  +!endif
          877  +
          878  +!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
          879  +!message *** Doing 64bit portability warnings
          880  +WARNINGS		    = $(WARNINGS) -Wp64
          881  +!endif
          882  +
          883  +!endif
          884  +
          885  +################################################################
          886  +# 9. Extract various version numbers
          887  +# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
          888  +# respectively. For extensions, versions are extracted from the
          889  +# configure.in or configure.ac from the TEA configuration if it
          890  +# exists, and unset otherwise.
          891  +# Sets the following macros:
          892  +# TCL_MAJOR_VERSION
          893  +# TCL_MINOR_VERSION
          894  +# TCL_PATCH_LEVEL
          895  +# TCL_VERSION
          896  +# TK_MAJOR_VERSION
          897  +# TK_MINOR_VERSION
          898  +# TK_PATCH_LEVEL
          899  +# TK_VERSION
          900  +# DOTVERSION - set as (for example) 2.5
          901  +# VERSION - set as (for example 25)
          902  +#--------------------------------------------------------------
          903  +
          904  +!if [echo REM = This file is generated from rules.vc > versions.vc]
          905  +!endif
          906  +!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
          907  +   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
          908  +!endif
          909  +!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
          910  +   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
          911  +!endif
          912  +!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
          913  +   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
          914  +!endif
          915  +
          916  +!if defined(_TK_H)
          917  +!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
          918  +   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
          919  +!endif
          920  +!if [echo TK_MINOR_VERSION = \>> versions.vc] \
          921  +   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
          922  +!endif
          923  +!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
          924  +   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
          925  +!endif
          926  +!endif # _TK_H
          927  +
          928  +!include versions.vc
          929  +
          930  +TCL_VERSION	= $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
          931  +TCL_DOTVERSION	= $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
          932  +!if defined(_TK_H)
          933  +TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
          934  +TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
          935  +!endif
          936  +
          937  +# Set DOTVERSION and VERSION
          938  +!if $(DOING_TCL)
          939  +
          940  +DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
          941  +VERSION = $(TCL_VERSION)
          942  +
          943  +!elseif $(DOING_TK)
          944  +
          945  +DOTVERSION = $(TK_DOTVERSION)
          946  +VERSION = $(TK_VERSION)
          947  +
          948  +!else # Doing a non-Tk extension
          949  +
          950  +# If parent makefile has not defined DOTVERSION, try to get it from TEA
          951  +# first from a configure.in file, and then from configure.ac
          952  +!ifndef DOTVERSION
          953  +!if [echo DOTVERSION = \> versions.vc] \
          954  +   || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
          955  +!if [echo DOTVERSION = \> versions.vc] \
          956  +   || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
          957  +!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
          958  +!endif
          959  +!endif
          960  +!include versions.vc
          961  +!endif # DOTVERSION
          962  +VERSION         = $(DOTVERSION:.=)
          963  +
          964  +!endif # $(DOING_TCL) ... etc.
          965  +
          966  +################################################################
          967  +# 10. Construct output directory and file paths
          968  +# Figure-out how to name our intermediate and output directories.
          969  +# In order to avoid inadvertent mixing of object files built using
          970  +# different compilers, build configurations etc.,
          971  +#
          972  +# Naming convention (suffixes):
          973  +#   t = full thread support.
          974  +#   s = static library (as opposed to an import library)
          975  +#   g = linked to the debug enabled C run-time.
          976  +#   x = special static build when it links to the dynamic C run-time.
          977  +#
          978  +# The following macros are set in this section:
          979  +# SUFX - the suffix to use for binaries based on above naming convention
          980  +# BUILDDIRTOP - the toplevel default output directory
          981  +#      is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
          982  +# TMP_DIR - directory where object files are created
          983  +# OUT_DIR - directory where output executables are created
          984  +# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
          985  +# parent makefile (or command line). The default values are
          986  +# based on BUILDDIRTOP.
          987  +# STUBPREFIX - name of the stubs library for this project
          988  +# PRJIMPLIB - output path of the generated project import library
          989  +# PRJLIBNAME - name of generated project library
          990  +# PRJLIB     - output path of generated project library
          991  +# PRJSTUBLIBNAME - name of the generated project stubs library
          992  +# PRJSTUBLIB - output path of the generated project stubs library
          993  +# RESFILE - output resource file (only if not static build)
          994  +
          995  +SUFX	    = tsgx
          996  +
          997  +!if $(DEBUG)
          998  +BUILDDIRTOP = Debug
          999  +!else
         1000  +BUILDDIRTOP = Release
         1001  +!endif
         1002  +
         1003  +!if "$(MACHINE)" != "IX86"
         1004  +BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
         1005  +!endif
         1006  +!if $(VCVER) > 6
         1007  +BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
         1008  +!endif
         1009  +
         1010  +!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
         1011  +SUFX	    = $(SUFX:g=)
         1012  +!endif
         1013  +
         1014  +TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
         1015  +
         1016  +!if !$(STATIC_BUILD)
         1017  +TMP_DIRFULL = $(TMP_DIRFULL:Static=)
         1018  +SUFX	    = $(SUFX:s=)
         1019  +EXT	    = dll
         1020  +TMP_DIRFULL = $(TMP_DIRFULL:X=)
         1021  +SUFX	    = $(SUFX:x=)
         1022  +!else
         1023  +TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
         1024  +EXT	    = lib
         1025  +!if !$(MSVCRT)
         1026  +TMP_DIRFULL = $(TMP_DIRFULL:X=)
         1027  +SUFX	    = $(SUFX:x=)
         1028  +!endif
         1029  +!endif
         1030  +
         1031  +!if !$(TCL_THREADS)
         1032  +TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
         1033  +SUFX	    = $(SUFX:t=)
         1034  +!endif
         1035  +
         1036  +!ifndef TMP_DIR
         1037  +TMP_DIR	    = $(TMP_DIRFULL)
         1038  +!ifndef OUT_DIR
         1039  +OUT_DIR	    = .\$(BUILDDIRTOP)
         1040  +!endif
         1041  +!else
         1042  +!ifndef OUT_DIR
         1043  +OUT_DIR	    = $(TMP_DIR)
         1044  +!endif
         1045  +!endif
         1046  +
         1047  +# Relative paths -> absolute
         1048  +!if [echo OUT_DIR = \> nmakehlp.out] \
         1049  +   || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
         1050  +!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
         1051  +!endif
         1052  +!if [echo TMP_DIR = \>> nmakehlp.out] \
         1053  +   || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
         1054  +!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
         1055  +!endif
         1056  +!include nmakehlp.out
         1057  +
         1058  +# The name of the stubs library for the project being built
         1059  +STUBPREFIX      = $(PROJECT)stub
         1060  +
         1061  +# Set up paths to various Tcl executables and libraries needed by extensions
         1062  +!if $(DOING_TCL)
         1063  +
         1064  +TCLSHNAME       = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
         1065  +TCLSH		= $(OUT_DIR)\$(TCLSHNAME)
         1066  +TCLIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
         1067  +TCLLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
         1068  +TCLLIB		= $(OUT_DIR)\$(TCLLIBNAME)
         1069  +
         1070  +TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
         1071  +TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
         1072  +TCL_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"
         1073  +
         1074  +!else # ! $(DOING_TCL)
         1075  +
         1076  +!if $(TCLINSTALL) # Building against an installed Tcl
         1077  +
         1078  +# When building extensions, we need to locate tclsh. Depending on version
         1079  +# of Tcl we are building against, this may or may not have a "t" suffix.
         1080  +# Try various possibilities in turn.
         1081  +TCLSH		= $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
         1082  +!if !exist("$(TCLSH)") && $(TCL_THREADS)
         1083  +TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
         1084  +!endif
         1085  +!if !exist("$(TCLSH)")
         1086  +TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
         1087  +!endif
         1088  +
         1089  +TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
         1090  +TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
         1091  +# When building extensions, may be linking against Tcl that does not add
         1092  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1093  +!if !exist("$(TCLIMPLIB)")
         1094  +TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
         1095  +!endif
         1096  +TCL_LIBRARY	= $(_TCLDIR)\lib
         1097  +TCLREGLIB	= $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
         1098  +TCLDDELIB	= $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
         1099  +TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
         1100  +TCL_INCLUDES    = -I"$(_TCLDIR)\include"
         1101  +
         1102  +!else # Building against Tcl sources
         1103  +
         1104  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
         1105  +!if !exist($(TCLSH)) && $(TCL_THREADS)
         1106  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
         1107  +!endif
         1108  +!if !exist($(TCLSH))
         1109  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
         1110  +!endif
         1111  +TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
         1112  +TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
         1113  +# When building extensions, may be linking against Tcl that does not add
         1114  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1115  +!if !exist("$(TCLIMPLIB)")
         1116  +TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
         1117  +!endif
         1118  +TCL_LIBRARY	= $(_TCLDIR)\library
         1119  +TCLREGLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
         1120  +TCLDDELIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
         1121  +TCLTOOLSDIR	= $(_TCLDIR)\tools
         1122  +TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
         1123  +
         1124  +!endif # TCLINSTALL
         1125  +
         1126  +tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
         1127  +
         1128  +!endif # $(DOING_TCL)
         1129  +
         1130  +# We need a tclsh that will run on the host machine as part of the build.
         1131  +# IX86 runs on all architectures.
         1132  +!ifndef TCLSH_NATIVE
         1133  +!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
         1134  +TCLSH_NATIVE	= $(TCLSH)
         1135  +!else
         1136  +!error You must explicitly set TCLSH_NATIVE for cross-compilation
         1137  +!endif
         1138  +!endif
         1139  +
         1140  +# Do the same for Tk and Tk extensions that require the Tk libraries
         1141  +!if $(DOING_TK) || $(NEED_TK)
         1142  +WISHNAMEPREFIX = wish
         1143  +WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
         1144  +TKLIBNAME	= $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
         1145  +TKSTUBLIBNAME	= tkstub$(TK_VERSION).lib
         1146  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib
         1147  +
         1148  +!if $(DOING_TK)
         1149  +WISH 		= $(OUT_DIR)\$(WISHNAME)
         1150  +TKSTUBLIB	= $(OUT_DIR)\$(TKSTUBLIBNAME)
         1151  +TKIMPLIB	= $(OUT_DIR)\$(TKIMPLIBNAME)
         1152  +TKLIB		= $(OUT_DIR)\$(TKLIBNAME)
         1153  +TK_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"
         1154  +
         1155  +!else # effectively NEED_TK
         1156  +
         1157  +!if $(TKINSTALL) # Building against installed Tk
         1158  +WISH		= $(_TKDIR)\bin\$(WISHNAME)
         1159  +TKSTUBLIB	= $(_TKDIR)\lib\$(TKSTUBLIBNAME)
         1160  +TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
         1161  +# When building extensions, may be linking against Tk that does not add
         1162  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1163  +!if !exist("$(TKIMPLIB)")
         1164  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
         1165  +TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
         1166  +!endif
         1167  +TK_INCLUDES     = -I"$(_TKDIR)\include"
         1168  +!else # Building against Tk sources
         1169  +WISH		= $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
         1170  +TKSTUBLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
         1171  +TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
         1172  +# When building extensions, may be linking against Tk that does not add
         1173  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1174  +!if !exist("$(TKIMPLIB)")
         1175  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
         1176  +TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
         1177  +!endif
         1178  +TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
         1179  +!endif # TKINSTALL
         1180  +tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
         1181  +
         1182  +!endif # $(DOING_TK)
         1183  +!endif # $(DOING_TK) || $(NEED_TK)
         1184  +
         1185  +# Various output paths
         1186  +PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
         1187  +PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
         1188  +PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)
         1189  +
         1190  +PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
         1191  +PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)
         1192  +
         1193  +# If extension parent makefile has not defined a resource definition file,
         1194  +# we will generate one from standard template.
         1195  +!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
         1196  +!ifdef RCFILE
         1197  +RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
         1198  +!else
         1199  +RESFILE = $(TMP_DIR)\$(PROJECT).res
         1200  +!endif
         1201  +!endif
         1202  +
         1203  +###################################################################
         1204  +# 11. Construct the paths for the installation directories
         1205  +# The following macros get defined in this section:
         1206  +# LIB_INSTALL_DIR - where libraries should be installed
         1207  +# BIN_INSTALL_DIR - where the executables should be installed
         1208  +# DOC_INSTALL_DIR - where documentation should be installed
         1209  +# SCRIPT_INSTALL_DIR - where scripts should be installed
         1210  +# INCLUDE_INSTALL_DIR - where C include files should be installed
         1211  +# DEMO_INSTALL_DIR - where demos should be installed
         1212  +# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)
         1213  +
         1214  +!if $(DOING_TCL) || $(DOING_TK)
         1215  +LIB_INSTALL_DIR		= $(_INSTALLDIR)\lib
         1216  +BIN_INSTALL_DIR		= $(_INSTALLDIR)\bin
         1217  +DOC_INSTALL_DIR		= $(_INSTALLDIR)\doc
         1218  +!if $(DOING_TCL)
         1219  +SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
         1220  +!else # DOING_TK
         1221  +SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
         1222  +!endif
         1223  +DEMO_INSTALL_DIR	= $(SCRIPT_INSTALL_DIR)\demos
         1224  +INCLUDE_INSTALL_DIR	= $(_INSTALLDIR)\include
         1225  +
         1226  +!else # extension other than Tk
         1227  +
         1228  +PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
         1229  +LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
         1230  +BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
         1231  +DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
         1232  +SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
         1233  +DEMO_INSTALL_DIR	= $(PRJ_INSTALL_DIR)\demos
         1234  +INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include
         1235  +
         1236  +!endif
         1237  +
         1238  +###################################################################
         1239  +# 12. Set up actual options to be passed to the compiler and linker
         1240  +# Now we have all the information we need, set up the actual flags and
         1241  +# options that we will pass to the compiler and linker. The main
         1242  +# makefile should use these in combination with whatever other flags
         1243  +# and switches are specific to it.
         1244  +# The following macros are defined, names are for historical compatibility:
         1245  +# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
         1246  +# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
         1247  +# crt - Compiler switch that selects the appropriate C runtime
         1248  +# cdebug - Compiler switches related to debug AND optimizations
         1249  +# cwarn - Compiler switches that set warning levels
         1250  +# cflags - complete compiler switches (subsumes cdebug and cwarn)
         1251  +# ldebug - Linker switches controlling debug information and optimization
         1252  +# lflags - complete linker switches (subsumes ldebug) except subsystem type
         1253  +# dlllflags - complete linker switches to build DLLs (subsumes lflags)
         1254  +# conlflags - complete linker switches for console program (subsumes lflags)
         1255  +# guilflags - complete linker switches for GUI program (subsumes lflags)
         1256  +# baselibs - minimum Windows libraries required. Parent makefile can
         1257  +#    define PRJ_LIBS before including rules.rc if additional libs are needed
         1258  +
         1259  +OPTDEFINES	= -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
         1260  +
         1261  +!if $(TCL_MEM_DEBUG)
         1262  +OPTDEFINES	= $(OPTDEFINES) -DTCL_MEM_DEBUG
         1263  +!endif
         1264  +!if $(TCL_COMPILE_DEBUG)
         1265  +OPTDEFINES	= $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
         1266  +!endif
         1267  +!if $(TCL_THREADS)
         1268  +OPTDEFINES	= $(OPTDEFINES) -DTCL_THREADS=1
         1269  +!if $(USE_THREAD_ALLOC)
         1270  +OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
         1271  +!endif
         1272  +!endif
         1273  +!if $(STATIC_BUILD)
         1274  +OPTDEFINES	= $(OPTDEFINES) -DSTATIC_BUILD
         1275  +!endif
         1276  +!if $(TCL_NO_DEPRECATED)
         1277  +OPTDEFINES	= $(OPTDEFINES) -DTCL_NO_DEPRECATED
         1278  +!endif
         1279  +
         1280  +!if $(USE_STUBS)
         1281  +# Note we do not define USE_TCL_STUBS even when building Tk since some
         1282  +# test targets in Tk do not use stubs
         1283  +!if ! $(DOING_TCL)
         1284  +USE_STUBS_DEFS  = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
         1285  +!if $(NEED_TK)
         1286  +USE_STUBS_DEFS  = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
         1287  +!endif
         1288  +!endif
         1289  +!endif # USE_STUBS
         1290  +
         1291  +!if !$(DEBUG)
         1292  +OPTDEFINES	= $(OPTDEFINES) -DNDEBUG
         1293  +!if $(OPTIMIZING)
         1294  +OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
         1295  +!endif
         1296  +!endif
         1297  +!if $(PROFILE)
         1298  +OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_PROFILED
         1299  +!endif
         1300  +!if "$(MACHINE)" == "AMD64"
         1301  +OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DO64BIT
         1302  +!endif
         1303  +!if $(VCVERSION) < 1300
         1304  +OPTDEFINES	= $(OPTDEFINES) -DNO_STRTOI64
         1305  +!endif
         1306  +
         1307  +# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
         1308  +COMPILERFLAGS  = /D_ATL_XP_TARGETING
         1309  +
         1310  +# Following is primarily for the benefit of extensions. Tcl 8.5 builds
         1311  +# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
         1312  +# an extension, it is advisable (but not mandated) to use the same Windows
         1313  +# API as the Tcl build. This is accordingly defaulted below. A particular
         1314  +# extension can override this by pre-defining USE_WIDECHAR_API.
         1315  +!ifndef USE_WIDECHAR_API
         1316  +!if $(TCL_VERSION) > 85
         1317  +USE_WIDECHAR_API = 1
         1318  +!else
         1319  +USE_WIDECHAR_API = 0
         1320  +!endif
         1321  +!endif
         1322  +
         1323  +!if $(USE_WIDECHAR_API)
         1324  +COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE 
         1325  +!endif
         1326  +
         1327  +# Like the TEA system only set this non empty for non-Tk extensions
         1328  +# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
         1329  +# so we pass both
         1330  +!if !$(DOING_TCL) && !$(DOING_TK)
         1331  +PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
         1332  +               -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
         1333  +               -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
         1334  +               -DMODULE_SCOPE=extern 
         1335  +!endif
         1336  +
         1337  +# crt picks the C run time based on selected OPTS
         1338  +!if $(MSVCRT)
         1339  +!if $(DEBUG) && !$(UNCHECKED)
         1340  +crt = -MDd
         1341  +!else
         1342  +crt = -MD
         1343  +!endif
         1344  +!else
         1345  +!if $(DEBUG) && !$(UNCHECKED)
         1346  +crt = -MTd
         1347  +!else
         1348  +crt = -MT
         1349  +!endif
         1350  +!endif
         1351  +
         1352  +# cdebug includes compiler options for debugging as well as optimization.
         1353  +!if $(DEBUG)
         1354  +
         1355  +# In debugging mode, optimizations need to be disabled
         1356  +cdebug = -Zi -Od $(DEBUGFLAGS)
         1357  +
         1358  +!else
         1359  +
         1360  +cdebug = $(OPTIMIZATIONS)
         1361  +!if $(SYMBOLS)
         1362  +cdebug = $(cdebug) -Zi
         1363  +!endif
         1364  +
         1365  +!endif # $(DEBUG)
         1366  +
         1367  +# cwarn includes default warning levels.
         1368  +cwarn = $(WARNINGS)
         1369  +
         1370  +!if "$(MACHINE)" == "AMD64"
         1371  +# Disable pointer<->int warnings related to cast between different sizes
         1372  +# There are a gadzillion of these due to use of ClientData and
         1373  +# clutter up compiler
         1374  +# output increasing chance of a real warning getting lost. So disable them.
         1375  +# Eventually some day, Tcl will be 64-bit clean.
         1376  +cwarn = $(cwarn) -wd4311 -wd4312
         1377  +!endif
         1378  +
         1379  +### Common compiler options that are architecture specific
         1380  +!if "$(MACHINE)" == "ARM"
         1381  +carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
         1382  +!else
         1383  +carch =
         1384  +!endif
         1385  +
         1386  +!if $(DEBUG)
         1387  +# Turn warnings into errors
         1388  +cwarn = $(cwarn) -WX
         1389  +!endif
         1390  +
         1391  +INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
         1392  +!if !$(DOING_TCL) && !$(DOING_TK)
         1393  +INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
         1394  +!endif
         1395  +
         1396  +# These flags are defined roughly in the order of the pre-reform
         1397  +# rules.vc/makefile.vc to help visually compare that the pre- and
         1398  +# post-reform build logs
         1399  +
         1400  +# cflags contains generic flags used for building practically all object files
         1401  +cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
         1402  +
         1403  +# appcflags contains $(cflags) and flags for building the application
         1404  +# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
         1405  +# flags used for building shared object files The two differ in the
         1406  +# BUILD_$(PROJECT) macro which should be defined only for the shared
         1407  +# library *implementation* and not for its caller interface
         1408  +
         1409  +appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
         1410  +appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
         1411  +pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
         1412  +pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
         1413  +
         1414  +# stubscflags contains $(cflags) plus flags used for building a stubs
         1415  +# library for the package.  Note: -DSTATIC_BUILD is defined in
         1416  +# $(OPTDEFINES) only if the OPTS configuration indicates a static
         1417  +# library. However the stubs library is ALWAYS static hence included
         1418  +# here irrespective of the OPTS setting.
         1419  +#
         1420  +# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
         1421  +# without stating why. Tcl itself compiled stubs libs with this flag.
         1422  +# so we do not remove it from cflags. -GL may prevent extensions
         1423  +# compiled with one VC version to fail to link against stubs library
         1424  +# compiled with another VC version. Check for this and fix accordingly.
         1425  +stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
         1426  +
         1427  +# Link flags 
         1428  +
         1429  +!if $(DEBUG)
         1430  +ldebug	= -debug -debugtype:cv
         1431  +!else
         1432  +ldebug	= -release -opt:ref -opt:icf,3
         1433  +!if $(SYMBOLS)
         1434  +ldebug	= $(ldebug) -debug -debugtype:cv
         1435  +!endif
         1436  +!endif
         1437  +
         1438  +# Note: Profiling is currently only possible with the Visual Studio Enterprise
         1439  +!if $(PROFILE)
         1440  +ldebug= $(ldebug) -profile
         1441  +!endif
         1442  +
         1443  +### Declarations common to all linker versions 
         1444  +lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
         1445  +
         1446  +!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
         1447  +lflags	= $(lflags) -nodefaultlib:libucrt.lib
         1448  +!endif
         1449  +
         1450  +# Old linkers (Visual C++ 6 in particular) will link for fast loading
         1451  +# on Win98. Since we do not support Win98 any more, we specify nowin98
         1452  +# as recommended for NT and later. However, this is only required by
         1453  +# IX86 on older compilers and only needed if we are not doing a static build.
         1454  +
         1455  +!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
         1456  +!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
         1457  +# Align sections for PE size savings.
         1458  +lflags	= $(lflags) -opt:nowin98
         1459  +!endif
         1460  +!endif
         1461  +
         1462  +dlllflags = $(lflags) -dll
         1463  +conlflags = $(lflags) -subsystem:console
         1464  +guilflags = $(lflags) -subsystem:windows
         1465  +
         1466  +# Libraries that are required for every image.
         1467  +# Extensions should define any additional libraries with $(PRJ_LIBS)
         1468  +winlibs   = kernel32.lib advapi32.lib
         1469  +
         1470  +!if $(NEED_TK)
         1471  +winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
         1472  +!endif
         1473  +
         1474  +# Avoid 'unresolved external symbol __security_cookie' errors.
         1475  +# c.f. http://support.microsoft.com/?id=894573
         1476  +!if "$(MACHINE)" == "AMD64"
         1477  +!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
         1478  +winlibs   = $(winlibs) bufferoverflowU.lib
         1479  +!endif
         1480  +!endif
         1481  +
         1482  +baselibs = $(winlibs) $(PRJ_LIBS)
         1483  +
         1484  +!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
         1485  +baselibs   = $(baselibs) ucrt.lib
         1486  +!endif
         1487  +
         1488  +################################################################
         1489  +# 13. Define standard commands, common make targets and implicit rules
         1490  +
         1491  +CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
         1492  +CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
         1493  +CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
         1494  +
         1495  +LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
         1496  +DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1497  +
         1498  +CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1499  +GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1500  +RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
         1501  +	    $(TCL_INCLUDES) \
         1502  +	    -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
         1503  +	    -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
         1504  +	    -DDOTVERSION=\"$(DOTVERSION)\" \
         1505  +	    -DVERSION=\"$(VERSION)\" \
         1506  +	    -DSUFX=\"$(SUFX)\" \
         1507  +            -DPROJECT=\"$(PROJECT)\" \
         1508  +            -DPRJLIBNAME=\"$(PRJLIBNAME)\" 
         1509  +
         1510  +!ifndef DEFAULT_BUILD_TARGET
         1511  +DEFAULT_BUILD_TARGET = $(PROJECT)
         1512  +!endif
         1513  +
         1514  +default-target: $(DEFAULT_BUILD_TARGET)
         1515  +
         1516  +default-pkgindex:
         1517  +	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
         1518  +	    [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
         1519  +
         1520  +default-pkgindex-tea:
         1521  +	@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
         1522  +@PACKAGE_VERSION@    $(DOTVERSION)
         1523  +@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
         1524  +@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
         1525  +@PKG_LIB_FILE@       $(PRJLIBNAME)
         1526  +<<
         1527  +
         1528  +
         1529  +default-install: default-install-binaries default-install-libraries
         1530  +
         1531  +default-install-binaries: $(PRJLIB)
         1532  +	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
         1533  +	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
         1534  +	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
         1535  +
         1536  +default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
         1537  +	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
         1538  +	@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
         1539  +	@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
         1540  +	@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
         1541  +
         1542  +default-install-stubs:
         1543  +	@echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
         1544  +	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
         1545  +	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
         1546  +
         1547  +default-install-docs-html:
         1548  +	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
         1549  +	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
         1550  +	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
         1551  +
         1552  +default-install-docs-n:
         1553  +	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
         1554  +	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
         1555  +	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
         1556  +
         1557  +default-install-demos:
         1558  +	@echo Installing demos to '$(DEMO_INSTALL_DIR)'
         1559  +	@if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
         1560  +	@if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
         1561  +
         1562  +default-clean:
         1563  +	@echo Cleaning $(TMP_DIR)\* ...
         1564  +	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
         1565  +	@echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
         1566  +	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
         1567  +	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
         1568  +	@if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
         1569  +	@echo Cleaning $(WINDIR)\nmhlp-out.txt ...
         1570  +	@if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
         1571  +	@echo Cleaning $(WINDIR)\_junk.pch ...
         1572  +	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
         1573  +	@echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
         1574  +	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
         1575  +	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
         1576  +	@echo Cleaning $(WINDIR)\versions.vc, version.vc ...
         1577  +	@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
         1578  +	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
         1579  +
         1580  +default-hose: default-clean
         1581  +	@echo Hosing $(OUT_DIR)\* ...
         1582  +	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
         1583  +
         1584  +# Only for backward compatibility
         1585  +default-distclean: default-hose
         1586  +
         1587  +default-setup:
         1588  +	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
         1589  +	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
         1590  +
         1591  +!if "$(TESTPAT)" != ""
         1592  +TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
         1593  +!endif
         1594  +
         1595  +default-test: default-setup $(PROJECT)
         1596  +	@set TCLLIBPATH=$(OUT_DIR:\=/)
         1597  +	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
         1598  +	cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
         1599  +
         1600  +default-shell: default-setup $(PROJECT)
         1601  +	@set TCLLIBPATH=$(OUT_DIR:\=/)
         1602  +	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
         1603  +	$(DEBUGGER) $(TCLSH)
         1604  +
         1605  +# Generation of Windows version resource 
         1606  +!ifdef RCFILE
         1607  +
         1608  +# Note: don't use $** in below rule because there may be other dependencies
         1609  +# and only the "master" rc must be passed to the resource compiler
         1610  +$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
         1611  +	$(RESCMD) $(RCDIR)\$(PROJECT).rc
         1612  +
         1613  +!else
         1614  +
         1615  +# If parent makefile has not defined a resource definition file,
         1616  +# we will generate one from standard template.
         1617  +$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
         1618  +
         1619  +$(TMP_DIR)\$(PROJECT).rc:
         1620  +	@$(COPY) << $(TMP_DIR)\$(PROJECT).rc
         1621  +#include <winver.h>
         1622  +
         1623  +VS_VERSION_INFO VERSIONINFO
         1624  + FILEVERSION	COMMAVERSION
         1625  + PRODUCTVERSION	COMMAVERSION
         1626  + FILEFLAGSMASK	0x3fL
         1627  +#ifdef DEBUG
         1628  + FILEFLAGS	VS_FF_DEBUG
         1629  +#else
         1630  + FILEFLAGS	0x0L
         1631  +#endif
         1632  + FILEOS		VOS_NT_WINDOWS32
         1633  + FILETYPE	VFT_DLL
         1634  + FILESUBTYPE	0x0L
         1635  +BEGIN
         1636  +    BLOCK "StringFileInfo"
         1637  +    BEGIN
         1638  +        BLOCK "040904b0"
         1639  +        BEGIN
         1640  +            VALUE "FileDescription",  "Tcl extension " PROJECT
         1641  +            VALUE "OriginalFilename", PRJLIBNAME
         1642  +            VALUE "FileVersion",      DOTVERSION
         1643  +            VALUE "ProductName",      "Package " PROJECT " for Tcl"
         1644  +            VALUE "ProductVersion",   DOTVERSION 
         1645  +        END
         1646  +    END
         1647  +    BLOCK "VarFileInfo"
         1648  +    BEGIN
         1649  +        VALUE "Translation", 0x409, 1200
         1650  +    END
         1651  +END
         1652  +
         1653  +<<
         1654  +
         1655  +!endif # ifdef RCFILE
         1656  +
         1657  +!ifndef DISABLE_IMPLICIT_RULES
         1658  +DISABLE_IMPLICIT_RULES = 0
         1659  +!endif
         1660  +
         1661  +!if !$(DISABLE_IMPLICIT_RULES)
         1662  +# Implicit rule definitions - only for building library objects. For stubs and
         1663  +# main application, the master makefile should define explicit rules.
         1664  +
         1665  +{$(ROOT)}.c{$(TMP_DIR)}.obj::
         1666  +	$(CCPKGCMD) @<<
         1667  +$<
         1668  +<<
         1669  +
         1670  +{$(WINDIR)}.c{$(TMP_DIR)}.obj::
         1671  +	$(CCPKGCMD) @<<
         1672  +$<
         1673  +<<
         1674  +
         1675  +{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
         1676  +	$(CCPKGCMD) @<<
         1677  +$<
         1678  +<<
         1679  +
         1680  +{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
         1681  +	$(CCPKGCMD) @<<
         1682  +$<
         1683  +<<
         1684  +
         1685  +{$(RCDIR)}.rc{$(TMP_DIR)}.res:
         1686  +	$(RESCMD) $<
         1687  +
         1688  +{$(WINDIR)}.rc{$(TMP_DIR)}.res:
         1689  +	$(RESCMD) $<
         1690  +
         1691  +{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
         1692  +	$(RESCMD) $<
         1693  +
         1694  +.SUFFIXES:
         1695  +.SUFFIXES:.c .rc
         1696  +
         1697  +!endif
         1698  +
         1699  +################################################################
         1700  +# 14. Sanity check selected options against Tcl build options
         1701  +# When building an extension, certain configuration options should
         1702  +# match the ones used when Tcl was built. Here we check and
         1703  +# warn on a mismatch.
         1704  +!if ! $(DOING_TCL)
         1705  +
         1706  +!if $(TCLINSTALL) # Building against an installed Tcl
         1707  +!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
         1708  +TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
         1709  +!endif
         1710  +!else # ! $(TCLINSTALL) - building against Tcl source
         1711  +!if exist("$(OUT_DIR)\tcl.nmake")
         1712  +TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
         1713  +!endif
         1714  +!endif # TCLINSTALL
         1715  +
         1716  +!if $(CONFIG_CHECK)
         1717  +!ifdef TCLNMAKECONFIG
         1718  +!include $(TCLNMAKECONFIG)
         1719  +
         1720  +!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
         1721  +!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
         1722  +!endif
         1723  +!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
         1724  +!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
         1725  +!endif
         1726  +!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
         1727  +!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
         1728  +!endif
         1729  +!endif
         1730  +
         1731  +!endif # TCLNMAKECONFIG
         1732  +
         1733  +!endif # ! $(DOING_TCL)
         1734  +
         1735  +
         1736  +#----------------------------------------------------------
         1737  +# Display stats being used.
         1738  +#----------------------------------------------------------
         1739  +
         1740  +!if !$(DOING_TCL)
         1741  +!message *** Building against Tcl at '$(_TCLDIR)'
         1742  +!endif
         1743  +!if !$(DOING_TK) && $(NEED_TK)
         1744  +!message *** Building against Tk at '$(_TKDIR)'
         1745  +!endif
         1746  +!message *** Intermediate directory will be '$(TMP_DIR)'
         1747  +!message *** Output directory will be '$(OUT_DIR)'
         1748  +!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
         1749  +!message *** Suffix for binaries will be '$(SUFX)'
         1750  +!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
         1751  +
         1752  +!endif # ifdef _RULES_VC

Added extensions/tnc/win/targets.vc.

            1  +#------------------------------------------------------------- -*- makefile -*-
            2  +# targets.vc --
            3  +#
            4  +# Part of the nmake based build system for Tcl and its extensions.
            5  +# This file defines some standard targets for the convenience of extensions
            6  +# and can be optionally included by the extension makefile.
            7  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
            8  +
            9  +$(PROJECT): setup pkgindex $(PRJLIB)
           10  +
           11  +!ifdef PRJ_STUBOBJS
           12  +$(PROJECT): $(PRJSTUBLIB)
           13  +$(PRJSTUBLIB): $(PRJ_STUBOBJS)
           14  +	$(LIBCMD) $**
           15  +
           16  +$(PRJ_STUBOBJS):
           17  +	$(CCSTUBSCMD) %s
           18  +!endif # PRJ_STUBOBJS
           19  +
           20  +!ifdef PRJ_MANIFEST
           21  +$(PROJECT): $(PRJLIB).manifest
           22  +$(PRJLIB).manifest: $(PRJ_MANIFEST)
           23  +	@nmakehlp -s << $** >$@
           24  +@MACHINE@	  $(MACHINE:IX86=X86)
           25  +<<
           26  +!endif
           27  +
           28  +!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
           29  +$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
           30  +!if $(STATIC_BUILD)
           31  +       $(LIBCMD) $**
           32  +!else
           33  +       $(DLLCMD) $**
           34  +       $(_VC_MANIFEST_EMBED_DLL)
           35  +!endif
           36  +       -@del $*.exp
           37  +!endif
           38  +
           39  +!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
           40  +$(PRJ_OBJS): $(PRJ_HEADERS)
           41  +!endif
           42  +
           43  +# If parent makefile has defined stub objects, add their installation
           44  +# to the default install
           45  +!if "$(PRJ_STUBOBJS)" != ""
           46  +default-install: default-install-stubs
           47  +!endif
           48  +
           49  +# Unlike the other default targets, these cannot be in rules.vc because
           50  +# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
           51  +# that the parent makefile will not define until after including rules-ext.vc
           52  +!if "$(PRJ_HEADERS_PUBLIC)" != ""
           53  +default-install: default-install-headers
           54  +default-install-headers:
           55  +	@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
           56  +	@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
           57  +!endif
           58  +
           59  +!if "$(DISABLE_STANDARD_TARGETS)" == ""
           60  +DISABLE_STANDARD_TARGETS = 0
           61  +!endif
           62  +
           63  +!if "$(DISABLE_TARGET_setup)" == ""
           64  +DISABLE_TARGET_setup = 0
           65  +!endif
           66  +!if "$(DISABLE_TARGET_install)" == ""
           67  +DISABLE_TARGET_install = 0
           68  +!endif
           69  +!if "$(DISABLE_TARGET_clean)" == ""
           70  +DISABLE_TARGET_clean = 0
           71  +!endif
           72  +!if "$(DISABLE_TARGET_test)" == ""
           73  +DISABLE_TARGET_test = 0
           74  +!endif
           75  +!if "$(DISABLE_TARGET_shell)" == ""
           76  +DISABLE_TARGET_shell = 0
           77  +!endif
           78  +
           79  +!if !$(DISABLE_STANDARD_TARGETS)
           80  +!if !$(DISABLE_TARGET_setup)
           81  +setup: default-setup
           82  +!endif
           83  +!if !$(DISABLE_TARGET_install)
           84  +install: default-install
           85  +!endif
           86  +!if !$(DISABLE_TARGET_clean)
           87  +clean: default-clean
           88  +realclean: hose
           89  +hose: default-hose
           90  +distclean: realclean default-distclean
           91  +!endif
           92  +!if !$(DISABLE_TARGET_test)
           93  +test: default-test
           94  +!endif
           95  +!if !$(DISABLE_TARGET_shell)
           96  +shell: default-shell
           97  +!endif
           98  +!endif # DISABLE_STANDARD_TARGETS

Changes to generic/dom.c.

    43     43   
    44     44   
    45     45   /*---------------------------------------------------------------------------
    46     46   |   Includes
    47     47   |
    48     48   \--------------------------------------------------------------------------*/
    49     49   #include <tcl.h>
    50         -#include <stdlib.h>
    51         -#include <string.h>
    52     50   #include <dom.h>
    53     51   #include <domxpath.h>
    54         -#include <utf8conv.h>
    55     52   #include <tclexpat.h>
    56     53   
    57     54   
    58         -
    59         -/*---------------------------------------------------------------------------
    60         -|   Defines
           55  +/* #define DEBUG */
           56  +/*----------------------------------------------------------------------------
           57  +|   Debug Macros
    61     58   |
    62         -\--------------------------------------------------------------------------*/
    63         -#define DBG(x)
    64         -#define TDOM_NS
    65         -#define XSLT_NAMESPACE  "http://www.w3.org/1999/XSL/Transform"
           59  +\---------------------------------------------------------------------------*/
           60  +#ifdef DEBUG
           61  +# define DBG(x) x
           62  +#else
           63  +# define DBG(x) 
           64  +#endif
    66     65   
    67     66   #define MutationEvent()
    68     67   #define MutationEvent2(type,node)
    69     68   #define MutationEvent3(type,node,relatioNode)
    70     69   
    71     70   #define MCHK(a)  if ((a)==NULL) { \
    72     71                        fprintf(stderr, \
................................................................................
    91     90   #endif
    92     91   
    93     92   static int domModuleIsInitialized = 0;
    94     93   TDomThreaded(static Tcl_Mutex initMutex;)
    95     94   
    96     95   static char *domException2StringTable [] = {
    97     96   
    98         -    "OK - no expection",
           97  +    "OK - no exception",
    99     98       "INDEX_SIZE_ERR",
   100     99       "DOMSTRING_SIZE_ERR",
   101    100       "HIERARCHY_REQUEST_ERR",
   102    101       "WRONG_DOCUMENT_ERR",
   103    102       "INVALID_CHARACTER_ERR",
   104    103       "NO_DATA_ALLOWED_ERR",
   105    104       "NO_MODIFICATION_ALLOWED_ERR",
................................................................................
   108    107       "INUSE_ATTRIBUTE_ERR"
   109    108   };
   110    109   
   111    110   static char tdom_usage[] =
   112    111                   "Usage tdom <expat parser obj> <subCommand>, where subCommand can be:\n"
   113    112                   "           enable             \n"
   114    113                   "           getdoc             \n"
   115         -                "           setResultEncoding  \n"
   116    114                   "           setStoreLineColumn \n"
   117    115                   ;
   118    116   
   119         -
   120         -/*---------------------------------------------------------------------------
   121         -|   type domActiveNS
   122         -|
   123         -\--------------------------------------------------------------------------*/
   124         -typedef struct _domActiveNS {
   125         -
   126         -    int    depth;
   127         -    domNS *namespace;
   128         -
   129         -} domActiveNS;
   130         -
   131    117   /*---------------------------------------------------------------------------
   132    118   |   type domBaseURIstackElem
   133    119   |
   134    120   \--------------------------------------------------------------------------*/
   135    121   typedef struct _domActiveBaseURI {
   136    122   
   137    123       int   depth;
................................................................................
   146    132   typedef struct _domReadInfo {
   147    133   
   148    134       XML_Parser        parser;
   149    135       domDocument      *document;
   150    136       domNode          *currentNode;
   151    137       int               depth;
   152    138       int               ignoreWhiteSpaces;
          139  +    int               cdataSection;
   153    140       Tcl_DString      *cdata;
   154         -    TEncoding        *encoding_8bit;
   155    141       int               storeLineColumn;
          142  +    int               ignorexmlns;
   156    143       int               feedbackAfter;
   157         -    int               lastFeedbackPosition;
          144  +    Tcl_Obj          *feedbackCmd;
          145  +    XML_Index         nextFeedbackPosition;
   158    146       Tcl_Interp       *interp;
   159    147       int               activeNSsize;
   160    148       int               activeNSpos;
   161    149       domActiveNS      *activeNS;
   162    150       int               baseURIstackSize;
   163    151       int               baseURIstackPos;
   164    152       domActiveBaseURI *baseURIstack;
   165    153       int               insideDTD;
          154  +    int               status;
   166    155   
   167    156   } domReadInfo;
   168    157   
   169    158   /*----------------------------------------------------------------------------
   170    159   |   Prototypes
   171    160   |
   172    161   \---------------------------------------------------------------------------*/
................................................................................
   353    342   {
   354    343       const char *p;
   355    344       int   clen;
   356    345       
   357    346       p = str;
   358    347       while (*p) {
   359    348           clen = UTF8_CHAR_LEN(*p);
          349  +        if (clen > 4) return 0;
   360    350           if (UTF8_XMLCHAR((unsigned const char *)p,clen))
   361    351               p += clen;
   362    352           else return 0;
   363    353       }
   364    354       return 1;
   365    355   }
          356  +
          357  +/*---------------------------------------------------------------------------
          358  +|   domIsBMPChar 
          359  +|
          360  +\--------------------------------------------------------------------------*/
          361  +int
          362  +domIsBMPChar (
          363  +    const char *str
          364  +    )
          365  +{
          366  +    const char *p;
          367  +    int   clen;
          368  +    
          369  +    p = str;
          370  +    while (*p) {
          371  +        clen = UTF8_CHAR_LEN(*p);
          372  +        if (clen > 3 || clen == 0) return 0;
          373  +        p += clen;
          374  +    }
          375  +    return 1;
          376  +}
   366    377   
   367    378   /*---------------------------------------------------------------------------
   368    379   |   domIsComment
   369    380   |
   370    381   \--------------------------------------------------------------------------*/
   371    382   int
   372    383   domIsComment (
................................................................................
   482    493   
   483    494   int
   484    495   domPrecedes (
   485    496       domNode *node,
   486    497       domNode *other
   487    498       )
   488    499   {
   489         -    domNode *nodeAncestor, *otherAncestor, *otherToplevel;
          500  +    domNode *nodeAncestor, *otherAncestor;
   490    501       domAttrNode *attrN, *attrO;
   491    502       
   492    503       if (node == other) {
   493    504           return 0;
   494    505       }
   495    506       
   496    507       if (node->nodeType == ATTRIBUTE_NODE) {
................................................................................
   540    551   #ifndef TCL_THREADS
   541    552       if (node->ownerDocument->nodeFlags & NEEDS_RENUMBERING) {
   542    553           domRenumberTree (node->ownerDocument->rootNode);
   543    554           node->ownerDocument->nodeFlags &= ~NEEDS_RENUMBERING;
   544    555       }
   545    556       return (node->nodeNumber < other->nodeNumber);
   546    557   # else 
          558  +    if (node->ownerDocument->nodeFlags & NEEDS_RENUMBERING
          559  +        && node->ownerDocument->refCount <= 1) {
          560  +        domRenumberTree (node->ownerDocument->rootNode);
          561  +        node->ownerDocument->nodeFlags &= ~NEEDS_RENUMBERING;
          562  +    }
   547    563       if (!(node->ownerDocument->nodeFlags & NEEDS_RENUMBERING)) {
   548    564           return (node->nodeNumber < other->nodeNumber);
   549    565       }
   550    566   #endif
   551    567       
   552    568       otherAncestor = other;
   553    569       while (otherAncestor->parentNode) {
   554    570           otherAncestor = otherAncestor->parentNode;
   555    571           if (otherAncestor == node) {
   556    572               return 1;
   557    573           }
   558    574       }
   559         -    otherToplevel = otherAncestor;
   560    575       
   561    576       nodeAncestor = node;
   562    577       while (nodeAncestor->parentNode) {
   563    578           otherAncestor = other;
   564    579           while (otherAncestor->parentNode) {
   565    580               if (nodeAncestor->parentNode == otherAncestor->parentNode) {
   566    581                   nodeAncestor = nodeAncestor->nextSibling;
................................................................................
   688    703       return NULL;
   689    704   }
   690    705   
   691    706   /*---------------------------------------------------------------------------
   692    707   |   domIsNamespaceInScope
   693    708   |
   694    709   \--------------------------------------------------------------------------*/
   695         -static int
          710  +int
   696    711   domIsNamespaceInScope (
   697    712       domActiveNS *NSstack,
   698    713       int          NSstackPos,
   699    714       const char  *prefix,
   700    715       const char  *namespaceURI
   701    716   )
   702    717   {
................................................................................
   795    810       domNS *ns = NULL;
   796    811   
   797    812       DBG(fprintf(stderr, "domNewNamespace '%s' --> '%s' \n", prefix, namespaceURI);)
   798    813   
   799    814       ns = domLookupNamespace (doc, prefix, namespaceURI);
   800    815       if (ns != NULL) return ns;
   801    816       doc->nsptr++;
          817  +#ifdef TDOM_LESS_NS
   802    818       if (doc->nsptr > 254) {
   803    819           DBG(fprintf (stderr, "maximum number of namespaces exceeded!!!\n");)
   804    820           domPanic("domNewNamespace: maximum number of namespaces exceeded!");
   805    821       }
          822  +#endif
   806    823       if (doc->nsptr >= doc->nslen) {
   807    824           doc->namespaces = (domNS**) REALLOC ((char*) doc->namespaces,
   808    825                                                sizeof (domNS*) * 2 * doc->nslen);
   809    826           doc->nslen *= 2;
   810    827       }
   811    828       doc->namespaces[doc->nsptr] = (domNS*)MALLOC (sizeof (domNS));
   812    829       ns = doc->namespaces[doc->nsptr];
................................................................................
   871    888   domNamespaceURI (
   872    889       domNode *node
   873    890   )
   874    891   {
   875    892       domAttrNode *attr;
   876    893       domNS       *ns;
   877    894   
   878         -    if (!node->namespace) return NULL;
   879    895       if (node->nodeType == ATTRIBUTE_NODE) {
   880    896           attr = (domAttrNode*)node;
          897  +        if (!attr->namespace) return NULL;
   881    898           if (attr->nodeFlags & IS_NS_NODE) return NULL;
   882    899           ns = attr->parentNode->ownerDocument->namespaces[attr->namespace-1];
   883    900       } else
   884    901       if (node->nodeType == ELEMENT_NODE) {
          902  +        if (!node->namespace) return NULL;
   885    903           ns = node->ownerDocument->namespaces[node->namespace-1];
   886    904       } else {
   887    905           return NULL;
   888    906       }
   889    907       return ns->uri;
   890    908   }
   891    909   
................................................................................
   898    916   domNamespacePrefix (
   899    917       domNode *node
   900    918   )
   901    919   {
   902    920       domAttrNode *attr;
   903    921       domNS *ns;
   904    922   
   905         -    if (!node->namespace) return NULL;
   906    923       if (node->nodeType == ATTRIBUTE_NODE) {
   907    924           attr = (domAttrNode*)node;
          925  +        if (!attr->namespace) return NULL;
   908    926           ns = attr->parentNode->ownerDocument->namespaces[attr->namespace-1];
   909    927       } else
   910    928       if (node->nodeType == ELEMENT_NODE) {
          929  +        if (!node->namespace) return NULL;
   911    930           ns = node->ownerDocument->namespaces[node->namespace-1];
   912    931       } else {
   913    932           return NULL;
   914    933       }
   915    934       if (ns) return ns->prefix;
   916    935       return NULL;
   917    936   }
................................................................................
  1001   1020    *      Returns the previous node to the given node or NULL, if there
  1002   1021    *      is no previous node. This function is needed in situations,
  1003   1022    *      where the given node may also be an domAttrNode. Namespace
  1004   1023    *      declaring attributes are treated as any other
  1005   1024    *      attributes. Since the domAttrNode struct doesn't has an
  1006   1025    *      element for the previous attribute, we need a function for the
  1007   1026    *      relatively rare cases, the 'previous attribute' is
  1008         - *      needed. Remeber, that the XML rec say, that there is no
         1027  + *      needed. Remember, that the XML rec say, that there is no
  1009   1028    *      specific order of the attributes of a node.
  1010   1029    *
  1011   1030    * Results: 
  1012   1031    *      A pointer to the previous node of the given one
  1013   1032    *      or NULL, if there isn't a previous node.
  1014   1033    *
  1015   1034    * Side effects:
................................................................................
  1060   1079   {
  1061   1080       domReadInfo   *info = userData;
  1062   1081       domNode       *node, *parentNode;
  1063   1082       domLineColumn *lc;
  1064   1083       domAttrNode   *attrnode, *lastAttr;
  1065   1084       const char   **atPtr, **idAttPtr;
  1066   1085       Tcl_HashEntry *h;
  1067         -    int            hnew, len, pos, idatt, newNS;
         1086  +    int            hnew, len, pos, idatt, newNS, result;
  1068   1087       const char    *xmlns, *localname;
  1069   1088       char           tagPrefix[MAX_PREFIX_LEN];
  1070   1089       char           prefix[MAX_PREFIX_LEN];
  1071   1090       domNS         *ns;
  1072   1091       char           feedbackCmd[24];
  1073   1092   
  1074   1093       if (info->feedbackAfter) {
  1075   1094   
  1076         -        if (info->lastFeedbackPosition
  1077         -             < XML_GetCurrentByteIndex (info->parser)
         1095  +        if (info->nextFeedbackPosition
         1096  +             <= XML_GetCurrentByteIndex (info->parser)
  1078   1097           ) {
  1079         -            sprintf(feedbackCmd, "%s", "::dom::domParseFeedback");
  1080         -            if (Tcl_Eval(info->interp, feedbackCmd) != TCL_OK) {
         1098  +            if (info->feedbackCmd) {
         1099  +                result = Tcl_GlobalEvalObj(info->interp, info->feedbackCmd);
         1100  +            } else {
         1101  +                sprintf(feedbackCmd, "%s", "::dom::domParseFeedback");
         1102  +                result = Tcl_Eval(info->interp, feedbackCmd);
         1103  +            }
         1104  +            if (result != TCL_OK) {
  1081   1105                   DBG(fprintf(stderr, "%s\n", 
  1082         -                            Tcl_GetStringResult (info->interp));)
  1083         -                /* FIXME: We simply ignore script errors in the
  1084         -                   feedbackCmd, for now. One fine day, expat may provide
  1085         -                   a way to cancel an already started parse run from
  1086         -                   inside a handler. Then we should revisit this. */
  1087         -                /* exit(1) */    
         1106  +                            Tcl_GetStringResult (info->interp)););
         1107  +                info->status = result;
         1108  +                XML_StopParser(info->parser, 1);
         1109  +                return;
  1088   1110               }
  1089         -            info->lastFeedbackPosition += info->feedbackAfter;
         1111  +            info->nextFeedbackPosition = 
         1112  +                XML_GetCurrentByteIndex (info->parser) + info->feedbackAfter;
         1113  +            Tcl_ResetResult (info->interp);
  1090   1114           }
  1091   1115       }
  1092   1116   
  1093   1117       DispatchPCDATA (info);
  1094   1118       
  1095   1119       h = Tcl_CreateHashEntry(&HASHTAB(info->document,tdom_tagNames), name,
  1096   1120                               &hnew);
................................................................................
  1157   1181   
  1158   1182   
  1159   1183       lastAttr = NULL;
  1160   1184       /*--------------------------------------------------------------
  1161   1185       |   process namespace declarations
  1162   1186       |
  1163   1187       \-------------------------------------------------------------*/
  1164         -#ifdef TDOM_NS
  1165         -    for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {
  1166         -
  1167         -        if (strncmp(atPtr[0], "xmlns", 5) == 0) {
  1168         -            xmlns = atPtr[0];
  1169         -            newNS = 1;
  1170         -            if (xmlns[5] == ':') {
  1171         -                if (domIsNamespaceInScope (info->activeNS, info->activeNSpos,
  1172         -                                           &(xmlns[6]), atPtr[1])) {
  1173         -                    ns = domLookupPrefix (info->currentNode, &(xmlns[6]));
  1174         -                    newNS = 0;
  1175         -                }
  1176         -                else {
  1177         -                    ns = domNewNamespace(info->document, &xmlns[6], atPtr[1]);
  1178         -                }
  1179         -            } else {
  1180         -                ns = domNewNamespace(info->document, "", atPtr[1]);
  1181         -            }
  1182         -            if (newNS) {
  1183         -                /* push active namespace */
  1184         -                info->activeNSpos++;
  1185         -                if (info->activeNSpos >= info->activeNSsize) {
  1186         -                    info->activeNS = (domActiveNS*) REALLOC(
  1187         -                        (char*)info->activeNS,
  1188         -                        sizeof(domActiveNS) * 2 * info->activeNSsize);
  1189         -                    info->activeNSsize = 2 * info->activeNSsize;
  1190         -                }
  1191         -                info->activeNS[info->activeNSpos].depth     = info->depth;
  1192         -                info->activeNS[info->activeNSpos].namespace = ns;
  1193         -            }
  1194         -
  1195         -            h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
  1196         -                                    atPtr[0], &hnew);
  1197         -            attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
  1198         -            memset(attrnode, 0, sizeof(domAttrNode));
  1199         -            attrnode->nodeType    = ATTRIBUTE_NODE;
  1200         -            attrnode->nodeFlags   = IS_NS_NODE;
  1201         -            attrnode->namespace   = ns->index;
  1202         -            attrnode->nodeName    = (char *)&(h->key);
  1203         -            attrnode->parentNode  = node;
  1204         -            len = strlen(atPtr[1]);
  1205         -            if (TclOnly8Bits && info->encoding_8bit) {
  1206         -                tdom_Utf8to8Bit(info->encoding_8bit, atPtr[1], &len);
  1207         -            }
  1208         -            attrnode->valueLength = len;
  1209         -            attrnode->nodeValue   = (char*)MALLOC(len+1);
  1210         -            strcpy(attrnode->nodeValue, atPtr[1]);
  1211         -            if (node->firstAttr) {
  1212         -                lastAttr->nextSibling = attrnode;
  1213         -            } else {
  1214         -                node->firstAttr = attrnode;
  1215         -            }
  1216         -            lastAttr = attrnode;
  1217         -        }
  1218         -
  1219         -    }
  1220         -
  1221         -    /*----------------------------------------------------------
  1222         -    |   look for namespace of element
  1223         -    \---------------------------------------------------------*/
  1224         -    domSplitQName (name, tagPrefix, &localname);
  1225         -    for (pos = info->activeNSpos; pos >= 0; pos--) {
  1226         -        if (  ((tagPrefix[0] == '\0') && (info->activeNS[pos].namespace->prefix[0] == '\0'))
  1227         -           || ((tagPrefix[0] != '\0') && (info->activeNS[pos].namespace->prefix[0] != '\0')
  1228         -               && (strcmp(tagPrefix, info->activeNS[pos].namespace->prefix) == 0))
  1229         -        ) {
  1230         -            if (info->activeNS[pos].namespace->prefix[0] == '\0'
  1231         -                && info->activeNS[pos].namespace->uri[0] == '\0'
  1232         -                && tagPrefix[0] == '\0') {
  1233         -                /* xml-names rec. 5.2: "The default namespace can be
  1234         -                   set to the empty string. This has the same effect,
  1235         -                   within the scope of the declaration, of there being
  1236         -                   no default namespace." */
  1237         -                goto elemNSfound;
  1238         -            }
  1239         -            node->namespace = info->activeNS[pos].namespace->index;
  1240         -            DBG(fprintf(stderr, "tag='%s' uri='%s' \n",
  1241         -                        node->nodeName,
  1242         -                        info->activeNS[pos].namespace->uri);
  1243         -            )
  1244         -            goto elemNSfound;
  1245         -        }
  1246         -    }
  1247         -    if (tagPrefix[0] != '\0') {
  1248         -        if (strcmp (tagPrefix, "xml")==0) {
  1249         -            node->namespace = info->document->rootNode->firstAttr->namespace;
  1250         -        } else {
  1251         -            /* Since where here, this means, the element has a
  1252         -               up to now not declared namespace prefix. We probably
  1253         -               should return this as an error, shouldn't we?*/
  1254         -        }
  1255         -    }
  1256         - elemNSfound:
  1257         -#endif
         1188  +    if (!info->ignorexmlns) {
         1189  +        for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {
         1190  +
         1191  +            if (strncmp(atPtr[0], "xmlns", 5) == 0) {
         1192  +                xmlns = atPtr[0];
         1193  +                newNS = 1;
         1194  +                if (xmlns[5] == ':') {
         1195  +                    if (atPtr[1][0] == '\0') {
         1196  +                        Tcl_SetResult (info->interp, "Missing URI in Namespace "
         1197  +                               "declaration", NULL);
         1198  +                        XML_StopParser(info->parser, 0);
         1199  +                        return;
         1200  +                    }
         1201  +                    if (domIsNamespaceInScope (info->activeNS, info->activeNSpos,
         1202  +                                               &(xmlns[6]), atPtr[1])) {
         1203  +                        ns = domLookupPrefix (info->currentNode, &(xmlns[6]));
         1204  +                        newNS = 0;
         1205  +                    }
         1206  +                    else {
         1207  +                        ns = domNewNamespace(info->document, &xmlns[6], atPtr[1]);
         1208  +                    }
         1209  +                } else {
         1210  +                    ns = domNewNamespace(info->document, "", atPtr[1]);
         1211  +                }
         1212  +                if (newNS) {
         1213  +                    /* push active namespace */
         1214  +                    info->activeNSpos++;
         1215  +                    if (info->activeNSpos >= info->activeNSsize) {
         1216  +                        info->activeNS = (domActiveNS*) REALLOC(
         1217  +                            (char*)info->activeNS,
         1218  +                            sizeof(domActiveNS) * 2 * info->activeNSsize);
         1219  +                        info->activeNSsize = 2 * info->activeNSsize;
         1220  +                    }
         1221  +                    info->activeNS[info->activeNSpos].depth     = info->depth;
         1222  +                    info->activeNS[info->activeNSpos].namespace = ns;
         1223  +                }
         1224  +
         1225  +                h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
         1226  +                                        atPtr[0], &hnew);
         1227  +                attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
         1228  +                memset(attrnode, 0, sizeof(domAttrNode));
         1229  +                attrnode->nodeType    = ATTRIBUTE_NODE;
         1230  +                attrnode->nodeFlags   = IS_NS_NODE;
         1231  +                attrnode->namespace   = ns->index;
         1232  +                attrnode->nodeName    = (char *)&(h->key);
         1233  +                attrnode->parentNode  = node;
         1234  +                len = strlen(atPtr[1]);
         1235  +                attrnode->valueLength = len;
         1236  +                attrnode->nodeValue   = (char*)MALLOC(len+1);
         1237  +                strcpy(attrnode->nodeValue, atPtr[1]);
         1238  +                if (node->firstAttr) {
         1239  +                    lastAttr->nextSibling = attrnode;
         1240  +                } else {
         1241  +                    node->firstAttr = attrnode;
         1242  +                }
         1243  +                lastAttr = attrnode;
         1244  +            }
         1245  +
         1246  +        }
         1247  +
         1248  +        /*----------------------------------------------------------
         1249  +          |   look for namespace of element
         1250  +          \---------------------------------------------------------*/
         1251  +        domSplitQName (name, tagPrefix, &localname);
         1252  +        for (pos = info->activeNSpos; pos >= 0; pos--) {
         1253  +            if (  ((tagPrefix[0] == '\0')
         1254  +                   && (info->activeNS[pos].namespace->prefix[0] == '\0'))
         1255  +                  || ((tagPrefix[0] != '\0') 
         1256  +                      && (info->activeNS[pos].namespace->prefix[0] != '\0')
         1257  +                      && (strcmp(tagPrefix, 
         1258  +                                 info->activeNS[pos].namespace->prefix) == 0))
         1259  +                ) {
         1260  +                if (info->activeNS[pos].namespace->prefix[0] == '\0'
         1261  +                    && info->activeNS[pos].namespace->uri[0] == '\0'
         1262  +                    && tagPrefix[0] == '\0') {
         1263  +                    /* xml-names rec. 5.2: "The default namespace can be
         1264  +                       set to the empty string. This has the same effect,
         1265  +                       within the scope of the declaration, of there being
         1266  +                       no default namespace." */
         1267  +                    goto elemNSfound;
         1268  +                }
         1269  +                node->namespace = info->activeNS[pos].namespace->index;
         1270  +                DBG(fprintf(stderr, "tag='%s' uri='%s' \n",
         1271  +                            node->nodeName,
         1272  +                            info->activeNS[pos].namespace->uri);
         1273  +                    )
         1274  +                    goto elemNSfound;
         1275  +            }
         1276  +        }
         1277  +        if (tagPrefix[0] != '\0') {
         1278  +            if (strcmp (tagPrefix, "xml")==0) {
         1279  +                node->namespace = info->document->rootNode->firstAttr->namespace;
         1280  +            } else {
         1281  +                /* Since where here, this means, the element has a
         1282  +                   up to now not declared namespace prefix. */
         1283  +                Tcl_SetResult (info->interp, "Namespace prefix is not "
         1284  +                               "defined", NULL);
         1285  +                XML_StopParser(info->parser, 0);
         1286  +                return;
         1287  +            }
         1288  +        }
         1289  +    }
         1290  +elemNSfound:
  1258   1291   
  1259   1292       /*--------------------------------------------------------------
  1260   1293       |   add the attribute nodes
  1261   1294       |
  1262   1295       \-------------------------------------------------------------*/
  1263   1296       if ((idatt = XML_GetIdAttributeIndex (info->parser)) != -1) {
  1264   1297           if (!info->document->ids) {
................................................................................
  1265   1298               info->document->ids = MALLOC (sizeof (Tcl_HashTable));
  1266   1299               Tcl_InitHashTable (info->document->ids, TCL_STRING_KEYS);
  1267   1300           }
  1268   1301           h = Tcl_CreateHashEntry (info->document->ids,
  1269   1302                                    atts[idatt+1],
  1270   1303                                    &hnew);
  1271   1304           /* if hnew isn't 1 this is a validation error. Hm, no clear way
  1272         -           to report this. And more, xslt and xpath can process not
         1305  +           to report this. And more, XSLT and XPath can process not
  1273   1306              valid XML, the spec mentioned this even within the context
  1274   1307              of id(). If some elements share the same ID, the first in
  1275   1308              document order should be used. Doing it this way, this is
  1276   1309              guaranteed for unchanged DOM trees. There are problems, if
  1277   1310              the DOM tree is changed, befor using id() */
  1278   1311           if (hnew) {
  1279   1312               Tcl_SetHashValue (h, node);
................................................................................
  1281   1314           idAttPtr = atts + idatt;
  1282   1315       } else {
  1283   1316           idAttPtr = NULL;
  1284   1317       }
  1285   1318       /* lastAttr already set right, either to NULL above, or to the last
  1286   1319          NS attribute */
  1287   1320       for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {
  1288         -
  1289         -#ifdef TDOM_NS
  1290         -        if (strncmp(atPtr[0], "xmlns", 5) == 0) {
  1291         -            continue;
         1321  +        if (!info->ignorexmlns) {
         1322  +            if (strncmp(atPtr[0], "xmlns", 5) == 0) {
         1323  +                continue;
         1324  +            }
  1292   1325           }
  1293         -#endif
  1294   1326           h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
  1295   1327                                   atPtr[0], &hnew);
  1296   1328           attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
  1297   1329           memset(attrnode, 0, sizeof(domAttrNode));
  1298   1330           attrnode->nodeType = ATTRIBUTE_NODE;
  1299   1331           if (atPtr == idAttPtr) {
  1300   1332               attrnode->nodeFlags |= IS_ID_ATTRIBUTE;
................................................................................
  1301   1333           } else {
  1302   1334               attrnode->nodeFlags = 0;
  1303   1335           }
  1304   1336           attrnode->namespace   = 0;
  1305   1337           attrnode->nodeName    = (char *)&(h->key);
  1306   1338           attrnode->parentNode  = node;
  1307   1339           len = strlen(atPtr[1]);
  1308         -        if (TclOnly8Bits && info->encoding_8bit) {
  1309         -            tdom_Utf8to8Bit(info->encoding_8bit, atPtr[1], &len);
  1310         -        }
  1311   1340           attrnode->valueLength = len;
  1312   1341           attrnode->nodeValue   = (char*)MALLOC(len+1);
  1313   1342           strcpy(attrnode->nodeValue, (char *)atPtr[1]);
  1314   1343   
  1315   1344           if (node->firstAttr) {
  1316   1345               lastAttr->nextSibling = attrnode;
  1317   1346           } else {
  1318   1347               node->firstAttr = attrnode;
  1319   1348           }
  1320   1349           lastAttr = attrnode;
  1321   1350   
  1322         -#ifdef TDOM_NS
  1323         -        /*----------------------------------------------------------
  1324         -        |   look for attribute namespace
  1325         -        \---------------------------------------------------------*/
  1326         -        domSplitQName (attrnode->nodeName, prefix, &localname);
  1327         -        if (prefix[0] != '\0') {
  1328         -            for (pos = info->activeNSpos; pos >= 0; pos--) {
  1329         -                if (  ((prefix[0] == '\0') && (info->activeNS[pos].namespace->prefix[0] == '\0'))
  1330         -                      || ((prefix[0] != '\0') && (info->activeNS[pos].namespace->prefix[0] != '\0')
  1331         -                          && (strcmp(prefix, info->activeNS[pos].namespace->prefix) == 0))
  1332         -                    ) {
  1333         -                    attrnode->namespace = info->activeNS[pos].namespace->index;
  1334         -                    DBG(fprintf(stderr, "attr='%s' uri='%s' \n",
  1335         -                                attrnode->nodeName,
  1336         -                                info->activeNS[pos].namespace->uri);
  1337         -                        )
  1338         -                    goto attrNSfound;
  1339         -                }
  1340         -            }
  1341         -            if (strcmp (prefix, "xml")==0) {
  1342         -                attrnode->namespace = 
  1343         -                    info->document->rootNode->firstAttr->namespace;
  1344         -            } else {
  1345         -                /* Since where here, this means, the attribute has a
  1346         -                   up to now not declared namespace prefix. We probably
  1347         -                   should return this as an error, shouldn't we?*/
  1348         -            }
  1349         -        attrNSfound:
  1350         -            ;
  1351         -        }
  1352         -#endif
         1351  +        if (!info->ignorexmlns) {
         1352  +            /*----------------------------------------------------------
         1353  +              |   look for attribute namespace
         1354  +              \---------------------------------------------------------*/
         1355  +            domSplitQName (attrnode->nodeName, prefix, &localname);
         1356  +            if (prefix[0] != '\0') {
         1357  +                for (pos = info->activeNSpos; pos >= 0; pos--) {
         1358  +                    if (  ((prefix[0] == '\0') 
         1359  +                           && (info->activeNS[pos].namespace->prefix[0] == '\0'))
         1360  +                          || ((prefix[0] != '\0') 
         1361  +                              && (info->activeNS[pos].namespace->prefix[0] != '\0')
         1362  +                              && (strcmp(prefix, info->activeNS[pos].namespace->prefix) == 0))
         1363  +                        ) {
         1364  +                        attrnode->namespace = info->activeNS[pos].namespace->index;
         1365  +                        DBG(fprintf(stderr, "attr='%s' uri='%s' \n",
         1366  +                                    attrnode->nodeName,
         1367  +                                    info->activeNS[pos].namespace->uri);
         1368  +                            )
         1369  +                            goto attrNSfound;
         1370  +                    }
         1371  +                }
         1372  +                if (strcmp (prefix, "xml")==0) {
         1373  +                    attrnode->namespace = 
         1374  +                        info->document->rootNode->firstAttr->namespace;
         1375  +                } else {
         1376  +                    /* Since where here, this means, the attribute has a
         1377  +                       up to now not declared namespace prefix. We probably
         1378  +                       should return this as an error, shouldn't we?*/
         1379  +                }
         1380  +            attrNSfound:
         1381  +                ;
         1382  +            }
         1383  +        }
  1353   1384       }
  1354   1385   
  1355   1386       info->depth++;
  1356   1387   }
  1357   1388   
  1358   1389   /*---------------------------------------------------------------------------
  1359   1390   |   endElement
................................................................................
  1366   1397   )
  1367   1398   {
  1368   1399       domReadInfo  *info = userData;
  1369   1400   
  1370   1401       DispatchPCDATA (info);
  1371   1402       
  1372   1403       info->depth--;
  1373         -#ifdef TDOM_NS
  1374         -    /* pop active namespaces */
  1375         -    while ( (info->activeNSpos >= 0) &&
  1376         -            (info->activeNS[info->activeNSpos].depth == info->depth) )
  1377         -    {
  1378         -        info->activeNSpos--;
         1404  +    if (!info->ignorexmlns) {
         1405  +        /* pop active namespaces */
         1406  +        while ( (info->activeNSpos >= 0) &&
         1407  +                (info->activeNS[info->activeNSpos].depth == info->depth) )
         1408  +        {
         1409  +            info->activeNSpos--;
         1410  +        }
  1379   1411       }
  1380         -#endif
  1381   1412   
  1382   1413       if (info->depth != -1) {
  1383   1414           info->currentNode = info->currentNode->parentNode;
  1384   1415       } else {
  1385   1416           info->currentNode = NULL;
  1386   1417       }
  1387   1418   
................................................................................
  1405   1436   {
  1406   1437       domReadInfo   *info = userData;
  1407   1438   
  1408   1439       Tcl_DStringAppend (info->cdata, s, len);
  1409   1440       return;
  1410   1441       
  1411   1442   }
         1443  +
         1444  +/*---------------------------------------------------------------------------
         1445  +|   startCDATA
         1446  +|
         1447  +\--------------------------------------------------------------------------*/
         1448  +static void
         1449  +startCDATA (
         1450  +    void        *userData
         1451  +    )
         1452  +{
         1453  +    domReadInfo   *info = userData;
         1454  +
         1455  +    DispatchPCDATA (info);
         1456  +    info->cdataSection = 1;
         1457  +}
         1458  +
         1459  +/*---------------------------------------------------------------------------
         1460  +|   endCDATA
         1461  +|
         1462  +\--------------------------------------------------------------------------*/
         1463  +static void
         1464  +endCDATA (
         1465  +    void        *userData
         1466  +    )
         1467  +{
         1468  +    domReadInfo   *info = userData;
         1469  +    
         1470  +    DispatchPCDATA (info);
         1471  +    info->cdataSection = 0;
         1472  +}
  1412   1473   
  1413   1474   /*---------------------------------------------------------------------------
  1414   1475   |   DispatchPCDATA
  1415   1476   |
  1416   1477   \--------------------------------------------------------------------------*/
  1417   1478   static void
  1418   1479   DispatchPCDATA (
................................................................................
  1422   1483       domTextNode   *node;
  1423   1484       domNode       *parentNode;
  1424   1485       domLineColumn *lc;
  1425   1486       Tcl_HashEntry *h;
  1426   1487       char          *s;
  1427   1488       int            len, hnew;
  1428   1489       
  1429         -    s = Tcl_DStringValue (info->cdata);
  1430   1490       len = Tcl_DStringLength (info->cdata);
  1431         -    if (!len) return;
         1491  +    if (!len && !info->cdataSection) return;
         1492  +    s = Tcl_DStringValue (info->cdata);
  1432   1493       
  1433         -    if (TclOnly8Bits && info->encoding_8bit) {
  1434         -        tdom_Utf8to8Bit( info->encoding_8bit, s, &len);
  1435         -    }
  1436   1494       parentNode = info->currentNode;
  1437   1495       if (!parentNode) return;
  1438         -    
         1496  +
  1439   1497       if (   parentNode->lastChild 
  1440         -        && parentNode->lastChild->nodeType == TEXT_NODE) {
         1498  +        && parentNode->lastChild->nodeType == TEXT_NODE
         1499  +        && !info->cdataSection) {
  1441   1500   
  1442   1501           /* normalize text node, i.e. there are no adjacent text nodes */
  1443   1502           node = (domTextNode*)parentNode->lastChild;
  1444   1503           node->nodeValue = REALLOC(node->nodeValue, node->valueLength + len);
  1445   1504           memmove(node->nodeValue + node->valueLength, s, len);
  1446   1505           node->valueLength += len;
  1447   1506   
................................................................................
  1470   1529           if (info->storeLineColumn) {
  1471   1530               node = (domTextNode*) domAlloc(sizeof(domTextNode)
  1472   1531                                               + sizeof(domLineColumn));
  1473   1532           } else {
  1474   1533               node = (domTextNode*) domAlloc(sizeof(domTextNode));
  1475   1534           }
  1476   1535           memset(node, 0, sizeof(domTextNode));
  1477         -        node->nodeType    = TEXT_NODE;
         1536  +        if (info->cdataSection)
         1537  +            node->nodeType    = CDATA_SECTION_NODE;
         1538  +        else 
         1539  +            node->nodeType    = TEXT_NODE;
  1478   1540           node->nodeFlags   = 0;
  1479         -        node->namespace   = 0;
  1480   1541           node->nodeNumber  = NODE_NO(info->document);
  1481   1542           node->valueLength = len;
  1482   1543           node->nodeValue   = (char*)MALLOC(len);
  1483   1544           memmove(node->nodeValue, s, len);
  1484   1545   
  1485   1546           node->ownerDocument = info->document;
  1486   1547           node->parentNode = parentNode;
................................................................................
  1535   1596           DBG(fprintf (stderr, "commentHandler: insideDTD, skipping\n");)
  1536   1597           return;
  1537   1598       }
  1538   1599   
  1539   1600       DispatchPCDATA (info);
  1540   1601   
  1541   1602       len = strlen(s);
  1542         -    if (TclOnly8Bits && info->encoding_8bit) {
  1543         -        tdom_Utf8to8Bit(info->encoding_8bit, s, &len);
  1544         -    }
  1545   1603       parentNode = info->currentNode;
  1546   1604   
  1547   1605       if (info->storeLineColumn) {
  1548   1606           node = (domTextNode*) domAlloc(sizeof(domTextNode)
  1549   1607                                           + sizeof(domLineColumn));
  1550   1608       } else {
  1551   1609           node = (domTextNode*) domAlloc(sizeof(domTextNode));
  1552   1610       }
  1553   1611       memset(node, 0, sizeof(domTextNode));
  1554   1612       node->nodeType    = COMMENT_NODE;
  1555   1613       node->nodeFlags   = 0;
  1556         -    node->namespace   = 0;
  1557   1614       node->nodeNumber  = NODE_NO(info->document);
  1558   1615       node->valueLength = len;
  1559   1616       node->nodeValue   = (char*)MALLOC(len);
  1560   1617       memmove(node->nodeValue, s, len);
  1561   1618   
  1562   1619       node->ownerDocument = info->document;
  1563   1620       node->parentNode = parentNode;
................................................................................
  1645   1702                                    (char*) node,
  1646   1703                                    &hnew);
  1647   1704           Tcl_SetHashValue (h, tdomstrdup (XML_GetBase (info->parser)));
  1648   1705           node->nodeFlags |= HAS_BASEURI;
  1649   1706       }
  1650   1707   
  1651   1708       len = strlen(target);
  1652         -    if (TclOnly8Bits && info->encoding_8bit) {
  1653         -        tdom_Utf8to8Bit(info->encoding_8bit, target, &len);
  1654         -    }
  1655   1709       node->targetLength = len;
  1656   1710       node->targetValue  = (char*)MALLOC(len);
  1657   1711       memmove(node->targetValue, target, len);
  1658   1712   
  1659   1713       len = strlen(data);
  1660         -    if (TclOnly8Bits && info->encoding_8bit) {
  1661         -        tdom_Utf8to8Bit(info->encoding_8bit, data, &len);
  1662         -    }
  1663   1714       node->dataLength = len;
  1664   1715       node->dataValue  = (char*)MALLOC(len);
  1665   1716       memmove(node->dataValue, data, len);
  1666   1717   
  1667   1718       node->ownerDocument = info->document;
  1668   1719       node->parentNode = parentNode;
  1669   1720       if (parentNode == NULL) {
................................................................................
  1729   1780   /*---------------------------------------------------------------------------
  1730   1781   |  externalEntityRefHandler
  1731   1782   |
  1732   1783   \--------------------------------------------------------------------------*/
  1733   1784   static int
  1734   1785   externalEntityRefHandler (
  1735   1786       XML_Parser  parser,
  1736         -    CONST char *openEntityNames,
  1737         -    CONST char *base,
  1738         -    CONST char *systemId,
  1739         -    CONST char *publicId
         1787  +    const char *openEntityNames,
         1788  +    const char *base,
         1789  +    const char *systemId,
         1790  +    const char *publicId
  1740   1791   )
  1741   1792   {
  1742   1793       domReadInfo   *info = (domReadInfo *) XML_GetUserData (parser);
  1743   1794   
  1744   1795       Tcl_Obj *cmdPtr, *resultObj, *resultTypeObj, *extbaseObj, *xmlstringObj;
  1745   1796       Tcl_Obj *channelIdObj;
  1746   1797       int result, mode, done, byteIndex, i;
         1798  +    int keepresult = 0;
  1747   1799       size_t len;
  1748   1800       int tclLen;
  1749   1801       XML_Parser extparser, oldparser = NULL;
  1750   1802       char buf[4096], *resultType, *extbase, *xmlstring, *channelId, s[50];
  1751   1803       Tcl_Channel chan = (Tcl_Channel) NULL;
         1804  +    enum XML_Status status;
         1805  +    XML_Index storedNextFeedbackPosition;
         1806  +    const char *interpResult;
  1752   1807   
  1753   1808       if (info->document->extResolver == NULL) {
  1754   1809           Tcl_AppendResult (info->interp, "Can't read external entity \"",
  1755   1810                             systemId, "\": No -externalentitycommand given",
  1756   1811                             NULL);
  1757   1812           return 0;
  1758   1813       }
................................................................................
  1791   1846                                    Tcl_NewStringObj(publicId, strlen(publicId)));
  1792   1847       } else {
  1793   1848           Tcl_ListObjAppendElement(info->interp, cmdPtr,
  1794   1849                                    Tcl_NewObj());
  1795   1850       }
  1796   1851   
  1797   1852    
  1798         -#if TclOnly8Bits
  1799         -    result = Tcl_GlobalEvalObj(info->interp, cmdPtr);
  1800         -#else
  1801   1853       result = Tcl_EvalObjEx (info->interp, cmdPtr, 
  1802   1854                               TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);
  1803         -#endif
  1804   1855   
  1805   1856       Tcl_DecrRefCount(cmdPtr);
  1806   1857   
  1807   1858       if (result != TCL_OK) {
         1859  +        info->status = result;
  1808   1860           return 0;
  1809   1861       }
  1810   1862   
  1811   1863       extparser = XML_ExternalEntityParserCreate (parser, openEntityNames, 0);
  1812   1864   
  1813   1865       resultObj = Tcl_GetObjResult (info->interp);
  1814   1866       Tcl_IncrRefCount (resultObj);
................................................................................
  1862   1914                          NULL);
  1863   1915           return 0;
  1864   1916       }
  1865   1917   
  1866   1918       oldparser = info->parser;
  1867   1919       info->parser = extparser;
  1868   1920       XML_SetBase (extparser, extbase);
         1921  +    storedNextFeedbackPosition = info->nextFeedbackPosition;
         1922  +    info->nextFeedbackPosition = info->feedbackAfter;
  1869   1923   
         1924  +    Tcl_ResetResult (info->interp);
         1925  +    result = 1;
  1870   1926       if (chan == NULL) {
  1871         -        if (!XML_Parse(extparser, xmlstring, strlen (xmlstring), 1)) {
  1872         -            Tcl_ResetResult (info->interp);
         1927  +        status = XML_Parse(extparser, xmlstring, strlen (xmlstring), 1);
         1928  +        switch (status) {
         1929  +        case XML_STATUS_ERROR:
         1930  +            interpResult = Tcl_GetStringResult(info->interp);
  1873   1931               sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));
  1874         -            Tcl_AppendResult(info->interp, "error \"",
  1875         -                             XML_ErrorString(XML_GetErrorCode(extparser)),
  1876         -                             "\" in entity \"", systemId,
  1877         -                             "\" at line ", s, " character ", NULL);
  1878         -            sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
  1879         -            Tcl_AppendResult(info->interp, s, NULL);
  1880         -            byteIndex = XML_GetCurrentByteIndex(extparser);
  1881         -            if (byteIndex != -1) {
  1882         -                Tcl_AppendResult(info->interp, "\n\"", NULL);
  1883         -                s[1] = '\0';
  1884         -                for (i=-20; i < 40; i++) {
  1885         -                    if ((byteIndex+i)>=0) {
  1886         -                        if (xmlstring[byteIndex+i]) {
  1887         -                            s[0] = xmlstring[byteIndex+i];
  1888         -                            Tcl_AppendResult(info->interp, s, NULL);
  1889         -                            if (i==0) {
  1890         -                                Tcl_AppendResult(info->interp,
  1891         -                                                 " <--Error-- ", NULL);
  1892         -                            }
  1893         -                        } else {
  1894         -                            break;
  1895         -                        }
  1896         -                    }
  1897         -                }
  1898         -                Tcl_AppendResult(info->interp, "\"",NULL);
  1899         -            } 
  1900         -            Tcl_DecrRefCount (resultObj);
  1901         -            XML_ParserFree (extparser);
  1902         -            info->parser = oldparser;
  1903         -            return 0;
  1904         -        }
  1905         -    } else {
  1906         -        do {
  1907         -            len = Tcl_Read (chan, buf, sizeof(buf));
  1908         -            done = len < sizeof(buf);
  1909         -            if (!XML_Parse (extparser, buf, len, done)) {
         1932  +            if (interpResult[0] == '\0') {
  1910   1933                   Tcl_ResetResult (info->interp);
  1911         -                sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));
  1912   1934                   Tcl_AppendResult(info->interp, "error \"",
  1913   1935                                    XML_ErrorString(XML_GetErrorCode(extparser)),
  1914   1936                                    "\" in entity \"", systemId,
  1915   1937                                    "\" at line ", s, " character ", NULL);
  1916   1938                   sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
  1917   1939                   Tcl_AppendResult(info->interp, s, NULL);
  1918         -                Tcl_DecrRefCount (resultObj);
  1919         -                XML_ParserFree (extparser);
  1920         -                info->parser = oldparser;
  1921         -                return 0;
         1940  +                byteIndex = XML_GetCurrentByteIndex(extparser);
         1941  +                if (byteIndex != -1) {
         1942  +                    Tcl_AppendResult(info->interp, "\n\"", NULL);
         1943  +                    s[1] = '\0';
         1944  +                    for (i=-20; i < 40; i++) {
         1945  +                        if ((byteIndex+i)>=0) {
         1946  +                            if (xmlstring[byteIndex+i]) {
         1947  +                                s[0] = xmlstring[byteIndex+i];
         1948  +                                Tcl_AppendResult(info->interp, s, NULL);
         1949  +                                if (i==0) {
         1950  +                                    Tcl_AppendResult(info->interp,
         1951  +                                                     " <--Error-- ", NULL);
         1952  +                                }
         1953  +                            } else {
         1954  +                                break;
         1955  +                            }
         1956  +                        }
         1957  +                    }
         1958  +                    Tcl_AppendResult(info->interp, "\"",NULL);
         1959  +                }
         1960  +            } else {
         1961  +                Tcl_AppendResult(info->interp, ", referenced in entity \"",
         1962  +                                 systemId, 
         1963  +                                 "\" at line ", s, " character ", NULL);
         1964  +                sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
         1965  +                Tcl_AppendResult(info->interp, s, NULL);
         1966  +            }
         1967  +            keepresult = 1;
         1968  +            result = 0;
         1969  +            break;
         1970  +        case XML_STATUS_SUSPENDED:
         1971  +            XML_StopParser (oldparser, 1);
         1972  +            keepresult = 1;
         1973  +            break;
         1974  +        default:
         1975  +            break;
         1976  +        }
         1977  +    } else {
         1978  +        do {
         1979  +            len = Tcl_Read (chan, buf, sizeof(buf));
         1980  +            done = len < sizeof(buf);
         1981  +            status = XML_Parse (extparser, buf, len, done);
         1982  +            switch (status) {
         1983  +            case XML_STATUS_ERROR:
         1984  +                interpResult = Tcl_GetStringResult(info->interp);
         1985  +                sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));
         1986  +                if (interpResult[0] == '\0') {
         1987  +                    Tcl_ResetResult (info->interp);
         1988  +                    Tcl_AppendResult(info->interp, "error \"",
         1989  +                                     XML_ErrorString(XML_GetErrorCode(extparser)),
         1990  +                                     "\" in entity \"", systemId,
         1991  +                                     "\" at line ", s, " character ", NULL);
         1992  +                    sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
         1993  +                    Tcl_AppendResult(info->interp, s, NULL);
         1994  +                } else {
         1995  +                    Tcl_AppendResult(info->interp, ", referenced in entity \"",
         1996  +                                     systemId, 
         1997  +                                     "\" at line ", s, " character ", NULL);
         1998  +                    sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
         1999  +                    Tcl_AppendResult(info->interp, s, NULL);
         2000  +                }
         2001  +                result = 0;
         2002  +                keepresult = 1;
         2003  +                done = 1;
         2004  +                break;
         2005  +            case XML_STATUS_SUSPENDED:
         2006  +                XML_StopParser (oldparser, 1);
         2007  +                keepresult = 1;
         2008  +                done = 1;
         2009  +                break;
         2010  +            default:
         2011  +                break;
  1922   2012               }
  1923   2013           } while (!done);
  1924   2014       }
  1925   2015   
  1926         -    DispatchPCDATA (info);
  1927         -
         2016  +    if (result) {
         2017  +        DispatchPCDATA (info);
         2018  +    }
         2019  +    if (!keepresult) {
         2020  +        Tcl_ResetResult (info->interp);
         2021  +    }
  1928   2022       XML_ParserFree (extparser);
  1929   2023       info->parser = oldparser;
  1930         -
         2024  +    info->nextFeedbackPosition = storedNextFeedbackPosition;
  1931   2025       Tcl_DecrRefCount (resultObj);
  1932         -    Tcl_ResetResult (info->interp);
  1933         -    return 1;
         2026  +    return result;
  1934   2027   
  1935   2028    wrongScriptResult:
  1936   2029       Tcl_DecrRefCount (resultObj);
  1937   2030       Tcl_ResetResult (info->interp);
  1938   2031       XML_ParserFree (extparser);
  1939   2032       if (oldparser) {
  1940   2033           info->parser = oldparser;
  1941   2034       }
         2035  +    info->status = TCL_ERROR;
  1942   2036       Tcl_AppendResult (info->interp, "The -externalentitycommand script "
  1943   2037                         "has to return a Tcl list with 3 elements.\n"
  1944   2038                         "Syntax: {string|channel|filename <baseurl> <data>}\n",
  1945   2039                         NULL);
  1946   2040       return 0;
  1947   2041   }
  1948   2042   
................................................................................
  1994   2088   \--------------------------------------------------------------------------*/
  1995   2089   domDocument *
  1996   2090   domReadDocument (
  1997   2091       XML_Parser  parser,
  1998   2092       char       *xml,
  1999   2093       int         length,
  2000   2094       int         ignoreWhiteSpaces,
  2001         -    TEncoding  *encoding_8bit,
         2095  +    int         keepCDATA,
  2002   2096       int         storeLineColumn,
         2097  +    int         ignorexmlns,
  2003   2098       int         feedbackAfter,
         2099  +    Tcl_Obj    *feedbackCmd,
  2004   2100       Tcl_Channel channel,
  2005   2101       const char *baseurl,
  2006         -    char       *extResolver,
         2102  +    Tcl_Obj    *extResolver,
  2007   2103       int         useForeignDTD,
  2008   2104       int         paramEntityParsing,
  2009         -    Tcl_Interp *interp
         2105  +    Tcl_Interp *interp,
         2106  +    int        *resultcode
  2010   2107   )
  2011   2108   {
  2012         -    int            done, tclLen;
  2013         -    size_t         len;
  2014         -    domReadInfo    info;
  2015         -    char           buf[8192];
  2016         -#if !TclOnly8Bits
  2017         -    Tcl_Obj       *bufObj;
  2018         -    Tcl_DString    dStr;
  2019         -    int            useBinary;
  2020         -    char          *str;
  2021         -#endif
  2022         -    domDocument   *doc = domCreateDoc(baseurl, storeLineColumn);
         2109  +    int             done, tclLen;
         2110  +    enum XML_Status status;
         2111  +    size_t          len;
         2112  +    domReadInfo     info;
         2113  +    char            buf[8192];
         2114  +    Tcl_Obj        *bufObj;
         2115  +    Tcl_DString     dStr;
         2116  +    int             useBinary;
         2117  +    char           *str;
         2118  +    domDocument    *doc = domCreateDoc(baseurl, storeLineColumn);
  2023   2119   
  2024         -    doc->extResolver = extResolver;
         2120  +    if (extResolver) {
         2121  +        doc->extResolver = tdomstrdup (Tcl_GetString (extResolver));
         2122  +    }
         2123  +    if (ignorexmlns) {
         2124  +        doc->nodeFlags |= IGNORE_XMLNS;
         2125  +    }
  2025   2126   
  2026   2127       info.parser               = parser;
  2027   2128       info.document             = doc;
  2028   2129       info.currentNode          = NULL;
  2029   2130       info.depth                = 0;
  2030   2131       info.ignoreWhiteSpaces    = ignoreWhiteSpaces;
  2031   2132       info.cdata                = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
  2032   2133       Tcl_DStringInit (info.cdata);
  2033         -    info.encoding_8bit        = encoding_8bit;
         2134  +    info.cdataSection         = 0;
  2034   2135       info.storeLineColumn      = storeLineColumn;
         2136  +    info.ignorexmlns          = ignorexmlns;
  2035   2137       info.feedbackAfter        = feedbackAfter;
  2036         -    info.lastFeedbackPosition = 0;
         2138  +    info.feedbackCmd          = feedbackCmd;
         2139  +    info.nextFeedbackPosition = feedbackAfter;
  2037   2140       info.interp               = interp;
  2038   2141       info.activeNSpos          = -1;
  2039   2142       info.activeNSsize         = 8;
  2040   2143       info.activeNS             = (domActiveNS*) MALLOC (sizeof(domActiveNS) 
  2041   2144                                                          * info.activeNSsize);
  2042   2145       info.baseURIstackPos      = 0;
  2043   2146       info.baseURIstackSize     = INITIAL_BASEURISTACK_SIZE;
  2044   2147       info.baseURIstack         = (domActiveBaseURI*) 
  2045   2148           MALLOC (sizeof(domActiveBaseURI) * info.baseURIstackSize);
  2046   2149       info.insideDTD            = 0;
         2150  +    info.status               = 0;
  2047   2151   
  2048   2152       XML_SetUserData(parser, &info);
  2049   2153       XML_SetBase (parser, baseurl);
  2050   2154       /* We must use XML_GetBase(), because XML_SetBase copies the baseURI,
  2051   2155          and we want to compare the pointers */
  2052   2156       info.baseURIstack[0].baseURI = XML_GetBase (parser);
  2053   2157       info.baseURIstack[0].depth = 0;
................................................................................
  2060   2164       if (extResolver) {
  2061   2165           XML_SetExternalEntityRefHandler (parser, externalEntityRefHandler);
  2062   2166       }
  2063   2167       XML_SetParamEntityParsing (parser, 
  2064   2168                                (enum XML_ParamEntityParsing) paramEntityParsing);
  2065   2169       XML_SetDoctypeDeclHandler (parser, startDoctypeDeclHandler,
  2066   2170                                  endDoctypeDeclHandler);
         2171  +    if (keepCDATA) {
         2172  +        XML_SetCdataSectionHandler(parser, startCDATA, endCDATA);
         2173  +    }
         2174  +    
  2067   2175   
  2068   2176       if (channel == NULL) {
  2069         -        if (!XML_Parse(parser, xml, length, 1)) {
         2177  +        status = XML_Parse(parser, xml, length, 1);
         2178  +        switch (status) {
         2179  +        case XML_STATUS_SUSPENDED:
         2180  +            DBG(fprintf(stderr, "XML_STATUS_SUSPENDED\n");)
         2181  +            if (info.status == TCL_BREAK) {
         2182  +                Tcl_ResetResult(interp);
         2183  +            }
         2184  +            /* fall throu */
         2185  +        case XML_STATUS_ERROR:
         2186  +            DBG(fprintf(stderr, "XML_STATUS_ERROR\n");)
  2070   2187               FREE ( info.activeNS );
  2071   2188               FREE ( info.baseURIstack );
  2072   2189               Tcl_DStringFree (info.cdata);
  2073   2190               FREE ( info.cdata);
  2074   2191               domFreeDocument (doc, NULL, NULL);
         2192  +            *resultcode = info.status;
  2075   2193               return NULL;
         2194  +        case XML_STATUS_OK:
         2195  +            break;
  2076   2196           }
  2077   2197       } else {
  2078         -#if !TclOnly8Bits
  2079   2198           Tcl_DStringInit (&dStr);
  2080   2199           if (Tcl_GetChannelOption (interp, channel, "-encoding", &dStr) != TCL_OK) {
  2081   2200               FREE ( (char*) info.activeNS );
  2082   2201               FREE ( info.baseURIstack );
  2083   2202               Tcl_DStringFree (info.cdata);
  2084   2203               FREE ( info.cdata);
  2085   2204               domFreeDocument (doc, NULL, NULL);
         2205  +            *resultcode = info.status;
  2086   2206               return NULL;
  2087   2207           }
  2088         -        if (strcmp (Tcl_DStringValue (&dStr), "identity")==0 ) useBinary = 1;
         2208  +        if (strcmp (Tcl_DStringValue (&dStr), "utf-8")==0 ) useBinary = 1;
  2089   2209           else useBinary = 0;
  2090   2210           Tcl_DStringFree (&dStr);
  2091   2211           if (useBinary) {
  2092   2212               do {
  2093   2213                   len = Tcl_Read (channel, buf, sizeof(buf));
  2094   2214                   done = len < sizeof(buf);
  2095         -                if (!XML_Parse (parser, buf, len, done)) {
         2215  +                status = XML_Parse (parser, buf, len, done);
         2216  +                switch (status) {
         2217  +                case XML_STATUS_SUSPENDED:
         2218  +                    DBG(fprintf(stderr, "XML_STATUS_SUSPENDED\n"););
         2219  +                    if (info.status == TCL_BREAK) {
         2220  +                        Tcl_ResetResult(interp);
         2221  +                    }
         2222  +                    /* fall throu */
         2223  +                case XML_STATUS_ERROR:
         2224  +                    DBG(fprintf(stderr, "XML_STATUS_ERROR\n");)
  2096   2225                       FREE ( info.activeNS );
  2097   2226                       FREE ( info.baseURIstack );
  2098   2227                       Tcl_DStringFree (info.cdata);
  2099   2228                       FREE ( info.cdata);
  2100   2229                       domFreeDocument (doc, NULL, NULL);
         2230  +                    *resultcode = info.status;
  2101   2231                       return NULL;
         2232  +                case XML_STATUS_OK:
         2233  +                    break;
  2102   2234                   }
  2103   2235               } while (!done);
  2104   2236           } else {
  2105   2237               bufObj = Tcl_NewObj();
  2106   2238               Tcl_SetObjLength (bufObj, 6144);
  2107   2239               do {
  2108   2240                   len = Tcl_ReadChars (channel, bufObj, 1024, 0);
  2109   2241                   done = (len < 1024);
  2110   2242                   str = Tcl_GetStringFromObj(bufObj, &tclLen);
  2111         -                if (!XML_Parse (parser, str, tclLen, done)) {
         2243  +                status = XML_Parse (parser, str, tclLen, done);
         2244  +                switch (status) {
         2245  +                case XML_STATUS_SUSPENDED:
         2246  +                    DBG(fprintf(stderr, "XML_STATUS_SUSPENDED\n"););
         2247  +                    if (info.status == TCL_BREAK) {
         2248  +                        Tcl_ResetResult(interp);
         2249  +                    }
         2250  +                    /* fall throu */
         2251  +                case XML_STATUS_ERROR:
         2252  +                    DBG(fprintf(stderr, "XML_STATUS_ERROR\n");)
  2112   2253                       FREE ( info.activeNS );
  2113   2254                       FREE ( info.baseURIstack );
  2114   2255                       Tcl_DStringFree (info.cdata);
  2115   2256                       FREE ( info.cdata);
  2116   2257                       domFreeDocument (doc, NULL, NULL);
  2117   2258                       Tcl_DecrRefCount (bufObj);
         2259  +                    *resultcode = info.status;
  2118   2260                       return NULL;
         2261  +                case XML_STATUS_OK:
         2262  +                    break;
  2119   2263                   }
  2120   2264               } while (!done);
  2121   2265               Tcl_DecrRefCount (bufObj);
  2122   2266           }
  2123         -#else
  2124         -        do {
  2125         -            len = Tcl_Read (channel, buf, sizeof(buf));
  2126         -            done = len < sizeof(buf);
  2127         -            if (!XML_Parse (parser, buf, len, done)) {
  2128         -                FREE ( info.activeNS );
  2129         -                FREE ( info.baseURIstack );
  2130         -                domFreeDocument (doc, NULL, NULL);
  2131         -                Tcl_DStringFree (info.cdata);
  2132         -                FREE ( info.cdata);
  2133         -                return NULL;
  2134         -            }
  2135         -        } while (!done);
  2136         -#endif
  2137   2267       }
  2138   2268       FREE ( info.activeNS );
  2139   2269       FREE ( info.baseURIstack );
  2140   2270       Tcl_DStringFree (info.cdata);
  2141   2271       FREE ( info.cdata);
  2142   2272   
  2143   2273       domSetDocumentElement (doc);
................................................................................
  2205   2335           *column = lc->column;
  2206   2336           return 0;
  2207   2337       } else {
  2208   2338           return -1;
  2209   2339       }
  2210   2340   }
  2211   2341   
  2212         -#ifdef TDOM_NS
  2213   2342   domAttrNode *
  2214   2343   domCreateXMLNamespaceNode (
  2215   2344       domNode  *parent
  2216   2345   )
  2217   2346   {
  2218   2347       Tcl_HashEntry  *h;
  2219   2348       int             hnew;
................................................................................
  2230   2359       attr->namespace     = ns->index;
  2231   2360       attr->nodeName      = (char *)&(h->key);
  2232   2361       attr->parentNode    = parent;
  2233   2362       attr->valueLength   = strlen (XML_NAMESPACE);
  2234   2363       attr->nodeValue     = tdomstrdup (XML_NAMESPACE);
  2235   2364       return attr;
  2236   2365   }
  2237         -#endif /* TDOM_NS */
  2238   2366   
  2239   2367   
  2240   2368   /*
  2241   2369    *----------------------------------------------------------------------
  2242   2370    *
  2243   2371    * domCreateDoc --
  2244   2372    *
................................................................................
  2255   2383    *----------------------------------------------------------------------
  2256   2384    */
  2257   2385   
  2258   2386   domDocument *
  2259   2387   domCreateDoc (
  2260   2388       const char * baseURI,
  2261   2389       int          storeLineColumn
  2262         -    )
         2390  +)
  2263   2391   {
  2264   2392       Tcl_HashEntry *h;
  2265   2393       int            hnew;
  2266   2394       domNode       *rootNode;
  2267   2395       domDocument   *doc;
  2268   2396       domLineColumn *lc;
  2269   2397   
................................................................................
  2271   2399       memset(doc, 0, sizeof(domDocument));
  2272   2400       doc->nodeType       = DOCUMENT_NODE;
  2273   2401       doc->documentNumber = DOC_NO(doc);
  2274   2402       doc->nsptr          = -1;
  2275   2403       doc->nslen          =  4;
  2276   2404       doc->namespaces     = (domNS**) MALLOC (sizeof (domNS*) * doc->nslen);
  2277   2405       
  2278         -    /* We malloc and initialze the baseURIs hash table here to avoid
         2406  +    /* We malloc and initialize the baseURIs hash table here to avoid
  2279   2407          cluttering of the code all over the place with checks. */
  2280   2408       doc->baseURIs = MALLOC (sizeof (Tcl_HashTable));
  2281   2409       Tcl_InitHashTable (doc->baseURIs, TCL_ONE_WORD_KEYS);
  2282   2410   
  2283   2411       TDomThreaded(
  2284   2412           domLocksAttach(doc);
  2285   2413           Tcl_InitHashTable(&doc->tdom_tagNames, TCL_STRING_KEYS);
................................................................................
  2303   2431       rootNode->namespace     = 0;
  2304   2432       h = Tcl_CreateHashEntry(&HASHTAB(doc,tdom_tagNames), "", &hnew);
  2305   2433       rootNode->nodeName      = (char *)&(h->key);
  2306   2434       rootNode->nodeNumber    = NODE_NO(doc);
  2307   2435       rootNode->ownerDocument = doc;
  2308   2436       rootNode->parentNode    = NULL;
  2309   2437       rootNode->firstChild    = rootNode->lastChild = NULL;
  2310         -#ifdef TDOM_NS
  2311   2438       rootNode->firstAttr     = domCreateXMLNamespaceNode (rootNode);
  2312         -#endif
  2313   2439       if (storeLineColumn) {
  2314   2440           lc = (domLineColumn*) ( ((char*)rootNode) + sizeof(domNode));
  2315   2441           rootNode->nodeFlags |= HAS_LINE_COLUMN;
  2316   2442           lc->line            = 0;
  2317   2443           lc->column          = 0;
  2318   2444       }
  2319   2445       doc->rootNode = rootNode;
................................................................................
  2323   2449   
  2324   2450   /*---------------------------------------------------------------------------
  2325   2451   |   domCreateDocument
  2326   2452   |
  2327   2453   \--------------------------------------------------------------------------*/
  2328   2454   domDocument *
  2329   2455   domCreateDocument (
  2330         -    Tcl_Interp *interp,
  2331   2456       const char *uri,
  2332   2457       char       *documentElementTagName
  2333   2458   )
  2334   2459   {
  2335   2460       Tcl_HashEntry *h;
  2336   2461       int            hnew;
  2337   2462       domNode       *node;
................................................................................
  2340   2465       const char    *localName;
  2341   2466       domNS         *ns = NULL;
  2342   2467   
  2343   2468       if (uri) {
  2344   2469           domSplitQName (documentElementTagName, prefix, &localName);
  2345   2470           DBG(fprintf(stderr, 
  2346   2471                       "rootName: -->%s<--, prefix: -->%s<--, localName: -->%s<--\n", 
  2347         -                    documentElementTagName, prefix, localName);)
  2348         -        if (prefix[0] != '\0') {
  2349         -            if (!domIsNCNAME (prefix)) {
  2350         -                if (interp) {
  2351         -                    Tcl_SetObjResult(interp, 
  2352         -                                     Tcl_NewStringObj("invalid prefix name", -1));
  2353         -                }
  2354         -                return NULL;
  2355         -            }
  2356         -        }
  2357         -        if (!domIsNCNAME (localName)) {
  2358         -            if (interp) {
  2359         -                Tcl_SetObjResult(interp, 
  2360         -                                 Tcl_NewStringObj("invalid local name", -1));
  2361         -            }
  2362         -            return NULL;
  2363         -        }
  2364         -    } else {
  2365         -        if (!domIsNAME (documentElementTagName)) {
  2366         -            if (interp) {
  2367         -                Tcl_SetObjResult(interp, 
  2368         -                                 Tcl_NewStringObj("invalid root element name", -1));
  2369         -            }
  2370         -            return NULL;
  2371         -        }
         2472  +                    documentElementTagName, prefix, localName););
  2372   2473       }
  2373   2474       doc = domCreateDoc (NULL, 0);
  2374   2475   
  2375   2476       h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames),
  2376   2477                               documentElementTagName, &hnew);
  2377   2478       node = (domNode*) domAlloc(sizeof(domNode));
  2378   2479       memset(node, 0, sizeof(domNode));
................................................................................
  2578   2679       \---------------------------------------------------------------*/
  2579   2680       if (freeCB) {
  2580   2681           freeCB(node, clientData);
  2581   2682       }
  2582   2683       TDomThreaded (    
  2583   2684           if (shared) {
  2584   2685               if (doc->deletedNodes) {
  2585         -                doc->deletedNodes->nextDeleted = node;
         2686  +                node->nextSibling = doc->deletedNodes;
  2586   2687               } else {
  2587         -                doc->deletedNodes = node;
         2688  +                node->nextSibling = NULL;
  2588   2689               }
         2690  +            doc->deletedNodes = node;
  2589   2691               node->nodeFlags |= IS_DELETED;
  2590         -            node->nextDeleted = NULL;
  2591   2692           }
  2592   2693       )
  2593   2694       MutationEvent3(DOMNodeRemoved, childToRemove, node);
  2594   2695       MutationEvent2(DOMSubtreeModified, node);
  2595   2696       domFreeNode(node, freeCB, clientData, 0);
  2596   2697   
  2597   2698       return OK;
................................................................................
  2716   2817           FREE (Tcl_GetHashValue (entryPtr));
  2717   2818           entryPtr = Tcl_NextHashEntry (&search);
  2718   2819       }
  2719   2820       Tcl_DeleteHashTable (doc->baseURIs);
  2720   2821       FREE (doc->baseURIs);
  2721   2822       
  2722   2823       /*-----------------------------------------------------------
  2723         -    | delete xpath cache hash table
         2824  +    | delete XPath cache hash table
  2724   2825       \-----------------------------------------------------------*/
  2725   2826       if (doc->xpathCache) {
  2726   2827           entryPtr = Tcl_FirstHashEntry (doc->xpathCache, &search);
  2727   2828           while (entryPtr) {
  2728   2829               xpathFreeAst((ast)Tcl_GetHashValue (entryPtr));
  2729   2830               entryPtr = Tcl_NextHashEntry (&search);
  2730   2831           }
................................................................................
  2923   3024               if (!attr->namespace) {
  2924   3025                   if (strcmp (attr->nodeName, localName)==0) break;
  2925   3026               }
  2926   3027           }
  2927   3028           attr = attr->nextSibling;
  2928   3029       }
  2929   3030       if (attr) {
  2930         -        DBG(fprintf (stderr, "domSetAttributeNS: reseting existing attribute %s ; old value: %s\n", attr->nodeName, attr->nodeValue);)
         3031  +        DBG(fprintf (stderr, "domSetAttributeNS: resetting existing attribute %s ; old value: %s\n", attr->nodeName, attr->nodeValue);)
  2931   3032           if (attr->nodeFlags & IS_ID_ATTRIBUTE) {
  2932   3033               h = Tcl_FindHashEntry (node->ownerDocument->ids, attr->nodeValue);
  2933   3034               if (h) {
  2934   3035                   Tcl_DeleteHashEntry (h);
  2935   3036                   h = Tcl_CreateHashEntry (node->ownerDocument->ids,
  2936   3037                                            attributeValue, &hnew);
  2937   3038                   Tcl_SetHashValue (h, node);
................................................................................
  3091   3192       }
  3092   3193   
  3093   3194       attr = node->firstAttr;
  3094   3195       while (attr) {
  3095   3196           domSplitQName (attr->nodeName, prefix, &str);
  3096   3197           if (strcmp(localName,str)==0) {
  3097   3198               ns = domGetNamespaceByIndex(node->ownerDocument, attr->namespace);
  3098         -            if (strcmp(ns->uri, uri)==0) {
         3199  +            if (ns && strcmp(ns->uri, uri)==0) {
  3099   3200                   if (previous) {
  3100   3201                       previous->nextSibling = attr->nextSibling;
  3101   3202                   } else {
  3102   3203                       attr->parentNode->firstAttr = attr->nextSibling;
  3103   3204                   }
  3104   3205   
  3105   3206                   if (attr->nodeFlags & IS_ID_ATTRIBUTE) {
................................................................................
  3812   3913   {
  3813   3914       domTextNode   *node;
  3814   3915   
  3815   3916       node = (domTextNode*) domAlloc(sizeof(domTextNode));
  3816   3917       memset(node, 0, sizeof(domTextNode));
  3817   3918       node->nodeType      = nodeType;
  3818   3919       node->nodeFlags     = 0;
  3819         -    node->namespace     = 0;
  3820   3920       node->nodeNumber    = NODE_NO(doc);
  3821   3921       node->ownerDocument = doc;
  3822   3922       node->valueLength   = length;
  3823   3923       node->nodeValue     = (char*)MALLOC(length);
  3824   3924       memmove(node->nodeValue, value, length);
  3825   3925   
  3826   3926       if (doc->fragments) {
................................................................................
  3906   4006       node = (domTextNode*) domAlloc(sizeof(domTextNode));
  3907   4007       memset(node, 0, sizeof(domTextNode));
  3908   4008       node->nodeType      = nodeType;
  3909   4009       node->nodeFlags     = 0;
  3910   4010       if (disableOutputEscaping) {
  3911   4011           node->nodeFlags |= DISABLE_OUTPUT_ESCAPING;
  3912   4012       }
  3913         -    node->namespace     = 0;
  3914   4013       node->nodeNumber    = NODE_NO(parent->ownerDocument);
  3915   4014       node->ownerDocument = parent->ownerDocument;
  3916   4015       node->valueLength   = length;
  3917   4016       node->nodeValue     = (char*)MALLOC(length);
  3918   4017       memmove(node->nodeValue, value, length);
  3919   4018   
  3920   4019       if (parent->lastChild) {
................................................................................
  4364   4463   /*---------------------------------------------------------------------------
  4365   4464   |   domNewElementNode
  4366   4465   |
  4367   4466   \--------------------------------------------------------------------------*/
  4368   4467   domNode *
  4369   4468   domNewElementNode(
  4370   4469       domDocument *doc,
  4371         -    const char  *tagName,
  4372         -    domNodeType  nodeType		
         4470  +    const char  *tagName
  4373   4471   )
  4374   4472   {
  4375   4473       domNode       *node;
  4376   4474       Tcl_HashEntry *h;
  4377   4475       int           hnew;
  4378   4476   
  4379   4477       h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames), tagName, &hnew);
  4380   4478       node = (domNode*) domAlloc(sizeof(domNode));
  4381   4479       memset(node, 0, sizeof(domNode));
  4382         -    node->nodeType      = nodeType;
         4480  +    node->nodeType      = ELEMENT_NODE;
  4383   4481       node->nodeFlags     = 0;
  4384   4482       node->namespace     = 0;
  4385   4483       node->nodeNumber    = NODE_NO(doc);
  4386   4484       node->ownerDocument = doc;
  4387   4485       node->nodeName      = (char *)&(h->key);
  4388   4486   
  4389   4487       if (doc->fragments) {
................................................................................
  4402   4500   |   domNewElementNodeNS
  4403   4501   |
  4404   4502   \--------------------------------------------------------------------------*/
  4405   4503   domNode *
  4406   4504   domNewElementNodeNS (
  4407   4505       domDocument *doc,
  4408   4506       const char  *tagName,
  4409         -    const char  *uri,
  4410         -    domNodeType  nodeType		
         4507  +    const char  *uri
  4411   4508   )
  4412   4509   {
  4413   4510       domNode       *node;
  4414   4511       Tcl_HashEntry *h;
  4415   4512       int            hnew;
  4416   4513       char           prefix[MAX_PREFIX_LEN];
  4417   4514       const char    *localname;
  4418   4515       domNS         *ns;
         4516  +
         4517  +    domSplitQName (tagName, prefix, &localname);
         4518  +    if (prefix[0] == '\0' && uri[0] == '\0') {
         4519  +        return NULL;
         4520  +    }
  4419   4521   
  4420   4522       h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames), tagName, &hnew);
  4421   4523       node = (domNode*) domAlloc(sizeof(domNode));
  4422   4524       memset(node, 0, sizeof(domNode));
  4423         -    node->nodeType      = nodeType;
         4525  +    node->nodeType      = ELEMENT_NODE;
  4424   4526       node->nodeFlags     = 0;
  4425   4527       node->namespace     = 0;
  4426   4528       node->nodeNumber    = NODE_NO(doc);
  4427   4529       node->ownerDocument = doc;
  4428   4530       node->nodeName      = (char *)&(h->key);
  4429   4531   
  4430         -    domSplitQName (tagName, prefix, &localname);
  4431   4532       ns = domNewNamespace(doc, prefix, uri);
  4432   4533       node->namespace = ns->index;
  4433   4534   
  4434   4535       if (doc->fragments) {
  4435   4536           node->nextSibling = doc->fragments;
  4436   4537           doc->fragments->previousSibling = node;
  4437   4538           doc->fragments = node;
................................................................................
  4464   4565                                            pinode->ownerDocument,
  4465   4566                                            pinode->targetValue,
  4466   4567                                            pinode->targetLength,
  4467   4568                                            pinode->dataValue,
  4468   4569                                            pinode->dataLength);
  4469   4570       }
  4470   4571       if (node->nodeType != ELEMENT_NODE) {
  4471         -        domTextNode *tnode = (domTextNode*)node;
  4472         -        return (domNode*) domNewTextNode(tnode->ownerDocument,
  4473         -                                         tnode->nodeValue, tnode->valueLength,
  4474         -					 tnode->nodeType);
         4572  +        domTextNode *t1node, *tnode = (domTextNode*)node;
         4573  +        if (tnode->info) {
         4574  +            t1node = domNewTextNode(tnode->ownerDocument,
         4575  +                                    tnode->nodeValue, tnode->valueLength,
         4576  +                                    tnode->nodeType);
         4577  +            t1node->info = tnode->info;
         4578  +            return (domNode*) t1node;
         4579  +        } else {
         4580  +            return (domNode*) domNewTextNode(tnode->ownerDocument,
         4581  +                                             tnode->nodeValue, tnode->valueLength,
         4582  +                                             tnode->nodeType);
         4583  +        }
  4475   4584       }
  4476   4585   
  4477         -    n = domNewElementNode(node->ownerDocument, node->nodeName, node->nodeType);
         4586  +    n = domNewElementNode(node->ownerDocument, node->nodeName);
  4478   4587       n->namespace = node->namespace;
  4479         -
         4588  +    n->info = node->info;
  4480   4589   
  4481   4590       /*------------------------------------------------------------------
  4482   4591       |   copy attributes (if any)
  4483   4592       \-----------------------------------------------------------------*/
  4484   4593       attr = node->firstAttr;
  4485   4594       while (attr != NULL) {
  4486   4595           nattr = domSetAttribute (n, attr->nodeName, attr->nodeValue );
................................................................................
  4622   4731       \-----------------------------------------------------------------*/
  4623   4732       attr = node->firstAttr;
  4624   4733       while (attr != NULL) {
  4625   4734           if (attr->nodeFlags & IS_NS_NODE) {
  4626   4735               if (copyNS) {
  4627   4736                   /* If copyNS is true, then all namespaces in scope
  4628   4737                    * (including the one declared with the node to copy)
  4629         -                 * are allready copied over. */
         4738  +                 * are already copied over. */
  4630   4739                   attr = attr->nextSibling;
  4631   4740                   continue;
  4632   4741                   
  4633   4742               }
  4634   4743               ns = node->ownerDocument->namespaces[attr->namespace-1];
  4635   4744               ns1 = domLookupPrefix (n, ns->prefix);
  4636   4745               if (ns1 && strcmp (ns->uri, ns1->uri)==0) {
................................................................................
  4956   5065       int            attrLen,
  4957   5066       domAddCallback addCallback,
  4958   5067       void         * clientData
  4959   5068   )
  4960   5069   {
  4961   5070       domNode     *ancestor;
  4962   5071       domAttrNode *attr;
  4963         -    int          found=0, result;
         5072  +    int          result;
  4964   5073   
  4965   5074   
  4966   5075       ancestor = node->parentNode;
  4967   5076       if (ancestor) {
  4968         -        found = 0;
  4969   5077           if ((type == ALL_NODES) || (ancestor->nodeType == type)) {
  4970   5078               if ((element == NULL) ||
  4971   5079                   ((ancestor->nodeType == ELEMENT_NODE) && (strcmp(ancestor->nodeName,element)==0))
  4972   5080                  ) {
  4973   5081                   if (attrName == NULL) {
  4974   5082                       *i = (instance<0) ? (*i)-1 : (*i)+1;
  4975   5083                       if (all || (*i == instance)) {
  4976   5084                           result = addCallback (ancestor, clientData);
  4977   5085                           if (result) {
  4978   5086                               return result;
  4979   5087                           }
  4980         -                        found = 1;
  4981   5088                       }
  4982   5089                   } else {
  4983   5090                       attr = ancestor->firstAttr;
  4984   5091                       while (attr) {
  4985   5092                           if ((strcmp(attr->nodeName,attrName)==0) &&
  4986   5093                               ( (strcmp(attrValue,"*")==0) ||
  4987   5094                                 ( (attr->valueLength == attrLen) &&
................................................................................
  4991   5098                              ) {
  4992   5099                               *i = (instance<0) ? (*i)-1 : (*i)+1;
  4993   5100                               if (all || (*i == instance)) {
  4994   5101                                   result = addCallback (ancestor, clientData);
  4995   5102                                   if (result) {
  4996   5103                                       return result;
  4997   5104                                   }
  4998         -                                found = 1;
  4999   5105                               }
  5000   5106                           }
  5001   5107                           attr = attr->nextSibling;
  5002   5108                       }
  5003   5109                   }
  5004   5110               }
  5005   5111           }
................................................................................
  5025   5131   typedef struct _tdomCmdReadInfo {
  5026   5132   
  5027   5133       XML_Parser        parser;
  5028   5134       domDocument      *document;
  5029   5135       domNode          *currentNode;
  5030   5136       int               depth;
  5031   5137       int               ignoreWhiteSpaces;
         5138  +    int               cdataSection;
  5032   5139       Tcl_DString      *cdata;
  5033         -    TEncoding        *encoding_8bit;
  5034   5140       int               storeLineColumn;
         5141  +    int               ignorexmlns;
  5035   5142       int               feedbackAfter;
  5036         -    int               lastFeedbackPosition;
         5143  +    Tcl_Obj          *feedbackCmd;
         5144  +    int               nextFeedbackPosition;
  5037   5145       Tcl_Interp       *interp;
  5038   5146       int               activeNSsize;
  5039   5147       int               activeNSpos;
  5040   5148       domActiveNS      *activeNS;
  5041   5149       int               baseURIstackSize;
  5042   5150       int               baseURIstackPos;
  5043   5151       domActiveBaseURI *baseURIstack;
................................................................................
  5104   5212           domFreeDocument (info->document, NULL, NULL);
  5105   5213       }
  5106   5214   
  5107   5215       info->document          = NULL;
  5108   5216       info->currentNode       = NULL;
  5109   5217       info->depth             = 0;
  5110   5218       info->feedbackAfter     = 0;
         5219  +    info->ignorexmlns       = 0;
  5111   5220       Tcl_DStringSetLength (info->cdata, 0);
  5112         -    info->lastFeedbackPosition = 0;
         5221  +    info->nextFeedbackPosition = info->feedbackAfter;
  5113   5222       info->interp            = interp;
  5114   5223       info->activeNSpos       = -1;
  5115   5224       info->insideDTD         = 0;
  5116   5225       info->baseURIstackPos   = 0;
  5117   5226       info->tdomStatus        = 0;
  5118   5227   
  5119   5228   }
................................................................................
  5153   5262   }
  5154   5263   
  5155   5264   int
  5156   5265   TclTdomObjCmd (dummy, interp, objc, objv)
  5157   5266        ClientData dummy;
  5158   5267        Tcl_Interp *interp;
  5159   5268        int objc;
  5160         -     Tcl_Obj *CONST objv[];
         5269  +     Tcl_Obj *const objv[];
  5161   5270   {
  5162         -    char            *method, *encodingName;
  5163   5271       CHandlerSet     *handlerSet;
  5164   5272       int              methodIndex, result, bool;
  5165   5273       tdomCmdReadInfo *info;
  5166   5274       TclGenExpatInfo *expat;
  5167   5275       Tcl_Obj         *newObjName = NULL;
  5168         -    TEncoding       *encoding;
  5169   5276   
  5170         -    static CONST84 char *tdomMethods[] = {
         5277  +    static const char *tdomMethods[] = {
  5171   5278           "enable", "getdoc",
  5172         -        "setResultEncoding", "setStoreLineColumn",
         5279  +        "setStoreLineColumn",
  5173   5280           "setExternalEntityResolver", "keepEmpties",
  5174         -        "remove",
         5281  +        "remove", "ignorexmlns", "keepCDATA",
  5175   5282           NULL
  5176   5283       };
  5177   5284       enum tdomMethod {
  5178   5285           m_enable, m_getdoc,
  5179         -        m_setResultEncoding, m_setStoreLineColumn,
         5286  +        m_setStoreLineColumn,
  5180   5287           m_setExternalEntityResolver, m_keepEmpties,
  5181         -        m_remove
         5288  +        m_remove, m_ignorexmlns, m_keepCDATA
  5182   5289       };
  5183   5290   
  5184   5291       if (objc < 3 || objc > 4) {
  5185   5292           Tcl_WrongNumArgs (interp, 1, objv, tdom_usage);
  5186   5293           return TCL_ERROR;
  5187   5294       }
  5188   5295   
  5189   5296       if (!CheckExpatParserObj (interp, objv[1])) {
  5190   5297           Tcl_SetResult (interp, "First argument has to be a expat parser object", NULL);
  5191   5298           return TCL_ERROR;
  5192   5299       }
  5193   5300   
  5194         -    method = Tcl_GetString(objv[2]);
  5195   5301       if (Tcl_GetIndexFromObj (interp, objv[2], tdomMethods, "method", 0,
  5196   5302                                &methodIndex) != TCL_OK)
  5197   5303       {
  5198   5304           Tcl_SetResult (interp, tdom_usage, NULL);
  5199   5305           return TCL_ERROR;
  5200   5306       }
  5201   5307   
................................................................................
  5202   5308       switch ((enum tdomMethod) methodIndex) {
  5203   5309   
  5204   5310       default:
  5205   5311           Tcl_SetResult (interp, "unknown method", NULL);
  5206   5312           return TCL_ERROR;
  5207   5313   
  5208   5314       case m_enable:
         5315  +        expat = GetExpatInfo (interp, objv[1]);
         5316  +        if (expat->parsingState != 0) {
         5317  +            Tcl_SetResult (interp, 
         5318  +                           "Parser is not in init or reset state.", NULL);
         5319  +            return TCL_ERROR;
         5320  +        }
         5321  +
  5209   5322           handlerSet = CHandlerSetCreate ("tdom");
  5210   5323           handlerSet->ignoreWhiteCDATAs       = 1;
  5211   5324           handlerSet->resetProc               = tdom_resetProc;
  5212   5325           handlerSet->freeProc                = tdom_freeProc;
  5213   5326           handlerSet->parserResetProc         = tdom_parserResetProc;
  5214   5327           handlerSet->initParseProc           = tdom_initParseProc;
  5215   5328           handlerSet->elementstartcommand     = startElement;
................................................................................
  5218   5331   /*         handlerSet->datacommand             = characterDataHandler; */
  5219   5332           handlerSet->commentCommand          = commentHandler;
  5220   5333           handlerSet->picommand               = processingInstructionHandler;
  5221   5334           handlerSet->entityDeclCommand       = entityDeclHandler;
  5222   5335           handlerSet->startDoctypeDeclCommand = startDoctypeDeclHandler;
  5223   5336           handlerSet->endDoctypeDeclCommand   = endDoctypeDeclHandler;
  5224   5337   
  5225         -        expat = GetExpatInfo (interp, objv[1]);
  5226         -
  5227   5338           info = (tdomCmdReadInfo *) MALLOC (sizeof (tdomCmdReadInfo));
  5228   5339           info->parser            = expat->parser;
  5229   5340           info->document          = NULL;
  5230   5341           info->currentNode       = NULL;
  5231   5342           info->depth             = 0;
  5232   5343           info->ignoreWhiteSpaces = 1;
         5344  +        info->cdataSection      = 0;
  5233   5345           info->cdata             = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
  5234   5346           Tcl_DStringInit (info->cdata);
  5235         -        info->encoding_8bit     = 0;
  5236   5347           info->storeLineColumn   = 0;
         5348  +        info->ignorexmlns       = 0;
  5237   5349           info->feedbackAfter     = 0;
  5238         -        info->lastFeedbackPosition = 0;
         5350  +        info->feedbackCmd       = NULL;
         5351  +        info->nextFeedbackPosition = 0;
  5239   5352           info->interp            = interp;
  5240   5353           info->activeNSpos       = -1;
  5241   5354           info->activeNSsize      = 8;
  5242   5355           info->activeNS          = 
  5243   5356               (domActiveNS*) MALLOC(sizeof(domActiveNS) * info->activeNSsize);
  5244   5357           info->baseURIstackPos   = 0;
  5245   5358           info->baseURIstackSize  = INITIAL_BASEURISTACK_SIZE;
................................................................................
  5258   5371           info = CHandlerSetGetUserData (interp, objv[1], "tdom");
  5259   5372           if (!info) {
  5260   5373               Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
  5261   5374               return TCL_ERROR;
  5262   5375           }
  5263   5376           expat = GetExpatInfo (interp, objv[1]);
  5264   5377           if (info->tdomStatus != 2 || !expat->finished) {
  5265         -            Tcl_SetResult (interp, "No DOM tree avaliable.", NULL);
         5378  +            Tcl_SetResult (interp, "No DOM tree available.", NULL);
  5266   5379               return TCL_ERROR;
  5267   5380           }
  5268   5381           domSetDocumentElement (info->document);
  5269   5382           result = tcldom_returnDocumentObj (interp, info->document, 0,
  5270   5383                                              newObjName, 0, 0);
  5271   5384           info->document = NULL;
  5272   5385           return result;
  5273   5386   
  5274         -    case m_setResultEncoding:
  5275         -        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
  5276         -        if (!info) {
  5277         -            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
  5278         -            return TCL_ERROR;
  5279         -        }
  5280         -        if (info->encoding_8bit == NULL) {
  5281         -            Tcl_AppendResult (interp, "UTF-8", NULL);
  5282         -        }
  5283         -        else {
  5284         -            Tcl_AppendResult (interp,
  5285         -                              tdom_GetEncodingName (info->encoding_8bit),
  5286         -                              NULL);
  5287         -        }
  5288         -        if (objc == 4) {
  5289         -            encodingName = Tcl_GetString(objv[3]);
  5290         -
  5291         -            if (   (strcmp(encodingName, "UTF-8") == 0)
  5292         -                 ||(strcmp(encodingName, "UTF8" ) == 0)
  5293         -                 ||(strcmp(encodingName, "utf-8") == 0)
  5294         -                 ||(strcmp(encodingName, "utf8" ) == 0)) {
  5295         -
  5296         -                info->encoding_8bit = NULL;
  5297         -            } else {
  5298         -                encoding = tdom_GetEncoding ( encodingName );
  5299         -                if (encoding == NULL) {
  5300         -                    Tcl_AppendResult(interp, "encoding not found", NULL);
  5301         -                    return TCL_ERROR;
  5302         -                }
  5303         -                info->encoding_8bit = encoding;
  5304         -            }
  5305         -        }
  5306         -        info->tdomStatus = 1;
  5307         -        break;
  5308         -        
  5309   5387       case m_setStoreLineColumn:
  5310   5388           info = CHandlerSetGetUserData (interp, objv[1], "tdom");
  5311   5389           if (!info) {
  5312   5390               Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
  5313   5391               return TCL_ERROR;
  5314   5392           }
  5315   5393           Tcl_SetIntObj (Tcl_GetObjResult (interp), info->storeLineColumn);
  5316   5394           if (objc == 4) {
  5317         -            Tcl_GetBooleanFromObj (interp, objv[3], &bool);
         5395  +            if (Tcl_GetBooleanFromObj (interp, objv[3], &bool) != TCL_OK) {
         5396  +                return TCL_ERROR;
         5397  +            }
  5318   5398               info->storeLineColumn = bool;
  5319   5399           }
  5320   5400           info->tdomStatus = 1;
  5321   5401           break;
  5322   5402           
  5323   5403       case m_remove:
  5324   5404           result = CHandlerSetRemove (interp, objv[1], "tdom");
................................................................................
  5326   5406               Tcl_SetResult (interp, "expat parser obj hasn't a C handler set named \"tdom\"", NULL);
  5327   5407               return TCL_ERROR;
  5328   5408           }
  5329   5409           break;
  5330   5410   
  5331   5411       case m_setExternalEntityResolver:
  5332   5412           if (objc != 4) {
  5333         -            Tcl_SetResult (interp, "You must name a tcl command as external entity resolver for setExternalEntityResolver.", NULL);
         5413  +            Tcl_SetResult (interp, "You must name a Tcl command as external entity resolver for setExternalEntityResolver.", NULL);
  5334   5414               return TCL_ERROR;
  5335   5415           }
  5336   5416           info = CHandlerSetGetUserData (interp, objv[1], "tdom");
  5337   5417           if (!info) {
  5338   5418               Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
  5339   5419               return TCL_ERROR;
  5340   5420           }
................................................................................
  5353   5433       case m_keepEmpties:
  5354   5434           if (objc != 4) {
  5355   5435               Tcl_SetResult (interp, "wrong # of args for method keepEmpties.",
  5356   5436                              NULL);
  5357   5437               return TCL_ERROR;
  5358   5438           }
  5359   5439           handlerSet = CHandlerSetGet (interp, objv[1], "tdom");
         5440  +        if (!handlerSet) {
         5441  +            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
         5442  +            return TCL_ERROR;
         5443  +        }
  5360   5444           info = handlerSet->userData;
  5361   5445           if (!info) {
  5362   5446               Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
  5363   5447               return TCL_ERROR;
  5364   5448           }
  5365   5449           Tcl_SetIntObj (Tcl_GetObjResult (interp), info->ignoreWhiteSpaces);
  5366         -        Tcl_GetBooleanFromObj (interp, objv[3], &bool);
         5450  +        if (Tcl_GetBooleanFromObj (interp, objv[3], &bool) != TCL_OK) {
         5451  +            return TCL_ERROR;
         5452  +        }
  5367   5453           info->ignoreWhiteSpaces = !bool;
  5368   5454           handlerSet->ignoreWhiteCDATAs = !bool;
  5369   5455           info->tdomStatus = 1;
  5370   5456           break;
         5457  +
         5458  +    case m_keepCDATA:
         5459  +        if (objc != 4) {
         5460  +            Tcl_SetResult (interp, "wrong # of args for method keepCDATA.",
         5461  +                           NULL);
         5462  +            return TCL_ERROR;
         5463  +        }
         5464  +        handlerSet = CHandlerSetGet (interp, objv[1], "tdom");
         5465  +        if (!handlerSet) {
         5466  +            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
         5467  +            return TCL_ERROR;
         5468  +        }
         5469  +        info = handlerSet->userData;
         5470  +        if (!info) {
         5471  +            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
         5472  +            return TCL_ERROR;
         5473  +        }
         5474  +        if (Tcl_GetBooleanFromObj (interp, objv[3], &bool) != TCL_OK) {
         5475  +            return TCL_ERROR;
         5476  +        }
         5477  +        if (bool) {
         5478  +            handlerSet->startCdataSectionCommand = startCDATA;
         5479  +            handlerSet->endCdataSectionCommand = endCDATA;
         5480  +        } else {
         5481  +            handlerSet->startCdataSectionCommand = startCDATA;
         5482  +            handlerSet->endCdataSectionCommand = endCDATA;
         5483  +        }
         5484  +        info->tdomStatus = 1;
         5485  +        break;
         5486  +        
         5487  +    case m_ignorexmlns:
         5488  +        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
         5489  +        if (!info) {
         5490  +            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
         5491  +            return TCL_ERROR;
         5492  +        }
         5493  +        Tcl_SetIntObj (Tcl_GetObjResult (interp), info->ignorexmlns);
         5494  +        if (objc == 4) {
         5495  +            if (Tcl_GetBooleanFromObj (interp, objv[3], &bool) != TCL_OK) {
         5496  +                return TCL_ERROR;
         5497  +            }
         5498  +            info->ignorexmlns = bool;
         5499  +        }
         5500  +        info->tdomStatus = 1;
         5501  +        break;
         5502  +        
         5503  +
  5371   5504       }
  5372   5505   
  5373   5506       return TCL_OK;
  5374   5507   }

Changes to generic/dom.h.

    33     33   |
    34     34   \--------------------------------------------------------------------------*/
    35     35   
    36     36   #ifndef __DOM_H__
    37     37   #define __DOM_H__
    38     38   
    39     39   #include <tcl.h>
           40  +#include <stdlib.h>
           41  +#include <string.h>
    40     42   #include <ctype.h>
    41     43   #include <expat.h>
    42         -#include <utf8conv.h>
    43     44   #include <domalloc.h>
    44     45   
    45     46   /*
    46     47    * tDOM provides it's own memory allocator which is optimized for
    47     48    * low heap usage. It uses the native Tcl allocator underneath,
    48     49    * though, but it is not very MT-friendly. Therefore, you might
    49     50    * use the (normal) Tcl allocator with USE_NORMAL_ALLOCATOR
................................................................................
    83     84      };
    84     85   #  define MEM_SUITE &memsuite
    85     86   #else
    86     87   #  define MEM_SUITE NULL
    87     88   #endif
    88     89   
    89     90   /*
    90         - * Beginning with 8.4, Tcl API is CONST'ified
           91  + * Beginning with 8.6, interp->errorLine isn't public visible anymore
           92  + * (TIP 330)
    91     93    */
    92         -#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3)
    93         -# define CONST84
           94  +#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
           95  +# define Tcl_GetErrorLine(interp) (interp)->errorLine
    94     96   #endif
    95     97   
    96     98   /*
    97     99    * Starting with Tcl 8.2 the Tcl_Panic() is defined properly
    98    100    * over the stubs table.
    99    101    * Also, we have a proper Tcl_GetString() shortcut afterwards.
   100    102    */
................................................................................
   124    126   # define TDomNotThreaded(x)
   125    127   # define TDomThreaded(x)    x
   126    128   # define HASHTAB(doc,tab)   (doc)->tab
   127    129   # define NODE_NO(doc)       ((doc)->nodeCounter)++
   128    130   # define DOC_NO(doc)        (unsigned long)(doc)
   129    131   #endif /* TCL_THREADS */
   130    132   
   131         -#define DOC_CMD(s,doc)      sprintf((s), "domDoc%p", (doc))
   132         -#define NODE_CMD(s,node)    sprintf((s), "domNode%p", (node))
   133         -#define XSLT_CMD(s,doc)     sprintf((s), "XSLTcmd%p", (doc))
          133  +#define DOC_CMD(s,doc)      sprintf((s), "domDoc%p", (void *)(doc))
          134  +#define NODE_CMD(s,node)    sprintf((s), "domNode%p", (void *)(node))
          135  +#define XSLT_CMD(s,doc)     sprintf((s), "XSLTcmd%p", (void *)(doc))
   134    136   
   135    137   #define XML_NAMESPACE "http://www.w3.org/XML/1998/namespace"
   136    138   #define XMLNS_NAMESPACE "http://www.w3.org/2000/xmlns"
   137    139   
   138         -#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0) || TCL_MAJOR_VERSION < 8
   139         -#define TclOnly8Bits 1
   140         -#else
   141         -#define TclOnly8Bits 0
   142         -#endif
   143         -
   144    140   #define UTF8_1BYTE_CHAR(c) ( 0    == ((c) & 0x80))
   145    141   #define UTF8_2BYTE_CHAR(c) ( 0xC0 == ((c) & 0xE0))
   146    142   #define UTF8_3BYTE_CHAR(c) ( 0xE0 == ((c) & 0xF0))
   147    143   #define UTF8_4BYTE_CHAR(c) ( 0xF0 == ((c) & 0xF8))
   148    144   
   149         -#if TclOnly8Bits
   150         -#define UTF8_CHAR_LEN(c) 1
   151         -#else
   152    145   #define UTF8_CHAR_LEN(c) \
   153    146     UTF8_1BYTE_CHAR((c)) ? 1 : \
   154    147      (UTF8_2BYTE_CHAR((c)) ? 2 : \
   155         -     (UTF8_3BYTE_CHAR((c)) ? 3 : 0))
   156         -#endif
          148  +     (UTF8_3BYTE_CHAR((c)) ? 3 : \
          149  +       (UTF8_4BYTE_CHAR((c)) ? 4 : 0)))
   157    150   
   158    151   /* The following 2 defines are out of the expat code */
   159    152   
   160    153   /* A 2 byte UTF-8 representation splits the characters 11 bits
   161    154   between the bottom 5 and 6 bits of the bytes.
   162    155   We need 8 bits to index into pages, 3 bits to add to that index and
   163    156   5 bits to generate the mask. */
................................................................................
   211    204     ? NCnameStart7Bit[(int)(*(p))] \
   212    205     : ((n) == 2 \
   213    206       ? UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)(p)) \
   214    207       : ((n) == 3 \
   215    208         ? UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)(p)) \
   216    209         : 0)))
   217    210   
   218         -#if TclOnly8Bits 
   219         -#  define UTF8_XMLCHAR(p,n) \
   220         - (*(p) < 0x80 ? CharBit[(int)(*(p))] : 1)
   221         -#else  
   222         -#  define UTF8_XMLCHAR3(p) \
          211  +#define UTF8_XMLCHAR3(p) \
   223    212     (*(p) == 0xED  \
   224    213      ? ((p)[1] < 0xA0 ? 1 : 0) \
   225    214      : (*(p) == 0xEF \
   226    215         ? ((p)[1] == 0xBF \
   227    216            ? ((p)[2] == 0xBE || (p)[2] == 0xBF ? 0 : 1) \
   228    217            : 1) \
   229    218         : 1)) \
   230    219       
   231         -#  define UTF8_XMLCHAR(p, n) \
          220  +/* This definition is lax in the sense, that it accepts every 4 byte
          221  + * utf-8 character beyond #xFFFF as valid, no matter, if Unicode has
          222  + * (so far) defined a character for that encoding point. Additionally,
          223  + * this define does not care about the discouraged characters beyond
          224  + * #xFFFF (but after all, they are only discouraged, not
          225  + * forbidden). */
          226  +#define UTF8_XMLCHAR(p, n) \
   232    227     ((n) == 1 \
   233    228     ? CharBit[(int)(*(p))] \
   234    229     : ((n) == 2 \
   235    230       ? 1 \
   236    231       : ((n) == 3 \
   237    232         ? (UTF8_XMLCHAR3(p)) \
   238         -      : 0)))
   239         -#endif
          233  +      : ((n) == 4 \
          234  +        ? 1 : 0))))
   240    235   
   241    236   #include "../expat/nametab.h"
   242    237   
   243    238   static const unsigned char nameChar7Bit[] = {
   244    239   /* 0x00 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   245    240   /* 0x08 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   246    241   /* 0x10 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
................................................................................
   334    329   /* 0x60 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
   335    330   /* 0x68 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
   336    331   /* 0x70 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
   337    332   /* 0x78 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
   338    333   };
   339    334   
   340    335   
   341         -#if TclOnly8Bits == 1
   342         -#  define isNameStart(x)   (isalpha(*x) || ((*x)=='_') || ((*x)==':'))
   343         -#  define isNameChar(x)    (isalnum(*x)  || ((*x)=='_') || ((*x)=='-') || ((*x)=='.') || ((*x)==':'))
   344         -#  define isNCNameStart(x) (isalpha(*x) || ((*x)=='_'))
   345         -#  define isNCNameChar(x)  (isalnum(*x)  || ((*x)=='_') || ((*x)=='-') || ((*x)=='.'))
   346         -#else
   347         -#  define isNameStart(x)   UTF8_GET_NAME_START((x),UTF8_CHAR_LEN(*(x)))
   348         -#  define isNCNameStart(x) UTF8_GET_NCNAME_START((x),UTF8_CHAR_LEN(*(x)))
   349         -#  define isNameChar(x)    UTF8_GET_NAMING_NMTOKEN((x),UTF8_CHAR_LEN(*(x)))
   350         -#  define isNCNameChar(x)  UTF8_GET_NAMING_NCNMTOKEN((x),UTF8_CHAR_LEN(*(x)))
   351         -#endif
          336  +#define isNameStart(x)   UTF8_GET_NAME_START((x),UTF8_CHAR_LEN(*(x)))
          337  +#define isNCNameStart(x) UTF8_GET_NCNAME_START((x),UTF8_CHAR_LEN(*(x)))
          338  +#define isNameChar(x)    UTF8_GET_NAMING_NMTOKEN((x),UTF8_CHAR_LEN(*(x)))
          339  +#define isNCNameChar(x)  UTF8_GET_NAMING_NCNMTOKEN((x),UTF8_CHAR_LEN(*(x)))
   352    340   
   353    341   #define IS_XML_WHITESPACE(c)  ((c)==' ' || (c)=='\n' || (c)=='\r' || (c)=='\t')
   354    342   
   355    343   /*--------------------------------------------------------------------------
   356    344   |   DOMString
   357    345   |
   358    346   \-------------------------------------------------------------------------*/
................................................................................
   419    407   #define IS_NS_NODE                2
   420    408   
   421    409   typedef unsigned int domDocFlags;
   422    410   
   423    411   #define OUTPUT_DEFAULT_INDENT     1
   424    412   #define NEEDS_RENUMBERING         2
   425    413   #define DONT_FREE                 4
          414  +#define IGNORE_XMLNS              8
          415  +#define DOCUMENT_CMD             16
          416  +#define VAR_TRACE                32
   426    417   
   427    418   /*--------------------------------------------------------------------------
   428    419   |   a index to the namespace records
   429    420   |
   430    421   \-------------------------------------------------------------------------*/
   431    422   typedef unsigned int domNameSpaceIndex;
   432    423   
................................................................................
   550    541      int     index;
   551    542   
   552    543   } domNS;
   553    544   
   554    545   
   555    546   #define MAX_PREFIX_LEN   80
   556    547   
          548  +/*---------------------------------------------------------------------------
          549  +|   type domActiveNS
          550  +|
          551  +\--------------------------------------------------------------------------*/
          552  +typedef struct _domActiveNS {
          553  +
          554  +    int    depth;
          555  +    domNS *namespace;
          556  +
          557  +} domActiveNS;
   557    558   
   558    559   
   559    560   /*--------------------------------------------------------------------------
   560    561   |   domLineColumn
   561    562   |
   562    563   \-------------------------------------------------------------------------*/
   563    564   typedef struct domLineColumn {
................................................................................
   572    573   |   domNode
   573    574   |
   574    575   \-------------------------------------------------------------------------*/
   575    576   typedef struct domNode {
   576    577   
   577    578       domNodeType         nodeType  : 8;
   578    579       domNodeFlags        nodeFlags : 8;
          580  +#ifdef TDOM_LESS_NS
   579    581       domNameSpaceIndex   namespace : 8;
   580    582       unsigned int        info      : 8;
          583  +#else
          584  +    unsigned int        dummy     : 8;
          585  +    unsigned int        info      : 8;    
          586  +#endif
   581    587       unsigned int        nodeNumber;
   582    588       domDocument        *ownerDocument;
   583    589       struct domNode     *parentNode;
   584    590       struct domNode     *previousSibling;
   585    591       struct domNode     *nextSibling;
   586    592   
   587    593       domString           nodeName;  /* now the element node specific fields */
          594  +#ifndef TDOM_LESS_NS
          595  +    domNameSpaceIndex   namespace;
          596  +#endif
   588    597       struct domNode     *firstChild;
   589    598       struct domNode     *lastChild;
   590         -#ifdef TCL_THREADS
   591         -    struct domNode     *nextDeleted;
   592         -#endif
   593    599       struct domAttrNode *firstAttr;
   594    600   
   595    601   } domNode;
   596    602   
   597    603   /*--------------------------------------------------------------------------
   598    604   |   domDeleteInfo
   599    605   |
................................................................................
   611    617   |   domTextNode
   612    618   |
   613    619   \-------------------------------------------------------------------------*/
   614    620   typedef struct domTextNode {
   615    621   
   616    622       domNodeType         nodeType  : 8;
   617    623       domNodeFlags        nodeFlags : 8;
          624  +#ifdef TDOM_LESS_NS
   618    625       domNameSpaceIndex   namespace : 8;
   619    626       unsigned int        info      : 8;
          627  +#else
          628  +    unsigned int        dummy     : 8;
          629  +    unsigned int        info      : 8;    
          630  +#endif
   620    631       unsigned int        nodeNumber;
   621    632       domDocument        *ownerDocument;
   622    633       struct domNode     *parentNode;
   623    634       struct domNode     *previousSibling;
   624    635       struct domNode     *nextSibling;
   625    636   
   626    637       domString           nodeValue;   /* now the text node specific fields */
................................................................................
   633    644   |   domProcessingInstructionNode
   634    645   |
   635    646   \-------------------------------------------------------------------------*/
   636    647   typedef struct domProcessingInstructionNode {
   637    648   
   638    649       domNodeType         nodeType  : 8;
   639    650       domNodeFlags        nodeFlags : 8;
          651  +#ifdef TDOM_LESS_NS
   640    652       domNameSpaceIndex   namespace : 8;
   641    653       unsigned int        info      : 8;
          654  +#else
          655  +    unsigned int        dummy     : 8;
          656  +    unsigned int        info      : 8;    
          657  +#endif
   642    658       unsigned int        nodeNumber;
   643    659       domDocument        *ownerDocument;
   644    660       struct domNode     *parentNode;
   645    661       struct domNode     *previousSibling;
   646    662       struct domNode     *nextSibling;
   647    663   
   648    664       domString           targetValue;   /* now the pi specific fields */
   649    665       int                 targetLength;
          666  +#ifndef TDOM_LESS_NS
          667  +    domNameSpaceIndex   namespace;
          668  +#endif
   650    669       domString           dataValue;
   651    670       int                 dataLength;
   652    671   
   653    672   } domProcessingInstructionNode;
   654    673   
   655    674   
   656    675   /*--------------------------------------------------------------------------
................................................................................
   657    676   |   domAttrNode
   658    677   |
   659    678   \-------------------------------------------------------------------------*/
   660    679   typedef struct domAttrNode {
   661    680   
   662    681       domNodeType         nodeType  : 8;
   663    682       domAttrFlags        nodeFlags : 8;
          683  +#ifdef TDOM_LESS_NS
   664    684       domNameSpaceIndex   namespace : 8;
   665    685       unsigned int        info      : 8;
          686  +#else
          687  +    unsigned int        dummy     : 8;
          688  +    unsigned int        info      : 8;    
          689  +    domNameSpaceIndex   namespace;
          690  +#endif
   666    691       domString           nodeName;
   667    692       domString           nodeValue;
   668    693       int                 valueLength;
   669    694       struct domNode     *parentNode;
   670    695       struct domAttrNode *nextSibling;
   671    696   
   672    697   } domAttrNode;
................................................................................
   678    703   typedef int  (*domAddCallback)  (domNode * node, void * clientData);
   679    704   typedef void (*domFreeCallback) (domNode * node, void * clientData);
   680    705   
   681    706   /*--------------------------------------------------------------------------
   682    707   |   Function prototypes
   683    708   |
   684    709   \-------------------------------------------------------------------------*/
   685         -const char *   domException2String (domException expection);
          710  +const char *   domException2String (domException exception);
   686    711   
   687    712   
   688    713   void           domModuleInitialize (void);
   689    714   domDocument *  domCreateDoc (const char *baseURI, int storeLineColumn);
   690         -domDocument *  domCreateDocument (Tcl_Interp *interp, const char *uri,
          715  +domDocument *  domCreateDocument (const char *uri,
   691    716                                     char *documentElementTagName);
   692    717   void           domSetDocumentElement (domDocument *doc);
   693    718   
   694    719   domDocument *  domReadDocument   (XML_Parser parser,
   695    720                                     char *xml,
   696    721                                     int   length,
   697    722                                     int   ignoreWhiteSpaces,
   698         -                                  TEncoding *encoding_8bit,
          723  +                                  int   keepCDATA,
   699    724                                     int   storeLineColumn,
          725  +                                  int   ignoreXMLNS,
   700    726                                     int   feedbackAfter,
          727  +                                  Tcl_Obj *feedbackCmd,
   701    728                                     Tcl_Channel channel,
   702    729                                     const char *baseurl,
   703         -                                  char *extResolver,
          730  +                                  Tcl_Obj *extResolver,
   704    731                                     int   useForeignDTD,
   705    732                                     int   paramEntityParsing,
   706         -                                  Tcl_Interp *interp);
          733  +                                  Tcl_Interp *interp,
          734  +                                  int  *status);
   707    735   
   708    736   void           domFreeDocument   (domDocument *doc, 
   709    737                                     domFreeCallback freeCB, 
   710    738                                     void * clientData);
   711    739   
   712    740   void           domFreeNode       (domNode *node, 
   713    741                                     domFreeCallback freeCB, 
................................................................................
   716    744   
   717    745   domTextNode *  domNewTextNode    (domDocument *doc,
   718    746                                     const char  *value,
   719    747                                     int          length,
   720    748                                     domNodeType  nodeType);
   721    749   
   722    750   domNode *      domNewElementNode (domDocument *doc,
   723         -                                  const char  *tagName,
   724         -                                  domNodeType  nodeType);
          751  +                                  const char  *tagName);
   725    752   		
   726    753   domNode *      domNewElementNodeNS (domDocument *doc,
   727    754                                       const char  *tagName,
   728         -                                    const char  *uri,
   729         -                                    domNodeType  nodeType);
          755  +                                    const char  *uri);
   730    756   
   731    757   domProcessingInstructionNode * domNewProcessingInstructionNode (
   732    758                                     domDocument *doc,
   733    759                                     const char  *targetValue,
   734    760                                     int          targetLength,
   735    761                                     const char  *dataValue,
   736    762                                     int          dataLength);
................................................................................
   767    793   const char *   domNamespaceURI    (domNode *node);
   768    794   const char *   domGetLocalName    (const char *nodeName);
   769    795   int            domSplitQName (const char *name, char *prefix,
   770    796                                 const char **localName);
   771    797   domNS *        domLookupNamespace (domDocument *doc, const char *prefix, 
   772    798                                      const char *namespaceURI);
   773    799   domNS *        domLookupPrefix  (domNode *node, const char *prefix);
          800  +int            domIsNamespaceInScope (domActiveNS *NSstack, int NSstackPos,
          801  +                                      const char *prefix, const char *namespaceURI);
   774    802   const char *   domLookupPrefixWithMappings (domNode *node, const char *prefix,
   775    803                                               char **prefixMappings);
   776    804   domNS *        domLookupURI     (domNode *node, char *uri);
   777    805   domNS *        domGetNamespaceByIndex (domDocument *doc, int nsIndex);
   778    806   domNS *        domNewNamespace (domDocument *doc, const char *prefix,
   779    807                                   const char *namespaceURI);
   780    808   int            domGetLineColumn (domNode *node, int *line, int *column);
................................................................................
   803    831   
   804    832   void           tcldom_tolower (const char *str, char *str_out, int  len);
   805    833   int            domIsNAME (const char *name);
   806    834   int            domIsPINAME (const char *name);
   807    835   int            domIsQNAME (const char *name);
   808    836   int            domIsNCNAME (const char *name);
   809    837   int            domIsChar (const char *str);
          838  +int            domIsBMPChar (const char *str);
   810    839   int            domIsComment (const char *str);
   811    840   int            domIsCDATA (const char *str);
   812    841   int            domIsPIValue (const char *str);
   813    842   void           domCopyTo (domNode *node, domNode *parent, int copyNS);
   814    843   void           domCopyNS (domNode *from, domNode *to);
   815    844   domAttrNode *  domCreateXMLNamespaceNode (domNode *parent);
   816    845   void           domRenumberTree (domNode *node);

Changes to generic/domalloc.h.

    30     30   |
    31     31   |
    32     32   |   written by Jochen Loewer
    33     33   |   October, 2000
    34     34   |
    35     35   \--------------------------------------------------------------------------*/
    36     36   
    37         -void   domAllocInit();
           37  +void   domAllocInit(void);
    38     38   void * domAlloc(int size);
    39     39   void   domFree(void *mem);
    40     40   

Changes to generic/domhtml.c.

    30     30   |
    31     31   |
    32     32   |   written by Jochen Loewer
    33     33   |   October 2000
    34     34   |
    35     35   |   ------------------------------------------------------------------------
    36     36   |
    37         -|   A parser for XML.
    38         -|
    39         -|   Copyright (C) 1998 D. Richard Hipp
    40         -|
    41         -|   This library is free software; you can redistribute it and/or
    42         -|   modify it under the terms of the GNU Library General Public
    43         -|   License as published by the Free Software Foundation; either
    44         -|   version 2 of the License, or (at your option) any later version.
    45         -|
    46         -|   This library is distributed in the hope that it will be useful,
    47         -|   but WITHOUT ANY WARRANTY; without even the implied warranty of
    48         -|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    49         -|   Library General Public License for more details.
    50         -|
    51         -|   You should have received a copy of the GNU Library General Public
    52         -|   License along with this library; if not, write to the
    53         -|   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    54         -|   Boston, MA  02111-1307, USA.
    55         -|
    56         -|   Author contact information:
    57         -|     drh@acm.org
    58         -|     http://www.hwaci.com/drh/
           37  +|   Partly based on a parser for XML (for TMML by R.Hipp 1998). 
           38  +|   This source code is released into the public domain by the author.
           39  +|   on 2002, December 17.
    59     40   |
    60     41   \---------------------------------------------------------------------------*/
    61     42   
    62     43   
    63     44   
    64     45   /*----------------------------------------------------------------------------
    65     46   |   Includes
................................................................................
   115     96   
   116     97   /*----------------------------------------------------------------------------
   117     98   |   The size of the hash table.  For best results this should
   118     99   |   be a prime number which is about the same size as the number of
   119    100   |   character entity references known to the system.
   120    101   |
   121    102   \---------------------------------------------------------------------------*/
   122         -#if TclOnly8Bits
   123         -#define ER_HASH_SIZE 107
   124         -#else
   125    103   #define ER_HASH_SIZE 257
   126         -#endif
   127    104   
   128    105   /*----------------------------------------------------------------------------
   129    106   |   The following flag is TRUE if entity reference hash table needs
   130    107   |   to be initialized.
   131    108   |
   132    109   \---------------------------------------------------------------------------*/
   133    110   static int bErNeedsInit = 1;
................................................................................
   180    157   \---------------------------------------------------------------------------*/
   181    158   static Er er_sequences[] = {
   182    159       { "amp",       "&",        0 },
   183    160       { "lt",        "<",        0 },
   184    161       { "gt",        ">",        0 },
   185    162       { "apos",      "'",        0 },
   186    163       { "quot",      "\"",       0 },
   187         -#if TclOnly8Bits
   188         -    { "nbsp",      "\240",     0 },
   189         -    { "iexcl",     "\241",     0 }, /* inverted exclamation mark  */
   190         -    { "cent",      "\242",     0 }, /* cent sign  */
   191         -    { "pound",     "\243",     0 }, /* pound sterling sign  */
   192         -    { "curren",    "\244",     0 }, /* general currency sign  */
   193         -    { "yen",       "\245",     0 }, /* yen sign  */
   194         -    { "brvbar",    "\246",     0 }, /* broken (vertical) bar  */
   195         -    { "sect",      "\247",     0 }, /* section sign  */
   196         -    { "uml",       "\250",     0 }, /* umlaut (dieresis)  */
   197         -    { "copy",      "\251",     0 }, /* copyright sign  */
   198         -    { "ordf",      "\252",     0 }, /* ordinal indicator, feminine  */
   199         -    { "laquo",     "\253",     0 }, /* angle quotation mark, left  */
   200         -    { "not",       "\254",     0 }, /* not sign  */
   201         -    { "shy",       "\255",     0 }, /* soft hyphen  */
   202         -    { "reg",       "\256",     0 }, /* registered sign  */
   203         -    { "macr",      "\257",     0 }, /* macron  */
   204         -    { "deg",       "\260",     0 }, /* degree sign  */
   205         -    { "plusmn",    "\261",     0 }, /* plus-or-minus sign  */
   206         -    { "sup2",      "\262",     0 }, /* superscript two  */
   207         -    { "sup3",      "\263",     0 }, /* superscript three  */
   208         -    { "acute",     "\264",     0 }, /* acute accent  */
   209         -    { "micro",     "\265",     0 }, /* micro sign  */
   210         -    { "para",      "\266",     0 }, /* pilcrow (paragraph sign)  */
   211         -    { "middot",    "\267",     0 }, /* middle dot  */
   212         -    { "cedil",     "\270",     0 }, /* cedilla  */
   213         -    { "sup1",      "\271",     0 }, /* superscript one  */
   214         -    { "ordm",      "\272",     0 }, /* ordinal indicator, masculine  */
   215         -    { "raquo",     "\273",     0 }, /* angle quotation mark, right  */
   216         -    { "frac14",    "\274",     0 }, /* fraction one-quarter  */
   217         -    { "frac12",    "\275",     0 }, /* fraction one-half  */
   218         -    { "frac34",    "\276",     0 }, /* fraction three-quarters  */
   219         -    { "iquest",    "\277",     0 }, /* inverted question mark  */
   220         -    { "Agrave",    "\300",     0 }, /* capital A, grave accent  */
   221         -    { "Aacute",    "\301",     0 }, /* capital A, acute accent  */
   222         -    { "Acirc",     "\302",     0 }, /* capital A, circumflex accent  */
   223         -    { "Atilde",    "\303",     0 }, /* capital A, tilde  */
   224         -    { "Auml",      "\304",     0 }, /* capital A, dieresis or umlaut mark  */
   225         -    { "Aring",     "\305",     0 }, /* capital A, ring  */
   226         -    { "AElig",     "\306",     0 }, /* capital AE diphthong (ligature)  */
   227         -    { "Ccedil",    "\307",     0 }, /* capital C, cedilla  */
   228         -    { "Egrave",    "\310",     0 }, /* capital E, grave accent  */
   229         -    { "Eacute",    "\311",     0 }, /* capital E, acute accent  */
   230         -    { "Ecirc",     "\312",     0 }, /* capital E, circumflex accent  */
   231         -    { "Euml",      "\313",     0 }, /* capital E, dieresis or umlaut mark  */
   232         -    { "Igrave",    "\314",     0 }, /* capital I, grave accent  */
   233         -    { "Iacute",    "\315",     0 }, /* capital I, acute accent  */
   234         -    { "Icirc",     "\316",     0 }, /* capital I, circumflex accent  */
   235         -    { "Iuml",      "\317",     0 }, /* capital I, dieresis or umlaut mark  */
   236         -    { "ETH",       "\320",     0 }, /* capital Eth, Icelandic  */
   237         -    { "Ntilde",    "\321",     0 }, /* capital N, tilde  */
   238         -    { "Ograve",    "\322",     0 }, /* capital O, grave accent  */
   239         -    { "Oacute",    "\323",     0 }, /* capital O, acute accent  */
   240         -    { "Ocirc",     "\324",     0 }, /* capital O, circumflex accent  */
   241         -    { "Otilde",    "\325",     0 }, /* capital O, tilde  */
   242         -    { "Ouml",      "\326",     0 }, /* capital O, dieresis or umlaut mark  */
   243         -    { "times",     "\327",     0 }, /* multiply sign  */
   244         -    { "Oslash",    "\330",     0 }, /* capital O, slash  */
   245         -    { "Ugrave",    "\331",     0 }, /* capital U, grave accent  */
   246         -    { "Uacute",    "\332",     0 }, /* capital U, acute accent  */
   247         -    { "Ucirc",     "\333",     0 }, /* capital U, circumflex accent  */
   248         -    { "Uuml",      "\334",     0 }, /* capital U, dieresis or umlaut mark  */
   249         -    { "Yacute",    "\335",     0 }, /* capital Y, acute accent  */
   250         -    { "THORN",     "\336",     0 }, /* capital THORN, Icelandic  */
   251         -    { "szlig",     "\337",     0 }, /* small sharp s, German (sz ligature)  */
   252         -    { "agrave",    "\340",     0 }, /* small a, grave accent  */
   253         -    { "aacute",    "\341",     0 }, /* small a, acute accent  */
   254         -    { "acirc",     "\342",     0 }, /* small a, circumflex accent  */
   255         -    { "atilde",    "\343",     0 }, /* small a, tilde  */
   256         -    { "auml",      "\344",     0 }, /* small a, dieresis or umlaut mark  */
   257         -    { "aring",     "\345",     0 }, /* small a, ring  */
   258         -    { "aelig",     "\346",     0 }, /* small ae diphthong (ligature)  */
   259         -    { "ccedil",    "\347",     0 }, /* small c, cedilla  */
   260         -    { "egrave",    "\350",     0 }, /* small e, grave accent  */
   261         -    { "eacute",    "\351",     0 }, /* small e, acute accent  */
   262         -    { "ecirc",     "\352",     0 }, /* small e, circumflex accent  */
   263         -    { "euml",      "\353",     0 }, /* small e, dieresis or umlaut mark  */
   264         -    { "igrave",    "\354",     0 }, /* small i, grave accent  */
   265         -    { "iacute",    "\355",     0 }, /* small i, acute accent  */
   266         -    { "icirc",     "\356",     0 }, /* small i, circumflex accent  */
   267         -    { "iuml",      "\357",     0 }, /* small i, dieresis or umlaut mark  */
   268         -    { "eth",       "\360",     0 }, /* small eth, Icelandic  */
   269         -    { "ntilde",    "\361",     0 }, /* small n, tilde  */
   270         -    { "ograve",    "\362",     0 }, /* small o, grave accent  */
   271         -    { "oacute",    "\363",     0 }, /* small o, acute accent  */
   272         -    { "ocirc",     "\364",     0 }, /* small o, circumflex accent  */
   273         -    { "otilde",    "\365",     0 }, /* small o, tilde  */
   274         -    { "ouml",      "\366",     0 }, /* small o, dieresis or umlaut mark  */
   275         -    { "divide",    "\367",     0 }, /* divide sign  */
   276         -    { "oslash",    "\370",     0 }, /* small o, slash  */
   277         -    { "ugrave",    "\371",     0 }, /* small u, grave accent  */
   278         -    { "uacute",    "\372",     0 }, /* small u, acute accent  */
   279         -    { "ucirc",     "\373",     0 }, /* small u, circumflex accent  */
   280         -    { "uuml",      "\374",     0 }, /* small u, dieresis or umlaut mark  */
   281         -    { "yacute",    "\375",     0 }, /* small y, acute accent  */
   282         -    { "thorn",     "\376",     0 }, /* small thorn, Icelandic  */
   283         -    { "yuml",      "\377",     0 }, /* small y, dieresis or umlaut mark  */
   284         -#else
   285    164       { "nbsp",      "\xC2\xA0",    0 },
   286    165       { "iexcl",     "\xC2\xA1",    0 },
   287    166       { "cent",      "\xC2\xA2",    0 },
   288    167       { "pound",     "\xC2\xA3",    0 },
   289    168       { "curren",    "\xC2\xA4",    0 },
   290    169       { "yen",       "\xC2\xA5",    0 },
   291    170       { "brvbar",    "\xC2\xA6",    0 },
................................................................................
   528    407       { "lang",      "\xE2\x8C\xA9",    0 },
   529    408       { "rang",      "\xE2\x8C\xAA",    0 },
   530    409       { "loz",       "\xE2\x97\x8A",    0 },
   531    410       { "spades",    "\xE2\x99\xA0",    0 },
   532    411       { "clubs",     "\xE2\x99\xA3",    0 },
   533    412       { "hearts",    "\xE2\x99\xA5",    0 },
   534    413       { "diams",     "\xE2\x99\xA6",    0 },
   535         -#endif
   536    414   };
   537    415   
   538    416   
   539    417   /*----------------------------------------------------------------------------
   540    418   |   ErInit --
   541    419   |
   542    420   |       Initialize the entity reference hash table
................................................................................
   591    469               bErNeedsInit = 0;
   592    470           }
   593    471           TDomThreaded(Tcl_MutexUnlock(&initMutex);)
   594    472       }
   595    473   
   596    474       while (z[from]) {
   597    475           if (z[from]=='&') {
          476  +            int isInvalid = 0;
   598    477               int i = from+1;
   599    478               int c;
   600    479   
   601    480               if (z[i] == '#') {
   602    481                   /*---------------------------------------------
   603    482                   |   convert character reference
   604    483                   \--------------------------------------------*/
................................................................................
   613    492                           if ((c>='A') && (c<='F')) {
   614    493                               value += c-'A' + 10;
   615    494                           } else
   616    495                           if ((c>='a') && (c<='f')) {
   617    496                               value += c-'a' + 10;
   618    497                           } else {
   619    498                               /* error */
          499  +			    isInvalid = 1;
          500  +			    break;
          501  +                        }
          502  +                        if (value > 2097152) {
          503  +                            /* error */
          504  +			    isInvalid = 1;
          505  +			    break;
   620    506                           }
   621    507                           i++;
   622    508                       }
   623    509                   } else {
   624    510                       while ((c=z[i]) && (c!=';')) {
   625    511                           value = value * 10;
   626    512                           if ((c>='0') && (c<='9')) {
   627    513                               value += c-'0';
   628    514                           } else {
   629    515                               /* error */
          516  +  			    isInvalid = 1;
          517  +			    break;
          518  +                        }
          519  +                        if (value > 2097152) {
          520  +                            /* error */
          521  +			    isInvalid = 1;
          522  +			    break;
   630    523                           }
   631    524                           i++;
   632    525                       }
   633    526                   }
   634    527                   if (z[i]!=';') {
   635    528                       /* error */
          529  +		    isInvalid = 1;
   636    530                   }
   637         -                from = i+1;
   638         -#if TclOnly8Bits
   639         -                z[to++] = value;
   640         -#else 
          531  +		if (isInvalid) {
          532  +		    /*
          533  +		     * In case the character reference was invalid
          534  +		     * it was a false alaram, no valid character
          535  +		     * reference, just copy the source chars;
          536  +		     */
          537  +		    int j;
          538  +		    for (j = from; j < i; j++) {
          539  +		        z[to++] = z[j];
          540  +		    }
          541  +		    from = i;
          542  +		} else {
   641    543                   if (value < 0x80) {
   642    544                       z[to++] = value;
   643    545                   } else if (value <= 0x7FF) {
   644    546                       z[to++] = (char) ((value >> 6) | 0xC0);
   645    547                       z[to++] = (char) ((value | 0x80) & 0xBF);
   646    548                   } else if (value <= 0xFFFF) {
   647    549                       z[to++] = (char) ((value >> 12) | 0xE0);
   648    550                       z[to++] = (char) (((value >> 6) | 0x80) & 0xBF);
   649    551                       z[to++] = (char) ((value | 0x80) & 0xBF);
   650    552                   } else {
   651    553                       /* error */
   652    554                   }
   653         -#endif
          555  +		    from = i+1;
          556  +		}
   654    557               } else {
   655    558                   while (z[i] && isalpha((unsigned char)z[i])) {
   656    559                      i++;
   657    560                   }
   658    561                   c = z[i];
   659    562                   z[i] = 0;
   660    563                   h = ErHash(&z[from+1]);
................................................................................
   759    662                   /*--------------------------------------------------------
   760    663                   |   allocate new TEXT node
   761    664                   \-------------------------------------------------------*/
   762    665                   tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
   763    666                   memset(tnode, 0, sizeof(domTextNode));
   764    667                   tnode->nodeType    = TEXT_NODE;
   765    668                   tnode->nodeFlags   = 0;
   766         -                tnode->namespace   = 0;
   767    669                   tnode->ownerDocument = doc;
   768    670                   tnode->nodeNumber  = NODE_NO(doc);
   769    671                   tnode->valueLength = (x - start);
   770    672                   tnode->nodeValue   = (char*)MALLOC((x - start)+1);
   771    673                   memmove(tnode->nodeValue, start, (x - start));
   772    674                   *(tnode->nodeValue + (x - start)) = 0;
   773    675                   DBG(fprintf(stderr, "New text node: '%s'\n", tnode->nodeValue);)
................................................................................
   837    739                   pnode = parent_node;
   838    740                   while (pnode != NULL) {
   839    741                       DBG(fprintf(stderr, "checking '%s' to top hierarchy: '%s' \n", start+2,pnode->nodeName);)
   840    742                       if (!strcmp(start+2,pnode->nodeName)) break;
   841    743                       pnode = pnode->parentNode;
   842    744                   }
   843    745                   if (pnode == NULL) {
   844         -                    /* begining tag was not found the way up the tag hierarchy
          746  +                    /* beginning tag was not found the way up the tag hierarchy
   845    747                          -> ignore the tag */
   846    748                       DBG(fprintf(stderr,"ignoring closing '%s' \n", start+2);)
   847    749                       ignore = 1;
   848    750                   }
   849    751               }            
   850    752               if (!ignore) {
   851    753   
................................................................................
   872    774   
   873    775   
   874    776                           /*---------------------------------------------------------------
   875    777                           |   check for tags for which end tag can be omitted
   876    778                           \--------------------------------------------------------------*/
   877    779                           autoclose = 0;
   878    780                           switch (pn[0]) {
   879         -                            case 'a': if (!strcmp(pn,"a"))        autoclose = 1; break;
   880         -                            case 'b': if (!strcmp(pn,"b"))        autoclose = 1; break;
   881         -                            case 'c': if (!strcmp(pn,"colgroup")) autoclose = 1; break;
   882         -                            case 'd': if (!strcmp(pn,"dd") ||
   883         -                                          !strcmp(pn,"dt") ||
   884         -                                          (!strcmp(start+2,"form") && !strcmp(pn,"div"))
   885         -                                         )                        autoclose = 1; break;
   886         -                            case 'h': if (!strcmp(pn,"head") ||
   887         -                                          !strcmp(pn,"html"))     autoclose = 1; break;
   888         -                            case 'f': if (!strcmp(pn,"font")||
   889         -                                          !strcmp(pn,"form"))     autoclose = 1; break;
   890         -                            case 'i': if (!strcmp(pn,"i"))        autoclose = 1; break;
   891         -                            case 'l': if (!strcmp(pn,"li"))       autoclose = 1; break;
   892         -                            case 'n': if (!strcmp(pn,"noscript")) autoclose = 1; break;
   893         -                            case 'o': if (!strcmp(pn,"option"))   autoclose = 1; break;
   894         -                            case 'p': if (!strcmp(pn,"p"))        autoclose = 1; break;
   895         -                            case 's': if (!strcmp(pn,"span"))     autoclose = 1; break;
   896         -                            case 't': if (!strcmp(pn,"tbody") ||
   897         -                                          !strcmp(pn,"td")    ||
   898         -                                          !strcmp(pn,"tfoot") ||
   899         -                                          !strcmp(pn,"thead") ||
   900         -                                          !strcmp(pn,"th")    ||
   901         -                                          !strcmp(pn,"tr")    ||
   902         -                                          !strcmp(pn,"tt"))       autoclose = 1; break;
   903         -                            case 'u': if (!strcmp(pn,"ul"))       autoclose = 1; break; /* ext */
          781  +                        case 'a': if (!strcmp(pn,"a"))        {autoclose = 1;} break;
          782  +                        case 'b': if (!strcmp(pn,"b"))        {autoclose = 1;} break;
          783  +                        case 'c': if (!strcmp(pn,"colgroup")) {autoclose = 1;} break;
          784  +                        case 'd': if (!strcmp(pn,"dd") ||
          785  +                                      !strcmp(pn,"dt") ||
          786  +                                      (!strcmp(start+2,"form") && !strcmp(pn,"div"))
          787  +                            )                        {autoclose = 1;}          break;
          788  +                        case 'h': if (!strcmp(pn,"head") ||
          789  +                                      !strcmp(pn,"html"))     {autoclose = 1;} break;
          790  +                        case 'f': if (!strcmp(pn,"font")||
          791  +                                      !strcmp(pn,"form"))     {autoclose = 1;} break;
          792  +                        case 'i': if (!strcmp(pn,"i"))        {autoclose = 1;} break;
          793  +                        case 'l': if (!strcmp(pn,"li"))       {autoclose = 1;} break;
          794  +                        case 'n': if (!strcmp(pn,"noscript")) {autoclose = 1;} break;
          795  +                        case 'o': if (!strcmp(pn,"option"))   {autoclose = 1;} break;
          796  +                        case 'p': if (!strcmp(pn,"p"))        {autoclose = 1;} break;
          797  +                        case 's': if (!strcmp(pn,"span"))     {autoclose = 1;} break;
          798  +                        case 't': if (!strcmp(pn,"tbody") ||
          799  +                                      !strcmp(pn,"td")    ||
          800  +                                      !strcmp(pn,"tfoot") ||
          801  +                                      !strcmp(pn,"thead") ||
          802  +                                      !strcmp(pn,"th")    ||
          803  +                                      !strcmp(pn,"tr")    ||
          804  +                                      !strcmp(pn,"tt"))       {autoclose = 1;} break;
          805  +                        case 'u': if (!strcmp(pn,"ul"))       {autoclose = 1;} break; /* ext */
   904    806                           }
   905    807                           /*---------------------------------------------------------------
   906    808                           |   check for tags for close inner tags
   907    809                           \--------------------------------------------------------------*/
   908    810                           switch (start[2]) {
   909    811                               case 'b': if (!strcmp(start+2,"body")) autoclose = 1; break;
   910    812                           }
................................................................................
   967    869                           /*----------------------------------------------------
   968    870                           |   allocate new COMMENT node for comments
   969    871                           \---------------------------------------------------*/
   970    872                           tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
   971    873                           memset(tnode, 0, sizeof(domTextNode));
   972    874                           tnode->nodeType      = COMMENT_NODE;
   973    875                           tnode->nodeFlags     = 0;
   974         -                        tnode->namespace     = 0;
   975    876                           tnode->ownerDocument = doc;
   976    877                           tnode->nodeNumber    = NODE_NO(doc);
   977    878                           tnode->parentNode    = parent_node;
   978    879                           tnode->valueLength   = x - start - 4;
   979    880                           tnode->nodeValue     = (char*)MALLOC(tnode->valueLength+1);
   980    881                           memmove(tnode->nodeValue, start+4, tnode->valueLength);
   981    882                           *(tnode->nodeValue + tnode->valueLength) = 0;
................................................................................
  1047    948                               /*----------------------------------------------------
  1048    949                               |   allocate new TEXT node for CDATA section data
  1049    950                               \---------------------------------------------------*/
  1050    951                               tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
  1051    952                               memset(tnode, 0, sizeof(domTextNode));
  1052    953                               tnode->nodeType      = TEXT_NODE;
  1053    954                               tnode->nodeFlags     = 0;
  1054         -                            tnode->namespace     = 0;
  1055    955                               tnode->ownerDocument = doc;
  1056    956                               tnode->nodeNumber    = NODE_NO(doc);
  1057    957                               tnode->parentNode    = parent_node;
  1058    958                               tnode->valueLength   = (x - start);
  1059    959                               tnode->nodeValue     = (char*)MALLOC((x - start)+1);
  1060    960                               memmove(tnode->nodeValue, start, (x - start));
  1061    961                               *(tnode->nodeValue + (x - start)) = 0;
................................................................................
  1327   1227                       h = Tcl_CreateHashEntry (doc->ids, attrnode->nodeValue,
  1328   1228                                                &hnew);
  1329   1229                       /* How to resolve in case of dublicates?  We
  1330   1230                          follow, what the core dom building code does:
  1331   1231                          the first value in document order wins. */
  1332   1232                       if (hnew) {
  1333   1233                           Tcl_SetHashValue (h, node);
         1234  +                        attrnode->nodeFlags |= IS_ID_ATTRIBUTE;
  1334   1235                       }
  1335   1236                   }
  1336   1237                   if (node->firstAttr) {
  1337   1238                       lastAttr->nextSibling = attrnode;
  1338   1239                   } else {
  1339   1240                       node->firstAttr = attrnode;
  1340   1241                   }
................................................................................
  1347   1248                   }
  1348   1249               }
  1349   1250   
  1350   1251               /*-----------------------------------------------------------
  1351   1252               |   check for empty HTML tags
  1352   1253               \----------------------------------------------------------*/
  1353   1254               switch (node->nodeName[0]) {
  1354         -                case 'a':  if (!strcmp(node->nodeName,"area"))     hasContent = 0; break;
  1355         -                case 'b':  if (!strcmp(node->nodeName,"br")     ||
  1356         -                               !strcmp(node->nodeName,"base")   ||
  1357         -                               !strcmp(node->nodeName,"basefont")) hasContent = 0; break;
  1358         -                case 'c':  if (!strcmp(node->nodeName,"col"))      hasContent = 0; break;
  1359         -                case 'e':  if (!strcmp(node->nodeName,"embed"))    hasContent = 0; break; /*ext*/
  1360         -                case 'f':  if (!strcmp(node->nodeName,"frame"))    hasContent = 0; break;
  1361         -                case 'h':  if (!strcmp(node->nodeName,"hr"))       hasContent = 0; break;
  1362         -                case 'i':  if (!strcmp(node->nodeName,"img")   ||
  1363         -                               !strcmp(node->nodeName,"input") ||
  1364         -                               !strcmp(node->nodeName,"isindex"))  hasContent = 0; break;
  1365         -                case 'l':  if (!strcmp(node->nodeName,"link"))     hasContent = 0; break;
  1366         -                case 'm':  if (!strcmp(node->nodeName,"meta"))     hasContent = 0; break;
  1367         -                case 'p':  if (!strcmp(node->nodeName,"param"))    hasContent = 0; break;
  1368         -                case 's':  if (!strcmp(node->nodeName,"spacer"))   hasContent = 0; break; /*ext*/
         1255  +            case 'a':  if (!strcmp(node->nodeName,"area"))     {hasContent = 0;} break;
         1256  +            case 'b':  if (!strcmp(node->nodeName,"br")     ||
         1257  +                           !strcmp(node->nodeName,"base")   ||
         1258  +                           !strcmp(node->nodeName,"basefont")) {hasContent = 0;} break;
         1259  +            case 'c':  if (!strcmp(node->nodeName,"col"))      {hasContent = 0;} break;
         1260  +            case 'e':  if (!strcmp(node->nodeName,"embed"))    {hasContent = 0;} break;
         1261  +            case 'f':  if (!strcmp(node->nodeName,"frame"))    {hasContent = 0;} break;
         1262  +            case 'h':  if (!strcmp(node->nodeName,"hr"))       {hasContent = 0;} break;
         1263  +            case 'i':  if (!strcmp(node->nodeName,"img")   ||
         1264  +                           !strcmp(node->nodeName,"input") ||
         1265  +                           !strcmp(node->nodeName,"isindex"))  {hasContent = 0;} break;
         1266  +            case 'l':  if (!strcmp(node->nodeName,"link"))     {hasContent = 0;} break;
         1267  +            case 'm':  if (!strcmp(node->nodeName,"meta"))     {hasContent = 0;} break;
         1268  +            case 'p':  if (!strcmp(node->nodeName,"param"))    {hasContent = 0;} break;
         1269  +            case 's':  if (!strcmp(node->nodeName,"spacer") || 
         1270  +                           !strcmp(node->nodeName,"source"))   {hasContent = 0;} break; /*html5*/
  1369   1271               }
  1370   1272   
  1371   1273               if (*x=='/') {
  1372   1274                   hasContent = 0;
  1373   1275                   x++;
  1374   1276                   if (*x!='>') {
  1375   1277                       RetError("Syntax Error",(x - html - 1) );
................................................................................
  1413   1315                       /*----------------------------------------------------
  1414   1316                       |   allocate new TEXT node for style/script data
  1415   1317                       \---------------------------------------------------*/
  1416   1318                       tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
  1417   1319                       memset(tnode, 0, sizeof(domTextNode));
  1418   1320                       tnode->nodeType      = TEXT_NODE;
  1419   1321                       tnode->nodeFlags     = 0;
  1420         -                    tnode->namespace     = 0;
  1421   1322                       tnode->ownerDocument = doc;
  1422   1323                       tnode->nodeNumber    = NODE_NO(doc);
  1423   1324                       tnode->parentNode    = node;
  1424   1325                       tnode->valueLength   = (x - start);
  1425   1326                       tnode->nodeValue     = (char*)MALLOC((x - start)+1);
  1426   1327                       memmove(tnode->nodeValue, start, (x - start));
  1427   1328                       *(tnode->nodeValue + (x - start)) = 0;
................................................................................
  1448   1349           pn = (char*)node->parentNode->nodeName;
  1449   1350           DBG(fprintf(stderr, "final autoclose '%s'? \n", pn);)
  1450   1351           /*---------------------------------------------------------------
  1451   1352           |   check for tags for which end tag can be omitted
  1452   1353           \--------------------------------------------------------------*/
  1453   1354           autoclose = 0;
  1454   1355           switch (pn[0]) {
  1455         -            case 'b': if (!strcmp(pn,"body"))     autoclose = 1; break;
  1456         -            case 'c': if (!strcmp(pn,"colgroup")) autoclose = 1; break;
  1457         -            case 'd': if (!strcmp(pn,"dd") ||
  1458         -                          !strcmp(pn,"dt"))       autoclose = 1; break;
  1459         -            case 'h': if (!strcmp(pn,"head") ||
  1460         -                          !strcmp(pn,"html"))     autoclose = 1; break;
  1461         -            case 'l': if (!strcmp(pn,"li"))       autoclose = 1; break;
  1462         -            case 'o': if (!strcmp(pn,"option"))   autoclose = 1; break;
  1463         -            case 'p': if (!strcmp(pn,"p"))        autoclose = 1; break;
  1464         -            case 't': if (!strcmp(pn,"tbody") ||
  1465         -                          !strcmp(pn,"td")    ||
  1466         -                          !strcmp(pn,"tfoot") ||
  1467         -                          !strcmp(pn,"thead") ||
  1468         -                          !strcmp(pn,"th")    ||
  1469         -                          !strcmp(pn,"tr"))       autoclose = 1; break;
  1470         -            case 'u': if (!strcmp(pn,"ul"))       autoclose = 1; break; /* ext */
         1356  +        case 'b': if (!strcmp(pn,"body"))     {autoclose = 1;} break;
         1357  +        case 'c': if (!strcmp(pn,"colgroup")) {autoclose = 1;} break;
         1358  +        case 'd': if (!strcmp(pn,"dd") ||
         1359  +                      !strcmp(pn,"dt"))       {autoclose = 1;} break;
         1360  +        case 'h': if (!strcmp(pn,"head") ||
         1361  +                      !strcmp(pn,"html"))     {autoclose = 1;} break;
         1362  +        case 'l': if (!strcmp(pn,"li"))       {autoclose = 1;} break;
         1363  +        case 'o': if (!strcmp(pn,"option"))   {autoclose = 1;} break;
         1364  +        case 'p': if (!strcmp(pn,"p"))        {autoclose = 1;} break;
         1365  +        case 't': if (!strcmp(pn,"tbody") ||
         1366  +                      !strcmp(pn,"td")    ||
         1367  +                      !strcmp(pn,"tfoot") ||
         1368  +                      !strcmp(pn,"thead") ||
         1369  +                      !strcmp(pn,"th")    ||
         1370  +                      !strcmp(pn,"tr"))       {autoclose = 1;} break;
         1371  +        case 'u': if (!strcmp(pn,"ul"))       {autoclose = 1;} break; /* ext */
  1471   1372           }
  1472   1373           if (!autoclose) break;
  1473   1374           DBG(fprintf(stderr, "final autoclosed '%s'! \n", pn);)
  1474   1375           node = node->parentNode;
  1475   1376           parent_node = node->parentNode;
  1476   1377       }
  1477   1378       if (parent_node == NULL) {

Added generic/domhtml5.c.

            1  +/*----------------------------------------------------------------------------
            2  +|   Copyright (c) 2017  Rolf Ade (rolf@pointsman.de)
            3  +|-----------------------------------------------------------------------------
            4  +|
            5  +|
            6  +|   The contents of this file are subject to the Mozilla Public License
            7  +|   Version 1.1 (the "License"); you may not use this file except in
            8  +|   compliance with the License. You may obtain a copy of the License at
            9  +|   http://www.mozilla.org/MPL/
           10  +|
           11  +|   Software distributed under the License is distributed on an "AS IS"
           12  +|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
           13  +|   License for the specific language governing rights and limitations
           14  +|   under the License.
           15  +|
           16  +|   Contributor(s):
           17  +|
           18  +|
           19  +|   written by Rolf Ade
           20  +|   March 2017
           21  +|
           22  +\---------------------------------------------------------------------------*/
           23  +
           24  +#ifdef TDOM_HAVE_GUMBO
           25  +
           26  +#define MAX_TAG_LEN 201
           27  +
           28  +/*----------------------------------------------------------------------------
           29  +|   Includes
           30  +|
           31  +\---------------------------------------------------------------------------*/
           32  +#include <tcl.h>
           33  +#include <dom.h>
           34  +#include "gumbo.h"
           35  +#include <assert.h>
           36  +
           37  +static const char *xhtml = "http://www.w3.org/1999/xhtml";
           38  +static const char *svg = "http://www.w3.org/2000/svg";
           39  +static const char *mathml = "http://www.w3.org/1998/Math/MathML";
           40  +static const char *xlink = "http://www.w3.org/1999/xlink";
           41  +
           42  +#ifdef DEBUG
           43  +# define DBG(x) x
           44  +#else
           45  +# define DBG(x) 
           46  +#endif
           47  +
           48  +static void
           49  +convertGumboToDom (
           50  +    domNode *parent,
           51  +    GumboNode *gumboParent,
           52  +    int ignoreWhiteSpaces,
           53  +    int ignorexmlns
           54  +    ) 
           55  +{
           56  +    int i, j, hnew;
           57  +    GumboVector *children = &gumboParent->v.element.children;
           58  +    GumboNode *child;
           59  +    GumboElement *gumboElm;
           60  +    GumboAttribute *gumboAtt;
           61  +    const char *tag;
           62  +    const char *attValue;
           63  +    const char *attUri = NULL;
           64  +    char buf[MAX_TAG_LEN];
           65  +    domNode *node;
           66  +    domNS *ns;
           67  +    domNodeType nodeType = ALL_NODES;
           68  +    domAttrNode *attr = NULL;
           69  +    Tcl_HashEntry *h;
           70  +    const char *elmns = NULL;
           71  +    
           72  +    for (i = 0; i < children->length; ++i) {
           73  +        child = (GumboNode*) (children->data[i]);
           74  +        switch (child->type) {
           75  +        case GUMBO_NODE_DOCUMENT:
           76  +            assert(false &&
           77  +                   "This gumbo node type can't happen here.");
           78  +            break;
           79  +        case GUMBO_NODE_ELEMENT:
           80  +        case GUMBO_NODE_TEMPLATE:
           81  +            gumboElm = &child->v.element;
           82  +            tag = gumbo_normalized_tagname(gumboElm->tag);
           83  +            if (!domIsNAME(tag)) {
           84  +                gumbo_tag_from_original_text(&gumboElm->original_tag);
           85  +                if (gumboElm->original_tag.length < MAX_TAG_LEN - 1) {
           86  +                    strncpy(&buf[0],
           87  +                            gumboElm->original_tag.data,
           88  +                            gumboElm->original_tag.length);
           89  +                    buf[gumboElm->original_tag.length] = '\0';
           90  +                    Tcl_UtfToLower(&buf[0]);
           91  +                    if (!domIsNAME(&buf[0])) {
           92  +                        DBG(fprintf (stderr, "invalid tag name '%s'\n", tag););
           93  +                        continue;
           94  +                    }
           95  +                    tag = &buf[0];
           96  +                } else {
           97  +                    /* Just skip this subtree */
           98  +                    DBG(fprintf(stderr, "long tag: %d bytes\n", gumboElm->original_tag.length););
           99  +                    continue;
          100  +                }
          101  +            }
          102  +            if (!ignorexmlns) {
          103  +                switch (gumboElm->tag_namespace) {
          104  +                case GUMBO_NAMESPACE_HTML:
          105  +                    elmns = xhtml;
          106  +                    break;
          107  +                case GUMBO_NAMESPACE_SVG:
          108  +                    elmns = svg;
          109  +                    break;
          110  +                case GUMBO_NAMESPACE_MATHML:
          111  +                    elmns = mathml;
          112  +                    break;
          113  +                default:
          114  +                    /* do nothing */
          115  +                    break;
          116  +                }
          117  +            }
          118  +            if (elmns == NULL) {
          119  +                node = domNewElementNode (parent->ownerDocument, tag);
          120  +            } else {
          121  +                DBG(fprintf (stderr, "namespaced node %s\n", tag););
          122  +                node = domNewElementNodeNS (parent->ownerDocument, tag,
          123  +                                            elmns);
          124  +            }
          125  +            domAppendChild(parent, node);
          126  +            for (j = 0; j < gumboElm->attributes.length; ++j) {
          127  +                gumboAtt = gumboElm->attributes.data[j];
          128  +                /* This is to ensure the same behavior as the -html
          129  +                 * parser: if there is just the attribute name given
          130  +                 * in the source (as 'selected' on a checkbox) then do
          131  +                 * it the XHTML style (att value is the att name,
          132  +                 * selected="selected"). If there is any value given
          133  +                 * in the source, including the empty string, use
          134  +                 * that. See gumbo.h for the details why/how this
          135  +                 * works.*/
          136  +                if (gumboAtt->original_value.data[0] != '"'
          137  +                    && gumboAtt->original_value.data[0] != '\'') {
          138  +                    attValue = gumboAtt->name;
          139  +                } else {
          140  +                    attValue = gumboAtt->value;
          141  +                }
          142  +
          143  +                if (ignorexmlns) {
          144  +                    if (gumboAtt->attr_namespace != GUMBO_ATTR_NAMESPACE_NONE) {
          145  +                        if (gumboAtt->original_name.length < MAX_TAG_LEN - 1) {
          146  +                            strncpy(&buf[0],
          147  +                                    gumboAtt->original_name.data,
          148  +                                    gumboAtt->original_name.length);
          149  +                            buf[gumboAtt->original_name.length] = '\0';
          150  +                            Tcl_UtfToLower(&buf[0]);
          151  +                            DBG(fprintf (stderr, "original att name: %s\n",
          152  +                                         &buf[0]););
          153  +                            if (!domIsNAME(&buf[0])) {
          154  +                                DBG(fprintf (stderr, "invalid att name '%s'\n", tag););
          155  +                                continue;
          156  +                            }
          157  +                            domSetAttribute(node, &buf[0], attValue);
          158  +                        } else {
          159  +                            continue;
          160  +                        }
          161  +                    } else {
          162  +                        attr = domSetAttribute (node, gumboAtt->name, attValue);
          163  +                    }
          164  +                } else {
          165  +                    attUri = NULL;
          166  +                    switch (gumboAtt->attr_namespace) {
          167  +                    case GUMBO_ATTR_NAMESPACE_XLINK:
          168  +                        DBG(fprintf (stderr, "GUMBO_ATTR_NAMESPACE_XLINK\n"););
          169  +                        attUri = xlink;
          170  +                        break;
          171  +                    case GUMBO_ATTR_NAMESPACE_XMLNS:
          172  +                        DBG(fprintf (stderr, "GUMBO_ATTR_NAMESPACE_XMLNS\n"););
          173  +                        if (attValue[5] == ':') {
          174  +                            ns = domLookupPrefix (node, &(attValue[6]));
          175  +                        } else {
          176  +                            ns = domLookupPrefix (node, "");
          177  +                        }
          178  +                        DBG(fprintf (stderr, "xmns att name: %s\n att value %s\n",
          179  +                                     gumboAtt->name,
          180  +                                     attValue););
          181  +                        if (ns) {
          182  +                            if (strcmp(ns->uri, attValue) == 0) {
          183  +                                /* Namespace already in scope. Skip
          184  +                                 * this attribute to prevent invalid
          185  +                                 * double attributes and unnecessary
          186  +                                 * namespace declarations. */
          187  +                                DBG(fprintf (stderr, "namespace %s already in scope\n",
          188  +                                             attValue););
          189  +                                continue;
          190  +                            }
          191  +                        }
          192  +                        if (gumboAtt->original_name.length < MAX_TAG_LEN - 1) {
          193  +                            strncpy(&buf[0],
          194  +                                    gumboAtt->original_name.data,
          195  +                                    gumboAtt->original_name.length);
          196  +                            buf[gumboAtt->original_name.length] = '\0';
          197  +                            Tcl_UtfToLower(&buf[0]);
          198  +                            DBG(fprintf (stderr, "original att name: %s\n",
          199  +                                         &buf[0]););
          200  +                            if (!domIsNAME(&buf[0])) {
          201  +                                DBG(fprintf (stderr, "invalid att name '%s'\n", tag););
          202  +                                continue;
          203  +                            }
          204  +                            domSetAttributeNS(node, &buf[0], attValue, NULL, 1);
          205  +                        }
          206  +                        continue;
          207  +                    case GUMBO_ATTR_NAMESPACE_XML:
          208  +                        /* The xml namespace is always in scope, nothing
          209  +                         * to do. */
          210  +                        continue;
          211  +                    default:
          212  +                        break;
          213  +                    }
          214  +
          215  +                    if (attUri) {
          216  +                        if (gumboAtt->original_name.length < MAX_TAG_LEN - 1) {
          217  +                            strncpy(&buf[0],
          218  +                                    gumboAtt->original_name.data,
          219  +                                    gumboAtt->original_name.length);
          220  +                            buf[gumboAtt->original_name.length] = '\0';
          221  +                            Tcl_UtfToLower(&buf[0]);
          222  +                            DBG(fprintf (stderr, "original att name: %s\n",
          223  +                                         &buf[0]););
          224  +                            if (!domIsNAME(&buf[0])) {
          225  +                                DBG(fprintf (stderr, "invalid att name '%s'\n", tag););
          226  +                                continue;
          227  +                            }
          228  +                        } else {
          229  +                            continue;
          230  +                        }
          231  +                        DBG(fprintf (stderr, "name: %s value %s\n", &buf[0], attValue););
          232  +                        attr = domSetAttributeNS (node, &buf[0],
          233  +                                                  attValue, xlink, 0);
          234  +                        DBG(fprintf(stderr, "attr: %p\n", attr););
          235  +                    } else {
          236  +                        attr = domSetAttribute (node, gumboAtt->name,
          237  +                                                attValue);
          238  +                    }
          239  +                }
          240  +                if (attr) {
          241  +                    if (strcmp(gumboAtt->name, "id") == 0) {
          242  +                        if (!node->ownerDocument->ids) {
          243  +                            node->ownerDocument->ids = (Tcl_HashTable *)
          244  +                                MALLOC (sizeof (Tcl_HashTable));
          245  +                            Tcl_InitHashTable (
          246  +                                node->ownerDocument->ids,
          247  +                                TCL_STRING_KEYS);
          248  +                        }
          249  +                        h = Tcl_CreateHashEntry (
          250  +                            node->ownerDocument->ids,
          251  +                            gumboAtt->value,
          252  +                            &hnew);
          253  +                        /* How to resolve in case of dublicates?  We
          254  +                           follow, what the core dom building code does:
          255  +                           the first value in document order wins. */
          256  +                        if (hnew) {
          257  +                            Tcl_SetHashValue (h, node);
          258  +                            attr->nodeFlags |= IS_ID_ATTRIBUTE;
          259  +                        }
          260  +                    }
          261  +                }
          262  +            }
          263  +            convertGumboToDom(node, child, ignoreWhiteSpaces, ignorexmlns);
          264  +            break;
          265  +        case GUMBO_NODE_WHITESPACE:
          266  +            if (ignoreWhiteSpaces) {
          267  +                continue;
          268  +            }
          269  +            /* fall thru */;
          270  +        case GUMBO_NODE_CDATA:
          271  +        case GUMBO_NODE_TEXT:
          272  +            nodeType = TEXT_NODE
          273  +            /* fall thru */;
          274  +        case GUMBO_NODE_COMMENT:
          275  +            if (nodeType == ALL_NODES) nodeType = COMMENT_NODE;
          276  +            node = (domNode*)domNewTextNode(parent->ownerDocument,
          277  +                                            child->v.text.text,
          278  +                                            strlen(child->v.text.text),
          279  +                                            nodeType);
          280  +            domAppendChild(parent, node);
          281  +            break;
          282  +        default:
          283  +            assert(false && "unknown node type");
          284  +        }
          285  +    }
          286  +}
          287  +
          288  +domDocument *
          289  +HTML_GumboParseDocument (
          290  +    char   *html,              /* Complete text of the XML being parsed.  */
          291  +    int     ignoreWhiteSpaces,
          292  +    int     ignorexmlns
          293  +    ) {
          294  +    domDocument *doc = domCreateDoc(NULL, 0);
          295  +    GumboOutput *output = gumbo_parse(html);
          296  +    GumboDocument* doctype = & output->document->v.document;
          297  +    /* Generate and populate doctype info. */
          298  +    doc->doctype = (domDocInfo *)MALLOC(sizeof(domDocInfo));
          299  +    memset(doc->doctype, 0,(sizeof(domDocInfo)));
          300  +    doc->doctype->publicId = tdomstrdup(doctype->public_identifier);
          301  +    doc->doctype->systemId = tdomstrdup(doctype->system_identifier);
          302  +    convertGumboToDom (doc->rootNode, output->document, ignoreWhiteSpaces,
          303  +                       ignorexmlns);
          304  +    domSetDocumentElement (doc);
          305  +    gumbo_destroy_output(&kGumboDefaultOptions, output);    
          306  +    return doc;
          307  +}
          308  +#else
          309  +typedef int make_pedantic_compiler_happy;
          310  +#endif

Added generic/domhtml5.h.

            1  +
            2  +domDocument *
            3  +HTML_GumboParseDocument (
            4  +    char   *html,              /* Complete text of the XML being parsed.  */
            5  +    int     ignoreWhiteSpaces,
            6  +    int     ignorexmlns
            7  +    );
            8  +

Added generic/domjson.c.

            1  +/*----------------------------------------------------------------------------
            2  +|   Copyright (c) 2017  Rolf Ade (rolf@pointsman.de)
            3  +|-----------------------------------------------------------------------------
            4  +|
            5  +|
            6  +|   The contents of this file are subject to the Mozilla Public License
            7  +|   Version 1.1 (the "License"); you may not use this file except in
            8  +|   compliance with the License. You may obtain a copy of the License at
            9  +|   http://www.mozilla.org/MPL/
           10  +|
           11  +|   Software distributed under the License is distributed on an "AS IS"
           12  +|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
           13  +|   License for the specific language governing rights and limitations
           14  +|   under the License.
           15  +|
           16  +|   Contributor(s):
           17  +|
           18  +|
           19  +|   written by Rolf Ade
           20  +|   April 2017
           21  +|
           22  +\---------------------------------------------------------------------------*/
           23  +
           24  +/* Some parts of the following are inspired, derivated or, for a few
           25  + * smaller pieces, even verbatim copied from the (public domain)
           26  + * sqlite JSON parser
           27  + * (https://www.sqlite.org/src/artifact/312b4ddf4c7399dc) */
           28  +
           29  +#include <dom.h>
           30  +#include <domjson.h>
           31  +#include <ctype.h>
           32  +
           33  +static const char jsonIsSpace[] = {
           34  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 0, 1, 0, 0,
           35  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           36  +  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           37  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           38  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           39  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           40  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           41  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           42  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           43  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           44  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           45  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           46  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           47  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           48  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           49  +  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
           50  +};
           51  +#define skipspace(x)  while (jsonIsSpace[(unsigned char)json[(x)]]) { (x)++; }
           52  +
           53  +#define rc(i) if (jparse->state != JSON_OK) return (i);
           54  +
           55  +/* The meaning of parse state values */
           56  +typedef enum {
           57  +    JSON_OK,
           58  +    JSON_MAX_NESTING_REACHED,
           59  +    JSON_SYNTAX_ERR,
           60  +} JSONParseState;
           61  +
           62  +/* Error string constants, indexed by JSONParseState. */
           63  +static const char *JSONParseStateStr[] = {
           64  +    "OK",
           65  +    "Maximum JSON object/array nesting depth exceeded",
           66  +    "JSON syntax error",
           67  +};
           68  +
           69  +typedef struct {
           70  +    JSONParseState state;
           71  +    JSONWithin within;
           72  +    int  nestingDepth;
           73  +    int  maxnesting;
           74  +    char *arrItemElm;
           75  +    char *buf;
           76  +    int len;
           77  +} JSONParse;
           78  +
           79  +
           80  +#define errReturn(i,j) {jparse->state = j; return (i);}
           81  +    
           82  +
           83  +/* #define DEBUG */
           84  +#ifdef DEBUG
           85  +# define DBG(x) x
           86  +#else
           87  +# define DBG(x) 
           88  +#endif
           89  +
           90  +/*
           91  +** Return true if z[] begins with 4 (or more) hexadecimal digits
           92  +*/
           93  +static int jsonIs4Hex(const char *z){
           94  +  int i;
           95  +  for (i=0; i<4; i++) if (!isxdigit(z[i])) return 0;
           96  +  return 1;
           97  +}
           98  +
           99  +/* Parse the single JSON string which begins (with the starting '"')
          100  + * at json[i]. Return the index of the closing '"' of the string
          101  + * parsed. */
          102  +
          103  +static int jsonParseString (
          104  +    char *json,
          105  +    int   i,
          106  +    JSONParse *jparse
          107  +    )
          108  +{
          109  +    unsigned char c;
          110  +    int clen, j, k, savedStart;
          111  +    unsigned int u;
          112  +    
          113  +    DBG(fprintf(stderr, "jsonParseString start: '%s'\n", &json[i]););
          114  +    if (jparse->len) jparse->buf[0] = '\0';
          115  +    savedStart = i;
          116  +
          117  +    if (json[i] != '"') {
          118  +        errReturn(i,JSON_SYNTAX_ERR);
          119  +    }
          120  +    i++;
          121  +    if (json[i] == '"') {
          122  +        return i;
          123  +    }
          124  +    for(;;) {
          125  +        c = json[i];
          126  +        DBG(fprintf (stderr, "Looking at '%d'\n", c););
          127  +        /* Unescaped control characters are not allowed in JSON
          128  +         * strings. */
          129  +        if (c <= 0x1f) {
          130  +            errReturn(i,JSON_SYNTAX_ERR);
          131  +        }
          132  +        if (c == '\\') {
          133  +            goto unescape;
          134  +        }
          135  +        if (c == '"') {
          136  +            return i;
          137  +        }
          138  +        if (c == 0xC0 && (unsigned char)json[i+1] == 0x80)
          139  +            errReturn(i,JSON_SYNTAX_ERR);
          140  +        if ((clen = UTF8_CHAR_LEN(c)) == 0)
          141  +            errReturn(i,JSON_SYNTAX_ERR);
          142  +        i += clen;
          143  +    }
          144  +    unescape:
          145  +    DBG(fprintf (stderr, "Continue with unescaping ..\n"););
          146  +    /* If we here, then i points to the first backslash in the string
          147  +     * to parse */
          148  +    if (i - savedStart > jparse->len - 200) {
          149  +        jparse->buf = REALLOC(jparse->buf, i-savedStart+200);
          150  +        jparse->len = i-savedStart+200;
          151  +    }
          152  +    memcpy (jparse->buf, &json[savedStart+1], i-savedStart);
          153  +    j = i-savedStart-1;
          154  +    for(;;) {
          155  +        c = json[i];
          156  +        DBG(fprintf (stderr, "Looking at '%c'\n", c););
          157  +        /* Unescaped control characters are not allowed in JSON
          158  +         * strings. */
          159  +        if (c <= 0x1f) errReturn(i,JSON_SYNTAX_ERR);
          160  +        if (jparse->len - j < 8) {
          161  +            jparse->buf = REALLOC (jparse->buf, jparse->len * 2);
          162  +            jparse->len *= 2;
          163  +        }
          164  +        if (c == '\\') {
          165  +            c = json[i+1];
          166  +            if (c == 'u' && jsonIs4Hex(&json[i+2])) {
          167  +                u = 0;
          168  +                for (k = 2; k < 6; k++) {
          169  +                    c = json[i+k];
          170  +                    if (c <= '9') u = u*16 + c - '0';
          171  +                    else if (c <= 'F') u = u*16 + c - 'A' + 10;
          172  +                    else u = u*16 + c - 'a' + 10;
          173  +                }
          174  +                if (u <= 0x7f) {
          175  +                    if (u == 0) {
          176  +                        jparse->buf[j++] = (char)0xC0;
          177  +                        jparse->buf[j++] = (char)0x80;
          178  +                        clen = 2;
          179  +                    } else {
          180  +                        jparse->buf[j++] = (char)u;
          181  +                        clen = 1;
          182  +                    }
          183  +                } else if (u <= 0x7ff) {
          184  +                    jparse->buf[j++] = (char)(0xc0 | (u>>6));
          185  +                    jparse->buf[j++] = 0x80 | (u&0x3f);
          186  +                    clen = 2;
          187  +                } else {
          188  +                    jparse->buf[j++] = (char)(0xe0 | (u>>12));
          189  +                    jparse->buf[j++] = 0x80 | ((u>>6)&0x3f);
          190  +                    jparse->buf[j++] = 0x80 | (u&0x3f);
          191  +                    clen = 3;
          192  +                }
          193  +                i += 6;
          194  +            } else {
          195  +                if (c == '\\') {
          196  +                    c = '\\';
          197  +                } else if (c == '"') {
          198  +                    c = '"';
          199  +                } else if (c == '/') {
          200  +                    c = '/';
          201  +                } else if (c == 'b') {
          202  +                    c = '\b';
          203  +                } else if (c == 'f') {
          204  +                    c = '\f';
          205  +                } else if (c == 'n') {
          206  +                    c = '\n';
          207  +                } else if (c == 'r') {
          208  +                    c = '\r';
          209  +                } else if (c == 't') {
          210  +                    c = '\t';
          211  +                } else {
          212  +                    errReturn(i+1,JSON_SYNTAX_ERR);
          213  +                }
          214  +                jparse->buf[j++] = c;
          215  +                i += 2;
          216  +            }
          217  +            continue;
          218  +        }
          219  +        if (c == '"') {
          220  +            jparse->buf[j] = '\0';
          221  +            return i;
          222  +        }
          223  +        if ((clen = UTF8_CHAR_LEN(json[i])) == 0)
          224  +            errReturn(i,JSON_SYNTAX_ERR);
          225  +        for (k = 0; k < clen; k++) {
          226  +            jparse->buf[j++] = json[i+k];
          227  +        }
          228  +        i += clen;
          229  +    }
          230  +}
          231  +
          232  +/* Parse a single JSON value which begins at json[i]. Return the index
          233  + * of the first character past the end of the value parsed. */
          234  +
          235  +static int jsonParseValue(
          236  +    domNode   *parent,
          237  +    char      *json,
          238  +    int        i,
          239  +    JSONParse *jparse
          240  +    )
          241  +{
          242  +    char c, save;
          243  +    int j;
          244  +    domNode *node;
          245  +    domTextNode *newTextNode;
          246  +    JSONWithin savedWithin = jparse->within;
          247  +    
          248  +    DBG(fprintf(stderr, "jsonParseValue start: '%s'\n", &json[i]););
          249  +    if (jparse->len) jparse->buf[0] = 0;
          250  +    skipspace(i);
          251  +    if ((c = json[i]) == '{' ) {
          252  +        /* Parse object */
          253  +        if (++jparse->nestingDepth > jparse->maxnesting)
          254  +            errReturn(i,JSON_MAX_NESTING_REACHED);
          255  +        i++;
          256  +        if (jparse->within == JSON_ARRAY) {
          257  +            node = domNewElementNode (parent->ownerDocument,
          258  +                                      JSON_OBJECT_CONTAINER);
          259  +            node->info = JSON_OBJECT;
          260  +            domAppendChild(parent, node);
          261  +            parent = node;
          262  +        } else {
          263  +            parent->info  = JSON_OBJECT;
          264  +        }
          265  +        skipspace(i);
          266  +        if (json[i] == '}') {
          267  +            /* Empty object. */
          268  +            jparse->nestingDepth--;
          269  +            return i+1;
          270  +        }
          271  +        jparse->within = JSON_WITHIN_OBJECT;
          272  +        for (;;) {
          273  +            j = jsonParseString (json, i, jparse);
          274  +            rc(j);
          275  +            if (jparse->len && jparse->buf[0]) {
          276  +                DBG(fprintf(stderr, "New object member '%s'\n", jparse->buf););
          277  +                node = domNewElementNode (parent->ownerDocument,
          278  +                                          jparse->buf);
          279  +                domAppendChild (parent, node);
          280  +                jparse->buf[0] = 0;
          281  +            } else {
          282  +                save = json[j];
          283  +                json[j] = '\0';
          284  +                DBG(fprintf(stderr, "New object member '%s'\n", jparse->buf););
          285  +                DBG(fprintf(stderr, "New object member '%s'\n", &json[i+1]););
          286  +                node = domNewElementNode (parent->ownerDocument, &json[i+1]);
          287  +                domAppendChild (parent, node);
          288  +                json[j] = save;
          289  +            }
          290  +            i = j+1;
          291  +            skipspace(i);
          292  +            if (json[i] != ':') errReturn(i,JSON_SYNTAX_ERR);
          293  +            i++;
          294  +            skipspace(i);
          295  +            j = jsonParseValue (node, json, i, jparse);
          296  +            rc(j);
          297  +            i = j;
          298  +            skipspace(i);
          299  +            if (json[i] == '}') {
          300  +                jparse->nestingDepth--;
          301  +                jparse->within = savedWithin;
          302  +                return i+1;
          303  +            }
          304  +            if (json[i] == ',') {
          305  +                i++; skipspace(i);
          306  +                continue;
          307  +            }
          308  +            errReturn(i,JSON_SYNTAX_ERR);
          309  +        }
          310  +    } else if (c == '[') {
          311  +        /* Parse array */
          312  +        if (++jparse->nestingDepth > jparse->maxnesting)
          313  +            errReturn(i,JSON_MAX_NESTING_REACHED);
          314  +        i++;
          315  +        skipspace(i);
          316  +        parent->info = JSON_ARRAY;
          317  +        if (jparse->within == JSON_WITHIN_ARRAY) {
          318  +            node = domNewElementNode (parent->ownerDocument,
          319  +                                      JSON_ARRAY_CONTAINER);
          320  +            node->info = JSON_ARRAY;
          321  +            domAppendChild(parent, node);
          322  +        } else {
          323  +            node = parent;
          324  +        }
          325  +        if (json[i] == ']') {
          326  +            /* empty array */
          327  +            DBG(fprintf(stderr,"Empty JSON array.\n"););
          328  +            jparse->nestingDepth--;
          329  +            return i+1;
          330  +        }
          331  +        jparse->within = JSON_WITHIN_ARRAY;
          332  +        for (;;) {
          333  +            DBG(fprintf(stderr, "Next array value node '%s'\n", &json[i]););
          334  +            skipspace(i);
          335  +            i = jsonParseValue (node, json, i, jparse);
          336  +            rc(i);
          337  +            skipspace(i);
          338  +            if (json[i] == ']') {
          339  +                jparse->within = savedWithin;
          340  +                jparse->nestingDepth--;
          341  +                return i+1;
          342  +            }
          343  +            if (json[i] == ',') {
          344  +                i++;
          345  +                continue;
          346  +            }
          347  +            errReturn(i,JSON_SYNTAX_ERR);
          348  +        }
          349  +    } else if (c == '"') {
          350  +        /* Parse string */
          351  +        j = jsonParseString (json, i, jparse);
          352  +        rc(j);
          353  +        if (jparse->len && jparse->buf[0]) {
          354  +            DBG(fprintf(stderr, "New unescaped text node '%s'\n", jparse->buf));
          355  +            newTextNode = domNewTextNode (parent->ownerDocument,
          356  +                                          jparse->buf, strlen(jparse->buf),
          357  +                                          TEXT_NODE);
          358  +            domAppendChild (parent, (domNode *) newTextNode);
          359  +        } else {
          360  +            DBG(save = json[j];json[j] = '\0';fprintf(stderr, "New text node '%s'\n", &json[i+1]);json[j] = save;);
          361  +            newTextNode = domNewTextNode (parent->ownerDocument,
          362  +                                          &json[i+1], j-i-1, TEXT_NODE);
          363  +            domAppendChild (parent, (domNode *) newTextNode);
          364  +        }
          365  +        newTextNode->info = JSON_STRING;
          366  +        return j+1;
          367  +    } else if (c == 'n'
          368  +               && strncmp (json+i, "null", 4) == 0
          369  +               && !isalnum(json[i+4])) {
          370  +        newTextNode = domNewTextNode (parent->ownerDocument, "null", 4,
          371  +                                      TEXT_NODE);
          372  +        newTextNode->info = JSON_NULL;
          373  +        domAppendChild (parent, (domNode *) newTextNode);
          374  +        return i+4;
          375  +    } else if (c == 't'
          376  +               && strncmp (json+i, "true", 4) == 0
          377  +               && !isalnum(json[i+4])) {
          378  +        newTextNode = domNewTextNode (parent->ownerDocument, "true", 4,
          379  +                                      TEXT_NODE);
          380  +        newTextNode->info = JSON_TRUE;
          381  +        domAppendChild (parent, (domNode *) newTextNode);
          382  +        return i+4;
          383  +    } else if (c == 'f'
          384  +               && strncmp (json+i, "false", 5) == 0
          385  +               && !isalnum(json[i+5])) {
          386  +        newTextNode = domNewTextNode (parent->ownerDocument, "false", 5,
          387  +                                      TEXT_NODE);
          388  +        newTextNode->info = JSON_FALSE;
          389  +        domAppendChild (parent, (domNode *) newTextNode);
          390  +        return i+5;
          391  +    } else if (c == '-' || (c>='0' && c<='9')) {
          392  +        /* Parse number */
          393  +        int seenDP = 0;
          394  +        int seenE = 0;
          395  +        if (c<='0') {
          396  +            j = (c == '-' ? i+1 : i);
          397  +            if (json[j] == '0' && json[j+1] >= '0' && json[j+1] <= '9')
          398  +                errReturn(j+1,JSON_SYNTAX_ERR);
          399  +        }
          400  +        j = i+1;
          401  +        for (;; j++) {
          402  +            c = json[j];
          403  +            if (c >= '0' && c <= '9') continue;
          404  +            if (c == '.') {
          405  +                if (json[j-1] == '-') errReturn(j,JSON_SYNTAX_ERR);
          406  +                if (seenDP) errReturn(j,JSON_SYNTAX_ERR);
          407  +                seenDP = 1;
          408  +                continue;
          409  +            }
          410  +            if (c == 'e' || c == 'E') {
          411  +                if (json[j-1] < '0') errReturn(j,JSON_SYNTAX_ERR);
          412  +                if (seenE) errReturn(j,JSON_SYNTAX_ERR);
          413  +                seenDP = seenE = 1;
          414  +                c = json[j+1];
          415  +                if (c == '+' || c == '-') {
          416  +                    j++;
          417  +                    c = json[j+1];
          418  +                }
          419  +                if (c < '0' || c > '9') errReturn(j,JSON_SYNTAX_ERR);
          420  +                continue;
          421  +            }
          422  +            break;
          423  +        }
          424  +        /* Catches a plain '-' without following digits */
          425  +        if( json[j-1]<'0' ) errReturn(j-1,JSON_SYNTAX_ERR);
          426  +        DBG(save = json[j];json[j] = '\0';fprintf(stderr, "New text node '%s'\n", &json[i]);json[j] = save;);
          427  +        newTextNode = domNewTextNode (parent->ownerDocument, &json[i], j-i,
          428  +                                      TEXT_NODE);
          429  +        newTextNode->info = JSON_NUMBER;
          430  +        domAppendChild(parent, (domNode *) newTextNode);
          431  +        return j;
          432  +    } else if (c == '\0') {
          433  +        return 0;   /* End of input */
          434  +    } else {
          435  +        errReturn(i,JSON_SYNTAX_ERR);
          436  +    }
          437  +}
          438  +
          439  +
          440  +domDocument *
          441  +JSON_Parse (
          442  +    char *json,    /* Complete text of the json string being parsed */
          443  +    char *documentElement, /* name of the root element, may be NULL */
          444  +    int   maxnesting,
          445  +    char **errStr,
          446  +    int  *byteIndex
          447  +    )
          448  +{
          449  +    domDocument *doc = domCreateDoc (NULL, 0);
          450  +    domNode *root;
          451  +    Tcl_HashEntry *h;
          452  +    JSONParse jparse;
          453  +    int hnew, pos = 0;
          454  +
          455  +    h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames), "item", &hnew);
          456  +    jparse.state = JSON_OK;
          457  +    jparse.within = JSON_START;
          458  +    jparse.nestingDepth = 0;
          459  +    jparse.maxnesting = maxnesting;
          460  +    jparse.arrItemElm = (char*)&h->key;
          461  +    jparse.buf = NULL;
          462  +    jparse.len = 0;
          463  +
          464  +    skipspace(pos);
          465  +    if (json[pos] == '\0') {
          466  +        *byteIndex = pos;
          467  +        jparse.state = JSON_SYNTAX_ERR;
          468  +        goto reportError;
          469  +    }
          470  +    if (documentElement) {
          471  +        root = domNewElementNode(doc, documentElement);
          472  +        domAppendChild(doc->rootNode, root);
          473  +    } else {
          474  +        root = doc->rootNode;
          475  +    }
          476  +    *byteIndex = jsonParseValue (root, json, pos, &jparse );
          477  +    if (jparse.state != JSON_OK) goto reportError;
          478  +    if (*byteIndex > 0) {
          479  +        pos = *byteIndex;
          480  +        skipspace(pos);
          481  +    }
          482  +    if (json[pos] != '\0') {
          483  +        *byteIndex = pos;
          484  +        jparse.state = JSON_SYNTAX_ERR;
          485  +        goto reportError;
          486  +    }
          487  +    if (jparse.len > 0) {
          488  +        FREE (jparse.buf);
          489  +    }
          490  +    domSetDocumentElement (doc);
          491  +    return doc;
          492  +reportError:
          493  +    if (jparse.len > 0) {
          494  +        FREE (jparse.buf);
          495  +    }
          496  +    domFreeDocument (doc, NULL, NULL);
          497  +    doc = NULL;
          498  +    *errStr = (char *)JSONParseStateStr[jparse.state];
          499  +    return doc;
          500  +}

Added generic/domjson.h.

            1  +
            2  +#ifndef JSON_MAX_NESTING
            3  +# define JSON_MAX_NESTING 2000
            4  +#endif
            5  +
            6  +#ifndef JSON_OBJECT_CONTAINER
            7  +# define JSON_OBJECT_CONTAINER "objectcontainer"
            8  +#endif
            9  +
           10  +#ifndef JSON_ARRAY_CONTAINER
           11  +# define JSON_ARRAY_CONTAINER "arraycontainer"
           12  +#endif
           13  +
           14  +typedef enum {
           15  +    JSON_START,
           16  +    JSON_WITHIN_ARRAY,
           17  +    JSON_WITHIN_OBJECT
           18  +} JSONWithin;
           19  +
           20  +#define JSON_ARRAY 1
           21  +#define JSON_OBJECT 2
           22  +#define JSON_NULL 3
           23  +#define JSON_TRUE 4
           24  +#define JSON_FALSE 5
           25  +#define JSON_STRING 6
           26  +#define JSON_NUMBER 7
           27  +
           28  +
           29  +domDocument *
           30  +JSON_Parse (
           31  +    char *json,    /* Complete text of the json string being parsed */
           32  +    char *documentElement, /* name of the root element, may be NULL */
           33  +    int   maxnesting,
           34  +    char **errStr,
           35  +    int  *byteIndex
           36  +    );
           37  +

Changes to generic/domxpath.c.

    65     65   #include <stdio.h>
    66     66   #include <stdlib.h>
    67     67   #include <string.h>
    68     68   #include <float.h>
    69     69   #include <math.h>
    70     70   #include <limits.h>
    71     71   #include <ctype.h>
           72  +#include <errno.h>
    72     73   #include <dom.h>
    73     74   #include <domxpath.h>
    74     75   #include <domxslt.h>
    75     76   
    76     77   
    77     78   /*----------------------------------------------------------------------------
    78     79   |   Macros
................................................................................
   173    174   };
   174    175   
   175    176   
   176    177   typedef struct {
   177    178   
   178    179       Token  token;
   179    180       char  *strvalue;
   180         -    int    intvalue;
          181  +    long   intvalue;
   181    182       double realvalue;
   182    183       int    pos;
   183    184   
   184    185   } XPathToken;
   185    186   
   186    187   typedef XPathToken *XPathTokens;
   187    188   
................................................................................
   190    191   |   Types for abstract syntax trees
   191    192   |
   192    193   \---------------------------------------------------------------------------*/
   193    194   static char *astType2str[] = {
   194    195       "Int", "Real", "Mult", "Div", "Mod", "UnaryMinus", "IsNSElement",
   195    196       "IsNode", "IsComment", "IsText", "IsPI", "IsSpecificPI", "IsElement",
   196    197       "IsFQElement", "GetVar", "GetFQVar", "Literal", "ExecFunction", "Pred",
   197         -    "EvalSteps", "SelectRoot", "CombineSets", "Add", "Substract", "Less",
          198  +    "EvalSteps", "SelectRoot", "CombineSets", "Add", "Subtract", "Less",
   198    199       "LessOrEq", "Greater", "GreaterOrEq", "Equal", "NotEqual", "And", "Or",
   199    200       "IsNSAttr", "IsAttr", "AxisAncestor", "AxisAncestorOrSelf",
   200    201       "AxisAttribute", "AxisChild",
   201    202       "AxisDescendant", "AxisDescendantOrSelf", "AxisFollowing",
   202    203       "AxisFollowingSibling", "AxisNamespace", "AxisParent",
   203    204       "AxisPreceding", "AxisPrecedingSilbing", "AxisSelf",
   204    205       "GetContextNode", "GetParentNode", "AxisDescendantOrSelfLit",
................................................................................
   242    243   
   243    244   static int xpathEvalPredicate (ast steps, domNode *exprContext, 
   244    245                                  xpathResultSet *result, 
   245    246                                  xpathResultSet *stepResult,
   246    247                                  xpathCBs *cbs, int *docOrder, char **errMsg);
   247    248   
   248    249   /*----------------------------------------------------------------------------
   249         -|   xpath result set functions
          250  +|   XPath result set functions
   250    251   |
   251    252   \---------------------------------------------------------------------------*/
   252    253   
   253    254   void xpathRSFree ( xpathResultSet *rs ) {
   254    255   
   255    256       if (rs->type == xNodeSetResult) {
   256    257           if (!rs->intvalue) {
................................................................................
   268    269       int i = 0,l;  char tmp[80];
   269    270       switch (rs->type) {
   270    271           case EmptyResult:
   271    272                fprintf(stderr, "empty result \n");
   272    273                break;
   273    274   
   274    275           case BoolResult:
   275         -             fprintf(stderr, "boolean result: %d \n", rs->intvalue);
          276  +             fprintf(stderr, "boolean result: %ld \n", rs->intvalue);
   276    277                break;
   277    278   
   278    279           case IntResult:
   279         -             fprintf(stderr, "int result: %d \n", rs->intvalue);
          280  +             fprintf(stderr, "int result: %ld \n", rs->intvalue);
   280    281                break;
   281    282   
   282    283           case RealResult:
   283    284                fprintf(stderr, "real result: %f \n", rs->realvalue);
   284    285                break;
   285    286   
   286    287           case StringResult:
................................................................................
   289    290                break;
   290    291   
   291    292           case xNodeSetResult:
   292    293                if (!i) fprintf(stderr,"nodeSet result (len %d):\n",rs->nr_nodes);
   293    294                for (i=0; i<rs->nr_nodes; i++) {
   294    295                    if (rs->nodes[i]->nodeType == ELEMENT_NODE) {
   295    296                        fprintf(stderr, "%2d domNode%p %s ",
   296         -                             i, rs->nodes[i], rs->nodes[i]->nodeName);
          297  +                             i, (void *)rs->nodes[i], rs->nodes[i]->nodeName);
   297    298                        if (rs->nodes[i]->firstChild &&
   298    299                            rs->nodes[i]->firstChild->nodeType == TEXT_NODE)
   299    300                        {
   300    301                            l = ((domTextNode*)rs->nodes[i]->firstChild)->valueLength;
   301    302                            if (l > 25) l = 25;
   302    303                            memcpy(tmp, ((domTextNode*)rs->nodes[i]->firstChild)->nodeValue, l);
   303    304                            tmp[l] = '\0';
................................................................................
   307    308                    } else
   308    309                    if (rs->nodes[i]->nodeType == TEXT_NODE) {
   309    310                        l = ((domTextNode*)rs->nodes[i])->valueLength;
   310    311                        if (l > 60) l = 60;
   311    312                        memcpy(tmp, ((domTextNode*)rs->nodes[i])->nodeValue, l);
   312    313                        tmp[l] = '\0';
   313    314                        fprintf(stderr, "%2d domNode%p text:'%s' \n",
   314         -                             i, rs->nodes[i], tmp);
          315  +                             i,  (void *)rs->nodes[i], tmp);
   315    316                    } else
   316    317                    if (rs->nodes[i]->nodeType == COMMENT_NODE) {
   317    318                        l = ((domTextNode*)rs->nodes[i])->valueLength;
   318    319                        memcpy (tmp, "<!--", 4);
   319    320                        if (l > 60) l = 60;
   320    321                        memcpy(&tmp[4], ((domTextNode*)rs->nodes[i])->nodeValue, l);
   321    322                        memcpy(&tmp[4+l], "-->", 3);
   322    323                        tmp[7+l] = '\0';
   323    324                        fprintf(stderr, "%2d domNode%p text:'%s' \n",
   324         -                             i, rs->nodes[i], tmp);
          325  +                             i,  (void *)rs->nodes[i], tmp);
   325    326                    } else
   326    327                    if (rs->nodes[i]->nodeType == ATTRIBUTE_NODE) {
   327    328                        fprintf(stderr, "%2d Attr %s='%*s'\n", i,
   328    329                                ((domAttrNode*)rs->nodes[i])->nodeName,
   329    330                                ((domAttrNode*)rs->nodes[i])->valueLength,
   330    331                                ((domAttrNode*)rs->nodes[i])->nodeValue);
   331    332                    }
................................................................................
   351    352   }
   352    353   void rsSetInf ( xpathResultSet *rs ) {
   353    354       rs->type = InfResult;
   354    355   }
   355    356   void rsSetNInf ( xpathResultSet *rs ) {
   356    357       rs->type = NInfResult;
   357    358   }
   358         -void rsSetInt ( xpathResultSet *rs, int i) {
          359  +void rsSetInt ( xpathResultSet *rs, long i) {
   359    360   
   360    361       rs->type = IntResult;
   361    362       rs->intvalue = i;
   362    363   }
   363         -void rsSetBool ( xpathResultSet *rs, int i) {
          364  +void rsSetBool ( xpathResultSet *rs, long i) {
   364    365   
   365    366       rs->type = BoolResult;
   366    367       rs->intvalue = (i ? 1 : 0);
   367    368   }
   368    369   void rsSetString ( xpathResultSet *rs, const char *s) {
   369    370   
   370    371       rs->type = StringResult;
................................................................................
   531    532           t->child->next = New1(EvalSteps, b);
   532    533       } else {
   533    534           t->child->next = b;
   534    535       }
   535    536       return t;
   536    537   }
   537    538   
   538         -static ast NewInt( int i ) {
          539  +static ast NewInt( long i ) {
   539    540       ast t = NEWCONS;
   540    541   
   541    542       t->type      = Int;
   542    543       t->strvalue  = NULL;
   543    544       t->intvalue  = i;
   544    545       t->realvalue = 0.0;
   545    546   
................................................................................
   606    607       }
   607    608       /*child->next = NULL;*/
   608    609       return m;
   609    610   }
   610    611   static void freeAst (ast t)
   611    612   {
   612    613       ast tmp;
   613         -
   614    614       while (t) {
   615    615           tmp = t->next;
   616    616           if (t->strvalue) FREE(t->strvalue);
   617    617           if (t->child) freeAst (t->child);
   618    618           FREE((char*)t);
   619    619           t = tmp;
   620    620       }
................................................................................
   624    624       int i;
   625    625   
   626    626       while (t) {
   627    627           for (i=0; i<depth; i++) fprintf(stderr, "   ");
   628    628           fprintf(stderr, "%s ", astType2str[t->type]);
   629    629           switch (t->type) {
   630    630   
   631         -            case Int :        fprintf(stderr, "%d", t->intvalue);   break;
          631  +            case Int :        fprintf(stderr, "%ld", t->intvalue);   break;
   632    632               case Real:        fprintf(stderr, "%f", t->realvalue);  break;
   633    633               case IsElement:
   634    634               case IsFQElement:
   635    635               case IsNSAttr:
   636    636               case IsAttr:
   637    637               case ExecFunction:
   638    638               case Literal:
................................................................................
   890    890                              } else {
   891    891                                  *errMsg = tdomstrdup("Expected variable name");
   892    892                                  return tokens;
   893    893                              }
   894    894                          }
   895    895                          break;
   896    896   
          897  +            case '%':  if (!varParseCB) {
          898  +                           *errMsg = tdomstrdup ("Unexpected char '%'");
          899  +                           return tokens;
          900  +                       }
          901  +                       ps = (varParseCB->parseVarCB) (
          902  +                                varParseCB->parseVarClientData, &xpath[i],
          903  +                                &offset, errMsg
          904  +                              );
          905  +                       if (ps) {
          906  +                           token = WCARDNAME;
          907  +                           tokens[l].strvalue = tdomstrdup (ps);
          908  +                           /* We kind of misuse the (in case of
          909  +                            * WCARDNAME token otherwise not used)
          910  +                            * intvalue to mark this WCARDNAME token
          911  +                            * to be meant as literal - this is to
          912  +                            * distinguish between '*' as wildcard and
          913  +                            * as literal element name. */
          914  +                           tokens[l].intvalue = 1;
          915  +                           i += offset - 1;
          916  +                       } else {
          917  +                           return tokens;
          918  +                       }
          919  +                       break;
          920  +                
   897    921               case '.':  if (xpath[i+1] == '.') {
   898    922                              token = DOTDOT;
   899    923                              i++;
   900    924                              break;
   901    925                          } else if (!isdigit((unsigned char)xpath[i+1])) {
   902    926                              token = DOT;
   903    927                              break;
................................................................................
  1075   1099                                  i++;
  1076   1100                                  while (xpath[i] 
  1077   1101                                         && isdigit((unsigned char)xpath[i])) i++;
  1078   1102                              }
  1079   1103                              save = xpath[i];
  1080   1104                              xpath[i] = '\0';
  1081   1105                              if (token == INTNUMBER) {
  1082         -                               tokens[l].intvalue = atoi(ps);
         1106  +                               errno = 0;
         1107  +                               tokens[l].intvalue = strtol(ps, NULL, 10);
         1108  +                               if (errno == ERANGE 
         1109  +                                   && ( tokens[l].intvalue == LONG_MAX 
         1110  +                                        || tokens[l].intvalue == LONG_MIN)) {
         1111  +                                   token = REALNUMBER;
         1112  +                               }
  1083   1113                              }
  1084   1114                              tokens[l].realvalue = (double)atof(ps);
  1085   1115                              xpath[i--] = save;
  1086   1116                          } else {
  1087   1117                              sprintf (tmpErr, "Unexpected character '%c' at "
  1088   1118                                       "position %d", xpath[i], i);
  1089   1119                              *errMsg = tdomstrdup (tmpErr);
................................................................................
  1151   1181       } else
  1152   1182       if (LA==NSWC) {
  1153   1183           Consume (NSWC);
  1154   1184           a = NewStr (IsNSElement, STRVAL);
  1155   1185       } else {
  1156   1186           Consume(WCARDNAME);
  1157   1187           a = NewStr (IsElement, STRVAL);
         1188  +        a->intvalue = INTVAL;
  1158   1189       }
  1159   1190   EndProduction
  1160   1191   
  1161   1192   
  1162   1193   /*-----------------------------------------------------------------
  1163   1194   |   AbbreviatedBasis  production
  1164   1195   |
................................................................................
  1305   1336           Consume(RPAR);
  1306   1337       } else {
  1307   1338           ErrExpected("$var or (expr) or literal or number or func");
  1308   1339       }
  1309   1340       while (LA==LBRACKET) {
  1310   1341           ast b;
  1311   1342           b = Recurse(Predicate);
  1312         -        if (!b) return NULL;
         1343  +        if (!b) return a;
  1313   1344           Append( a, New1WithEvalSteps( Pred, b));
  1314   1345       }
  1315   1346   EndProduction
  1316   1347   
  1317   1348   
  1318   1349   /*-----------------------------------------------------------------
  1319   1350   |   PathExpr  production
................................................................................
  1335   1366               Consume(SLASH);
  1336   1367               Append(a, Recurse(RelativeLocationPath));
  1337   1368   
  1338   1369           } else if (LA==SLASHSLASH) {
  1339   1370               ast b;
  1340   1371               Consume(SLASHSLASH);
  1341   1372               b = Recurse(RelativeLocationPath);
         1373  +            if (!b) return a;
  1342   1374               if (b->type == AxisChild) {
  1343   1375                   b->type = AxisDescendant;
  1344   1376               } else {
  1345   1377                   Append(a, New( AxisDescendantOrSelf ) );
  1346   1378               }
  1347   1379               Append(a, b );
  1348   1380           }
................................................................................
  1437   1469             ||(LA==MINUS)
  1438   1470       ) {
  1439   1471           if (LA==PLUS) {
  1440   1472               Consume(PLUS);
  1441   1473               a = New2( Add, a, Recurse(MultiplicativeExpr));
  1442   1474           } else {
  1443   1475               Consume(MINUS);
  1444         -            a = New2( Substract, a, Recurse(MultiplicativeExpr));
         1476  +            a = New2( Subtract, a, Recurse(MultiplicativeExpr));
  1445   1477           }
  1446   1478       }
  1447   1479   EndProduction
  1448   1480   
  1449   1481   
  1450   1482   /*-----------------------------------------------------------------
  1451   1483   |   RelationalExpr  production
................................................................................
  1572   1604   EndProduction
  1573   1605   
  1574   1606   
  1575   1607   /*-----------------------------------------------------------------
  1576   1608   |   Step  production
  1577   1609   |
  1578   1610   \----------------------------------------------------------------*/
  1579         -static int IsStepPredOptimizable (ast a) {
         1611  +static long IsStepPredOptimizable (ast a) {
  1580   1612       ast b;
  1581         -    int left;
         1613  +    long left;
  1582   1614       
  1583   1615       /* Must be called with a != NULL */
  1584   1616       DBG (
  1585   1617           fprintf (stderr, "IsStepPredOptimizable:\n");
  1586   1618           printAst (0,a);
  1587   1619       )
  1588   1620       switch (a->type) {
................................................................................
  1590   1622       case Less:
  1591   1623       case LessOrEq:
  1592   1624           b = a->child;
  1593   1625           if (!b) return 0;
  1594   1626           if (b->type != ExecFunction 
  1595   1627               || b->intvalue != f_position) return 0;
  1596   1628           b = b->next;
         1629  +        if (!b) return 0;
  1597   1630           if (b->type != Int) return 0;
  1598   1631           if (a->type == Less) return b->intvalue;
  1599   1632           else                 return b->intvalue + 1;
  1600   1633       case Greater:
  1601   1634       case GreaterOrEq:
  1602   1635           b = a->child;
  1603   1636           if (!b) return 0;
  1604   1637           if (b->type != Int) return 0;
  1605   1638           left = b->intvalue;
  1606   1639           b = b->next;
         1640  +        if (!b) return 0;
  1607   1641           if (b->type != ExecFunction 
  1608   1642               || b->intvalue != f_position) return 0;
  1609   1643           if (a->type == Greater) return left;
  1610   1644           else                    return left + 1;
  1611   1645       case Equal:
  1612   1646           b = a->child;
  1613   1647           if (!b) return 0;
  1614   1648           if (b->type == Int
         1649  +            && b->next
  1615   1650               && b->next->type == ExecFunction
  1616   1651               && b->next->intvalue == f_position) return b->intvalue;
  1617   1652           if (b->type == ExecFunction
  1618   1653               && b->intvalue == f_position
         1654  +            && b->next
  1619   1655               && b->next->type == Int) return b->next->intvalue;
  1620   1656           return 0;
  1621   1657       default: return 0;
  1622   1658       }
  1623   1659   }
  1624   1660   
  1625   1661   Production(Step)
................................................................................
  1640   1676           a = Recurse(Basis);
  1641   1677           if (LA==LBRACKET && !a) {
  1642   1678               if (*errMsg == NULL) { ErrExpected("Step"); }
  1643   1679               return NULL;
  1644   1680           }
  1645   1681           while (LA==LBRACKET) {
  1646   1682               b = Recurse (Predicate);
  1647         -            if (!b) return NULL;
         1683  +            if (!b) return a;
  1648   1684               if (isFirst) {
  1649   1685                   a->intvalue = IsStepPredOptimizable (b);
  1650   1686                   DBG (fprintf (stderr, "step type %s, intvalue: %d\n", astType2str[a->type], a->intvalue);)
  1651   1687                       isFirst = 0;
  1652   1688               }
  1653   1689               Append( a, New1WithEvalSteps( Pred, b));
  1654   1690           }
................................................................................
  1668   1704           if (LA==SLASH) {
  1669   1705               Consume(SLASH);
  1670   1706               Append(a, Recurse(Step));
  1671   1707           } else {
  1672   1708               ast b;
  1673   1709               Consume(SLASHSLASH);
  1674   1710               b = Recurse(Step);
         1711  +            if (!b) return a;
  1675   1712               if (b->type == AxisChild) {
  1676   1713                   b->type = AxisDescendant;
  1677   1714               } else {
  1678   1715                   Append(a, New( AxisDescendantOrSelf ) );
  1679   1716               }
  1680   1717               Append(a, b );
  1681   1718           }
................................................................................
  1754   1791           }
  1755   1792           a = a->next;
  1756   1793       }
  1757   1794       return 0;
  1758   1795   }
  1759   1796   
  1760   1797   /* Must be called with a != NULL */
  1761         -static int checkStepPatternPredOptimizability ( ast a , int *max) {
         1798  +static int checkStepPatternPredOptimizability ( ast a , long *max) {
  1762   1799       ast b;
  1763   1800   
  1764   1801       switch (a->type) {
  1765   1802           case Literal:
  1766   1803           case AxisAncestor:
  1767   1804           case AxisAncestorOrSelf:
  1768   1805           case AxisChild:
................................................................................
  1794   1831               return 1;
  1795   1832           case Less:
  1796   1833           case LessOrEq:
  1797   1834               b = a->child;
  1798   1835               if (b
  1799   1836                   && b->type == ExecFunction
  1800   1837                   && b->intvalue == f_position
         1838  +                && b->next
  1801   1839                   && b->next->type == Int) {
  1802   1840                   if (a->type == Less) *max = b->next->intvalue;
  1803   1841                   else *max = b->next->intvalue + 1;
  1804   1842                   return 0;
  1805   1843               }
  1806   1844               if (usesPositionInformation(a->child)) return 0;
  1807   1845               return 1;            
  1808   1846           case Greater:
  1809   1847           case GreaterOrEq:
  1810   1848               b = a->child;
  1811   1849               if (b
  1812   1850                   && b->type == Int 
         1851  +                && b->next
  1813   1852                   && b->next->type == ExecFunction
  1814   1853                   && b->next->intvalue == f_position) {
  1815   1854                   if (a->type == Greater) *max = b->intvalue;
  1816   1855                   else *max = b->intvalue + 1;
  1817   1856                   return 0;
  1818   1857               }
  1819   1858               if (usesPositionInformation(a->child)) return 0;
  1820   1859               return 1;            
  1821   1860           case Equal:
  1822   1861               b = a->child;
  1823   1862               if (b
  1824   1863                   && b->type == Int
         1864  +                && b->next
  1825   1865                   && b->next->type == ExecFunction
  1826   1866                   && b->next->intvalue == f_position) {
  1827   1867                   *max = b->intvalue;
  1828   1868                   return 0;
  1829   1869               }
  1830   1870               if (b
  1831   1871                   && b->type == ExecFunction 
  1832   1872                   && b->intvalue == f_position
         1873  +                && b->next
  1833   1874                   && b->next->type == Int) {
  1834   1875                   *max = b->next->intvalue;
  1835   1876                   return 0;
  1836   1877               }
  1837   1878               if (usesPositionInformation(a->child)) return 0;
  1838   1879               return 1;
  1839   1880           case NotEqual:
................................................................................
  1850   1891           default: 
  1851   1892               return 0;
  1852   1893       }
  1853   1894       return 1;
  1854   1895   }
  1855   1896   
  1856   1897   /* Must be called with a != NULL */
  1857         -static int IsStepPatternPredOptimizable ( ast a, int *max ) {
  1858         -    int f;
         1898  +static long IsStepPatternPredOptimizable ( ast a, long *max ) {
         1899  +    long f;
  1859   1900   
  1860   1901       *max = 0;
  1861   1902       f = checkStepPatternPredOptimizability(a, max);
  1862   1903       DBG(
  1863   1904           if (f) {
  1864   1905               fprintf(stderr, "\nStepPattern Pred is optimizable:\n");
  1865   1906           } else {
................................................................................
  1907   1948       }
  1908   1949       if (!a) {
  1909   1950           if (*errMsg == NULL) { ErrExpected("StepPattern") }; 
  1910   1951           return NULL;
  1911   1952       }
  1912   1953       {
  1913   1954           ast b = NULL, c = NULL, aCopy = NULL;
  1914         -        int stepIsOptimizable = 1, isFirst = 1, max, savedmax;
         1955  +        int stepIsOptimizable = 1, isFirst = 1;
         1956  +        long max, savedmax;
  1915   1957           while (LA==LBRACKET) {
  1916   1958               b = Recurse (Predicate);
  1917         -            if (!b) return NULL;
         1959  +            if (!b) return a;
  1918   1960               if (stepIsOptimizable) {
  1919   1961                   if (!IsStepPatternPredOptimizable(b, &max)) 
  1920   1962                       stepIsOptimizable = 0;
  1921   1963               }
  1922   1964               if (isFirst) {
  1923   1965                   savedmax = max;
  1924   1966                   c = New1WithEvalSteps( Pred, b);
................................................................................
  2141   2183       DBG(
  2142   2184           fprintf(stderr, "xpathParsePostProcess start:\n");
  2143   2185           printAst (0, t);
  2144   2186           )
  2145   2187       while (t) {
  2146   2188           DBG(printAst (4, t);)
  2147   2189           if (t->type == AxisNamespace) {
  2148         -            if (t->child->type == IsElement && t->child->strvalue[0] != '*') {
         2190  +            if (t->child->type == IsElement
         2191  +                && t->child->strvalue[0] != '*'
         2192  +                && t->child->intvalue == 0) {
  2149   2193                   uri = domLookupPrefixWithMappings (exprContext, 
  2150   2194                                                      t->child->strvalue, 
  2151   2195                                                      prefixMappings);
  2152   2196                   if (!uri) {
  2153   2197                       *errMsg = tdomstrdup ("Prefix doesn't resolve");
  2154   2198                       return 0;
  2155   2199                   }
................................................................................
  2236   2280                           varParseCB, errMsg);
  2237   2281       if (*errMsg != NULL) {
  2238   2282           if (tokens != NULL) xpathFreeTokens (tokens);
  2239   2283           return XPATH_LEX_ERR;
  2240   2284       }
  2241   2285       DDBG(
  2242   2286           for (i=0; tokens[i].token != EOS; i++) {
  2243         -            fprintf(stderr, "%3d %-12s %5d %8.3f %5d  %s\n",
         2287  +            fprintf(stderr, "%3d %-12s %5ld %8.3f %5d  %s\n",
  2244   2288                               i,
  2245   2289                               token2str[tokens[i].token-LPAR],
  2246   2290                               tokens[i].intvalue,
  2247   2291                               tokens[i].realvalue,
  2248   2292                               tokens[i].pos,
  2249   2293                               tokens[i].strvalue
  2250   2294               );
................................................................................
  2269   2313           newlen = strlen(xpath);
  2270   2314           *errMsg = (char*)REALLOC(*errMsg, len+newlen+10);
  2271   2315           memmove(*errMsg + len, " for '", 6);
  2272   2316           memmove(*errMsg + len+6, xpath, newlen);
  2273   2317           memmove(*errMsg + len+6+newlen, "' ", 3);
  2274   2318   
  2275   2319           for (i=0; tokens[i].token != EOS; i++) {
  2276         -            sprintf(tmp, "%s\n%3s%3d %-12s %5d %8.3f %5d  ",
         2320  +            sprintf(tmp, "%s\n%3s%3d %-12s %5ld %09.3f %5d  ",
  2277   2321                            (i==0) ? "\n\nParsed symbols:" : "",
  2278   2322                            (i==l) ? "-->" : "   ",
  2279   2323                             i,
  2280   2324                            token2str[tokens[i].token-LPAR],
  2281   2325                            tokens[i].intvalue,
  2282   2326                            tokens[i].realvalue,
  2283   2327                            tokens[i].pos
................................................................................
  2326   2370       const char *localName, *nodeUri;
  2327   2371   
  2328   2372       if (!(step->child)) return 1;
  2329   2373       if (step->child->type == IsElement) {
  2330   2374           if (node->nodeType == ELEMENT_NODE) {
  2331   2375               if ((step->child->strvalue[0] == '*') &&
  2332   2376                   (step->child->strvalue[1] == '\0') &&
  2333         -                (node->ownerDocument->rootNode != node)) return 1;
  2334         -            if (node->namespace) return 0;
         2377  +                (node->ownerDocument->rootNode != node) &&
         2378  +                (step->child->intvalue == 0)) return 1;
         2379  +            if (node->namespace
         2380  +                && (node->ownerDocument->namespaces[node->namespace-1]->prefix[0] != '\0'
         2381  +                    || node->ownerDocument->namespaces[node->namespace-1]->uri[0] != '\0')
         2382  +                ) return 0;
  2335   2383               return (strcmp(node->nodeName, step->child->strvalue)==0);
  2336   2384           }
  2337   2385           return 0;
  2338   2386       } else
  2339   2387       if (step->child->type == IsAttr) {
  2340   2388           if (node->nodeType == ATTRIBUTE_NODE) {
  2341   2389               if (node->nodeFlags & IS_NS_NODE) return 0;
................................................................................
  2404   2452   |
  2405   2453   \---------------------------------------------------------------------------*/
  2406   2454   int xpathFuncBoolean (
  2407   2455       xpathResultSet  *rs
  2408   2456   )
  2409   2457   {
  2410   2458       switch (rs->type) {
  2411         -        case BoolResult:         return ( rs->intvalue         );
         2459  +        case BoolResult:         return ( rs->intvalue ? 1 : 0 );
  2412   2460           case IntResult:          return ( rs->intvalue ? 1 : 0 );
  2413   2461           case RealResult:         return ((rs->realvalue != 0.0 ) && !IS_NAN (rs->realvalue));
  2414   2462           case StringResult:       return ( rs->string_len > 0   );
  2415   2463           case xNodeSetResult:     return ( rs->nr_nodes > 0     );
  2416   2464           case InfResult:
  2417   2465           case NInfResult:         return 1;
  2418   2466           /* NaNResult and EmptyResult are 'false' */
  2419   2467           default:                 return 0;
  2420   2468       }
  2421   2469   }
  2422   2470   
  2423         -static int
  2424         -xpathIsNumber (
  2425         -    char *str
         2471  +static double xpathStringToNumber (
         2472  +    char *str,
         2473  +    int  *NaN
  2426   2474       )
  2427   2475   {
  2428   2476       int dotseen = 0;
  2429         -    
  2430         -    while (*str && IS_XML_WHITESPACE(*str)) str++;
  2431         -    if (!*str) return 0;
  2432         -    if (*str == '-') {
  2433         -        str++;
  2434         -        if (!*str) return 0;
  2435         -    } else if (*str == '.') {
         2477  +    double d;
         2478  +    char *pc, *tailptr;
         2479  +
         2480  +    /* 
         2481  +       Just to use strtod() isn't sufficient for a few reasons:
         2482  +       - strtod() accepts a leading - or +, but XPath allows only a
         2483  +         leading -
         2484  +       - strtod() accepts the string representation of a hexadecimal
         2485  +         number, but XPath does not
         2486  +       - strtod() accepts an optional exponent but XPath does not
         2487  +       - strtod() accepts leading whitespace including \f and \v, but
         2488  +         XPath doesn't allow this characters. Since this two
         2489  +         characters are not legal XML characters, they can not be part
         2490  +         of a DOM tree and therefor there isn't a problem with XPath
         2491  +         expressions on DOM trees or in XSLT. But on Tcl level it's
         2492  +         possible, to feed that characters literal into the XPath
         2493  +         engine.
         2494  +    */
         2495  +    *NaN = 0;
         2496  +    pc = str;
         2497  +    while (*pc && IS_XML_WHITESPACE(*pc)) pc++;
         2498  +    if (!*pc) goto returnNaN;
         2499  +    if (*pc == '-') {
         2500  +        pc++;
         2501  +        if (!*pc) goto returnNaN;
         2502  +    } else if (*pc == '.') {
  2436   2503           dotseen = 1;
  2437         -        str++;
  2438         -        if (!*str) return 0;
         2504  +        pc++;
         2505  +        if (!*pc) goto returnNaN;
  2439   2506       }
  2440         -    if (!isdigit((unsigned char)*str)) return 0;
  2441         -    while (*str) {
  2442         -        if (isdigit((unsigned char)*str)) {
  2443         -            str++;
         2507  +    if (!isdigit((unsigned char)*pc)) goto returnNaN;
         2508  +    while (*pc) {
         2509  +        if (isdigit((unsigned char)*pc)) {
         2510  +            pc++;
  2444   2511               continue;
  2445   2512           }
  2446         -        if (*str == '.' && !dotseen) {
         2513  +        if (*pc == '.' && !dotseen) {
  2447   2514               dotseen = 1;
  2448         -            str++;
         2515  +            pc++;
  2449   2516               continue;
  2450   2517           }
  2451   2518           break;
  2452   2519       }
  2453         -    while (*str && IS_XML_WHITESPACE(*str)) str++;
  2454         -    if (*str) return 0;
  2455         -    else return 1;
         2520  +    while (*pc && IS_XML_WHITESPACE(*pc)) pc++;
         2521  +    if (*pc) goto returnNaN;
         2522  +
         2523  +    /* If we are here str is a number string, as XPath expects it. Now
         2524  +       we just use strtod(), to get the number */
         2525  +    d = strtod (str, &tailptr);
         2526  +    if (d == 0.0 && tailptr == str) goto returnNaN;
         2527  +    else if (IS_NAN(d)) goto returnNaN;
         2528  +    return d;
         2529  +
         2530  +    returnNaN:
         2531  +    *NaN = 2;
         2532  +    return strtod ("nan", &tailptr);
  2456   2533   }
  2457   2534   
  2458   2535   /*----------------------------------------------------------------------------
  2459   2536   |   xpathFuncNumber
  2460   2537   |
  2461   2538   \---------------------------------------------------------------------------*/
  2462   2539   double xpathFuncNumber (
  2463   2540       xpathResultSet  *rs,
  2464   2541       int             *NaN
  2465   2542   )
  2466   2543   {
  2467   2544       double d;
  2468         -    char   tmp[80], *pc, *tailptr;
         2545  +    char  *pc, *tailptr;
  2469   2546   
  2470   2547       *NaN = 0;
  2471   2548       switch (rs->type) {
  2472   2549           case BoolResult:   return (rs->intvalue? 1.0 : 0.0);
  2473   2550           case IntResult:    return rs->intvalue;
  2474   2551           case RealResult:   
  2475   2552               if (IS_NAN(rs->realvalue)) *NaN = 2;
................................................................................
  2499   2576               return -DBL_MAX;
  2500   2577   #   else
  2501   2578               /* well, what? */
  2502   2579               return 0.0
  2503   2580   #   endif
  2504   2581   #endif
  2505   2582           case StringResult:
  2506         -              if (!xpathIsNumber (rs->string)) {
  2507         -                  d = strtod ("nan", &tailptr);
  2508         -                  *NaN = 2;
  2509         -                  return d;
  2510         -              }
  2511         -              strncpy(tmp, rs->string, (rs->string_len<79) ? rs->string_len : 79);
  2512         -              tmp[(rs->string_len<79) ? rs->string_len : 79] = '\0';
  2513         -              d = strtod (tmp, &tailptr);
  2514         -              if (d == 0.0 && tailptr == tmp) {
  2515         -                  d = strtod ("nan", &tailptr);
  2516         -                  *NaN = 2;
  2517         -              } else
  2518         -              if (IS_NAN(d)) {
  2519         -                  *NaN = 2;
  2520         -              } else
  2521         -              if (tailptr) {
  2522         -                  while (*tailptr) {
  2523         -                      switch (*tailptr) {
  2524         -                      case ' ' :
  2525         -                      case '\n':
  2526         -                      case '\r':
  2527         -                      case '\t': tailptr++; continue;
  2528         -                      default: break; /*do nothing */
  2529         -                      }
  2530         -                      d = strtod ("nan", &tailptr);
  2531         -                      *NaN = 2;
  2532         -                      break;
  2533         -                  }
  2534         -              }
  2535         -              return d;
         2583  +            return xpathStringToNumber(rs->string, NaN);
  2536   2584           case xNodeSetResult:
  2537         -              pc = xpathFuncString(rs);
  2538         -              if (!xpathIsNumber (pc)) {
  2539         -                  d = strtod ("nan", &tailptr);
  2540         -                  *NaN = 2;
  2541         -                  FREE(pc);
  2542         -                  return d;
  2543         -              }
  2544         -              d = strtod (pc, &tailptr);
  2545         -              if (d == 0.0 && tailptr == pc) {
  2546         -                  d = strtod ("nan", &tailptr);
  2547         -                  *NaN = 2;
  2548         -              } else
  2549         -              if (IS_NAN(d)) {
  2550         -                  *NaN = 2;
  2551         -              } else
  2552         -              if (tailptr) {
  2553         -                  while (*tailptr) {
  2554         -                      switch (*tailptr) {
  2555         -                      case ' ' :
  2556         -                      case '\n':
  2557         -                      case '\r':
  2558         -                      case '\t': tailptr++; continue;
  2559         -                      default: break; /*do nothing */
  2560         -                      }
  2561         -                      d = strtod ("nan", &tailptr);
  2562         -                      *NaN = 2;
  2563         -                      break;
  2564         -                  }
  2565         -              }
  2566         -              FREE(pc);
  2567         -              return d;
         2585  +            pc = xpathFuncString(rs);
         2586  +            d = xpathStringToNumber(pc, NaN);
         2587  +            FREE(pc);
         2588  +            return d;
  2568   2589           default:
  2569   2590                 DBG(fprintf(stderr, "funcNumber: default: 0.0\n");)
  2570   2591                 d = strtod ("nan", &tailptr);
  2571   2592                 *NaN = 2;
  2572   2593                 return d;
  2573   2594       }
  2574   2595   }
................................................................................
  2683   2704       int          len;
  2684   2705   
  2685   2706       switch (rs->type) {
  2686   2707           case BoolResult:
  2687   2708               if (rs->intvalue) return (tdomstrdup("true"));
  2688   2709                            else return (tdomstrdup("false"));
  2689   2710           case IntResult:
  2690         -            sprintf(tmp, "%d", rs->intvalue);
         2711  +            sprintf(tmp, "%ld", rs->intvalue);
  2691   2712               return (tdomstrdup(tmp));
  2692   2713   
  2693   2714           case RealResult:
  2694   2715               if (IS_NAN (rs->realvalue)) return tdomstrdup ("NaN");
  2695   2716               else if (IS_INF (rs->realvalue)) {
  2696   2717                   if (IS_INF (rs->realvalue) == 1) return tdomstrdup ("Infinity");
  2697   2718                   else                             return tdomstrdup ("-Infinity");
................................................................................
  2739   2760       domNode *node
  2740   2761   )
  2741   2762   {
  2742   2763       int          len;
  2743   2764   
  2744   2765       return xpathGetStringValue (node, &len);
  2745   2766   }
  2746         -
  2747         -/*----------------------------------------------------------------------------
  2748         -|   xpathFuncNumberForNode
  2749         -|
  2750         -\---------------------------------------------------------------------------*/
  2751         -double xpathFuncNumberForNode (
  2752         -    domNode *node,
  2753         -    int      *NaN
  2754         -)
  2755         -{
  2756         -    char        *pc;
  2757         -    int          len, rc;
  2758         -    double       d;
  2759         -
  2760         -    *NaN = 0;
  2761         -    pc = xpathGetStringValue (node, &len);
  2762         -    rc = sscanf (pc,"%lf", &d);
  2763         -    if (rc != 1) *NaN = 2;
  2764         -    FREE(pc);
  2765         -    return d;
  2766         -}
  2767         -
  2768   2767   
  2769   2768   /*----------------------------------------------------------------------------
  2770   2769   |   xpathArity
  2771   2770   |
  2772   2771   \---------------------------------------------------------------------------*/
  2773   2772   static int xpathArity (
  2774   2773       ast step
................................................................................
  2848   2847       domNode         *node;
  2849   2848       domAttrNode     *attr;
  2850   2849       double           leftReal;
  2851   2850       ast              nextStep;
  2852   2851       int              argc, savedDocOrder, from;
  2853   2852       xpathResultSets *args;
  2854   2853       xpathResultSet  *arg;
         2854  +    Tcl_HashTable   *ids;
  2855   2855       Tcl_HashEntry   *entryPtr;
  2856         -    int              left = 0, useFastAdd;
         2856  +    int              left = 0;
  2857   2857       double           dRight = 0.0;
  2858   2858       char            *leftStr = NULL, *rightStr = NULL;
  2859   2859       const char      *str;
  2860   2860       Tcl_DString      dStr;
  2861         -#if TclOnly8Bits
  2862         -    char            *fStr;
  2863         -#else
  2864   2861       int              found, j;
  2865   2862       int              lenstr, fromlen, utfCharLen;
  2866   2863       char             utfBuf[TCL_UTF_MAX];
  2867   2864       Tcl_DString      tstr, tfrom, tto, tresult;
  2868   2865       Tcl_UniChar     *ufStr, *upfrom, unichar;
  2869         -#endif
  2870         -
  2871         -    if (result->type == EmptyResult) useFastAdd = 1;
  2872         -    else useFastAdd = 0;
  2873         -
  2874   2866   
  2875   2867       switch (step->intvalue) {
  2876   2868   
  2877   2869       case f_position:
  2878   2870           XPATH_ARITYCHECK(step,0,errMsg);
  2879   2871           if (*docOrder) {
  2880   2872               rsSetInt (result, position+1);
................................................................................
  2983   2975   
  2984   2976           leftStr = xpathFuncString (&leftResult );
  2985   2977           xpathRSFree( &leftResult );
  2986   2978           DBG(fprintf(stderr, "leftStr='%s'\n", leftStr);)
  2987   2979           if      (step->intvalue == f_string)
  2988   2980               rsSetString (result, leftStr);
  2989   2981           else if (step->intvalue == f_stringLength) {
  2990         -#if TclOnly8Bits            
  2991         -            rsSetInt (result, strlen(leftStr));
  2992         -#else
  2993   2982               pto = leftStr;
  2994   2983               len = 0;
  2995   2984               while (*pto) {
  2996   2985                   len++;
  2997   2986                   i = UTF8_CHAR_LEN (*pto);
  2998   2987                   if (!i) {
  2999   2988                       FREE (leftStr);
  3000   2989                       *errMsg = tdomstrdup("Can only handle UTF-8 chars up "
  3001         -                                         "to 3 bytes length");
         2990  +                                         "to 4 bytes length");
  3002   2991                       return XPATH_I18N_ERR;
  3003   2992                   }
  3004   2993                   pto += i;
  3005   2994               }
  3006   2995               rsSetInt (result, len);
  3007         -#endif
  3008   2996           }
  3009   2997           else {
  3010   2998               pwhite = 1;
  3011   2999               pfrom = pto = leftStr;
  3012   3000               while (*pfrom) {
  3013   3001                   switch (*pfrom) {
  3014   3002                   case ' ' : case '\n': case '\r': case '\t':
................................................................................
  3055   3043       case f_false:
  3056   3044           XPATH_ARITYCHECK(step,0,errMsg);
  3057   3045           rsSetBool (result, 0);
  3058   3046           break;
  3059   3047   
  3060   3048       case f_id:
  3061   3049           XPATH_ARITYCHECK(step,1,errMsg);
  3062         -        if (!ctxNode->ownerDocument->ids) {
         3050  +        if (ctxNode->nodeType == ATTRIBUTE_NODE) {
         3051  +            ids = ((domAttrNode*)ctxNode)->parentNode->ownerDocument->ids;
         3052  +        } else {
         3053  +            ids = ctxNode->ownerDocument->ids;
         3054  +        }
         3055  +        if (!ids) {
  3063   3056               break;
  3064   3057           }
  3065   3058           xpathRSInit (&leftResult);
  3066   3059           rc = xpathEvalStep( step->child, ctxNode, exprContext, position,
  3067   3060                               nodeList, cbs, &leftResult, docOrder, errMsg);
  3068   3061           if (rc) {
  3069   3062               xpathRSFree( &leftResult );
................................................................................
  3075   3068           if (leftResult.type == EmptyResult) {
  3076   3069               xpathRSFree (&leftResult);
  3077   3070               return XPATH_OK;
  3078   3071           }
  3079   3072           if (leftResult.type == xNodeSetResult) {
  3080   3073               for (i=0; i < leftResult.nr_nodes; i++) {
  3081   3074                   leftStr = xpathFuncStringForNode (leftResult.nodes[i]);
  3082         -                entryPtr = Tcl_FindHashEntry (ctxNode->ownerDocument->ids,
  3083         -                                              leftStr);
         3075  +                entryPtr = Tcl_FindHashEntry (ids, leftStr);
  3084   3076                   if (entryPtr) {
  3085   3077                       node = (domNode*) Tcl_GetHashValue (entryPtr);
  3086   3078                       /* Don't report nodes out of the fragment list */
  3087   3079                       if (node->parentNode != NULL ||
  3088   3080                           (node == node->ownerDocument->documentElement)) {
  3089   3081                           rsAddNode (result, node);
  3090   3082                       }
................................................................................
  3101   3093                   switch (*pto) {
  3102   3094                   case ' ' : case '\n': case '\r': case '\t':
  3103   3095                       if (pwhite) {
  3104   3096                           pto++;
  3105   3097                           continue;
  3106   3098                       }
  3107   3099                       *pto = '\0';
  3108         -                    entryPtr = Tcl_FindHashEntry (ctxNode->ownerDocument->ids,
  3109         -                                                  pfrom);
         3100  +                    entryPtr = Tcl_FindHashEntry (ids, pfrom);
  3110   3101                       if (entryPtr) {
  3111   3102                           node = (domNode*) Tcl_GetHashValue (entryPtr);
  3112   3103                           /* Don't report nodes out of the fragment list */
  3113   3104                           if (node->parentNode != NULL ||
  3114   3105                               (node == node->ownerDocument->documentElement)) {
  3115   3106                               rsAddNode (result, node);
  3116   3107                           }
................................................................................
  3123   3114                           pfrom = pto;
  3124   3115                           pwhite = 0;
  3125   3116                       }
  3126   3117                       pto++;
  3127   3118                   }
  3128   3119               }
  3129   3120               if (!pwhite) {
  3130         -                entryPtr = Tcl_FindHashEntry (ctxNode->ownerDocument->ids,
  3131         -                                              pfrom);
         3121  +                entryPtr = Tcl_FindHashEntry (ids, pfrom);
  3132   3122                   if (entryPtr) {
  3133   3123                       node = (domNode*) Tcl_GetHashValue (entryPtr);
  3134   3124                       /* Don't report nodes out of the fragment list */
  3135   3125                       if (node->parentNode != NULL ||
  3136   3126                           (node == node->ownerDocument->documentElement)) {
  3137   3127                           rsAddNode (result, node);
  3138   3128                       }
................................................................................
  3191   3181                               nodeList, cbs, &leftResult, docOrder, errMsg);
  3192   3182           if (rc) {
  3193   3183               xpathRSFree (&leftResult);
  3194   3184               return rc;
  3195   3185           }
  3196   3186           leftStr = xpathFuncString (&leftResult);
  3197   3187           if (ctxNode->nodeType != ELEMENT_NODE) {
  3198         -            node = ctxNode->parentNode;
         3188  +            if (ctxNode->nodeType == ATTRIBUTE_NODE) {
         3189  +                node = ((domAttrNode*)ctxNode)->parentNode;
         3190  +            } else {
         3191  +                node = ctxNode->parentNode;
         3192  +            }
  3199   3193           } else {
  3200   3194               node = ctxNode;
  3201   3195           }
  3202   3196           while (node) {
  3203   3197               attr = node->firstAttr;
  3204   3198               while (attr) {
  3205   3199                   if (strcmp (attr->nodeName, "xml:lang")!=0) {
................................................................................
  3402   3396                       rsSetString (result, "");
  3403   3397                       return XPATH_OK;
  3404   3398                   }
  3405   3399                   from = 0;
  3406   3400               }
  3407   3401           } else {
  3408   3402               if (from < 0) from = 0;
  3409         -#if TclOnly8Bits
  3410         -            len = strlen(leftStr) - from;
  3411         -#else
  3412   3403               len = INT_MAX;
  3413         -#endif
  3414   3404           }
  3415   3405   
  3416         -#if TclOnly8Bits
  3417         -        if (from >= (int) strlen(leftStr)) {
  3418         -            rsSetString (result, "");
  3419         -            FREE(leftStr);
  3420         -            return XPATH_OK;
  3421         -        } else {
  3422         -            if ( (len == INT_MAX) || ((from + len) > (int) strlen(leftStr)) ) {
  3423         -                len =  strlen(leftStr) - from;
  3424         -            }
  3425         -        }
  3426         -        DBG(fprintf(stderr, "substring leftStr='%s' from=%d len=%d \n",
  3427         -                    leftStr, from, len);
  3428         -            )
  3429         -
  3430         -            *(leftStr+from+len) = '\0';
  3431         -        rsSetString (result, (leftStr+from));
  3432         -#else 
  3433   3406           pfrom = leftStr;
  3434   3407           while (*pfrom && (from > 0)) {
  3435   3408               i = UTF8_CHAR_LEN (*pfrom);
  3436   3409               if (!i) {
  3437   3410                   FREE (leftStr);
  3438   3411                   *errMsg = tdomstrdup("Can only handle UTF-8 chars up "
  3439         -                                     "to 3 bytes length");
         3412  +                                     "to 4 bytes length");
  3440   3413                   return XPATH_I18N_ERR;
  3441   3414               }
  3442   3415               pfrom += i;
  3443   3416               from--;
  3444   3417           }
  3445   3418           if (len < INT_MAX) {
  3446   3419               pto = pfrom;
  3447   3420               while (*pto && (len > 0)) {
  3448   3421                   i = UTF8_CHAR_LEN (*pto);
  3449   3422                   if (!i) {
  3450   3423                       FREE (leftStr);
  3451   3424                       *errMsg = tdomstrdup("Can only handle UTF-8 chars up "
  3452         -                                         "to 3 bytes length");
         3425  +                                         "to 4 bytes length");
  3453   3426                       return XPATH_I18N_ERR;
  3454   3427                   }
  3455   3428                   pto += i;
  3456   3429                   len--;
  3457   3430               }
  3458   3431               *pto = '\0';
  3459   3432           }
  3460   3433           rsSetString (result, pfrom);
  3461         -#endif
  3462   3434           FREE(leftStr);
  3463   3435           break;
  3464   3436   
  3465   3437       case f_translate:
  3466   3438           XPATH_ARITYCHECK(step,3,errMsg);
  3467   3439           xpathRSInit (&leftResult);
  3468   3440           savedDocOrder = *docOrder;
................................................................................
  3482   3454           CHECK_RC;
  3483   3455           *docOrder = savedDocOrder;
  3484   3456           leftStr    = xpathFuncString( &leftResult    );
  3485   3457           rightStr   = xpathFuncString( &rightResult   );
  3486   3458           replaceStr = xpathFuncString( &replaceResult );
  3487   3459   
  3488   3460   
  3489         -#if TclOnly8Bits
  3490         -        len = strlen(replaceStr);
  3491         -        pfrom = pto = leftStr;
  3492         -        while (*pfrom) {
  3493         -            fStr = strchr(rightStr, *pfrom);
  3494         -            if (fStr == NULL) {
  3495         -                *pto++ = *pfrom;
  3496         -            } else {
  3497         -                i = (fStr - rightStr);
  3498         -                if (i < len) {
  3499         -                    *pto++ = *(replaceStr+i);
  3500         -                }
  3501         -            }
  3502         -            pfrom++;
  3503         -        }
  3504         -        *pto = '\0';
  3505         -        rsSetString (result, leftStr);
  3506         -#else
  3507   3461           Tcl_DStringInit (&tstr);
  3508   3462           Tcl_DStringInit (&tfrom);
  3509   3463           Tcl_DStringInit (&tto);
  3510   3464           Tcl_DStringInit (&tresult);
  3511   3465   
  3512   3466           Tcl_UtfToUniCharDString (leftStr, -1, &tstr);
  3513   3467           Tcl_UtfToUniCharDString (rightStr, -1, &tfrom);
................................................................................
  3541   3495               upfrom++;
  3542   3496           }
  3543   3497           rsSetString (result, Tcl_DStringValue (&tresult));
  3544   3498           Tcl_DStringFree (&tstr);
  3545   3499           Tcl_DStringFree (&tfrom);
  3546   3500           Tcl_DStringFree (&tto);
  3547   3501           Tcl_DStringFree (&tresult);
  3548         -#endif
  3549   3502   
  3550   3503           xpathRSFree( &replaceResult );
  3551   3504           xpathRSFree( &rightResult   );
  3552   3505           xpathRSFree( &leftResult    );
  3553   3506           FREE(leftStr); FREE(rightStr); FREE(replaceStr);
  3554   3507           break;
  3555   3508   
................................................................................
  3635   3588                   i = 0;
  3636   3589                   attr = node->firstAttr;
  3637   3590                   while (attr) {
  3638   3591                       if ((domNode*)attr == leftResult.nodes[0]) break;
  3639   3592                       attr = attr->nextSibling;
  3640   3593                       i++;
  3641   3594                   }
  3642         -                sprintf(tmp,"id%p-%d", node, i);
         3595  +                sprintf(tmp,"id%p-%d", (void *)node, i);
  3643   3596               } else {
  3644         -                sprintf(tmp,"id%p", leftResult.nodes[0]);
         3597  +                sprintf(tmp,"id%p", (void *)leftResult.nodes[0]);
  3645   3598               }
  3646   3599               rsSetString (result, tmp);
  3647   3600           } else
  3648   3601   
  3649   3602           if (step->intvalue == f_namespaceUri) {
  3650   3603               if (leftResult.type != xNodeSetResult) {
  3651   3604                   *errMsg = tdomstrdup("namespace-uri() requires a node set!");
................................................................................
  3864   3817               while (child && (count < step->intvalue)) {
  3865   3818                   DBG(fprintf(stderr, "AxisChild: child '%s' domNode%p \n", 
  3866   3819                               child->nodeName, child);)
  3867   3820                   if (xpathNodeTest(child, step)) {
  3868   3821                       DBG(fprintf(stderr, 
  3869   3822                         "AxisChild: after node taking child '%s' domNode%p \n",
  3870   3823                                   child->nodeName, child);)
  3871         -                    rsAddNodeFast( result, child);
         3824  +                    checkRsAddNode( result, child);
  3872   3825                       count++;
  3873   3826                   }
  3874   3827                   child = child->nextSibling;
  3875   3828               }
  3876   3829           } else {
  3877   3830               while (child) {
  3878   3831                   DBG(fprintf(stderr, "AxisChild: child '%s' domNode%p \n",
  3879   3832                               child->nodeName, child);)
  3880   3833                   if (xpathNodeTest(child, step)) {
  3881   3834                       DBG(fprintf(stderr,
  3882   3835                         "AxisChild: after node taking child '%s' domNode%p \n",
  3883   3836                                   child->nodeName, child);)
  3884         -                    rsAddNodeFast( result, child);
         3837  +                    checkRsAddNode( result, child);
  3885   3838                   }
  3886   3839                   child = child->nextSibling;
  3887   3840               }
  3888   3841           }
  3889   3842           DBG( fprintf(stderr,"AxisChild result:\n");
  3890   3843                rsPrint(result);
  3891   3844           )
  3892   3845           break;
  3893   3846   
  3894   3847       case SlashSlash:
  3895         -        if (step->intvalue) predLimit = 1;
  3896         -        else predLimit = 0;
  3897         -        predLimit = 0;
  3898   3848           xpathRSInit (&tResult);
  3899   3849           node = ctxNode->firstChild;
  3900   3850           while (node) {
  3901   3851               if (node->nodeType == ELEMENT_NODE) {
  3902   3852                   rc = xpathEvalStep (step, node, exprContext, position,
  3903   3853                                       nodeList, cbs, result, docOrder, errMsg);
  3904   3854                   if (rc) {
  3905   3855                       xpathRSFree (&tResult);
  3906   3856                       return rc;
  3907   3857                   }
  3908   3858               }
  3909   3859               if (xpathNodeTest(node, step)) {
  3910   3860                   rsAddNodeFast( &tResult, node);
  3911         -                if (predLimit) {
  3912         -                    count++;
  3913         -                    if (count >= step->intvalue) break;
  3914         -                }
  3915   3861               }
  3916   3862               node = node->nextSibling;
  3917   3863           }
  3918         -        if (node) {
  3919         -            node = node->nextSibling;
  3920         -            while (node) {
  3921         -                if (node->nodeType == ELEMENT_NODE) {
  3922         -                    rc = xpathEvalStep (step, node, exprContext, position,
  3923         -                                        nodeList, cbs, result, docOrder,
  3924         -                                        errMsg);
  3925         -                    if (rc) {
  3926         -                        xpathRSFree (&tResult);
  3927         -                        return rc;
  3928         -                    }
  3929         -                }
  3930         -                node = node->nextSibling;
  3931         -            }
  3932         -        }
  3933   3864           rc = xpathEvalPredicate (step->next, exprContext, result, &tResult,
  3934   3865                                     cbs, docOrder, errMsg);
  3935   3866           xpathRSFree (&tResult);
  3936   3867           CHECK_RC;
  3937   3868           break;
  3938   3869   
  3939   3870       case AxisDescendant:
................................................................................
  3962   3893               step->type = SlashSlash;
  3963   3894               rc = xpathEvalStep (step, ctxNode, exprContext, position, 
  3964   3895                                   nodeList, cbs, result, docOrder, errMsg);
  3965   3896               step->type = savedAstType;
  3966   3897               CHECK_RC;
  3967   3898               break;
  3968   3899           }
  3969         -        /* whithout following Pred step, // is the same as 
         3900  +        /* without following Pred step, // is the same as 
  3970   3901              AxisDescendantOrSelf, fall throu */
  3971   3902   
  3972   3903       case AxisDescendantLit:
  3973   3904       case AxisDescendantOrSelfLit:
  3974   3905           *docOrder = 1;
  3975   3906           if (step->intvalue
  3976   3907               && (step->type == AxisDescendantLit 
................................................................................
  4030   3961           }
  4031   3962           break;
  4032   3963   
  4033   3964       case AxisSelf:
  4034   3965           *docOrder = 1;
  4035   3966           DBG(fprintf(stderr, "AxisSelf :: \n");)
  4036   3967           if (xpathNodeTest(ctxNode, step)) {
  4037         -            checkRsAddNode( result, ctxNode);
         3968  +            rsAddNode( result, ctxNode);
  4038   3969           }
  4039   3970           break;
  4040   3971   
  4041   3972       case GetContextNode:
  4042         -        checkRsAddNode( result, ctxNode);
         3973  +        rsAddNode( result, ctxNode);
  4043   3974           break;
  4044   3975   
  4045   3976       case AxisAttribute:
  4046   3977           *docOrder = 1;
  4047   3978           DBG(fprintf(stderr, "AxisAttribute %s \n", step->child->strvalue);)
  4048   3979           if (ctxNode->nodeType != ELEMENT_NODE) return XPATH_OK;
  4049   3980           if (step->child->type == IsElement) {
................................................................................
  4050   3981               step->child->type = IsAttr;
  4051   3982           }
  4052   3983           if (step->child->type == IsAttr) {
  4053   3984               if (strcmp(step->child->strvalue, "*")==0) {
  4054   3985                   attr = ctxNode->firstAttr;
  4055   3986                   while (attr) {
  4056   3987                       if (!(attr->nodeFlags & IS_NS_NODE)) {
  4057         -                        rsAddNodeFast (result, (domNode *)attr);
         3988  +                        checkRsAddNode (result, (domNode *)attr);
  4058   3989                       }
  4059   3990                       attr = attr->nextSibling;
  4060   3991                   }
  4061   3992               } else {
  4062   3993                   attr = ctxNode->firstAttr;
  4063   3994                   while (attr && (attr->nodeFlags & IS_NS_NODE))
  4064   3995                       attr = attr->nextSibling;
  4065   3996                   while (attr) {
  4066   3997                       if (xpathNodeTest( (domNode*)attr, step)) {
  4067         -                        rsAddNodeFast (result, (domNode *)attr);
         3998  +                        checkRsAddNode (result, (domNode *)attr);
  4068   3999                       }
  4069   4000                       attr = attr->nextSibling;
  4070   4001                   }
  4071   4002               }
  4072   4003           } else
  4073   4004           if (step->child->type == IsNSAttr) {
  4074   4005               attr = ctxNode->firstAttr;
  4075   4006               while (attr && (attr->nodeFlags & IS_NS_NODE))
  4076   4007                   attr = attr->nextSibling;
  4077   4008               while (attr) {
  4078   4009                   if (xpathNodeTest ( (domNode*)attr, step)) {
  4079         -                    rsAddNodeFast (result, (domNode *)attr);
         4010  +                    checkRsAddNode (result, (domNode *)attr);
  4080   4011                   }
  4081   4012                   attr = attr->nextSibling;
  4082   4013               }
  4083   4014           }
  4084   4015           break;
  4085   4016   
  4086   4017       case AxisParent:
................................................................................
  4119   4050           break;
  4120   4051   
  4121   4052       case AxisAncestor:
  4122   4053       case AxisAncestorOrSelf:
  4123   4054           *docOrder = 0;
  4124   4055           xpathRSInit (&tResult);
  4125   4056           if (step->type == AxisAncestorOrSelf) {
  4126         -            if (xpathNodeTest(ctxNode, step))
         4057  +            if (xpathNodeTest(ctxNode, step)) {
  4127   4058                   rsAddNodeFast(&tResult, ctxNode);
         4059  +            }
  4128   4060           }
  4129   4061           if (ctxNode->nodeType == ATTRIBUTE_NODE) {
  4130   4062               ctxNode = ((domAttrNode *)ctxNode)->parentNode;
  4131         -            if (xpathNodeTest(ctxNode, step))
         4063  +            if (xpathNodeTest(ctxNode, step)) {
  4132   4064                   rsAddNodeFast(&tResult, ctxNode);
         4065  +            }
  4133   4066           }
  4134   4067           startingNode = ctxNode;
  4135   4068           while (ctxNode->parentNode) {
  4136   4069               ctxNode = ctxNode->parentNode;
  4137         -            if (xpathNodeTest(ctxNode, step))
         4070  +            if (xpathNodeTest(ctxNode, step)) {
  4138   4071                   rsAddNodeFast(&tResult, ctxNode);
         4072  +            }
  4139   4073           }
  4140   4074           if (startingNode != ctxNode->ownerDocument->rootNode) {
  4141   4075               if (xpathNodeTest (ctxNode->ownerDocument->rootNode, step)) {
  4142   4076                   rsAddNodeFast (&tResult, ctxNode->ownerDocument->rootNode);
  4143   4077               }
  4144   4078           }
  4145   4079           for (i = tResult.nr_nodes - 1; i >= 0;  i--) {
................................................................................
  4349   4283                   rc = 0;
  4350   4284                   for (i = 0; i < result->nr_nodes; i++) {
  4351   4285                       if (strcmp (attr->nodeName, ((domAttrNode*)result->nodes[i])->nodeName)==0) {
  4352   4286                           rc = 1; break;
  4353   4287                       }
  4354   4288                   }
  4355   4289                   if (rc) {attr = attr->nextSibling; continue;}
  4356         -                rsAddNodeFast (result, (domNode *)attr);
         4290  +                checkRsAddNode (result, (domNode *)attr);
  4357   4291                   attr = attr->nextSibling;
  4358   4292               }
  4359   4293   
  4360   4294               if (node == node->ownerDocument->documentElement) {
  4361   4295                   if (ctxNode != ctxNode->ownerDocument->rootNode) {
  4362   4296                       node = ctxNode->ownerDocument->rootNode;
  4363   4297                   } else {
................................................................................
  4394   4328           break;
  4395   4329   
  4396   4330       case Real:
  4397   4331           rsSetReal (result, step->realvalue);
  4398   4332           break;
  4399   4333   
  4400   4334       case Add:
  4401         -    case Substract:
         4335  +    case Subtract:
  4402   4336       case Mult:
  4403   4337       case Div:
  4404   4338       case Mod:
  4405   4339           xpathRSInit (&leftResult);
  4406   4340           xpathRSInit (&rightResult);
  4407   4341   
  4408   4342           savedDocOrder = *docOrder;
................................................................................
  4439   4373               dRight = xpathFuncNumber(&rightResult, &NaN1);
  4440   4374           }
  4441   4375           if (NaN || NaN1) {
  4442   4376               if ((NaN == 2) || (NaN1 == 2)) {
  4443   4377                   rsSetNaN (result);
  4444   4378               } else {
  4445   4379                   switch (step->type) {
  4446         -                case Substract:
         4380  +                case Subtract:
  4447   4381                       NaN1 = -1 * NaN1;
  4448   4382                       /* fall throu */   
  4449   4383                   case Add:
  4450   4384                       if (NaN == NaN1) {
  4451   4385                           if (NaN == 1) rsSetInf (result);
  4452   4386                           else          rsSetNInf (result);
  4453   4387                       } else if ((rc = NaN + NaN1) != 0) {
................................................................................
  4488   4422               }
  4489   4423               xpathRSFree (&rightResult);
  4490   4424               xpathRSFree (&leftResult);
  4491   4425               return XPATH_OK;
  4492   4426           }
  4493   4427           switch (step->type) {
  4494   4428           case Add:       rsSetReal (result, dLeft + dRight); break;
  4495         -        case Substract: rsSetReal (result, dLeft - dRight); break;
         4429  +        case Subtract: rsSetReal (result, dLeft - dRight); break;
  4496   4430           case Mult:      rsSetReal (result, dLeft * dRight); break;
  4497   4431           case Div:
  4498   4432               if (dRight == 0.0) {
  4499   4433                   if (dLeft == 0.0) {
  4500   4434                       rsSetNaN (result);
  4501   4435                   } else {
  4502   4436                       if (dLeft > 0) {
................................................................................
  4506   4440                       }
  4507   4441                   }
  4508   4442               } else {
  4509   4443                   rsSetReal (result, dLeft / dRight);
  4510   4444               }
  4511   4445               break;
  4512   4446           case Mod:
  4513         -            if (dRight == 0.0) {
         4447  +            if ((int)dRight == 0) {
  4514   4448                   rsSetNaN (result);
  4515   4449               } else {
  4516   4450                   rsSetInt  (result, ((int)dLeft) % ((int)dRight));
  4517   4451               }
  4518   4452               break;
  4519   4453           default:        break;
  4520   4454           }
................................................................................
  4701   4635                       /* The real value of a node could never be inf/-inf */
  4702   4636                       /* And NaN is always != NaN (and != everything else) */
  4703   4637                       if (step->type == Equal) res = 0;
  4704   4638                       else                     res = 1;
  4705   4639                       break;
  4706   4640                   }
  4707   4641                   for (i=0; i < pleftResult->nr_nodes; i++) {
  4708         -                    dLeft = xpathFuncNumberForNode (pleftResult->nodes[i], &NaN);
         4642  +                    leftStr = xpathFuncStringForNode (pleftResult->nodes[i]);
         4643  +                    dLeft = xpathStringToNumber (leftStr, &NaN);
         4644  +                    FREE(leftStr);
  4709   4645                       if (NaN) continue;
  4710   4646                       if (step->type == Equal) res = (dLeft == dRight);
  4711   4647                       else                     res = (dLeft != dRight);
  4712   4648                       if (res) break;
  4713   4649                   }
  4714   4650                   break;
  4715   4651               case NaNResult:
................................................................................
  4810   4746           CHECK_RC;
  4811   4747           *docOrder = savedDocOrder;
  4812   4748   
  4813   4749           DBG( fprintf(stderr,"right:\n");
  4814   4750                rsPrint(&rightResult);
  4815   4751           )
  4816   4752           res = 0;
  4817         -
  4818   4753           if (   leftResult.type == xNodeSetResult
  4819   4754               || rightResult.type == xNodeSetResult) {
  4820   4755               if (leftResult.type == xNodeSetResult) {
  4821   4756                   pleftResult = &leftResult;
  4822   4757                   prightResult = &rightResult;
  4823   4758                   switchResult = 0;
  4824   4759               } else {
  4825   4760                   pleftResult = &rightResult;
  4826   4761                   prightResult = &leftResult;
  4827   4762                   switchResult = 1;
  4828   4763               }
         4764  +
  4829   4765               switch (prightResult->type) {
  4830   4766               case EmptyResult:
  4831   4767                   res = 0;
  4832   4768                   break;
  4833   4769               case xNodeSetResult:
  4834   4770                   JDBG( fprintf(stderr,"\nleft+right result:\n");
  4835   4771                        rsPrint(pleftResult);
  4836   4772                        rsPrint(prightResult);
  4837   4773                   )
  4838   4774                   for (i=0; i < pleftResult->nr_nodes; i++) {
  4839         -                    dLeft = xpathFuncNumberForNode (pleftResult->nodes[i], &NaN);
         4775  +                    leftStr = xpathFuncStringForNode (pleftResult->nodes[i]);
         4776  +                    dLeft = xpathStringToNumber (leftStr, &NaN);
         4777  +                    FREE(leftStr);
  4840   4778                       if (NaN) continue;
  4841   4779                       for (j=0; j < prightResult->nr_nodes; j++) {
  4842         -                        dRight = xpathFuncNumberForNode (prightResult->nodes[j], &NaN);
         4780  +                        rightStr = xpathFuncStringForNode (prightResult->nodes[j]);
         4781  +                        dRight = xpathStringToNumber (rightStr, &NaN);
         4782  +                        FREE(rightStr);
  4843   4783                           if (NaN)  continue;
  4844   4784                           if (switchResult) {
  4845   4785                               dTmp   = dLeft;
  4846   4786                               dLeft  = dRight;
  4847   4787                               dRight = dTmp;
  4848   4788                           }
  4849   4789                           if      (step->type == Less)     res = (dLeft < dRight);
................................................................................
  4853   4793   
  4854   4794                           if (res) break;
  4855   4795                       }
  4856   4796                       if (res) break;
  4857   4797                   }
  4858   4798                   break;
  4859   4799               case BoolResult:
  4860         -                /* pleftResult is a non-emtpy nodeset, therefor: */
         4800  +                /* pleftResult is a non-empty nodeset, therefor: */
  4861   4801                   dLeft = 1.0;
  4862   4802                   dRight = xpathFuncNumber (prightResult, &NaN);
  4863   4803                   if (NaN) break;
  4864   4804                   if      (step->type == Less)     res = (dLeft < dRight);
  4865   4805                   else if (step->type == LessOrEq) res = (dLeft <= dRight);
  4866   4806                   else if (step->type == Greater)  res = (dLeft >  dRight);
  4867   4807                   else                             res = (dLeft >= dRight);
................................................................................
  4882   4822                       if (NaN == 2) break;
  4883   4823   #ifdef DBL_MAX                    
  4884   4824                       if (NaN == 1) dRight = DBL_MAX;
  4885   4825                       else          dRight = -DBL_MAX;
  4886   4826   #endif
  4887   4827                   }
  4888   4828                   for (i=0; i < pleftResult->nr_nodes; i++) {
  4889         -                    dLeft = xpathFuncNumberForNode (pleftResult->nodes[i], &NaN);
         4829  +                    leftStr = xpathFuncStringForNode (pleftResult->nodes[i]);
         4830  +                    dLeft = xpathStringToNumber (leftStr, &NaN);
         4831  +                    FREE (leftStr);
  4890   4832                       if (NaN) continue;
  4891   4833                       if (switchResult) {
  4892   4834                           dTmp   = dLeft;
  4893   4835                           dLeft  = dRight;
  4894   4836                           dRight = dTmp;
  4895   4837                       }
  4896   4838                       if      (step->type == Less)     res = (dLeft < dRight);
................................................................................
  5048   4990               rc = xpathEvalStep( step->child, stepResult->nodes[i],
  5049   4991                                   exprContext, i, stepResult, cbs, &predResult,
  5050   4992                                   docOrder, errMsg);
  5051   4993               CHECK_RC;
  5052   4994               *docOrder = savedDocOrder;
  5053   4995               DBG( fprintf(stderr, "after eval for Predicate: \n"); )
  5054   4996               DBG( rsPrint( &predResult); )
  5055         -
  5056   4997               if (predResult.type == RealResult) {
  5057   4998                   predResult.type = IntResult;
  5058   4999                   predResult.intvalue = xpathRound(predResult.realvalue);
  5059   5000               }
  5060   5001               if (predResult.type == IntResult) {
  5061   5002                   if (predResult.intvalue < 0) {
  5062   5003                       predResult.intvalue = 
................................................................................
  5233   5174       char            ** errMsg,
  5234   5175       xpathResultSet   * result
  5235   5176   )
  5236   5177   {
  5237   5178       xpathResultSet nodeList;
  5238   5179       int            rc, hnew = 1, docOrder = 1;
  5239   5180       ast            t;
  5240         -    Tcl_HashEntry *h;
         5181  +    Tcl_HashEntry *h = NULL;
  5241   5182   
  5242   5183       *errMsg = NULL;
  5243   5184       if (cache) {
  5244   5185           h = Tcl_CreateHashEntry (cache, xpath, &hnew);
  5245   5186       }
  5246   5187       if (hnew) {
  5247   5188           rc = xpathParse(xpath, exprContext, XPATH_EXPR, prefixMappings,
  5248   5189                           parseVarCB, &t, errMsg);
  5249         -        CHECK_RC;
         5190  +        if (rc) {
         5191  +            if (h != NULL) {
         5192  +                Tcl_DeleteHashEntry(h);
         5193  +            }
         5194  +            return rc;
         5195  +        }
  5250   5196           if (cache) {
  5251   5197               Tcl_SetHashValue(h, t);
  5252   5198           }
  5253   5199       } else {
  5254   5200           t = (ast)Tcl_GetHashValue(h);
  5255   5201       }
  5256   5202       
................................................................................
  5323   5269                       if (nodeToMatch->nodeType != ELEMENT_NODE) {
  5324   5270                           xpathRSFree (&nodeList); return 0;
  5325   5271                       }
  5326   5272                       if (nodeToMatch == nodeToMatch->ownerDocument->rootNode) {
  5327   5273                           xpathRSFree (&nodeList); return 0;
  5328   5274                       }
  5329   5275                       if ((step->child->strvalue[0] != '*') ||
  5330         -                        (step->child->strvalue[1] != '\0'))
         5276  +                        (step->child->strvalue[1] != '\0') ||
         5277  +                        (step->child->intvalue != 0))
  5331   5278                       {
  5332   5279                           if (nodeToMatch->namespace) return 0;
  5333   5280                           if (strcmp(nodeToMatch->nodeName, step->child->strvalue)!=0) {
  5334   5281                               xpathRSFree (&nodeList); return 0;
  5335   5282                           }
  5336   5283                       }
  5337   5284                       break;
................................................................................
  5367   5314                   if (nodeToMatch->nodeType != ELEMENT_NODE) {
  5368   5315                       xpathRSFree (&nodeList); return 0;
  5369   5316                   }
  5370   5317                   if (nodeToMatch == nodeToMatch->ownerDocument->rootNode) {
  5371   5318                       xpathRSFree (&nodeList); return 0;
  5372   5319                   }
  5373   5320                   if ((step->strvalue[0] != '*') ||
  5374         -                    (step->strvalue[1] != '\0'))
         5321  +                    (step->strvalue[1] != '\0') ||
         5322  +                    (step->intvalue != 0))
  5375   5323                   {
  5376   5324                       if (nodeToMatch->namespace) return 0;
  5377   5325                       if (strcmp(nodeToMatch->nodeName, step->strvalue)!=0) {
  5378   5326                           xpathRSFree (&nodeList); return 0;
  5379   5327                       }
  5380   5328                   }
  5381   5329                   break;
................................................................................
  5723   5671   {
  5724   5672       if (!steps) return 0.0;
  5725   5673   
  5726   5674       DBG(printAst(0, steps);)
  5727   5675   
  5728   5676       if (steps->next == NULL) {
  5729   5677           if (steps->type == IsElement) {
  5730         -            if (strcmp(steps->strvalue, "*")==0) {
         5678  +            if (strcmp(steps->strvalue, "*")==0 && steps->intvalue==0) {
  5731   5679                   return -0.5;
  5732   5680               } else {
  5733   5681                   return 0.0;
  5734   5682               }
  5735   5683           } else
  5736   5684           if (steps->type == IsFQElement) {
  5737   5685               return 0.0;
................................................................................
  5777   5725   |   nodeToXPath  -  returns a XPath addressing exactly the given node
  5778   5726   |
  5779   5727   \---------------------------------------------------------------------------*/
  5780   5728   static void nodeToXPath (
  5781   5729       domNode  * node,
  5782   5730       char    ** xpath,
  5783   5731       int      * xpathLen,
  5784         -    int      * xpathAllocated
         5732  +    int      * xpathAllocated,
         5733  +    int        legacy
  5785   5734   )
  5786   5735   {
  5787   5736       domNode *parent, *child;
  5788   5737       char    step[200], *nTest;
  5789   5738       int     sameNodes, nodeIndex, len;
  5790   5739   
  5791   5740   
  5792   5741       parent = node->parentNode;
  5793   5742       if (parent == NULL) {
  5794   5743           parent = node->ownerDocument->rootNode;
  5795   5744       } else {
  5796         -        nodeToXPath (parent, xpath, xpathLen, xpathAllocated);
         5745  +        nodeToXPath (parent, xpath, xpathLen, xpathAllocated, legacy);
  5797   5746       }
  5798   5747   
  5799   5748       step[0] = '\0';
  5800   5749       switch (node->nodeType) {
  5801   5750   
  5802   5751       case ELEMENT_NODE:
  5803   5752           nodeIndex = 0;
  5804   5753           sameNodes = 0;
  5805   5754           child = parent->firstChild;
  5806         -        while (child) {
  5807         -            if (strcmp(child->nodeName, node->nodeName)==0) {
  5808         -                sameNodes++;
  5809         -                if (node == child) nodeIndex = sameNodes;
  5810         -                if ((nodeIndex != 0) && (sameNodes > 2)) break;
         5755  +        if (node->namespace && !legacy) {
         5756  +            while (child) {
         5757  +                if (child->nodeType == ELEMENT_NODE) {
         5758  +                    sameNodes++;
         5759  +                    if (node == child) {
         5760  +                        nodeIndex = sameNodes;
         5761  +                        if (sameNodes > 1) break;
         5762  +                    }
         5763  +                }
         5764  +                child = child->nextSibling;
  5811   5765               }
  5812         -            child = child->nextSibling;
  5813         -        }
  5814         -        if (sameNodes == 1) {
  5815         -            sprintf(step, "/%s", node->nodeName);
         5766  +            if (sameNodes == 1) {
         5767  +                sprintf(step, "/*");
         5768  +            } else {
         5769  +                sprintf(step, "/*[%d]", nodeIndex);
         5770  +            }
  5816   5771           } else {
  5817         -            sprintf(step, "/%s[%d]", node->nodeName, nodeIndex);
         5772  +            while (child) {
         5773  +                if (strcmp(child->nodeName, node->nodeName)==0) {
         5774  +                    sameNodes++;
         5775  +                    if (node == child) nodeIndex = sameNodes;
         5776  +                    if ((nodeIndex != 0) && (sameNodes > 2)) break;
         5777  +                }
         5778  +                child = child->nextSibling;
         5779  +            }
         5780  +            if (sameNodes == 1) {
         5781  +                sprintf(step, "/%s", node->nodeName);
         5782  +            } else {
         5783  +                sprintf(step, "/%s[%d]", node->nodeName, nodeIndex);
         5784  +            }
  5818   5785           }
  5819   5786           break;
  5820   5787   
  5821   5788       case TEXT_NODE:
  5822   5789       case COMMENT_NODE:
  5823   5790       case PROCESSING_INSTRUCTION_NODE:
  5824   5791           nodeIndex = 0;
................................................................................
  5860   5827   
  5861   5828   
  5862   5829   /*----------------------------------------------------------------------------
  5863   5830   |   xpathNodeToXPath
  5864   5831   |
  5865   5832   \---------------------------------------------------------------------------*/
  5866   5833   char * xpathNodeToXPath (
  5867         -    domNode *node
         5834  +    domNode *node,
         5835  +    int      legacy
  5868   5836   )
  5869   5837   {
  5870   5838       char  * xpath;
  5871   5839       int     xpathLen, xpathAllocated;
  5872   5840   
  5873   5841   
  5874   5842       xpathAllocated = 100;
  5875   5843       xpathLen       = 0;
  5876   5844       xpath          = MALLOC(xpathAllocated + 1);
  5877   5845   
  5878         -    nodeToXPath (node, &xpath, &xpathLen, &xpathAllocated);
         5846  +    nodeToXPath (node, &xpath, &xpathLen, &xpathAllocated, legacy);
  5879   5847   
  5880   5848       return xpath;
  5881   5849   
  5882   5850   } /* xpathNodeToXPath */
  5883   5851   

Changes to generic/domxpath.h.

    71     71   |   Types for abstract syntax trees
    72     72   |
    73     73   \---------------------------------------------------------------------------*/
    74     74   typedef enum {
    75     75       Int, Real, Mult, Div, Mod, UnaryMinus, IsNSElement,
    76     76       IsNode, IsComment, IsText, IsPI, IsSpecificPI, IsElement,
    77     77       IsFQElement, GetVar, GetFQVar, Literal, ExecFunction, Pred,
    78         -    EvalSteps, SelectRoot, CombineSets, Add, Substract, Less,
           78  +    EvalSteps, SelectRoot, CombineSets, Add, Subtract, Less,
    79     79       LessOrEq, Greater, GreaterOrEq, Equal,  NotEqual, And, Or,
    80     80       IsNSAttr, IsAttr, AxisAncestor, AxisAncestorOrSelf, 
    81     81       AxisAttribute, AxisChild,
    82     82       AxisDescendant, AxisDescendantOrSelf, AxisFollowing,
    83     83       AxisFollowingSibling, AxisNamespace, AxisParent,
    84     84       AxisPreceding, AxisPrecedingSibling, AxisSelf,
    85     85       GetContextNode, GetParentNode, AxisDescendantOrSelfLit,
................................................................................
    93     93   
    94     94   
    95     95   typedef struct astElem {
    96     96       astType         type;
    97     97       struct astElem *child;
    98     98       struct astElem *next;
    99     99       char           *strvalue;
   100         -    int             intvalue;
          100  +    long            intvalue;
   101    101       double          realvalue;
   102    102   } astElem;
   103    103   
   104    104   typedef astElem *ast;
   105    105   
   106    106   
   107    107   /*----------------------------------------------------------------------------
................................................................................
   115    115   
   116    116   
   117    117   typedef struct xpathResultSet {
   118    118   
   119    119       xpathResultType type;
   120    120       char           *string;
   121    121       int             string_len;
   122         -    int             intvalue;
          122  +    long            intvalue;
   123    123       double          realvalue;          
   124    124       domNode       **nodes;
   125    125       int             nr_nodes;
   126    126       int             allocated;
   127    127   
   128    128   } xpathResultSet;
   129    129   
................................................................................
   194    194   double xpathFuncNumber   (xpathResultSet *rs, int *NaN);
   195    195   char * xpathFuncString   (xpathResultSet *rs); 
   196    196   char * xpathFuncStringForNode (domNode *node);
   197    197   int    xpathRound        (double r);
   198    198   
   199    199   char * xpathGetStringValue (domNode *node, int *strLen);
   200    200   
   201         -char * xpathNodeToXPath  (domNode *node);
          201  +char * xpathNodeToXPath  (domNode *node, int legacy);
   202    202       
   203         -void rsSetBool      ( xpathResultSet *rs, int          i    );
   204         -void rsSetInt       ( xpathResultSet *rs, int          i    );
          203  +void rsSetBool      ( xpathResultSet *rs, long         i    );
          204  +void rsSetInt       ( xpathResultSet *rs, long         i    );
   205    205   void rsSetReal      ( xpathResultSet *rs, double       d    );
   206    206   void rsSetString    ( xpathResultSet *rs, const char  *s    );
   207    207   void rsAddNode      ( xpathResultSet *rs, domNode     *node );
   208    208   void rsAddNodeFast  ( xpathResultSet *rs, domNode     *node );
   209    209   void rsCopy         ( xpathResultSet *to, xpathResultSet *from );
   210    210   
   211    211   /* This function is only used for debugging code */
   212    212   void rsPrint        ( xpathResultSet *rs );
   213    213   
   214    214   #endif
   215    215   

Changes to generic/domxslt.c.

    45     45   
    46     46   
    47     47   /*----------------------------------------------------------------------------
    48     48   |   Includes
    49     49   |
    50     50   \---------------------------------------------------------------------------*/
    51     51   #include <stdio.h>
    52         -#include <stdlib.h>
    53         -#include <string.h>
    54     52   #include <math.h>
    55     53   #include <limits.h>
    56         -#include <ctype.h>
    57     54   #include <locale.h>
    58     55   #include <dom.h>
    59     56   #include <domxpath.h>
    60     57   #include <domxslt.h>
    61     58   #include <tcl.h>         /* for hash tables */
    62     59   
    63     60   /*----------------------------------------------------------------------------
................................................................................
    64     61   |   Defines
    65     62   |
    66     63   \---------------------------------------------------------------------------*/
    67     64   #define XSLT_NAMESPACE  "http://www.w3.org/1999/XSL/Transform"
    68     65   #define INITIAL_SIZE_FOR_KEYSETS 10
    69     66   
    70     67   
           68  +/* #define DEBUG */
    71     69   /*----------------------------------------------------------------------------
    72         -|   Macros
           70  +|   Debug Macros
    73     71   |
    74     72   \---------------------------------------------------------------------------*/
           73  +#ifdef DEBUG
           74  +# define DBG(x) x
           75  +#else
           76  +# define DBG(x) 
           77  +#endif
    75     78   #define DBG(x)              
    76     79   #define TRACE(x)            DBG(fprintf(stderr,(x)))
    77     80   #define TRACE1(x,a)         DBG(fprintf(stderr,(x),(a)))
    78     81   #define TRACE2(x,a,b)       DBG(fprintf(stderr,(x),(a),(b)))
    79     82   #define TRACE3(x,a,b,c)     DBG(fprintf(stderr,(x),(a),(b),(c)))
    80     83   #define TRACE4(x,a,b,c,d)   DBG(fprintf(stderr,(x),(a),(b),(c),(d)))
    81     84   #define TRACE5(x,a,b,c,d,e) DBG(fprintf(stderr,(x),(a),(b),(c),(d),(e)))
    82     85   
           86  +/*----------------------------------------------------------------------------
           87  +|   Macros
           88  +|
           89  +\---------------------------------------------------------------------------*/
    83     90   #define CHECK_RC            if (rc < 0) return rc
    84     91   #define CHECK_RC1(x)        if (rc < 0) {FREE((char*)(x)); return rc;}
    85     92   #define SET_TAG(t,n,s,v)    if (strcmp(n,s)==0) { t->info = v; return v; }
    86     93   #define SETSCOPESTART       xs->varFramesStack[xs->varFramesStackPtr].stop=1
    87     94   #define SETPARAMDEF         xs->varFramesStack[xs->varFramesStackPtr].stop=2
    88     95   
    89     96   #if defined(_MSC_VER)
................................................................................
   194    201   |
   195    202   \-------------------------------------------------------------------------*/
   196    203   typedef struct xsltAttrSet {
   197    204   
   198    205       const char * name;
   199    206       const char * uri;
   200    207       domNode    * content;
   201         -
          208  +    int          inUse;
          209  +    
   202    210       struct xsltAttrSet *next;
   203    211   
   204    212   } xsltAttrSet;
   205    213   
   206    214   /*--------------------------------------------------------------------------
   207    215   |   xsltNodeSet
   208    216   |
................................................................................
   289    297   
   290    298   /*--------------------------------------------------------------------------
   291    299   |   xsltDecimalFormat
   292    300   |
   293    301   \-------------------------------------------------------------------------*/
   294    302   typedef struct xsltDecimalFormat
   295    303   {
   296         -#if TclOnly8Bits
   297         -    char   * name;
   298         -    char   * uri;
   299         -    char     decimalSeparator;
   300         -    char     groupingSeparator;
   301         -    char   * infinity;
   302         -    char     minusSign;
   303         -    char   * NaN;
   304         -    char     percent;
   305         -    char     zeroDigit;
   306         -    char     digit;
   307         -    char     patternSeparator;
   308         -#else 
   309    304       char        * name;
   310    305       char        * uri;
   311    306       Tcl_UniChar   decimalSeparator;
   312    307       Tcl_UniChar   groupingSeparator;
   313    308       char        * infinity;
   314    309       Tcl_UniChar   minusSign;
   315    310       char        * NaN;
   316    311       Tcl_UniChar   percent;
   317    312       Tcl_UniChar   perMille;
   318    313       Tcl_UniChar   zeroDigit;
   319    314       Tcl_UniChar   digit;
   320    315       Tcl_UniChar   patternSeparator;
   321         -#endif /* TclOnly8Bits */
   322    316   
   323    317       struct xsltDecimalFormat * next;
   324    318   
   325    319   } xsltDecimalFormat;
   326    320   
   327    321   
   328    322   /*--------------------------------------------------------------------------
................................................................................
   356    350   /*--------------------------------------------------------------------------
   357    351   |   xsltState
   358    352   |
   359    353   \-------------------------------------------------------------------------*/
   360    354   typedef struct {
   361    355   
   362    356       xsltTemplate      * templates;
          357  +    int                 nestedApplyTemplates;
          358  +    int                 maxNestedApplyTemplates;
   363    359       Tcl_HashTable       namedTemplates;
   364    360       Tcl_HashTable       isElementTpls;
   365    361       xsltWSInfo          wsInfo;
   366    362       domNode           * xmlRootNode;
   367    363       domDocInfo          doctype;
   368    364       int                 indentOutput;
   369    365       domDocument       * resultDoc;
................................................................................
   456    452   
   457    453   static domDocument * getExternalDocument (Tcl_Interp *interp, xsltState *xs,
   458    454                                             domDocument *xsltDoc, 
   459    455                                             const char *baseURI,
   460    456                                             const char *href, int isStylesheet,
   461    457                                             int fixedXMLSource, char **errMsg);
   462    458   
   463         -
          459  +#ifdef DEBUG
   464    460   /*----------------------------------------------------------------------------
   465    461   |   printXML
   466    462   |
   467    463   \---------------------------------------------------------------------------*/
   468    464   static void printXML (domNode *node, int level, int maxlevel) {
   469    465   
   470    466       domTextNode *tnode;
................................................................................
   530    526               fprintf(stderr, "%s?>\n", tmp);
   531    527           }
   532    528           node = node->nextSibling;
   533    529           n++;
   534    530           if (n>8) { fprintf(stderr, "...\n"); return; }
   535    531       }
   536    532   }
   537         -        
          533  +#endif /* #ifdef DEBUG */
          534  +
   538    535   /*----------------------------------------------------------------------------
   539    536   |   reportError
   540    537   |
   541    538   \---------------------------------------------------------------------------*/
   542    539   static void
   543    540   reportError (
   544    541       domNode * node,
................................................................................
   748    745       domDocument * extDocument;
   749    746       int           found;
   750    747   
   751    748       DBG(
   752    749           fprintf (stderr, "xsltAddExternalDocument: baseURI '%s'\n", baseURI);
   753    750           fprintf (stderr, "xsltAddExternalDocument: systemID '%s'\n", str);
   754    751       )
   755         -
   756    752       found = 0;
   757    753       sdoc = xs->subDocs;
   758    754       if (str) {
   759    755           while (sdoc) {
   760    756               if (!sdoc->isStylesheet
   761    757                   && sdoc->baseURI 
   762    758                   && strcmp (sdoc->baseURI, str)==0) {
................................................................................
   765    761                   break;
   766    762               }
   767    763               sdoc = sdoc->next;
   768    764           }
   769    765       }
   770    766       if (!found) {
   771    767           if (!xs->xsltDoc->extResolver) {
   772         -            *errMsg = tdomstrdup("need resolver Script to include Stylesheet! "
   773         -                                 "(use \"-externalentitycommand\")");
          768  +            *errMsg = tdomstrdup("Need resolver script for document() calls. "
          769  +                                 "(Use \"-externalentitycommand\")");
   774    770               return -1;
   775    771           }
   776    772           extDocument = getExternalDocument (
   777    773                            (Tcl_Interp*)xs->orig_funcClientData,
   778    774                            xs, xs->xsltDoc, baseURI, str, 0, fixedXMLSource,
   779    775                            errMsg);
   780    776           if (extDocument) {
................................................................................
   817    813           Tcl_SetHashValue (h, format);
   818    814           format->formatStr = p = Tcl_GetHashKey (&(xs->formats), h);
   819    815       }
   820    816       while (*p) {
   821    817           clen = UTF8_CHAR_LEN(*p);
   822    818           if (!clen) {
   823    819               reportError (xs->currentXSLTNode, "xsl:number: UTF-8 form of"
   824         -                         " character longer than 3 Byte", errMsg);
          820  +                         " character longer than 4 Byte", errMsg);
   825    821               return NULL;
   826    822           }
   827    823           if (clen > 1) {
   828    824               /* hack: skip over multibyte chars - this may be wrong */
   829    825               format->prologLen += clen;
   830    826               p += clen;
   831    827               continue;
................................................................................
   845    841       p++;                                         \
   846    842       if (*p) {                                    \
   847    843           format->tokens[nrOfTokens].sepStart = p; \
   848    844       }                                            \
   849    845       while (*p) {                                 \
   850    846           clen = UTF8_CHAR_LEN(*p);                \
   851    847           if (!clen) {                             \
   852         -            reportError (xs->currentXSLTNode, "xsl:number: UTF-8 form of character longer than 3 Byte", errMsg); \
          848  +            reportError (xs->currentXSLTNode, "xsl:number: UTF-8 form of character longer than 4 Byte", errMsg); \
   853    849               return NULL;                         \
   854    850           }                                        \
   855    851           if (clen > 1) {                          \
   856    852               /* hack: skip over multibyte chars - this may be wrong */ \
   857    853               format->tokens[nrOfTokens].sepLen += clen;  \
   858    854               p += clen;                           \
   859    855               continue;                            \
................................................................................
   928    924   static void formatValue (
   929    925       xsltNumberFormat *f,
   930    926       int              *useFormatToken,
   931    927       int               value,
   932    928       Tcl_DString      *str,
   933    929       char             *groupingSeparator,
   934    930       long              groupingSize,
   935         -    int               addSeperater
          931  +    int               addSeparater
   936    932   )
   937    933   {
   938    934       int         len, fulllen, gslen, upper = 0, e, m, b, i, z, v;
   939    935       char        tmp[80], *pt;
   940    936       Tcl_DString tmp1;
   941    937       static struct { char *digit; char *ldigit; int value; } RomanDigit[] = {
   942    938             { "M" , "m" , 1000, },
................................................................................
  1076   1072       default:
  1077   1073           sprintf (tmp, "%d", value);
  1078   1074           break;
  1079   1075       }
  1080   1076       len = strlen (tmp);
  1081   1077       Tcl_DStringAppend (str, tmp, len);
  1082   1078    appendSeperator:
  1083         -    if (addSeperater) {
         1079  +    if (addSeparater) {
  1084   1080           if (f->tokens[*useFormatToken].sepStart) {
  1085   1081               Tcl_DStringAppend (str, f->tokens[*useFormatToken].sepStart,
  1086   1082                                  f->tokens[*useFormatToken].sepLen);
  1087   1083               *useFormatToken += 1;
  1088   1084           } else {
  1089   1085               if (*useFormatToken > 0) {
  1090   1086                   Tcl_DStringAppend (str, f->tokens[*useFormatToken-1].sepStart,
  1091   1087                                      f->tokens[*useFormatToken-1].sepLen);
  1092   1088               } else {
  1093         -                /* insert default seperator '.' */
         1089  +                /* insert default separator '.' */
  1094   1090                   Tcl_DStringAppend (str, ".", 1);
  1095   1091               }
  1096   1092           }
  1097   1093       }
  1098   1094   
  1099   1095       return;
  1100   1096   }
  1101   1097   
  1102   1098   /*----------------------------------------------------------------------------
  1103   1099   |   xsltFormatNumber
  1104   1100   |
  1105   1101   \---------------------------------------------------------------------------*/
  1106         -#if TclOnly8Bits
  1107         -static int xsltFormatNumber (
  1108         -    double              number,
  1109         -    char              * formatStr,
  1110         -    xsltDecimalFormat * df,
  1111         -    char             ** resultStr,
  1112         -    int               * resultLen,
  1113         -    char             ** errMsg
  1114         -)
  1115         -{
  1116         -    char *p, prefix[800], suffix[800], s[2400], n[800], f[800];
  1117         -    char *negformat = NULL, save = '\0', save1;
  1118         -    int i, l, zl, g, nHash, nZero, fHash, fZero, gLen, isNeg;
  1119         -/*      struct lconv *lc = NULL;  */
  1120         -    char wrongFormat[] = "Unable to interpret format pattern.";
  1121         -
  1122         -    DBG(fprintf(stderr, "\nformatStr='%s' \n", formatStr);)
  1123         -    if (number < 0.0) {
  1124         -        isNeg = 1;
  1125         -        number *= -1.0;
  1126         -    } else {
  1127         -        isNeg = 0;
  1128         -    }
  1129         -    p = formatStr;
  1130         -    while (*p) {
  1131         -        if (*p == df->patternSeparator) {
  1132         -            *p = '\0';
  1133         -            negformat = ++p;
  1134         -            break;
  1135         -        }
  1136         -        p++;
  1137         -    }
  1138         -    /* Check for more than one patternSeparator in the formatStr */
  1139         -    while (*p) {
  1140         -        if (*p == df->patternSeparator) {
  1141         -            *errMsg = tdomstrdup(wrongFormat);
  1142         -            return -1;
  1143         -        }
  1144         -        p++;
  1145         -    }
  1146         -    p = formatStr;
  1147         -
  1148         -    i = 0;
  1149         -    while (*p 
  1150         -           && (*p!=df->zeroDigit) 
  1151         -           && (*p!=df->digit) 
  1152         -           && (*p!=df->groupingSeparator) 
  1153         -           && (*p!=df->decimalSeparator)) {
  1154         -        if (i<79) { prefix[i++] = *p; }
  1155         -        p++;
  1156         -    }
  1157         -    prefix[i] = '\0';
  1158         -    nHash = nZero = fHash = fZero = 0;
  1159         -    gLen = -2222;
  1160         -    while (*p) {
  1161         -             if (*p==df->digit) {
  1162         -                 if (nZero) {*errMsg = tdomstrdup(wrongFormat); return -1;}
  1163         -                 nHash++;}
  1164         -        else if (*p==df->zeroDigit) { nZero++; }
  1165         -        else if (*p==df->groupingSeparator) { gLen=-1; }
  1166         -        else break;
  1167         -        p++; gLen++;
  1168         -    }
  1169         -    if (*p && (*p==df->decimalSeparator)) {
  1170         -        p++;
  1171         -        while (*p && (*p==df->zeroDigit)) { p++; fZero++; }
  1172         -        while (*p && (*p==df->digit)) { p++; fHash++; }
  1173         -    }
  1174         -    i = 0;
  1175         -    while (*p) {
  1176         -        if (i<79) { suffix[i++] = *p; }
  1177         -        p++;
  1178         -    }
  1179         -    suffix[i] = '\0';
  1180         -    if (save) *p = save;
  1181         -
  1182         -    if (isNeg && negformat) {
  1183         -        /* Only prefix and suffix are taken from the second format string */
  1184         -        p++;
  1185         -        i = 0;
  1186         -        while (*p 
  1187         -               && *p!=df->zeroDigit
  1188         -               && *p!=df->digit 
  1189         -               && *p!=df->groupingSeparator 
  1190         -               && *p!=df->decimalSeparator) {
  1191         -            if (i<79) { prefix[i++] = *p; }
  1192         -            p++;
  1193         -        }
  1194         -        prefix[i] = '\0';
  1195         -        while (*p 
  1196         -               && ((*p==df->zeroDigit) 
  1197         -                   || (*p==df->digit) 
  1198         -                   || (*p==df->groupingSeparator) 
  1199         -                   || (*p==df->decimalSeparator))) p++;
  1200         -        i = 0;
  1201         -        while (*p) {
  1202         -            if (i<79) { suffix[i++] = *p; }
  1203         -            p++;
  1204         -        }
  1205         -        suffix[i] = '\0';
  1206         -    }
  1207         -
  1208         -    if (isNeg) {
  1209         -        if (negformat) {
  1210         -            if (prefix[0]=='\0' && suffix[0]=='\0') {
  1211         -                prefix[0] = df->minusSign;
  1212         -                prefix[1] = '\0';
  1213         -            }
  1214         -        } else {
  1215         -            i = 0;
  1216         -            save = prefix[0];
  1217         -            prefix[0] = df->minusSign;
  1218         -            while (i < 79) {
  1219         -                i++;
  1220         -                if (save == '\0') {
  1221         -                    prefix[i] = save;
  1222         -                    break;
  1223         -                }
  1224         -                save1 = prefix[i];
  1225         -                prefix[i] = save;
  1226         -                save = save1;
  1227         -            }
  1228         -            if (i == 79) prefix[79] = '\0';
  1229         -        }
  1230         -    }
  1231         -    if (prefix[0]=='\xc2' && prefix[1]=='\xa4') {
  1232         -/*          lc = localeconv(); */
  1233         -/*          if (strlen (lc->currency_symbol) > 79 */
  1234         -/*              || lc->currency_symbol[0] == '\0') { */
  1235         -            prefix[0] = '$';
  1236         -            prefix[1] = '\0';
  1237         -/*          } else { */
  1238         -/*              strcpy (prefix, lc->currency_symbol); */
  1239         -/*          } */
  1240         -    }
  1241         -
  1242         -    if (suffix[0] == df->percent) {
  1243         -        number *= 100.0;
  1244         -    } else 
  1245         -    if (suffix[0]=='\xe2' && suffix[1]=='\x80' && suffix[2]=='\xb0') {
  1246         -        number *= 1000.0;
  1247         -    }
  1248         -    
  1249         -    if (fHash + fZero == 0) {
  1250         -        i = (int) (number+0.5);
  1251         -    } else {
  1252         -        i = (int) number;
  1253         -    }
  1254         -    DBG(fprintf(stderr,"normal part nZero=%d i=%d glen=%d\n", nZero, i, gLen);)
  1255         -    /* fill in grouping char */
  1256         -    if (gLen > 0) {
  1257         -        if (i < 0.0) {isNeg = 1; i *= -1;}
  1258         -        else isNeg = 0;
  1259         -        sprintf(s,"%0*d", nZero, i);
  1260         -        l = strlen(s);
  1261         -        /* if (l > (nHash+nZero)) { l = nHash+nZero; } */
  1262         -        DBG(fprintf(stderr,"s='%s isNeg=%d'\n", s, isNeg);)
  1263         -        zl = l + ((l-1) / gLen);
  1264         -        DBG(fprintf(stderr, "l=%d zl=%d \n", l, zl);)
  1265         -        n[zl--] = '\0';
  1266         -        p = s + strlen(s) -1;
  1267         -        g = 0;
  1268         -        while (zl>=0) {
  1269         -            g++;
  1270         -            n[zl--] = *p--;
  1271         -            if ((g == gLen) && (zl>=1)) {
  1272         -                n[zl--] = df->groupingSeparator;
  1273         -                g = 0;
  1274         -            }
  1275         -        }
  1276         -        DBG(fprintf(stderr,"s='%s' --> n='%s'\n", s, n);)
  1277         -
  1278         -    } else {
  1279         -        sprintf(n,"%0*d", nZero, i);
  1280         -        DBG(fprintf(stderr,"n='%s'\n", n);)
  1281         -    }
  1282         -
  1283         -    DBG(fprintf(stderr, "number=%f Hash=%d fZero=%d \n", number, fHash, fZero);)
  1284         -    if ((fHash+fZero) > 0) {
  1285         -        i = (int) number;
  1286         -        /* format fraction part */
  1287         -        if (number >= 0.0) {
  1288         -            sprintf(f,"%0.*f", fZero+fHash, number -i);
  1289         -        } else {
  1290         -            sprintf(f,"%0.*f", fZero+fHash, -1.0 * (number -i) );
  1291         -        }
  1292         -        l = strlen(f);
  1293         -        while (l>0 && fHash>0) {   /* strip not need 0's */
  1294         -            if (f[l-1] == '0') {
  1295         -                f[l-1]='\0'; l--; fHash--;
  1296         -            } else {
  1297         -                break;
  1298         -            }
  1299         -        }
  1300         -        DBG(fprintf(stderr, "f='%s'\n", f);)
  1301         -        sprintf(s,"%s%s%c%s%s", prefix, n, df->decimalSeparator, &(f[2]), suffix);
  1302         -    } else {
  1303         -        sprintf(s,"%s%s%s", prefix, n, suffix);
  1304         -    }
  1305         -    DBG(fprintf(stderr, "returning s='%s' \n\n", s);)
  1306         -    *resultStr = tdomstrdup(s);
  1307         -    *resultLen = strlen(s);
  1308         -    return 0;
  1309         -}
  1310         -
  1311         -#else
  1312         -
  1313   1102   static int addCurrencySymbol (
  1314   1103       Tcl_UniChar  *p,
  1315   1104       Tcl_UniChar  *result,
  1316   1105       int          *i
  1317   1106   )
  1318   1107   {
  1319   1108       Tcl_DString dStr;
................................................................................
  1357   1146       int               * resultLen,
  1358   1147       char             ** errMsg
  1359   1148   )
  1360   1149   {
  1361   1150       Tcl_UniChar prefix1[800], prefix2[800], suffix1[800], suffix2[800];
  1362   1151       Tcl_UniChar save = '\0', save1, t, *prefix, *suffix, n[800], f[800];
  1363   1152       Tcl_UniChar uniCharNull = '\0';
  1364         -    char stmp[240], ftmp[80];
         1153  +    char stmp[240], ftmp[80], *tstr;
  1365   1154       char wrongFormat[] = "Unable to interpret format pattern.";
  1366   1155       int i, j, k, l, zl, g, nHash, nZero, fHash, fZero, gLen, isNeg;
  1367   1156       int prefixMinux, percentMul = 0, perMilleMul = 0;
  1368   1157       Tcl_DString  dStr, s;
  1369   1158       Tcl_UniChar *format, *negformat = NULL, *p, *p1;
  1370   1159       DBG(Tcl_DString dbStr;)
  1371   1160   
................................................................................
  1586   1375       }
  1587   1376       
  1588   1377       if (fHash + fZero == 0) {
  1589   1378           i = (int) (number+0.5);
  1590   1379       } else {
  1591   1380           i = (int) number;
  1592   1381           /* format fraction part */
  1593         -        DBG(fprintf(stderr, "formating fraction part: '%f', fZero+fHash: '%d'\n",
         1382  +        DBG(fprintf(stderr, "formatting fraction part: '%f', fZero+fHash: '%d'\n",
  1594   1383                       number - i, fZero+fHash);)
  1595   1384           sprintf(ftmp,"%.*f", fZero+fHash, number -i);
  1596         -        DBG(fprintf(stderr, "raw formated fraction part: '%s'\n", ftmp);)
         1385  +        DBG(fprintf(stderr, "raw formatted fraction part: '%s'\n", ftmp);)
  1597   1386           if (ftmp[0] == '1') {
  1598   1387               i++;
  1599   1388           }
  1600   1389       }
  1601   1390       
  1602   1391       DBG(fprintf(stderr,"normal part nZero=%d i=%d glen=%d\n", nZero, i, gLen);)
  1603   1392       /* fill in grouping char */
................................................................................
  1718   1507                   Tcl_UniCharToUtfDString(
  1719   1508                       (Tcl_UniChar*)Tcl_DStringValue (&s),
  1720   1509                       Tcl_UniCharLen((Tcl_UniChar*)Tcl_DStringValue(&s)), &dStr
  1721   1510                       ));
  1722   1511           Tcl_DStringFree (&dbStr);
  1723   1512       )
  1724   1513       Tcl_DStringSetLength (&dStr, 0);
  1725         -    *resultStr = tdomstrdup(
  1726         -        Tcl_UniCharToUtfDString(
  1727         -            (Tcl_UniChar*)Tcl_DStringValue (&s),
  1728         -            Tcl_UniCharLen((Tcl_UniChar*)Tcl_DStringValue(&s)), &dStr
  1729         -            )
         1514  +    tstr = Tcl_UniCharToUtfDString(
         1515  +        (Tcl_UniChar*)Tcl_DStringValue (&s),
         1516  +        Tcl_UniCharLen((Tcl_UniChar*)Tcl_DStringValue(&s)), &dStr
  1730   1517           );
         1518  +    *resultStr = tdomstrdup(tstr);
  1731   1519       Tcl_DStringFree (&dStr);
  1732   1520       Tcl_DStringFree (&s);
  1733   1521       *resultLen = strlen(*resultStr);
  1734   1522       return 0;
  1735   1523   
  1736   1524    xsltFormatNumberError:
  1737   1525       Tcl_DStringFree (&dStr);
  1738   1526       Tcl_DStringFree (&s);
  1739   1527       return -1;
  1740   1528   }
  1741         -
  1742         -#endif /* TclOnly8Bits */
  1743         -
  1744   1529   
  1745   1530   static xsltNodeSet *
  1746         -createXsltNodeSet () 
         1531  +createXsltNodeSet (void) 
  1747   1532   {
  1748   1533       xsltNodeSet * ns;
  1749   1534   
  1750   1535       ns = (xsltNodeSet *) MALLOC (sizeof(xsltNodeSet));
  1751   1536       ns->nodes = (domNode**)MALLOC(INITIAL_SIZE_FOR_KEYSETS * sizeof(domNode*));
  1752   1537       ns->allocated = INITIAL_SIZE_FOR_KEYSETS;
  1753   1538       ns->nr_nodes = 0;
................................................................................
  1882   1667               }
  1883   1668               kinfo = kinfo->next;
  1884   1669           }
  1885   1670           if ((node->nodeType == ELEMENT_NODE) && (node->firstAttr)) {
  1886   1671               node = (domNode*) node->firstAttr;
  1887   1672               continue;
  1888   1673           }
  1889         -        if ((node->nodeType == ATTRIBUTE_NODE)) {
         1674  +        if (node->nodeType == ATTRIBUTE_NODE) {
  1890   1675               if (((domAttrNode*)node)->nextSibling) {
  1891   1676                   node = (domNode*) ((domAttrNode*)node)->nextSibling;
  1892   1677                   continue;
  1893   1678               }
  1894   1679               node = ((domAttrNode*)node)->parentNode;
  1895   1680           }
  1896   1681           if ((node->nodeType == ELEMENT_NODE) && (node->firstChild)) {
................................................................................
  2507   2292       char      * strB,
  2508   2293       double      realA,
  2509   2294       double      realB,
  2510   2295       int       * greater
  2511   2296   )
  2512   2297   {
  2513   2298       int             rc;
  2514         -#if TclOnly8Bits == 0
  2515   2299       char           *strAptr, *strBptr;
  2516   2300       int             lenA, lenB, len;
  2517   2301       Tcl_UniChar     unicharA, unicharB;
  2518         -#endif
  2519   2302   
  2520   2303       *greater = 0;
  2521   2304   
  2522   2305       if (typeText) {
  2523         -
  2524         -#if TclOnly8Bits
  2525         -        /* TODO: this only works for 7 bit ASCII */
  2526         -        rc = STRCASECMP(strA, strB);
  2527         -        if (rc == 0) {
  2528         -            rc = strcmp (strA, strB);
  2529         -            if (!upperFirst) {
  2530         -                rc *= -1;
  2531         -            }
  2532         -        }
  2533         -DBG(   fprintf(stderr, "nodeGreater %d <-- strA='%s' strB='%s'\n", rc, strA, strB);)
  2534         -#else
  2535   2306           lenA = Tcl_NumUtfChars (strA, -1);
  2536   2307           lenB = Tcl_NumUtfChars (strB, -1);
  2537   2308           len = (lenA < lenB ? lenA : lenB);
  2538   2309           rc = Tcl_UtfNcasecmp (strA, strB, len);
  2539   2310           if (rc == 0) {
  2540   2311               if (lenA > lenB) {
  2541   2312                   rc = 1;
................................................................................
  2554   2325                       break;
  2555   2326                   }
  2556   2327               }
  2557   2328               if (!upperFirst) {
  2558   2329                   rc *= -1;
  2559   2330               }
  2560   2331           }
  2561         -#endif
  2562   2332           if (asc) *greater = (rc > 0);
  2563   2333               else *greater = (rc < 0);
  2564   2334   
  2565   2335       } else {
  2566   2336   DBG(   fprintf(stderr, "nodeGreater  realA='%f' realB='%f'\n",realA, realB);)
  2567   2337           if (IS_NAN (realA) || IS_NAN (realB)) {
  2568   2338               if (asc) {
................................................................................
  2675   2445               b    [i] = a   [lptr  ];
  2676   2446               posb [i] = posa[lptr  ];
  2677   2447               vstmp[i] = vs  [lptr  ];
  2678   2448               vdtmp[i] = vd  [lptr++];
  2679   2449           }
  2680   2450       }
  2681   2451       memcpy(a,    b,     size*sizeof(domNode*));
  2682         -    memcpy(posa, posb,  size*sizeof(int*));
         2452  +    memcpy(posa, posb,  size*sizeof(int));
  2683   2453       memcpy(vs,   vstmp, size*sizeof(char*));
  2684   2454       memcpy(vd,   vdtmp, size*sizeof(double));
  2685   2455       return 0;
  2686   2456   }
  2687   2457   
  2688   2458   static int sortNodeSetFastMerge(
  2689   2459       int         txt,
................................................................................
  2750   2520                           errMsg);
  2751   2521           CHECK_RC;
  2752   2522       } else {
  2753   2523           if (!actionNode->firstChild) {
  2754   2524               xpathRSInit (&rs);
  2755   2525               rsSetString (&rs, "");
  2756   2526           } else {
  2757         -            fragmentNode = domNewElementNode(xs->resultDoc, "",
  2758         -                                             ELEMENT_NODE);
         2527  +            fragmentNode = domNewElementNode(xs->resultDoc, "");
  2759   2528               savedLastNode = xs->lastNode;
  2760   2529               xs->lastNode = fragmentNode;
  2761   2530               /* process the children as well */
  2762   2531               xsltPushVarFrame (xs);
  2763   2532               rc = ExecActions(xs, context, currentNode, currentPos,
  2764   2533                                actionNode->firstChild, errMsg);
  2765   2534               xsltPopVarFrame (xs);
................................................................................
  2943   2712               CHECK_RC;
  2944   2713               rc = xsltGetVar (xs, variableName, varURI, result, errMsg);
  2945   2714               CHECK_RC;
  2946   2715               /* remove var out of the varsInProcess list. Should be first
  2947   2716                  in the list, shouldn't it? */
  2948   2717               varInProcess = xs->varsInProcess;
  2949   2718               if (varInProcess != &thisVarInProcess) {
  2950         -                domPanic ("error in top level vars processing");
         2719  +                reportError (topLevelVar->node, "Error in top level"
         2720  +                             " vars processing.", errMsg);
         2721  +                return XPATH_EVAL_ERR;
  2951   2722               }
  2952   2723               xs->varsInProcess = varInProcess->next;
  2953   2724               xs->currentXSLTNode = savedCurrentXSLTNode;
  2954   2725               return XPATH_OK;
  2955   2726           }
  2956   2727       }
  2957   2728       Tcl_DStringInit (&dErrMsg);
................................................................................
  3170   2941               reportError (node, "A template without a \"match\" attribute must"
  3171   2942                            " not have a \"mode\" attribute.", errMsg);
  3172   2943               rc = -1;
  3173   2944           }
  3174   2945           domSplitQName (str, prefix, &localName);
  3175   2946           if (prefix[0] != '\0') {
  3176   2947               ns = domLookupPrefix (node, prefix);
  3177         -            if (!ns) {
         2948  +            if (ns) {
         2949  +                tpl->modeURI = ns->uri;
         2950  +            } else {
  3178   2951                   reportError (node, "The prefix of the \"mode\" attribute value"
  3179   2952                                " isn't bound to a namespace.", errMsg);
  3180   2953                   rc = -1;
  3181   2954               }
  3182         -            tpl->modeURI = ns->uri;
  3183   2955           }
  3184   2956           tpl->mode = localName;
  3185   2957           if (rc < 0) {
  3186   2958               /* If the template has a name attribute, it is already stored in
  3187   2959                  in the namedTemplates hash table and will be freed. */
  3188   2960               if (!tpl->name) {
  3189   2961                   FREE ((char*)tpl);
................................................................................
  3204   2976       sDoc = xs->subDocs;
  3205   2977       while (sDoc) {
  3206   2978           if (sDoc->doc == node->ownerDocument) break;
  3207   2979           sDoc = sDoc->next;
  3208   2980       }
  3209   2981       tpl->sDoc = sDoc;
  3210   2982       
  3211         -    TRACE1("compiling XPATH '%s' ...\n", tpl->match);
         2983  +    TRACE1("compiling XPath '%s' ...\n", tpl->match);
  3212   2984       if (tpl->match) {
  3213   2985           rc = xpathParse(tpl->match, node, XPATH_TEMPMATCH_PATTERN, NULL, NULL,
  3214   2986                           &(tpl->freeAst), errMsg);
  3215   2987           if (rc < 0) {
  3216   2988               reportError (node, *errMsg, errMsg);
  3217   2989           } else {
  3218   2990               rc = addMatch (xs, node, tpl, prioStr, tpl->freeAst, errMsg);
................................................................................
  3222   2994                   /* The template is already stored in the namedTemplates
  3223   2995                      hash table. Therefor we don't free tpl here, but
  3224   2996                      set tpl->match to NULL, which ensures, that the
  3225   2997                      tpl will be freed while the namedTemplates hash table
  3226   2998                      is cleand up. */
  3227   2999                   tpl->match = NULL;
  3228   3000               } else {
  3229         -                free ((char*)tpl);
         3001  +                FREE ((char*)tpl);
  3230   3002               }
  3231   3003               return rc;
  3232   3004           }
  3233   3005       }
  3234   3006   
  3235   3007       return 0;
  3236   3008   }
................................................................................
  3279   3051                           if (strcmp (ns->uri, attrSet->uri)==0) {
  3280   3052                               if (strcmp (attrSet->name, localName)==0) rc = 1;
  3281   3053                           }
  3282   3054                       }
  3283   3055                   }
  3284   3056               }
  3285   3057               if (rc) {
         3058  +                if (attrSet->inUse) {
         3059  +                    attrSet->inUse = 0;
         3060  +                    *pc = save;
         3061  +                    reportError(actionNode, "Circular reference "
         3062  +                                "to attribute set", errMsg);
         3063  +                    return -1;
         3064  +                }
         3065  +                attrSet->inUse = 1;
  3286   3066                   str = getAttr (attrSet->content, "use-attribute-sets",
  3287   3067                                  a_useAttributeSets);
  3288   3068                   if (str) {
  3289   3069                       rc = ExecUseAttributeSets (xs, context, currentNode,
  3290   3070                                                  currentPos, attrSet->content,
  3291   3071                                                  str, errMsg);
  3292         -                    CHECK_RC;
         3072  +                    if (rc < 0) {
         3073  +                        attrSet->inUse = 0;
         3074  +                        *pc = save;
         3075  +                        return rc;
         3076  +                    }
  3293   3077                   }
  3294   3078                   rc = ExecActions(xs, context, currentNode, currentPos,
  3295   3079                                    attrSet->content->firstChild, errMsg);
  3296         -                CHECK_RC;
         3080  +                attrSet->inUse = 0;
         3081  +                if (rc < 0) {
         3082  +                    attrSet->inUse = 0;
         3083  +                    *pc = save;
         3084  +                    return rc;
         3085  +                }
  3297   3086               }
  3298   3087               attrSet = attrSet->next;
  3299   3088           }
  3300   3089           *pc = save;
  3301   3090       }
  3302   3091       return 0;
  3303   3092   }
................................................................................
  3466   3255       xpathResultSet  * context,
  3467   3256       domNode         * currentNode,
  3468   3257       int               currentPos,
  3469   3258       char           ** errMsg
  3470   3259   )
  3471   3260   {
  3472   3261       domNode       *child;
  3473         -    char          *str, *evStr, *select, *lang;
         3262  +    char          *str, *evStr, *select;
         3263  +    /* todo */
         3264  +    /* char       *lang; */
  3474   3265       char         **vs = NULL;
  3475   3266       char           prefix[MAX_PREFIX_LEN];
  3476   3267       const char    *localName;
  3477   3268       double        *vd = NULL;
  3478   3269       int            rc = 0, typeText, ascending, upperFirst, *pos = NULL, i, NaN;
  3479   3270       xpathResultSet rs;
  3480   3271   
................................................................................
  3546   3337                           FREE(evStr);
  3547   3338                           rc = -1;
  3548   3339                           break;
  3549   3340                       }
  3550   3341                       FREE(evStr);
  3551   3342                   }
  3552   3343                   /* jcl: TODO */
  3553         -                lang = getAttr(child, "lang", a_lang);
         3344  +                /* lang = getAttr(child, "lang", a_lang); */
         3345  +                /* The getAttr call should be done, to set attr->info
         3346  +                   to the attribute type for faster checks in further
         3347  +                   runs */
         3348  +                getAttr(child, "lang", a_lang);
  3554   3349   
  3555   3350                   TRACE4("sorting with '%s' typeText %d ascending %d nodeSetLen=%d\n",
  3556   3351                          select, typeText, ascending, nodelist->nr_nodes);
  3557   3352                   CHECK_RC;
  3558   3353                   if (!pos)
  3559   3354                       pos = (int*)MALLOC(sizeof(int) * nodelist->nr_nodes);
  3560   3355                   for (i=0; i<nodelist->nr_nodes;i++) pos[i] = i;
................................................................................
  3667   3462           TRACE2("xsltNumber value='%s' format='%s' \n", value, format);
  3668   3463           rc = evalXPath(xs, context, currentNode, currentPos,
  3669   3464                          value, &rs, errMsg);
  3670   3465           if (rc < 0) goto xsltNumberError;
  3671   3466           vVals = 1;
  3672   3467           v[0] = xpathRound(xpathFuncNumber( &rs, &NaN ));
  3673   3468           /* MARK recoverable error */
  3674         -        /* This is one of the not so satisfying corners of the xslt
         3469  +        /* This is one of the not so satisfying corners of the XSLT
  3675   3470            * rec. The rec doesn't say, what to do, if the value isn't a
  3676   3471            * (finit) number. E24 from the erratas doesn't makes things
  3677   3472            * much better - a little bit dubious wording and a not very
  3678   3473            * convincing decision. Well, at least saxon seems to follow
  3679   3474            * the words of E24. I'll postpone this topic. */
  3680   3475           if (NaN) v[0] = 0;
  3681   3476           xpathRSFree( &rs );
................................................................................
  3919   3714       xsltExclExtNS  *eNS;
  3920   3715       xsltNSAlias    *nsAlias;
  3921   3716       Tcl_DString     dStr;
  3922   3717       domProcessingInstructionNode *pi;
  3923   3718       xpathResultSet  rs, nodeList;
  3924   3719       char           *str, *str2, *select, *pc, *nsAT, *out;
  3925   3720       const char     *mode, *modeURI, *localName, *uri, *nsStr;
  3926         -    char            prefix[MAX_PREFIX_LEN];
         3721  +    char            prefix[MAX_PREFIX_LEN], tmpErr[200];
  3927   3722       int             rc, b, i, len, terminate, chooseState, disableEsc = 0;
  3928   3723       double          currentPrio, currentPrec;
  3929   3724       Tcl_HashEntry  *h;
  3930   3725   
  3931   3726       if (actionNode->nodeType == TEXT_NODE) {
  3932   3727           domAppendNewTextNode(xs->lastNode,
  3933   3728                                ((domTextNode*)actionNode)->nodeValue,
................................................................................
  3984   3779                                          Tcl_DStringValue (&dStr));
  3985   3780                   Tcl_DStringFree (&dStr);
  3986   3781   
  3987   3782                   if (h) {
  3988   3783                       for (tpl = (xsltTemplate *) Tcl_GetHashValue (h);
  3989   3784                            tpl != NULL;
  3990   3785                            tpl = tpl->next) {
  3991         -                        if (tpl->precedence > xs->currentTplRule->precedence
         3786  +                        if (tpl->precedence >= xs->currentTplRule->precedence
  3992   3787                               || tpl == xs->currentTplRule) continue;
  3993         -                        TRACE3("find element tpl match='%s' mode='%s' name='%s'\n",
         3788  +                        TRACE3("testing element tpl match='%s' mode='%s' name='%s'\n",
  3994   3789                                  tpl->match, tpl->mode, tpl->name);
  3995   3790                           TRACE4("tpl has prio='%f' precedence='%f'\n", tpl->prio, tpl->precedence, currentPrio, currentPrec);
  3996   3791                           rc = xpathMatches ( tpl->ast, actionNode, currentNode,
  3997   3792                                               &(xs->cbs), errMsg);
  3998   3793                           if (rc < 0) {
  3999   3794                               TRACE1("xpathMatches had errors '%s' \n", *errMsg);
  4000   3795                               return rc;
................................................................................
  4007   3802                           break;
  4008   3803                       }
  4009   3804                   }
  4010   3805               }
  4011   3806   
  4012   3807               TRACE2("apply-imports: current template precedence='%f' mode='%s'\n", xs->currentTplRule->precedence, xs->currentTplRule->mode);
  4013   3808               for (tpl = xs->templates; tpl != NULL; tpl = tpl->next) {
  4014         -                TRACE4("find tpl match='%s' mode='%s' modeURI='%s' name='%s'\n",
         3809  +                TRACE4("testing tpl match='%s' mode='%s' modeURI='%s' name='%s'\n",
  4015   3810                          tpl->match, tpl->mode, tpl->modeURI, tpl->name);
  4016   3811                   /* exclude those, which don't match the current mode
  4017   3812                      and the currentTplRule */
  4018   3813                   if (   ( mode && !tpl->mode)
  4019   3814                          || (!mode &&  tpl->mode)
  4020   3815                          || ( mode &&  tpl->mode && (strcmp(mode,tpl->mode)!=0))
  4021   3816                          || (!modeURI && tpl->modeURI)
................................................................................
  4243   4038                       }
  4244   4039                       Tcl_DStringAppend (&dStr, str2, -1);
  4245   4040                   }
  4246   4041               }
  4247   4042   
  4248   4043               savedLastNode = xs->lastNode;
  4249   4044               xs->lastNode  = domNewElementNode (xs->resultDoc,
  4250         -                                               "container", ELEMENT_NODE);
         4045  +                                               "container");
  4251   4046               xsltPushVarFrame (xs);
  4252   4047               rc = ExecActions(xs, context, currentNode, currentPos,
  4253   4048                                actionNode->firstChild, errMsg);
  4254   4049               xsltPopVarFrame (xs);
  4255   4050               if (rc < 0) {
  4256   4051                   if (out) FREE(out);
  4257   4052                   FREE(str2);
................................................................................
  4305   4100                                          Tcl_DStringValue (&dStr));
  4306   4101                   Tcl_DStringFree (&dStr);
  4307   4102               } else {
  4308   4103                   h = Tcl_FindHashEntry (&(xs->namedTemplates), localName);
  4309   4104               }
  4310   4105               if (!h) {
  4311   4106                   reportError (actionNode, "xsl:call-template calls a non"
  4312         -                             " existend template!", errMsg);
         4107  +                             " existing template!", errMsg);
  4313   4108                   return -1;
  4314   4109               } 
  4315   4110               tplChoosen = (xsltTemplate *) Tcl_GetHashValue (h);
  4316   4111               xsltPushVarFrame (xs);
  4317   4112               SETPARAMDEF;
  4318   4113               TRACE3("call template %s match='%s' name='%s' \n", localName, 
  4319   4114                      tplChoosen->match, tplChoosen->name);
................................................................................
  4412   4207                   reportError (actionNode, "\"choose\" must have at least"
  4413   4208                                " one \"when\" clause", errMsg);
  4414   4209                   return -1;
  4415   4210               }
  4416   4211               break;
  4417   4212   
  4418   4213           case comment:
  4419         -            fragmentNode = domNewElementNode(xs->resultDoc, "", ELEMENT_NODE);
         4214  +            fragmentNode = domNewElementNode(xs->resultDoc, "");
  4420   4215               savedLastNode = xs->lastNode;
  4421   4216               xs->lastNode = fragmentNode;
  4422   4217               xsltPushVarFrame (xs);
  4423   4218               rc = ExecActions(xs, context, currentNode, currentPos,
  4424   4219                                actionNode->firstChild, errMsg);
  4425   4220               xsltPopVarFrame (xs);
  4426   4221               CHECK_RC;
................................................................................
  4432   4227                                    " nodes other than text nodes.", errMsg);
  4433   4228                       return -1;
  4434   4229                   }
  4435   4230                   child = child->nextSibling;
  4436   4231               }
  4437   4232               str = xpathGetStringValue (fragmentNode, &len);
  4438   4233               if (!domIsComment (str)) {
  4439         -                reportError (actionNode, "Invalide comment value", errMsg);
         4234  +                reportError (actionNode, "Invalid comment value", errMsg);
  4440   4235                   domDeleteNode (fragmentNode, NULL, NULL);
  4441   4236                   FREE(str);
  4442   4237                   return -1;
  4443   4238               }
  4444   4239               xs->lastNode = savedLastNode;
  4445   4240               domAppendNewTextNode(xs->lastNode, str, len, COMMENT_NODE, 0);
  4446   4241               domDeleteNode (fragmentNode, NULL, NULL);
................................................................................
  4546   4341               TRACE1(" copyOf select='%s':\n", select);
  4547   4342               DBG(rsPrint(&rs));
  4548   4343               if (rs.type == xNodeSetResult) {
  4549   4344                   for (i=0; i<rs.nr_nodes; i++) {
  4550   4345                       if (rs.nodes[i]->nodeType == ATTRIBUTE_NODE) {
  4551   4346                           attr = (domAttrNode*)rs.nodes[i];
  4552   4347                           if (attr ->nodeFlags & IS_NS_NODE) {
  4553         -                            /* If someone selects explicitely namespace nodes
         4348  +                            /* If someone selects explicitly namespace nodes
  4554   4349                                  to copy-of with e.g namespace::* (remember: @*
  4555   4350                                  doesn't select namespace nodes), we must this
  4556         -                               handle seperately.*/
         4351  +                               handle separately.*/
  4557   4352                               /* The xmlns:xml namespace node will always
  4558   4353                                  be in scope, but never needed to be copied,
  4559   4354                                  because the result tree will also always
  4560   4355                                  already have it. To suppress, that the result
  4561   4356                                  tree gets glutted with xmlns:xml declarations
  4562   4357                                  (they would not harm, but ev. irritate some and
  4563   4358                                  are unnecessary, we check this here as a 
................................................................................
  4801   4596   
  4802   4597           case message:
  4803   4598               str  = getAttr(actionNode,"terminate", a_terminate);
  4804   4599               if (!str) terminate = 0;
  4805   4600               else if (strcmp (str, "yes") == 0) terminate = 1;
  4806   4601               else if (strcmp (str, "no")  == 0) terminate = 0;
  4807   4602               else {
  4808         -                reportError (actionNode, "Value for terminate should equal"
  4809         -                             " 'yes' or 'no'", errMsg);
         4603  +                reportError (actionNode, "Allowed values for the 'terminate'"
         4604  +                             "attribute: 'yes' or 'no'", errMsg);
  4810   4605                   return -1;
  4811   4606               }
  4812         -            fragmentNode = domNewElementNode(xs->resultDoc, "",
  4813         -                                             ELEMENT_NODE);
         4607  +            fragmentNode = domNewElementNode(xs->resultDoc, "");
  4814   4608               savedLastNode = xs->lastNode;
  4815   4609               xs->lastNode = fragmentNode;
  4816   4610               xsltPushVarFrame (xs);
  4817   4611               rc = ExecActions(xs, context, currentNode, currentPos,
  4818   4612                                actionNode->firstChild, errMsg);
  4819   4613               xsltPopVarFrame (xs);
  4820   4614               CHECK_RC;
  4821   4615   
  4822   4616               str2 = xpathGetStringValue(fragmentNode, &len);
  4823         -            xs->xsltMsgCB (xs->xsltMsgClientData, str2, len, terminate);
         4617  +            rc = xs->xsltMsgCB (xs->xsltMsgClientData, str2, len, terminate);
  4824   4618               FREE(str2);
  4825   4619               xs->lastNode = savedLastNode;
  4826   4620               domDeleteNode (fragmentNode, NULL, NULL);
  4827   4621               if (terminate) {
  4828   4622                   reportError (actionNode, "xsl:message with attribute"
  4829   4623                                " \"terminate\"=\"yes\"", errMsg);
  4830   4624                   return -1;
  4831   4625               }
  4832         -            return 0;
  4833         -
         4626  +            switch (rc) {
         4627  +            case 0: return 0;
         4628  +            case 3: 
         4629  +                reportError (actionNode, "", errMsg);
         4630  +                return -1;
         4631  +            default:
         4632  +                sprintf (tmpErr, "Error while executing message callback."
         4633  +                         " Message callback result code: %d", rc);
         4634  +                reportError (actionNode, tmpErr, errMsg);
         4635  +                return -1;
         4636  +            }
  4834   4637           case namespaceAlias: 
  4835   4638               reportError (actionNode, "xsl:namespaceAlias is only allowed"
  4836   4639                            " at toplevel.", errMsg);
  4837   4640               return -1;
  4838   4641   
  4839   4642           case number:
  4840   4643               if (actionNode->firstChild) {
................................................................................
  4895   4698                       return -1;
  4896   4699                   }
  4897   4700               } else {
  4898   4701                   reportError (actionNode, "xsl:processing-instruction:"
  4899   4702                                " missing mandatory attribute \"name\".", errMsg);
  4900   4703                   return -1;
  4901   4704               }
  4902         -            fragmentNode = domNewElementNode(xs->resultDoc, "", ELEMENT_NODE);
         4705  +            fragmentNode = domNewElementNode(xs->resultDoc, "");
  4903   4706               savedLastNode = xs->lastNode;
  4904   4707               xs->lastNode = fragmentNode;
  4905   4708               xsltPushVarFrame (xs);
  4906   4709               rc = ExecActions(xs, context, currentNode, currentPos,
  4907   4710                                actionNode->firstChild, errMsg);
  4908   4711               xsltPopVarFrame (xs);
  4909   4712               CHECK_RC;
................................................................................
  4917   4720                       FREE(str2);
  4918   4721                       return -1;
  4919   4722                   }
  4920   4723                   child = child->nextSibling;
  4921   4724               }
  4922   4725               str = xpathGetStringValue (fragmentNode, &len);
  4923   4726               if (!domIsPIValue (str)) {
  4924         -                reportError (actionNode, "Invalide processing instruction "
         4727  +                reportError (actionNode, "Invalid processing instruction "
  4925   4728                                "value", errMsg);
  4926   4729                   domDeleteNode (fragmentNode, NULL, NULL);
  4927   4730                   FREE(str);
  4928   4731                   FREE(str2);
  4929   4732                   return -1;
  4930   4733               }
  4931   4734               xs->lastNode = savedLastNode;
................................................................................
  5061   4864                           actionNode->nodeName, domNamespaceURI(actionNode) ););
  5062   4865               xs->lastNode = domAppendLiteralNode (xs->lastNode, actionNode);
  5063   4866               n = actionNode;
  5064   4867   
  5065   4868               while (n) {
  5066   4869                   attr = n->firstAttr;
  5067   4870                   while (attr && (attr->nodeFlags & IS_NS_NODE)) {
  5068         -                    /* xslt namespace isn't copied */
  5069         -                    /* Well, xslt implementors doesn't seem to agree
         4871  +                    /* XSLT namespace isn't copied */
         4872  +                    /* Well, XSLT implementors doesn't seem to agree
  5070   4873                          at which point this rule out of the second paragraph
  5071   4874                          of 7.1.1 must be applied: before or after applying
  5072   4875                          the namespace aliases (or, in other words: is this
  5073   4876                          rule (of not copying the XSLT namespace for lre)
  5074   4877                          considered, at the time, the lre is found in the
  5075   4878                          stylesheet or at the time, the lre is written to the
  5076   4879                          result doc). In deed the rec doesn't clarify this
................................................................................
  5358   5161               || ( modeURI && !tpl->modeURI)
  5359   5162               || ( modeURI && tpl->modeURI && (strcmp(modeURI, tpl->modeURI)!=0))
  5360   5163           ) {
  5361   5164               TRACE("doesn't match mode\n");
  5362   5165               continue; /* doesn't match mode */
  5363   5166           }
  5364   5167           TRACE4("tpl has prio='%f' precedence='%f', currentPrio='%f', currentPrec='%f'\n", tpl->prio, tpl->precedence, currentPrio, currentPrec);
  5365         -        /* According to xslt rec 5.5: First test precedence */
         5168  +        /* According to XSLT rec 5.5: First test precedence */
  5366   5169           if (tpl->precedence < currentPrec) break;
  5367   5170           if (tpl->precedence == currentPrec) {
  5368   5171               if (tpl->prio < currentPrio) break;
  5369   5172               if (tpl->prio == currentPrio
  5370   5173                   && domPrecedes (tpl->content, tplChoosen->content))
  5371   5174                   break;
  5372   5175           }
................................................................................
  5456   5259       char          ** errMsg
  5457   5260   )
  5458   5261   {
  5459   5262       domNode  * savedLastNode;
  5460   5263       int        i, rc, needNewVarFrame = 1;
  5461   5264   
  5462   5265       if (nodeList->type == xNodeSetResult) {
         5266  +        if (xs->nestedApplyTemplates > xs->maxNestedApplyTemplates) {
         5267  +            *errMsg = tdomstrdup("Maximum nested apply templates reached "
         5268  +                                 "(potential infinite template recursion?).");
         5269  +            return -1;
         5270  +        }
         5271  +        xs->nestedApplyTemplates++;
  5463   5272           savedLastNode = xs->lastNode;
  5464   5273           for (i=0; i < nodeList->nr_nodes; i++) {
  5465   5274               if (needNewVarFrame) {
  5466   5275                   xsltPushVarFrame (xs);
  5467   5276                   SETPARAMDEF;
  5468   5277                   rc = setParamVars (xs, context, currentNode, currentPos,
  5469   5278                                      actionNode, errMsg);
................................................................................
  5487   5296                   needNewVarFrame = 1;
  5488   5297               } else needNewVarFrame = 0;
  5489   5298           }
  5490   5299           if (!needNewVarFrame) {
  5491   5300               xsltPopVarFrame (xs);
  5492   5301           }
  5493   5302           xs->lastNode = savedLastNode;
         5303  +        xs->nestedApplyTemplates--;
  5494   5304       } else {
  5495   5305           TRACE("ApplyTemplates: nodeList not a NodeSetResult !!!\n");
  5496   5306           DBG(rsPrint(nodeList);)
  5497   5307       }
  5498   5308       return 0;
  5499   5309   }
  5500   5310   
................................................................................
  5609   5419       Tcl_HashTable  * HashTable,
  5610   5420       char          ** errMsg
  5611   5421       )
  5612   5422   {
  5613   5423       char *pc, *start, save, prefix[MAX_PREFIX_LEN];
  5614   5424       const char *localName;
  5615   5425       int hnew;
  5616         -    Tcl_HashEntry *h;
  5617   5426   
  5618   5427       Tcl_DString dStr;
  5619   5428       domNS  *ns;
  5620   5429   
  5621   5430       Tcl_DStringInit (&dStr);
  5622   5431       pc = qnameList;
  5623   5432       while (*pc) {
................................................................................
  5658   5467               Tcl_DStringAppend (&dStr, prefix, -1);
  5659   5468               Tcl_DStringAppend (&dStr, "'.", 2);
  5660   5469               reportError (node, Tcl_DStringValue (&dStr), errMsg);
  5661   5470               Tcl_DStringFree (&dStr);
  5662   5471               return 0;
  5663   5472           }
  5664   5473           Tcl_DStringAppend (&dStr, localName, -1);
  5665         -        h = Tcl_CreateHashEntry (HashTable, Tcl_DStringValue (&dStr), &hnew);
         5474  +        Tcl_CreateHashEntry (HashTable, Tcl_DStringValue (&dStr), &hnew);
  5666   5475           Tcl_DStringSetLength (&dStr, 0);
  5667   5476           *pc = save;
  5668   5477       }
  5669   5478       return 1;
  5670   5479   }
  5671   5480           
  5672   5481   /*----------------------------------------------------------------------------
................................................................................
  5816   5625       }
  5817   5626       if (d > 1.0) {
  5818   5627           docData->fwCmpProcessing = 1;
  5819   5628       } else {
  5820   5629           if (d != 1.0) {
  5821   5630               reportError (xsltRoot, "Strange \"version\" value.", errMsg);
  5822   5631               return -1;
  5823         -            docData->fwCmpProcessing = 0;
  5824   5632           }
  5825   5633       }
  5826   5634   
  5827   5635       str = getAttr (xsltRoot, "exclude-result-prefixes",
  5828   5636                      a_excludeResultPrefixes);
  5829   5637       rc = parseList (docData, xsltRoot, str, 0, errMsg);
  5830   5638       CHECK_RC;
................................................................................
  5851   5659       int          fixedXMLSource,
  5852   5660       char       **errMsg
  5853   5661       )
  5854   5662   {
  5855   5663       Tcl_Obj      *cmdPtr, *resultObj, *extbaseObj, *xmlstringObj;
  5856   5664       Tcl_Obj      *channelIdObj, *resultTypeObj;
  5857   5665       int           len, mode, result, storeLineColumn;
         5666  +    int           resultcode = 0;
  5858   5667       char         *resultType, *extbase, *xmlstring, *channelId, s[20];
  5859         -    char         *extResolver = NULL;
  5860         -    CONST84 char *str;
         5668  +    Tcl_Obj      *extResolver = NULL;
         5669  +    const char   *str;
  5861   5670       domDocument  *doc;
  5862   5671       xsltSubDoc   *sdoc;
  5863   5672       XML_Parser    parser;
  5864   5673       Tcl_Channel   chan;
  5865   5674       Tcl_DString   dStr;
  5866   5675       
  5867   5676       if (isStylesheet && (href[0] == '\0')) {
  5868   5677           *errMsg = tdomstrdup("Recursive import/include: stylesheet tries "
  5869   5678                                "to access itself.");
  5870   5679           return NULL;
  5871   5680       }
         5681  +    DBG(
         5682  +        fprintf (stderr, "getExternalDocument: baseURI '%s'\n", baseURI);
         5683  +        fprintf (stderr, "getExternalDocument: systemID '%s'\n", href);
         5684  +    )
         5685  +    
  5872   5686       cmdPtr = Tcl_NewStringObj (xsltDoc->extResolver, -1);
  5873   5687       Tcl_IncrRefCount (cmdPtr);
  5874   5688       if (baseURI) {
  5875   5689           Tcl_ListObjAppendElement(interp, cmdPtr,
  5876   5690                                    Tcl_NewStringObj (baseURI,
  5877   5691                                                      strlen(baseURI)));
  5878   5692       } else {
................................................................................
  5881   5695       }
  5882   5696       Tcl_ListObjAppendElement (interp, cmdPtr, (href ?
  5883   5697                                 Tcl_NewStringObj (href, strlen (href))
  5884   5698                                 : Tcl_NewStringObj ("", 0)));
  5885   5699       Tcl_ListObjAppendElement (interp, cmdPtr,
  5886   5700                                 Tcl_NewStringObj ("", 0));
  5887   5701   
  5888         -#if TclOnly8Bits
  5889         -    result = Tcl_GlobalEvalObj(interp, cmdPtr);
  5890         -#else 
  5891   5702       result = Tcl_EvalObjEx (interp, cmdPtr, TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);
  5892         -#endif    
  5893   5703   
  5894   5704       Tcl_DecrRefCount (cmdPtr);
  5895   5705       resultObj = Tcl_GetObjResult (interp);
  5896   5706       Tcl_IncrRefCount (resultObj);
  5897   5707   
  5898   5708       if (result != TCL_OK) {
  5899   5709           goto wrongScriptResult;
................................................................................
  5955   5765           storeLineColumn = 0;
  5956   5766       }
  5957   5767   
  5958   5768       parser = XML_ParserCreate_MM (NULL, MEM_SUITE, NULL);
  5959   5769   
  5960   5770       Tcl_ResetResult (interp);
  5961   5771       if (xsltDoc->extResolver) {
  5962         -        extResolver = tdomstrdup (xsltDoc->extResolver);
         5772  +        extResolver = Tcl_NewStringObj(xsltDoc->extResolver, -1);
         5773  +        Tcl_IncrRefCount (extResolver);
  5963   5774       }
  5964   5775       /* keep white space, no fiddling with the encoding (is this
  5965   5776          a good idea?) */
  5966         -    doc = domReadDocument (parser, xmlstring, len, 0, 0, storeLineColumn, 0,
  5967         -                           chan, extbase, extResolver, 0, 
  5968         -                           (int) XML_PARAM_ENTITY_PARSING_ALWAYS, interp);
  5969         -
         5777  +    doc = domReadDocument (parser, xmlstring, len, 0, 0, storeLineColumn,
         5778  +                           0, 0, NULL, chan, extbase, extResolver, 0, 
         5779  +                           (int) XML_PARAM_ENTITY_PARSING_ALWAYS, interp,
         5780  +                           &resultcode);
         5781  +    if (xsltDoc->extResolver) {
         5782  +        Tcl_DecrRefCount (extResolver);
         5783  +    }
  5970   5784       if (doc == NULL) {
  5971   5785           DBG(fprintf (stderr, "parse error, str len %d, xmlstring: -->%s<--\n",
  5972   5786                        strlen (xmlstring), xmlstring);)
  5973   5787           Tcl_DStringInit (&dStr);
  5974   5788           Tcl_DStringAppend (&dStr, "Error while processing external entity \"",
  5975   5789                              -1);
  5976   5790           Tcl_DStringAppend (&dStr, href, -1);
................................................................................
  6238   6052                       } else {
  6239   6053                           attrSet = (xsltAttrSet*)MALLOC(sizeof(xsltAttrSet));
  6240   6054                           xs->attrSets = attrSet;
  6241   6055                       }
  6242   6056                       attrSet->next    = NULL;
  6243   6057                       attrSet->content = node;
  6244   6058                       attrSet->name    = localName;
         6059  +                    attrSet->inUse   = 0;
  6245   6060                       if (ns) {
  6246   6061                           attrSet->uri = ns->uri;
  6247   6062                       } else {
  6248   6063                           attrSet->uri = NULL;
  6249   6064                       }
  6250   6065                   } else {
  6251   6066                       reportError (node, "xsl:attribute-set: missing mandatory"
................................................................................
  6286   6101                           df = df->next;
  6287   6102                       }
  6288   6103                       if (df == NULL) {
  6289   6104                           df = (xsltDecimalFormat*)MALLOC(sizeof(xsltDecimalFormat));
  6290   6105                           memset (df, 0, sizeof (xsltDecimalFormat));
  6291   6106                           newdf = 1;
  6292   6107                           /* initialize to defaults */
  6293         -#if TclOnly8Bits
  6294         -                        df->decimalSeparator  = '.';
  6295         -                        df->groupingSeparator = ',';
  6296         -                        df->infinity          = "Infinity";
  6297         -                        df->minusSign         = '-';
  6298         -                        df->NaN               = "NaN";
  6299         -                        df->percent           = '%';
  6300         -                        df->zeroDigit         = '0';
  6301         -                        df->digit             = '#';
  6302         -                        df->patternSeparator  = ';';
  6303         -#else 
  6304   6108                           df->decimalSeparator  = 46;          
  6305   6109                           df->groupingSeparator = 44;          
  6306   6110                           df->infinity          = "Infinity";  
  6307   6111                           df->minusSign         = 45;          
  6308   6112                           df->NaN               = "NaN";       
  6309   6113                           df->percent           = 37;          
  6310   6114                           df->perMille          = 0x2030;      
  6311   6115                           df->zeroDigit         = 48;          
  6312   6116                           df->digit             = 35;          
  6313   6117                           df->patternSeparator  = 59;
  6314         -#endif /* TclOnly8Bits */
  6315   6118                           df->name = tdomstrdup(str);
  6316   6119                           if (ns) df->uri = tdomstrdup(ns->uri);
  6317   6120                           else df->uri = NULL;
  6318   6121                           /* prepend into list of decimal format
  6319   6122                              after the default one */
  6320   6123                           df->next = xs->decimalFormats->next;
  6321   6124                           xs->decimalFormats->next = df;
................................................................................
  6322   6125                       }
  6323   6126                   } else {
  6324   6127                       /* definitions for default decimal format */
  6325   6128                       df = xs->decimalFormats;
  6326   6129                   }
  6327   6130                   str = getAttr(node, "decimal-separator",  a_decimalSeparator);
  6328   6131                   if (str) {
  6329         -#if TclOnly8Bits
  6330         -                    if (str[1] != '\0') {
  6331         -                        reportError (node, "decimal-separator has to be a"
  6332         -                                     " single char", errMsg);
  6333         -                        if (newdf) FREE((char*)df);
  6334         -                        return -1;
  6335         -                    }
  6336         -                    df->decimalSeparator = str[0];
  6337         -#else
  6338   6132                       clen = UTF8_CHAR_LEN (str[0]);
  6339   6133                       if (str[clen] != '\0') {
  6340   6134                           reportError (node, "decimal-separator has to be a"
  6341   6135                                        " single char", errMsg);
  6342   6136                           if (newdf) FREE((char*)df);
  6343   6137                           return -1;
  6344   6138                       }
  6345   6139                       Tcl_UtfToUniChar (str, &df->decimalSeparator);
  6346         -#endif /* TclOnly8Bits */
  6347   6140                   }
  6348   6141                   str = getAttr(node, "grouping-separator", a_groupingSeparator);
  6349   6142                   if (str) {
  6350         -#if TclOnly8Bits
  6351         -                    if (str[1] != '\0') {
  6352         -                        reportError (node, "grouping-separator has to be a"
  6353         -                                     " single char", errMsg);
  6354         -                        if (newdf) FREE((char*)df);
  6355         -                        return -1;
  6356         -                    }
  6357         -                    df->groupingSeparator = str[0];
  6358         -#else 
  6359   6143                       clen = UTF8_CHAR_LEN (str[0]);
  6360   6144                       if (str[clen] != '\0') {
  6361   6145                           reportError (node, "groupingSeparator has to be a"
  6362   6146                                        " single char", errMsg);
  6363   6147                           if (newdf) FREE((char*)df);
  6364   6148                           return -1;
  6365   6149                       }
  6366   6150                       Tcl_UtfToUniChar (str, &df->groupingSeparator);
  6367         -#endif /* TclOnly8Bits */                    
  6368   6151                   }
  6369   6152                   str = getAttr(node, "infinity",           a_infinity);
  6370   6153                   if (str) df->infinity = str;
  6371   6154                   str = getAttr(node, "minus-sign",         a_minusSign);
  6372   6155                   if (str) {
  6373         -#if TclOnly8Bits
  6374         -                    if (str[1] != '\0') {
  6375         -                        reportError (node, "minus-sign has to be a single"
  6376         -                                     " char", errMsg);
  6377         -                        return -1;
  6378         -                    }
  6379         -                    df->minusSign = str[0];
  6380         -#else                     
  6381   6156                       clen = UTF8_CHAR_LEN (str[0]);
  6382   6157                       if (str[clen] != '\0') {
  6383   6158                           reportError (node, "minus-sign has to be a single"
  6384   6159                                        " char", errMsg);
  6385   6160                           if (newdf) FREE((char*)df);
  6386   6161                           return -1;
  6387   6162                       }
  6388   6163                       Tcl_UtfToUniChar (str, &df->minusSign);
  6389         -#endif /* TclOnly8Bits */         
  6390   6164                   }
  6391   6165                   str = getAttr(node, "NaN",                a_nan);
  6392   6166                   if (str) df->NaN = str;
  6393   6167                   str = getAttr(node, "percent",            a_percent);
  6394   6168                   if (str) {
  6395         -#if TclOnly8Bits
  6396   6169                       if (str[1] != '\0') {
  6397   6170                           reportError (node, "percent has to be a single"
  6398   6171                                        " char", errMsg);
  6399   6172                           return -1;
  6400   6173                       }
  6401   6174                       df->percent = str[0];
  6402         -#else
  6403   6175                       clen = UTF8_CHAR_LEN (str[0]);
  6404   6176                       if (str[clen] != '\0') {
  6405   6177                           reportError (node, "percent has to be a single"
  6406   6178                                        " char", errMsg);
  6407   6179                           if (newdf) FREE((char*)df);
  6408   6180                           return -1;
  6409   6181                       }
  6410   6182                       Tcl_UtfToUniChar (str, &df->percent);                    
  6411         -#endif /* TclOnly8Bits */
  6412   6183                   }
  6413   6184                   str = getAttr(node, "per-mille",          a_perMille);
  6414   6185                   if (str) {
  6415         -#if TclOnly8Bits
  6416         -                    reportError (node, "User defined per-mille sign not"
  6417         -                                 " supported, sorry.", errMsg);
  6418         -                    return -1;
  6419         -#else
  6420   6186                       clen = UTF8_CHAR_LEN (str[0]);
  6421   6187                       if (str[clen] != '\0') {
  6422   6188                           reportError (node, "per-mille has to be a single"
  6423   6189                                        " char", errMsg);
  6424   6190                           if (newdf) FREE((char*)df);
  6425   6191                           return -1;
  6426   6192                       }
  6427   6193                       Tcl_UtfToUniChar (str, &df->perMille);                    
  6428         -#endif /* TclOnly8Bits */
  6429   6194                   }
  6430   6195                   str = getAttr(node, "zero-digit",         a_zeroDigit);
  6431   6196                   if (str) {
  6432         -#if TclOnly8Bits                    
  6433         -                    if (str[1] != '\0') {
  6434         -                        reportError (node, "zero-digit has to be a single"
  6435         -                                     " char", errMsg);
  6436         -                        return -1;
  6437         -                    }
  6438         -                    df->zeroDigit = str[0];
  6439         -#else
  6440   6197                       clen = UTF8_CHAR_LEN (str[0]);
  6441   6198                       if (str[clen] != '\0') {
  6442   6199                           reportError (node, "zero-digit has to be a single"
  6443   6200                                        " char", errMsg);
  6444   6201                           if (newdf) FREE((char*)df);
  6445   6202                           return -1;
  6446   6203                       }
  6447   6204                       Tcl_UtfToUniChar (str, &df->zeroDigit);                    
  6448         -#endif /* TclOnly8Bits */
  6449   6205                   }
  6450   6206                   str = getAttr(node, "digit",              a_digit);
  6451   6207                   if (str) {
  6452         -#if TclOnly8Bits
  6453         -                    if (str[1] != '\0') {
  6454         -                        reportError (node, "digit has to be a single char",
  6455         -                                     errMsg);
  6456         -                        return -1;
  6457         -                    }
  6458         -                    df->digit = str[0];
  6459         -#else 
  6460   6208                       clen = UTF8_CHAR_LEN (str[0]);
  6461   6209                       if (str[clen] != '\0') {
  6462   6210                           reportError (node, "digit has to be a single char",
  6463   6211                                        errMsg);
  6464   6212                           if (newdf) FREE((char*)df);
  6465   6213                           return -1;
  6466   6214                       }
  6467   6215                       Tcl_UtfToUniChar (str, &df->digit);
  6468         -#endif /* TclOnly8Bits */
  6469   6216                   }
  6470   6217                   str = getAttr(node, "pattern-separator",  a_patternSeparator);
  6471   6218                   if (str) {
  6472         -#if TclOnly8Bits
  6473         -                    if (str[1] != '\0') {
  6474         -                        reportError (node, "pattern-separator has to be a"
  6475         -                                     " single char", errMsg);
  6476         -                        return -1;
  6477         -                    }
  6478         -                    df->patternSeparator = str[0];
  6479         -#else
  6480   6219                       clen = UTF8_CHAR_LEN (str[0]);
  6481   6220                       if (str[clen] != '\0') {
  6482   6221                           reportError (node, "pattern-separator has to be a"
  6483   6222                                        " single char", errMsg);
  6484   6223                           return -1;
  6485   6224                       }
  6486   6225                       Tcl_UtfToUniChar (str, &df->patternSeparator);
  6487         -#endif /* TclOnly8Bits */
  6488   6226                   }
  6489   6227                   break;
  6490   6228   
  6491   6229               case import:
  6492   6230                   if (nonImportElemSeen) {
  6493   6231                       reportError (node, "xsl:import elements must come first",
  6494   6232                                    errMsg);
................................................................................
  6589   6327   
  6590   6328                   keyInfo = (xsltKeyInfo *)MALLOC(sizeof(xsltKeyInfo));
  6591   6329                   keyInfo->node = node;
  6592   6330                   rc = xpathParse (match, node, XPATH_KEY_MATCH_PATTERN, NULL,
  6593   6331                                    NULL, &(keyInfo->matchAst), errMsg);
  6594   6332                   if (rc < 0) {
  6595   6333                       reportError (node, *errMsg, errMsg);
  6596         -                    free ((char*)keyInfo);
         6334  +                    FREE ((char*)keyInfo);
  6597   6335                       return rc;
  6598   6336                   }
  6599   6337                   keyInfo->use       = use;
  6600   6338                   rc = xpathParse (use, node, XPATH_KEY_USE_EXPR, NULL,
  6601   6339                                    NULL, &(keyInfo->useAst), errMsg);
  6602   6340                   if (rc < 0) {
  6603   6341                       reportError (node, *errMsg, errMsg);
  6604   6342                       xpathFreeAst (keyInfo->matchAst);
  6605         -                    free ((char*)keyInfo);
         6343  +                    FREE ((char*)keyInfo);
  6606   6344                       return rc;
  6607   6345                   }
  6608   6346                   domSplitQName (name, prefix, &localName);
  6609   6347                   Tcl_DStringInit (&dStr);
  6610   6348                   if (prefix[0] != '\0') {
  6611   6349                       ns = domLookupPrefix (node, prefix);
  6612   6350                       if (!ns) {
................................................................................
  7003   6741               entryPtr = Tcl_NextHashEntry(&search)) {
  7004   6742           nf = (xsltNumberFormat *) Tcl_GetHashValue (entryPtr);
  7005   6743           FREE(nf->tokens);
  7006   6744           FREE(nf);
  7007   6745       }
  7008   6746       Tcl_DeleteHashTable(&xs->formats);
  7009   6747   
  7010         -    if (&xs->topLevelVars) {
  7011         -        for (entryPtr = Tcl_FirstHashEntry(&xs->topLevelVars, &search);
  7012         -             entryPtr != (Tcl_HashEntry*) NULL;
  7013         -             entryPtr = Tcl_NextHashEntry(&search)) {
  7014         -            tlv = (xsltTopLevelVar *) Tcl_GetHashValue (entryPtr);
  7015         -            FREE(tlv);
  7016         -        }
  7017         -        Tcl_DeleteHashTable (&xs->topLevelVars);
         6748  +    for (entryPtr = Tcl_FirstHashEntry(&xs->topLevelVars, &search);
         6749  +         entryPtr != (Tcl_HashEntry*) NULL;
         6750  +         entryPtr = Tcl_NextHashEntry(&search)) {
         6751  +        tlv = (xsltTopLevelVar *) Tcl_GetHashValue (entryPtr);
         6752  +        FREE(tlv);
  7018   6753       }
         6754  +    Tcl_DeleteHashTable (&xs->topLevelVars);
  7019   6755   
  7020   6756       /*--- free key definition information ---*/
  7021   6757       for (entryPtr = Tcl_FirstHashEntry (&xs->keyInfos, &search);
  7022   6758            entryPtr != (Tcl_HashEntry*) NULL;
  7023   6759            entryPtr = Tcl_NextHashEntry (&search)) {
  7024   6760           ki = (xsltKeyInfo *) Tcl_GetHashValue (entryPtr);
  7025   6761           while (ki) {
................................................................................
  7162   6898       /* Free the sub documents, which are resolved relative to nodes in
  7163   6899        * the xml source. */
  7164   6900       /* XML documents don't have excludeNS and extensionNS information
  7165   6901          and the already parsed XSLT documents information is
  7166   6902          preserved, therefor we don't touch excludeNS and extensionNS
  7167   6903          information */
  7168   6904       /* This loop works only as coded, because, the first subdoc will
  7169         -     * always be the primary xslt doc, so xs->subDocs will not
         6905  +     * always be the primary XSLT doc, so xs->subDocs will not
  7170   6906        * change. Crusty stuff, this code. */
  7171   6907       sd = xs->subDocs;
  7172   6908       while (sd)  {
  7173   6909           sdsave = sd;
  7174   6910           sd = sd->next;
  7175   6911           if (sdsave->isStylesheet || sdsave->fixedXMLSource) {
  7176   6912               if (lastSubDoc) {
................................................................................
  7203   6939               if (sdsave->baseURI) FREE(sdsave->baseURI);
  7204   6940               
  7205   6941               FREE(sdsave);
  7206   6942           }
  7207   6943       }
  7208   6944       xs->nsUniqeNr = 0;
  7209   6945       /* In theory, the varFramesStack and varStack pointers should
  7210         -       be always back to there inital state. But to be sure, we
         6946  +       be always back to there initial state. But to be sure, we
  7211   6947          re-initialize, just in case of a bizarre error or something. */
  7212   6948       xs->varFramesStackPtr = -1;
  7213   6949       xs->varStackPtr       = -1;
  7214   6950   }
  7215   6951   
  7216   6952   /*----------------------------------------------------------------------------
  7217   6953   |   xsltCompileStylesheet
................................................................................
  7274   7010       Tcl_InitHashTable ( &(xs->xpaths), TCL_STRING_KEYS);
  7275   7011       Tcl_InitHashTable ( &(xs->pattern), TCL_STRING_KEYS);
  7276   7012       Tcl_InitHashTable ( &(xs->formats), TCL_STRING_KEYS);
  7277   7013       Tcl_InitHashTable ( &(xs->topLevelVars), TCL_STRING_KEYS);
  7278   7014       Tcl_InitHashTable ( &(xs->keyInfos), TCL_STRING_KEYS);
  7279   7015       xs->decimalFormats->name              = NULL;
  7280   7016       xs->decimalFormats->uri               = NULL;
  7281         -#if TclOnly8Bits
  7282         -    xs->decimalFormats->decimalSeparator  = '.';
  7283         -    xs->decimalFormats->groupingSeparator = ',';
  7284         -    xs->decimalFormats->minusSign         = '-';
  7285         -    xs->decimalFormats->percent           = '%';
  7286         -    xs->decimalFormats->zeroDigit         = '0';
  7287         -    xs->decimalFormats->digit             = '#';
  7288         -    xs->decimalFormats->patternSeparator  = ';';
  7289         -#else 
  7290   7017       xs->decimalFormats->decimalSeparator  = 46;          
  7291   7018       xs->decimalFormats->groupingSeparator = 44;          
  7292   7019       xs->decimalFormats->minusSign         = 45;          
  7293   7020       xs->decimalFormats->percent           = 37;          
  7294   7021       xs->decimalFormats->perMille          = 0x2030;          
  7295   7022       xs->decimalFormats->zeroDigit         = 48;          
  7296   7023       xs->decimalFormats->digit             = 35;          
  7297   7024       xs->decimalFormats->patternSeparator  = 59;          
  7298         -#endif /* TclOnly8Bits */
  7299   7025       xs->decimalFormats->infinity          = "Infinity";
  7300   7026       xs->decimalFormats->NaN               = "NaN";
  7301   7027       xs->decimalFormats->next              = NULL;
  7302   7028       xs->indentOutput = 0;
  7303   7029       memset (&xs->doctype, 0, sizeof (domDocInfo));
  7304   7030       
  7305   7031       node = xsltDoc->documentElement;
  7306   7032   
  7307         -    /* add the xslt doc to the doc list */
         7033  +    /* add the XSLT doc to the doc list */
  7308   7034       sdoc = (xsltSubDoc*)MALLOC(sizeof (xsltSubDoc));
  7309   7035       sdoc->doc = xsltDoc;
  7310   7036       baseURI = findBaseURI (xsltDoc->documentElement);
  7311   7037       if (baseURI) {
  7312   7038           sdoc->baseURI = tdomstrdup (baseURI);
  7313   7039       } else {
  7314   7040           sdoc->baseURI = NULL;
................................................................................
  7368   7094       } else {
  7369   7095           rc = addExclExtNS (sdoc, node, errMsg);
  7370   7096           if (rc < 0) goto error;
  7371   7097           
  7372   7098           StripXSLTSpace (xsltDoc->rootNode);
  7373   7099           precedence = 1.0;
  7374   7100           precedenceLowBound = 0.0;
  7375         -        rc = 0;
  7376   7101           rc = processTopLevel (xpathFuncClientData, node, xs, precedence, 
  7377   7102                                 &precedenceLowBound, errMsg);
  7378   7103           if (rc != 0) goto error;
  7379   7104       }
  7380   7105           
  7381   7106       return xs;
  7382   7107   
................................................................................
  7391   7116   \---------------------------------------------------------------------------*/
  7392   7117   int xsltProcess (
  7393   7118       domDocument       * xsltDoc,
  7394   7119       domNode           * xmlNode,
  7395   7120       void              * xsltCmdData,
  7396   7121       char             ** parameters,
  7397   7122       int                 ignoreUndeclaredParameters,
         7123  +    int                 maxApplyDepth,
  7398   7124       xpathFuncCallback   funcCB,
  7399   7125       void              * xpathFuncClientData,
  7400   7126       xsltMsgCB           xsltMsgCB,
  7401   7127       void              * xsltMsgClientData,
  7402   7128       char             ** errMsg,
  7403   7129       domDocument      ** resultDoc   
  7404   7130       )
................................................................................
  7417   7143           xs = (xsltState *) xsltCmdData;
  7418   7144       } else {
  7419   7145           xs = (xsltState *) xsltCompileStylesheet (xsltDoc, funcCB,
  7420   7146                                                     xpathFuncClientData,
  7421   7147                                                     1, errMsg);
  7422   7148           if (!xs) return -1;
  7423   7149       }
  7424         -
         7150  +    xs->maxNestedApplyTemplates = maxApplyDepth;
         7151  +    xs->nestedApplyTemplates = 0;
         7152  +    
  7425   7153       if (xmlNode->nodeType == DOCUMENT_NODE) {
  7426   7154           xmlNode = ((domDocument *)xmlNode)->rootNode;
  7427   7155       } else {
  7428   7156           xmlNode = xmlNode->ownerDocument->rootNode;
  7429   7157       }
  7430   7158       DBG(printXML(xmlNode, 0, 1);)
  7431   7159   
................................................................................
  7594   7322       }
  7595   7323       return 0;
  7596   7324   
  7597   7325    error:
  7598   7326       xsltPopVarFrame (xs);
  7599   7327       xpathRSFree( &nodeList );
  7600   7328       domFreeDocument (xs->resultDoc, NULL, NULL);
         7329  +    xs->resultDoc = NULL;
  7601   7330       if (xsltCmdData) {
  7602   7331           xsltResetState (xs);
  7603   7332       } else {
  7604   7333           xsltFreeState (xs);
  7605   7334       }
  7606   7335       return -1;
  7607   7336   
  7608   7337   } /* xsltProcess */
  7609   7338   

Changes to generic/domxslt.h.

    66     66   #ifndef __DOMXSLT_H__
    67     67   #define __DOMXSLT_H__
    68     68   
    69     69   #include <dom.h>
    70     70   #include <domxpath.h>
    71     71   
    72     72   
    73         -typedef void (*xsltMsgCB) (void *clientData, char *str, 
           73  +typedef int (*xsltMsgCB) (void *clientData, char *str, 
    74     74                             int length, int terminate);
    75     75   
    76     76   /*----------------------------------------------------------------------------
    77     77   |   Prototypes
    78     78   |
    79     79   \---------------------------------------------------------------------------*/
    80     80   int xsltProcess (domDocument       * xsltDoc,
    81     81                    domNode           * xmlNode,
    82     82                    void              * xsltCmdData,
    83     83                    char             ** parameters,
    84     84                    int                 ignoreUndeclaredParameters,
           85  +                 int                 maxApplyDepth,
    85     86                    xpathFuncCallback   funcCB,
    86     87                    void              * xpathFuncClientData,
    87     88                    xsltMsgCB           xsltMsgCB,
    88     89                    void              * xsltMsgClientData,
    89     90                    char             ** errMsg,
    90     91                    domDocument      ** resultDoc
    91     92                   );

Deleted generic/encodings.inc.

     1         -/*------------------------------------------------------------------------
     2         -|   WARNING! This is file automatically generated by GenCompactCodings !  
     3         -|   WARNING!         Do not edit!                                         
     4         -|                                                                         
     5         -|   Unicode(UTF) ---> 8bit code conversion tables                         
     6         -|                                                                         
     7         -\-----------------------------------------------------------------------*/
     8         -static TEncodingRule TDOM_UnicodeToASCII [] = {
     9         -    { ENC_IDENTITY, 1, 126, "" }, 
    10         -    { ENC_END, 0, 0, NULL } 
    11         -};
    12         -
    13         -static TEncodingRule TDOM_UnicodeToCP1250 [] = {
    14         -    { ENC_IDENTITY, 1, 129, "" }, 
    15         -    { ENC_MAP, 131, 153, 
    16         -        "\203\077\077\077\210\077\077\077\077\077\077\077\220\077"
    17         -        "\077\077\077\077\077\077\230\077\077\077\077\077\077\077"
    18         -        "\240\077\077\077\244\077\246\247\250\251\077\253\077\255"
    19         -        "\256\077\260\261\077\077\264\265\266\267\270\077\077\273"
    20         -        "\077\077\077\077\077\301\302\077\304\077\077\307\077\311"
    21         -        "\077\313\077\315\316\077\077\077\077\323\324\077\326\327"
    22         -        "\077\077\332\077\334\335\077\337\077\341\342\077\344\077"
    23         -        "\077\347\077\351\077\353\077\355\356\077\077\077\077\363"
    24         -        "\364\077\366\367\077\077\372\077\374\375\077\077\077\077"
    25         -        "\303\343\245\271\306\346\077\077\077\077\310\350\317\357"
    26         -        "\320\360\077\077\077\077\077\077\312\352\314\354" },
    27         -    { ENC_MAP, 313, 70, 
    28         -        "\305\345\077\077\274\276\077\077\243\263\321\361\077\077"
    29         -        "\322\362\077\077\077\077\077\077\077\325\365\077\077\300"
    30         -        "\340\077\077\330\370\214\234\077\077\252\272\212\232\336"
    31         -        "\376\215\235\077\077\077\077\077\077\077\077\331\371\333"
    32         -        "\373\077\077\077\077\077\077\077\217\237\257\277\216\236"
    33         -    },
    34         -    { ENC_MAP, 711, 23, 
    35         -        "\241\077\077\077\077\077\077\077\077\077\077\077\077\077"
    36         -        "\077\077\077\242\377\077\262\077\275" },
    37         -    { ENC_MAP, 8211, 40, 
    38         -        "\226\227\077\077\077\221\222\202\077\223\224\204\077\206"
    39         -        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
    40         -        "\077\211\077\077\077\077\077\077\077\077\213\233" },
    41         -    { ENC_MAP, 8482, 1, 
    42         -        "\231" },
    43         -    { ENC_END, 0, 0, NULL } 
    44         -};
    45         -
    46         -static TEncodingRule TDOM_UnicodeToCP1251 [] = {
    47         -    { ENC_IDENTITY, 1, 127, "" }, 
    48         -    { ENC_MAP, 136, 52, 
    49         -        "\210\077\077\077\077\077\077\077\077\077\077\077\077\077"
    50         -        "\077\230\077\077\077\077\077\077\077\240\077\077\077\244"
    51         -        "\077\246\247\077\251\077\253\254\255\256\077\260\261\077"
    52         -        "\077\077\265\266\267\077\077\077\273" },
    53         -    { ENC_MAP, 1025, 95, 
    54         -        "\250\200\201\252\275\262\257\243\212\214\216\215\077\241"
    55         -        "\217\300\301\302\303\304\305\306\307\310\311\312\313\314"
    56         -        "\315\316\317\320\321\322\323\324\325\326\327\330\331\332"
    57         -        "\333\334\335\336\337\340\341\342\343\344\345\346\347\350"
    58         -        "\351\352\353\354\355\356\357\360\361\362\363\364\365\366"
    59         -        "\367\370\371\372\373\374\375\376\377\077\270\220\203\272"
    60         -        "\276\263\277\274\232\234\236\235\077\242\237" },
    61         -    { ENC_MAP, 1168, 2, 
    62         -        "\245\264" },
    63         -    { ENC_MAP, 8211, 40, 
    64         -        "\226\227\077\077\077\221\222\202\077\223\224\204\077\206"
    65         -        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
    66         -        "\077\211\077\077\077\077\077\077\077\077\213\233" },
    67         -    { ENC_MAP, 8470, 13, 
    68         -        "\271\077\077\077\077\077\077\077\077\077\077\077\231" },
    69         -    { ENC_END, 0, 0, NULL } 
    70         -};
    71         -
    72         -static TEncodingRule TDOM_UnicodeToCP1252 [] = {
    73         -    { ENC_IDENTITY, 1, 129, "" }, 
    74         -    { ENC_MAP, 141, 18, 
    75         -        "\215\216\217\220\077\077\077\077\077\077\077\077\235\236"
    76         -    },
    77         -    { ENC_IDENTITY, 160, 96, "" }, 
    78         -    { ENC_MAP, 338, 16, 
    79         -        "\214\234\077\077\077\077\077\077\077\077\077\077\077\077"
    80         -        "\212\232" },
    81         -    { ENC_MAP, 376, 1, 
    82         -        "\237" },
    83         -    { ENC_MAP, 402, 1, 
    84         -        "\203" },
    85         -    { ENC_MAP, 710, 1, 
    86         -        "\210" },
    87         -    { ENC_MAP, 732, 1, 
    88         -        "\230" },
    89         -    { ENC_MAP, 8211, 40, 
    90         -        "\226\227\077\077\077\221\222\202\077\223\224\204\077\206"
    91         -        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
    92         -        "\077\211\077\077\077\077\077\077\077\077\213\233" },
    93         -    { ENC_MAP, 8482, 1, 
    94         -        "\231" },
    95         -    { ENC_END, 0, 0, NULL } 
    96         -};
    97         -
    98         -static TEncodingRule TDOM_UnicodeToCP1253 [] = {
    99         -    { ENC_IDENTITY, 1, 129, "" }, 
   100         -    { ENC_MAP, 136, 54, 
   101         -        "\210\212\077\214\215\216\217\220\077\077\077\077\077\077"
   102         -        "\077\230\077\232\077\234\235\236\237\240\077\077\243\244"
   103         -        "\245\246\247\250\251\077\253\254\255\256\077\260\261\262"
   104         -        "\263\077\265\266\267\077\077\077\273\077\275" },
   105         -    { ENC_MAP, 402, 1, 
   106         -        "\203" },
   107         -    { ENC_MAP, 900, 75, 
   108         -        "\264\241\242\077\270\271\272\077\274\077\276\277\300\301"
   109         -        "\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
   110         -        "\320\321\077\323\324\325\326\327\330\331\332\333\334\335"
   111         -        "\336\337\340\341\342\343\344\345\346\347\350\351\352\353"
   112         -        "\354\355\356\357\360\361\362\363\364\365\366\367\370\371"
   113         -        "\372\373\374\375\376" },
   114         -    { ENC_MAP, 8211, 40, 
   115         -        "\226\227\257\077\077\221\222\202\077\223\224\204\077\206"
   116         -        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
   117         -        "\077\211\077\077\077\077\077\077\077\077\213\233" },
   118         -    { ENC_MAP, 8482, 1, 
   119         -        "\231" },
   120         -    { ENC_END, 0, 0, NULL } 
   121         -};
   122         -
   123         -static TEncodingRule TDOM_UnicodeToCP1254 [] = {
   124         -    { ENC_IDENTITY, 1, 129, "" }, 
   125         -    { ENC_MAP, 141, 115, 
   126         -        "\215\216\217\220\077\077\077\077\077\077\077\077\235\236"
   127         -        "\077\240\241\242\243\244\245\246\247\250\251\252\253\254"
   128         -        "\255\256\257\260\261\262\263\264\265\266\267\270\271\272"
   129         -        "\273\274\275\276\277\300\301\302\303\304\305\306\307\310"
   130         -        "\311\312\313\314\315\316\317\077\321\322\323\324\325\326"
   131         -        "\327\330\331\332\333\334\077\077\337\340\341\342\343\344"
   132         -        "\345\346\347\350\351\352\353\354\355\356\357\077\361\362"
   133         -        "\363\364\365\366\367\370\371\372\373\374\077\077\377" },
   134         -    { ENC_MAP, 286, 20, 
   135         -        "\320\360\077\077\077\077\077\077\077\077\077\077\077\077"
   136         -        "\077\077\077\077\335\375" },
   137         -    { ENC_MAP, 338, 16, 
   138         -        "\214\234\077\077\077\077\077\077\077\077\077\077\336\376"
   139         -        "\212\232" },
   140         -    { ENC_MAP, 376, 1, 
   141         -        "\237" },
   142         -    { ENC_MAP, 402, 1, 
   143         -        "\203" },
   144         -    { ENC_MAP, 710, 1, 
   145         -        "\210" },
   146         -    { ENC_MAP, 732, 1, 
   147         -        "\230" },
   148         -    { ENC_MAP, 8211, 40, 
   149         -        "\226\227\077\077\077\221\222\202\077\223\224\204\077\206"
   150         -        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
   151         -        "\077\211\077\077\077\077\077\077\077\077\213\233" },
   152         -    { ENC_MAP, 8482, 1, 
   153         -        "\231" },
   154         -    { ENC_END, 0, 0, NULL } 
   155         -};
   156         -
   157         -static TEncodingRule TDOM_UnicodeToCP1255 [] = {
   158         -    { ENC_IDENTITY, 1, 129, "" }, 
   159         -    { ENC_MAP, 138, 53, 
   160         -        "\212\214\215\216\217\220\077\077\077\077\077\077\077\077"
   161         -        "\077\232\077\234\235\236\237\240\077\242\243\077\245\246"
   162         -        "\247\250\251\077\253\254\255\256\257\260\261\262\263\264"
   163         -        "\265\266\267\077\271\077\273\274\275\276" },
   164         -    { ENC_MAP, 402, 1, 
   165         -        "\203" },
   166         -    { ENC_MAP, 710, 1, 
   167         -        "\210" },
   168         -    { ENC_MAP, 732, 1, 
   169         -        "\230" },
   170         -    { ENC_MAP, 1456, 67, 
   171         -        "\300\301\302\303\304\305\306\307\310\311\312\313\314\315"
   172         -        "\316\317\320\321\322\323\077\077\077\077\077\077\077\077"
   173         -        "\077\077\077\077\340\341\342\343\344\345\346\347\350\351"
   174         -        "\352\353\354\355\356\357\360\361\362\363\364\365\366\367"
   175         -        "\370\371\372\077\077\077\077\077\324\325\326" },
   176         -    { ENC_MAP, 8206, 45, 
   177         -        "\375\376\077\077\077\226\227\077\077\077\221\222\202\077"
   178         -        "\223\224\204\077\206\207\225\077\077\077\205\077\077\077"
   179         -        "\077\077\077\077\077\077\211\077\077\077\077\077\077\077"
   180         -        "\077\213\233" },
   181         -    { ENC_MAP, 8362, 1, 
   182         -        "\244" },
   183         -    { ENC_MAP, 8482, 1, 
   184         -        "\231" },
   185         -    { ENC_END, 0, 0, NULL } 
   186         -};
   187         -
   188         -static TEncodingRule TDOM_UnicodeToCP1256 [] = {
   189         -    { ENC_IDENTITY, 1, 128, "" }, 
   190         -    { ENC_MAP, 138, 53, 
   191         -        "\212\077\077\077\217\077\077\077\077\077\077\077\077\230"
   192         -        "\077\232\077\077\077\077\237\240\077\242\243\244\245\246"
   193         -        "\247\250\251\077\253\254\255\256\257\260\261\262\263\264"
   194         -        "\265\266\267\270\271\077\273\274\275\276" },
   195         -    { ENC_MAP, 215, 38, 
   196         -        "\327\077\077\077\077\077\077\077\340\077\342\077\077\077"
   197         -        "\077\347\350\351\352\353\077\077\356\357\077\077\077\077"
   198         -        "\364\077\077\367\077\371\077\373\374" },
   199         -    { ENC_MAP, 338, 2, 
   200         -        "\214\234" },
   201         -    { ENC_MAP, 402, 1, 
   202         -        "\203" },
   203         -    { ENC_MAP, 710, 1, 
   204         -        "\210" },
   205         -    { ENC_MAP, 1548, 71, 
   206         -        "\241\077\077\077\077\077\077\077\077\077\077\077\077\077"
   207         -        "\077\272\077\077\077\277\077\301\302\303\304\305\306\307"
   208         -        "\310\311\312\313\314\315\316\317\320\321\322\323\324\325"
   209         -        "\326\330\331\332\333\077\077\077\077\077\334\335\336\337"
   210         -        "\341\343\344\345\346\354\355\360\361\362\363\365\366\370"
   211         -        "\372" },
   212         -    { ENC_MAP, 1662, 27, 
   213         -        "\201\077\077\077\077\077\077\077\215\077\077\077\077\077"
   214         -        "\077\077\077\077\077\077\077\077\077\077\077\077\216" },
   215         -    { ENC_MAP, 1711, 1, 
   216         -        "\220" },
   217         -    { ENC_MAP, 8204, 47, 
   218         -        "\235\236\375\376\077\077\077\226\227\077\077\077\221\222"
   219         -        "\202\077\223\224\204\077\206\207\225\077\077\077\205\077"
   220         -        "\077\077\077\077\077\077\077\077\211\077\077\077\077\077"
   221         -        "\077\077\077\213\233" },
   222         -    { ENC_MAP, 8482, 1, 
   223         -        "\231" },
   224         -    { ENC_END, 0, 0, NULL } 
   225         -};
   226         -
   227         -static TEncodingRule TDOM_UnicodeToCP437 [] = {
   228         -    { ENC_IDENTITY, 1, 127, "" }, 
   229         -    { ENC_MAP, 160, 96, 
   230         -        "\377\255\233\234\077\235\077\077\077\077\246\256\252\077"
   231         -        "\077\077\370\361\375\077\077\346\077\372\077\077\247\257"
   232         -        "\254\253\077\250\077\077\077\077\216\217\222\200\077\220"
   233         -        "\077\077\077\077\077\077\077\245\077\077\077\077\231\077"
   234         -        "\077\077\077\077\232\077\077\341\205\240\203\077\204\206"
   235         -        "\221\207\212\202\210\211\215\241\214\213\077\244\225\242"
   236         -        "\223\077\224\366\077\227\243\226\201\077\077\230" },
   237         -    { ENC_MAP, 402, 1, 
   238         -        "\237" },
   239         -    { ENC_MAP, 915, 52, 
   240         -        "\342\077\077\077\077\351\077\077\077\077\077\077\077\077"
   241         -        "\077\077\344\077\077\350\077\077\352\077\077\077\077\077"
   242         -        "\077\077\340\077\077\353\356\077\077\077\077\077\077\077"
   243         -        "\077\077\077\343\077\077\345\347\077\355" },
   244         -    { ENC_MAP, 8319, 1, 
   245         -        "\374" },
   246         -    { ENC_MAP, 8359, 1, 
   247         -        "\236" },
   248         -    { ENC_MAP, 8729, 17, 
   249         -        "\371\373\077\077\077\354\077\077\077\077\077\077\077\077"
   250         -        "\077\077\357" },
   251         -    { ENC_MAP, 8776, 1, 
   252         -        "\367" },
   253         -    { ENC_MAP, 8801, 5, 
   254         -        "\360\077\077\363\362" },
   255         -    { ENC_MAP, 8976, 18, 
   256         -        "\251\077\077\077\077\077\077\077\077\077\077\077\077\077"
   257         -        "\077\077\364\365" },
   258         -    { ENC_MAP, 9472, 161, 
   259         -        "\304\077\263\077\077\077\077\077\077\077\077\077\332\077"
   260         -        "\077\077\277\077\077\077\300\077\077\077\331\077\077\077"
   261         -        "\303\077\077\077\077\077\077\077\264\077\077\077\077\077"
   262         -        "\077\077\302\077\077\077\077\077\077\077\301\077\077\077"
   263         -        "\077\077\077\077\305\077\077\077\077\077\077\077\077\077"
   264         -        "\077\077\077\077\077\077\077\077\077\077\315\272\325\326"
   265         -        "\311\270\267\273\324\323\310\276\275\274\306\307\314\265"
   266         -        "\266\271\321\322\313\317\320\312\330\327\316\077\077\077"
   267         -        "\077\077\077\077\077\077\077\077\077\077\077\077\077\077"
   268         -        "\077\077\337\077\077\077\334\077\077\077\333\077\077\077"
   269         -        "\335\077\077\077\336\260\261\262\077\077\077\077\077\077"
   270         -        "\077\077\077\077\077\077\376" },
   271         -    { ENC_END, 0, 0, NULL } 
   272         -};
   273         -
   274         -static TEncodingRule TDOM_UnicodeToCP850 [] = {
   275         -    { ENC_IDENTITY, 1, 127, "" }, 
   276         -    { ENC_MAP, 160, 96, 
   277         -        "\377\255\275\234\317\276\335\365\371\270\246\256\252\360"
   278         -        "\251\356\370\361\375\374\357\346\364\372\367\373\247\257"
   279         -        "\254\253\363\250\267\265\266\307\216\217\222\200\324\220"
   280         -        "\322\323\336\326\327\330\321\245\343\340\342\345\231\236"
   281         -        "\235\353\351\352\232\355\350\341\205\240\203\306\204\206"
   282         -        "\221\207\212\202\210\211\215\241\214\213\320\244\225\242"
   283         -        "\223\344\224\366\233\227\243\226\201\354\347\230" },
   284         -    { ENC_MAP, 305, 1, 
   285         -        "\325" },
   286         -    { ENC_MAP, 402, 1, 
   287         -        "\237" },
   288         -    { ENC_MAP, 8215, 1, 
   289         -        "\362" },
   290         -    { ENC_MAP, 9472, 161, 
   291         -        "\304\077\263\077\077\077\077\077\077\077\077\077\332\077"
   292         -        "\077\077\277\077\077\077\300\077\077\077\331\077\077\077"
   293         -        "\303\077\077\077\077\077\077\077\264\077\077\077\077\077"
   294         -        "\077\077\302\077\077\077\077\077\077\077\301\077\077\077"
   295         -        "\077\077\077\077\305\077\077\077\077\077\077\077\077\077"
   296         -        "\077\077\077\077\077\077\077\077\077\077\315\272\077\077"
   297         -        "\311\077\077\273\077\077\310\077\077\274\077\077\314\077"
   298         -        "\077\271\077\077\313\077\077\312\077\077\316\077\077\077"
   299         -        "\077\077\077\077\077\077\077\077\077\077\077\077\077\077"
   300         -        "\077\077\337\077\077\077\334\077\077\077\333\077\077\077"
   301         -        "\077\077\077\077\077\260\261\262\077\077\077\077\077\077"
   302         -        "\077\077\077\077\077\077\376" },
   303         -    { ENC_END, 0, 0, NULL } 
   304         -};
   305         -
   306         -static TEncodingRule TDOM_UnicodeToISO88591 [] = {
   307         -    { ENC_IDENTITY, 1, 255, "" }, 
   308         -    { ENC_END, 0, 0, NULL } 
   309         -};
   310         -
   311         -static TEncodingRule TDOM_UnicodeToISO88592 [] = {
   312         -    { ENC_IDENTITY, 1, 160, "" }, 
   313         -    { ENC_MAP, 164, 120, 
   314         -        "\244\077\247\250\077\077\077\077\255\077\077\260\077\077"
   315         -        "\077\264\077\077\077\270\077\077\077\077\077\077\077\077"
   316         -        "\301\302\077\304\077\077\307\077\311\077\313\077\315\316"
   317         -        "\077\077\077\077\323\324\077\326\327\077\077\332\077\334"
   318         -        "\335\077\337\077\341\342\077\344\077\077\347\077\351\077"
   319         -        "\353\077\355\356\077\077\077\077\363\364\077\366\367\077"
   320         -        "\077\372\077\374\375\077\077\077\077\303\343\241\261\306"
   321         -        "\346\077\077\077\077\310\350\317\357\320\360\077\077\077"
   322         -        "\077\077\077\312\352\314\354" },
   323         -    { ENC_MAP, 313, 70, 
   324         -        "\305\345\077\077\245\265\077\077\243\263\321\361\077\077"
   325         -        "\322\362\077\077\077\077\077\077\077\325\365\077\077\300"
   326         -        "\340\077\077\330\370\246\266\077\077\252\272\251\271\336"
   327         -        "\376\253\273\077\077\077\077\077\077\077\077\331\371\333"
   328         -        "\373\077\077\077\077\077\077\077\254\274\257\277\256\276"
   329         -    },
   330         -    { ENC_MAP, 711, 23, 
   331         -        "\267\077\077\077\077\077\077\077\077\077\077\077\077\077"
   332         -        "\077\077\077\242\377\077\262\077\275" },
   333         -    { ENC_END, 0, 0, NULL } 
   334         -};
   335         -
   336         -static TEncodingRule TDOM_UnicodeToISO88593 [] = {
   337         -    { ENC_IDENTITY, 1, 160, "" }, 
   338         -    { ENC_MAP, 163, 147, 
   339         -        "\243\244\247\250\077\077\077\077\255\077\077\260\077\262"
   340         -        "\263\264\265\077\267\270\077\077\077\077\275\077\077\300"
   341         -        "\301\302\077\304\077\077\307\310\311\312\313\314\315\316"
   342         -        "\317\077\321\322\323\324\077\326\327\077\331\332\333\334"
   343         -        "\077\077\337\340\341\342\077\344\077\077\347\350\351\352"
   344         -        "\353\354\355\356\357\077\361\362\363\364\077\366\367\077"
   345         -        "\371\372\373\374\077\077\077\077\077\077\077\077\077\077"
   346         -        "\077\306\346\305\345\077\077\077\077\077\077\077\077\077"
   347         -        "\077\077\077\077\077\077\077\330\370\253\273\325\365\077"
   348         -        "\077\246\266\241\261\077\077\077\077\077\077\077\077\251"
   349         -        "\271\077\077\254\274" },
   350         -    { ENC_MAP, 348, 33, 
   351         -        "\336\376\252\272\077\077\077\077\077\077\077\077\077\077"
   352         -        "\077\077\335\375\077\077\077\077\077\077\077\077\077\077"
   353         -        "\077\077\077\257\277" },
   354         -    { ENC_MAP, 728, 2, 
   355         -        "\242\377" },
   356         -    { ENC_END, 0, 0, NULL } 
   357         -};
   358         -
   359         -static TEncodingRule TDOM_UnicodeToISO88594 [] = {
   360         -    { ENC_IDENTITY, 1, 160, "" }, 
   361         -    { ENC_MAP, 164, 219, 
   362         -        "\244\077\247\250\077\077\077\077\255\077\257\260\077\077"
   363         -        "\077\264\077\077\077\270\077\077\077\077\077\077\077\077"
   364         -        "\301\302\303\304\305\306\077\077\311\077\313\077\315\316"
   365         -        "\077\077\077\077\077\324\325\326\327\330\077\332\333\334"
   366         -        "\077\077\337\077\341\342\343\344\345\346\077\077\351\077"
   367         -        "\353\077\355\356\077\077\077\077\077\364\365\366\367\370"
   368         -        "\077\372\373\374\077\077\077\300\340\077\077\241\261\077"
   369         -        "\077\077\077\077\077\310\350\077\077\320\360\252\272\077"
   370         -        "\077\314\354\312\352\077\077\077\077\077\077\077\077\253"
   371         -        "\273\077\077\077\077\245\265\317\357\077\077\307\347\077"
   372         -        "\077\077\077\077\077\323\363\242\077\077\246\266\077\077"
   373         -        "\077\077\077\077\077\077\321\361\077\077\077\275\277\322"
   374         -        "\362\077\077\077\077\077\077\077\077\243\263\077\077\077"
   375         -        "\077\077\077\077\077\251\271\077\077\077\077\254\274\335"
   376         -        "\375\336\376\077\077\077\077\077\077\331\371\077\077\077"
   377         -        "\077\077\077\077\077\077\256\276" },
   378         -    { ENC_MAP, 711, 21, 
   379         -        "\267\077\077\077\077\077\077\077\077\077\077\077\077\077"
   380         -        "\077\077\077\077\377\077\262" },
   381         -    { ENC_END, 0, 0, NULL } 
   382         -};
   383         -
   384         -static TEncodingRule TDOM_UnicodeToISO88595 [] = {
   385         -    { ENC_IDENTITY, 1, 160, "" }, 
   386         -    { ENC_MAP, 167, 7, 
   387         -        "\375\077\077\077\077\077\255" },
   388         -    { ENC_MAP, 1025, 95, 
   389         -        "\241\242\243\244\245\246\247\250\251\252\253\254\077\256"
   390         -        "\257\260\261\262\263\264\265\266\267\270\271\272\273\274"
   391         -        "\275\276\277\300\301\302\303\304\305\306\307\310\311\312"
   392         -        "\313\314\315\316\317\320\321\322\323\324\325\326\327\330"
   393         -        "\331\332\333\334\335\336\337\340\341\342\343\344\345\346"
   394         -        "\347\350\351\352\353\354\355\356\357\077\361\362\363\364"
   395         -        "\365\366\367\370\371\372\373\374\077\376\377" },
   396         -    { ENC_MAP, 8470, 1, 
   397         -        "\360" },
   398         -    { ENC_END, 0, 0, NULL } 
   399         -};
   400         -
   401         -static TEncodingRule TDOM_UnicodeToISO88596 [] = {
   402         -    { ENC_IDENTITY, 1, 47, "" }, 
   403         -    { ENC_IDENTITY, 58, 103, "" }, 
   404         -    { ENC_MAP, 164, 10, 
   405         -        "\244\077\077\077\077\077\077\077\255" },
   406         -    { ENC_MAP, 1548, 94, 
   407         -        "\254\077\077\077\077\077\077\077\077\077\077\077\077\077"
   408         -        "\077\273\077\077\077\277\077\301\302\303\304\305\306\307"
   409         -        "\310\311\312\313\314\315\316\317\320\321\322\323\324\325"
   410         -        "\326\327\330\331\332\077\077\077\077\077\340\341\342\343"
   411         -        "\344\345\346\347\350\351\352\353\354\355\356\357\360\361"
   412         -        "\362\077\077\077\077\077\077\077\077\077\077\077\077\077"
   413         -        "\060\061\062\063\064\065\066\067\070\071" },
   414         -    { ENC_END, 0, 0, NULL } 
   415         -};
   416         -
   417         -static TEncodingRule TDOM_UnicodeToISO88597 [] = {
   418         -    { ENC_IDENTITY, 1, 160, "" }, 
   419         -    { ENC_MAP, 163, 27, 
   420         -        "\243\077\246\247\250\251\077\253\254\255\077\077\260\261"
   421         -        "\262\263\077\077\077\267\077\077\077\273\077\275" },
   422         -    { ENC_MAP, 700, 2, 
   423         -        "\242\241" },
   424         -    { ENC_MAP, 900, 75, 
   425         -        "\264\265\266\077\270\271\272\077\274\077\276\277\300\301"
   426         -        "\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
   427         -        "\320\321\077\323\324\325\326\327\330\331\332\333\334\335"
   428         -        "\336\337\340\341\342\343\344\345\346\347\350\351\352\353"
   429         -        "\354\355\356\357\360\361\362\363\364\365\366\367\370\371"
   430         -        "\372\373\374\375\376" },
   431         -    { ENC_MAP, 8213, 1, 
   432         -        "\257" },
   433         -    { ENC_END, 0, 0, NULL } 
   434         -};
   435         -
   436         -static TEncodingRule TDOM_UnicodeToISO88598 [] = {
   437         -    { ENC_IDENTITY, 1, 160, "" }, 
   438         -    { ENC_MAP, 162, 54, 
   439         -        "\242\243\244\245\246\247\250\251\253\254\255\256\260\261"
   440         -        "\262\263\264\265\266\267\270\271\273\274\275\276\077\077"
   441         -        "\077\077\077\077\077\077\077\077\077\077\077\077\077\077"
   442         -        "\077\077\077\252" },
   443         -    { ENC_MAP, 247, 1, 
   444         -        "\272" },
   445         -    { ENC_MAP, 1488, 27, 
   446         -        "\340\341\342\343\344\345\346\347\350\351\352\353\354\355"
   447         -        "\356\357\360\361\362\363\364\365\366\367\370\371\372" },
   448         -    { ENC_MAP, 8215, 1, 
   449         -        "\337" },
   450         -    { ENC_MAP, 8254, 1, 
   451         -        "\257" },
   452         -    { ENC_END, 0, 0, NULL } 
   453         -};
   454         -
   455         -static TEncodingRule TDOM_UnicodeToISO88599 [] = {
   456         -    { ENC_IDENTITY, 1, 207, "" }, 
   457         -    { ENC_MAP, 209, 54, 
   458         -        "\321\322\323\324\325\326\327\330\331\332\333\334\337\340"
   459         -        "\341\342\343\344\345\346\347\350\351\352\353\354\355\356"
   460         -        "\357\361\362\363\364\365\366\367\370\371\372\373\374\377"
   461         -    },
   462         -    { ENC_MAP, 286, 20, 
   463         -        "\320\360\077\077\077\077\077\077\077\077\077\077\077\077"
   464         -        "\077\077\077\077\335\375" },
   465         -    { ENC_MAP, 350, 2, 
   466         -        "\336\376" },
   467         -    { ENC_END, 0, 0, NULL } 
   468         -};
   469         -
   470         -static TEncodingRule TDOM_UnicodeToKOI8R [] = {
   471         -    { ENC_IDENTITY, 1, 127, "" }, 
   472         -    { ENC_MAP, 160, 24, 
   473         -        "\232\077\077\077\077\077\077\077\077\277\077\077\077\077"
   474         -        "\077\077\234\077\235\077\077\077\077\236" },
   475         -    { ENC_MAP, 247, 1, 
   476         -        "\237" },
   477         -    { ENC_MAP, 1025, 81, 
   478         -        "\263\077\077\077\077\077\077\077\077\077\077\077\077\077"
   479         -        "\077\341\342\367\347\344\345\366\372\351\352\353\354\355"
   480         -        "\356\357\360\362\363\364\365\346\350\343\376\373\375\377"
   481         -        "\371\370\374\340\361\301\302\327\307\304\305\326\332\311"
   482         -        "\312\313\314\315\316\317\320\322\323\324\325\306\310\303"
   483         -        "\336\333\335\337\331\330\334\300\321\077\243" },
   484         -    { ENC_MAP, 8729, 2, 
   485         -        "\225\226" },
   486         -    { ENC_MAP, 8776, 1, 
   487         -        "\227" },
   488         -    { ENC_MAP, 8804, 2, 
   489         -        "\230\231" },
   490         -    { ENC_MAP, 8992, 2, 
   491         -        "\223\233" },
   492         -    { ENC_MAP, 9472, 161, 
   493         -        "\200\077\201\077\077\077\077\077\077\077\077\077\202\077"
   494         -        "\077\077\203\077\077\077\204\077\077\077\205\077\077\077"
   495         -        "\206\077\077\077\077\077\077\077\207\077\077\077\077\077"
   496         -        "\077\077\210\077\077\077\077\077\077\077\211\077\077\077"
   497         -        "\077\077\077\077\212\077\077\077\077\077\077\077\077\077"
   498         -        "\077\077\077\077\077\077\077\077\077\077\240\241\242\244"
   499         -        "\245\246\247\250\251\252\253\254\255\256\257\260\261\262"
   500         -        "\264\265\266\267\270\271\272\273\274\275\276\077\077\077"
   501         -        "\077\077\077\077\077\077\077\077\077\077\077\077\077\077"
   502         -        "\077\077\213\077\077\077\214\077\077\077\215\077\077\077"
   503         -        "\216\077\077\077\217\220\221\222\077\077\077\077\077\077"
   504         -        "\077\077\077\077\077\077\224" },
   505         -    { ENC_END, 0, 0, NULL } 
   506         -};
   507         -
   508         -
   509         -static TEncoding TDOM_UnicodeTo8bitEncodings [] = {
   510         -    { "ascii"     , 0x3F, TDOM_UnicodeToASCII },
   511         -    { "cp1250"    , 0x3F, TDOM_UnicodeToCP1250 },
   512         -    { "cp1251"    , 0x3F, TDOM_UnicodeToCP1251 },
   513         -    { "cp1252"    , 0x3F, TDOM_UnicodeToCP1252 },
   514         -    { "cp1253"    , 0x3F, TDOM_UnicodeToCP1253 },
   515         -    { "cp1254"    , 0x3F, TDOM_UnicodeToCP1254 },
   516         -    { "cp1255"    , 0x3F, TDOM_UnicodeToCP1255 },
   517         -    { "cp1256"    , 0x3F, TDOM_UnicodeToCP1256 },
   518         -    { "cp437"     , 0x3F, TDOM_UnicodeToCP437 },
   519         -    { "cp850"     , 0x3F, TDOM_UnicodeToCP850 },
   520         -    { "iso8859-1" , 0x3F, TDOM_UnicodeToISO88591 },
   521         -    { "iso8859-2" , 0x3F, TDOM_UnicodeToISO88592 },
   522         -    { "iso8859-3" , 0x3F, TDOM_UnicodeToISO88593 },
   523         -    { "iso8859-4" , 0x3F, TDOM_UnicodeToISO88594 },
   524         -    { "iso8859-5" , 0x3F, TDOM_UnicodeToISO88595 },
   525         -    { "iso8859-6" , 0x3F, TDOM_UnicodeToISO88596 },
   526         -    { "iso8859-7" , 0x3F, TDOM_UnicodeToISO88597 },
   527         -    { "iso8859-8" , 0x3F, TDOM_UnicodeToISO88598 },
   528         -    { "iso8859-9" , 0x3F, TDOM_UnicodeToISO88599 },
   529         -    { "koi8-r"    , 0x3F, TDOM_UnicodeToKOI8R },
   530         -    { NULL, 0, NULL }
   531         -};

Changes to generic/nodecmd.c.

    84     84   |   The structure stores, which type of node the command has
    85     85   |   to create and, in case of elementNodes and if given, the
    86     86   |   namespace of the node.
    87     87   \---------------------------------------------------------------------------*/
    88     88   typedef struct NodeInfo {
    89     89       int   type;
    90     90       char *namespace;
           91  +    int   jsonType;
           92  +    char *tagName;
    91     93   } NodeInfo;
    92     94   
    93     95   #ifndef TCL_THREADS
    94     96     static CurrentStack dataKey;
    95     97   # define TSDPTR(a) a
    96     98   #else
    97     99     static Tcl_ThreadDataKey dataKey;
................................................................................
    98    100   # define TSDPTR(a) (CurrentStack*)Tcl_GetThreadData((a),sizeof(CurrentStack))
    99    101   #endif
   100    102   
   101    103   /*----------------------------------------------------------------------------
   102    104   |   Forward declarations
   103    105   |
   104    106   \---------------------------------------------------------------------------*/
   105         -static void * StackPush  _ANSI_ARGS_((void *));
   106         -static void * StackPop   _ANSI_ARGS_((void));
   107         -static void * StackTop   _ANSI_ARGS_((void));
   108         -static int    NodeObjCmd _ANSI_ARGS_((ClientData,Tcl_Interp*,int,Tcl_Obj *CONST o[]));
   109         -static void   StackFinalize _ANSI_ARGS_((ClientData));
          107  +static void * StackPush  (void *);
          108  +static void * StackPop   (void);
          109  +static void * StackTop   (void);
          110  +static int    NodeObjCmd (ClientData,Tcl_Interp*,int,Tcl_Obj *const o[]);
          111  +static void   StackFinalize (ClientData);
   110    112   
   111    113   extern int tcldom_appendXML (Tcl_Interp*, domNode*, Tcl_Obj*);
   112    114   
   113    115   
   114    116   /*----------------------------------------------------------------------------
   115    117   |   StackPush
   116    118   |
   117    119   \---------------------------------------------------------------------------*/
   118    120   static void *
   119         -StackPush (element)
   120         -    void *element;
   121         -{
          121  +StackPush (
          122  +    void *element
          123  +) {
   122    124       StackSlot *newElement;
   123    125       CurrentStack *tsdPtr = TSDPTR(&dataKey);
   124    126   
   125    127       /*-------------------------------------------------------------------
   126    128       |   Reuse already allocated stack slots, if any
   127    129       |
   128    130       \------------------------------------------------------------------*/
................................................................................
   158    160   }
   159    161   
   160    162   /*----------------------------------------------------------------------------
   161    163   |   StackPop  -  pops the element from stack
   162    164   |
   163    165   \---------------------------------------------------------------------------*/
   164    166   static void *
   165         -StackPop ()
          167  +StackPop (void)
   166    168   {
   167    169       void *element;
   168    170       CurrentStack *tsdPtr = TSDPTR(&dataKey);
   169    171   
   170    172       element = tsdPtr->currentSlot->element;
   171    173       if (tsdPtr->currentSlot->prevPtr) {
   172    174           tsdPtr->currentSlot = tsdPtr->currentSlot->prevPtr;
................................................................................
   178    180   }
   179    181   
   180    182   /*----------------------------------------------------------------------------
   181    183   |   StackTop  -  returns top-level element from stack
   182    184   |
   183    185   \---------------------------------------------------------------------------*/
   184    186   static void *
   185         -StackTop ()
          187  +StackTop (void)
   186    188   {
   187    189       CurrentStack *tsdPtr = TSDPTR(&dataKey);
   188    190   
   189    191       if (tsdPtr->currentSlot == NULL) {
   190    192           return NULL;
   191    193       }
   192    194   
................................................................................
   195    197   
   196    198   
   197    199   /*----------------------------------------------------------------------------
   198    200   |   StackFinalize - reclaims stack memory (slots only, not elements)
   199    201   |
   200    202   \---------------------------------------------------------------------------*/
   201    203   static void
   202         -StackFinalize (clientData)
   203         -    ClientData clientData;
   204         -{
          204  +StackFinalize (
          205  +    ClientData clientData
          206  +) {
   205    207       StackSlot *tmp, *stack = (StackSlot *)clientData;
   206    208   
   207    209       while (stack) {
   208    210           tmp = stack->nextPtr;
   209    211           FREE((char*)stack);
   210    212           stack = tmp;
   211    213       }
................................................................................
   227    229    *
   228    230    * Side effects:
   229    231    *	None.
   230    232    *
   231    233    *----------------------------------------------------------------------
   232    234    */
   233    235   static char*
   234         -namespaceTail (nameObj) 
   235         -    Tcl_Obj *nameObj;
          236  +namespaceTail (
          237  +    Tcl_Obj *nameObj
          238  +)    
   236    239   {
   237    240       char *name,*p;
   238    241       int   len;
   239    242       
   240    243       name = Tcl_GetStringFromObj(nameObj, &len);
   241    244       p = name + len;
   242    245       /* Isolate just the tail name, i.e. skip it's parent namespace */
................................................................................
   260    263       )
   261    264   {
   262    265       NodeInfo *nodeInfo = (NodeInfo *) clientData;
   263    266       
   264    267       if (nodeInfo->namespace) {
   265    268           FREE (nodeInfo->namespace);
   266    269       }
          270  +    if (nodeInfo->tagName) {
          271  +        FREE (nodeInfo->tagName);
          272  +    }
   267    273       FREE (nodeInfo);
   268    274   }
   269    275   
   270    276   /*----------------------------------------------------------------------------
   271    277   |   NodeObjCmd
   272    278   |
   273    279   \---------------------------------------------------------------------------*/
   274    280   static int
   275         -NodeObjCmd (arg, interp, objc, objv)
   276         -    ClientData      arg;                /* Type of node to create. */
   277         -    Tcl_Interp    * interp;             /* Current interpreter. */
   278         -    int             objc;               /* Number of arguments. */
   279         -    Tcl_Obj *CONST  objv[];             /* Argument objects. */
   280         -{
          281  +NodeObjCmd (
          282  +    ClientData      arg,                /* Type of node to create. */
          283  +    Tcl_Interp    * interp,             /* Current interpreter. */
          284  +    int             objc,               /* Number of arguments. */
          285  +    Tcl_Obj *const  objv[]             /* Argument objects. */
          286  +) {
   281    287       int type, createType, len, dlen, i, ret, disableOutputEscaping = 0, 
   282    288           index = 1;
   283    289       char *tag, *p, *tval, *aval;
   284    290       domNode *parent, *newNode = NULL;
          291  +    domTextNode *textNode = NULL;
   285    292       domDocument *doc;
   286    293       Tcl_Obj *cmdObj, **opts;
   287    294       NodeInfo *nodeInfo = (NodeInfo*) arg;
   288    295   
   289    296       /*------------------------------------------------------------------------
   290    297       |   Need parent node to get the owner document and to append new 
   291    298       |   child tag to it. The current parent node is stored on the stack.
................................................................................
   347    354               if (!tcldom_CDATACheck (interp, tval)) return TCL_ERROR;
   348    355               createType = CDATA_SECTION_NODE;
   349    356               break;
   350    357           default:
   351    358               createType = nodeInfo->type;
   352    359               break;
   353    360           }
   354         -        newNode = (domNode*)domNewTextNode(doc, tval, len, createType);
          361  +        textNode = domNewTextNode(doc, tval, len, createType);
          362  +        textNode->info = nodeInfo->jsonType;
   355    363           if (disableOutputEscaping) {
   356         -            newNode->nodeFlags |= DISABLE_OUTPUT_ESCAPING;
          364  +            textNode->nodeFlags |= DISABLE_OUTPUT_ESCAPING;
   357    365           }
   358         -        domAppendChild(parent, newNode);
          366  +        domAppendChild(parent, (domNode*) textNode);
   359    367           break;
   360    368   
   361    369       case PROCESSING_INSTRUCTION_NODE_NAME_CHK:
   362    370       case PROCESSING_INSTRUCTION_NODE_VALUE_CHK:
   363    371       case PROCESSING_INSTRUCTION_NODE_CHK:
   364    372       case PROCESSING_INSTRUCTION_NODE:
   365    373           if (objc != 3) {
................................................................................
   389    397           ret = tcldom_appendXML(interp, parent, objv[1]);
   390    398           break;
   391    399   
   392    400       case ELEMENT_NODE_ANAME_CHK:
   393    401       case ELEMENT_NODE_AVALUE_CHK:
   394    402       case ELEMENT_NODE_CHK:
   395    403       case ELEMENT_NODE:
   396         -        tag = Tcl_GetStringFromObj(objv[0], &len);
   397         -        p = tag + len;
   398         -        /* Isolate just the tag name, i.e. skip it's parent namespace */
   399         -        while (--p > tag) {
   400         -            if ((*p == ':') && (*(p-1) == ':')) {
   401         -                p++; /* just after the last "::" */
   402         -                tag = p;
   403         -                break;
          404  +        if (!nodeInfo->tagName) {
          405  +            tag = Tcl_GetStringFromObj(objv[0], &len);
          406  +            p = tag + len;
          407  +            /* Isolate just the tag name, i.e. skip it's parent namespace */
          408  +            while (--p > tag) {
          409  +                if ((*p == ':') && (*(p-1) == ':')) {
          410  +                    p++; /* just after the last "::" */
          411  +                    tag = p;
          412  +                    break;
          413  +                }
   404    414               }
          415  +        } else {
          416  +            tag = nodeInfo->tagName;
   405    417           }
   406    418   
   407         -        newNode = domAppendNewElementNode (parent, tag, NULL);
          419  +        newNode = domAppendNewElementNode (parent, tag, nodeInfo->namespace);
          420  +        newNode->info = nodeInfo->jsonType;
   408    421           
   409    422           /*
   410    423            * Allow for following syntax:
   411    424            *   cmd ?-option value ...? ?script?
   412    425            *   cmd ?opton value ...? ?script?
   413    426            *   cmd key_value_list script
   414    427            *       where list contains "-key value ..." or "key value ..."
................................................................................
   500    513   |           set title [html::title {html::t "This is an example"}]
   501    514   |           $title setAttribute dummy 1
   502    515   |      }
   503    516   |      % puts [$n asHTML]
   504    517   |
   505    518   \---------------------------------------------------------------------------*/
   506    519   int
   507         -nodecmd_createNodeCmd (interp, objc, objv, checkName, checkCharData)
   508         -    Tcl_Interp    * interp;             /* Current interpreter. */
   509         -    int             objc;               /* Number of arguments. */
   510         -    Tcl_Obj *CONST  objv[];             /* Argument objects. */
   511         -    int             checkName;          /* Flag: Name checks? */
   512         -    int             checkCharData;      /* Flag: Data checks? */
   513         -{
   514         -    int ix, index, ret, type, nodecmd = 0;
          520  +nodecmd_createNodeCmd (
          521  +    Tcl_Interp    * interp,             /* Current interpreter. */
          522  +    int             objc,               /* Number of arguments. */
          523  +    Tcl_Obj *const  objv[],             /* Argument objects. */
          524  +    int             checkName,          /* Flag: Name checks? */
          525  +    int             checkCharData       /* Flag: Data checks? */
          526  +) {
          527  +    int index, ret, type, nodecmd = 0, jsonType = 0, haveJsonType = 0;
          528  +    int isElement = 0;
   515    529       char *nsName, buf[64];
          530  +    Tcl_Obj *tagName = NULL, *namespace = NULL;
   516    531       Tcl_DString cmdName;
   517    532       NodeInfo *nodeInfo;
   518    533   
   519    534       /*
   520    535        * Syntax:  
   521    536        *
   522    537        *     dom createNodeCmd ?-returnNodeCmd? nodeType commandName
   523    538        */
   524    539   
   525    540       enum subCmd {
   526    541           ELM_NODE, TXT_NODE, CDS_NODE, CMT_NODE, PIC_NODE, PRS_NODE
   527    542       };
   528    543   
   529         -    static CONST84 char *subcmds[] = {
          544  +    static const char *subcmds[] = {
   530    545           "elementNode", "textNode", "cdataNode", "commentNode", "piNode",
   531    546           "parserNode", NULL
   532    547       };
   533    548   
   534         -    if (objc != 3 && objc != 4) {
          549  +    static const char *options[] = {
          550  +        "-returnNodeCmd", "-jsonType", "-tagName", "-namespace", NULL
          551  +    };
          552  +
          553  +    enum option {
          554  +        o_returnNodeCmd, o_jsonType, o_tagName, o_namespace
          555  +    };
          556  +
          557  +    static const char *jsonTypes[] = {
          558  +        "NONE",
          559  +        "ARRAY",
          560  +        "OBJECT",
          561  +        "NULL",
          562  +        "TRUE",
          563  +        "FALSE",
          564  +        "STRING",
          565  +        "NUMBER"
          566  +    };
          567  +
          568  +    if (objc < 3 ) {
          569  +        goto usage;
          570  +    }
          571  +
          572  +    while (objc > 3) {
          573  +        if (Tcl_GetIndexFromObj (interp, objv[1], options, "option",
          574  +                                 0, &index) != TCL_OK) {
          575  +            return TCL_ERROR;
          576  +        }
          577  +        switch ((enum option) index) {
          578  +        case o_returnNodeCmd:
          579  +            nodecmd = 1;
          580  +            objc--;
          581  +            objv++;
          582  +            break;
          583  +            
          584  +        case o_jsonType:
          585  +            if (Tcl_GetIndexFromObj (interp, objv[2], jsonTypes, "jsonType",
          586  +                                     1, &jsonType) != TCL_OK) {
          587  +                return TCL_ERROR;
          588  +            }
          589  +            haveJsonType = 1;
          590  +            objc -= 2;
          591  +            objv += 2;
          592  +            break;
          593  +            
          594  +        case o_tagName:
          595  +            tagName = objv[2];
          596  +            objc -= 2;
          597  +            objv += 2;
          598  +            break;
          599  +
          600  +        case o_namespace:
          601  +            namespace = objv[2];
          602  +            objc -= 2;
          603  +            objv += 2;
          604  +            break;
          605  +            
          606  +        }
          607  +    }
          608  +    if (objc != 3) {
   535    609           goto usage;
   536    610       }
   537         -    if (objc == 4) {
   538         -        if (strcmp(Tcl_GetString(objv[1]), "-returnNodeCmd")) {
   539         -            goto usage;
   540         -        }
   541         -        nodecmd = 1;
   542         -        ix = 2;
   543         -    } else {
   544         -        nodecmd = 0;
   545         -        ix = 1;
   546         -    }
   547         -    ret = Tcl_GetIndexFromObj(interp, objv[ix], subcmds, "option", 0, &index);
          611  +
          612  +    ret = Tcl_GetIndexFromObj(interp, objv[1], subcmds, "nodeType", 0, &index);
   548    613       if (ret != TCL_OK) {
   549    614           return ret;
   550    615       }
   551    616   
   552    617       /*--------------------------------------------------------------------
   553    618       |   Construct fully qualified command name using current namespace
   554    619       |
................................................................................
   560    625           return ret;
   561    626       }
   562    627       nsName = (char *)Tcl_GetStringResult(interp);
   563    628       Tcl_DStringAppend(&cmdName, nsName, -1);
   564    629       if (strcmp(nsName, "::")) {
   565    630           Tcl_DStringAppend(&cmdName, "::", 2);
   566    631       }
   567         -    Tcl_DStringAppend(&cmdName, Tcl_GetString(objv[ix+1]), -1);
          632  +    Tcl_DStringAppend(&cmdName, Tcl_GetString(objv[2]), -1);
   568    633   
   569         -    nodeInfo = (NodeInfo *) MALLOC (sizeof (NodeInfo));
   570         -    nodeInfo->namespace = NULL;
   571    634       Tcl_ResetResult (interp);
   572    635       switch ((enum subCmd)index) {
   573    636       case ELM_NODE: 
   574         -        if (!tcldom_nameCheck(interp, namespaceTail(objv[ix+1]), "tag", 0)) {
   575         -            FREE (nodeInfo);
   576         -            return TCL_ERROR;
   577         -        }
   578         -        if (checkName && checkCharData) {
   579         -            type = ELEMENT_NODE_CHK;
   580         -        } else if (checkName) {
   581         -            type = ELEMENT_NODE_ANAME_CHK;
   582         -        } else if (checkCharData) {
   583         -            type = ELEMENT_NODE_AVALUE_CHK;
          637  +        isElement = 1;
          638  +        if (!haveJsonType) {
          639  +            if (!tcldom_nameCheck(interp, namespaceTail(objv[2]),
          640  +                                  "tag", 0)) {
          641  +                return TCL_ERROR;
          642  +            }
          643  +            if (checkName && checkCharData) {
          644  +                type = ELEMENT_NODE_CHK;
          645  +            } else if (checkName) {
          646  +                type = ELEMENT_NODE_ANAME_CHK;
          647  +            } else if (checkCharData) {
          648  +                type = ELEMENT_NODE_AVALUE_CHK;
          649  +            } else {
          650  +                type = ELEMENT_NODE;
          651  +            }
   584    652           } else {
          653  +            if (jsonType > 2) {
          654  +                Tcl_SetResult(interp, "For an element node the jsonType"
          655  +                              " argument must be one out of this list: ARRAY"
          656  +                              " OBJECT NONE.", NULL);
          657  +                return TCL_ERROR;
          658  +            }
   585    659               type = ELEMENT_NODE;
   586    660           }
   587    661           break;
   588    662       case PRS_NODE: 
   589    663           type = PARSER_NODE;
   590    664           break;
   591    665       case TXT_NODE: 
   592         -        if (checkCharData) {
   593         -            type = TEXT_NODE_CHK;
          666  +        if (!haveJsonType) {
          667  +            if (checkCharData) {
          668  +                type = TEXT_NODE_CHK;
          669  +            } else {
          670  +                type = TEXT_NODE;
          671  +            }
   594    672           } else {
          673  +            if (jsonType < 3 && jsonType > 0) {
          674  +                Tcl_SetResult(interp, "For a text node the jsonType "
          675  +                              "argument must be one out of this list: "
          676  +                              "TRUE FALSE NULL NUMBER STRING NONE",
          677  +                              NULL);
          678  +                return TCL_ERROR;
          679  +            }
   595    680               type = TEXT_NODE;
   596    681           }
   597    682           break;
   598    683       case CDS_NODE: 
   599    684           if (checkCharData) {
   600    685               type = CDATA_SECTION_NODE_CHK;
   601    686           } else {
................................................................................
   616    701               type = PROCESSING_INSTRUCTION_NODE_NAME_CHK;
   617    702           } else if (checkCharData) {
   618    703               type = PROCESSING_INSTRUCTION_NODE_VALUE_CHK;
   619    704           } else {
   620    705               type = PROCESSING_INSTRUCTION_NODE;
   621    706           }
   622    707           break;
          708  +    default:
          709  +        Tcl_SetResult (interp, "Invalid/unexpected node type", NULL);
          710  +        return TCL_ERROR;
          711  +    }
          712  +
          713  +    if (tagName && !isElement) {
          714  +        Tcl_SetResult(interp, "The -tagName option is allowed only for "
          715  +                      "element node commands.", NULL);
          716  +        return TCL_ERROR;        
          717  +    }
          718  +
          719  +    if (namespace && !isElement) {
          720  +        Tcl_SetResult(interp, "The -namespace option is allowed only for "
          721  +                      "element node commands.", NULL);
          722  +        return TCL_ERROR;        
          723  +    }
          724  +    
          725  +    if (haveJsonType && type != ELEMENT_NODE && type != TEXT_NODE) {
          726  +        Tcl_SetResult(interp, "Only element and text nodes may have a "
          727  +                      "JSON type.", NULL);
          728  +        return TCL_ERROR;        
   623    729       }
   624    730       
          731  +    nodeInfo = (NodeInfo *) MALLOC (sizeof (NodeInfo));
          732  +    nodeInfo->namespace = NULL;
   625    733       nodeInfo->type = type;
   626    734       if (nodecmd) {
   627    735           nodeInfo->type *= -1; /* Signal this fact */
   628    736       }
          737  +    nodeInfo->jsonType = jsonType;
          738  +    nodeInfo->tagName = NULL;
          739  +    if (namespace) {
          740  +        nodeInfo->namespace = tdomstrdup (Tcl_GetString(namespace));
          741  +    }
          742  +    if (tagName) {
          743  +        nodeInfo->tagName = tdomstrdup (Tcl_GetString(tagName));
          744  +    }
   629    745       Tcl_CreateObjCommand(interp, Tcl_DStringValue(&cmdName), NodeObjCmd,
   630    746                            (ClientData)nodeInfo, NodeObjCmdDeleteProc);
   631    747       Tcl_DStringResult(interp, &cmdName);
   632    748       Tcl_DStringFree(&cmdName);
   633    749   
   634    750       return TCL_OK;
   635    751   
   636    752    usage:
   637         -    Tcl_AppendResult(interp, "dom createNodeCmd ?-returnNodeCmd?"
          753  +    Tcl_AppendResult(interp, "dom createNodeCmd\n"
          754  +                     "\t?-returnNodeCmd?\n"
          755  +                     "\t?-jsonType <jsonType>?\n"
          756  +                     "\t?-tagName <tagName>?\n"
   638    757                        " nodeType cmdName", NULL);
   639    758       return TCL_ERROR;
   640    759   }
   641    760   
   642    761   
   643    762   /*
   644    763    *----------------------------------------------------------------------
................................................................................
   654    773    * Side effects:
   655    774    *	Appends new child nodes to node.
   656    775    *
   657    776    *----------------------------------------------------------------------
   658    777    */
   659    778   
   660    779   int
   661         -nodecmd_appendFromScript (interp, node, cmdObj)
   662         -    Tcl_Interp *interp;                 /* Current interpreter. */
   663         -    domNode    *node;                   /* Parent dom node */
   664         -    Tcl_Obj    *cmdObj;                 /* Argument objects. */
   665         -{
          780  +nodecmd_appendFromScript (
          781  +    Tcl_Interp *interp,                /* Current interpreter. */
          782  +    domNode    *node,                  /* Parent dom node */
          783  +    Tcl_Obj    *cmdObj                 /* Argument objects. */
          784  +) {
   666    785       int ret;
   667    786       domNode *oldLastChild, *child, *nextChild;
   668    787   
   669    788       if (node->nodeType != ELEMENT_NODE) {
   670    789           Tcl_SetResult (interp, "NOT_AN_ELEMENT : can't append nodes", NULL);
   671    790           return TCL_ERROR;
   672    791       }
   673    792       
   674    793       oldLastChild = node->lastChild;
   675    794   
   676    795       StackPush((void *)node);
   677    796       Tcl_AllowExceptions(interp);
   678         -    ret = Tcl_EvalObj(interp, cmdObj);
          797  +    ret = Tcl_EvalObjEx(interp, cmdObj, 0);
   679    798       if (ret != TCL_ERROR) {
   680    799           Tcl_ResetResult(interp);
   681    800       }
   682    801       StackPop();
   683    802   
   684    803       if (ret == TCL_ERROR) {
   685    804           if (oldLastChild) {
................................................................................
   723    842    * Side effects:
   724    843    *	Insert new child nodes before referenceChild to node.
   725    844    *
   726    845    *----------------------------------------------------------------------
   727    846    */
   728    847   
   729    848   int
   730         -nodecmd_insertBeforeFromScript (interp, node, cmdObj, refChild)
   731         -    Tcl_Interp *interp;                 /* Current interpreter. */
   732         -    domNode    *node;                   /* Parent dom node */
   733         -    Tcl_Obj    *cmdObj;                 /* Argument objects. */
   734         -    domNode    *refChild;               /* Insert new childs before this
          849  +nodecmd_insertBeforeFromScript (
          850  +    Tcl_Interp *interp,                 /* Current interpreter. */
          851  +    domNode    *node,                   /* Parent dom node */
          852  +    Tcl_Obj    *cmdObj,                 /* Argument objects. */
          853  +    domNode    *refChild                /* Insert new childs before this
   735    854                                            * node; may be NULL */
   736         -{
          855  +) {
   737    856       int      ret;
   738    857       domNode *storedLastChild, *n;
   739    858   
   740    859       if (!refChild) {
   741    860           return nodecmd_appendFromScript (interp, node, cmdObj);
   742    861       }
   743    862       

Changes to generic/nodecmd.h.

    30     30   |   Written by Zoran Vasiljevic
    31     31   |   July 12, 2000
    32     32   |
    33     33   \---------------------------------------------------------------------------*/
    34     34   
    35     35   int nodecmd_createNodeCmd (Tcl_Interp    * interp,
    36     36                              int             objc,
    37         -                           Tcl_Obj *CONST  objv[],
           37  +                           Tcl_Obj *const  objv[],
    38     38                              int             checkName,
    39     39                              int             checkCharData);
    40     40   
    41     41   int nodecmd_appendFromScript (Tcl_Interp *interp, 
    42     42                                 domNode    *node,
    43     43                                 Tcl_Obj    *cmdObj);
    44     44   

Changes to generic/tcldom.c.

    38     38   
    39     39   
    40     40   /*----------------------------------------------------------------------------
    41     41   |   Includes
    42     42   |
    43     43   \---------------------------------------------------------------------------*/
    44     44   #include <tcl.h>
    45         -#include <stdlib.h>
    46         -#include <string.h>
    47         -#include <ctype.h>
    48     45   #include <dom.h>
    49     46   #include <domxpath.h>
    50     47   #include <domxslt.h>
    51     48   #include <xmlsimple.h>
           49  +#include <domjson.h>
    52     50   #include <domhtml.h>
           51  +#include <domhtml5.h>
    53     52   #include <nodecmd.h>
    54     53   #include <tcldom.h>
           54  +#include <versionhash.h>
    55     55   
    56     56   /* #define DEBUG */
    57     57   /*----------------------------------------------------------------------------
    58     58   |   Debug Macros
    59     59   |
    60     60   \---------------------------------------------------------------------------*/
    61     61   #ifdef DEBUG
................................................................................
    72     72   #define XP_CHILD         0
    73     73   #define XP_DESCENDANT    1
    74     74   #define XP_ANCESTOR      2
    75     75   #define XP_FSIBLING      3
    76     76   #define XP_PSIBLING      4
    77     77   
    78     78   #define MAX_REWRITE_ARGS 50
           79  +
           80  +#define MAX_XSLT_APPLY_DEPTH 3000
    79     81   
    80     82   #define SetResult(str) Tcl_ResetResult(interp); \
    81     83                        Tcl_SetStringObj(Tcl_GetObjResult(interp), (str), -1)
    82     84   
    83         -#define SetIntResult(i) Tcl_ResetResult(interp); \
           85  +#define SetResult3(str1,str2,str3) Tcl_ResetResult(interp);     \
           86  +                     Tcl_AppendResult(interp, (str1), (str2), (str3), NULL)
           87  +
           88  +#define SetIntResult(i) Tcl_ResetResult(interp);                        \
    84     89                        Tcl_SetIntObj(Tcl_GetObjResult(interp), (i))
    85     90                        
    86     91   #define SetDoubleResult(d) Tcl_ResetResult(interp); \
    87     92                        Tcl_SetDoubleObj(Tcl_GetObjResult(interp), (d))
    88     93   
    89     94   #define SetBooleanResult(i) Tcl_ResetResult(interp); \
    90     95                        Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (i))
................................................................................
   139    144   #define CheckPIValue(interp, text) \
   140    145                        if (!TSD(dontCheckCharData)) { \
   141    146                            if (!tcldom_PIValueCheck(interp, text)) {\
   142    147                                return TCL_ERROR; \
   143    148                            } \
   144    149                        }
   145    150   
   146         -#if TclOnly8Bits
   147         -#define writeChars(var,chan,buf,len)  (chan) ? \
   148         -                     ((void)Tcl_Write ((chan), (buf), (len) )) : \
   149         -                     (Tcl_AppendToObj ((var), (buf), (len) ));
   150         -#else
   151    151   #define writeChars(var,chan,buf,len)  (chan) ? \
   152    152                        ((void)Tcl_WriteChars ((chan), (buf), (len) )) : \
   153    153                        (Tcl_AppendToObj ((var), (buf), (len) ));
   154         -#endif
   155    154   
   156    155   #define DOM_CREATECMDMODE_AUTO 0
   157    156   #define DOM_CREATECMDMODE_CMDS 1
   158    157   #define DOM_CREATECMDMODE_TOKENS 2
   159    158   
          159  +#define SERIALIZE_XML_DECLARATION 1
          160  +#define SERIALIZE_DOCTYPE_DECLARATION 2
          161  +#define SERIALIZE_FOR_ATTR 4 
          162  +#define SERIALIZE_ESCAPE_NON_ASCII 8
          163  +#define SERIALIZE_HTML_ENTITIES 16
          164  +#define SERIALIZE_ESCAPE_ALL_QUOT 32
          165  +#define SERIALIZE_NO_GT_ESCAPE 64
          166  +#define SERIALIZE_NO_EMPTY_ELEMENT_TAG 128
          167  +
   160    168   /*----------------------------------------------------------------------------
   161    169   |   Module Globals
   162    170   |
   163    171   \---------------------------------------------------------------------------*/
   164    172   #ifndef TCL_THREADS
   165         -    static TEncoding *Encoding_to_8bit      = NULL;
   166    173       static int        storeLineColumn       = 0;
   167    174       static int        dontCreateObjCommands = 0;
   168    175       static int        dontCheckCharData     = 0;
   169    176       static int        dontCheckName         = 0;
   170    177       static int        domCreateCmdMode      = 0;
   171    178   #   define TSD(x)     x
   172    179   #   define GetTcldomTSD()
   173    180   #else
   174    181       typedef struct ThreadSpecificData {
   175         -        TEncoding *Encoding_to_8bit;
   176    182           int        storeLineColumn;
   177    183           int        dontCreateObjCommands;
   178    184           int        dontCheckCharData;
   179    185           int        dontCheckName;
   180    186           int        domCreateCmdMode;
   181    187       } ThreadSpecificData;
   182    188       static Tcl_ThreadDataKey dataKey;
................................................................................
   191    197                                       sizeof(ThreadSpecificData));
   192    198   #endif /* TCL_THREADS */
   193    199   
   194    200   static char dom_usage[] =
   195    201       "Usage dom <subCommand> <args>, where subCommand can be:    \n"
   196    202       "    parse ?-keepEmpties? ?-channel <channel> ?-baseurl <baseurl>?  \n"
   197    203       "        ?-feedbackAfter <#Bytes>?                    \n"
          204  +    "        ?-feedbackcmd <cmd>?                         \n"
   198    205       "        ?-externalentitycommand <cmd>?               \n"
   199    206       "        ?-useForeignDTD <boolean>?                   \n"
   200    207       "        ?-paramentityparsing <none|always|standalone>\n"
   201         -    "        ?-simple? ?-html? ?<xml>? ?<objVar>?         \n"
          208  +    "        ?-simple? ?-html? ?-html5? ?-json?           \n"
          209  +    "        ?-jsonmaxnesting <#nr>?                      \n"
          210  +    "        ?-jsonroot name?                             \n"
          211  +    "        ?<xml|html|json>? ?<objVar>?                 \n"
   202    212       "    createDocument docElemName ?objVar?              \n"
   203    213       "    createDocumentNS uri docElemName ?objVar?        \n"
   204    214       "    createDocumentNode ?objVar?                      \n"
   205    215       TDomThreaded(
   206    216       "    attachDocument domDoc ?objVar?                   \n"
   207    217       "    detachDocument domDoc                            \n"
   208    218       )
   209         -    "    createNodeCmd ?-returnNodeCmd? (element|comment|text|cdata|pi)Node cmdName \n"
   210         -    "    setResultEncoding ?encodingName?                 \n"
          219  +    "    createNodeCmd ?-returnNodeCmd? ?-tagName name? ?-jsonType jsonType? ?-namespace URI? (element|comment|text|cdata|pi)Node cmdName \n"
   211    220       "    setStoreLineColumn ?boolean?                     \n"
   212    221       "    setNameCheck ?boolean?                           \n"
   213    222       "    setTextCheck ?boolean?                           \n"
   214    223       "    setObjectCommands ?(automatic|token|command)?    \n"
   215    224       "    isCharData string                                \n"
   216    225       "    isComment string                                 \n"
   217    226       "    isCDATA string                                   \n"
   218    227       "    isPIValue string                                 \n"
   219    228       "    isName string                                    \n"
   220    229       "    isQName string                                   \n"
   221    230       "    isNCName string                                  \n"
   222    231       "    isPIName string                                  \n"
          232  +    "    featureinfo feature                              \n"
   223    233   ;
   224    234   
   225    235   static char doc_usage[] =
   226    236       "Usage domDoc <method> <args>, where method can be:\n"
   227    237       "    documentElement ?objVar?                \n"
   228    238       "    getElementsByTagName name               \n"
   229    239       "    getElementsByTagNameNS uri localname    \n"
................................................................................
   232    242       "    createCDATASection data ?objVar?        \n"
   233    243       "    createTextNode text ?objVar?            \n"
   234    244       "    createComment text ?objVar?             \n"
   235    245       "    createProcessingInstruction target data ?objVar? \n"
   236    246       "    asXML ?-indent <none,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
   237    247       "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
   238    248       "    asText                                  \n"
          249  +    "    asJSON ?-indent <none,0..8>?            \n"
   239    250       "    getDefaultOutputMethod                  \n"
   240    251       "    publicId ?publicId?                     \n"
   241    252       "    systemId ?systemId?                     \n"
   242    253       "    internalSubset ?internalSubset?         \n"
   243    254       "    indent ?boolean?                        \n"
   244    255       "    omit-xml-declaration ?boolean?          \n"
   245    256       "    encoding ?value?                        \n"
................................................................................
   295    306       "    setAttribute attrName value ?attrName value ...? \n"
   296    307       "    removeAttribute attrName     \n"
   297    308       "    hasAttributeNS uri localName \n"
   298    309       "    getAttributeNS uri localName ?defaultValue? \n"
   299    310       "    setAttributeNS uri attrName value ?attrName value ...? \n"
   300    311       "    removeAttributeNS uri attrName \n"
   301    312       "    attributes ?attrNamePattern?   \n"
          313  +    "    attributeNames ?attrNamePattern?   \n"
   302    314       "    appendChild new              \n"
   303    315       "    insertBefore new ref         \n"
   304    316       "    replaceChild new old         \n"
   305    317       "    removeChild child            \n"
   306    318       "    cloneNode ?-deep?            \n"
   307    319       "    ownerDocument                \n"
   308    320       "    getElementsByTagName name    \n"
................................................................................
   327    339       "    getLine                      \n"
   328    340       "    getColumn                    \n"
   329    341       "    @<attrName> ?defaultValue?   \n"
   330    342       "    asList                       \n"
   331    343       "    asXML ?-indent <none,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
   332    344       "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
   333    345       "    asText                       \n"
          346  +    "    asJSON ?-indent <none,0..8>? \n"
   334    347       "    appendFromList nestedList    \n"
   335    348       "    appendFromScript script      \n"
   336    349       "    insertBeforeFromScript script ref \n"
   337    350       "    appendXML xmlString          \n"
   338    351       "    selectNodes ?-namespaces prefixUriList? ?-cache <boolean>? xpathQuery ?typeVar? \n"
   339         -    "    toXPath                      \n"
          352  +    "    toXPath ?-legacy?            \n"
   340    353       "    disableOutputEscaping ?boolean? \n"
   341    354       "    precedes node                \n"
   342    355       "    normalize ?-forXPath?        \n"
   343    356       "    xslt ?-parameters parameterList? <xsltDocNode>\n"
          357  +    "    jsonType ?jsonType?          \n"
   344    358       TDomThreaded(
   345    359       "    readlock                     \n"
   346    360       "    writelock                    \n"
   347    361       )
   348    362   ;
          363  +
          364  +static const char *jsonTypes[] = {
          365  +    "NONE",
          366  +    "ARRAY",
          367  +    "OBJECT",
          368  +    "NULL",
          369  +    "TRUE",
          370  +    "FALSE",
          371  +    "STRING",
          372  +    "NUMBER",
          373  +    NULL
          374  +};
   349    375   
   350    376   /*----------------------------------------------------------------------------
   351    377   |   Types
   352    378   |
   353    379   \---------------------------------------------------------------------------*/
   354    380   
   355    381   typedef struct XsltMsgCBInfo {
   356    382       Tcl_Interp * interp;
   357    383       Tcl_Obj    * msgcmd;
   358    384   } XsltMsgCBInfo;
   359    385   
          386  +
          387  +static void UpdateStringOfTdomNode(Tcl_Obj *objPtr);
          388  +static int  SetTdomNodeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
          389  +
          390  +const Tcl_ObjType tdomNodeType = {
          391  +    "tdom-node",
          392  +    NULL,
          393  +    NULL,
          394  +    UpdateStringOfTdomNode,
          395  +    SetTdomNodeFromAny
          396  +};
          397  +
   360    398   /*----------------------------------------------------------------------------
   361    399   |   Prototypes for procedures defined later in this file:
   362    400   |
   363    401   \---------------------------------------------------------------------------*/
   364         -
          402  +#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3)
          403  +/*
          404  + * Before Tcl 8.4, Tcl_VarTraceProc and Tcl_CmdDeleteProc were not
          405  + * CONST84'ified. When compiling with -DTCL_NO_DEPRECATED, CONST84 is
          406  + * gone, therefore we can't use the function type definitions of
          407  + * Tcl_VarTraceProc and Tcl_CmdDeleteProc for these old version.
          408  + * 
          409  + */
          410  +static char * tcldom_docTrace(
          411  +    ClientData clientData, Tcl_Interp *interp,
          412  +    const char *part1, const char *part2, int flags);
          413  +static void tcldom_docCmdDeleteProc(ClientData clientData);
          414  +#else 
   365    415   static Tcl_VarTraceProc  tcldom_docTrace;
   366         -static Tcl_VarTraceProc  tcldom_nodeTrace;
   367         -
   368    416   static Tcl_CmdDeleteProc tcldom_docCmdDeleteProc;
   369         -static Tcl_CmdDeleteProc tcldom_nodeCmdDeleteProc;
          417  +#endif
          418  +
          419  +static void tcldom_treeAsJSON(Tcl_Obj *jstring, domNode *node,
          420  +                              Tcl_Channel channel, int indent,
          421  +                              int level,
          422  +                              int inside);
   370    423   
   371    424   #ifdef TCL_THREADS
   372    425   
   373    426   static int tcldom_EvalLocked(Tcl_Interp* interp, Tcl_Obj** objv,
   374    427                                domDocument* doc, int flag);
   375    428   
   376    429   static int tcldom_RegisterDocShared(domDocument* doc);
................................................................................
   388    441   \---------------------------------------------------------------------------*/
   389    442   
   390    443   static void 
   391    444   tcldom_Finalize(
   392    445       ClientData unused
   393    446   )
   394    447   {
          448  +    DBG(fprintf(stderr, "--> tcldom_Finalize\n"));
   395    449       Tcl_MutexLock(&tableMutex);
   396    450       Tcl_DeleteHashTable(&sharedDocs);
          451  +    tcldomInitialized = 0;
   397    452       Tcl_MutexUnlock(&tableMutex);
   398    453   }
   399    454   
   400    455   /*----------------------------------------------------------------------------
   401    456   |   tcldom_initialize
   402    457   |   Activated at module load to initialize shared document table.
   403    458   |   This is exported since we need it in tdominit.c.
   404    459   \---------------------------------------------------------------------------*/
   405    460   
   406         -void tcldom_initialize()
          461  +void tcldom_initialize(void)
   407    462   {
   408    463       if (!tcldomInitialized) {
          464  +        DBG(fprintf(stderr, "--> tcldom_initialize\n"));
   409    465           Tcl_MutexLock(&tableMutex);
   410    466           Tcl_InitHashTable(&sharedDocs, TCL_ONE_WORD_KEYS);
   411    467           Tcl_CreateExitHandler(tcldom_Finalize, NULL);
   412    468           tcldomInitialized = 1;
   413    469           Tcl_MutexUnlock(&tableMutex);
   414    470       }
   415    471   }
................................................................................
   462    518   static
   463    519   void tcldom_docCmdDeleteProc(
   464    520       ClientData clientData
   465    521   )
   466    522   {
   467    523       domDeleteInfo *dinfo = (domDeleteInfo *)clientData;
   468    524       domDocument   *doc   = dinfo->document;
   469         -    char          *var   = dinfo->traceVarName;
          525  +    int            hasTrace  = dinfo->document->nodeFlags & VAR_TRACE;
   470    526       
   471    527       DBG(fprintf(stderr, "--> tcldom_docCmdDeleteProc doc %p\n", doc));
   472         -    if (var) {
   473         -        DBG(fprintf(stderr, "--> tcldom_docCmdDeleteProc calls "
   474         -                    "Tcl_UntraceVar for \"%s\"\n", var));
   475         -        Tcl_UntraceVar(dinfo->interp, var, TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
   476         -                       tcldom_docTrace, clientData);
   477         -        FREE(var);
   478         -        dinfo->traceVarName = NULL;
   479         -    }
   480         -
   481    528       tcldom_deleteDoc(dinfo->interp, doc);
   482    529   
   483         -    FREE((void*)dinfo);
          530  +    if (hasTrace) {
          531  +        dinfo->document = NULL;
          532  +    } else {
          533  +        FREE((void*)dinfo);
          534  +    }
   484    535   }
   485         -
   486         -
   487         -/*----------------------------------------------------------------------------
   488         -|   tcldom_nodeCmdDeleteProc
   489         -|
   490         -\---------------------------------------------------------------------------*/
   491         -static
   492         -void tcldom_nodeCmdDeleteProc (
   493         -    ClientData  clientData
   494         -)
   495         -{
   496         -    domDeleteInfo *dinfo = (domDeleteInfo *)clientData;
   497         -    char          *var   = dinfo->traceVarName;
   498         -
   499         -    DBG(fprintf (stderr, "--> tcldom_nodeCmdDeleteProc node %p\n", 
   500         -                 dinfo->node));
   501         -
   502         -    if (var) {
   503         -         DBG(fprintf(stderr, "--> tcldom_nodeCmdDeleteProc calls "
   504         -                    "Tcl_UntraceVar for \"%s\"\n", var));
   505         -        Tcl_UntraceVar(dinfo->interp, var, 
   506         -                       TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
   507         -                       tcldom_nodeTrace, clientData);
   508         -        FREE(var);
   509         -        dinfo->traceVarName = NULL;
   510         -    }
   511         -    FREE((void*)dinfo);
   512         -}
   513         -
   514    536   
   515    537   /*----------------------------------------------------------------------------
   516    538   |   tcldom_docTrace
   517    539   |
   518    540   \---------------------------------------------------------------------------*/
   519    541   static
   520    542   char * tcldom_docTrace (
   521    543       ClientData    clientData,
   522    544       Tcl_Interp   *interp,
   523         -    CONST84 char *name1,
   524         -    CONST84 char *name2,
          545  +    const char *name1,
          546  +    const char *name2,
   525    547       int           flags
   526    548   )
   527    549   {
   528    550       domDeleteInfo *dinfo = (domDeleteInfo*) clientData;
   529    551       domDocument   *doc   = dinfo->document;
   530    552       char           objCmdName[80];
   531    553   
   532    554       DBG(fprintf(stderr, "--> tcldom_docTrace %x %p\n", flags, doc));
   533    555   
   534         -    if (flags & TCL_INTERP_DESTROYED) {
          556  +    if (doc == NULL) {
          557  +        if (!(flags & TCL_INTERP_DESTROYED)) {
          558  +            Tcl_UntraceVar(dinfo->interp, dinfo->traceVarName,
          559  +                           TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
          560  +                           tcldom_docTrace, clientData);
          561  +        }
          562  +        FREE (dinfo->traceVarName);
          563  +        FREE (dinfo);
   535    564           return NULL;
   536    565       }
   537    566       if (flags & TCL_TRACE_WRITES) {
          567  +        DOC_CMD(objCmdName, doc);
          568  +        Tcl_SetVar2 (interp, name1, name2, objCmdName, TCL_LEAVE_ERR_MSG);
   538    569           return "var is read-only";
   539    570       }
   540    571       if (flags & TCL_TRACE_UNSETS) {
   541    572           DOC_CMD(objCmdName, doc);
   542    573           DBG(fprintf(stderr, "--> tcldom_docTrace delete doc %p\n", doc));
   543    574           Tcl_DeleteCommand(interp, objCmdName);
          575  +        FREE (dinfo->traceVarName);
          576  +        FREE (dinfo);
   544    577       }
   545    578   
   546    579       return NULL;
   547    580   }
   548    581   
   549         -
   550         -/*----------------------------------------------------------------------------
   551         -|   tcldom_nodeTrace
   552         -|
   553         -\---------------------------------------------------------------------------*/
   554         -static
   555         -char * tcldom_nodeTrace (
   556         -    ClientData    clientData,
   557         -    Tcl_Interp   *interp,
   558         -    CONST84 char *name1,
   559         -    CONST84 char *name2,
   560         -    int           flags
   561         -)
   562         -{
   563         -    domDeleteInfo *dinfo = (domDeleteInfo*)clientData;
   564         -    domNode       *node = dinfo->node;
   565         -    char           objCmdName[80];
   566         -
   567         -    DBG(fprintf(stderr, "--> tcldom_nodeTrace %x %p\n", flags, node));
   568         -
   569         -    if (flags & TCL_INTERP_DESTROYED) {
   570         -        return NULL;
   571         -    }
   572         -    if (flags & TCL_TRACE_WRITES) {
   573         -        return "var is read-only";
   574         -    }
   575         -    if (flags & TCL_TRACE_UNSETS) {
   576         -        NODE_CMD(objCmdName, node);
   577         -        DBG(fprintf(stderr, "--> tcldom_nodeTrace delete node %p\n", node));
   578         -        Tcl_UntraceVar(interp, name1, TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
   579         -                       tcldom_nodeTrace, clientData);
   580         -        Tcl_DeleteCommand(interp, objCmdName);
   581         -        node->nodeFlags &= ~VISIBLE_IN_TCL;
   582         -    }
   583         -
   584         -    return NULL;
   585         -}
   586         -
          582  +/*----------------------------------------------------------------------------
          583  +|   UpdateStringOfTdomNode
          584  +|
          585  +\---------------------------------------------------------------------------*/
          586  +static void
          587  +UpdateStringOfTdomNode(
          588  +    Tcl_Obj *objPtr)
          589  +{
          590  +    char nodeName[80];
          591  +    int  len;
          592  +    
          593  +    NODE_CMD(nodeName, objPtr->internalRep.otherValuePtr);
          594  +    len = strlen(nodeName);
          595  +    objPtr->bytes = (ckalloc((unsigned char) len+1));
          596  +    memcpy(objPtr->bytes, nodeName, len+1);
          597  +    objPtr->length = len;
          598  +}
          599  +
          600  +/*----------------------------------------------------------------------------
          601  +|   SetTdomNodeFromAny
          602  +|
          603  +\---------------------------------------------------------------------------*/
          604  +static int
          605  +SetTdomNodeFromAny(
          606  +    Tcl_Interp *interp,		/* Tcl interpreter or NULL */
          607  +    Tcl_Obj *objPtr)		/* Pointer to the object to parse */
          608  +{
          609  +    Tcl_CmdInfo  cmdInfo;
          610  +    domNode     *node = NULL;
          611  +    char        *nodeName;
          612  +    char         eolcheck;
          613  +
          614  +    if (objPtr->typePtr == &tdomNodeType) {
          615  +        return TCL_OK;
          616  +    }
          617  +
          618  +    nodeName = Tcl_GetString(objPtr);
          619  +    if (strncmp(nodeName, "domNode", 7)) {
          620  +        if (interp) {
          621  +            SetResult3("Parameter \"", nodeName, "\" is not a domNode.");
          622  +            return TCL_ERROR;
          623  +        }
          624  +    }
          625  +    if (sscanf(&nodeName[7], "%p%1c", (void **)&node, &eolcheck) != 1) {
          626  +        if (!Tcl_GetCommandInfo(interp, nodeName, &cmdInfo)) {
          627  +            if (interp) {
          628  +                SetResult3("Parameter \"", nodeName, "\" is not a domNode.");
          629  +                return TCL_ERROR;
          630  +            }
          631  +        }
          632  +        if (   (cmdInfo.isNativeObjectProc == 0)
          633  +            || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_NodeObjCmd)) {
          634  +            if (interp) {
          635  +                SetResult3("Parameter \"", nodeName, "\" is not a domNode"
          636  +                    " object command");
          637  +                return TCL_ERROR;
          638  +            }
          639  +        }
          640  +        node = (domNode*)cmdInfo.objClientData;
          641  +    }
          642  +    if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
          643  +        objPtr->typePtr->freeIntRepProc(objPtr);
          644  +    }
          645  +    objPtr->internalRep.otherValuePtr = node;
          646  +    objPtr->typePtr = &tdomNodeType;
          647  +    
          648  +    return TCL_OK;
          649  +}
   587    650   
   588    651   /*----------------------------------------------------------------------------
   589    652   |   tcldom_createNodeObj
   590    653   |
   591    654   \---------------------------------------------------------------------------*/
   592    655   void tcldom_createNodeObj (
   593    656       Tcl_Interp * interp,
................................................................................
   607    670                                (ClientData)        node,
   608    671                                (Tcl_CmdDeleteProc*)NULL);
   609    672           node->nodeFlags |= VISIBLE_IN_TCL;
   610    673       }
   611    674   }
   612    675   
   613    676   /*----------------------------------------------------------------------------
   614         -|   tcldom_returnNodeObj
          677  +|   tcldom_setInterpAndReturnVar
   615    678   |
   616    679   \---------------------------------------------------------------------------*/
   617    680   static
   618         -int tcldom_returnNodeObj (
          681  +int tcldom_setInterpAndReturnVar (
   619    682       Tcl_Interp *interp,
   620    683       domNode    *node,
   621    684       int         setVariable,
   622    685       Tcl_Obj    *var_name
   623    686   )
   624    687   {
   625         -    char            objCmdName[80], *objVar;
   626         -    domDeleteInfo * dinfo;
   627         -    Tcl_CmdInfo     cmdInfo;
   628         -
          688  +    char     objCmdName[80];
          689  +    Tcl_Obj *resultObj;
          690  +    
   629    691       GetTcldomTSD()
   630    692   
   631    693       if (node == NULL) {
   632    694           if (setVariable) {
   633         -            objVar = Tcl_GetString(var_name);
   634         -            Tcl_UnsetVar(interp, objVar, 0);
   635         -            Tcl_SetVar(interp, objVar, "", 0);
          695  +            if (!Tcl_ObjSetVar2 (interp, var_name, NULL,
          696  +                                 Tcl_NewStringObj("",0),
          697  +                                 TCL_LEAVE_ERR_MSG)) {
          698  +                return TCL_ERROR;
          699  +            }
   636    700           }
   637    701           SetResult("");
   638    702           return TCL_OK;
   639    703       }
   640         -    tcldom_createNodeObj(interp, node, objCmdName);
   641         -    if (TSD(dontCreateObjCommands)) {
   642         -        if (setVariable) {
   643         -            objVar = Tcl_GetString(var_name);
   644         -            Tcl_SetVar(interp, objVar, objCmdName, 0);
   645         -        }
   646         -    } else {
   647         -        if (setVariable) {
   648         -            objVar = Tcl_GetString(var_name);
   649         -            Tcl_UnsetVar(interp, objVar, 0);
   650         -            Tcl_SetVar  (interp, objVar, objCmdName, 0);
   651         -            Tcl_GetCommandInfo(interp, objCmdName, &cmdInfo);
   652         -            if (0) {
   653         -                dinfo = (domDeleteInfo*)MALLOC(sizeof(domDeleteInfo));
   654         -                dinfo->interp       = interp;
   655         -                dinfo->node         = node;
   656         -                dinfo->traceVarName = NULL;
   657         -                Tcl_TraceVar(interp, objVar, 
   658         -                             TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
   659         -                             (Tcl_VarTraceProc*)tcldom_nodeTrace,
   660         -                             (ClientData)dinfo);
   661         -                dinfo->traceVarName = tdomstrdup(objVar);
   662         -
   663         -                /* Patch node object command to remove above trace 
   664         -                   on teardown */
   665         -                cmdInfo.deleteData = (ClientData)dinfo;
   666         -                cmdInfo.deleteProc = tcldom_nodeCmdDeleteProc;
   667         -                Tcl_SetCommandInfo(interp, objCmdName, &cmdInfo);
   668         -            }
   669         -        }
   670         -    }
   671         -
   672         -    SetResult(objCmdName);
   673         -    return TCL_OK;
          704  +    resultObj = Tcl_NewObj();
          705  +    resultObj->bytes = NULL;
          706  +    resultObj->length = 0;
          707  +    resultObj->internalRep.otherValuePtr = node;
          708  +    resultObj->typePtr = &tdomNodeType;
          709  +    Tcl_SetObjResult (interp, resultObj);
          710  +    if (TSD(dontCreateObjCommands) == 0) {
          711  +        tcldom_createNodeObj(interp, node, objCmdName);
          712  +    }
          713  +    if (setVariable) {
          714  +        if (!Tcl_ObjSetVar2 (interp, var_name, NULL, resultObj,
          715  +                             TCL_LEAVE_ERR_MSG)) {
          716  +            return TCL_ERROR;
          717  +        }
          718  +    }
          719  +    return TCL_OK;
          720  +}
          721  +
          722  +/*----------------------------------------------------------------------------
          723  +|   tcldom_returnNodeObj
          724  +|
          725  +\---------------------------------------------------------------------------*/
          726  +static
          727  +Tcl_Obj *tcldom_returnNodeObj (
          728  +    Tcl_Interp *interp,
          729  +    domNode    *node)
          730  +{
          731  +    char     objCmdName[80];
          732  +    Tcl_Obj *resultObj;
          733  +    
          734  +    GetTcldomTSD()
          735  +
          736  +    resultObj = Tcl_NewObj();
          737  +    if (node == NULL) {
          738  +        return resultObj;
          739  +    }
          740  +    if (TSD(dontCreateObjCommands) == 0) {
          741  +        tcldom_createNodeObj(interp, node, objCmdName);
          742  +    }
          743  +    resultObj->bytes = NULL;
          744  +    resultObj->length = 0;
          745  +    resultObj->internalRep.otherValuePtr = node;
          746  +    resultObj->typePtr = &tdomNodeType;
          747  +    return resultObj;
   674    748   }
   675    749   
   676    750   /*----------------------------------------------------------------------------
   677    751   |   tcldom_returnDocumentObj
   678    752   |
   679    753   \---------------------------------------------------------------------------*/
   680    754   int tcldom_returnDocumentObj (
................................................................................
   710    784               Tcl_SetVar(interp, objVar, objCmdName, 0);
   711    785           }
   712    786       } else {
   713    787           if (!Tcl_GetCommandInfo(interp, objCmdName, &cmd_info)) {
   714    788               dinfo = (domDeleteInfo*)MALLOC(sizeof(domDeleteInfo));
   715    789               dinfo->interp       = interp;
   716    790               dinfo->document     = document;
          791  +            document->nodeFlags |= DOCUMENT_CMD;
   717    792               dinfo->traceVarName = NULL;
   718    793               Tcl_CreateObjCommand(interp, objCmdName,
   719    794                                    (Tcl_ObjCmdProc *)  tcldom_DocObjCmd,
   720    795                                    (ClientData)        dinfo,
   721    796                                    (Tcl_CmdDeleteProc*)tcldom_docCmdDeleteProc);
   722    797           } else {
   723    798               dinfo = (domDeleteInfo*)cmd_info.objClientData;
   724    799           }
   725    800           if (setVariable) {
   726    801               objVar = Tcl_GetString(var_name);
   727    802               Tcl_UnsetVar(interp, objVar, 0);
   728    803               Tcl_SetVar  (interp, objVar, objCmdName, 0);
   729    804               if (trace) {
          805  +                document->nodeFlags |= VAR_TRACE;
   730    806                   dinfo->traceVarName = tdomstrdup(objVar);
   731    807                   Tcl_TraceVar(interp,objVar,TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
   732    808                                (Tcl_VarTraceProc*)tcldom_docTrace,
   733    809                                (ClientData)dinfo);
   734    810               }
   735    811           }
   736    812       }
................................................................................
   755    831       domNode    *node,
   756    832       int         nsIndex,
   757    833       const char *uri
   758    834   )
   759    835   {
   760    836       int         result;
   761    837       domNode    *child;
   762         -    char        prefix[MAX_PREFIX_LEN], objCmdName[80];
          838  +    char        prefix[MAX_PREFIX_LEN];
   763    839       const char *localName;
   764    840       Tcl_Obj    *namePtr, *resultPtr;
   765    841   
   766    842       /* nsIndex == -1 ==> DOM 1 no NS i.e getElementsByTagName
   767    843          nsIndex != -1 are the NS aware cases
   768    844          nsIndex == -2 ==> more than one namespace in the document with the 
   769    845                            requested namespace, we have to strcmp the URI
................................................................................
   790    866               if (nsIndex == -1) {
   791    867                   localName = node->nodeName;
   792    868               } else {
   793    869                   domSplitQName(node->nodeName, prefix, &localName);
   794    870               }
   795    871               if (Tcl_StringMatch(localName, namePattern)) {
   796    872                   resultPtr = Tcl_GetObjResult(interp);
   797         -                tcldom_createNodeObj(interp, node, objCmdName);
   798         -                namePtr = Tcl_NewStringObj(objCmdName, -1);
          873  +                namePtr = tcldom_returnNodeObj(interp, node);
   799    874                   result = Tcl_ListObjAppendElement(interp, resultPtr, namePtr);
   800    875                   if (result != TCL_OK) {
   801    876                       Tcl_DecrRefCount(namePtr);
   802    877                       return result;
   803    878                   }
   804    879               }
   805    880           }
................................................................................
   867    942       domNode    * node,
   868    943       void       * clientData
   869    944   )
   870    945   {
   871    946       Tcl_Interp * interp = (Tcl_Interp*)clientData;
   872    947       Tcl_Obj    * resultPtr = Tcl_GetObjResult(interp);
   873    948       Tcl_Obj    * namePtr;
   874         -    char         objCmdName[80];
   875    949       int          result;
   876    950   
   877    951   
   878         -    tcldom_createNodeObj(interp, node, objCmdName);
   879         -    namePtr = Tcl_NewStringObj(objCmdName, -1);
          952  +    namePtr = tcldom_returnNodeObj(interp, node);
   880    953       result  = Tcl_ListObjAppendElement(interp, resultPtr, namePtr);
   881    954       if (result != TCL_OK) {
   882    955           Tcl_DecrRefCount(namePtr);
   883    956       }
   884    957       return result;
   885    958   }
   886    959   
................................................................................
   891    964   \---------------------------------------------------------------------------*/
   892    965   static
   893    966   int tcldom_xpointerSearch (
   894    967       Tcl_Interp * interp,
   895    968       int          mode,
   896    969       domNode    * node,
   897    970       int          objc,
   898         -    Tcl_Obj    * CONST  objv[]
          971  +    Tcl_Obj    * const  objv[]
   899    972   )
   900    973   {
   901    974       char *str;
   902    975       int   i = 0;
   903    976       int   result = 0;
   904    977       int   all = 0;
   905    978       int   instance = 0;
................................................................................
   985   1058       }
   986   1059       if (result != 0) {
   987   1060           return TCL_ERROR;
   988   1061       }
   989   1062       return TCL_OK;
   990   1063   }
   991   1064   
         1065  +
         1066  +/*----------------------------------------------------------------------------
         1067  +|   tcldom_getNodeFromObj
         1068  +|
         1069  +\---------------------------------------------------------------------------*/
         1070  +domNode * tcldom_getNodeFromObj (
         1071  +    Tcl_Interp  *interp,
         1072  +    Tcl_Obj     *nodeObj
         1073  +)
         1074  +{
         1075  +    Tcl_CmdInfo  cmdInfo;
         1076  +    domNode     *node = NULL;
         1077  +    char        *nodeName;
         1078  +    char         eolcheck;
         1079  +
         1080  +    GetTcldomTSD()
         1081  +
         1082  +    if (nodeObj->typePtr == &tdomNodeType) {
         1083  +        return (domNode*)nodeObj->internalRep.otherValuePtr;
         1084  +    }
         1085  +    
         1086  +    if (TSD(dontCreateObjCommands)) {
         1087  +        if (SetTdomNodeFromAny (interp, nodeObj) == TCL_OK) {
         1088  +            return (domNode*)nodeObj->internalRep.otherValuePtr;
         1089  +        }
         1090  +        return NULL;
         1091  +    }
         1092  +    
         1093  +    nodeName = Tcl_GetString(nodeObj);
         1094  +    if (strncmp(nodeName, "domNode", 7)) {
         1095  +        SetResult3("Parameter \"", nodeName, "\" is not a domNode.");
         1096  +        return NULL;
         1097  +    }
         1098  +    if (sscanf(&nodeName[7], "%p%1c", (void **)&node, &eolcheck) != 1) {
         1099  +        if (!Tcl_GetCommandInfo(interp, nodeName, &cmdInfo)) {
         1100  +            SetResult3("Parameter \"", nodeName, "\" is not a domNode.");
         1101  +            return NULL;
         1102  +        }
         1103  +        if (   (cmdInfo.isNativeObjectProc == 0)
         1104  +            || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_NodeObjCmd)) {
         1105  +            SetResult3("Parameter \"", nodeName, "\" is not a domNode"
         1106  +                       " object command.");
         1107  +            return NULL;
         1108  +        }
         1109  +        node = (domNode*)cmdInfo.objClientData;
         1110  +    }
         1111  +
         1112  +    return node;
         1113  +}
   992   1114   
   993   1115   /*----------------------------------------------------------------------------
   994   1116   |   tcldom_getNodeFromName
   995   1117   |
   996   1118   \---------------------------------------------------------------------------*/
   997   1119   domNode * tcldom_getNodeFromName (
   998   1120       Tcl_Interp  *interp,
   999   1121       char        *nodeName,
  1000   1122       char       **errMsg
  1001   1123   )
  1002   1124   {
  1003   1125       Tcl_CmdInfo  cmdInfo;
  1004   1126       domNode     *node = NULL;
         1127  +    char         eolcheck;
  1005   1128   
  1006   1129       if (strncmp(nodeName, "domNode", 7)) {
  1007   1130           *errMsg = "parameter not a domNode!";
  1008   1131           return NULL;
  1009   1132       }
  1010         -    if (sscanf(&nodeName[7], "%p", &node) != 1) {
         1133  +    if (sscanf(&nodeName[7], "%p%1c", (void **)&node, &eolcheck) != 1) {
  1011   1134           if (!Tcl_GetCommandInfo(interp, nodeName, &cmdInfo)) {
  1012   1135              *errMsg = "parameter not a domNode!";
  1013   1136              return NULL;
  1014   1137           }
  1015   1138           if (   (cmdInfo.isNativeObjectProc == 0)
  1016   1139               || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_NodeObjCmd)) {
  1017   1140               *errMsg = "parameter not a domNode object command!";
................................................................................
  1032   1155       char        *docName,
  1033   1156       char       **errMsg
  1034   1157   )
  1035   1158   {
  1036   1159       Tcl_CmdInfo  cmdInfo;
  1037   1160       domDocument *doc = NULL;
  1038   1161       int          shared = 1;
  1039         -    
         1162  +    char         eolcheck;
         1163  +
  1040   1164       if (strncmp(docName, "domDoc", 6)) {
  1041   1165           *errMsg = "parameter not a domDoc!";
  1042   1166           return NULL;
  1043   1167       }
  1044         -    if (sscanf(&docName[6], "%p", &doc) != 1) {
         1168  +    if (sscanf(&docName[6], "%p%1c", (void **)&doc, &eolcheck) != 1) {
  1045   1169           if (!Tcl_GetCommandInfo(interp, docName, &cmdInfo)) {
  1046   1170               *errMsg = "parameter not a domDoc!";
  1047   1171               return NULL;
  1048   1172           }
  1049   1173           if (   (cmdInfo.isNativeObjectProc == 0)
  1050   1174               || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_DocObjCmd)) {
  1051   1175               *errMsg = "parameter not a domDoc object command!";
................................................................................
  1071   1195   \---------------------------------------------------------------------------*/
  1072   1196   int tcldom_appendXML (
  1073   1197       Tcl_Interp *interp,
  1074   1198       domNode    *node,
  1075   1199       Tcl_Obj    *obj
  1076   1200   )
  1077   1201   {
  1078         -    char        *xml_string, *extResolver = NULL;
         1202  +    char        *xml_string;
         1203  +    Tcl_Obj     *extResolver = NULL;
  1079   1204       int          xml_string_len;
         1205  +    int          resultcode = 0;
         1206  +    int          ignorexmlns = 0;
  1080   1207       domDocument *doc;
  1081   1208       domNode     *nodeToAppend;
  1082   1209       XML_Parser   parser;
  1083   1210   
  1084   1211       GetTcldomTSD()
  1085   1212   
  1086   1213       xml_string = Tcl_GetStringFromObj(obj, &xml_string_len);
................................................................................
  1088   1215   #ifdef TDOM_NO_EXPAT
  1089   1216       SetResult("tDOM was compiled without Expat!");
  1090   1217       return TCL_ERROR;
  1091   1218   #else
  1092   1219       parser = XML_ParserCreate_MM(NULL, MEM_SUITE, NULL);
  1093   1220   
  1094   1221       if (node->ownerDocument->extResolver) {
  1095         -        extResolver = tdomstrdup (node->ownerDocument->extResolver);
         1222  +        extResolver = Tcl_NewStringObj(node->ownerDocument->extResolver, -1);
         1223  +        Tcl_IncrRefCount (extResolver);
         1224  +    }
         1225  +    if (node->ownerDocument->nodeFlags & IGNORE_XMLNS) {
         1226  +        ignorexmlns = 1;
  1096   1227       }
  1097   1228   
  1098   1229       doc = domReadDocument(parser,
  1099   1230                             xml_string,
  1100   1231                             xml_string_len,
  1101   1232                             1,
  1102         -                          TSD(Encoding_to_8bit),
         1233  +                          0,
  1103   1234                             TSD(storeLineColumn),
         1235  +                          ignorexmlns,
  1104   1236                             0,
         1237  +                          NULL,
  1105   1238                             NULL,
  1106   1239                             NULL,
  1107   1240                             extResolver,
  1108   1241                             0,
  1109   1242                             (int) XML_PARAM_ENTITY_PARSING_ALWAYS,
  1110         -                          interp);
         1243  +                          interp,
         1244  +                          &resultcode);
         1245  +    if (extResolver) {
         1246  +        Tcl_DecrRefCount(extResolver);
         1247  +    }
  1111   1248       if (doc == NULL) {
  1112   1249           char s[50];
  1113   1250           long byteIndex, i;
  1114   1251   
  1115   1252           Tcl_ResetResult(interp);
  1116   1253           sprintf(s, "%ld", XML_GetCurrentLineNumber(parser));
  1117   1254           Tcl_AppendResult(interp, "error \"",
................................................................................
  1147   1284       nodeToAppend = doc->rootNode->firstChild;
  1148   1285       while (nodeToAppend) {
  1149   1286           domAppendChild(node, nodeToAppend);
  1150   1287           nodeToAppend = nodeToAppend->nextSibling;
  1151   1288       }
  1152   1289       domFreeDocument(doc, NULL, NULL);
  1153   1290   
  1154         -    return tcldom_returnNodeObj(interp, node, 0, NULL);
         1291  +    return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
  1155   1292   #endif
  1156   1293   }
  1157   1294   
  1158   1295   
  1159   1296   /*----------------------------------------------------------------------------
  1160   1297   |   tcldom_xpathResultSet
  1161   1298   |
................................................................................
  1166   1303       xpathResultSet  *rs,
  1167   1304       Tcl_Obj         *type,
  1168   1305       Tcl_Obj         *value
  1169   1306   )
  1170   1307   {
  1171   1308       int          rc, i;
  1172   1309       Tcl_Obj     *namePtr, *objv[2];
  1173         -    char         objCmdName[80];
  1174   1310       domAttrNode *attr;
  1175   1311       domNodeType  startType;
  1176   1312       int          mixedNodeSet;
  1177   1313   
  1178   1314       switch (rs->type) {
  1179   1315           case EmptyResult:
  1180   1316                Tcl_SetStringObj(type, "empty", -1);
................................................................................
  1225   1361                    if (rs->nodes[i]->nodeType == ATTRIBUTE_NODE) {
  1226   1362                        attr = (domAttrNode*)rs->nodes[i];
  1227   1363                        objv[0] = Tcl_NewStringObj(attr->nodeName, -1);
  1228   1364                        objv[1] = Tcl_NewStringObj(attr->nodeValue,
  1229   1365                                                   attr->valueLength);
  1230   1366                        namePtr = Tcl_NewListObj(2, objv);
  1231   1367                    } else {
  1232         -                     tcldom_createNodeObj(interp, rs->nodes[i], objCmdName);
  1233         -                     namePtr = Tcl_NewStringObj(objCmdName, -1);
         1368  +                     namePtr = tcldom_returnNodeObj(interp, rs->nodes[i]);
  1234   1369                    }
  1235   1370                    rc = Tcl_ListObjAppendElement(interp, value, namePtr);
  1236   1371                    if (rc != TCL_OK) {
  1237   1372                        Tcl_DecrRefCount(namePtr);
  1238   1373                        return rc;
  1239   1374                    }
  1240   1375                }
................................................................................
  1269   1404       xpathResultSets *args,
  1270   1405       xpathResultSet  *result,
  1271   1406       char           **errMsg
  1272   1407   )
  1273   1408   {
  1274   1409       Tcl_Interp  *interp = (Tcl_Interp*) clientData;
  1275   1410       char         tclxpathFuncName[200], objCmdName[80];
  1276         -    char         *errStr, *typeStr, *nodeName;
  1277         -    Tcl_Obj     *resultPtr, *objv[MAX_REWRITE_ARGS], *type, *value, *nodeObj;
         1411  +    char         *errStr, *typeStr;
         1412  +    Tcl_Obj     *resultPtr, *objv[MAX_REWRITE_ARGS], *type, *value, *nodeObj,
         1413  +                *tmpObj;
  1278   1414       Tcl_CmdInfo  cmdInfo;
  1279   1415       int          objc, rc, i, errStrLen, listLen, intValue, res;
  1280   1416       double       doubleValue;
  1281   1417       domNode     *node;
  1282   1418   
  1283   1419       DBG(fprintf(stderr, "tcldom_xpathFuncCallBack functionName=%s "
  1284   1420                   "position=%d argc=%d\n", functionName, position, argc);)
  1285   1421   
         1422  +    if (strlen(functionName) > 199) {
         1423  +        *errMsg = (char*)MALLOC (80 + strlen (functionName));
         1424  +        strcpy (*errMsg, "Unreasonable long XPath function name: \"");
         1425  +        strcat (*errMsg, functionName);
         1426  +        strcat (*errMsg, "\"!");
         1427  +        return XPATH_EVAL_ERR;
         1428  +    }
  1286   1429       sprintf (tclxpathFuncName, "::dom::xpathFunc::%s", functionName);
  1287   1430       DBG(fprintf(stderr, "testing %s\n", tclxpathFuncName);)
  1288   1431       rc = Tcl_GetCommandInfo (interp, tclxpathFuncName, &cmdInfo);
  1289   1432       if (!rc) {
  1290   1433           *errMsg = (char*)MALLOC (80 + strlen (functionName));
  1291   1434           strcpy (*errMsg, "Unknown XPath function: \"");
  1292   1435           strcat (*errMsg, functionName);
................................................................................
  1300   1443       if ( (5+(2*argc)) >= MAX_REWRITE_ARGS) {
  1301   1444           *errMsg = (char*)tdomstrdup("too many args for Tcl level method!");
  1302   1445           return XPATH_EVAL_ERR;
  1303   1446       }
  1304   1447       objc = 0;
  1305   1448       objv[objc] = Tcl_NewStringObj(tclxpathFuncName, -1);
  1306   1449       Tcl_IncrRefCount(objv[objc++]);
  1307         -    tcldom_createNodeObj(interp, ctxNode, objCmdName);
  1308         -    objv[objc] = Tcl_NewStringObj(objCmdName, -1);
         1450  +    if (ctxNode->nodeType == ATTRIBUTE_NODE) {
         1451  +        tcldom_createNodeObj(interp, ((domAttrNode*)ctxNode)->parentNode,
         1452  +                             objCmdName);
         1453  +        tmpObj = Tcl_NewListObj(0, NULL);
         1454  +        Tcl_ListObjAppendElement(interp, tmpObj, 
         1455  +                                 Tcl_NewStringObj(objCmdName, -1));
         1456  +        Tcl_ListObjAppendElement(
         1457  +            interp, tmpObj,
         1458  +            Tcl_NewStringObj(((domAttrNode*)ctxNode)->nodeName, -1));
         1459  +    } else {
         1460  +        tmpObj = tcldom_returnNodeObj(interp, ctxNode);
         1461  +    }
         1462  +    objv[objc] = tmpObj;
  1309   1463       Tcl_IncrRefCount(objv[objc++]);
  1310   1464   
  1311   1465       objv[objc] = Tcl_NewIntObj(position);
  1312   1466       Tcl_IncrRefCount(objv[objc++]);
  1313   1467   
  1314   1468       type  = Tcl_NewObj();
  1315   1469       value = Tcl_NewObj();
................................................................................
  1333   1487           xpathRSInit(result);
  1334   1488           resultPtr = Tcl_GetObjResult(interp);
  1335   1489           rc = Tcl_ListObjLength(interp, resultPtr, &listLen);
  1336   1490           if (rc == TCL_OK) {
  1337   1491               if (listLen == 1) {
  1338   1492                   rsSetString(result, Tcl_GetString(resultPtr));
  1339   1493                   res = XPATH_OK;
         1494  +                Tcl_ResetResult(interp);
  1340   1495                   goto funcCallCleanup;
  1341   1496               }
  1342   1497               if (listLen != 2) {
  1343   1498                   *errMsg = (char*)tdomstrdup("wrong return tuple; "
  1344   1499                                               "must be {type value}!");
  1345   1500                   res = XPATH_EVAL_ERR;
  1346   1501                   goto funcCallCleanup;
................................................................................
  1369   1524                   if (rc != TCL_OK) {
  1370   1525                       *errMsg = tdomstrdup("value not a node list!");
  1371   1526                       res = XPATH_EVAL_ERR;
  1372   1527                       goto funcCallCleanup;
  1373   1528                   }
  1374   1529                   for (i=0; i < listLen; i++) {
  1375   1530                       rc = Tcl_ListObjIndex(interp, value, i, &nodeObj);
  1376         -                    nodeName = Tcl_GetString(nodeObj);
  1377         -                    node = tcldom_getNodeFromName(interp, nodeName, &errStr);
         1531  +                    node = tcldom_getNodeFromObj(interp, nodeObj);
  1378   1532                       if (node == NULL) {
  1379         -                        *errMsg = tdomstrdup(errStr);
         1533  +                        *errMsg = tdomstrdup(Tcl_GetStringResult(interp));
  1380   1534                           res = XPATH_EVAL_ERR;
  1381   1535                           goto funcCallCleanup;
  1382   1536                       }
  1383   1537                       rsAddNode(result, node);
  1384   1538                   }
  1385   1539                   sortByDocOrder(result);
  1386   1540               } else
................................................................................
  1392   1546               if (strcmp(typeStr, "attrvalues")==0) {
  1393   1547                   rsSetString(result, Tcl_GetString(value));
  1394   1548               } else {
  1395   1549                   *errMsg = (char*)MALLOC (80 + strlen (typeStr)
  1396   1550                                            + strlen (functionName));
  1397   1551                   strcpy(*errMsg, "Unknown type of return value \"");
  1398   1552                   strcat(*errMsg, typeStr);
  1399         -                strcat(*errMsg, "\" from tcl coded XPath function \"");
         1553  +                strcat(*errMsg, "\" from Tcl coded XPath function \"");
  1400   1554                   strcat(*errMsg, functionName);
  1401   1555                   strcat(*errMsg, "\"!");
  1402   1556                   res = XPATH_EVAL_ERR;
  1403   1557                   goto funcCallCleanup;
  1404   1558               }
  1405   1559           } else {
  1406   1560               DBG(fprintf(stderr, "ListObjLength != TCL_OK "
................................................................................
  1409   1563               goto funcCallCleanup;
  1410   1564           }
  1411   1565           Tcl_ResetResult(interp);
  1412   1566           res = XPATH_OK;
  1413   1567       } else {
  1414   1568           errStr = Tcl_GetStringFromObj( Tcl_GetObjResult(interp), &errStrLen);
  1415   1569           *errMsg = (char*)MALLOC(120+strlen(functionName) + errStrLen);
  1416         -        strcpy(*errMsg, "Tcl error while executing XPATH extension function '");
         1570  +        strcpy(*errMsg, "Tcl error while executing XPath extension function '");
  1417   1571           strcat(*errMsg, functionName );
  1418   1572           strcat(*errMsg, "':\n" );
  1419   1573           strcat(*errMsg, errStr);
  1420   1574           Tcl_ResetResult(interp);
  1421   1575           DBG(fprintf(stderr, "returning XPATH_EVAL_ERR \n");)
  1422   1576           res = XPATH_EVAL_ERR;
  1423   1577       }
................................................................................
  1429   1583   }
  1430   1584   
  1431   1585   /*----------------------------------------------------------------------------
  1432   1586   |   tcldom_xsltMsgCB
  1433   1587   |
  1434   1588   \---------------------------------------------------------------------------*/
  1435   1589   static
  1436         -void tcldom_xsltMsgCB (
         1590  +int tcldom_xsltMsgCB (
  1437   1591       void *clientData,
  1438   1592       char *str,
  1439   1593       int   length,
  1440   1594       int   terminate
  1441   1595       )
  1442   1596   {
  1443   1597       XsltMsgCBInfo *msgCBInfo = (XsltMsgCBInfo *)clientData;
  1444   1598       Tcl_Obj       *cmdPtr;
  1445         -
         1599  +    int            rc;
         1600  +    
  1446   1601       if (msgCBInfo->msgcmd == NULL) {
  1447         -        return;
         1602  +        return 0;
  1448   1603       }
  1449   1604       
  1450   1605       cmdPtr = Tcl_DuplicateObj(msgCBInfo->msgcmd);
  1451   1606       Tcl_IncrRefCount(cmdPtr);
  1452   1607       if (Tcl_ListObjAppendElement(msgCBInfo->interp, cmdPtr, 
  1453   1608                                    Tcl_NewStringObj(str, length)) != TCL_OK) {
  1454   1609           Tcl_DecrRefCount(cmdPtr);
  1455         -        return;
         1610  +        return 1;
  1456   1611       }
  1457   1612       if (terminate) {
  1458   1613           Tcl_ListObjAppendElement(msgCBInfo->interp, cmdPtr,
  1459   1614                                    Tcl_NewBooleanObj(1));
  1460   1615       } else {
  1461   1616           Tcl_ListObjAppendElement(msgCBInfo->interp, cmdPtr,
  1462   1617                                    Tcl_NewBooleanObj(0));
  1463   1618       }
  1464         -    Tcl_GlobalEvalObj(msgCBInfo->interp, cmdPtr);
         1619  +    rc = Tcl_GlobalEvalObj(msgCBInfo->interp, cmdPtr);
  1465   1620       Tcl_DecrRefCount(cmdPtr);
  1466         -    return;
         1621  +    switch (rc) {
         1622  +    case TCL_OK: return 0;
         1623  +    case TCL_BREAK: return 3;
         1624  +    default: return rc;
         1625  +    }
  1467   1626   }
  1468   1627   
  1469   1628   /*----------------------------------------------------------------------------
  1470   1629   |   tcldom_xpathResolveVar
  1471   1630   |
  1472   1631   \---------------------------------------------------------------------------*/
  1473   1632   static
................................................................................
  1474   1633   char * tcldom_xpathResolveVar (
  1475   1634       void  *clientData,
  1476   1635       char  *strToParse,
  1477   1636       int   *offset,
  1478   1637       char **errMsg
  1479   1638       )
  1480   1639   {
  1481         -    CONST char *varValue;
  1482         -    CONST char *termPtr;
         1640  +    const char *varValue;
         1641  +    const char *termPtr;
  1483   1642       Tcl_Interp *interp = (Tcl_Interp *) clientData;
  1484   1643       
  1485   1644       *offset = 0;
  1486   1645       varValue = Tcl_ParseVar(interp, strToParse, &termPtr);
  1487   1646       if (varValue) {
  1488   1647           *offset = termPtr - strToParse;
  1489   1648           /* If strToParse start with a single '$' without a following
  1490         -         * var name (according to tcl var name rules), Tcl_ParseVar()
         1649  +         * var name (according to Tcl var name rules), Tcl_ParseVar()
  1491   1650            * doesn't report a parsing error but returns just a pointer
  1492   1651            * to a static string "$". */ 
  1493   1652           if (*offset == 1) {
  1494   1653               *errMsg = tdomstrdup ("Missing var name after '$'.");
  1495   1654               varValue = NULL;
  1496   1655           }
  1497   1656       } else {
................................................................................
  1506   1665   |
  1507   1666   \---------------------------------------------------------------------------*/
  1508   1667   static
  1509   1668   int tcldom_selectNodes (
  1510   1669       Tcl_Interp *interp,
  1511   1670       domNode    *node,
  1512   1671       int         objc,
  1513         -    Tcl_Obj    *CONST objv[]
         1672  +    Tcl_Obj    *const objv[]
  1514   1673   )
  1515   1674   {
  1516   1675       char          *xpathQuery, *typeVar, *option;
  1517   1676       char          *errMsg = NULL, **mappings = NULL;
  1518         -    int            rc, i, len, optionIndex, localmapping, cache = 0;
         1677  +    int            rc, i, len, optionIndex, localmapping = 0, cache = 0;
         1678  +    int            mappingListObjLen = 0;
  1519   1679       xpathResultSet rs;
  1520         -    Tcl_Obj       *type, *objPtr;
         1680  +    Tcl_Obj       *type, *objPtr, *objPtr1, *mappingListObj = NULL;
  1521   1681       xpathCBs       cbs;
  1522   1682       xpathParseVarCB parseVarCB;
  1523   1683   
  1524         -    static CONST84 char *selectNodesOptions[] = {
         1684  +    static const char *selectNodesOptions[] = {
  1525   1685           "-namespaces", "-cache", NULL
  1526   1686       };
  1527   1687       enum selectNodesOption {
  1528   1688           o_namespaces, o_cache
  1529   1689       };
  1530   1690   
  1531   1691       if (objc < 2) {
................................................................................
  1543   1703           }
  1544   1704           switch ((enum selectNodesOption) optionIndex) {
  1545   1705           case o_namespaces:
  1546   1706               rc = Tcl_ListObjLength (interp, objv[2], &len);
  1547   1707               if (rc != TCL_OK || (len % 2) != 0) {
  1548   1708                   SetResult ("The \"-namespaces\" option requires a 'prefix"
  1549   1709                              " namespace' pairs list as argument");
  1550         -                return TCL_ERROR;
         1710  +                rc = TCL_ERROR;
         1711  +                goto cleanup;
  1551   1712               }
  1552   1713               if (mappings) {
         1714  +                for (i = 0; i < mappingListObjLen; i++) {
         1715  +                    Tcl_ListObjIndex (interp, mappingListObj, i, &objPtr1);
         1716  +                    Tcl_DecrRefCount (objPtr1);
         1717  +                }
         1718  +                Tcl_DecrRefCount (mappingListObj);
  1553   1719                   FREE (mappings);
  1554   1720               }
  1555   1721               mappings = MALLOC (sizeof (char *) * (len + 1));
         1722  +            localmapping = 1;
  1556   1723               for (i = 0; i < len; i++) {
  1557   1724                   Tcl_ListObjIndex (interp, objv[2], i, &objPtr);
  1558         -                /* The prefixMappings array is only used at xpath expr
  1559         -                   compile time. (And every needed info is strdup'ed.)
  1560         -                   So, we don't need to fiddle around with the refcounts
  1561         -                   of the prefixMappings list members.
  1562         -                   If we, at some day, allow to evaluate tcl scripts during
  1563         -                   xpath lexing/parsing, this must be revisited. */
         1725  +                Tcl_IncrRefCount (objPtr);
  1564   1726                   mappings[i] = Tcl_GetString (objPtr);
  1565   1727               }
  1566   1728               mappings[len] = NULL;
         1729  +            mappingListObj = objv[2];
         1730  +            Tcl_IncrRefCount (mappingListObj);
         1731  +            mappingListObjLen = len;
  1567   1732               objc -= 2;
  1568   1733               objv += 2;
  1569   1734               break;
  1570   1735   
  1571   1736           case o_cache:
  1572   1737               if (Tcl_GetBooleanFromObj (interp, objv[2], &cache) != TCL_OK) {
  1573   1738                   return TCL_ERROR;
................................................................................
  1581   1746               Tcl_AppendResult (interp, "bad option \"", 
  1582   1747                                 Tcl_GetString (objv[1]), "\"; must be "
  1583   1748                                 "-namespaces", NULL);
  1584   1749               return TCL_ERROR;
  1585   1750           }
  1586   1751       }
  1587   1752       if (objc != 2 && objc != 3) {
  1588         -        if (mappings) {
  1589         -            FREE (mappings);
  1590         -        }
  1591   1753           SetResult("Wrong # of arguments.");
  1592         -        return TCL_ERROR;
         1754  +        rc = TCL_ERROR;
         1755  +        goto cleanup;
  1593   1756       }
  1594   1757   
  1595   1758       xpathQuery = Tcl_GetString(objv[1]);
  1596   1759   
  1597   1760       xpathRSInit(&rs);
  1598   1761   
  1599   1762       cbs.funcCB         = tcldom_xpathFuncCallBack;
................................................................................
  1602   1765       cbs.varClientData  = NULL;
  1603   1766   
  1604   1767       parseVarCB.parseVarCB         = tcldom_xpathResolveVar;
  1605   1768       parseVarCB.parseVarClientData = interp;
  1606   1769       
  1607   1770       if (mappings == NULL) {
  1608   1771           mappings = node->ownerDocument->prefixNSMappings;
  1609         -        localmapping = 0;
  1610         -    } else {
  1611         -        localmapping = 1;
  1612   1772       }
         1773  +
  1613   1774       if (cache) {
  1614   1775           if (!node->ownerDocument->xpathCache) {
  1615   1776               node->ownerDocument->xpathCache = MALLOC (sizeof (Tcl_HashTable));
  1616   1777               Tcl_InitHashTable (node->ownerDocument->xpathCache,
  1617   1778                                  TCL_STRING_KEYS);
  1618   1779           }
  1619   1780           rc = xpathEval (node, node, xpathQuery, mappings, &cbs, &parseVarCB,
................................................................................
  1626   1787       if (rc != XPATH_OK) {
  1627   1788           xpathRSFree(&rs);
  1628   1789           SetResult(errMsg);
  1629   1790           DBG(fprintf(stderr, "errMsg = %s \n", errMsg);)
  1630   1791           if (errMsg) {
  1631   1792               FREE(errMsg);
  1632   1793           }
  1633         -        if (localmapping && mappings) {
  1634         -            FREE(mappings);
  1635         -        }
  1636         -        return TCL_ERROR;
         1794  +        rc = TCL_ERROR;
         1795  +        goto cleanup;
  1637   1796       }
  1638   1797       if (errMsg) {
         1798  +        fprintf (stderr, "Why this: '%s'\n", errMsg);
  1639   1799           FREE(errMsg);
  1640   1800       }
  1641   1801       typeVar = NULL;
  1642   1802       if (objc > 2) {
  1643   1803           typeVar = Tcl_GetString(objv[2]);
  1644   1804       }
  1645   1805       type = Tcl_NewObj();
................................................................................
  1646   1806       Tcl_IncrRefCount(type);
  1647   1807       DBG(fprintf(stderr, "before tcldom_xpathResultSet \n");)
  1648   1808       tcldom_xpathResultSet(interp, &rs, type, Tcl_GetObjResult(interp));
  1649   1809       DBG(fprintf(stderr, "after tcldom_xpathResultSet \n");)
  1650   1810       if (typeVar) {
  1651   1811           Tcl_SetVar(interp,typeVar, Tcl_GetString(type), 0);
  1652   1812       }
         1813  +    rc = TCL_OK;
  1653   1814       Tcl_DecrRefCount(type);
  1654   1815   
  1655   1816       xpathRSFree( &rs );
  1656         -    if (localmapping && mappings) {
         1817  +cleanup:
         1818  +    if (localmapping) {
         1819  +        for (i = 0; i < mappingListObjLen; i++) {
         1820  +            Tcl_ListObjIndex (interp, mappingListObj, i, &objPtr1);
         1821  +            Tcl_DecrRefCount (objPtr1);
         1822  +        }
         1823  +        Tcl_DecrRefCount (mappingListObj);
  1657   1824           FREE (mappings);
  1658   1825       }
  1659         -    return TCL_OK;
         1826  +    return rc;
  1660   1827   }
  1661   1828   
  1662   1829   /*----------------------------------------------------------------------------
  1663   1830   |   tcldom_nameCheck
  1664   1831   |
  1665   1832   \---------------------------------------------------------------------------*/
  1666   1833   int tcldom_nameCheck (
................................................................................
  1879   2046       |   create element node
  1880   2047       \-----------------------------------------------------------------------*/
  1881   2048       if (length != 3) {
  1882   2049           SetResult("invalid element node list format!");
  1883   2050           return TCL_ERROR;
  1884   2051       }
  1885   2052       CheckName (interp, tag_name, "tag", 0);
  1886         -    newnode = domNewElementNode(node->ownerDocument, tag_name, ELEMENT_NODE);
         2053  +    newnode = domNewElementNode(node->ownerDocument, tag_name);
  1887   2054       domAppendChild(node, newnode);
  1888   2055   
  1889   2056       /*------------------------------------------------------------------------
  1890         -    |   create atributes
         2057  +    |   create attributes
  1891   2058       \-----------------------------------------------------------------------*/
  1892   2059       if ((rc = Tcl_ListObjIndex(interp, lnode, 1, &attrListObj)) != TCL_OK) {
  1893   2060           return rc;
  1894   2061       }
  1895   2062       if ((rc = Tcl_ListObjLength(interp, attrListObj, &attrLength))
  1896   2063           != TCL_OK) {
  1897   2064           return rc;
................................................................................
  1936   2103               return rc;
  1937   2104           }
  1938   2105           if ((rc = tcldom_appendFromTclList(interp, newnode, childObj))
  1939   2106               != TCL_OK) {
  1940   2107               return rc;
  1941   2108           }
  1942   2109       }
  1943         -    return tcldom_returnNodeObj(interp, node, 0, NULL);
         2110  +    return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
  1944   2111   }
  1945   2112   
  1946   2113   
  1947   2114   /*----------------------------------------------------------------------------
  1948   2115   |   tcldom_treeAsTclList
  1949   2116   |
  1950   2117   \---------------------------------------------------------------------------*/
................................................................................
  2021   2188       objv[0] = name;
  2022   2189       objv[1] = attrsList;
  2023   2190       objv[2] = childList;
  2024   2191   
  2025   2192       return Tcl_NewListObj(3, objv);
  2026   2193   }
  2027   2194   
  2028         -
  2029   2195   /*----------------------------------------------------------------------------
  2030   2196   |   tcldom_AppendEscaped
  2031   2197   |
  2032   2198   \---------------------------------------------------------------------------*/
  2033   2199   static
  2034   2200   void tcldom_AppendEscaped (
  2035   2201       Tcl_Obj    *xmlString,
  2036   2202       Tcl_Channel chan,
  2037   2203       char       *value,
  2038   2204       int         value_length,
  2039         -    int         forAttr,
  2040         -    int         escapeNonASCII,
  2041         -    int         htmlEntities,
  2042         -    int         escapeAllQuot
         2205  +    int         outputFlags
  2043   2206   )
  2044   2207   {
  2045   2208   #define APESC_BUF_SIZE 512
  2046   2209   #define AP(c)  *b++ = c;
  2047   2210   #define AE(s)  pc1 = s; while(*pc1) *b++ = *pc1++;
  2048   2211       char  buf[APESC_BUF_SIZE+80], *b, *bLimit,  *pc, *pc1, *pEnd, charRef[10];
  2049   2212       int   charDone, i;
  2050         -#if !TclOnly8Bits
  2051   2213       int   clen = 0;
         2214  +    int   unicode;
  2052   2215       Tcl_UniChar uniChar;
  2053         -#endif
  2054         -
         2216  +    
  2055   2217       b = buf;
  2056   2218       bLimit = b + APESC_BUF_SIZE;
  2057   2219       pc = pEnd = value;
  2058   2220       if (value_length != -1) {
  2059   2221           pEnd = pc + value_length;
  2060   2222       }
  2061   2223       while (   (value_length == -1 && *pc)
  2062   2224              || (value_length != -1 && pc != pEnd)
  2063   2225       ) {
  2064         -        if ((forAttr || escapeAllQuot) && (*pc == '"')) { 
         2226  +        if ((*pc == '"') && (outputFlags & SERIALIZE_FOR_ATTR
         2227  +                             || outputFlags & SERIALIZE_ESCAPE_ALL_QUOT)) { 
  2065   2228               AP('&') AP('q') AP('u') AP('o') AP('t') AP(';')
  2066   2229           } else
  2067   2230           if (*pc == '&') { AP('&') AP('a') AP('m') AP('p') AP(';')
  2068   2231           } else
  2069   2232           if (*pc == '<') { AP('&') AP('l') AP('t') AP(';')
  2070   2233           } else
  2071         -        if (*pc == '>') { AP('&') AP('g') AP('t') AP(';')
         2234  +        if (*pc == '>' && !(outputFlags & SERIALIZE_NO_GT_ESCAPE)) {
         2235  +            AP('&') AP('g') AP('t') AP(';')
  2072   2236           } else
  2073         -        if (forAttr && (*pc == '\n')) { AP('&') AP('#') AP('x') AP('A') AP(';')
         2237  +        if ((*pc == '\n') && outputFlags & SERIALIZE_FOR_ATTR) {
         2238  +            AP('&') AP('#') AP('x') AP('A') AP(';')
  2074   2239           } else
  2075   2240           {
  2076   2241               charDone = 0;
  2077         -            if (htmlEntities) {
         2242  +            if (outputFlags & SERIALIZE_HTML_ENTITIES) {
  2078   2243                   charDone = 1;
  2079         -#if TclOnly8Bits
  2080         -                switch ((unsigned int)*pc)
  2081         -#else           
  2082   2244                   Tcl_UtfToUniChar(pc, &uniChar);
  2083   2245                   switch (uniChar) 
  2084         -#endif
  2085   2246                   {
  2086   2247                   case 0240: AE("&nbsp;");    break;     
  2087   2248                   case 0241: AE("&iexcl;");   break;    
  2088   2249                   case 0242: AE("&cent;");    break;     
  2089   2250                   case 0243: AE("&pound;");   break;    
  2090   2251                   case 0244: AE("&curren;");  break;   
  2091   2252                   case 0245: AE("&yen;");     break;      
................................................................................
  2175   2336                   case 0371: AE("&ugrave;");  break;   
  2176   2337                   case 0372: AE("&uacute;");  break;   
  2177   2338                   case 0373: AE("&ucirc;");   break;    
  2178   2339                   case 0374: AE("&uuml;");    break;     
  2179   2340                   case 0375: AE("&yacute;");  break;   
  2180   2341                   case 0376: AE("&thorn;");   break;    
  2181   2342                   case 0377: AE("&yuml;");    break;     
  2182         -#if !TclOnly8Bits
  2183   2343                   /* "Special" chars, according to XHTML xhtml-special.ent */
  2184   2344                   case 338:  AE("&OElig;");   break;
  2185   2345                   case 339:  AE("&oelig;");   break;
  2186   2346                   case 352:  AE("&Scaron;");  break;
  2187   2347                   case 353:  AE("&scaron;");  break;
  2188   2348                   case 376:  AE("&Yuml;");    break;
  2189   2349                   case 710:  AE("&circ;");    break;
................................................................................
  2330   2490                   case 9001: AE("&lang;");    break;     
  2331   2491                   case 9002: AE("&rang;");    break;     
  2332   2492                   case 9674: AE("&loz;");     break;      
  2333   2493                   case 9824: AE("&spades;");  break;   
  2334   2494                   case 9827: AE("&clubs;");   break;    
  2335   2495                   case 9829: AE("&hearts;");  break;   
  2336   2496                   case 9830: AE("&diams;");   break;    
  2337         -#endif                    
  2338   2497                   default: charDone = 0; 
  2339   2498                   }
  2340         -#if !TclOnly8Bits
  2341   2499                   if (charDone) {
  2342   2500                       clen = UTF8_CHAR_LEN(*pc);
  2343   2501                       pc += (clen - 1);
  2344   2502                   }
  2345         -#endif
  2346   2503               }
  2347         -#if TclOnly8Bits
  2348         -            if (!charDone) {
  2349         -                if (escapeNonASCII && ((unsigned char)*pc > 127)) {
  2350         -                    AP('&') AP('#')
  2351         -                    sprintf(charRef, "%d", (unsigned char)*pc);
  2352         -                    for (i = 0; i < 3; i++) {
  2353         -                        AP(charRef[i]);
  2354         -                    }
  2355         -                    AP(';')
  2356         -                } else {
  2357         -                    AP(*pc);
  2358         -                }
  2359         -            }
  2360         -#else
  2361   2504               if (!charDone) {
  2362   2505                   if ((unsigned char)*pc > 127) {
  2363   2506                       clen = UTF8_CHAR_LEN(*pc);
  2364   2507                       if (!clen) {
  2365   2508                           domPanic("tcldom_AppendEscaped: can only handle "
  2366         -                                 "UTF-8 chars up to 3 bytes length");
         2509  +                                 "UTF-8 chars up to 4 bytes length");
         2510  +
  2367   2511                       }
  2368         -                    if (escapeNonASCII) {
  2369         -                        Tcl_UtfToUniChar(pc, &uniChar);
         2512  +                    if (clen == 4 || outputFlags & SERIALIZE_ESCAPE_NON_ASCII) {
         2513  +                        if (clen == 4) {
         2514  +                            unicode = ((pc[0] & 0x07) << 18) 
         2515  +                                + ((pc[1] & 0x3F) << 12)
         2516  +                                + ((pc[2] & 0x3F) <<  6) 
         2517  +                                + (pc[3] & 0x3F);
         2518  +                        } else {
         2519  +                            unicode = 0;
         2520  +                            Tcl_UtfToUniChar(pc, (Tcl_UniChar*)&unicode);
         2521  +                        }
  2370   2522                           AP('&') AP('#')
  2371         -                            sprintf(charRef, "%d", uniChar);
         2523  +                        sprintf(charRef, "%d", unicode);
  2372   2524                           for (i = 0; i < (int)strlen(charRef); i++) {
  2373   2525                               AP(charRef[i]);
  2374   2526                           }
  2375   2527                           AP(';')
  2376   2528                           pc += (clen - 1);
  2377   2529                       } else {
  2378   2530                           for (i = 0; i < clen; i++) {
................................................................................
  2381   2533                           }
  2382   2534                           pc--;
  2383   2535                       }
  2384   2536                   } else {
  2385   2537                       AP(*pc);
  2386   2538                   }
  2387   2539               }
  2388         -#endif
  2389   2540           }
  2390   2541           if (b >= bLimit) {
  2391   2542               writeChars(xmlString, chan, buf, b - buf);
  2392   2543               b = buf;
  2393   2544           }
  2394   2545           pc++;
  2395   2546       }
................................................................................
  2431   2582       Tcl_Channel  chan,
  2432   2583       int          escapeNonASCII,
  2433   2584       int          htmlEntities,
  2434   2585       int          doctypeDeclaration,
  2435   2586       int          noEscaping
  2436   2587   )
  2437   2588   {
  2438         -    int          empty, scriptTag;
         2589  +    int          empty, scriptTag, outputFlags = 0;
  2439   2590       domNode     *child;
  2440   2591       domAttrNode *attrs;
  2441   2592       domDocument *doc;
  2442   2593       char         tag[80], attrName[80];
  2443   2594   
         2595  +    if (escapeNonASCII) outputFlags = SERIALIZE_ESCAPE_NON_ASCII;
         2596  +    if (htmlEntities) outputFlags |= SERIALIZE_HTML_ENTITIES;
  2444   2597       if (node->nodeType == DOCUMENT_NODE) {
  2445   2598           doc = (domDocument*) node;
  2446   2599           if (doctypeDeclaration && doc->documentElement) {
  2447   2600               writeChars(htmlString, chan, "<!DOCTYPE ", 10);
  2448   2601               writeChars(htmlString, chan, doc->documentElement->nodeName, -1);
  2449   2602               if (   doc->doctype 
  2450   2603                   && doc->doctype->systemId 
................................................................................
  2493   2646           if ((node->nodeFlags & DISABLE_OUTPUT_ESCAPING) 
  2494   2647               || noEscaping) {
  2495   2648               writeChars(htmlString, chan, ((domTextNode*)node)->nodeValue,
  2496   2649                          ((domTextNode*)node)->valueLength);
  2497   2650           } else {
  2498   2651               tcldom_AppendEscaped(htmlString, chan,
  2499   2652                                    ((domTextNode*)node)->nodeValue,
  2500         -                                 ((domTextNode*)node)->valueLength, 0,
  2501         -                                 escapeNonASCII, htmlEntities, 0);
         2653  +                                 ((domTextNode*)node)->valueLength,
         2654  +                                 outputFlags);
  2502   2655           }
  2503   2656           return;
  2504   2657       }
  2505   2658   
  2506   2659       if (node->nodeType == CDATA_SECTION_NODE) {
  2507   2660           if (noEscaping) {
  2508   2661               writeChars(htmlString, chan, ((domTextNode*)node)->nodeValue,
  2509   2662                          ((domTextNode*)node)->valueLength);
  2510   2663           } else {
  2511   2664               tcldom_AppendEscaped(htmlString, chan,
  2512   2665                                    ((domTextNode*)node)->nodeValue,
  2513         -                                 ((domTextNode*)node)->valueLength, 0,
  2514         -                                 escapeNonASCII, htmlEntities, 0);
         2666  +                                 ((domTextNode*)node)->valueLength,
         2667  +                                 outputFlags);
  2515   2668           }
         2669  +        return;
  2516   2670       }
  2517   2671   
  2518   2672       if (node->nodeType == COMMENT_NODE) {
  2519   2673           writeChars(htmlString, chan, "<!--", 4);
  2520   2674           writeChars(htmlString, chan, ((domTextNode*)node)->nodeValue,
  2521   2675                      ((domTextNode*)node)->valueLength);
  2522   2676           writeChars(htmlString, chan,  "-->", 3);
................................................................................
  2534   2688       |   empty tags and script tags (todo: HTML tags with
  2535   2689       |   URI attributes, to do escaping of Non-ASCII chars
  2536   2690       |   in the URI).
  2537   2691       \----------------------------------------------------------*/
  2538   2692       empty = 0;
  2539   2693       scriptTag = 0;
  2540   2694       switch (tag[0]) {
  2541         -        case 'a':  if (!strcmp(tag,"area"))       empty = 1; break;
  2542         -        case 'b':  if (!strcmp(tag,"br")     ||
  2543         -                       !strcmp(tag,"base")   ||
  2544         -                       !strcmp(tag,"basefont"))   empty = 1;
  2545         -        case 'c':  if (!strcmp(tag,"col"))        empty = 1; break;
  2546         -        case 'f':  if (!strcmp(tag,"frame"))      empty = 1; break;
  2547         -        case 'h':  if (!strcmp(tag,"hr"))         empty = 1; break;
  2548         -        case 'i':  if (!strcmp(tag,"img")    ||
  2549         -                       !strcmp(tag,"input")  ||
  2550         -                       !strcmp(tag,"isindex"))    empty = 1; break;
  2551         -        case 'l':  if (!strcmp(tag,"link"))       empty = 1; break;
  2552         -        case 'm':  if (!strcmp(tag,"meta"))       empty = 1; break;
  2553         -        case 'p':  if (!strcmp(tag,"param"))      empty = 1; break;
  2554         -        case 's':  if (!strcmp(tag,"script") ||     
  2555         -                       !strcmp(tag,"style"))  scriptTag = 1; break;
         2695  +    case 'a':  if (!strcmp(tag,"area"))       {empty = 1;} break;
         2696  +    case 'b':  if (!strcmp(tag,"br")     ||
         2697  +                   !strcmp(tag,"base")   ||
         2698  +                   !strcmp(tag,"basefont"))   {empty = 1;} break;
         2699  +    case 'c':  if (!strcmp(tag,"col"))        {empty = 1;} break;
         2700  +    case 'f':  if (!strcmp(tag,"frame"))      {empty = 1;} break;
         2701  +    case 'h':  if (!strcmp(tag,"hr"))         {empty = 1;} break;
         2702  +    case 'i':  if (!strcmp(tag,"img")    ||
         2703  +                   !strcmp(tag,"input")  ||
         2704  +                   !strcmp(tag,"isindex"))    {empty = 1;} break;
         2705  +    case 'l':  if (!strcmp(tag,"link"))       {empty = 1;} break;
         2706  +    case 'm':  if (!strcmp(tag,"meta"))       {empty = 1;} break;
         2707  +    case 'p':  if (!strcmp(tag,"param"))      {empty = 1;} break;
         2708  +    case 's':  if (!strcmp(tag,"script") ||     
         2709  +                   !strcmp(tag,"style"))  {scriptTag = 1;} break;
  2556   2710       }
  2557   2711   
  2558   2712   
  2559   2713       attrs = node->firstAttr;
  2560   2714       while (attrs) {
  2561   2715           tcldom_tolower(attrs->nodeName, attrName, 80);
  2562   2716           writeChars(htmlString, chan, " ", 1);
  2563   2717           writeChars (htmlString, chan, attrName, -1);
  2564   2718           writeChars(htmlString, chan, "=\"", 2);
  2565         -        tcldom_AppendEscaped(htmlString, chan, attrs->nodeValue, -1, 1,
  2566         -                             escapeNonASCII, htmlEntities, 0);
         2719  +        tcldom_AppendEscaped(htmlString, chan, attrs->nodeValue, -1,
         2720  +                             outputFlags | SERIALIZE_FOR_ATTR);
  2567   2721           writeChars(htmlString, chan, "\"", 1);
  2568   2722           attrs = attrs->nextSibling;
  2569   2723       }
  2570   2724       writeChars(htmlString, chan, ">", 1);
  2571   2725   
  2572   2726   
  2573   2727       if (empty) {
................................................................................
  2611   2765   void tcldom_treeAsXML (
  2612   2766       Tcl_Obj    *xmlString,
  2613   2767       domNode    *node,
  2614   2768       int         indent,
  2615   2769       int         level,
  2616   2770       int         doIndent,
  2617   2771       Tcl_Channel chan,
  2618         -    int         escapeNonASCII,
  2619         -    int         doctypeDeclaration,
         2772  +    Tcl_Obj    *encString,
  2620   2773       int         cdataChild,
  2621         -    int         escapeAllQuot
         2774  +    int         outputFlags,
         2775  +    int         indentAttrs
  2622   2776   )
  2623   2777   {
  2624   2778       domAttrNode   *attrs;
  2625   2779       domNode       *child;
  2626   2780       domDocument   *doc;
  2627   2781       int            first, hasElements, i;
  2628   2782       char           prefix[MAX_PREFIX_LEN], *start, *p;
  2629   2783       const char    *localName;
  2630   2784       Tcl_HashEntry *h;
  2631   2785       Tcl_DString    dStr;
  2632   2786   
         2787  +    if (outputFlags & SERIALIZE_XML_DECLARATION) {
         2788  +        outputFlags &= ~SERIALIZE_XML_DECLARATION;
         2789  +        writeChars(xmlString, chan, "<?xml version=\"1.0\"", 19);
         2790  +        if (encString) {
         2791  +            writeChars(xmlString, chan, " encoding=\"", 11);
         2792  +            writeChars(xmlString, chan,
         2793  +                       Tcl_GetString(encString), -1);
         2794  +            writeChars(xmlString, chan, "\"", 1);
         2795  +        } else if (node->nodeType == DOCUMENT_NODE &&
         2796  +                   ((domDocument*) node)->doctype &&
         2797  +                   ((domDocument*) node)->doctype->encoding) {
         2798  +            writeChars(xmlString, chan, " encoding=\"", 11);
         2799  +            writeChars(xmlString, chan,
         2800  +                       ((domDocument*) node)->doctype->encoding, -1);
         2801  +            writeChars(xmlString, chan, "\"", 1);
         2802  +        }
         2803  +        writeChars(xmlString, chan, "?>\n", 3);
         2804  +    }
  2633   2805       if (node->nodeType == DOCUMENT_NODE) {
  2634   2806           doc = (domDocument*) node;
  2635         -        if (doctypeDeclaration && doc->documentElement) {
         2807  +        if (outputFlags & SERIALIZE_DOCTYPE_DECLARATION
         2808  +            && doc->documentElement) {
  2636   2809               writeChars(xmlString, chan, "<!DOCTYPE ", 10);
  2637   2810               writeChars(xmlString, chan, doc->documentElement->nodeName, -1);
  2638   2811               if (   doc->doctype 
  2639   2812                   && doc->doctype->systemId
  2640   2813                   && (doc->doctype->systemId[0] != '\0')) {
  2641   2814                   if (   doc->doctype->publicId 
  2642   2815                       && doc->doctype->publicId[0] != '\0') {
................................................................................
  2658   2831                   }
  2659   2832               }
  2660   2833               writeChars(xmlString, chan, ">\n", 2);
  2661   2834           }
  2662   2835           child = doc->rootNode->firstChild;
  2663   2836           while (child) {
  2664   2837               tcldom_treeAsXML(xmlString, child, indent, level, doIndent, chan,
  2665         -                             escapeNonASCII, doctypeDeclaration, 0,
  2666         -                             escapeAllQuot);
         2838  +                             NULL, 0, outputFlags, indentAttrs);
  2667   2839               child = child->nextSibling;
  2668   2840           }
  2669   2841           return;
  2670   2842       }
  2671   2843   
  2672   2844       if (node->nodeType == TEXT_NODE) {
  2673   2845           if (cdataChild) {
................................................................................
  2695   2867           } else {
  2696   2868               if (node->nodeFlags & DISABLE_OUTPUT_ESCAPING) {
  2697   2869                   writeChars(xmlString, chan, ((domTextNode*)node)->nodeValue,
  2698   2870                              ((domTextNode*)node)->valueLength);
  2699   2871               } else {
  2700   2872                   tcldom_AppendEscaped(xmlString, chan,
  2701   2873                                        ((domTextNode*)node)->nodeValue,
  2702         -                                     ((domTextNode*)node)->valueLength, 0,
  2703         -                                     escapeNonASCII, 0, escapeAllQuot);
         2874  +                                     ((domTextNode*)node)->valueLength,
         2875  +                                     outputFlags);
  2704   2876               }
  2705   2877           }
  2706   2878           return;
  2707   2879       }
  2708   2880   
  2709   2881       if (node->nodeType == CDATA_SECTION_NODE) {
  2710   2882           writeChars(xmlString, chan, "<![CDATA[", 9);
................................................................................
  2744   2916       }
  2745   2917   
  2746   2918       writeChars(xmlString, chan, "<", 1);
  2747   2919       writeChars(xmlString, chan, node->nodeName, -1);
  2748   2920   
  2749   2921       attrs = node->firstAttr;
  2750   2922       while (attrs) {
  2751         -        writeChars(xmlString, chan, " ", 1);
         2923  +        if (indentAttrs > -1) {
         2924  +            writeChars(xmlString, chan, "\n", 1);
         2925  +            if ((indent != -1) && doIndent) {
         2926  +                for(i=0; i<level; i++) {
         2927  +                    writeChars(xmlString, chan, "        ", indent);
         2928  +                }
         2929  +                if (indentAttrs) {
         2930  +                    writeChars(xmlString, chan, "        ", indentAttrs);
         2931  +                }
         2932  +            }
         2933  +        } else {
         2934  +            writeChars(xmlString, chan, " ", 1);
         2935  +        }
  2752   2936           writeChars(xmlString, chan, attrs->nodeName, -1);
  2753   2937           writeChars(xmlString, chan, "=\"", 2);
  2754   2938           tcldom_AppendEscaped(xmlString, chan, attrs->nodeValue, 
  2755         -                             attrs->valueLength, 1, escapeNonASCII, 0,
  2756         -                             escapeAllQuot);
         2939  +                             attrs->valueLength,
         2940  +                             outputFlags | SERIALIZE_FOR_ATTR);
  2757   2941           writeChars(xmlString, chan, "\"", 1);
  2758   2942           attrs = attrs->nextSibling;
  2759   2943       }
  2760   2944   
  2761   2945       hasElements = 0;
  2762   2946       first       = 1;
  2763   2947       doIndent    = 1;
................................................................................
  2798   2982                   writeChars(xmlString, chan, ">", 1);
  2799   2983                   if ((indent != -1) && hasElements) {
  2800   2984                       writeChars(xmlString, chan, "\n", 1);
  2801   2985                   }
  2802   2986               }
  2803   2987               first = 0;
  2804   2988               tcldom_treeAsXML(xmlString, child, indent, level+1, doIndent,
  2805         -                             chan, escapeNonASCII, doctypeDeclaration,
  2806         -                             cdataChild, escapeAllQuot);
         2989  +                             chan, NULL, cdataChild, outputFlags, indentAttrs);
  2807   2990               doIndent = 0;
  2808   2991               if (  (child->nodeType == ELEMENT_NODE)
  2809   2992                   ||(child->nodeType == PROCESSING_INSTRUCTION_NODE)
  2810   2993                   ||(child->nodeType == COMMENT_NODE) )
  2811   2994               {
  2812   2995                  doIndent = 1;
  2813   2996               }
  2814   2997               child = child->nextSibling;
  2815   2998           }
  2816   2999       }
  2817   3000   
  2818   3001       if (first) {
  2819   3002           if (indent != -1) {
  2820         -            writeChars(xmlString, chan, "/>\n", 3);
         3003  +            if (outputFlags & SERIALIZE_NO_EMPTY_ELEMENT_TAG) {
         3004  +                writeChars (xmlString, chan, "></", 3);
         3005  +                writeChars(xmlString, chan, node->nodeName, -1);
         3006  +                writeChars(xmlString, chan, ">\n", 2);
         3007  +            } else {
         3008  +                writeChars(xmlString, chan, "/>\n", 3);
         3009  +            }
  2821   3010           } else {
  2822         -            writeChars(xmlString, chan, "/>",   2);
         3011  +            if (outputFlags & SERIALIZE_NO_EMPTY_ELEMENT_TAG) {
         3012  +                writeChars (xmlString, chan, "></", 3);
         3013  +                writeChars(xmlString, chan, node->nodeName, -1);
         3014  +                writeChars(xmlString, chan, ">", 1);
         3015  +            } else {
         3016  +                writeChars(xmlString, chan, "/>",   2);
         3017  +            }
  2823   3018           }
  2824   3019       } else {
  2825   3020           if ((indent != -1) && hasElements) {
  2826   3021               for(i=0; i<level; i++) {
  2827   3022                   writeChars(xmlString, chan, "        ", indent);
  2828   3023               }
  2829   3024           }
................................................................................
  2832   3027           if (indent != -1) {
  2833   3028               writeChars(xmlString, chan, ">\n", 2);
  2834   3029           } else {
  2835   3030               writeChars(xmlString, chan, ">",   1);
  2836   3031           }
  2837   3032       }
  2838   3033   }
         3034  +
         3035  +/*----------------------------------------------------------------------------
         3036  +|   tcldom_AppendEscapedJSON
         3037  +|
         3038  +\---------------------------------------------------------------------------*/
         3039  +static
         3040  +void tcldom_AppendEscapedJSON (
         3041  +    Tcl_Obj    *jstring,
         3042  +    Tcl_Channel chan,
         3043  +    char       *value,
         3044  +    int         value_length
         3045  +)
         3046  +{
         3047  +    char  buf[APESC_BUF_SIZE+80], *b, *bLimit,  *pc, *pEnd;
         3048  +    int   i;
         3049  +    int   clen = 0;
         3050  +
         3051  +    b = buf;
         3052  +    bLimit = b + APESC_BUF_SIZE;
         3053  +    pc = pEnd = value;
         3054  +    if (value_length != -1) {
         3055  +        pEnd = pc + value_length;
         3056  +    }
         3057  +    AP('"');
         3058  +    while (
         3059  +        (value_length == -1 && *pc)
         3060  +        || (value_length != -1 && pc != pEnd)
         3061  +    ) {
         3062  +        clen = UTF8_CHAR_LEN(*pc);
         3063  +        if (!clen) {
         3064  +            /* This would be invalid utf-8 encoding. */
         3065  +            clen = 1;
         3066  +        }
         3067  +        if (clen == 1) {
         3068  +            if (*pc == '\\') {
         3069  +                AP('\\'); AP('\\');
         3070  +            } else if (*pc == '"') {
         3071  +                AP('\\'); AP('"');
         3072  +            } else if (*pc == '\b') {
         3073  +                AP('\\'); AP('b');
         3074  +            } else if (*pc == '\f') {
         3075  +                AP('\\'); AP('f');
         3076  +            } else if (*pc == '\n') {
         3077  +                AP('\\'); AP('n');
         3078  +            } else if (*pc == '\r') {
         3079  +                AP('\\'); AP('r');
         3080  +            } else if (*pc == '\t') {
         3081  +                AP('\\'); AP('t');
         3082  +            } else if ((unsigned char)*pc < 0x20) {
         3083  +                AP('\\'); AP('u'); AP('0'); AP('0');
         3084  +                AP('0' + (*pc>>4));
         3085  +                AP("0123456789abcdef"[*pc&0xf]);
         3086  +            } else {
         3087  +                AP(*pc);
         3088  +            }
         3089  +            pc++;
         3090  +        } else {
         3091  +            if ((unsigned char)*pc == 0xC0 && (unsigned char)*(pc+1) == 0x80) {
         3092  +                AP('\\');AP('u');AP('0');AP('0');AP('0');AP('0');
         3093  +                pc++;pc++;
         3094  +            } else {
         3095  +                for (i = 0; i < clen; i++) {
         3096  +                    AP(*pc);
         3097  +                    pc++;
         3098  +                }
         3099  +            }
         3100  +        }
         3101  +        if (b >= bLimit) {
         3102  +            writeChars(jstring, chan, buf, b - buf);
         3103  +            b = buf;
         3104  +        }
         3105  +    }
         3106  +    AP('"');
         3107  +    writeChars(jstring, chan, buf, b - buf);
         3108  +}
         3109  +
         3110  +static
         3111  +void tcldom_childsAsJSON (
         3112  +    Tcl_Obj     *jstring,
         3113  +    domNode     *node, /* Must be an ELEMENT_NODE */
         3114  +    Tcl_Channel  channel,
         3115  +    int          indent,
         3116  +    int          level,
         3117  +    int          inside
         3118  +    )
         3119  +{
         3120  +    domNode   *child, *nextChild;
         3121  +    int i, effectivParentType = 0;
         3122  +    int first = 1;
         3123  +
         3124  +    child = node->firstChild;
         3125  +    while (child
         3126  +           && child->nodeType != TEXT_NODE
         3127  +           && child->nodeType != ELEMENT_NODE) {
         3128  +        child = child->nextSibling;
         3129  +    }
         3130  +
         3131  +    if (node->info == JSON_ARRAY || node->info == JSON_OBJECT) {
         3132  +        effectivParentType = node->info;
         3133  +    } else if (child == NULL) {
         3134  +        /* Need 'heuristic rule' to decide, what to do. */
         3135  +        switch (inside) {
         3136  +        case JSON_OBJECT:
         3137  +            /* The childs to serialize are the value of an object member. */
         3138  +            /* No content at all. This could be an empty string,
         3139  +             * an empty object or an empty array. We default to
         3140  +             * empty string. */
         3141  +            writeChars(jstring, channel, "\"\"",2);
         3142  +            return;
         3143  +        case JSON_START:
         3144  +        case JSON_ARRAY:
         3145  +            /* The childs, we serialize are the value of an array
         3146  +             * element. The node is a container for either a
         3147  +             * (nested, in case of JSON_ARRAY) array or an object. */
         3148  +            /* Look, if the name of the container gives a hint.*/
         3149  +            if (strcmp (node->nodeName, JSON_ARRAY_CONTAINER)==0) {
         3150  +                effectivParentType = JSON_ARRAY;
         3151  +                break;
         3152  +            }
         3153  +            /* If we here, heuristics didn't helped. We have to
         3154  +             * default to something. Let's say ... */
         3155  +            effectivParentType = JSON_OBJECT;
         3156  +            break;
         3157  +        }
         3158  +    } else {
         3159  +        if (child->nodeType == ELEMENT_NODE) {
         3160  +            /* The first 'relevant' child node is ELEMENT_NODE */
         3161  +            effectivParentType = JSON_OBJECT;
         3162  +            if (inside == JSON_ARRAY) {
         3163  +                /* Though, if we inside of an array and the node name
         3164  +                 * of the first 'relevant' child is the array
         3165  +                 * container element, we assume an array (with a
         3166  +                 * nested array as first value of that array. */
         3167  +                if (strcmp (child->nodeName, JSON_ARRAY_CONTAINER))
         3168  +                    effectivParentType = JSON_ARRAY;
         3169  +            }
         3170  +        } else {
         3171  +            /* If we are here, the first 'relevant' child is a
         3172  +             * text node. If there is any other 'relevant' child,
         3173  +             * we assume the value to be an array. Otherwise (only
         3174  +             * single 'relevant' child is a text node), this is
         3175  +             * any of string, true, false null. Child may have a
         3176  +             * type hint. */
         3177  +            nextChild = child->nextSibling;
         3178  +            while (nextChild
         3179  +                   && nextChild->nodeType != TEXT_NODE
         3180  +                   && nextChild->nodeType != ELEMENT_NODE) {
         3181  +                nextChild = nextChild->nextSibling;
         3182  +            }
         3183  +            if (nextChild) {
         3184  +                effectivParentType = JSON_ARRAY;
         3185  +            } else {
         3186  +                /* Exactly one 'relevant' child node, a text node;
         3187  +                 * serialize it as simple token value. */
         3188  +                tcldom_treeAsJSON (jstring, child, channel, indent,
         3189  +                                   level, JSON_ARRAY);
         3190  +                return;
         3191  +            }
         3192  +        }
         3193  +    }
         3194  +        
         3195  +    switch (effectivParentType) {
         3196  +    case JSON_ARRAY:
         3197  +        writeChars(jstring, channel, "[",1);
         3198  +        while (child) {
         3199  +            if (first) {
         3200  +                first = 0;
         3201  +                level++;
         3202  +            } else {
         3203  +                writeChars(jstring, channel, ",", 1);
         3204  +            }
         3205  +            if (indent > -1) {
         3206  +                writeChars(jstring, channel, "\n", 1);
         3207  +                if (first) level++;
         3208  +                for (i = 0; i < level; i++) {
         3209  +                    writeChars(jstring, channel, "        ", indent);
         3210  +                }
         3211  +            }
         3212  +            tcldom_treeAsJSON (jstring, child, channel, indent,
         3213  +                               level, JSON_ARRAY);
         3214  +            child = child->nextSibling;
         3215  +            while (child
         3216  +                   && child->nodeType != TEXT_NODE
         3217  +                   && child->nodeType != ELEMENT_NODE) {
         3218  +                child = child->nextSibling;
         3219  +            }
         3220  +        }
         3221  +        if (indent > -1 && first == 0) {
         3222  +            writeChars(jstring, channel, "\n", 1);
         3223  +            level--;
         3224  +            for (i = 0; i < level; i++) {
         3225  +                writeChars(jstring, channel, "        ", indent);
         3226  +            }
         3227  +        }
         3228  +        writeChars(jstring, channel, "]",1);
         3229  +        break;
         3230  +    case JSON_OBJECT:
         3231  +        writeChars(jstring, channel, "{",1);
         3232  +        while (child) {
         3233  +            if (first) {
         3234  +                first = 0;
         3235  +                level++;
         3236  +            } else {
         3237  +                writeChars(jstring, channel, ",", 1);
         3238  +            }
         3239  +            if (indent > -1) {
         3240  +                writeChars(jstring, channel, "\n", 1);
         3241  +                if (first) level++;
         3242  +                for (i = 0; i < level; i++) {
         3243  +                    writeChars(jstring, channel, "        ", indent);
         3244  +                }
         3245  +            }
         3246  +            tcldom_treeAsJSON (jstring, child, channel, indent,
         3247  +                               level, JSON_OBJECT);
         3248  +            child = child->nextSibling;
         3249  +            /* Inside of a JSON_OBJECT, only element childs make
         3250  +             * semantically sense. */
         3251  +            while (child && child->nodeType != ELEMENT_NODE) {
         3252  +                child = child->nextSibling;
         3253  +            }
         3254  +        }
         3255  +        if (indent > -1 && first == 0) {
         3256  +            writeChars(jstring, channel, "\n", 1);
         3257  +            level--;
         3258  +            for (i = 0; i < level; i++) {
         3259  +                writeChars(jstring, channel, "        ", indent);
         3260  +            }
         3261  +        }
         3262  +        writeChars(jstring, channel, "}",1);
         3263  +        break;
         3264  +    default:
         3265  +        break;
         3266  +    }
         3267  +}
         3268  +
         3269  +
         3270  +/*----------------------------------------------------------------------------
         3271  +|   tcldom_treeAsJSON
         3272  +|
         3273  +\---------------------------------------------------------------------------*/
         3274  +static
         3275  +void tcldom_treeAsJSON (
         3276  +    Tcl_Obj     *jstring,
         3277  +    domNode     *node,  /* Must not be NULL */
         3278  +    Tcl_Channel  channel,
         3279  +    int          indent,
         3280  +    int          level,
         3281  +    int          inside
         3282  +    )
         3283  +{
         3284  +    domTextNode *textNode;
         3285  +    int i, seenDP, seenE;
         3286  +    unsigned char c;
         3287  +    char *num;
         3288  +    
         3289  +    switch (node->nodeType) {
         3290  +    case TEXT_NODE:
         3291  +        if (inside == JSON_OBJECT) {
         3292  +            /* We're inside a JSON object. A text node can not be
         3293  +             * meaningful interpreted as member of an object. Ignore
         3294  +             * the node */
         3295  +            return;
         3296  +        }
         3297  +        textNode = (domTextNode *) node;
         3298  +        switch (node->info) {
         3299  +        case JSON_NUMBER:
         3300  +            /* Check, if the text value is a JSON number and fall back
         3301  +             * to string token, if not. This is to ensure, the
         3302  +             * serialization is always a valid JSON string. */
         3303  +            if (textNode->valueLength == 0) goto notANumber;
         3304  +            seenDP = 0;
         3305  +            seenE = 0;
         3306  +            i = 0;
         3307  +            num = textNode->nodeValue;
         3308  +            c = num[0];
         3309  +            if (!(c == '-' || (c>='0' && c<='9'))) goto notANumber;
         3310  +            if (c<='0') {
         3311  +                i = (c == '-' ? i+1 : i);
         3312  +                if (i+1 < textNode->valueLength) {
         3313  +                    if (num[i] == '0' && num[i+1] >= '0' && num[i+1] <= '9') {
         3314  +                        goto notANumber;
         3315  +                    }
         3316  +                }
         3317  +            }
         3318  +            i = 1;
         3319  +            for (; i < textNode->valueLength; i++) {
         3320  +                c = num[i];
         3321  +                if (c >= '0' && c <= '9') continue;
         3322  +                if (c == '.') {
         3323  +                    if (num[i-1] == '-') goto notANumber;
         3324  +                    if (seenDP) goto notANumber;
         3325  +                    seenDP = 1;
         3326  +                    continue;
         3327  +                }
         3328  +                if (c == 'e' || c == 'E') {
         3329  +                    if (num[i-1] < '0') goto notANumber;
         3330  +                    if (seenE) goto notANumber;
         3331  +                    seenDP = seenE = 1;
         3332  +                    c = num[i+1];
         3333  +                    if (c == '+' || c == '-') {
         3334  +                        i++;
         3335  +                        c = num[i+1];
         3336  +                    }
         3337  +                    if (c < '0' || c > '9') goto notANumber;
         3338  +                    continue;
         3339  +                }
         3340  +                break;
         3341  +            }
         3342  +            /* Catches a plain '-' without following digits */
         3343  +            if (num[i-1] < '0') goto notANumber;
         3344  +            /* Catches trailing chars */
         3345  +            if (i < textNode->valueLength) goto notANumber;
         3346  +            writeChars(jstring, channel, textNode->nodeValue,
         3347  +                       textNode->valueLength);
         3348  +            break;
         3349  +            notANumber:
         3350  +            tcldom_AppendEscapedJSON (jstring, channel,
         3351  +                                      textNode->nodeValue,
         3352  +                                      textNode->valueLength);
         3353  +            break;
         3354  +        case JSON_NULL:
         3355  +            writeChars(jstring, channel, "null",4);
         3356  +            break;
         3357  +        case JSON_TRUE:
         3358  +            writeChars(jstring, channel, "true",4);
         3359  +            break;
         3360  +        case JSON_FALSE:
         3361  +            writeChars(jstring, channel, "false",5);
         3362  +            break;
         3363  +        case JSON_STRING:
         3364  +            /* Fall through */
         3365  +        default:
         3366  +            tcldom_AppendEscapedJSON (jstring, channel,
         3367  +                                      textNode->nodeValue,
         3368  +                                      textNode->valueLength);
         3369  +            break;
         3370  +        };
         3371  +        return;
         3372  +    case ELEMENT_NODE:
         3373  +        switch (inside) {
         3374  +        case JSON_OBJECT:
         3375  +            /* Write the member name and recurse to the childs for the
         3376  +             * value. */
         3377  +            tcldom_AppendEscapedJSON (jstring, channel,
         3378  +                                      node->nodeName, -1);
         3379  +            writeChars (jstring, channel, ":", 1);
         3380  +            tcldom_childsAsJSON (jstring, node, channel, indent,
         3381  +                                 level, inside);
         3382  +            break;
         3383  +        case JSON_ARRAY:
         3384  +            /* Since we're already inside of an array, the element can
         3385  +               only be interpreted as a container for a nested JSON
         3386  +               object or array. */
         3387  +            tcldom_childsAsJSON (jstring, node, channel, indent,
         3388  +                                 level, inside);
         3389  +            break;
         3390  +        case JSON_START:
         3391  +            tcldom_childsAsJSON (jstring, node, channel, indent,
         3392  +                                 level, inside);            
         3393  +            break;
         3394  +        }
         3395  +        return;
         3396  +    default:
         3397  +        /* Any other node types (COMMENT_NODE, CDATA_SECTION_NODE, 
         3398  +           PROCESSING_INSTRUCTION_NODE) are ignored. */
         3399  +        return;
         3400  +    }
         3401  +}
  2839   3402   
  2840   3403   /*----------------------------------------------------------------------------
  2841   3404   |   findBaseURI
  2842   3405   |
  2843   3406   \---------------------------------------------------------------------------*/
  2844   3407   const char *findBaseURI (
  2845   3408       domNode *node
................................................................................
  2875   3438   |   serializeAsXML
  2876   3439   |
  2877   3440   \---------------------------------------------------------------------------*/
  2878   3441   static int serializeAsXML (
  2879   3442       domNode    *node,
  2880   3443       Tcl_Interp *interp,
  2881   3444       int         objc,
  2882         -    Tcl_Obj    *CONST objv[]
         3445  +    Tcl_Obj    *const objv[]
  2883   3446   )
  2884   3447   {
  2885   3448       char          *channelId, prefix[MAX_PREFIX_LEN];
  2886   3449       const char    *localName;
  2887         -    int            indent, mode, escapeNonASCII = 0, doctypeDeclaration = 0;
  2888         -    int            optionIndex, cdataChild, escapeAllQuot = 0;
  2889         -    Tcl_Obj       *resultPtr;
         3450  +    int            indent, mode, bool;
         3451  +    int            outputFlags = 0;
         3452  +    int            optionIndex, cdataChild;
         3453  +    Tcl_Obj       *resultPtr, *encString = NULL;
  2890   3454       Tcl_Channel    chan = (Tcl_Channel) NULL;
  2891   3455       Tcl_HashEntry *h;
  2892   3456       Tcl_DString    dStr;
         3457  +    int            indentAttrs = -1;
  2893   3458   
  2894         -    static CONST84 char *asXMLOptions[] = {
         3459  +    static const char *asXMLOptions[] = {
  2895   3460           "-indent", "-channel", "-escapeNonASCII", "-doctypeDeclaration",
  2896         -        "-escapeAllQuot", 
         3461  +        "-xmlDeclaration", "-encString", "-escapeAllQuot", "-indentAttrs",
         3462  +        "-nogtescape", "-noEmptyElementTag",
  2897   3463           NULL
  2898   3464       };
  2899   3465       enum asXMLOption {
  2900   3466           m_indent, m_channel, m_escapeNonASCII, m_doctypeDeclaration,
  2901         -        m_escapeAllQuot
         3467  +        m_xmlDeclaration, m_encString, m_escapeAllQuot, m_indentAttrs,
         3468  +        m_nogtescape, m_noEmptyElementTag
  2902   3469       };
  2903   3470       
  2904         -    if (objc > 10) {
  2905         -        Tcl_WrongNumArgs(interp, 2, objv,
  2906         -                         "?-indent <0..8>? ?-channel <channelID>? "
  2907         -                         "?-escapeNonASCII? ?-escapeAllQuot? "
  2908         -                         "?-doctypeDeclaration <boolean>?");
  2909         -        return TCL_ERROR;
  2910         -    }
  2911   3471       indent = 4;
  2912   3472       while (objc > 2) {
  2913   3473           if (Tcl_GetIndexFromObj(interp, objv[2], asXMLOptions, "option", 0,
  2914   3474                                  &optionIndex) != TCL_OK) {
  2915         -            return TCL_ERROR;
         3475  +            goto cleanup;
  2916   3476           }
  2917   3477           switch ((enum asXMLOption) optionIndex) {
  2918   3478   
  2919   3479           case m_indent:
  2920   3480               if (objc < 4) {
  2921   3481                   SetResult("-indent must have an argument "
  2922   3482                             "(0..8 or 'no'/'none')");
  2923         -                return TCL_ERROR;
         3483  +                goto cleanup;
  2924   3484               }
  2925   3485               if (strcmp("none", Tcl_GetString(objv[3]))==0) {
  2926   3486                   indent = -1;
  2927   3487               }
  2928   3488               else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
  2929   3489                   indent = -1;
  2930   3490               }
  2931   3491               else if (Tcl_GetIntFromObj(interp, objv[3], &indent) != TCL_OK) {
  2932   3492                   SetResult( "indent must be an integer (0..8) or 'no'/'none'");
  2933         -                return TCL_ERROR;
         3493  +                goto cleanup;
  2934   3494               }
  2935   3495               objc -= 2;
  2936   3496               objv += 2;
  2937   3497               break;
         3498  +
         3499  +        case m_indentAttrs:
         3500  +            if (objc < 4) {
         3501  +                SetResult("-indentAttrs must have an argument "
         3502  +                          "(0..8 or 'no'/'none')");
         3503  +                goto cleanup;
         3504  +            }
         3505  +            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
         3506  +                indentAttrs = -1;
         3507  +            }
         3508  +            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
         3509  +                indentAttrs = -1;
         3510  +            }
         3511  +            else if (Tcl_GetIntFromObj(interp, objv[3], &indentAttrs) != TCL_OK) {
         3512  +                SetResult( "indentAttrs must be an integer (0..8) or 'no'/'none'");
         3513  +                goto cleanup;
         3514  +            }
         3515  +            if (indentAttrs > 8) indentAttrs = 8;
         3516  +            if (indentAttrs < 0) indentAttrs = 0;
         3517  +            objc -= 2;
         3518  +            objv += 2;
         3519  +            break;
  2938   3520   
  2939   3521           case m_channel:
  2940   3522               if (objc < 4) {
  2941   3523                   SetResult("-channel must have a channeldID as argument");
  2942         -                return TCL_ERROR;
         3524  +                goto cleanup;
  2943   3525               }
  2944   3526               channelId = Tcl_GetString(objv[3]);
  2945   3527               chan = Tcl_GetChannel(interp, channelId, &mode);
  2946   3528               if (chan == (Tcl_Channel) NULL) {
  2947   3529                   SetResult("-channel must have a channeldID as argument");
  2948         -                return TCL_ERROR;
         3530  +                goto cleanup;
  2949   3531               }
  2950   3532               if ((mode & TCL_WRITABLE) == 0) {
  2951   3533                   Tcl_AppendResult(interp, "channel \"", channelId,
  2952         -                                "\" wasn't opened for writing", (char*)NULL);
  2953         -                return TCL_ERROR;
         3534  +                                "\" isnt't opened for writing", (char*)NULL);
         3535  +                goto cleanup;
  2954   3536               }
  2955   3537               objc -= 2;
  2956   3538               objv += 2;
  2957   3539               break;
  2958   3540   
  2959   3541           case m_escapeNonASCII:
  2960         -            escapeNonASCII = 1;
         3542  +            outputFlags |= SERIALIZE_ESCAPE_NON_ASCII;
  2961   3543               objc--;
  2962   3544               objv++;
  2963   3545               break;
  2964   3546               
  2965   3547           case m_doctypeDeclaration:
  2966   3548               if (node->nodeType != DOCUMENT_NODE) {
  2967   3549                   SetResult("-doctypeDeclaration as flag to the method "
  2968   3550                             "'asXML' is only allowed for domDocCmds");
  2969         -                return TCL_ERROR;
         3551  +                goto cleanup;
  2970   3552               }
  2971   3553               if (objc < 4) {
  2972   3554                   SetResult("-doctypeDeclaration must have a boolean value "
  2973   3555                             "as argument");
  2974         -                return TCL_ERROR;
         3556  +                goto cleanup;
  2975   3557               }
  2976         -            if (Tcl_GetBooleanFromObj(interp, objv[3], &doctypeDeclaration)
         3558  +            if (Tcl_GetBooleanFromObj(interp, objv[3], &bool)
         3559  +                != TCL_OK) {
         3560  +                goto cleanup;
         3561  +            }
         3562  +            if (bool) outputFlags |= SERIALIZE_DOCTYPE_DECLARATION;
         3563  +            objc -= 2;
         3564  +            objv += 2;
         3565  +            break;
         3566  +
         3567  +        case m_xmlDeclaration:
         3568  +            if (objc < 4) {
         3569  +                SetResult("-xmlDeclaration must have a boolean value "
         3570  +                          "as argument");
         3571  +                goto cleanup;
         3572  +            }
         3573  +            if (Tcl_GetBooleanFromObj(interp, objv[3], &bool)
  2977   3574                   != TCL_OK) {
  2978         -                return TCL_ERROR;
         3575  +                goto cleanup;
  2979   3576               }
         3577  +            if (bool) outputFlags |= SERIALIZE_XML_DECLARATION;
         3578  +            objc -= 2;
         3579  +            objv += 2;
         3580  +            break;
         3581  +
         3582  +        case m_encString:
         3583  +            if (objc < 4) {
         3584  +                SetResult("-encString must have a string "
         3585  +                          "as argument");
         3586  +                goto cleanup;
         3587  +            }
         3588  +            if (encString) {
         3589  +                Tcl_DecrRefCount(encString);
         3590  +            }
         3591  +            encString = objv[3];
         3592  +            Tcl_IncrRefCount(encString);
  2980   3593               objc -= 2;
  2981   3594               objv += 2;
  2982   3595               break;
  2983         -
         3596  +            
  2984   3597           case m_escapeAllQuot:
  2985         -            escapeAllQuot = 1;
         3598  +            outputFlags |= SERIALIZE_ESCAPE_ALL_QUOT;
         3599  +            objc -= 1;
         3600  +            objv += 1;
         3601  +            break;
         3602  +
         3603  +        case m_nogtescape:
         3604  +            outputFlags |= SERIALIZE_NO_GT_ESCAPE;
         3605  +            objc -= 1;
         3606  +            objv += 1;
         3607  +            break;
         3608  +
         3609  +        case m_noEmptyElementTag:
         3610  +            outputFlags |= SERIALIZE_NO_EMPTY_ELEMENT_TAG;
  2986   3611               objc -= 1;
  2987   3612               objv += 1;
  2988   3613               break;
  2989   3614           }
  2990   3615       }
  2991   3616       if (indent > 8)  indent = 8;
  2992   3617       if (indent < -1) indent = -1;
................................................................................
  3011   3636                   node->ownerDocument->doctype->cdataSectionElements,
  3012   3637                   node->nodeName);
  3013   3638           }
  3014   3639           if (h) {
  3015   3640               cdataChild = 1;
  3016   3641           }
  3017   3642       }
  3018         -    tcldom_treeAsXML(resultPtr, node, indent, 0, 1, chan, escapeNonASCII,
  3019         -                     doctypeDeclaration, cdataChild, escapeAllQuot);
         3643  +    tcldom_treeAsXML(resultPtr, node, indent, 0, 1, chan, encString,
         3644  +                     cdataChild, outputFlags, indentAttrs);
  3020   3645       Tcl_SetObjResult(interp, resultPtr);
         3646  +    if (encString) {
         3647  +        Tcl_DecrRefCount(encString);
         3648  +    }
  3021   3649       return TCL_OK;
         3650  +cleanup:
         3651  +    if (encString) {
         3652  +        Tcl_DecrRefCount(encString);
         3653  +    }
         3654  +    return TCL_ERROR;
  3022   3655   }
  3023   3656   
  3024   3657   /*----------------------------------------------------------------------------
  3025   3658   |   serializeAsHTML
  3026   3659   |
  3027   3660   \---------------------------------------------------------------------------*/
  3028   3661   static int serializeAsHTML (
  3029   3662       domNode    *node,
  3030   3663       Tcl_Interp *interp,
  3031   3664       int         objc,
  3032         -    Tcl_Obj    *CONST objv[]
         3665  +    Tcl_Obj    *const objv[]
  3033   3666   )
  3034   3667   {
  3035   3668       char       *channelId;
  3036   3669       int         optionIndex, mode, escapeNonASCII = 0, htmlEntities = 0;
  3037   3670       int         doctypeDeclaration = 0;
  3038   3671       Tcl_Obj    *resultPtr;
  3039   3672       Tcl_Channel chan = (Tcl_Channel) NULL;
  3040   3673   
  3041         -    static CONST84 char *asHTMLOptions[] = {
         3674  +    static const char *asHTMLOptions[] = {
  3042   3675           "-channel", "-escapeNonASCII", "-htmlEntities", "-doctypeDeclaration",
  3043   3676           NULL
  3044   3677       };
  3045   3678       enum asHTMLOption {
  3046   3679           m_channel, m_escapeNonASCII, m_htmlEntities, m_doctypeDeclaration
  3047   3680       };
  3048   3681       
................................................................................
  3114   3747       resultPtr = Tcl_NewStringObj("", 0);
  3115   3748       tcldom_treeAsHTML(resultPtr, node, chan, escapeNonASCII, htmlEntities,
  3116   3749                         doctypeDeclaration, 0);
  3117   3750       Tcl_AppendResult(interp, Tcl_GetString(resultPtr), NULL);
  3118   3751       Tcl_DecrRefCount(resultPtr);
  3119   3752       return TCL_OK;
  3120   3753   }
         3754  +
         3755  +/*----------------------------------------------------------------------------
         3756  +|   serializeAsJSON
         3757  +|
         3758  +\---------------------------------------------------------------------------*/
         3759  +static int serializeAsJSON (
         3760  +    domNode    *node,
         3761  +    Tcl_Interp *interp,
         3762  +    int         objc,
         3763  +    Tcl_Obj    *const objv[]
         3764  +)
         3765  +{
         3766  +    char       *channelId;
         3767  +    int         optionIndex, mode, indent = -1;
         3768  +    Tcl_Obj    *resultPtr;
         3769  +    Tcl_Channel chan = (Tcl_Channel) NULL;
         3770  +
         3771  +    static const char *asJSONOptions[] = {
         3772  +        "-channel", "-indent",
         3773  +        NULL
         3774  +    };
         3775  +    enum asJSONOption {
         3776  +        m_channel, m_indent
         3777  +    };
         3778  +
         3779  +    if (node->nodeType != ELEMENT_NODE) {
         3780  +        SetResult("Not an element node.\n");
         3781  +        return TCL_ERROR;
         3782  +    }
         3783  +    
         3784  +    if (objc > 5) {
         3785  +        Tcl_WrongNumArgs(interp, 2, objv,
         3786  +                         "?-channel <channelId>? "
         3787  +                         "?-indent <none,0..8>?");
         3788  +        return TCL_ERROR;
         3789  +    }
         3790  +    while (objc > 2) {
         3791  +        if (Tcl_GetIndexFromObj(interp, objv[2], asJSONOptions, "option", 
         3792  +                                0, &optionIndex) != TCL_OK) {
         3793  +            return TCL_ERROR;
         3794  +        }
         3795  +        switch ((enum asJSONOption) optionIndex) {
         3796  +
         3797  +        case m_channel:
         3798  +            if (objc < 4) {
         3799  +                SetResult("-channel must have a channeldID as argument");
         3800  +                return TCL_ERROR;
         3801  +            }
         3802  +            channelId = Tcl_GetString(objv[3]);
         3803  +            chan = Tcl_GetChannel(interp, channelId, &mode);
         3804  +            if (chan == (Tcl_Channel) NULL) {
         3805  +                SetResult("-channel must have a channeldID as argument");
         3806  +                return TCL_ERROR;
         3807  +            }
         3808  +            if ((mode & TCL_WRITABLE) == 0) {
         3809  +                Tcl_AppendResult(interp, "channel \"", channelId,
         3810  +                                "\" wasn't opened for writing", (char*)NULL);
         3811  +                return TCL_ERROR;
         3812  +            }
         3813  +            objc -= 2;
         3814  +            objv += 2;
         3815  +            break;
         3816  +
         3817  +        case m_indent:
         3818  +            if (objc < 4) {
         3819  +                SetResult("-indent must have an argument "
         3820  +                          "(0..8 or 'no'/'none')");
         3821  +                return TCL_ERROR;
         3822  +            }
         3823  +            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
         3824  +                indent = -1;
         3825  +            }
         3826  +            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
         3827  +                indent = -1;
         3828  +            }
         3829  +            else if (Tcl_GetIntFromObj(interp, objv[3], &indent) != TCL_OK) {
         3830  +                SetResult( "indent must be an integer (0..8) or 'no'/'none'");
         3831  +                return TCL_ERROR;
         3832  +            } else if (indent < 0 || indent > 8) {
         3833  +                SetResult( "indent must be an integer (0..8) or 'no'/'none'");
         3834  +                return TCL_ERROR;
         3835  +            }
         3836  +                
         3837  +            objc -= 2;
         3838  +            objv += 2;
         3839  +            break;
         3840  +        }
         3841  +    }
         3842  +    resultPtr = Tcl_NewStringObj("", 0);
         3843  +    tcldom_treeAsJSON(resultPtr, node, chan, indent, 0, JSON_START);
         3844  +    Tcl_AppendResult(interp, Tcl_GetString(resultPtr), NULL);
         3845  +    Tcl_DecrRefCount(resultPtr);
         3846  +    return TCL_OK;
         3847  +}
  3121   3848   
  3122   3849   /*----------------------------------------------------------------------------
  3123   3850   |   cdataSectionElements
  3124   3851   |
  3125   3852   \---------------------------------------------------------------------------*/
  3126   3853   static int cdataSectionElements (
  3127   3854       domDocument *doc,
  3128   3855       Tcl_Interp  *interp,
  3129   3856       int          objc,
  3130         -    Tcl_Obj     *CONST objv[] 
         3857  +    Tcl_Obj     *const objv[] 
  3131   3858       )
  3132   3859   {
  3133   3860       int result, hnew;
  3134   3861       Tcl_Obj *resultPtr,*namePtr;
  3135   3862       Tcl_HashEntry *h;
  3136   3863       Tcl_HashSearch search;
  3137   3864       
................................................................................
  3213   3940   |   selectNodesNamespaces
  3214   3941   |
  3215   3942   \---------------------------------------------------------------------------*/
  3216   3943   static int selectNodesNamespaces (
  3217   3944       domDocument *doc,
  3218   3945       Tcl_Interp  *interp,
  3219   3946       int          objc,
  3220         -    Tcl_Obj     *CONST objv[] 
         3947  +    Tcl_Obj     *const objv[] 
  3221   3948       )
  3222   3949   {
  3223   3950       int      len, i, result;
  3224   3951       Tcl_Obj *objPtr, *listPtr;
  3225   3952   
  3226   3953       CheckArgs (2,3,2, "?prefixUriList?");
  3227   3954       if (objc == 3) {
................................................................................
  3267   3994   |   renameNodes
  3268   3995   |
  3269   3996   \---------------------------------------------------------------------------*/
  3270   3997   static int renameNodes (
  3271   3998       domDocument *doc,
  3272   3999       Tcl_Interp  *interp,
  3273   4000       int          objc,
  3274         -    Tcl_Obj     *CONST objv[] 
         4001  +    Tcl_Obj     *const objv[] 
  3275   4002       )
  3276   4003   {
  3277   4004       int      len, i, hnew;
  3278         -    char    *errMsg;
  3279   4005       Tcl_HashEntry *h;
  3280   4006       Tcl_Obj *objPtr;
  3281   4007       domNode     *node;
  3282   4008       
  3283   4009       CheckArgs (4,4,0, "<domDoc> renameNode nodeList name");
  3284   4010       if (Tcl_ListObjLength (interp, objv[2], &len) != TCL_OK) {
  3285   4011           SetResult ("The first argument to the renameNode method"
................................................................................
  3286   4012                      " must be a list of element nodes.");
  3287   4013           return TCL_ERROR;
  3288   4014       }
  3289   4015       h = Tcl_CreateHashEntry(&HASHTAB(doc,tdom_tagNames), 
  3290   4016                               Tcl_GetString(objv[3]), &hnew);
  3291   4017       for (i = 0; i < len; i++) {
  3292   4018           Tcl_ListObjIndex (interp, objv[2], i, &objPtr);
  3293         -        node = tcldom_getNodeFromName (interp, Tcl_GetString (objPtr),
  3294         -                                       &errMsg);
         4019  +        node = tcldom_getNodeFromObj (interp, objPtr);
  3295   4020           if (node == NULL) {
  3296         -            SetResult (errMsg);
  3297         -            if (errMsg) FREE (errMsg);
  3298   4021               return TCL_ERROR;
  3299   4022           }
  3300   4023           node->nodeName = (char *)&(h->key);
  3301   4024       }
  3302   4025       return TCL_OK;
  3303   4026   }
  3304   4027   
................................................................................
  3306   4029   |   deleteXPathCache
  3307   4030   |
  3308   4031   \---------------------------------------------------------------------------*/
  3309   4032   static int deleteXPathCache (
  3310   4033       domDocument *doc,
  3311   4034       Tcl_Interp  *interp,
  3312   4035       int          objc,
  3313         -    Tcl_Obj     *CONST objv[] 
         4036  +    Tcl_Obj     *const objv[] 
  3314   4037       )
  3315   4038   {
  3316   4039       Tcl_HashEntry *h;
  3317   4040       Tcl_HashSearch search;
  3318   4041       
  3319   4042       CheckArgs (2,3,0, "<domDoc> deleteXPathCache ?xpathQuery?");
  3320   4043       if (objc == 3) {
................................................................................
  3348   4071   |
  3349   4072   \---------------------------------------------------------------------------*/
  3350   4073   static int applyXSLT (
  3351   4074       domNode     *node,
  3352   4075       Tcl_Interp  *interp,
  3353   4076       void        *clientData,
  3354   4077       int          objc,
  3355         -    Tcl_Obj     *CONST objv[]
         4078  +    Tcl_Obj     *const objv[]
  3356   4079       )
  3357   4080   {
  3358   4081       char          *usage, **parameters = NULL, *errMsg, *option;
  3359   4082       Tcl_Obj       *objPtr, *localListPtr = (Tcl_Obj *)NULL;
  3360   4083       int            i, result, length, optionIndex;
  3361   4084       int            ignoreUndeclaredParameters = 0;
  3362         -    domDocument   *xsltDoc, *xmlDoc, *resultDoc;
         4085  +    int            maxApplyDepth = MAX_XSLT_APPLY_DEPTH;
         4086  +    domDocument   *xsltDoc, *xmlDoc, *resultDoc = NULL;
  3363   4087       XsltMsgCBInfo  xsltMsgInfo;
  3364   4088   
  3365   4089       static char *method_usage = 
  3366   4090           "wrong # args: should be \"nodeObj xslt ?-parameters parameterList? "
  3367         -        "?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? xsltDocNode "
  3368         -        "?varname?\"";
         4091  +        "?-ignoreUndeclaredParameters? ?-maxApplyDepth int? "
         4092  +        "?-xsltmessagecmd cmd? xsltDocNode ?varname?\"";
  3369   4093   
  3370   4094       static char *cmd_usage = 
  3371   4095           "wrong # args: should be \"?-parameters parameterList? "
  3372         -        "?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? <xmlDocObj> "
  3373         -        "?objVar?\"";
         4096  +        "?-ignoreUndeclaredParameters? ?-maxApplyDepth int? "
         4097  +        "?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?\"";
  3374   4098   
  3375         -    static CONST84 char *xsltOptions[] = {
  3376         -        "-parameters", "-ignoreUndeclaredParameters", "-xsltmessagecmd", NULL
         4099  +    static const char *xsltOptions[] = {
         4100  +        "-parameters", "-ignoreUndeclaredParameters",
         4101  +        "-maxApplyDepth", "-xsltmessagecmd", NULL
  3377   4102       };
  3378   4103   
  3379   4104       enum xsltOption {
  3380         -        m_parmeters, m_ignoreUndeclaredParameters, m_xsltmessagecmd
         4105  +        m_parameters, m_ignoreUndeclaredParameters, m_maxApplyDepth,
         4106  +        m_xsltmessagecmd
  3381   4107       };
  3382   4108   
  3383   4109       xsltMsgInfo.interp = interp;
  3384   4110       xsltMsgInfo.msgcmd = NULL;
  3385   4111   
  3386   4112       if (node)  usage = method_usage;
  3387   4113       else       usage = cmd_usage;
................................................................................
  3394   4120           if (Tcl_GetIndexFromObj(interp, objv[0], xsltOptions, "option", 0,
  3395   4121                                    &optionIndex) != TCL_OK) {
  3396   4122               goto applyXSLTCleanUP;
  3397   4123           }
  3398   4124       
  3399   4125           switch ((enum xsltOption) optionIndex) {
  3400   4126   
  3401         -        case m_parmeters:
         4127  +        case m_parameters:
  3402   4128               if (objc < 3) {SetResult(usage); goto applyXSLTCleanUP;}
  3403   4129               if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK) {
  3404   4130                   SetResult("ill-formed parameters list: the -parameters "
  3405   4131                             "option needs a list of parameter name and "
  3406   4132                             "parameter value pairs");
  3407   4133                   goto applyXSLTCleanUP;
  3408   4134               }
................................................................................
  3420   4146               Tcl_IncrRefCount(localListPtr);
  3421   4147               parameters =  (char **)MALLOC(sizeof(char *)*(length+1));
  3422   4148               for (i = 0; i < length; i ++) {
  3423   4149                   Tcl_ListObjIndex(interp, localListPtr, i, &objPtr);
  3424   4150                   parameters[i] = Tcl_GetString(objPtr);
  3425   4151               }
  3426   4152               parameters[length] = NULL;
         4153  +            objc -= 2;
         4154  +            objv += 2;
         4155  +            break;
         4156  +
         4157  +        case m_maxApplyDepth:
         4158  +            if (objc < 3) {SetResult(usage); goto applyXSLTCleanUP;}
         4159  +            if (Tcl_GetIntFromObj(interp, objv[1], &maxApplyDepth)
         4160  +                != TCL_OK) {
         4161  +                SetResult("-maxApplyDepth requires a positive integer "
         4162  +                          "as argument");
         4163  +                goto applyXSLTCleanUP;
         4164  +            }
         4165  +            if (maxApplyDepth < 1) {
         4166  +                SetResult("-maxApplyDepth requires a positive integer "
         4167  +                          "as argument");
         4168  +                goto applyXSLTCleanUP;
         4169  +            }
  3427   4170               objc -= 2;
  3428   4171               objv += 2;
  3429   4172               break;
  3430   4173           
  3431   4174           case m_ignoreUndeclaredParameters:
  3432   4175               if (objc < 2) {SetResult(usage); goto applyXSLTCleanUP;}
  3433   4176               ignoreUndeclaredParameters = 1;
................................................................................
  3461   4204               SetResult( errMsg );
  3462   4205               goto applyXSLTCleanUP;
  3463   4206           }
  3464   4207           node = (domNode *) xmlDoc;
  3465   4208           xsltDoc = NULL;
  3466   4209       }
  3467   4210       result = xsltProcess(xsltDoc, node, clientData, parameters, 
  3468         -                          ignoreUndeclaredParameters,
  3469         -                          tcldom_xpathFuncCallBack,  interp,
  3470         -                          tcldom_xsltMsgCB, &xsltMsgInfo,
  3471         -                          &errMsg, &resultDoc);
         4211  +                         ignoreUndeclaredParameters,
         4212  +                         maxApplyDepth,
         4213  +                         tcldom_xpathFuncCallBack,  interp,
         4214  +                         tcldom_xsltMsgCB, &xsltMsgInfo,
         4215  +                         &errMsg, &resultDoc);
  3472   4216   
  3473   4217       if (result < 0) {
  3474   4218           SetResult( errMsg );
  3475   4219           FREE(errMsg);
         4220  +        if (objc == 2) {
         4221  +            Tcl_SetVar (interp, Tcl_GetString(objv[1]), "", 0);
         4222  +        }
  3476   4223           goto applyXSLTCleanUP;
  3477   4224       }
  3478   4225       if (parameters) {
  3479   4226           Tcl_DecrRefCount(localListPtr);
  3480   4227           FREE((char *) parameters);
  3481   4228       }
  3482   4229       if (xsltMsgInfo.msgcmd) {
  3483   4230           Tcl_DecrRefCount(xsltMsgInfo.msgcmd);
  3484   4231       }
  3485   4232       return tcldom_returnDocumentObj(interp, resultDoc, (objc == 2),
  3486         -                                     (objc == 2) ? objv[1] : NULL, 1, 0);
         4233  +                                    (objc == 2) ? objv[1] : NULL, 1, 0);
  3487   4234               
  3488   4235    applyXSLTCleanUP:
  3489   4236       if (localListPtr) {
  3490   4237           Tcl_DecrRefCount(localListPtr);
  3491   4238           FREE((char *) parameters);
  3492   4239       }
  3493   4240       if (xsltMsgInfo.msgcmd) {
................................................................................
  3500   4247   |   tcldom_XSLTObjCmd
  3501   4248   |
  3502   4249   \---------------------------------------------------------------------------*/
  3503   4250   static int tcldom_XSLTObjCmd (
  3504   4251       ClientData  clientData,
  3505   4252       Tcl_Interp *interp,
  3506   4253       int         objc,
  3507         -    Tcl_Obj    *CONST objv[]
         4254  +    Tcl_Obj    *const objv[]
  3508   4255   )
  3509   4256   {
  3510   4257       int          index;
  3511   4258       char        *errMsg = NULL;
  3512   4259       
  3513         -    static CONST84 char *options[] = {
         4260  +    static const char *options[] = {
  3514   4261           "transform", "delete", NULL
  3515   4262       };
  3516   4263       enum option {
  3517   4264           m_transform, m_delete
  3518   4265       };
  3519   4266       
  3520   4267   
................................................................................
  3602   4349   |   tcldom_NodeObjCmd
  3603   4350   |
  3604   4351   \---------------------------------------------------------------------------*/
  3605   4352   int tcldom_NodeObjCmd (
  3606   4353       ClientData  clientData,
  3607   4354       Tcl_Interp *interp,
  3608   4355       int         objc,
  3609         -    Tcl_Obj    *CONST objv[]
         4356  +    Tcl_Obj    *const objv[]
  3610   4357   )
  3611   4358   {
  3612   4359       GetTcldomTSD()
  3613   4360   
  3614   4361       domNode     *node, *child, *refChild, *oldChild, *refNode;
  3615   4362       domNS       *ns;
  3616   4363       domAttrNode *attrs;
  3617   4364       domException exception;
  3618         -    char         tmp[200], objCmdName[80], prefix[MAX_PREFIX_LEN],
  3619         -                *method, *nodeName, *str, *attr_name, *attr_val, *filter,
  3620         -                *errMsg;
         4365  +    char         tmp[200], prefix[MAX_PREFIX_LEN], *method, *nodeName,
         4366  +                 *str, *attr_name, *attr_val, *filter;
  3621   4367       const char  *localName, *uri, *nsStr;
  3622   4368       int          result, length, methodIndex, i, line, column;
  3623         -    int          nsIndex, bool, hnew;
         4369  +    int          nsIndex, bool, hnew, legacy, jsonType, fromToken = 0;
  3624   4370       Tcl_Obj     *namePtr, *resultPtr;
  3625   4371       Tcl_Obj     *mobjv[MAX_REWRITE_ARGS];
  3626   4372       Tcl_CmdInfo  cmdInfo;
  3627   4373       Tcl_HashEntry *h;
  3628   4374   
  3629         -    static CONST84 char *nodeMethods[] = {
         4375  +    static const char *nodeMethods[] = {
  3630   4376           "firstChild",      "nextSibling",    "getAttribute",    "nodeName",
  3631   4377           "nodeValue",       "nodeType",       "attributes",      "asList",
  3632   4378           "find",            "setAttribute",   "removeAttribute", "parentNode",
  3633   4379           "previousSibling", "lastChild",      "appendChild",     "removeChild",
  3634   4380           "hasChildNodes",   "localName",      "childNodes",      "ownerDocument",
  3635   4381           "insertBefore",    "replaceChild",   "getLine",         "getColumn",
  3636   4382           "asXML",           "appendFromList", "child",           "fsibling",
................................................................................
  3639   4385           "target",          "data",           "selectNodes",     "namespaceURI",
  3640   4386           "getAttributeNS",  "setAttributeNS", "hasAttributeNS",  "removeAttributeNS",
  3641   4387           "asHTML",          "prefix",         "getBaseURI",      "appendFromScript",
  3642   4388           "xslt",            "toXPath",        "delete",          "getElementById",
  3643   4389           "getElementsByTagName",              "getElementsByTagNameNS",
  3644   4390           "disableOutputEscaping",             "precedes",         "asText",
  3645   4391           "insertBeforeFromScript",            "normalize",        "baseURI",
         4392  +        "asJSON",          "jsonType",       "attributeNames",
  3646   4393   #ifdef TCL_THREADS
  3647   4394           "readlock",        "writelock",
  3648   4395   #endif
  3649   4396           NULL
  3650   4397       };
  3651   4398       enum nodeMethod {
  3652   4399           m_firstChild,      m_nextSibling,    m_getAttribute,    m_nodeName,
................................................................................
  3660   4407           m_root,            m_hasAttribute,   m_cloneNode,       m_appendXML,
  3661   4408           m_target,          m_data,           m_selectNodes,     m_namespaceURI,
  3662   4409           m_getAttributeNS,  m_setAttributeNS, m_hasAttributeNS,  m_removeAttributeNS,
  3663   4410           m_asHTML,          m_prefix,         m_getBaseURI,      m_appendFromScript,
  3664   4411           m_xslt,            m_toXPath,        m_delete,          m_getElementById,
  3665   4412           m_getElementsByTagName,              m_getElementsByTagNameNS,
  3666   4413           m_disableOutputEscaping,             m_precedes,        m_asText,
  3667         -        m_insertBeforeFromScript,            m_normalize,       m_baseURI
         4414  +        m_insertBeforeFromScript,            m_normalize,       m_baseURI,
         4415  +        m_asJSON,          m_jsonType,       m_attributeNames
  3668   4416   #ifdef TCL_THREADS
  3669         -        ,m_readlock,        m_writelock
         4417  +        ,m_readlock,       m_writelock
  3670   4418   #endif
  3671   4419       };
  3672         -
  3673   4420   
  3674   4421       node = (domNode*) clientData;
  3675   4422       if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
  3676   4423           TSD(dontCreateObjCommands) = 0;
  3677   4424       }
  3678   4425       if (node == NULL) {
  3679   4426           if (objc < 3) {
  3680   4427               SetResult(node_usage);
  3681   4428               return TCL_ERROR;
  3682   4429           }
  3683   4430           if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
  3684   4431               TSD(dontCreateObjCommands) = 1;
  3685   4432           }
  3686         -        nodeName = Tcl_GetString(objv[1]);
  3687         -        node = tcldom_getNodeFromName(interp, nodeName, &errMsg);
         4433  +        node = tcldom_getNodeFromObj(interp, objv[1]);
  3688   4434           if (node == NULL) {
  3689         -            SetResult(errMsg);
  3690   4435               return TCL_ERROR;
  3691   4436           }
         4437  +        fromToken = 1;
  3692   4438           objc--;
  3693   4439           objv++;
  3694   4440       }
  3695   4441       if (objc < 2) {
  3696   4442           SetResult(node_usage);
  3697   4443           return TCL_ERROR;
  3698   4444       }
................................................................................
  3789   4535       /*----------------------------------------------------------------------
  3790   4536       |   dispatch the node object method
  3791   4537       |
  3792   4538       \---------------------------------------------------------------------*/
  3793   4539       switch ((enum nodeMethod)methodIndex) {
  3794   4540   
  3795   4541           case m_toXPath:
  3796         -            CheckArgs(2,2,2,"");
  3797         -            str = xpathNodeToXPath(node);
         4542  +            CheckArgs(2,3,2,"?-legacy?");
         4543  +            legacy = 0;
         4544  +            if (objc == 3) {
         4545  +                if (!strcmp(Tcl_GetString(objv[2]), "-legacy")) {
         4546  +                    legacy = 1;
         4547  +                } else {
         4548  +                    SetResult("unknown option! Options: ?-legacy?");
         4549  +                    return TCL_ERROR;
         4550  +                }
         4551  +            }
         4552  +            str = xpathNodeToXPath(node, legacy);
  3798   4553               SetResult (str);
  3799   4554               FREE (str);
  3800   4555               return TCL_OK;
  3801   4556   
  3802   4557           case m_xslt:
  3803   4558               CheckArgs(3,9,2, "?-parameters parameterList? "
  3804   4559                         "?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? "
................................................................................
  3809   4564           case m_selectNodes:
  3810   4565               return tcldom_selectNodes (interp, node, --objc, ++objv);
  3811   4566   
  3812   4567           case m_find:
  3813   4568               CheckArgs(4,5,2,"attrName attrVal ?nodeObjVar?");
  3814   4569               attr_name = Tcl_GetStringFromObj(objv[2], NULL);
  3815   4570               attr_val  = Tcl_GetStringFromObj(objv[3], &length);
  3816         -            return tcldom_returnNodeObj
         4571  +            return tcldom_setInterpAndReturnVar
  3817   4572                   (interp, tcldom_find(node, attr_name, attr_val, length),
  3818   4573                    (objc == 5), (objc == 5) ? objv[4] : NULL);
  3819   4574   
  3820   4575           case m_child:
  3821   4576               CheckArgs(3,6,2,"instance|all ?type? ?attr value?");
  3822   4577               return tcldom_xpointerSearch(interp, XP_CHILD, node, objc, objv);
  3823   4578   
................................................................................
  3838   4593               return tcldom_xpointerSearch(interp, XP_PSIBLING, node,objc,objv);
  3839   4594   
  3840   4595           case m_root:
  3841   4596               CheckArgs(2,3,2,"?nodeObjVar?");
  3842   4597               while (node->parentNode) {
  3843   4598                   node = node->parentNode;
  3844   4599               }
  3845         -            return tcldom_returnNodeObj(interp, node, (objc == 3),
         4600  +            return tcldom_setInterpAndReturnVar(interp, node, (objc == 3),
  3846   4601                                           (objc == 3) ? objv[2] : NULL);
  3847   4602   
  3848   4603           case m_text:
  3849   4604               CheckArgs(2,2,2,"");
  3850   4605               if (node->nodeType != ELEMENT_NODE) {
  3851   4606                   SetResult("NOT_AN_ELEMENT");
  3852   4607                   return TCL_ERROR;
................................................................................
  3866   4621   
  3867   4622           case m_attributes:
  3868   4623               CheckArgs(2,3,2,"?nameFilter?");
  3869   4624               if (node->nodeType != ELEMENT_NODE) {
  3870   4625                   SetResult("");
  3871   4626                   return TCL_OK;
  3872   4627               }
         4628  +            filter = NULL;
  3873   4629               if (objc == 3) {
  3874   4630                   filter = Tcl_GetString(objv[2]);
  3875         -            } else {
  3876         -                filter = "*";
  3877   4631               }
  3878   4632               Tcl_ResetResult(interp);
  3879   4633               resultPtr = Tcl_GetObjResult(interp);
  3880   4634   
  3881   4635               attrs = node->firstAttr;
  3882   4636               while (attrs != NULL) {
  3883         -                if (Tcl_StringMatch((char*)attrs->nodeName, filter)) {
  3884         -
         4637  +                if (!filter || Tcl_StringMatch((char*)attrs->nodeName, filter)) {
  3885   4638                       if (attrs->namespace == 0) {
  3886   4639                           namePtr = Tcl_NewStringObj((char*)attrs->nodeName, -1);
  3887   4640                       } else {
  3888   4641                           domSplitQName((char*)attrs->nodeName, prefix, 
  3889   4642                                         &localName);
  3890   4643                           mobjv[0] = Tcl_NewStringObj((char*)localName, -1);
  3891   4644                           mobjv[1] = Tcl_NewStringObj(
................................................................................
  3898   4651                       }
  3899   4652                       result = Tcl_ListObjAppendElement(interp, resultPtr, 
  3900   4653                                                         namePtr);
  3901   4654                       if (result != TCL_OK) {
  3902   4655                           Tcl_DecrRefCount(namePtr);
  3903   4656                           return result;
  3904   4657                       }
         4658  +                }
         4659  +                attrs = attrs->nextSibling;
         4660  +            }
         4661  +            break;
         4662  +
         4663  +        case m_attributeNames:
         4664  +            CheckArgs(2,3,2,"?nameFilter?");
         4665  +            if (node->nodeType != ELEMENT_NODE) {
         4666  +                SetResult("");
         4667  +                return TCL_OK;
         4668  +            }
         4669  +            filter = NULL;
         4670  +            if (objc == 3) {
         4671  +                filter = Tcl_GetString(objv[2]);
         4672  +            }
         4673  +            resultPtr = Tcl_GetObjResult(interp);
         4674  +
         4675  +            attrs = node->firstAttr;
         4676  +            while (attrs != NULL) {
         4677  +                if (!filter || Tcl_StringMatch((char*)attrs->nodeName, filter)) {
         4678  +                    namePtr = Tcl_NewStringObj((char*)attrs->nodeName, -1);
         4679  +                    result = Tcl_ListObjAppendElement(interp, resultPtr, 
         4680  +                                                      namePtr);
         4681  +                    if (result != TCL_OK) {
         4682  +                        Tcl_DecrRefCount(namePtr);
         4683  +                        return result;
         4684  +                    }
  3905   4685                   }
  3906   4686                   attrs = attrs->nextSibling;
  3907   4687               }
  3908   4688               break;
  3909   4689   
  3910   4690           case m_asList:
  3911   4691               CheckArgs(2,2,2,"");
................................................................................
  3922   4702           case m_asHTML:
  3923   4703               Tcl_ResetResult(interp);
  3924   4704               if (serializeAsHTML(node, interp, objc, objv) != TCL_OK) {
  3925   4705                   return TCL_ERROR;
  3926   4706               }
  3927   4707               break;
  3928   4708   
         4709  +        case m_asJSON:
         4710  +            if (serializeAsJSON(node, interp, objc, objv) != TCL_OK) {
         4711  +                return TCL_ERROR;
         4712  +            }
         4713  +            break;
         4714  +            
  3929   4715           case m_getAttribute:
  3930   4716               CheckArgs(3,4,2,"attrName ?defaultValue?");
  3931   4717               if (node->nodeType != ELEMENT_NODE) {
  3932   4718                   SetResult("NOT_AN_ELEMENT : there are no attributes");
  3933   4719                   return TCL_ERROR;
  3934   4720               }
  3935   4721               attr_name = Tcl_GetString(objv[2]);
................................................................................
  3981   4767               for ( i = 2;  i < objc; ) {
  3982   4768                   attr_name = Tcl_GetString(objv[i++]);
  3983   4769                   CheckName (interp, attr_name, "attribute", 0);
  3984   4770                   attr_val  = Tcl_GetString(objv[i++]);
  3985   4771                   CheckText (interp, attr_val, "attribute");
  3986   4772                   domSetAttribute(node, attr_name, attr_val);
  3987   4773               }
  3988         -            return tcldom_returnNodeObj(interp, node, 0, NULL);
         4774  +            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
  3989   4775   
  3990   4776           case m_setAttributeNS:
  3991   4777               if (node->nodeType != ELEMENT_NODE) {
  3992   4778                   SetResult("NOT_AN_ELEMENT : there are no attributes");
  3993   4779                   return TCL_ERROR;
  3994   4780               }
  3995   4781               if ((objc < 5) || (((objc - 2) % 3) != 0)) {
................................................................................
  4011   4797                           SetResult("For all prefixed attributes with prefixes "
  4012   4798                                     "other than 'xml' or 'xmlns' "
  4013   4799                                     "you have to provide a namespace URI");
  4014   4800                       }
  4015   4801                       return TCL_ERROR;
  4016   4802                   }
  4017   4803               }
  4018         -            return tcldom_returnNodeObj(interp, node, 0, NULL);
         4804  +            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
  4019   4805   
  4020   4806           case m_hasAttribute:
  4021   4807               CheckArgs(3,3,2,"attrName");
  4022   4808               if (node->nodeType != ELEMENT_NODE) {		
  4023   4809                   SetResult("NOT_AN_ELEMENT : there are no attributes");
  4024   4810                   return TCL_ERROR;
  4025   4811               }
................................................................................
  4069   4855               result = domRemoveAttribute(node, attr_name);
  4070   4856               if (result) {
  4071   4857                   SetResult("can't remove attribute '");
  4072   4858                   AppendResult(attr_name);
  4073   4859                   AppendResult("'");
  4074   4860                   return TCL_ERROR;
  4075   4861               }
  4076         -            return tcldom_returnNodeObj(interp, node, 0, NULL);
         4862  +            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
  4077   4863   
  4078   4864           case m_removeAttributeNS:
  4079   4865               CheckArgs(4,4,2,"uri attrName");
  4080   4866               if (node->nodeType != ELEMENT_NODE) {		
  4081   4867                   SetResult("NOT_AN_ELEMENT : there are no attributes");
  4082   4868                   return TCL_ERROR;
  4083   4869               }
................................................................................
  4086   4872               result = domRemoveAttributeNS(node, uri, localName);
  4087   4873               if (result < 0) {
  4088   4874                   SetResult("can't remove attribute with localName '");
  4089   4875                   AppendResult(localName);
  4090   4876                   AppendResult("'");
  4091   4877                   return TCL_ERROR;
  4092   4878               }
  4093         -            return tcldom_returnNodeObj(interp, node, 0, NULL);
         4879  +            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
  4094   4880   
  4095   4881           case m_nextSibling:
  4096   4882               CheckArgs(2,3,2,"?nodeObjVar?");
  4097         -            return tcldom_returnNodeObj(interp, node->nextSibling,
         4883  +            return tcldom_setInterpAndReturnVar(interp, node->nextSibling,
  4098   4884                                           (objc == 3), 
  4099   4885                                           (objc == 3) ? objv[2] : NULL);
  4100   4886           case m_previousSibling:
  4101   4887               CheckArgs(2,3,2,"?nodeObjVar?");
  4102         -            return tcldom_returnNodeObj(interp, node->previousSibling,
         4888  +            return tcldom_setInterpAndReturnVar(interp, node->previousSibling,
  4103   4889                                           (objc == 3),
  4104   4890                                           (objc == 3) ? objv[2] : NULL);
  4105   4891           case m_firstChild:
  4106   4892               CheckArgs(2,3,2,"?nodeObjVar?");
  4107   4893               if (node->nodeType == ELEMENT_NODE) {
  4108         -                return tcldom_returnNodeObj(interp, node->firstChild,
         4894  +                return tcldom_setInterpAndReturnVar(interp, node->firstChild,
  4109   4895                                               (objc == 3),
  4110   4896                                               (objc == 3) ? objv[2] : NULL);
  4111   4897               }
  4112         -            return tcldom_returnNodeObj(interp, NULL, (objc == 3),
         4898  +            return tcldom_setInterpAndReturnVar(interp, NULL, (objc == 3),
  4113   4899                                           (objc == 3) ? objv[2] : NULL);
  4114   4900           case m_lastChild:
  4115   4901               CheckArgs(2,3,2,"?nodeObjVar?");
  4116   4902               if (node->nodeType == ELEMENT_NODE) {
  4117         -                return tcldom_returnNodeObj(interp, node->lastChild,
         4903  +                return tcldom_setInterpAndReturnVar(interp, node->lastChild,
  4118   4904                                               (objc == 3),
  4119   4905                                               (objc == 3) ? objv[2] : NULL);
  4120   4906               }
  4121         -            return tcldom_returnNodeObj(interp, NULL, (objc == 3),
         4907  +            return tcldom_setInterpAndReturnVar(interp, NULL, (objc == 3),
  4122   4908                                           (objc == 3) ? objv[2] : NULL);
  4123   4909           case m_parentNode:
  4124   4910               CheckArgs(2,3,2,"?nodeObjVar?");
  4125         -            return tcldom_returnNodeObj(interp, node->parentNode, (objc == 3),
         4911  +            return tcldom_setInterpAndReturnVar(interp, node->parentNode, (objc == 3),
  4126   4912                                           (objc == 3) ? objv[2] : NULL);
  4127   4913           case m_appendFromList:
  4128   4914               CheckArgs(3,3,2,"list");
  4129   4915               return tcldom_appendFromTclList(interp, node, objv[2]);
  4130   4916   
  4131   4917           case m_appendFromScript:
  4132   4918               CheckArgs(3,3,2,"script");
  4133   4919               if (nodecmd_appendFromScript(interp, node, objv[2]) != TCL_OK) {
  4134   4920                   return TCL_ERROR;
  4135   4921               }
  4136         -            return tcldom_returnNodeObj(interp, node, 0, NULL);
         4922  +            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
  4137   4923   
  4138   4924           case m_insertBeforeFromScript:
  4139   4925               CheckArgs(4,4,2, "script refChild");
  4140         -            nodeName = Tcl_GetString (objv[3]);
  4141         -            if (nodeName[0] == '\0') {
  4142         -                refChild = NULL;
         4926  +            if (objv[3]->typePtr == &tdomNodeType) {
         4927  +                refChild = objv[3]->internalRep.otherValuePtr;
  4143   4928               } else {
  4144         -                refChild = tcldom_getNodeFromName (interp, nodeName, &errMsg);
  4145         -                if (refChild == NULL) {
  4146         -                    SetResult ( errMsg );
  4147         -                    return TCL_ERROR;
         4929  +                nodeName = Tcl_GetString (objv[3]);
         4930  +                if (nodeName[0] == '\0') {
         4931  +                    refChild = NULL;
         4932  +                } else {
         4933  +                    refChild = tcldom_getNodeFromObj (interp, objv[3]);
         4934  +                    if (refChild == NULL) {
         4935  +                        return TCL_ERROR;
         4936  +                    }
  4148   4937                   }
  4149   4938               }
  4150   4939               if (nodecmd_insertBeforeFromScript(interp, node, objv[2], refChild)
  4151   4940                   != TCL_OK) {
  4152   4941                   return TCL_ERROR;
  4153   4942               }
  4154         -            return tcldom_returnNodeObj (interp, node, 0, NULL);
         4943  +            return tcldom_setInterpAndReturnVar (interp, node, 0, NULL);
  4155   4944               
  4156   4945           case m_appendXML:
  4157   4946               CheckArgs(3,3,2,"xmlString");
  4158   4947               return tcldom_appendXML(interp, node, objv[2]);
  4159   4948   
  4160   4949           case m_appendChild:
  4161   4950               CheckArgs(3,3,2,"nodeToAppend");
  4162         -            nodeName = Tcl_GetString(objv[2]);
  4163         -            child = tcldom_getNodeFromName(interp, nodeName, &errMsg);
         4951  +            child = tcldom_getNodeFromObj(interp, objv[2]);
  4164   4952               if (child == NULL) {
  4165         -                SetResult(errMsg);
  4166   4953                   return TCL_ERROR;
  4167   4954               }
  4168   4955               exception = domAppendChild (node, child);
  4169   4956               if (exception != OK) {
  4170   4957                   SetResult(domException2String(exception));
  4171   4958                   return TCL_ERROR;
  4172   4959               }
  4173         -            return tcldom_returnNodeObj(interp, child, 0, NULL);
         4960  +            return tcldom_setInterpAndReturnVar(interp, child, 0, NULL);
  4174   4961   
  4175   4962           case m_cloneNode:
  4176   4963               CheckArgs(2,3,2,"?-deep?");
  4177   4964               if (objc == 3) {
  4178   4965                   if (!strcmp(Tcl_GetString(objv[2]), "-deep")) {
  4179         -                    return tcldom_returnNodeObj(interp, domCloneNode(node, 1),
         4966  +                    return tcldom_setInterpAndReturnVar(interp, domCloneNode(node, 1),
  4180   4967                                                   0, NULL);
  4181   4968                   }
  4182   4969                   SetResult("unknown option! Options: ?-deep? ");
  4183   4970                   return TCL_ERROR;
  4184   4971               }
  4185         -            return tcldom_returnNodeObj(interp, domCloneNode(node, 0), 0, NULL);
         4972  +            return tcldom_setInterpAndReturnVar(interp, domCloneNode(node, 0), 0, NULL);
  4186   4973   
  4187   4974           case m_removeChild:
  4188   4975               CheckArgs(3,3,2,"childToRemove");
  4189         -            nodeName = Tcl_GetString(objv[2]);
  4190         -            child = tcldom_getNodeFromName(interp, nodeName, &errMsg);
         4976  +            child = tcldom_getNodeFromObj(interp, objv[2]);
  4191   4977               if (child == NULL) {
  4192         -                SetResult(errMsg);
  4193   4978                   return TCL_ERROR;
  4194   4979               }
  4195   4980               exception = domRemoveChild (node, child);
  4196   4981               if (exception != OK) {
  4197   4982                   SetResult (domException2String (exception));
  4198   4983                   return TCL_ERROR;
  4199   4984               }
  4200         -            return tcldom_returnNodeObj(interp, child, 0, NULL);
         4985  +            return tcldom_setInterpAndReturnVar(interp, child, 0, NULL);
  4201   4986   
  4202   4987           case m_insertBefore:
  4203   4988               CheckArgs(4,4,2,"childToInsert refChild");
  4204         -            nodeName = Tcl_GetString(objv[2]);
  4205         -            child = tcldom_getNodeFromName(interp, nodeName, &errMsg);
         4989  +            child = tcldom_getNodeFromObj(interp, objv[2]);
  4206   4990               if (child == NULL) {
  4207         -                SetResult(errMsg);
  4208   4991                   return TCL_ERROR;
  4209   4992               }
  4210   4993   
  4211         -            nodeName = Tcl_GetString (objv[3]);
  4212         -            if (nodeName[0] == '\0') {
  4213         -                refChild = NULL;
         4994  +            if (objv[3]->typePtr == &tdomNodeType) {
         4995  +                refChild = objv[3]->internalRep.otherValuePtr;
  4214   4996               } else {
  4215         -                refChild = tcldom_getNodeFromName (interp, nodeName, &errMsg);
  4216         -                if (refChild == NULL) {
  4217         -                    SetResult ( errMsg );
  4218         -                    return TCL_ERROR;
         4997  +                nodeName = Tcl_GetString (objv[3]);
         4998  +                if (nodeName[0] == '\0') {
         4999  +                    refChild = NULL;
         5000  +                } else {
         5001  +                    refChild = tcldom_getNodeFromObj (interp, objv[3]);
         5002  +                    if (refChild == NULL) {
         5003  +                        return TCL_ERROR;
         5004  +                    }
  4219   5005                   }
  4220   5006               }
  4221   5007               exception = domInsertBefore(node, child, refChild);
  4222   5008               if (exception != OK) {
  4223   5009                   SetResult(domException2String(exception));
  4224   5010                   return TCL_ERROR;
  4225   5011               }
  4226         -            return tcldom_returnNodeObj(interp, child, 0, NULL);
         5012  +            return tcldom_setInterpAndReturnVar(interp, child, 0, NULL);
  4227   5013   
  4228   5014           case m_replaceChild:
  4229   5015               CheckArgs(4,4,2,"new old");
  4230         -            nodeName = Tcl_GetString(objv[2]);
  4231         -            child = tcldom_getNodeFromName(interp, nodeName, &errMsg);
         5016  +            child = tcldom_getNodeFromObj(interp, objv[2]);
  4232   5017               if (child == NULL) {
  4233         -                SetResult(errMsg);
  4234   5018                   return TCL_ERROR;
  4235   5019               }
  4236         -
  4237         -            nodeName = Tcl_GetString(objv[3]);
  4238         -            oldChild = tcldom_getNodeFromName(interp, nodeName, &errMsg);
         5020  +            oldChild = tcldom_getNodeFromObj(interp, objv[3]);
  4239   5021               if (oldChild == NULL) {
  4240         -                SetResult(errMsg);
  4241   5022                   return TCL_ERROR;
  4242   5023               }
  4243   5024               exception = domReplaceChild(node, child, oldChild);
  4244   5025               if (exception != OK) {
  4245   5026                   SetResult(domException2String(exception));
  4246   5027                   return TCL_ERROR;
  4247   5028               }
  4248         -            return tcldom_returnNodeObj(interp, oldChild, 0, NULL);
         5029  +            return tcldom_setInterpAndReturnVar(interp, oldChild, 0, NULL);
  4249   5030   
  4250   5031           case m_hasChildNodes:
  4251   5032               CheckArgs(2,2,2,"");
  4252   5033               if (node->nodeType == ELEMENT_NODE) {
  4253   5034                   SetIntResult(node->firstChild ? 1 : 0);
  4254   5035               } else {
  4255   5036                   SetIntResult(0);
................................................................................
  4258   5039   
  4259   5040           case m_childNodes:
  4260   5041               CheckArgs(2,2,2,"");
  4261   5042               resultPtr = Tcl_GetObjResult(interp);
  4262   5043               if (node->nodeType == ELEMENT_NODE) {
  4263   5044                   child = node->firstChild;
  4264   5045                   while (child != NULL) {
  4265         -                    tcldom_createNodeObj(interp, child, objCmdName);
  4266         -                    namePtr = Tcl_NewStringObj(objCmdName, -1);
         5046  +                    namePtr = tcldom_returnNodeObj(interp, child);
  4267   5047                       result  = Tcl_ListObjAppendElement(interp, resultPtr,
  4268   5048                                                          namePtr);
  4269   5049                       if (result != TCL_OK) {
  4270   5050                           Tcl_DecrRefCount(namePtr);
  4271   5051                           return result;
  4272   5052                       }
  4273   5053                       child = child->nextSibling;
................................................................................
  4312   5092                           }
  4313   5093                           nsIndex = node->ownerDocument->namespaces[i]->index;
  4314   5094                       }
  4315   5095                   }
  4316   5096               }
  4317   5097               if (nsIndex == -1) {
  4318   5098                   /* There isn't such a namespace declared in this document.
  4319         -                   Since getElementsByTagNameNS doesn't raise an execption
         5099  +                   Since getElementsByTagNameNS doesn't raise an exception
  4320   5100                      short cut: return empty result */
  4321   5101                   Tcl_ResetResult(interp);
  4322   5102                   return TCL_OK;
  4323   5103               }
  4324   5104               return tcldom_getElementsByTagName(interp, str, node->firstChild,
  4325   5105                                                   nsIndex, uri);
  4326   5106               
................................................................................
  4327   5107           case m_getElementById:
  4328   5108               CheckArgs(3,3,2,"id");
  4329   5109               if (node->ownerDocument->ids) {
  4330   5110                   str = Tcl_GetString(objv[2]);
  4331   5111                   h = Tcl_FindHashEntry(node->ownerDocument->ids, str);
  4332   5112                   if (h) {
  4333   5113                       domNode *node = Tcl_GetHashValue(h);
  4334         -                    return tcldom_returnNodeObj(interp, node, 0, NULL);
         5114  +                    return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
  4335   5115                   }
  4336   5116               }
  4337   5117               SetResult("");
  4338   5118               return TCL_OK;
  4339   5119   
  4340   5120           case m_nodeName:
  4341   5121               CheckArgs(2,2,2,"");
................................................................................
  4468   5248                                    dpn->targetValue, dpn->targetLength);
  4469   5249               }
  4470   5250               break;
  4471   5251   
  4472   5252           case m_delete:
  4473   5253               CheckArgs(2,2,2,"");
  4474   5254               domDeleteNode(node, tcldom_deleteNode, interp);
         5255  +            if (fromToken && (objv[0]->typePtr == &tdomNodeType)) {
         5256  +                if (objv[0]->bytes) ckfree (objv[0]->bytes);
         5257  +                objv[0]->typePtr = NULL;
         5258  +                objv[0]->bytes = ckalloc((unsigned char) 1);
         5259  +                objv[0]->bytes[0] = '\0';
         5260  +                objv[0]->length = 0;
         5261  +            }
  4475   5262               break;
  4476   5263   
  4477   5264           case m_data:
  4478   5265               CheckArgs(2,2,2,"");
  4479   5266               if (node->nodeType == PROCESSING_INSTRUCTION_NODE) {
  4480   5267                   domProcessingInstructionNode *dpn;
  4481   5268                   dpn = (domProcessingInstructionNode*)node;
................................................................................
  4560   5347                       node->nodeFlags &= (~DISABLE_OUTPUT_ESCAPING);
  4561   5348                   }
  4562   5349               }
  4563   5350               break;
  4564   5351   
  4565   5352           case m_precedes:
  4566   5353               CheckArgs(3,3,2, "node");
  4567         -            nodeName = Tcl_GetString(objv[2]);
  4568         -            refNode = tcldom_getNodeFromName(interp, nodeName, &errMsg);
         5354  +            refNode = tcldom_getNodeFromObj(interp, objv[2]);
  4569   5355               if (refNode == NULL) {
  4570         -                SetResult(errMsg);
  4571   5356                   return TCL_ERROR;
  4572   5357               }
  4573   5358               if (node->ownerDocument != refNode->ownerDocument) {
  4574   5359                   SetResult("Cannot compare the relative order of nodes "
  4575   5360                             "out of different documents.");
  4576   5361                   return TCL_ERROR;
  4577   5362               }
................................................................................
  4606   5391                       SetResult("unknown option! Options: ?-forXPath?");
  4607   5392                       return TCL_ERROR;
  4608   5393                   }
  4609   5394               }
  4610   5395               domNormalize (node, bool, tcldom_deleteNode, interp);
  4611   5396               return TCL_OK;
  4612   5397   
         5398  +        case m_jsonType:
         5399  +            CheckArgs (2,3,2, "?jsonType?");
         5400  +            if (node->nodeType != ELEMENT_NODE
         5401  +                && node->nodeType != TEXT_NODE) {
         5402  +                SetResult("Only element and text nodes may have a JSON type.");
         5403  +                return TCL_ERROR;
         5404  +            }
         5405  +            if (objc == 3) {
         5406  +                if (Tcl_GetIndexFromObj (interp, objv[2], jsonTypes,
         5407  +                                         "jsonType", 0, &jsonType)
         5408  +                    != TCL_OK) {
         5409  +                    return TCL_ERROR;
         5410  +                }
         5411  +                if (node->nodeType == ELEMENT_NODE) {
         5412  +                    if (jsonType > 2) {
         5413  +                        SetResult("For an element node the jsonType argument "
         5414  +                                  "must be one out of this list: ARRAY OBJECT NONE.");
         5415  +                        return TCL_ERROR;
         5416  +                    }
         5417  +                } else {
         5418  +                    /* Text nodes */
         5419  +                    if (jsonType < 3 && jsonType > 0) {
         5420  +                        SetResult("For a text node the jsonType argument must be "
         5421  +                                  "one out of this list: TRUE FALSE NULL NUMBER "
         5422  +                                  "STRING NONE");
         5423  +                        return TCL_ERROR;
         5424  +                    }
         5425  +                }
         5426  +                node->info = jsonType;
         5427  +                SetIntResult(jsonType);
         5428  +                return TCL_OK;
         5429  +            }
         5430  +            if (node->info < 0 || node->info > 7) {
         5431  +                SetResult(jsonTypes[0]);
         5432  +            } else {
         5433  +                SetResult(jsonTypes[node->info]);
         5434  +            }
         5435  +            return TCL_OK;
         5436  +            
  4613   5437           TDomThreaded(
  4614   5438           case m_writelock:
  4615   5439               CheckArgs(3,3,2,"script");
  4616   5440               return tcldom_EvalLocked(interp, (Tcl_Obj**)objv, 
  4617   5441                                        node->ownerDocument, LOCK_WRITE);
  4618   5442           case m_readlock:
  4619   5443               CheckArgs(3,3,2,"script");
  4620   5444               return tcldom_EvalLocked(interp, (Tcl_Obj**)objv, 
  4621   5445                                        node->ownerDocument, LOCK_READ);
  4622   5446           )
  4623   5447       }
  4624         -    return TCL_OK;
  4625         -}
         5448  +    return TCL_OK;}
         5449  +
  4626   5450   
  4627   5451   
  4628   5452   /*----------------------------------------------------------------------------
  4629   5453   |   tcldom_DocObjCmd
  4630   5454   |
  4631   5455   \---------------------------------------------------------------------------*/
  4632   5456   int tcldom_DocObjCmd (
  4633   5457       ClientData  clientData,
  4634   5458       Tcl_Interp *interp,
  4635   5459       int         objc,
  4636         -    Tcl_Obj    *CONST objv[]
         5460  +    Tcl_Obj    *const objv[]
  4637   5461   )
  4638   5462   {
  4639   5463       GetTcldomTSD()
  4640   5464   
  4641   5465       domDeleteInfo       * dinfo;
  4642   5466       domDocument         * doc;
  4643   5467       char                * method, *tag, *data, *target, *uri, tmp[100];
................................................................................
  4645   5469       int                   methodIndex, result, data_length, target_length, i;
  4646   5470       int                   nsIndex, forXPath, bool, setDocumentElement = 0;
  4647   5471       int                   restoreDomCreateCmdMode = 0;
  4648   5472       domNode             * n;
  4649   5473       Tcl_CmdInfo           cmdInfo;
  4650   5474       Tcl_Obj             * mobjv[MAX_REWRITE_ARGS];
  4651   5475   
  4652         -    static CONST84 char *docMethods[] = {
         5476  +    static const char *docMethods[] = {
  4653   5477           "documentElement", "getElementsByTagName",       "delete",
  4654   5478           "createElement",   "createCDATASection",         "createTextNode",
  4655   5479           "createComment",   "createProcessingInstruction",
  4656   5480           "createElementNS", "getDefaultOutputMethod",     "asXML",
  4657   5481           "asHTML",          "getElementsByTagNameNS",     "xslt", 
  4658   5482           "publicId",        "systemId",                   "internalSubset",
  4659   5483           "toXSLTcmd",       "asText",                     "normalize",
................................................................................
  4664   5488           "renameNode",      "deleteXPathCache", 
  4665   5489           /* The following methods will be dispatched to tcldom_NodeObjCmd */
  4666   5490           "getElementById",  "firstChild",                 "lastChild",
  4667   5491           "appendChild",     "removeChild",                "hasChildNodes",
  4668   5492           "childNodes",      "ownerDocument",              "insertBefore",
  4669   5493           "replaceChild",    "appendFromList",             "appendXML",
  4670   5494           "selectNodes",     "baseURI",                    "appendFromScript",
  4671         -        "insertBeforeFromScript",
         5495  +        "insertBeforeFromScript",                        "asJSON",
         5496  +        "jsonType",
  4672   5497   #ifdef TCL_THREADS
  4673   5498           "readlock",        "writelock",                  "renumber",
  4674   5499   #endif
  4675   5500           NULL
  4676   5501       };
  4677   5502       enum docMethod {
  4678   5503           m_documentElement,  m_getElementsByTagName,       m_delete,
................................................................................
  4689   5514           m_renameNode,       m_deleteXPathCache,
  4690   5515           /* The following methods will be dispatched to tcldom_NodeObjCmd */
  4691   5516           m_getElementById,   m_firstChild,                 m_lastChild,
  4692   5517           m_appendChild,      m_removeChild,                m_hasChildNodes,
  4693   5518           m_childNodes,       m_ownerDocument,              m_insertBefore,
  4694   5519           m_replaceChild,     m_appendFromList,             m_appendXML,
  4695   5520           m_selectNodes,      m_baseURI,                    m_appendFromScript,
  4696         -        m_insertBeforeFromScript
         5521  +        m_insertBeforeFromScript,                         m_asJSON,
         5522  +        m_jsonType
  4697   5523   #ifdef TCL_THREADS
  4698   5524          ,m_readlock,         m_writelock,                  m_renumber
  4699   5525   #endif
  4700   5526       };
  4701   5527   
  4702   5528       dinfo = (domDeleteInfo*)clientData;
  4703   5529       if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
................................................................................
  4753   5579           mobjv[1] = objv[0];
  4754   5580           for (i = 2; i < objc; i++) {
  4755   5581               mobjv[i] = objv[i];
  4756   5582           }
  4757   5583           return cmdInfo.objProc(cmdInfo.objClientData, interp, objc, mobjv);
  4758   5584       }
  4759   5585   
  4760         -    CheckArgs (2,10,1,dom_usage);
         5586  +    CheckArgs (2,10,1,doc_usage);
  4761   5587       Tcl_ResetResult (interp);
  4762   5588   
  4763   5589       /*----------------------------------------------------------------------
  4764   5590       |   dispatch the doc object method
  4765   5591       |
  4766   5592       \---------------------------------------------------------------------*/
  4767   5593   
  4768   5594       switch ((enum docMethod) methodIndex ) {
  4769   5595   
  4770   5596           case m_documentElement:
  4771   5597               CheckArgs(2,3,2,"");
  4772         -            return tcldom_returnNodeObj(interp, doc->documentElement,
         5598  +            return tcldom_setInterpAndReturnVar(interp, doc->documentElement,
  4773   5599                                           (objc == 3), 
  4774   5600                                           (objc == 3) ? objv[2] : NULL);
  4775   5601           case m_getElementsByTagName:
  4776   5602               CheckArgs(3,3,2,"elementName");
  4777   5603               return tcldom_getElementsByTagName(interp, Tcl_GetString(objv[2]),
  4778   5604                                                  doc->documentElement, -1, NULL);
  4779   5605           case m_getElementsByTagNameNS:
................................................................................
  4798   5624                           }
  4799   5625                           nsIndex = doc->namespaces[i]->index;
  4800   5626                       }
  4801   5627                   }
  4802   5628               }
  4803   5629               if (nsIndex == -1) {
  4804   5630                   /* There isn't such a namespace declared in this document.
  4805         -                   Since getElementsByTagNameNS doesn't raise an execption
         5631  +                   Since getElementsByTagNameNS doesn't raise an exception
  4806   5632                      short cut: return empty result */
  4807   5633                   return TCL_OK;
  4808   5634               }
  4809   5635               return tcldom_getElementsByTagName(interp, str,
  4810   5636                                                  doc->documentElement, nsIndex,
  4811   5637                                                  uri);
  4812   5638           case m_createElement:
  4813   5639               CheckArgs(3,4,2,"elementName ?newObjVar?");
  4814   5640               tag = Tcl_GetString(objv[2]);
  4815   5641               CheckName (interp, tag, "tag", 0);
  4816         -            n = domNewElementNode(doc, tag, ELEMENT_NODE);
  4817         -            return tcldom_returnNodeObj(interp, n, (objc == 4),
         5642  +            n = domNewElementNode(doc, tag);
         5643  +            return tcldom_setInterpAndReturnVar(interp, n, (objc == 4),
  4818   5644                                           (objc == 4) ? objv[3] : NULL);
  4819   5645   
  4820   5646           case m_createElementNS:
  4821   5647               CheckArgs(4,5,2,"elementName uri ?newObjVar?");
  4822   5648               uri = Tcl_GetString(objv[2]);
  4823   5649               tag = Tcl_GetString(objv[3]);
  4824   5650               CheckName (interp, tag, "full qualified tag", 1);
  4825         -            n = domNewElementNodeNS(doc, tag, uri, ELEMENT_NODE);
  4826         -            return tcldom_returnNodeObj(interp, n, (objc == 5),
         5651  +            n = domNewElementNodeNS(doc, tag, uri);
         5652  +            if (n == NULL) {
         5653  +                SetResult("Missing URI in Namespace declaration");
         5654  +                return TCL_ERROR;
         5655  +            }
         5656  +            return tcldom_setInterpAndReturnVar(interp, n, (objc == 5),
  4827   5657                                           (objc == 5) ? objv[4] : NULL);
  4828   5658   
  4829   5659           case m_createTextNode:
  4830   5660               CheckArgs(3,4,2,"data ?newObjVar?");
  4831   5661               data = Tcl_GetStringFromObj(objv[2], &data_length);
  4832   5662               CheckText (interp, data, "text");
  4833   5663               n = (domNode*)domNewTextNode(doc, data, data_length, TEXT_NODE);
  4834         -            return tcldom_returnNodeObj(interp, n, (objc == 4),
         5664  +            return tcldom_setInterpAndReturnVar(interp, n, (objc == 4),
  4835   5665                                           (objc == 4) ? objv[3] : NULL);
  4836   5666   
  4837   5667           case m_createCDATASection:
  4838   5668               CheckArgs(3,4,2,"data ?newObjVar?");
  4839   5669               data = Tcl_GetStringFromObj(objv[2], &data_length);
  4840   5670               CheckCDATA (interp, data);
  4841   5671               n = (domNode*)domNewTextNode(doc, data, data_length, 
  4842   5672                                            CDATA_SECTION_NODE);
  4843         -            return tcldom_returnNodeObj(interp, n, (objc == 4),
         5673  +            return tcldom_setInterpAndReturnVar(interp, n, (objc == 4),
  4844   5674                                           (objc == 4) ? objv[3] : NULL);
  4845   5675   
  4846   5676           case m_createComment:
  4847   5677               CheckArgs(3,4,2,"data ?newObjVar?");
  4848   5678               data = Tcl_GetStringFromObj(objv[2], &data_length);
  4849   5679               CheckComment(interp, data);
  4850   5680               n = (domNode*)domNewTextNode(doc, data, data_length, COMMENT_NODE);
  4851         -            return tcldom_returnNodeObj(interp, n, (objc == 4),
         5681  +            return tcldom_setInterpAndReturnVar(interp, n, (objc == 4),
  4852   5682                                           (objc == 4) ? objv[3] : NULL);
  4853   5683   
  4854   5684           case m_createProcessingInstruction:
  4855   5685               CheckArgs(4,5,2,"target data ?newObjVar?");
  4856   5686               target = Tcl_GetStringFromObj(objv[2], &target_length);
  4857   5687               CheckPIName (interp, target);
  4858   5688               data   = Tcl_GetStringFromObj(objv[3], &data_length);
  4859   5689               CheckPIValue (interp, data);
  4860   5690               n = (domNode*)domNewProcessingInstructionNode(doc, target, 
  4861   5691                                                             target_length, data, 
  4862   5692                                                             data_length);
  4863         -            return tcldom_returnNodeObj(interp, n, (objc == 5),
         5693  +            return tcldom_setInterpAndReturnVar(interp, n, (objc == 5),
  4864   5694                                           (objc == 5) ? objv[4] : NULL);
  4865   5695   
  4866   5696           case m_delete:
  4867   5697               CheckArgs(2,2,2,"");
  4868         -            if (clientData != NULL) {
         5698  +            if (clientData != NULL || doc->nodeFlags & DOCUMENT_CMD) {
  4869   5699                   Tcl_DeleteCommand(interp, Tcl_GetString (objv[0]));
  4870   5700               } else {
  4871   5701                   tcldom_deleteDoc(interp, doc);
  4872   5702               }
  4873   5703               SetResult("");
  4874   5704               return TCL_OK;
  4875   5705   
................................................................................
  5110   5940           case m_firstChild:
  5111   5941           case m_lastChild:
  5112   5942           case m_hasChildNodes:
  5113   5943           case m_childNodes:
  5114   5944           case m_ownerDocument:
  5115   5945           case m_selectNodes:
  5116   5946           case m_baseURI:
         5947  +        case m_asJSON:
         5948  +        case m_jsonType:
  5117   5949           case m_getElementById:
  5118   5950               /* We dispatch the method call to tcldom_NodeObjCmd */
  5119   5951               if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
  5120   5952                   if (dinfo == NULL) {
  5121   5953                       /* tcldom_DocObjCmd was called with a doc token.
  5122   5954                          Since the domCreateCmdMode is 'automatic'
  5123   5955                          and we call tcldom_DocObjCmd with the root node
................................................................................
  5183   6015       Tcl_Obj    * const objv[]
  5184   6016   )
  5185   6017   {
  5186   6018       int          setVariable = 0;
  5187   6019       domDocument *doc;
  5188   6020       Tcl_Obj     *newObjName = NULL;
  5189   6021   
         6022  +    GetTcldomTSD()
  5190   6023   
  5191   6024       CheckArgs(2,3,1,"docElemName ?newObjVar?");
  5192   6025   
  5193   6026       if (objc == 3) {
  5194   6027           newObjName = objv[2];
  5195   6028           setVariable = 1;
  5196   6029       }
  5197   6030   
  5198         -    doc = domCreateDocument(interp, NULL, Tcl_GetString(objv[1]));
  5199         -    if (doc == NULL) {
  5200         -        return TCL_ERROR;
  5201         -    }
  5202         -
         6031  +    CheckName(interp, Tcl_GetString(objv[1]), "root element", 0);
         6032  +    doc = domCreateDocument(NULL, Tcl_GetString(objv[1]));
  5203   6033       return tcldom_returnDocumentObj(interp, doc, setVariable, newObjName, 1,
  5204   6034                                       0);
  5205   6035   }
  5206   6036   
  5207   6037   /*----------------------------------------------------------------------------
  5208   6038   |   tcldom_createDocumentNode
  5209   6039   |
................................................................................
  5212   6042   int tcldom_createDocumentNode (
  5213   6043       ClientData  clientData,
  5214   6044       Tcl_Interp *interp,
  5215   6045       int         objc,
  5216   6046       Tcl_Obj    * const objv[]
  5217   6047   )
  5218   6048   {
  5219         -    int          setVariable = 0;
         6049  +    int          setVariable = 0, jsonType = 0, index;
  5220   6050       domDocument *doc;
  5221   6051       Tcl_Obj     *newObjName = NULL;
  5222   6052   
  5223         -
  5224         -    CheckArgs(1,2,1,"?newObjVar?");
         6053  +    static const char *options[] = {"-jsonType", NULL};
         6054  +    
         6055  +    CheckArgs(1,4,1,"?-jsonType jsonType? ?newObjVar?");
  5225   6056   
  5226   6057       if (objc == 2) {
  5227   6058           newObjName = objv[1];
  5228   6059           setVariable = 1;
  5229   6060       }
         6061  +    if (objc > 2) {
         6062  +        if (Tcl_GetIndexFromObj(interp, objv[1], options, "option",
         6063  +                                0, &index) != TCL_OK) {
         6064  +            return TCL_ERROR;
         6065  +        }
         6066  +        Tcl_ResetResult(interp);
         6067  +            if (Tcl_GetIndexFromObj(interp, objv[2], jsonTypes, "jsonType",
         6068  +                                0, &jsonType) != TCL_OK) {
         6069  +            return TCL_ERROR;
         6070  +        }
         6071  +        if (objc == 4) {
         6072  +            newObjName = objv[3];
         6073  +            setVariable = 1;
         6074  +        }
         6075  +    }
  5230   6076   
  5231   6077       doc = domCreateDoc(NULL, 0);
  5232         -
         6078  +    doc->rootNode->info = jsonType;
         6079  +    
  5233   6080       return tcldom_returnDocumentObj(interp, doc, setVariable, newObjName, 1,
  5234   6081                                       0);
  5235   6082   }
  5236   6083   
  5237   6084   /*----------------------------------------------------------------------------
  5238   6085   |   tcldom_createDocumentNS
  5239   6086   |
................................................................................
  5242   6089   int tcldom_createDocumentNS (
  5243   6090       ClientData  clientData,
  5244   6091       Tcl_Interp *interp,
  5245   6092       int         objc,
  5246   6093       Tcl_Obj    * const objv[]
  5247   6094   )
  5248   6095   {
  5249         -    int          setVariable = 0;
         6096  +    int          setVariable = 0, len;
         6097  +    char        *uri;
  5250   6098       domDocument *doc;
  5251   6099       Tcl_Obj     *newObjName = NULL;
  5252   6100   
         6101  +    GetTcldomTSD()
  5253   6102   
  5254   6103       CheckArgs(3,4,1,"uri docElemName ?newObjVar?");
  5255   6104   
  5256   6105       if (objc == 4) {
  5257   6106           newObjName = objv[3];
  5258   6107           setVariable = 1;
  5259   6108       }
  5260   6109   
  5261         -    doc = domCreateDocument(interp, Tcl_GetString(objv[1]),
  5262         -                            Tcl_GetString(objv[2]));
  5263         -    if (doc == NULL) {
  5264         -        return TCL_ERROR;
         6110  +    CheckName(interp, Tcl_GetString(objv[2]), "root element", 1);
         6111  +    uri = Tcl_GetStringFromObj (objv[1], &len);
         6112  +    if (len == 0) {
         6113  +        if (!TSD(dontCheckName)) {
         6114  +            if (!domIsNCNAME (Tcl_GetString(objv[2]))) {
         6115  +                SetResult ("Missing URI in Namespace declaration");
         6116  +                return TCL_ERROR;
         6117  +            }
         6118  +        }
         6119  +        doc = domCreateDocument (NULL, Tcl_GetString(objv[2]));
         6120  +    } else {
         6121  +        doc = domCreateDocument (uri, Tcl_GetString(objv[2]));
  5265   6122       }
  5266         -
  5267         -    return tcldom_returnDocumentObj(interp, doc, setVariable, newObjName, 1,
         6123  +    return tcldom_returnDocumentObj (interp, doc, setVariable, newObjName, 1,
  5268   6124                                       0);
  5269   6125   }
  5270         -
  5271         -
  5272         -/*----------------------------------------------------------------------------
  5273         -|   tcldom_setResultEncoding
  5274         -|
  5275         -\---------------------------------------------------------------------------*/
  5276         -static
  5277         -int tcldom_setResultEncoding (
  5278         -    ClientData  clientData,
  5279         -    Tcl_Interp *interp,
  5280         -    int         objc,
  5281         -    Tcl_Obj    * const objv[]
  5282         -)
  5283         -{
  5284         -    GetTcldomTSD()
  5285         -
  5286         -    TEncoding *encoding;
  5287         -    char      *encodingName;
  5288         -
  5289         -    CheckArgs(1,2,1,"?encodingName?");
  5290         -    if (objc == 1) {
  5291         -        if (TSD(Encoding_to_8bit) == NULL) {
  5292         -            Tcl_AppendResult(interp, "UTF-8", NULL);
  5293         -        } else {
  5294         -            Tcl_AppendResult(interp, TSD(Encoding_to_8bit->name), NULL);
  5295         -        }
  5296         -        return TCL_OK;
  5297         -    }
  5298         -    encodingName = Tcl_GetString(objv[1]);
  5299         -    if ( (strcmp(encodingName, "UTF-8")==0)
  5300         -       ||(strcmp(encodingName, "UTF8")==0)
  5301         -       ||(strcmp(encodingName, "utf-8")==0)
  5302         -       ||(strcmp(encodingName, "utf8")==0)) {
  5303         -
  5304         -        TSD(Encoding_to_8bit) = NULL;
  5305         -    } else {
  5306         -        encoding = tdom_GetEncoding ( encodingName );
  5307         -        if (encoding == NULL) {
  5308         -             Tcl_AppendResult(interp, "encoding not found", NULL);
  5309         -             return TCL_ERROR;
  5310         -        }
  5311         -        TSD(Encoding_to_8bit) = encoding;
  5312         -    }
  5313         -    return TCL_OK;
  5314         -}
  5315         -
  5316   6126   
  5317   6127   /*----------------------------------------------------------------------------
  5318   6128   |   tcldom_parse
  5319   6129   |
  5320   6130   \---------------------------------------------------------------------------*/
  5321   6131   static
  5322   6132   int tcldom_parse (
................................................................................
  5325   6135       int         objc,
  5326   6136       Tcl_Obj    * const objv[]
  5327   6137   )
  5328   6138   {
  5329   6139       GetTcldomTSD()
  5330   6140   
  5331   6141       char        *xml_string, *option, *errStr, *channelId, *baseURI = NULL;
  5332         -    char        *extResolver = NULL;
  5333         -    CONST84 char *interpResult;
         6142  +    char        *jsonRoot = NULL;
         6143  +    Tcl_Obj     *extResolver = NULL;
         6144  +    Tcl_Obj     *feedbackCmd = NULL;
         6145  +    const char  *interpResult;
  5334   6146       int          optionIndex, value, xml_string_len, mode;
         6147  +    int          jsonmaxnesting = JSON_MAX_NESTING;
  5335   6148       int          ignoreWhiteSpaces   = 1;
         6149  +    int          takeJSONParser      = 0;
  5336   6150       int          takeSimpleParser    = 0;
  5337   6151       int          takeHTMLParser      = 0;
         6152  +    int          takeGUMBOParser     = 0;
  5338   6153       int          setVariable         = 0;
         6154  +    int          ignorexmlns         = 0;
  5339   6155       int          feedbackAfter       = 0;
  5340   6156       int          useForeignDTD       = 0;
  5341   6157       int          paramEntityParsing  = (int)XML_PARAM_ENTITY_PARSING_ALWAYS;
         6158  +    int          keepCDATA           = 0;
         6159  +    int          status              = 0;
  5342   6160       domDocument *doc;
  5343   6161       Tcl_Obj     *newObjName = NULL;
  5344   6162       XML_Parser   parser;
  5345   6163       Tcl_Channel  chan = (Tcl_Channel) NULL;
         6164  +    Tcl_CmdInfo  cmdInfo;
  5346   6165   
  5347         -    static CONST84 char *parseOptions[] = {
         6166  +    static const char *parseOptions[] = {
  5348   6167           "-keepEmpties",           "-simple",        "-html",
  5349   6168           "-feedbackAfter",         "-channel",       "-baseurl",
  5350   6169           "-externalentitycommand", "-useForeignDTD", "-paramentityparsing",
  5351         -        NULL
         6170  +        "-feedbackcmd",           "-json",          "-jsonroot",
         6171  +#ifdef TDOM_HAVE_GUMBO
         6172  +        "-html5",
         6173  +#endif
         6174  +        "-jsonmaxnesting",        "-ignorexmlns",   "--",
         6175  +        "-keepCDATA",                NULL
  5352   6176       };
  5353   6177       enum parseOption {
  5354   6178           o_keepEmpties,            o_simple,         o_html,
  5355   6179           o_feedbackAfter,          o_channel,        o_baseurl,
  5356         -        o_externalentitycommand,  o_useForeignDTD,  o_paramentityparsing
         6180  +        o_externalentitycommand,  o_useForeignDTD,  o_paramentityparsing,
         6181  +        o_feedbackcmd,            o_json,           o_jsonroot,
         6182  +#ifdef TDOM_HAVE_GUMBO
         6183  +        o_htmlfive,
         6184  +#endif
         6185  +        o_jsonmaxnesting,         o_ignorexmlns,    o_LAST,
         6186  +        o_keepCDATA
  5357   6187       };
  5358   6188   
  5359         -    static CONST84 char *paramEntityParsingValues[] = {
         6189  +    static const char *paramEntityParsingValues[] = {
  5360   6190           "always",
  5361   6191           "never",
  5362   6192           "notstandalone",
  5363   6193           (char *) NULL
  5364   6194       };
  5365   6195       enum paramEntityParsingValue {
  5366   6196           EXPAT_PARAMENTITYPARSINGALWAYS,
  5367   6197           EXPAT_PARAMENTITYPARSINGNEVER,
  5368   6198           EXPAT_PARAMENTITYPARSINGNOTSTANDALONE
  5369   6199       };
  5370         -    
         6200  +
  5371   6201       while (objc > 1) {
  5372   6202           option = Tcl_GetString(objv[1]);
  5373   6203           if (option[0] != '-') {
  5374   6204               break;
  5375   6205           }
  5376   6206           if (Tcl_GetIndexFromObj(interp, objv[1], parseOptions, "option", 0,
  5377   6207                                    &optionIndex) != TCL_OK) {
................................................................................
  5380   6210   
  5381   6211           switch ((enum parseOption) optionIndex) {
  5382   6212   
  5383   6213           case o_keepEmpties:
  5384   6214               ignoreWhiteSpaces = 0;
  5385   6215               objv++;  objc--; continue;
  5386   6216   
         6217  +        case o_json:
         6218  +            if (takeGUMBOParser || takeHTMLParser) {
         6219  +                SetResult("The options -html, -html5 and -json are "
         6220  +                          "mutually exclusive.");
         6221  +                return TCL_ERROR;
         6222  +            }
         6223  +            takeJSONParser = 1;
         6224  +            objv++;  objc--; continue;
         6225  +            
         6226  +        case o_jsonroot:
         6227  +            objv++; objc--;
         6228  +            if (objc > 1) {
         6229  +                jsonRoot = Tcl_GetString(objv[1]);
         6230  +            } else {
         6231  +                SetResult("The \"dom parse\" option \"-jsonroot\" "
         6232  +                          "expects the document element name of the "
         6233  +                          "DOM tree to create as argument.");
         6234  +                return TCL_ERROR;
         6235  +            }
         6236  +            if (!domIsNAME(jsonRoot)) {
         6237  +                SetResult("-jsonroot value: not a valid element name");
         6238  +                return TCL_ERROR;
         6239  +            }
         6240  +            objv++; objc--; continue;
         6241  +            
  5387   6242           case o_simple:
  5388   6243               takeSimpleParser = 1;
  5389   6244               objv++;  objc--; continue;
  5390   6245   
  5391   6246           case o_html:
         6247  +            if (takeGUMBOParser || takeJSONParser) {
         6248  +                SetResult("The options -html, -html5 and -json are "
         6249  +                          "mutually exclusive.");
         6250  +                return TCL_ERROR;
         6251  +            }
  5392   6252               takeSimpleParser = 1;
  5393   6253               takeHTMLParser = 1;
  5394   6254               objv++;  objc--; continue;
         6255  +
         6256  +#ifdef TDOM_HAVE_GUMBO
         6257  +        case o_htmlfive:
         6258  +            if (takeHTMLParser || takeJSONParser) {
         6259  +                SetResult("The options -html, -html5 and -json are "
         6260  +                          "mutually exclusive.");
         6261  +                return TCL_ERROR;
         6262  +            }
         6263  +            takeGUMBOParser = 1;
         6264  +            objv++;  objc--; continue;
         6265  +#endif
  5395   6266               
  5396   6267           case o_feedbackAfter:
  5397   6268               objv++; objc--;
  5398   6269               if (objc > 1) {
  5399   6270                   if (Tcl_GetIntFromObj(interp, objv[1], &feedbackAfter)
  5400   6271                       != TCL_OK) {
  5401   6272                       SetResult("-feedbackAfter must have an integer argument");
  5402   6273                       return TCL_ERROR;
  5403   6274                   }
  5404   6275               } else {
  5405   6276                   SetResult("The \"dom parse\" option \"-feedbackAfter\" requires"
  5406         -                          " an integer as argument.");
         6277  +                          " a positive integer as argument.");
         6278  +                return TCL_ERROR;
         6279  +            }
         6280  +            if (feedbackAfter <= 0) {
         6281  +                SetResult("The \"dom parse\" option \"-feedbackAfter\" requires"
         6282  +                          " a positive integer as argument.");
  5407   6283                   return TCL_ERROR;
  5408         -            }
         6284  +            }                
  5409   6285               objv++; objc--;
  5410   6286               continue;
  5411   6287   
  5412   6288           case o_channel:
  5413   6289               objv++; objc--;
  5414   6290               if (objc > 1) {
  5415   6291                   channelId = Tcl_GetString(objv[1]);
  5416   6292               } else {
  5417   6293                   SetResult("The \"dom parse\" option \"-channel\" "
  5418         -                          "requires a tcl channel as argument.");
         6294  +                          "requires a Tcl channel as argument.");
  5419   6295                   return TCL_ERROR;
  5420   6296               }
  5421   6297               chan = Tcl_GetChannel(interp, channelId, &mode);
  5422   6298               if (chan == (Tcl_Channel) NULL) {
  5423   6299                   return TCL_ERROR;
  5424   6300               }
  5425   6301               if ((mode & TCL_READABLE) == 0) {
................................................................................
  5442   6318               }
  5443   6319               objv++; objc--;
  5444   6320               continue;
  5445   6321   
  5446   6322           case o_externalentitycommand:
  5447   6323               objv++; objc--;
  5448   6324               if (objc > 1) {
  5449         -                extResolver = tdomstrdup (Tcl_GetString (objv[1]));
         6325  +                extResolver = objv[1];
  5450   6326               } else {
  5451   6327                   SetResult("The \"dom parse\" option \"-externalentitycommand\" "
  5452   6328                             "requires a script as argument.");
  5453   6329                   return TCL_ERROR;
  5454   6330               }
  5455   6331               objv++; objc--;
  5456   6332               continue;
................................................................................
  5492   6368                   SetResult("-paramEntityParsing requires 'always', 'never' "
  5493   6369                             "or 'notstandalone' as argument");
  5494   6370                   return TCL_ERROR;
  5495   6371               }
  5496   6372               objv++; objc--;
  5497   6373               objv++; objc--;
  5498   6374               continue;
         6375  +
         6376  +        case o_feedbackcmd:
         6377  +            objv++; objc--;
         6378  +            if (objc > 1) {
         6379  +                feedbackCmd = objv[1];
         6380  +            } else {
         6381  +                SetResult("The \"dom parse\" option \"-feedbackcmd\" "
         6382  +                          "requires a script as argument.");
         6383  +                return TCL_ERROR;
         6384  +            }
         6385  +            objv++; objc--;
         6386  +            continue;
         6387  +            
         6388  +        case o_ignorexmlns:
         6389  +            ignorexmlns = 1;
         6390  +            objv++;  objc--; continue;
         6391  +
         6392  +        case o_jsonmaxnesting:
         6393  +            objv++; objc--;
         6394  +            if (objc < 2) {
         6395  +                SetResult("The \"dom parse\" option \"-jsonmaxnesting\" "
         6396  +                          "requires an integer as argument.");
         6397  +                return TCL_ERROR;
         6398  +            }
         6399  +            if (Tcl_GetIntFromObj(interp, objv[1], &jsonmaxnesting)
         6400  +                != TCL_OK) {
         6401  +                SetResult("-jsonmaxnesting must have an integer argument");
         6402  +                return TCL_ERROR;
         6403  +            }
         6404  +            if (jsonmaxnesting < 0) {
         6405  +                SetResult("The value of -jsonmaxnesting cannot be negativ");
         6406  +                return TCL_ERROR;
         6407  +            }
         6408  +            objv++;  objc--; continue;
         6409  +                        
         6410  +        case o_LAST:
         6411  +            objv++;  objc--; break;
         6412  +            
         6413  +        case o_keepCDATA:
         6414  +            keepCDATA = 1;
         6415  +            objv++;  objc--; break;
         6416  +            
         6417  +        }
         6418  +        if ((enum parseOption) optionIndex == o_LAST) break;
         6419  +    }
         6420  +
         6421  +    if (feedbackAfter && !feedbackCmd) {
         6422  +        if (!Tcl_GetCommandInfo(interp, "::dom::domParseFeedback", 
         6423  +                                &cmdInfo)) {
         6424  +            SetResult("If -feedbackAfter is used, "
         6425  +                      "-feedbackcmd must also be used.");
         6426  +            return TCL_ERROR;
  5499   6427           }
  5500   6428       }
  5501         -    
  5502   6429       if (chan == NULL) {
  5503   6430           if (objc < 2) {
  5504   6431               SetResult(dom_usage);
  5505   6432               return TCL_ERROR;
  5506   6433           }
  5507   6434           xml_string = Tcl_GetStringFromObj( objv[1], &xml_string_len);
  5508   6435           if (objc == 3) {
................................................................................
  5512   6439       } else {
  5513   6440           if (objc > 2) {
  5514   6441               SetResult(dom_usage);
  5515   6442               return TCL_ERROR;
  5516   6443           }
  5517   6444           xml_string = NULL;
  5518   6445           xml_string_len = 0;
  5519         -        if (takeSimpleParser || takeHTMLParser) {
  5520         -            Tcl_AppendResult(interp, "simple and/or HTML parser(s) "
         6446  +        if (takeSimpleParser || takeHTMLParser || takeJSONParser
         6447  +#ifdef TDOM_HAVE_GUMBO
         6448  +                || takeGUMBOParser
         6449  +#endif
         6450  +            ) {
         6451  +            Tcl_AppendResult(interp, "simple, JSON or HTML parser(s) "
  5521   6452                                " don't support channel reading", NULL);
  5522   6453               return TCL_ERROR;
  5523   6454           }
  5524   6455           if (objc == 2) {
  5525   6456               newObjName = objv[1];
  5526   6457               setVariable = 1;
  5527   6458           }
  5528   6459       }
  5529   6460   
         6461  +#ifdef TDOM_HAVE_GUMBO
         6462  +    if (takeGUMBOParser) {
         6463  +        doc = HTML_GumboParseDocument(xml_string, ignoreWhiteSpaces,
         6464  +                                      ignorexmlns);
         6465  +        return tcldom_returnDocumentObj (interp, doc, setVariable, newObjName,
         6466  +                                         1, 0);
         6467  +    }
         6468  +#endif
         6469  +    
         6470  +    if (takeJSONParser) {
         6471  +        char s[50];
         6472  +        int byteIndex, i;
         6473  +
         6474  +        errStr = NULL;
         6475  +
         6476  +        doc = JSON_Parse (xml_string, jsonRoot, jsonmaxnesting, &errStr,
         6477  +                          &byteIndex);
         6478  +        if (doc) {
         6479  +            return tcldom_returnDocumentObj (interp, doc, setVariable,
         6480  +                                             newObjName, 1, 0);
         6481  +        } else {
         6482  +            Tcl_ResetResult(interp);
         6483  +            sprintf(s, "%d", byteIndex);
         6484  +            Tcl_AppendResult(interp, "error \"", errStr, "\" at position ", 
         6485  +                             s, NULL);
         6486  +            Tcl_AppendResult(interp, "\n\"", NULL);
         6487  +            s[1] = '\0';
         6488  +            for (i=-20; i < 40; i++) {
         6489  +                if (byteIndex+i>=0) {
         6490  +                    if (xml_string[byteIndex+i]) {
         6491  +                        s[0] = xml_string[byteIndex+i];
         6492  +                        Tcl_AppendResult(interp, s, NULL);
         6493  +                        if (i==0) {
         6494  +                            Tcl_AppendResult(interp, " <--Error-- ", NULL);
         6495  +                        }
         6496  +                    } else {
         6497  +                        break;
         6498  +                    }
         6499  +                }
         6500  +            }
         6501  +            Tcl_AppendResult(interp, "\"",NULL);
         6502  +            return TCL_ERROR;
         6503  +        }
         6504  +    }
         6505  +    
  5530   6506       if (takeSimpleParser) {
  5531   6507           char s[50];
  5532   6508           int  byteIndex, i;
  5533   6509   
  5534   6510           errStr = NULL;
  5535   6511   
  5536   6512           if (takeHTMLParser) {
  5537   6513               doc = HTML_SimpleParseDocument(xml_string, ignoreWhiteSpaces,
  5538   6514                                              &byteIndex, &errStr);
  5539   6515           } else {
  5540   6516               doc = XML_SimpleParseDocument(xml_string, ignoreWhiteSpaces,
         6517  +                                          keepCDATA,
  5541   6518                                             baseURI, extResolver,
  5542   6519                                             &byteIndex, &errStr);
  5543   6520           }
  5544   6521           if (errStr != NULL) {
  5545   6522               domFreeDocument (doc, NULL, interp);
  5546   6523   
  5547   6524               Tcl_ResetResult(interp);
................................................................................
  5581   6558   #else
  5582   6559       parser = XML_ParserCreate_MM(NULL, MEM_SUITE, NULL);
  5583   6560       Tcl_ResetResult(interp);
  5584   6561   
  5585   6562       doc = domReadDocument(parser, xml_string,
  5586   6563                             xml_string_len,
  5587   6564                             ignoreWhiteSpaces,
  5588         -                          TSD(Encoding_to_8bit),
         6565  +                          keepCDATA,
  5589   6566                             TSD(storeLineColumn),
         6567  +                          ignorexmlns,
  5590   6568                             feedbackAfter,
         6569  +                          feedbackCmd,
  5591   6570                             chan,
  5592   6571                             baseURI,
  5593   6572                             extResolver,
  5594   6573                             useForeignDTD,
  5595   6574                             paramEntityParsing,
  5596         -                          interp);
         6575  +                          interp,
         6576  +                          &status);
  5597   6577       if (doc == NULL) {
  5598   6578           char s[50];
  5599   6579           long byteIndex, i;
  5600         -
  5601         -        interpResult = Tcl_GetStringResult(interp);
  5602         -        if (interpResult[0] == '\0') {
  5603         -            /* If the interp result isn't empty, then there was an error
  5604         -               in an enternal entity and the interp result has already the
  5605         -               error msg. If we don't got a document, but interp result is
  5606         -               empty, the error occured in the main document and we
  5607         -               build the error msg as follows. */
         6580  +        
         6581  +        switch (status) {
         6582  +        case TCL_BREAK:
         6583  +            /* Abort of parsing by the application */
         6584  +            Tcl_ResetResult(interp);
         6585  +            XML_ParserFree(parser);
         6586  +            return TCL_OK;
         6587  +        default:
         6588  +            interpResult = Tcl_GetStringResult(interp);
  5608   6589               sprintf(s, "%ld", XML_GetCurrentLineNumber(parser));
  5609         -            Tcl_AppendResult(interp, "error \"", 
  5610         -                             XML_ErrorString(XML_GetErrorCode(parser)),
  5611         -                             "\" at line ", s, " character ", NULL);
  5612         -            sprintf(s, "%ld", XML_GetCurrentColumnNumber(parser));
  5613         -            Tcl_AppendResult(interp, s, NULL);
  5614         -            byteIndex = XML_GetCurrentByteIndex(parser);
  5615         -            if ((byteIndex != -1) && (chan == NULL)) {
  5616         -                Tcl_AppendResult(interp, "\n\"", NULL);
  5617         -                s[1] = '\0';
  5618         -                for (i=-20; i < 40; i++) {
  5619         -                    if ((byteIndex+i)>=0) {
  5620         -                        if (xml_string[byteIndex+i]) {
  5621         -                            s[0] = xml_string[byteIndex+i];
  5622         -                            Tcl_AppendResult(interp, s, NULL);
  5623         -                            if (i==0) {
  5624         -                                Tcl_AppendResult(interp, " <--Error-- ", NULL);
  5625         -                            }
  5626         -                        } else {
  5627         -                            break;
         6590  +            if (interpResult[0] == '\0') {
         6591  +                /* If the interp result isn't empty, then there was an error
         6592  +                   in an enternal entity and the interp result has already the
         6593  +                   error msg. If we don't got a document, but interp result is
         6594  +                   empty, the error occurred in the main document and we
         6595  +                   build the error msg as follows. */
         6596  +                Tcl_AppendResult(interp, "error \"", 
         6597  +                                 XML_ErrorString(XML_GetErrorCode(parser)),
         6598  +                                 "\" at line ", s, " character ", NULL);
         6599  +                sprintf(s, "%ld", XML_GetCurrentColumnNumber(parser));
         6600  +                Tcl_AppendResult(interp, s, NULL);
         6601  +                byteIndex = XML_GetCurrentByteIndex(parser);
         6602  +                if ((byteIndex != -1) && (chan == NULL)) {
         6603  +                    Tcl_AppendResult(interp, "\n\"", NULL);
         6604  +                    s[1] = '\0';
         6605  +                    for (i=-20; i < 40; i++) {
         6606  +                        if ((byteIndex+i)>=0) {
         6607  +                            if (xml_string[byteIndex+i]) {
         6608  +                                s[0] = xml_string[byteIndex+i];
         6609  +                                Tcl_AppendResult(interp, s, NULL);
         6610  +                                if (i==0) {
         6611  +                                    Tcl_AppendResult(interp, " <--Error-- ", NULL);
         6612  +                                }
         6613  +                            } else {
         6614  +                                break;
         6615  +                            }
  5628   6616                           }
  5629   6617                       }
         6618  +                    Tcl_AppendResult(interp, "\"",NULL);
  5630   6619                   }
  5631         -                Tcl_AppendResult(interp, "\"",NULL);
         6620  +            } else {
         6621  +                if (status == TCL_OK) {
         6622  +                    /* For Tcl errors (in -externalentitycommand or
         6623  +                     * feedback callback) we leave the error msg in
         6624  +                     * the interpreter alone. If there wasn't a Tcl
         6625  +                     * error, there was a parsing error. Because the
         6626  +                     * interp has already an error msg, that parsing
         6627  +                     * error was in an external entity. Therefore, we
         6628  +                     * just add the place of the referencing entity in
         6629  +                     * the mail document.*/
         6630  +                    Tcl_AppendResult(interp, ", referenced at line ", s, NULL);
         6631  +                    sprintf(s, "%ld", XML_GetCurrentColumnNumber(parser));
         6632  +                    Tcl_AppendResult(interp, " character ", s, NULL);
         6633  +                }
  5632   6634               }
         6635  +            XML_ParserFree(parser);
         6636  +            return TCL_ERROR;
  5633   6637           }
  5634         -        XML_ParserFree(parser);
  5635         -        return TCL_ERROR;
  5636   6638       }
  5637   6639       XML_ParserFree(parser);
  5638   6640   
  5639   6641       return tcldom_returnDocumentObj (interp, doc, setVariable, newObjName, 1,
  5640   6642                                        0);
  5641   6643   #endif
  5642   6644   
  5643   6645   }
  5644   6646   
         6647  +/*----------------------------------------------------------------------------
         6648  +|   tcldom_featureinfo
         6649  +|
         6650  +\---------------------------------------------------------------------------*/
         6651  +static
         6652  +int tcldom_featureinfo (
         6653  +    ClientData  clientData,
         6654  +    Tcl_Interp *interp,
         6655  +    int         objc,
         6656  +    Tcl_Obj    * const objv[]
         6657  +)
         6658  +{
         6659  +    int featureIndex, result;
         6660  +    
         6661  +    static const char *features[] = {
         6662  +        "expatversion",      "expatmajorversion",  "expatminorversion",
         6663  +        "expatmicroversion", "dtd",                "ns",
         6664  +        "unknown",           "tdomalloc",          "lessns",
         6665  +        "html5",             "jsonmaxnesting",     "versionhash",
         6666  +        "pullparser",        "TCL_UTF_MAX",        NULL
         6667  +    };
         6668  +    enum feature {
         6669  +        o_expatversion,      o_expatmajorversion,  o_expatminorversion,
         6670  +        o_expatmicroversion, o_dtd,                o_ns,
         6671  +        o_unknown,           o_tdomalloc,          o_lessns,
         6672  +        o_html5,             o_jsonmaxnesting,     o_versionhash,
         6673  +        o_pullparser,        o_TCL_UTF_MAX,
         6674  +    };
         6675  +
         6676  +    if (Tcl_GetIndexFromObj(interp, objv[1], features, "feature", 0,
         6677  +                            &featureIndex) != TCL_OK) {
         6678  +        return TCL_ERROR;
         6679  +    }
         6680  +
         6681  +    switch ((enum feature) featureIndex) {
         6682  +    case o_expatversion:
         6683  +        SetResult(XML_ExpatVersion());
         6684  +        break;
         6685  +    case o_expatmajorversion:
         6686  +        SetIntResult(XML_MAJOR_VERSION);
         6687  +        break;
         6688  +    case o_expatminorversion:
         6689  +        SetIntResult(XML_MINOR_VERSION);
         6690  +        break;
         6691  +    case o_expatmicroversion:
         6692  +        SetIntResult(XML_MICRO_VERSION);
         6693  +        break;
         6694  +    case o_dtd:
         6695  +#ifdef XML_DTD
         6696  +        result = 1;
         6697  +#else
         6698  +        result = 0;
         6699  +#endif
         6700  +        SetBooleanResult(result);
         6701  +        break;
         6702  +    case o_ns:
         6703  +#ifdef XML_NS
         6704  +        result = 1;
         6705  +#else
         6706  +        result = 0;
         6707  +#endif
         6708  +        SetBooleanResult(result);
         6709  +        break;
         6710  +    case o_unknown:       
         6711  +#ifdef TDOM_NO_UNKNOWN_CMD
         6712  +        result = 0;
         6713  +#else
         6714  +        result = 1;
         6715  +#endif
         6716  +        SetBooleanResult(result);
         6717  +        break;
         6718  +    case o_tdomalloc:
         6719  +#ifdef USE_NORMAL_ALLOCATOR
         6720  +        result = 0;
         6721  +#else
         6722  +        result = 1;
         6723  +#endif
         6724  +        SetBooleanResult(result);
         6725  +        break;
         6726  +    case o_lessns:
         6727  +#ifdef TDOM_LESS_NS
         6728  +        result = 1;
         6729  +#else
         6730  +        result = 0;
         6731  +#endif
         6732  +        SetBooleanResult(result);
         6733  +        break;
         6734  +    case o_html5:
         6735  +#ifdef TDOM_HAVE_GUMBO
         6736  +        result = 1;
         6737  +#else
         6738  +        result = 0;
         6739  +#endif
         6740  +        SetBooleanResult(result);
         6741  +        break;
         6742  +    case o_jsonmaxnesting:
         6743  +        SetIntResult(JSON_MAX_NESTING);
         6744  +        break;
         6745  +
         6746  +    case o_versionhash:
         6747  +        SetResult(FOSSIL_HASH);
         6748  +        break;
         6749  +    case o_pullparser:
         6750  +#ifndef TDOM_NO_PULL
         6751  +        result = 1;
         6752  +#else
         6753  +        result = 0;
         6754  +#endif
         6755  +        SetBooleanResult(result);
         6756  +        break;
         6757  +    case o_TCL_UTF_MAX:
         6758  +        SetIntResult(TCL_UTF_MAX);
         6759  +        break;
         6760  +    }
         6761  +    return TCL_OK;
         6762  +}
  5645   6763   
  5646   6764   /*----------------------------------------------------------------------------
  5647   6765   |   tcldom_DomObjCmd
  5648   6766   |
  5649   6767   \---------------------------------------------------------------------------*/
  5650   6768   int tcldom_DomObjCmd (
  5651   6769       ClientData   clientData,
  5652   6770       Tcl_Interp * interp,
  5653   6771       int          objc,
  5654         -    Tcl_Obj    * CONST objv[]
         6772  +    Tcl_Obj    * const objv[]
  5655   6773   )
  5656   6774   {
  5657   6775       GetTcldomTSD()
  5658   6776   
  5659   6777       char        * method, tmp[300];
  5660   6778       int           methodIndex, result, i, bool;
  5661   6779       Tcl_CmdInfo   cmdInfo;
  5662   6780       Tcl_Obj     * mobjv[MAX_REWRITE_ARGS];
  5663   6781   
  5664         -    static CONST84 char *domMethods[] = {
         6782  +    static const char *domMethods[] = {
  5665   6783           "createDocument",  "createDocumentNS",   "createNodeCmd",
  5666         -        "parse",           "setResultEncoding",  "setStoreLineColumn",
         6784  +        "parse",                                 "setStoreLineColumn",
  5667   6785           "isCharData",      "isName",             "isPIName",
  5668   6786           "isQName",         "isComment",          "isCDATA",
  5669   6787           "isPIValue",       "isNCName",           "createDocumentNode",
  5670   6788           "setNameCheck",    "setTextCheck",       "setObjectCommands",
         6789  +        "featureinfo",     "isBMPCharData",
  5671   6790   #ifdef TCL_THREADS
  5672   6791           "attachDocument",  "detachDocument",
  5673   6792   #endif
  5674   6793           NULL
  5675   6794       };
  5676   6795       enum domMethod {
  5677   6796           m_createDocument,    m_createDocumentNS,   m_createNodeCmd,
  5678         -        m_parse,             m_setResultEncoding,  m_setStoreLineColumn,
         6797  +        m_parse,                                   m_setStoreLineColumn,
  5679   6798           m_isCharData,        m_isName,             m_isPIName,
  5680   6799           m_isQName,           m_isComment,          m_isCDATA,
  5681   6800           m_isPIValue,         m_isNCName,           m_createDocumentNode,
  5682         -        m_setNameCheck,      m_setTextCheck,       m_setObjectCommands
         6801  +        m_setNameCheck,      m_setTextCheck,       m_setObjectCommands,
         6802  +        m_featureinfo,       m_isBMPCharData
  5683   6803   #ifdef TCL_THREADS
  5684   6804           ,m_attachDocument,   m_detachDocument
  5685   6805   #endif
  5686   6806       };
  5687   6807   
  5688         -    static CONST84 char *nodeModeValues[] = {
         6808  +    static const char *nodeModeValues[] = {
  5689   6809           "automatic", "command", "token", NULL
  5690   6810       };
  5691   6811       enum nodeModeValue {
  5692   6812           v_automatic, v_command, v_token
  5693   6813       };
  5694   6814   
  5695   6815       if (objc < 2) {
................................................................................
  5702   6822       method = Tcl_GetString(objv[1]);
  5703   6823       if (Tcl_GetIndexFromObj(NULL, objv[1], domMethods, "method", 0,
  5704   6824                               &methodIndex) != TCL_OK) {
  5705   6825           /*--------------------------------------------------------
  5706   6826           |   try to find method implemented as normal Tcl proc
  5707   6827           \-------------------------------------------------------*/
  5708   6828           if ((strlen(method)-1) >= 270) {
  5709         -            SetResult("method name to long!");
         6829  +            SetResult("method name too long!");
  5710   6830               return TCL_ERROR;
  5711   6831           }
  5712   6832           sprintf(tmp, "::dom::DOMImplementation::%s", method);
  5713   6833           DBG(fprintf(stderr, "testing %s\n", tmp));
  5714   6834           result = Tcl_GetCommandInfo(interp, tmp, &cmdInfo);
  5715   6835           if (!result) {
  5716   6836               SetResult(dom_usage);
................................................................................
  5791   6911                   }
  5792   6912                   SetResult("");
  5793   6913                   return TCL_OK;
  5794   6914               }
  5795   6915               break;
  5796   6916   #endif
  5797   6917   
  5798         -        case m_setResultEncoding:
  5799         -            return tcldom_setResultEncoding(clientData, interp, --objc, objv+1);
  5800         -
  5801   6918           case m_setStoreLineColumn:
  5802   6919               if (objc == 3) {
  5803   6920                   if (Tcl_GetBooleanFromObj(interp, objv[2], &bool) != TCL_OK) {
  5804   6921                       return TCL_ERROR;
  5805   6922                   }
  5806   6923                   TSD(storeLineColumn) = bool;
  5807   6924               }
................................................................................
  5900   7017               return TCL_OK;
  5901   7018               
  5902   7019           case m_isNCName:
  5903   7020               CheckArgs(3,3,2,"string");
  5904   7021               SetBooleanResult(domIsNCNAME(Tcl_GetString(objv[2])));
  5905   7022               return TCL_OK;
  5906   7023   
         7024  +        case m_featureinfo:
         7025  +            CheckArgs(3,3,2,"feature")
         7026  +            return tcldom_featureinfo(clientData, interp, --objc, objv+1);
         7027  +
         7028  +        case m_isBMPCharData:
         7029  +            CheckArgs(3,3,2,"string");
         7030  +            SetBooleanResult(domIsBMPChar(Tcl_GetString(objv[2])));
         7031  +            return TCL_OK;
         7032  +                
  5907   7033       }
  5908   7034       SetResult( dom_usage);
  5909   7035       return TCL_ERROR;
  5910   7036   }
  5911   7037   
  5912   7038   #ifdef TCL_THREADS
  5913   7039   
................................................................................
  5920   7046   int tcldom_EvalLocked (
  5921   7047       Tcl_Interp  * interp, 
  5922   7048       Tcl_Obj    ** objv, 
  5923   7049       domDocument * doc,
  5924   7050       int          flag
  5925   7051   )
  5926   7052   {
  5927         -    int ret = TCL_OK;
         7053  +    int ret;
  5928   7054       domlock *dl = doc->lock;
  5929   7055   
  5930   7056       domLocksLock(dl, flag);
  5931   7057   
  5932   7058       Tcl_AllowExceptions(interp);
  5933         -    ret = Tcl_EvalObj(interp, objv[2]);
         7059  +    ret = Tcl_EvalObjEx(interp, objv[2], 0);
  5934   7060       if (ret == TCL_ERROR) {
  5935   7061           char msg[64 + TCL_INTEGER_SPACE];
  5936   7062           sprintf(msg, "\n    (\"%s %s\" body line %d)", Tcl_GetString(objv[0]),
  5937         -                Tcl_GetString(objv[1]), interp->errorLine);
         7063  +                Tcl_GetString(objv[1]), Tcl_GetErrorLine(interp));
  5938   7064           Tcl_AddErrorInfo(interp, msg);
  5939   7065       }
  5940   7066   
  5941   7067       domLocksUnlock(dl);
  5942   7068   
  5943   7069       return (ret == TCL_BREAK) ? TCL_OK : ret;
  5944   7070   }
................................................................................
  5950   7076   
  5951   7077   static
  5952   7078   int tcldom_RegisterDocShared (
  5953   7079       domDocument * doc
  5954   7080   )
  5955   7081   {
  5956   7082       Tcl_HashEntry *entryPtr;
  5957         -    int refCount, newEntry;
         7083  +    int newEntry = 0;
         7084  +#ifdef DEBUG    
         7085  +    int refCount;
         7086  +#endif
  5958   7087   
  5959   7088       Tcl_MutexLock(&tableMutex);
         7089  +#ifdef DEBUG    
  5960   7090       refCount = ++doc->refCount;
         7091  +#else
         7092  +    ++doc->refCount;
         7093  +#endif
  5961   7094       entryPtr = Tcl_CreateHashEntry(&sharedDocs, (char*)doc, &newEntry);
  5962   7095       if (newEntry) {
  5963   7096           Tcl_SetHashValue(entryPtr, (ClientData)doc);
  5964   7097       }
  5965   7098       Tcl_MutexUnlock(&tableMutex);
  5966   7099   
  5967   7100       DBG(fprintf(stderr, "--> tcldom_RegisterDocShared: doc %p %s "
................................................................................
  5986   7119       Tcl_MutexLock(&tableMutex);
  5987   7120       if (doc->refCount > 1) {
  5988   7121           tcldom_deleteNode(doc->rootNode, interp);
  5989   7122           domFreeNode(doc->rootNode, tcldom_deleteNode, interp, 1);
  5990   7123           doc->refCount--;
  5991   7124           deleted = 0;
  5992   7125       } else {
  5993         -        Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&sharedDocs, (char*)doc);
  5994         -        if (entryPtr) {
  5995         -            Tcl_DeleteHashEntry(entryPtr);
  5996         -            deleted = 1;
         7126  +        if (tcldomInitialized) {
         7127  +            Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&sharedDocs, (char*)doc);
         7128  +            if (entryPtr) {
         7129  +                Tcl_DeleteHashEntry(entryPtr);
         7130  +                deleted = 1;
         7131  +            } else {
         7132  +                deleted = 0;
         7133  +            }
  5997   7134           } else {
  5998   7135               deleted = 0;
  5999   7136           }
  6000   7137       }
  6001   7138       Tcl_MutexUnlock(&tableMutex);
  6002   7139   
  6003   7140       DBG(fprintf(stderr, "--> tcldom_UnregisterDocShared: doc %p %s "
................................................................................
  6017   7154   )
  6018   7155   {
  6019   7156       Tcl_HashEntry *entryPtr;
  6020   7157       domDocument *tabDoc = NULL;
  6021   7158       int found = 0;
  6022   7159   
  6023   7160       Tcl_MutexLock(&tableMutex);
  6024         -    entryPtr = Tcl_FindHashEntry(&sharedDocs, (char*)doc);
  6025         -    if (entryPtr == NULL) {
  6026         -        found = 0;
  6027         -    } else {
  6028         -        tabDoc = (domDocument*)Tcl_GetHashValue(entryPtr);
  6029         -        found  = tabDoc ? 1 : 0;
         7161  +    if (tcldomInitialized) {
         7162  +        entryPtr = Tcl_FindHashEntry(&sharedDocs, (char*)doc);
         7163  +        if (entryPtr == NULL) {
         7164  +            found = 0;
         7165  +        } else {
         7166  +            tabDoc = (domDocument*)Tcl_GetHashValue(entryPtr);
         7167  +            found  = tabDoc ? 1 : 0;
         7168  +        }
  6030   7169       }
  6031   7170       Tcl_MutexUnlock(&tableMutex);
  6032   7171   
  6033   7172       if (found && doc != tabDoc) {
  6034         -        Tcl_Panic("document mismatch; doc=%p, in table=%p\n", doc, tabDoc);
         7173  +        Tcl_Panic("document mismatch; doc=%p, in table=%p\n", (void *)doc,
         7174  +                  (void *)tabDoc);
  6035   7175       }
  6036   7176   
  6037   7177       return found;
  6038   7178   }
  6039   7179   
  6040   7180   #endif /* TCL_THREADS */
  6041   7181   
................................................................................
  6045   7185   |   tcldom_unknownCmd
  6046   7186   |
  6047   7187   \---------------------------------------------------------------------------*/
  6048   7188   int tcldom_unknownCmd (
  6049   7189       ClientData   clientData,
  6050   7190       Tcl_Interp * interp,
  6051   7191       int          objc,
  6052         -    Tcl_Obj    * CONST objv[]
         7192  +    Tcl_Obj    * const objv[]
  6053   7193   )
  6054   7194   {
  6055   7195       int          len, i, rc, openedParen, count, args;
  6056   7196       char        *cmd, *dot, *paren, *arg[MAX_REWRITE_ARGS], *object, *method;
  6057   7197       Tcl_DString  callString;
  6058   7198       Tcl_CmdInfo  cmdInfo;
  6059   7199       Tcl_Obj     *vector[2+MAX_REWRITE_ARGS];

Changes to generic/tcldom.h.

    58     58   Tcl_ObjCmdProc tcldom_DomObjCmd;
    59     59   Tcl_ObjCmdProc tcldom_DocObjCmd;
    60     60   Tcl_ObjCmdProc tcldom_NodeObjCmd;
    61     61   Tcl_ObjCmdProc TclExpatObjCmd;
    62     62   Tcl_ObjCmdProc tcldom_unknownCmd;
    63     63   Tcl_ObjCmdProc TclTdomObjCmd;
    64     64   
    65         -#if defined(_MSC_VER)
           65  +#if defined(_MSC_VER) || defined(__MINGW32__)
    66     66   #  undef TCL_STORAGE_CLASS
    67     67   #  define TCL_STORAGE_CLASS DLLEXPORT
    68     68   #endif
    69     69   
    70     70   #define STR_TDOM_VERSION(v) (VERSION)
    71     71   
    72         -EXTERN int Tdom_Init     _ANSI_ARGS_((Tcl_Interp *interp));
    73         -EXTERN int Tdom_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
           72  +EXTERN int Tdom_Init     (Tcl_Interp *interp);
           73  +EXTERN int Tdom_SafeInit (Tcl_Interp *interp);
    74     74   
    75     75   #endif
    76     76   
    77     77   

Changes to generic/tclexpat.c.

    38     38   #include <string.h>
    39     39   #include <dom.h>
    40     40   #include <tclexpat.h>
    41     41   #include <fcntl.h>
    42     42   
    43     43   #ifdef _MSC_VER
    44     44   #include <io.h>
    45         -#endif
    46         -
    47         -#ifdef _POSIX_SOURCE
           45  +#else
    48     46   #include <unistd.h>
    49     47   #endif
    50     48   
    51     49   /* Used internal als status, like TCL_OK, TCL_ERROR etc.  As a
    52         -   consequent, application specific error codes must be at least
           50  +   consequence, application specific error codes must be at least
    53     51      greater than 5 */
    54     52   #define ERROR_IN_EXTREFHANDLER 5
    55     53   
    56         -#define READ_SIZE (1024*8)
           54  +#ifndef TDOM_EXPAT_READ_SIZE
           55  +# define TDOM_EXPAT_READ_SIZE (1024*8)
           56  +#endif
    57     57   #ifndef O_BINARY
    58     58   #ifdef _O_BINARY
    59     59   #define O_BINARY _O_BINARY
    60     60   #else
    61     61   #define O_BINARY 0
    62     62   #endif
    63     63   #endif
................................................................................
   109    109                                   */
   110    110   TDomThreaded(static Tcl_Mutex counterMutex;) /* Protect the counter (zv) */
   111    111   
   112    112   /*----------------------------------------------------------------------------
   113    113   |   Prototypes for procedures defined later in this file:
   114    114   |
   115    115   \---------------------------------------------------------------------------*/
   116         -int             TclExpatObjCmd _ANSI_ARGS_((ClientData dummy,
   117         -                    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
   118         -static int      TclExpatInstanceCmd _ANSI_ARGS_((ClientData dummy,
   119         -                    Tcl_Interp *interp, int objc, struct Tcl_Obj *CONST objv[]));
   120         -static void     TclExpatDeleteCmd _ANSI_ARGS_((ClientData clientData));
          116  +int             TclExpatObjCmd (ClientData dummy,
          117  +                    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
          118  +static int      TclExpatInstanceCmd (ClientData dummy,
          119  +                    Tcl_Interp *interp, int objc, struct Tcl_Obj *const objv[]);
          120  +static void     TclExpatDeleteCmd (ClientData clientData);
   121    121   
   122         -static Tcl_Obj* FindUniqueCmdName _ANSI_ARGS_((Tcl_Interp *interp));
   123         -static int      TclExpatCheckWhiteData _ANSI_ARGS_((char *pc, int len));
          122  +static Tcl_Obj* FindUniqueCmdName (Tcl_Interp *interp);
          123  +static int      TclExpatCheckWhiteData (char *pc, int len);
   124    124   
   125         -static int      TclExpatInitializeParser _ANSI_ARGS_((Tcl_Interp *interp,
   126         -                    TclGenExpatInfo *expat, int resetOptions ));
   127         -static void     TclExpatFreeParser  _ANSI_ARGS_((TclGenExpatInfo *expat));
   128         -static int      TclExpatParse _ANSI_ARGS_((Tcl_Interp *interp,
          125  +static int      TclExpatInitializeParser (Tcl_Interp *interp,
          126  +                    TclGenExpatInfo *expat, int resetOptions );
          127  +static void     TclExpatFreeParser  (TclGenExpatInfo *expat);
          128  +static int      TclExpatParse (Tcl_Interp *interp,
   129    129                       TclGenExpatInfo *expat, char *data, int len,
   130         -                                     TclExpat_InputType type));
   131         -static int      TclExpatConfigure _ANSI_ARGS_((Tcl_Interp *interp,
   132         -                    TclGenExpatInfo *expat, int objc, Tcl_Obj *CONST objv[]));
   133         -static int      TclExpatCget _ANSI_ARGS_((Tcl_Interp *interp,
   134         -                    TclGenExpatInfo *expat, int objc, Tcl_Obj *CONST objv[]));
          130  +                               TclExpat_InputType type);
          131  +static int      TclExpatConfigure (Tcl_Interp *interp,
          132  +                    TclGenExpatInfo *expat, int objc, Tcl_Obj *const objv[]);
          133  +static int      TclExpatCget (Tcl_Interp *interp,
          134  +                    TclGenExpatInfo *expat, int objc, Tcl_Obj *const objv[]);
   135    135   
   136         -static int	TclExpatGet _ANSI_ARGS_((Tcl_Interp *interp,
   137         -		    TclGenExpatInfo *expat, int objc, Tcl_Obj *CONST objv[]));
   138         -static void	TclExpatDispatchPCDATA _ANSI_ARGS_((TclGenExpatInfo *expat));
   139         -static void TclGenExpatElementStartHandler _ANSI_ARGS_((void *userdata,
   140         -                                                        const XML_Char *name,
   141         -                                                        const XML_Char **atts));
   142         -static void TclGenExpatElementEndHandler _ANSI_ARGS_((void *userData,
   143         -                                                      const XML_Char *name));
   144         -static void TclGenExpatCharacterDataHandler _ANSI_ARGS_((void *userData,
   145         -                                                         const XML_Char *s,
   146         -                                                         int len));
          136  +static int	TclExpatGet (Tcl_Interp *interp,
          137  +		    TclGenExpatInfo *expat, int objc, Tcl_Obj *const objv[]);
          138  +static void	TclExpatDispatchPCDATA (TclGenExpatInfo *expat);
          139  +static void TclGenExpatElementStartHandler (void *userdata,
          140  +                                            const XML_Char *name,
          141  +                                            const XML_Char **atts);
          142  +static void TclGenExpatElementEndHandler (void *userData,
          143  +                                          const XML_Char *name);
          144  +static void TclGenExpatCharacterDataHandler (void *userData,
          145  +                                             const XML_Char *s,
          146  +                                             int len);
   147    147   
   148         -static void 	TclGenExpatProcessingInstructionHandler _ANSI_ARGS_((
          148  +static void 	TclGenExpatProcessingInstructionHandler (
   149    149   	    	    void *userData, const XML_Char *target,
   150         -	    	    const XML_Char *data));
   151         -static int 	TclGenExpatExternalEntityRefHandler _ANSI_ARGS_((
          150  +	    	    const XML_Char *data);
          151  +static int 	TclGenExpatExternalEntityRefHandler (
   152    152   	    	    XML_Parser parser, const XML_Char *openEntityNames,
   153    153   	    	    const XML_Char *base, const XML_Char *systemId,
   154         -	    	    const XML_Char *publicId));
   155         -static void 	TclGenExpatDefaultHandler _ANSI_ARGS_ ((void *userData,
   156         -	    	    const XML_Char *s, int len));
   157         -static void 	TclGenExpatNotationDeclHandler _ANSI_ARGS_ ((void *userData,
          154  +	    	    const XML_Char *publicId);
          155  +static void 	TclGenExpatDefaultHandler (void *userData,
          156  +	    	    const XML_Char *s, int len);
          157  +static void 	TclGenExpatNotationDeclHandler (void *userData,
   158    158   		    const XML_Char *notationName, const XML_Char *base,
   159         -		    const XML_Char *systemId, const XML_Char *publicId));
   160         -static int	TclGenExpatUnknownEncodingHandler _ANSI_ARGS_ ((
          159  +		    const XML_Char *systemId, const XML_Char *publicId);
          160  +static int	TclGenExpatUnknownEncodingHandler (
   161    161   		    void *encodingHandlerData, const XML_Char *name,
   162         -		    XML_Encoding *info));
          162  +		    XML_Encoding *info);
   163    163   
   164         -static void  TclGenExpatStartNamespaceDeclHandler _ANSI_ARGS_((void *userdata,
   165         -                                                               const XML_Char *prefix,
   166         -                                                               const XML_Char *uri));
   167         -static void  TclGenExpatEndNamespaceDeclHandler _ANSI_ARGS_((void *userData,
   168         -                                                          const XML_Char *prefix));
          164  +static void  TclGenExpatStartNamespaceDeclHandler (void *userdata,
          165  +                                                   const XML_Char *prefix,
          166  +						   const XML_Char *uri);
          167  +static void  TclGenExpatEndNamespaceDeclHandler (void *userData,
          168  +						 const XML_Char *prefix);
   169    169   
   170    170   
   171    171   /* Following added by ericm@scriptics, 1999.6.25 */
   172    172   /* Prototype definition for the TclExpat comment handler */
   173         -static void 	TclGenExpatCommentHandler _ANSI_ARGS_ ((void *userData,
   174         -						     const XML_Char *data));
          173  +static void 	TclGenExpatCommentHandler (void *userData,
          174  +					   const XML_Char *data);
   175    175   /* Prototype for TclExpat Not Standalone Handler */
   176         -static int 	TclGenExpatNotStandaloneHandler _ANSI_ARGS_ ((void *userData));
          176  +static int 	TclGenExpatNotStandaloneHandler (void *userData);
   177    177   
   178    178   /* Prototype for TclExpat {Start|End}CdataSectionHandler */
   179         -static void 	TclGenExpatStartCdataSectionHandler _ANSI_ARGS_((void *userData));
   180         -static void 	TclGenExpatEndCdataSectionHandler _ANSI_ARGS_((void *userData));
          179  +static void 	TclGenExpatStartCdataSectionHandler (void *userData);
          180  +static void 	TclGenExpatEndCdataSectionHandler (void *userData);
   181    181   
   182    182   /* Added by ericm@scriptics.com, 1999.09.13 */
   183    183   /* Prototype for TclExpat (Element|Attlist) Declaration Handlers */
   184         -static void     TclGenExpatElementDeclHandler _ANSI_ARGS_((void *userData,
   185         -                    const XML_Char *name, XML_Content *model));
   186         -static void     TclGenExpatAttlistDeclHandler _ANSI_ARGS_((void *userData,
          184  +static void     TclGenExpatElementDeclHandler (void *userData,
          185  +                    const XML_Char *name, XML_Content *model);
          186  +static void     TclGenExpatAttlistDeclHandler (void *userData,
   187    187                       const XML_Char *elname, const XML_Char *name,
   188    188                       const XML_Char *type, const XML_Char *dflt,
   189         -                    int isrequired));
          189  +                    int isrequired);
   190    190   /* Prototypes for the TclExpat Doctype Decl handlers */
   191         -static void     TclGenExpatStartDoctypeDeclHandler _ANSI_ARGS_((void *userData,
   192         -                    const XML_Char *doctypeName, const XML_Char *sysid,
   193         -                    const XML_Char *pubid, int has_internal_subset));
   194         -static void     TclGenExpatEndDoctypeDeclHandler _ANSI_ARGS_((void *userData));
   195         -static void     TclGenExpatXmlDeclHandler _ANSI_ARGS_((void *userData,
   196         -                                                       const XML_Char *version,
   197         -                                                       const XML_Char *encoding,
   198         -                                                       int standalone));
   199         -static void     TclGenExpatEntityDeclHandler _ANSI_ARGS_((void *userData,
   200         -                                                          const XML_Char *entityname,
   201         -                                                          int is_param,
   202         -                                                          const XML_Char *value,
   203         -                                                          int length,
   204         -                                                          CONST XML_Char *base,
   205         -                                                          CONST XML_Char *systemId,
   206         -                                                          CONST XML_Char *publicId,
   207         -                                                          CONST XML_Char *notationName));
   208         -
          191  +static void     TclGenExpatStartDoctypeDeclHandler (
          192  +    void *userData,
          193  +    const XML_Char *doctypeName,
          194  +    const XML_Char *sysid,
          195  +    const XML_Char *pubid,
          196  +    int has_internal_subset);
          197  +static void     TclGenExpatEndDoctypeDeclHandler (void *userData);
          198  +static void     TclGenExpatXmlDeclHandler (void *userData,
          199  +                                           const XML_Char *version,
          200  +                                           const XML_Char *encoding,
          201  +					   int standalone);
          202  +static void     TclGenExpatEntityDeclHandler (void *userData,
          203  +                                              const XML_Char *entityname,
          204  +                                              int is_param,
          205  +                                              const XML_Char *value,
          206  +                                              int length,
          207  +                                              const XML_Char *base,
          208  +                                              const XML_Char *systemId,
          209  +                                              const XML_Char *publicId,
          210  +					      const XML_Char *notationName);
   209    211   
   210    212   /*
   211    213    *----------------------------------------------------------------------------
   212    214    *
   213    215    * CreateTclHandlerSet --
   214    216    *
   215    217    *	Malloc's and initializes a tclHandlerSet.
................................................................................
   221    223    *	Mallocs memory for the structure and the 'name' field, sets all
   222    224    *      handler scripts to NULL and inits some other fields.
   223    225    *
   224    226    *----------------------------------------------------------------------------
   225    227    */
   226    228   
   227    229   static TclHandlerSet*
   228         -CreateTclHandlerSet (name)
   229         -    char *name;
   230         -{
          230  +CreateTclHandlerSet (
          231  +    char *name
          232  +) {
   231    233       TclHandlerSet *handlerSet;
   232    234   
   233    235       handlerSet = (TclHandlerSet*) MALLOC (sizeof (TclHandlerSet)); \
   234    236       handlerSet->name                      = tdomstrdup (name);
   235    237       handlerSet->ignoreWhiteCDATAs         = 0;
   236    238       handlerSet->status                    = TCL_OK;
   237    239       handlerSet->continueCount             = 0;
................................................................................
   274    276    *	Mallocs memory for the 'name' of the structure, sets all
   275    277    *      handler functions to NULL and inits some other fields.
   276    278    *
   277    279    *----------------------------------------------------------------------------
   278    280    */
   279    281   
   280    282   CHandlerSet*
   281         -CHandlerSetCreate (name)
   282         -    char *name;
   283         -{
          283  +CHandlerSetCreate (
          284  +    char *name
          285  +) {
   284    286       CHandlerSet *handlerSet;
   285    287   
   286    288       handlerSet = (CHandlerSet *) MALLOC (sizeof (CHandlerSet));
   287    289       handlerSet->name                     = tdomstrdup (name);
   288    290       handlerSet->ignoreWhiteCDATAs        = 0;
   289    291       handlerSet->nextHandlerSet           = NULL;
   290    292   
................................................................................
   331    333    * Side effects:
   332    334    *	This creates an expat parser.
   333    335    *
   334    336    *----------------------------------------------------------------------------
   335    337    */
   336    338   
   337    339   int
   338         -TclExpatObjCmd(dummy, interp, objc, objv)
   339         -     ClientData dummy;
   340         -     Tcl_Interp *interp;
   341         -     int objc;
   342         -     Tcl_Obj *CONST objv[];
   343         -{
          340  +TclExpatObjCmd(
          341  +    ClientData dummy,
          342  +    Tcl_Interp *interp,
          343  +    int objc,
          344  +    Tcl_Obj *const objv[]
          345  +) {
   344    346     TclGenExpatInfo *genexpat;
   345    347     int ns_mode = 0;
   346    348     char *nsoption;
   347    349   
   348    350   
   349    351     /*
   350    352      * Create the data structures for this parser.
................................................................................
   429    431    * Side effects:
   430    432    *	Allocates Tcl object.
   431    433    *
   432    434    *----------------------------------------------------------------------------
   433    435    */
   434    436   
   435    437   static Tcl_Obj *
   436         -FindUniqueCmdName(interp)
   437         -     Tcl_Interp *interp;
   438         -{
          438  +FindUniqueCmdName(
          439  +    Tcl_Interp *interp
          440  +) {
   439    441     Tcl_Obj *name;
   440    442     Tcl_CmdInfo info;
   441    443     char s[20];
   442    444   
   443    445     name = Tcl_NewStringObj("", 0);
   444    446     Tcl_IncrRefCount(name);
   445    447   
................................................................................
   472    474    *	Creates or reset an expat parser.
   473    475    *	Modifies TclExpatInfo fields.
   474    476    *
   475    477    *----------------------------------------------------------------------------
   476    478    */
   477    479   
   478    480   static int
   479         -TclExpatInitializeParser(interp, expat, resetOptions)
   480         -     Tcl_Interp      *interp;
   481         -     TclGenExpatInfo *expat;
   482         -     int              resetOptions;
   483         -{
          481  +TclExpatInitializeParser(
          482  +    Tcl_Interp      *interp,
          483  +    TclGenExpatInfo *expat,
          484  +    int              resetOptions
          485  +) {
   484    486       CHandlerSet *activeCHandlerSet;
   485    487       ExpatElemContent *eContent, *eContentSave;
   486    488   
   487    489       if (expat->parser) {
   488    490           XML_ParserReset (expat->parser, NULL);
   489    491           activeCHandlerSet = expat->firstCHandlerSet;
   490    492           while (activeCHandlerSet) {
................................................................................
   549    551       }
   550    552       
   551    553       /*
   552    554        * Set handlers for the parser to routines in this module.
   553    555        */
   554    556   
   555    557       XML_SetElementHandler(expat->parser,
   556         -                          (XML_StartElementHandler) TclGenExpatElementStartHandler,
   557         -                          (XML_EndElementHandler) TclGenExpatElementEndHandler);
          558  +                          TclGenExpatElementStartHandler,
          559  +                          TclGenExpatElementEndHandler);
   558    560       XML_SetNamespaceDeclHandler(expat->parser,
   559         -                                (XML_StartNamespaceDeclHandler) TclGenExpatStartNamespaceDeclHandler,
   560         -                                (XML_EndNamespaceDeclHandler) TclGenExpatEndNamespaceDeclHandler);
          561  +                                TclGenExpatStartNamespaceDeclHandler,
          562  +                                TclGenExpatEndNamespaceDeclHandler);
   561    563       XML_SetCharacterDataHandler(expat->parser,
   562         -                                (XML_CharacterDataHandler) TclGenExpatCharacterDataHandler);
          564  +                                TclGenExpatCharacterDataHandler);
   563    565       XML_SetProcessingInstructionHandler(expat->parser,
   564         -                                        (XML_ProcessingInstructionHandler) TclGenExpatProcessingInstructionHandler);
   565         -    XML_SetDefaultHandlerExpand(expat->parser,
   566         -                                (XML_DefaultHandler) TclGenExpatDefaultHandler);
   567         -    
          566  +                                        TclGenExpatProcessingInstructionHandler);
          567  +    XML_SetDefaultHandlerExpand(expat->parser, TclGenExpatDefaultHandler);
   568    568       XML_SetNotationDeclHandler(expat->parser,
   569         -                               (XML_NotationDeclHandler) TclGenExpatNotationDeclHandler);
          569  +                               TclGenExpatNotationDeclHandler);
   570    570       XML_SetExternalEntityRefHandler(expat->parser,
   571         -                                    (XML_ExternalEntityRefHandler) TclGenExpatExternalEntityRefHandler);
          571  +                                    TclGenExpatExternalEntityRefHandler);
   572    572       XML_SetUnknownEncodingHandler(expat->parser,
   573         -                                  (XML_UnknownEncodingHandler) TclGenExpatUnknownEncodingHandler,
          573  +                                  TclGenExpatUnknownEncodingHandler,
   574    574                                     (void *) expat);
   575         -    
   576         -    
   577    575       XML_SetCommentHandler(expat->parser, TclGenExpatCommentHandler);
   578         -    
   579         -    XML_SetNotStandaloneHandler(expat->parser, TclGenExpatNotStandaloneHandler);
   580         -    
   581         -    XML_SetCdataSectionHandler(expat->parser, TclGenExpatStartCdataSectionHandler,
          576  +    XML_SetNotStandaloneHandler(expat->parser, 
          577  +                                TclGenExpatNotStandaloneHandler);
          578  +    XML_SetCdataSectionHandler(expat->parser, 
          579  +                               TclGenExpatStartCdataSectionHandler,
   582    580                                  TclGenExpatEndCdataSectionHandler);
   583         -    
   584    581       XML_SetElementDeclHandler(expat->parser, TclGenExpatElementDeclHandler);
   585         -    
   586    582       XML_SetAttlistDeclHandler(expat->parser, TclGenExpatAttlistDeclHandler);
   587         -    
   588    583       XML_SetDoctypeDeclHandler(expat->parser,
   589    584                                 TclGenExpatStartDoctypeDeclHandler,
   590    585                                 TclGenExpatEndDoctypeDeclHandler);
   591         -    
   592    586       XML_SetXmlDeclHandler (expat->parser, TclGenExpatXmlDeclHandler);
   593         -    
   594    587       XML_SetEntityDeclHandler (expat->parser,
   595    588                                 TclGenExpatEntityDeclHandler);
   596    589       if (expat->noexpand) {
   597         -        XML_SetDefaultHandlerExpand(expat->parser, NULL);
   598    590           XML_SetDefaultHandler(expat->parser,
   599         -                              (XML_DefaultHandler) TclGenExpatDefaultHandler);
          591  +                              TclGenExpatDefaultHandler);
   600    592       } else {
   601         -        XML_SetDefaultHandler(expat->parser, NULL);
   602    593           XML_SetDefaultHandlerExpand(expat->parser,
   603         -                              (XML_DefaultHandler) TclGenExpatDefaultHandler);
          594  +                                    TclGenExpatDefaultHandler);
   604    595       }
   605    596       
   606    597       XML_SetUserData(expat->parser, (void *) expat);
   607    598       
   608    599       return TCL_OK;
   609    600   }
   610    601   
................................................................................
   623    614    *	Frees any memory allocated for the XML parser and (if still present)
   624    615    *      the stored content models.
   625    616    *
   626    617    *----------------------------------------------------------------------------
   627    618    */
   628    619   
   629    620   static void
   630         -TclExpatFreeParser(expat)
   631         -     TclGenExpatInfo *expat;
   632         -{
          621  +TclExpatFreeParser(
          622  +    TclGenExpatInfo *expat
          623  +) {
   633    624     ExpatElemContent *eContent, *eContentSave;
   634    625   
   635    626     eContent = expat->eContents;
   636    627     while (eContent) {
   637    628         XML_FreeContentModel (expat->parser, eContent->content);
   638    629         eContentSave = eContent;
   639    630         eContent = eContent->next;
................................................................................
   644    635     XML_ParserFree(expat->parser);
   645    636     expat->parser = NULL;
   646    637   }
   647    638   
   648    639   /*
   649    640    *----------------------------------------------------------------------------
   650    641    *
          642  + * CurrentmarkupCommand --
          643  + *
          644  + *	Set as defaultHandler prior to XML_Currentmarkup() call.
          645  + *
          646  + * Results:
          647  + *	None.
          648  + *
          649  + * Side effects:
          650  + *	Stores the markup context in expapt->currentmarkup.
          651  + *
          652  + *----------------------------------------------------------------------------
          653  + */
          654  +static void
          655  +CurrentmarkupCommand (
          656  +    void *userData,
          657  +    const char *s,
          658  +    int len
          659  +) {
          660  +    TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
          661  +
          662  +    if (expat->status != TCL_OK) {
          663  +        return;
          664  +    }
          665  +  
          666  +    if (expat->cdata) {
          667  +        /* TclGenExpatCharacterDataHandler() was called and
          668  +         * initialized expat->cdata, but expat->cdata isn't reset by
          669  +         * TclExpatDispatchPCDATA(), so we're called from
          670  +         * -characterdatacommand and return the empty string by
          671  +         * definition. */
          672  +        expat->currentmarkup = NULL;
          673  +        expat->currentmarkuplen = 0;
          674  +        return;
          675  +    }
          676  +    expat->currentmarkup = s;
          677  +    expat->currentmarkuplen = len;
          678  +    return;
          679  +}
          680  +
          681  +
          682  +
          683  +/*
          684  + *----------------------------------------------------------------------------
          685  + *
   651    686    * TclExpatInstanceCmd --
   652    687    *
   653    688    *	Implements instance command for expat class objects.
   654    689    *
   655    690    * Results:
   656    691    *	Depends on the method.
   657    692    *
................................................................................
   658    693    * Side effects:
   659    694    *	Depends on the method.
   660    695    *
   661    696    *----------------------------------------------------------------------------
   662    697    */
   663    698   
   664    699   static int
   665         -TclExpatInstanceCmd (clientData, interp, objc, objv)
   666         -     ClientData clientData;
   667         -     Tcl_Interp *interp;
   668         -     int objc;
   669         -     Tcl_Obj *CONST objv[];
   670         -{
          700  +TclExpatInstanceCmd (
          701  +    ClientData clientData,
          702  +    Tcl_Interp *interp,
          703  +    int objc,
          704  +    Tcl_Obj *const objv[]
          705  +) {
   671    706     TclGenExpatInfo *expat = (TclGenExpatInfo *) clientData;
   672    707     char *data;
   673    708     int len = 0, optionIndex, result = TCL_OK;
   674    709   
   675         -  static CONST84 char *options[] = {
   676         -      "configure", "cget", "free", "get",
   677         -      "parse", "parsechannel", "parsefile", "reset", NULL
          710  +  static const char *options[] = {
          711  +      "configure", "cget", "currentmarkup", "free", "get",
          712  +      "parse", "parsechannel", "parsefile", "reset", "delete",
          713  +      NULL
   678    714     };
   679    715     enum options {
   680         -      EXPAT_CONFIGURE, EXPAT_CGET, EXPAT_FREE, EXPAT_GET,
   681         -      EXPAT_PARSE, EXPAT_PARSECHANNEL, EXPAT_PARSEFILE, EXPAT_RESET
          716  +      EXPAT_CONFIGURE, EXPAT_CGET, EXPAT_CURRENTMARKUP, EXPAT_FREE, EXPAT_GET,
          717  +      EXPAT_PARSE, EXPAT_PARSECHANNEL, EXPAT_PARSEFILE, EXPAT_RESET,
          718  +      EXPAT_DELETE
   682    719     };
   683    720   
   684    721   
   685    722     if (objc < 2) {
   686    723         Tcl_SetResult (interp, 
   687    724                        "wrong # args: should be \"parserCmd method ?arg ...?\"",
   688    725                        TCL_STATIC);
................................................................................
   707    744   
   708    745       case EXPAT_CGET:
   709    746   
   710    747           CheckArgs (3,5,2, "?-handlerset handlersetname? switch");
   711    748           result = TclExpatCget(interp, expat, objc - 2, objv + 2);
   712    749           break;
   713    750   
          751  +    case EXPAT_CURRENTMARKUP:
          752  +
          753  +        CheckArgs (2,2,1, "");
          754  +        if (expat->parsingState < 2) {
          755  +            Tcl_ResetResult(expat->interp);
          756  +            break;
          757  +        }
          758  +        
          759  +        XML_SetDefaultHandlerExpand(expat->parser,
          760  +                                    CurrentmarkupCommand);
          761  +        XML_DefaultCurrent(expat->parser);
          762  +        if (expat->currentmarkuplen) {
          763  +            Tcl_SetObjResult(expat->interp, 
          764  +                             Tcl_NewStringObj(expat->currentmarkup,
          765  +                                              expat->currentmarkuplen));
          766  +        } else {
          767  +            Tcl_ResetResult(expat->interp);
          768  +        }
          769  +        expat->currentmarkup = NULL;
          770  +        expat->currentmarkuplen = 0;
          771  +        if (expat->noexpand) {
          772  +            XML_SetDefaultHandler(expat->parser,
          773  +                                  TclGenExpatDefaultHandler);
          774  +        } else {
          775  +            XML_SetDefaultHandlerExpand(expat->parser,
          776  +                                        TclGenExpatDefaultHandler);
          777  +        }
          778  +        result = TCL_OK;
          779  +        break;
          780  +
          781  +    case EXPAT_DELETE:
   714    782       case EXPAT_FREE:
   715    783   
   716    784           CheckArgs (2,2,1,"");
   717    785   
   718    786           if (expat->parsingState > 1) {
   719         -            Tcl_SetResult (interp, "parser freeing not allowed from within "
          787  +            Tcl_SetResult (interp, "parser delete not allowed from within "
   720    788                              "callback", TCL_STATIC);
   721    789               result = TCL_ERROR;
   722    790           } else {
   723    791               Tcl_DeleteCommand(interp, Tcl_GetString(expat->name));
   724    792               result = TCL_OK;
   725    793           }
   726    794   	break;
   727    795   
   728    796       case EXPAT_GET:
   729    797   
          798  +        CheckArgs (3,3,2,"<option>");
   730    799           /* ericm@scriptics.com, 1999.6.28 */
   731    800           result = TclExpatGet(interp, expat, objc - 2, objv + 2);
   732    801           break;
   733    802   
   734    803       case EXPAT_PARSE:
   735    804   
   736    805           CheckArgs (3,3,2,"<XML-String>");
................................................................................
   812    881    * Side effects:
   813    882    *     Sets interpreter result as appropriate.
   814    883    *
   815    884    *----------------------------------------------------------------------------
   816    885    */
   817    886   
   818    887   static int
   819         -TclExpatParse (interp, expat, data, len, type)
   820         -     Tcl_Interp *interp;
   821         -     TclGenExpatInfo *expat;
   822         -     char *data;
   823         -     int len;
   824         -     TclExpat_InputType type;
   825         -{
          888  +TclExpatParse (
          889  +    Tcl_Interp *interp,
          890  +    TclGenExpatInfo *expat,
          891  +    char *data,
          892  +    int len,
          893  +    TclExpat_InputType type
          894  +) {
   826    895     int result, mode, done;
   827    896     size_t bytesread;
   828    897     char s[255], buf[8*1024];
   829    898     int fd;
   830    899     XML_Parser  parser;
   831    900     Tcl_Channel channel = NULL;
   832    901     CHandlerSet *activeCHandlerSet;
   833         -#if !TclOnly8Bits
   834    902     Tcl_Obj       *bufObj = NULL;
   835    903     Tcl_DString    dStr;
   836    904     int            useBinary;
   837    905     char          *str;
   838         -#endif
   839    906   
   840    907     if (expat->finished) {
   841    908         if ((result = TclExpatInitializeParser (interp, expat, 0)) != TCL_OK) 
   842    909             return TCL_ERROR;
   843    910     }
   844    911   
   845    912     if (!expat->parsingState) {
................................................................................
   880    947         }
   881    948         if (!(mode & TCL_READABLE)) {
   882    949             Tcl_ResetResult (interp);
   883    950             Tcl_AppendResult (interp, "channel \"", data,
   884    951                               "wasn't opened for reading", (char *) NULL);
   885    952             return TCL_ERROR;
   886    953         }
   887         -#if !TclOnly8Bits
   888    954         Tcl_DStringInit (&dStr);
   889    955         if (Tcl_GetChannelOption (interp, channel, "-encoding", &dStr) 
   890    956             != TCL_OK) {
   891    957             return TCL_ERROR;
   892    958         }
   893    959         if (strcmp (Tcl_DStringValue (&dStr), "binary")==0 ) useBinary = 1;
   894    960         else useBinary = 0;
   895    961         Tcl_DStringFree (&dStr);
   896    962         expat->parsingState = 2;
   897    963         if (useBinary) {
   898    964             do {
   899    965                 bytesread = Tcl_Read (channel, buf, sizeof (buf));
   900    966                 done = bytesread < sizeof (buf);
   901         -              if (done) {
   902         -                  result = XML_Parse (expat->parser, buf, bytesread, done);
   903         -              } else {
   904         -                  if (!XML_Parse (expat->parser, buf, bytesread, done)) {
   905         -                      result = 0;
   906         -                      break;
   907         -                  }
   908         -              }
          967  +              result = XML_Parse (expat->parser, buf, bytesread, done);
          968  +              if (result != XML_STATUS_OK) break;
   909    969             } while (!done);
   910    970         } else {
   911    971             bufObj = Tcl_NewObj();
   912    972             Tcl_IncrRefCount (bufObj);
   913    973             Tcl_SetObjLength (bufObj, 6144);
   914    974             do {
   915    975                 len = Tcl_ReadChars (channel, bufObj, 1024, 0);
   916    976                 done = (len < 1024);
   917    977                 str = Tcl_GetStringFromObj (bufObj, &len);
   918         -              if (!XML_Parse (expat->parser, str, len, done)) {
   919         -                  result = 0;
   920         -                  break;
   921         -              }
          978  +              result = XML_Parse (expat->parser, str, len, done);
          979  +              if (result != XML_STATUS_OK) break;
   922    980             } while (!done);
   923    981             /* In case of a parsing error we need the string rep of the
   924    982                bufObj until the error reporting is done (otherwise,
   925    983                calling XML_GetCurrentLineNumber() results in invalid mem
   926    984                reads */
   927    985             if (result) {
   928    986                 Tcl_DecrRefCount (bufObj);
   929    987             }
   930    988         }
   931         -#else
   932         -      expat->parsingState = 2;
   933         -      do {
   934         -          bytesread = Tcl_Read (channel, buf, sizeof (buf));
   935         -          done = bytesread < sizeof (buf);
   936         -          if (done) {
   937         -              result = XML_Parse (expat->parser, buf, bytesread, done);
   938         -          } else {
   939         -              if (!XML_Parse (expat->parser, buf, bytesread, done)) {
   940         -                  result = 0;
   941         -                      break;
   942         -              }
   943         -          }
   944         -      } while (!done);
   945         -#endif /* !TclOnly8Bits */
   946    989         expat->parsingState = 1;
   947    990         break;
   948    991   
   949    992     case EXPAT_INPUT_FILENAME:
   950    993         fd = open(data, O_BINARY|O_RDONLY);
   951    994         if (fd < 0) {
   952    995             Tcl_ResetResult (interp);
................................................................................
   954    997                               data, "\"", (char *) NULL);
   955    998             return TCL_ERROR;
   956    999         }
   957   1000         parser = expat->parser;
   958   1001         expat->parsingState = 2;
   959   1002         for (;;) {
   960   1003             int nread;
   961         -          char *fbuf = XML_GetBuffer (parser, READ_SIZE);
         1004  +          char *fbuf = XML_GetBuffer (parser, TDOM_EXPAT_READ_SIZE);
   962   1005             if (!fbuf) {
   963   1006                 close (fd);
   964   1007                 Tcl_ResetResult (interp);
   965   1008                 Tcl_SetResult (interp, "Out of memory\n", NULL);
   966   1009                 expat->parsingState = 1;
   967   1010                 return TCL_ERROR;
   968   1011             }
   969         -          nread = read(fd, fbuf, READ_SIZE);
         1012  +          nread = read(fd, fbuf, TDOM_EXPAT_READ_SIZE);
   970   1013             if (nread < 0) {
   971   1014                 close (fd);
   972   1015                 Tcl_ResetResult (interp);
   973   1016                 Tcl_AppendResult (interp, "error reading from file \"",
   974   1017                                   data, "\"", (char *) NULL);
   975   1018                 expat->parsingState = 1;
   976   1019                 return TCL_ERROR;
   977   1020             }
   978         -          if (!XML_ParseBuffer (parser, nread, nread == 0)) {
         1021  +          result = XML_ParseBuffer (parser, nread, nread == 0);
         1022  +          if (result != XML_STATUS_OK || !nread) {
   979   1023                 close (fd);
   980         -              result = 0;
   981         -              break;
   982         -          }
   983         -          if (nread == 0) {
   984         -              close(fd);
   985   1024                 break;
   986   1025             }
   987   1026         }
   988   1027         expat->parsingState = 1;
   989   1028         break;
   990   1029     }
   991   1030   
................................................................................
   998   1037             sprintf(s, "%ld", XML_GetCurrentLineNumber(expat->parser));
   999   1038             Tcl_AppendResult(interp, "error \"",
  1000   1039                              XML_ErrorString(XML_GetErrorCode(expat->parser)),
  1001   1040                              "\" at line ", s, " character ", NULL);
  1002   1041             sprintf(s, "%ld", XML_GetCurrentColumnNumber(expat->parser));
  1003   1042             Tcl_AppendResult(interp, s, NULL);
  1004   1043         }
  1005         -#if !TclOnly8Bits
  1006   1044         if (bufObj) {
  1007   1045             Tcl_DecrRefCount (bufObj);
  1008   1046         }
  1009         -#endif
  1010   1047         return TCL_ERROR;
  1011   1048     }
  1012   1049     switch (expat->status) {
  1013   1050       case TCL_OK:
  1014   1051       case TCL_BREAK:
  1015   1052       case TCL_CONTINUE:
         1053  +    case TCL_RETURN:
  1016   1054         Tcl_ResetResult(interp);
  1017   1055         return TCL_OK;
  1018   1056   
  1019   1057       case TCL_ERROR:
  1020   1058         Tcl_SetObjResult(interp, expat->result);
  1021   1059         return TCL_ERROR;
  1022   1060   
................................................................................
  1043   1081    * Side effects:
  1044   1082    *	Depends on the method.
  1045   1083    *
  1046   1084    *----------------------------------------------------------------------------
  1047   1085    */
  1048   1086   
  1049   1087   static int
  1050         -TclExpatConfigure (interp, expat, objc, objv)
  1051         -     Tcl_Interp *interp;
  1052         -     TclGenExpatInfo *expat;
  1053         -     int objc;
  1054         -     Tcl_Obj *CONST objv[];
  1055         -{
  1056         -  static CONST84 char *switches[] = {
         1088  +TclExpatConfigure (
         1089  +    Tcl_Interp *interp,
         1090  +    TclGenExpatInfo *expat,
         1091  +    int objc,
         1092  +    Tcl_Obj *const objv[]
         1093  +) {
         1094  +  static const char *switches[] = {
  1057   1095       "-final",
  1058   1096       "-baseurl",
  1059   1097       "-elementstartcommand",
  1060   1098       "-elementendcommand",
  1061   1099       "-characterdatacommand",
  1062   1100       "-processinginstructioncommand",
  1063   1101       "-defaultcommand",
................................................................................
  1104   1142       EXPAT_XMLDECLCMD,
  1105   1143       EXPAT_PARAMENTITYPARSING,
  1106   1144       EXPAT_ENTITYDECLCOMMAND,
  1107   1145       EXPAT_NOWHITESPACE,
  1108   1146       EXPAT_HANDLERSET,
  1109   1147       EXPAT_NOEXPAND
  1110   1148     };
  1111         -  static CONST84 char *paramEntityParsingValues[] = {
         1149  +  static const char *paramEntityParsingValues[] = {
  1112   1150         "always",
  1113   1151         "never",
  1114   1152         "notstandalone",
  1115   1153         (char *) NULL
  1116   1154     };
  1117   1155     enum paramEntityParsingValues {
  1118   1156         EXPAT_PARAMENTITYPARSINGALWAYS,
  1119   1157         EXPAT_PARAMENTITYPARSINGNEVER,
  1120   1158         EXPAT_PARAMENTITYPARSINGNOTSTANDALONE
  1121   1159     };
  1122   1160     int optionIndex, value, bool;
  1123         -  Tcl_Obj *CONST *objPtr = objv;
         1161  +  Tcl_Obj *const *objPtr = objv;
  1124   1162     Tcl_CmdInfo cmdInfo;
  1125   1163     int rc;
  1126   1164     char *handlerSetName = NULL;
  1127   1165     TclHandlerSet *tmpTclHandlerSet, *activeTclHandlerSet = NULL;
  1128   1166   
  1129   1167     if (expat->firstTclHandlerSet 
  1130   1168         && (strcmp ("default", expat->firstTclHandlerSet->name)==0)) {
................................................................................
  1173   1211   	Tcl_IncrRefCount(activeTclHandlerSet->elementstartcommand);
  1174   1212           rc = Tcl_GetCommandInfo(interp, Tcl_GetString(objPtr[1]), &cmdInfo);
  1175   1213           if (rc && cmdInfo.isNativeObjectProc) {
  1176   1214               activeTclHandlerSet->elementstartObjProc = cmdInfo.objProc;
  1177   1215               activeTclHandlerSet->elementstartclientData 
  1178   1216                   = cmdInfo.objClientData;
  1179   1217           } else {
  1180         -            /* hmoreau 22 May 2003 */
  1181   1218               activeTclHandlerSet->elementstartObjProc = NULL;
  1182   1219           }
  1183   1220   	break;
  1184   1221   
  1185   1222         case EXPAT_ELEMENTENDCMD:		/* -elementendcommand */
  1186   1223   
  1187   1224           CheckDefaultTclHandlerSet;
................................................................................
  1192   1229   	activeTclHandlerSet->elementendcommand = objPtr[1];
  1193   1230   	Tcl_IncrRefCount(activeTclHandlerSet->elementendcommand);
  1194   1231           rc = Tcl_GetCommandInfo(interp, Tcl_GetString(objPtr[1]), &cmdInfo);
  1195   1232           if (rc && cmdInfo.isNativeObjectProc) {
  1196   1233               activeTclHandlerSet->elementendObjProc = cmdInfo.objProc;
  1197   1234               activeTclHandlerSet->elementendclientData = cmdInfo.objClientData;
  1198   1235           } else {
  1199         -            /* hmoreau 22 May 2003 */
  1200   1236               activeTclHandlerSet->elementendObjProc = NULL;
  1201   1237           }
  1202   1238   	break;
  1203   1239   
  1204   1240         case EXPAT_STARTNAMESPACEDECLCMD:	/* -startnamespacedeclcommand */
  1205   1241   
  1206   1242           CheckDefaultTclHandlerSet;
................................................................................
  1235   1271   	activeTclHandlerSet->datacommand = objPtr[1];
  1236   1272   	Tcl_IncrRefCount(activeTclHandlerSet->datacommand);
  1237   1273           rc = Tcl_GetCommandInfo (interp, Tcl_GetString(objPtr[1]), &cmdInfo);
  1238   1274           if (rc && cmdInfo.isNativeObjectProc) {
  1239   1275               activeTclHandlerSet->datacommandObjProc = cmdInfo.objProc;
  1240   1276               activeTclHandlerSet->datacommandclientData = cmdInfo.objClientData;
  1241   1277           } else {
  1242         -            /* hmoreau 22 May 2003 */
  1243   1278               activeTclHandlerSet->datacommandObjProc = NULL;
  1244   1279           }
  1245   1280   	break;
  1246   1281   
  1247   1282         case EXPAT_PICMD:			/* -processinginstructioncommand */
  1248   1283   
  1249   1284           CheckDefaultTclHandlerSet;
................................................................................
  1502   1537           break;
  1503   1538   
  1504   1539       case EXPAT_NOEXPAND:
  1505   1540           if (Tcl_GetBooleanFromObj (interp, objv[1], &bool) != TCL_OK) {
  1506   1541               return TCL_ERROR;
  1507   1542           }
  1508   1543           if (bool) {
  1509         -            XML_SetDefaultHandlerExpand(expat->parser, NULL);
  1510         -            XML_SetDefaultHandler(expat->parser,
  1511         -                        (XML_DefaultHandler) TclGenExpatDefaultHandler);
  1512         -        }
  1513         -        else {
  1514         -            XML_SetDefaultHandler(expat->parser, NULL);
  1515         -            XML_SetDefaultHandlerExpand(expat->parser,
  1516         -                        (XML_DefaultHandler) TclGenExpatDefaultHandler);
         1544  +            XML_SetDefaultHandler( expat->parser,
         1545  +                                   TclGenExpatDefaultHandler);
         1546  +        } else {
         1547  +            XML_SetDefaultHandlerExpand( expat->parser,
         1548  +                                         TclGenExpatDefaultHandler);
  1517   1549           }
  1518   1550           expat->noexpand = bool;
  1519   1551           break;
  1520   1552   
  1521   1553       }
  1522   1554   
  1523   1555       objPtr += 2;
................................................................................
  1541   1573    * Side effects:
  1542   1574    *	None.
  1543   1575    *
  1544   1576    *----------------------------------------------------------------------------
  1545   1577    */
  1546   1578   
  1547   1579   static int
  1548         -TclExpatCget (interp, expat, objc, objv)
  1549         -     Tcl_Interp *interp;
  1550         -     TclGenExpatInfo *expat;
  1551         -     int objc;
  1552         -     Tcl_Obj *CONST objv[];
  1553         -{
  1554         -    static CONST84 char *switches[] = {
         1580  +TclExpatCget (
         1581  +    Tcl_Interp *interp,
         1582  +    TclGenExpatInfo *expat,
         1583  +    int objc,
         1584  +    Tcl_Obj *const objv[]
         1585  +) {
         1586  +    static const char *switches[] = {
  1555   1587           "-final",
  1556   1588           "-baseurl",
  1557   1589           "-elementstartcommand",
  1558   1590           "-elementendcommand",
  1559   1591           "-characterdatacommand",
  1560   1592           "-processinginstructioncommand",
  1561   1593           "-defaultcommand",
................................................................................
  1943   1975    *
  1944   1976    * Side effects:
  1945   1977    *	None.
  1946   1978    *
  1947   1979    *----------------------------------------------------------------------------
  1948   1980    */
  1949   1981   static int
  1950         -TclExpatGet (interp, expat, objc, objv)
  1951         -     Tcl_Interp *interp;
  1952         -     TclGenExpatInfo *expat;
  1953         -     int objc;
  1954         -     Tcl_Obj *CONST objv[];
         1982  +TclExpatGet (
         1983  +    Tcl_Interp *interp,
         1984  +    TclGenExpatInfo *expat,
         1985  +    int objc,
         1986  +    Tcl_Obj *const objv[]
         1987  +)
  1955   1988   {
  1956         -  static CONST84 char *getSwitches[] = {
         1989  +  static const char *getSwitches[] = {
  1957   1990       "-specifiedattributecount",
  1958   1991       "-currentbytecount",
  1959   1992       "-currentlinenumber",
  1960   1993       "-currentcolumnnumber",
  1961   1994       "-currentbyteindex",
  1962   1995       (char *) NULL
  1963   1996     };
................................................................................
  1967   2000       EXPAT_CURRENTLINENUMBER,
  1968   2001       EXPAT_CURRENTCOLUMNNUMBER,
  1969   2002       EXPAT_CURRENTBYTEINDEX
  1970   2003     };
  1971   2004     int switchIndex;
  1972   2005     Tcl_Obj *resultPtr;
  1973   2006   
  1974         -  if (objc > 1) {
  1975         -    Tcl_SetResult(interp, "Only one value may be requested at a time",
  1976         -		  TCL_STATIC);
  1977         -    return TCL_ERROR;
  1978         -  }
  1979         -
  1980   2007     if (Tcl_GetIndexFromObj(interp, objv[0], getSwitches,
  1981   2008   			  "switch", 0, &switchIndex) != TCL_OK) {
  1982   2009       return TCL_ERROR;
  1983   2010     }
  1984   2011     resultPtr = Tcl_GetObjResult(interp);
  1985   2012   
  1986   2013     switch ((enum getSwitch) switchIndex) {
................................................................................
  2029   2056    * Side Effects:
  2030   2057    *	Further invocation of callback scripts may be inhibited.
  2031   2058    *
  2032   2059    *----------------------------------------------------------------------------
  2033   2060    */
  2034   2061   
  2035   2062   static void
  2036         -TclExpatHandlerResult(expat, handlerSet, result)
  2037         -     TclGenExpatInfo *expat;
  2038         -     TclHandlerSet *handlerSet;
  2039         -     int result;
  2040         -{
         2063  +TclExpatHandlerResult(
         2064  +    TclGenExpatInfo *expat,
         2065  +    TclHandlerSet *handlerSet,
         2066  +    int result
         2067  +) {
  2041   2068     switch (result) {
  2042   2069       case TCL_OK:
  2043   2070         handlerSet->status = TCL_OK;
         2071  +      Tcl_ResetResult (expat->interp);
  2044   2072         break;
  2045   2073   
  2046   2074       case TCL_CONTINUE:
  2047   2075         /*
  2048   2076          * Skip callbacks until the matching end element event
  2049   2077          * occurs for the currently open element.
  2050   2078          * Keep a reference count to handle nested
  2051   2079          * elements.
  2052   2080          */
  2053   2081         handlerSet->status = TCL_CONTINUE;
  2054   2082         handlerSet->continueCount = 1;
         2083  +      Tcl_ResetResult (expat->interp);
  2055   2084         break;
  2056   2085   
  2057   2086       case TCL_BREAK:
  2058   2087         /*
  2059         -       * Skip all further callbacks, but return OK.
         2088  +       * Skip all further callbacks of this handlerSet, but return OK.
  2060   2089          */
  2061   2090         handlerSet->status = TCL_BREAK;
         2091  +      Tcl_ResetResult (expat->interp);
  2062   2092         break;
  2063   2093   
  2064   2094       case TCL_ERROR:
  2065   2095         /*
  2066         -       * Skip all further callbacks, and return error.
         2096  +       * Cancel parsing and return error.
  2067   2097          */
  2068   2098         expat->status = TCL_ERROR;
         2099  +      XML_StopParser (expat->parser, 1);
  2069   2100         expat->result = Tcl_GetObjResult(expat->interp);
  2070   2101         Tcl_IncrRefCount(expat->result);
  2071   2102         break;
         2103  +
         2104  +    case TCL_RETURN:
         2105  +      /*
         2106  +       * Cancel parser and return OK.
         2107  +       */
         2108  +      expat->status = TCL_RETURN;
         2109  +      XML_StopParser (expat->parser, 1);
         2110  +      expat->result = Tcl_NewObj ();
         2111  +      Tcl_IncrRefCount(expat->result);
         2112  +      break;
  2072   2113         
  2073   2114       default:
  2074   2115         /*
  2075         -       * Skip all further callbacks, set return value and return error.
         2116  +       * Cancel parser and return the error code.
  2076   2117          */
  2077   2118         expat->status = result;
         2119  +      XML_StopParser (expat->parser, 1);
  2078   2120         expat->result = Tcl_GetObjResult(expat->interp);
  2079   2121         Tcl_IncrRefCount(expat->result);
  2080   2122         break;
  2081   2123     }
  2082   2124   }
  2083   2125   
  2084   2126   /*
................................................................................
  2094   2136    * Side Effects:
  2095   2137    *	Callback scripts are invoked.
  2096   2138    *
  2097   2139    *----------------------------------------------------------------------------
  2098   2140    */
  2099   2141   
  2100   2142   static void
  2101         -TclGenExpatElementStartHandler(userData, name, atts)
  2102         -     void *userData;
  2103         -     const char *name;
  2104         -     const char **atts;
  2105         -{
         2143  +TclGenExpatElementStartHandler(
         2144  +    void *userData,
         2145  +    const char *name,
         2146  +    const char **atts
         2147  +) {
  2106   2148     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  2107   2149     Tcl_Obj *atList = NULL;
  2108   2150     const char **atPtr;
  2109   2151     int result;
  2110   2152     Tcl_Obj *vector[3];
  2111   2153     TclHandlerSet *activeTclHandlerSet;
  2112   2154     CHandlerSet *activeCHandlerSet;
................................................................................
  2179   2221                 cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->elementstartcommand);
  2180   2222                 Tcl_IncrRefCount(cmdPtr);
  2181   2223                 Tcl_Preserve((ClientData) expat->interp);
  2182   2224   
  2183   2225                 Tcl_ListObjAppendElement(expat->interp, cmdPtr,
  2184   2226                                          Tcl_NewStringObj((char *)name, -1));
  2185   2227                 Tcl_ListObjAppendElement(expat->interp, cmdPtr, atList);
  2186         -
  2187         -              /*
  2188         -               * It would be desirable to be able to terminate parsing
  2189         -               * if the return result is TCL_ERROR or TCL_BREAK.
  2190         -               */
  2191   2228   #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
  2192   2229                 result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
  2193   2230   #else
  2194   2231                 result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
  2195   2232                                        TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
  2196   2233   #endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */
  2197   2234   
................................................................................
  2234   2271    * Side Effects:
  2235   2272    *	Callback scripts are invoked.
  2236   2273    *
  2237   2274    *----------------------------------------------------------------------------
  2238   2275    */
  2239   2276   
  2240   2277   static void
  2241         -TclGenExpatElementEndHandler(userData, name)
  2242         -     void *userData;
  2243         -     CONST char *name;
  2244         -{
         2278  +TclGenExpatElementEndHandler(
         2279  +    void *userData,
         2280  +    const char *name
         2281  +) {
  2245   2282     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  2246   2283     int result;
  2247   2284     Tcl_Obj *vector[2], *ename = NULL;
  2248   2285     TclHandlerSet *activeTclHandlerSet;
  2249   2286     CHandlerSet *activeCHandlerSet;
  2250   2287     Tcl_Obj      *cmdPtr;
  2251   2288   
................................................................................
  2304   2341   
  2305   2342                 cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->elementendcommand);
  2306   2343                 Tcl_IncrRefCount(cmdPtr);
  2307   2344                 Tcl_Preserve((ClientData) expat->interp);
  2308   2345   
  2309   2346                 Tcl_ListObjAppendElement(expat->interp, cmdPtr,
  2310   2347                                          Tcl_NewStringObj((char *)name, -1));
  2311         -
  2312         -              /*
  2313         -               * It would be desirable to be able to terminate parsing
  2314         -               * if the return result is TCL_ERROR or TCL_BREAK.
  2315         -               */
  2316   2348   #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
  2317   2349                 result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
  2318   2350   #else
  2319   2351                 result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
  2320   2352                                        TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT );
  2321   2353   #endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */
  2322   2354   
................................................................................
  2359   2391    * Side Effects:
  2360   2392    *	Callback scripts are invoked.
  2361   2393    *
  2362   2394    *----------------------------------------------------------------------------
  2363   2395    */
  2364   2396   
  2365   2397   static void
  2366         -TclGenExpatStartNamespaceDeclHandler(userData, prefix, uri)
  2367         -     void       *userData;
  2368         -     const char *prefix;
  2369         -     const char *uri;
  2370         -{
         2398  +TclGenExpatStartNamespaceDeclHandler(
         2399  +    void       *userData,
         2400  +    const char *prefix,
         2401  +    const char *uri
         2402  +) {
  2371   2403     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  2372   2404     Tcl_Obj      *cmdPtr;
  2373   2405     int           result;
  2374   2406     TclHandlerSet *activeTclHandlerSet;
  2375   2407     CHandlerSet *activeCHandlerSet;
  2376   2408   
  2377   2409     if (expat->status != TCL_OK) {
................................................................................
  2410   2442         Tcl_IncrRefCount(cmdPtr);
  2411   2443         Tcl_Preserve((ClientData) expat->interp);
  2412   2444   
  2413   2445         Tcl_ListObjAppendElement(expat->interp, cmdPtr,
  2414   2446                                  Tcl_NewStringObj((char *)prefix, -1));
  2415   2447         Tcl_ListObjAppendElement(expat->interp, cmdPtr,
  2416   2448                                  Tcl_NewStringObj((char *)uri,    -1));
  2417         -
  2418         -      /*
  2419         -       * It would be desirable to be able to terminate parsing
  2420         -       * if the return result is TCL_ERROR or TCL_BREAK.
  2421         -       */
  2422   2449   #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
  2423   2450         result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
  2424   2451   #else
  2425   2452         result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
  2426   2453                                TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
  2427   2454   #endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */
  2428   2455   
................................................................................
  2459   2486    * Side Effects:
  2460   2487    *	Callback scripts are invoked.
  2461   2488    *
  2462   2489    *----------------------------------------------------------------------------
  2463   2490    */
  2464   2491   
  2465   2492   static void
  2466         -TclGenExpatEndNamespaceDeclHandler(userData, prefix)
  2467         -     void       *userData;
  2468         -     CONST char *prefix;
  2469         -{
         2493  +TclGenExpatEndNamespaceDeclHandler(
         2494  +    void       *userData,
         2495  +    const char *prefix
         2496  +) {
  2470   2497     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  2471   2498     Tcl_Obj *cmdPtr;
  2472   2499     int result;
  2473   2500     TclHandlerSet *activeTclHandlerSet;
  2474   2501     CHandlerSet *activeCHandlerSet;
  2475   2502   
  2476   2503     if (expat->status != TCL_OK) {
................................................................................
  2508   2535          */
  2509   2536   
  2510   2537         cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->endnsdeclcommand);
  2511   2538         Tcl_IncrRefCount(cmdPtr);
  2512   2539         Tcl_Preserve((ClientData) expat->interp);
  2513   2540   
  2514   2541         Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)prefix, -1));
  2515         -
  2516         -      /*
  2517         -       * It would be desirable to be able to terminate parsing
  2518         -       * if the return result is TCL_ERROR or TCL_BREAK.
  2519         -       */
  2520   2542   #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
  2521   2543         result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
  2522   2544   #else
  2523   2545         result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
  2524   2546                                TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
  2525   2547   #endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */
  2526   2548   
................................................................................
  2554   2576    * Results:
  2555   2577    *	1 if string contains just white characters
  2556   2578    *
  2557   2579    *----------------------------------------------------------------------------
  2558   2580    */
  2559   2581   
  2560   2582   static int
  2561         -TclExpatCheckWhiteData (pc, len)
  2562         -     char         *pc;
  2563         -     int           len;
  2564         -{
         2583  +TclExpatCheckWhiteData (
         2584  +    char         *pc,
         2585  +    int           len
         2586  +) {
  2565   2587       for (; len > 0; len--, pc++) {
  2566   2588           if ( (*pc != ' ')  &&
  2567   2589                (*pc != '\t') &&
  2568   2590                (*pc != '\n') &&
  2569   2591                (*pc != '\r') ) {
  2570   2592               return 0;
  2571   2593           }
................................................................................
  2587   2609    * Side Effects:
  2588   2610    *	Callback script is invoked.
  2589   2611    *
  2590   2612    *----------------------------------------------------------------------------
  2591   2613    */
  2592   2614   
  2593   2615   static void
  2594         -TclGenExpatCharacterDataHandler(userData, s, len)
  2595         -     void *userData;
  2596         -     CONST char *s;
  2597         -     int len;
  2598         -{
         2616  +TclGenExpatCharacterDataHandler(
         2617  +    void *userData,
         2618  +    const char *s,
         2619  +    int len
         2620  +) {
  2599   2621     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  2600   2622   
  2601   2623     if (expat->status != TCL_OK) {
  2602   2624         return;
  2603   2625     }
  2604   2626   
  2605   2627     if (!expat->cdata) {
................................................................................
  2624   2646    * Side Effects:
  2625   2647    *	Callback script evaluated.
  2626   2648    *
  2627   2649    *----------------------------------------------------------------------------
  2628   2650    */
  2629   2651   
  2630   2652   static void
  2631         -TclExpatDispatchPCDATA(expat)
  2632         -     TclGenExpatInfo *expat;
  2633         -{
         2653  +TclExpatDispatchPCDATA(
         2654  +    TclGenExpatInfo *expat
         2655  +) {
  2634   2656     int len, result, onlyWhiteSpace = 0;
  2635   2657     Tcl_Obj *vector[2];
  2636   2658     TclHandlerSet *activeTclHandlerSet;
  2637   2659     CHandlerSet *activeCHandlerSet;
  2638   2660     Tcl_Obj* cmdPtr;
  2639   2661     char *s;
  2640   2662   
................................................................................
  2690   2712              */
  2691   2713             cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->datacommand);
  2692   2714             Tcl_IncrRefCount(cmdPtr);
  2693   2715             Tcl_Preserve((ClientData) expat->interp);
  2694   2716   
  2695   2717             Tcl_ListObjAppendElement(expat->interp, cmdPtr,
  2696   2718                                      Tcl_NewStringObj((char *)s, len));
  2697         -
  2698         -          /*
  2699         -           * It would be desirable to be able to terminate parsing
  2700         -           * if the return result is TCL_ERROR or TCL_BREAK.
  2701         -           */
  2702   2719   #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
  2703   2720             result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
  2704   2721   #else
  2705   2722             result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
  2706   2723                                    TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
  2707   2724   #endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */
  2708   2725   
................................................................................
  2725   2742                 activeCHandlerSet->datacommand (activeCHandlerSet->userData,
  2726   2743                                                 s, len);
  2727   2744             }
  2728   2745         }
  2729   2746         activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  2730   2747     }
  2731   2748     Tcl_DecrRefCount (expat->cdata);
  2732         -  expat->cdata = 0;
         2749  +  expat->cdata = NULL;
  2733   2750     return;
  2734   2751   }
  2735   2752   
  2736   2753   
  2737   2754   /*
  2738   2755    *----------------------------------------------------------------------------
  2739   2756    *
................................................................................
  2747   2764    * Side Effects:
  2748   2765    *	Callback scripts are invoked.
  2749   2766    *
  2750   2767    *----------------------------------------------------------------------------
  2751   2768    */
  2752   2769   
  2753   2770   static void
  2754         -TclGenExpatProcessingInstructionHandler(userData, target, data)
  2755         -     void *userData;
  2756         -     CONST char *target;
  2757         -     CONST char *data;
  2758         -{
         2771  +TclGenExpatProcessingInstructionHandler(
         2772  +    void *userData,
         2773  +    const char *target,
         2774  +    const char *data
         2775  +) {
  2759   2776     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  2760   2777     Tcl_Obj *cmdPtr;
  2761   2778     int result;
  2762   2779     TclHandlerSet *activeTclHandlerSet;
  2763   2780     CHandlerSet *activeCHandlerSet;
  2764   2781   
  2765   2782     if (expat->status != TCL_OK) {
................................................................................
  2790   2807   
  2791   2808         cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->picommand);
  2792   2809         Tcl_IncrRefCount(cmdPtr);
  2793   2810         Tcl_Preserve((ClientData) expat->interp);
  2794   2811   
  2795   2812         Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)target, strlen(target)));
  2796   2813         Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)data, strlen(data)));
  2797         -
  2798         -      /*
  2799         -       * It would be desirable to be able to terminate parsing
  2800         -       * if the return result is TCL_ERROR or TCL_BREAK.
  2801         -       */
  2802   2814   #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
  2803   2815         result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
  2804   2816   #else
  2805   2817         result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
  2806   2818                                TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
  2807   2819   #endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */
  2808   2820   
................................................................................
  2838   2850    * Side Effects:
  2839   2851    *	Callback scripts are invoked.
  2840   2852    *
  2841   2853    *----------------------------------------------------------------------------
  2842   2854    */
  2843   2855   
  2844   2856   static void
  2845         -TclGenExpatDefaultHandler(userData, s, len)
  2846         -     void *userData;
  2847         -     CONST char *s;
  2848         -     int len;
  2849         -{
         2857  +TclGenExpatDefaultHandler(
         2858  +    void *userData,
         2859  +    const char *s,
         2860  +    int len
         2861  +) {
  2850   2862     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  2851   2863     Tcl_Obj *cmdPtr;
  2852   2864     int result;
  2853   2865     TclHandlerSet *activeTclHandlerSet;
  2854   2866     CHandlerSet *activeCHandlerSet;
  2855   2867   
  2856   2868     TclExpatDispatchPCDATA(expat);
................................................................................
  2880   2892          */
  2881   2893   
  2882   2894         cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->defaultcommand);
  2883   2895         Tcl_IncrRefCount(cmdPtr);
  2884   2896         Tcl_Preserve((ClientData) expat->interp);
  2885   2897   
  2886   2898         Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)s, len));
  2887         -
  2888         -      /*
  2889         -       * It would be desirable to be able to terminate parsing
  2890         -       * if the return result is TCL_ERROR or TCL_BREAK.
  2891         -       */
  2892   2899   #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
  2893   2900         result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
  2894   2901   #else
  2895   2902         result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
  2896   2903                                TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
  2897   2904   #endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */
  2898   2905   
................................................................................
  2929   2936    * Side Effects:
  2930   2937    *	Callback scripts are invoked.
  2931   2938    *
  2932   2939    *----------------------------------------------------------------------------
  2933   2940    */
  2934   2941   
  2935   2942   static void
  2936         -TclGenExpatEntityDeclHandler(userData, entityname, is_param, value, length, base, systemId, publicId, notationName)
  2937         -     void *userData;
  2938         -     CONST char *entityname;
  2939         -     int         is_param;
  2940         -     CONST char *value;
  2941         -     int         length;
  2942         -     CONST char *base;
  2943         -     CONST char *systemId;
  2944         -     CONST char *publicId;
  2945         -     CONST char *notationName;
  2946         -{
         2943  +TclGenExpatEntityDeclHandler(
         2944  +    void *userData,
         2945  +    const char *entityname,
         2946  +    int         is_param,
         2947  +    const char *value,
         2948  +    int         length,
         2949  +    const char *base,
         2950  +    const char *systemId,
         2951  +    const char *publicId,
         2952  +    const char *notationName
         2953  +) {
  2947   2954     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  2948   2955     Tcl_Obj *cmdPtr;
  2949   2956     int result;
  2950   2957     TclHandlerSet *activeTclHandlerSet;
  2951   2958     CHandlerSet *activeCHandlerSet;
  2952   2959   
  2953   2960     TclExpatDispatchPCDATA(expat);
................................................................................
  3005   3012             Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)publicId, strlen(publicId)));
  3006   3013         }
  3007   3014         if (notationName == NULL) {
  3008   3015             Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewListObj(0, NULL));
  3009   3016         } else {
  3010   3017             Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)notationName, strlen(notationName)));
  3011   3018         }
  3012         -
  3013         -      /*
  3014         -       * It would be desirable to be able to terminate parsing
  3015         -       * if the return result is TCL_ERROR or TCL_BREAK.
  3016         -       */
  3017   3019   #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
  3018   3020         result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
  3019   3021   #else
  3020   3022         result = Tcl_EvalObjEx(expat->interp, cmdPtr,
  3021   3023                                TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
  3022   3024   #endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */
  3023   3025   
................................................................................
  3055   3057    * Side Effects:
  3056   3058    *	Callback scripts are invoked.
  3057   3059    *
  3058   3060    *----------------------------------------------------------------------------
  3059   3061    */
  3060   3062   
  3061   3063   static void
  3062         -TclGenExpatNotationDeclHandler(userData, notationName, base, systemId, publicId)
  3063         -     void *userData;
  3064         -     CONST char *notationName;
  3065         -     CONST char *base;
  3066         -     CONST char *systemId;
  3067         -     CONST char *publicId;
  3068         -{
         3064  +TclGenExpatNotationDeclHandler(
         3065  +    void *userData,
         3066  +    const char *notationName,
         3067  +    const char *base,
         3068  +    const char *systemId,
         3069  +    const char *publicId
         3070  +) {
  3069   3071     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  3070   3072     Tcl_Obj *cmdPtr;
  3071   3073     int result;
  3072   3074     TclHandlerSet *activeTclHandlerSet;
  3073   3075     CHandlerSet *activeCHandlerSet;
  3074   3076   
  3075   3077     TclExpatDispatchPCDATA(expat);
................................................................................
  3109   3111             Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)systemId, strlen(systemId)));
  3110   3112         }
  3111   3113         if (publicId == NULL) {
  3112   3114             Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewListObj(0, NULL));
  3113   3115         } else {
  3114   3116             Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)publicId, strlen(publicId)));
  3115   3117         }
  3116         -
  3117         -      /*
  3118         -       * It would be desirable to be able to terminate parsing
  3119         -       * if the return result is TCL_ERROR or TCL_BREAK.
  3120         -       */
  3121   3118   #if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
  3122   3119         result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
  3123   3120   #else
  3124   3121         result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
  3125   3122                                TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
  3126   3123   #endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */
  3127   3124   
................................................................................
  3159   3156    * Side Effects:
  3160   3157    *	Callback scripts are invoked.
  3161   3158    *
  3162   3159    *----------------------------------------------------------------------------
  3163   3160    */
  3164   3161   
  3165   3162   static int
  3166         -TclGenExpatUnknownEncodingHandler(encodingHandlerData, name, info)
  3167         -     void *encodingHandlerData;
  3168         -     CONST char *name;
  3169         -     XML_Encoding *info;
  3170         -{
         3163  +TclGenExpatUnknownEncodingHandler(
         3164  +    void *encodingHandlerData,
         3165  +    const char *name,
         3166  +    XML_Encoding *info
         3167  +) {
  3171   3168     TclGenExpatInfo *expat = (TclGenExpatInfo *) encodingHandlerData;
  3172   3169     CHandlerSet *activeCHandlerSet;
  3173   3170   
  3174   3171     TclExpatDispatchPCDATA(expat);
  3175   3172   
  3176   3173     if (expat->status != TCL_OK) {
  3177   3174         return 1;
................................................................................
  3205   3202    *
  3206   3203    * Side Effects:
  3207   3204    *	Callback scripts are invoked.
  3208   3205    *
  3209   3206    *----------------------------------------------------------------------------
  3210   3207    */
  3211   3208   static int
  3212         -TclGenExpatExternalEntityRefHandler(parser, openEntityNames, base, systemId,
  3213         -                                    publicId)
  3214         -     XML_Parser parser;
  3215         -     CONST char *openEntityNames;
  3216         -     CONST char *base;
  3217         -     CONST char *systemId;
  3218         -     CONST char *publicId;
  3219         -{
         3209  +TclGenExpatExternalEntityRefHandler(
         3210  +    XML_Parser parser,
         3211  +    const char *openEntityNames,
         3212  +    const char *base,
         3213  +    const char *systemId,
         3214  +    const char *publicId
         3215  +) {
  3220   3216     TclGenExpatInfo *expat = (TclGenExpatInfo *) XML_GetUserData(parser);
  3221   3217     Tcl_Obj *cmdPtr, *resultObj, *resultTypeObj, *extbaseObj, *dataObj;
  3222   3218     int result, mode, done, fd, tclLen;
  3223   3219     size_t len;
  3224   3220     TclHandlerSet *activeTclHandlerSet;
  3225   3221     CHandlerSet *activeCHandlerSet;
  3226   3222     XML_Parser extparser, oldparser = NULL;
................................................................................
  3389   3385                 expat->parser = oldparser;
  3390   3386                 return 0;
  3391   3387             }
  3392   3388             result = 1;
  3393   3389             do {
  3394   3390                 len = Tcl_Read (chan, buf, sizeof (buf));
  3395   3391                 done = len < sizeof (buf);
  3396         -              if (!XML_Parse (extparser, buf, len, done)) {
  3397         -                  result = 0;
  3398         -                  break;
  3399         -              }
         3392  +              result = XML_Parse (extparser, buf, len, done);
         3393  +              if (result != XML_STATUS_OK) break;
  3400   3394             } while (!done);
  3401   3395             Tcl_UnregisterChannel (expat->interp, chan);
  3402   3396             break;
  3403   3397   
  3404   3398         case EXPAT_INPUT_FILENAME:
  3405   3399             fd = open(dataStr, O_BINARY|O_RDONLY);
  3406   3400             if (fd < 0) {
................................................................................
  3413   3407                 XML_ParserFree (extparser);
  3414   3408                 expat->parser = oldparser;
  3415   3409                 return 0;
  3416   3410             }
  3417   3411             result = 1;
  3418   3412             for (;;) {
  3419   3413                 int nread;
  3420         -              char *fbuf = XML_GetBuffer (extparser, READ_SIZE);
         3414  +              char *fbuf = XML_GetBuffer (extparser, TDOM_EXPAT_READ_SIZE);
  3421   3415                 if (!fbuf) {
  3422   3416                     close (fd);
  3423   3417                     Tcl_ResetResult (expat->interp);
  3424   3418                     Tcl_SetResult (expat->interp, "Out of memory\n", NULL);
  3425   3419                     TclExpatHandlerResult (expat, activeTclHandlerSet,
  3426   3420                                            ERROR_IN_EXTREFHANDLER);
  3427   3421                     return 0;
  3428   3422                 }
  3429         -              nread = read(fd, fbuf, READ_SIZE);
         3423  +              nread = read(fd, fbuf, TDOM_EXPAT_READ_SIZE);
  3430   3424                 if (nread < 0) {
  3431   3425                     close (fd);
  3432   3426                     Tcl_ResetResult (expat->interp);
  3433   3427                     Tcl_AppendResult (expat->interp,
  3434   3428                                       "error reading from file \"",
  3435   3429                                       dataStr, "\"", (char *) NULL);
  3436   3430                     TclExpatHandlerResult (expat, activeTclHandlerSet,
  3437   3431                                            ERROR_IN_EXTREFHANDLER);
  3438   3432                     return 0;
  3439   3433                 }
  3440         -              if (!XML_ParseBuffer (extparser, nread, nread == 0)) {
         3434  +              result = XML_ParseBuffer (extparser, nread, nread == 0);
         3435  +              if (result != XML_STATUS_OK || !nread) {
  3441   3436                     close (fd);
  3442         -                  result = 0;
  3443         -                  break;
  3444         -              }
  3445         -              if (nread == 0) {
  3446         -                  close(fd);
  3447   3437                     break;
  3448   3438                 }
  3449   3439             }
  3450   3440             break;
  3451   3441         }
  3452   3442   
  3453   3443         Tcl_DecrRefCount (resultObj);
................................................................................
  3465   3455             TclExpatHandlerResult(expat, activeTclHandlerSet,
  3466   3456                                   ERROR_IN_EXTREFHANDLER);
  3467   3457             return 0;
  3468   3458         }
  3469   3459         
  3470   3460         /* The last node in the external entity may be a text node. To call 
  3471   3461            TclExpatDispatchPCDATA, before switching back to the old parser
  3472         -         ensures, that that last text node has the right base URI. */
         3462  +         ensures, that last text node has the right base URI. */
  3473   3463         TclExpatDispatchPCDATA(expat);
  3474   3464   
  3475   3465         XML_ParserFree (extparser);
  3476   3466         expat->parser = oldparser;
  3477   3467   
  3478   3468         activeCHandlerSet = expat->firstCHandlerSet;
  3479   3469         while (activeCHandlerSet) {
................................................................................
  3534   3524    *
  3535   3525    * Side Effects:
  3536   3526    *	Callback scripts are invoked.
  3537   3527    *
  3538   3528    *----------------------------------------------------------------------------
  3539   3529    */
  3540   3530   static void
  3541         -TclGenExpatCommentHandler(userData, data)
  3542         -    void *userData;
  3543         -    const char *data;
  3544         -{
         3531  +TclGenExpatCommentHandler(
         3532  +    void *userData,
         3533  +    const char *data
         3534  +) {
  3545   3535     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  3546   3536     Tcl_Obj *cmdPtr;
  3547   3537     int result;
  3548   3538     TclHandlerSet *activeTclHandlerSet;
  3549   3539     CHandlerSet *activeCHandlerSet;
  3550   3540   
  3551   3541   
................................................................................
  3618   3608    *
  3619   3609    * Side Effects:
  3620   3610    *	Callback scripts are invoked.
  3621   3611    *
  3622   3612    *----------------------------------------------------------------------------
  3623   3613    */
  3624   3614   static int
  3625         -TclGenExpatNotStandaloneHandler(userData)
  3626         -    void *userData;
  3627         -{
         3615  +TclGenExpatNotStandaloneHandler(
         3616  +    void *userData
         3617  +) {
  3628   3618     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  3629   3619     Tcl_Obj *cmdPtr;
  3630   3620     int result;
  3631   3621     TclHandlerSet *activeTclHandlerSet;
  3632   3622     CHandlerSet *activeCHandlerSet;
  3633   3623   
  3634   3624     TclExpatDispatchPCDATA(expat);
................................................................................
  3695   3685    *
  3696   3686    * Side Effects:
  3697   3687    *	Callback scripts are invoked.
  3698   3688    *
  3699   3689    *----------------------------------------------------------------------------
  3700   3690    */
  3701   3691   static void
  3702         -TclGenExpatStartCdataSectionHandler(userData)
  3703         -    void *userData;
  3704         -{
         3692  +TclGenExpatStartCdataSectionHandler(
         3693  +    void *userData
         3694  +) {
  3705   3695     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  3706   3696     Tcl_Obj *cmdPtr;
  3707   3697     int result;
  3708   3698     TclHandlerSet *activeTclHandlerSet;
  3709   3699     CHandlerSet *activeCHandlerSet;
  3710   3700   
  3711   3701     if (expat->status != TCL_OK) {
................................................................................
  3775   3765    *
  3776   3766    * Side Effects:
  3777   3767    *	Callback scripts are invoked.
  3778   3768    *
  3779   3769    *----------------------------------------------------------------------------
  3780   3770    */
  3781   3771   static void
  3782         -TclGenExpatEndCdataSectionHandler(userData)
  3783         -    void *userData;
  3784         -{
         3772  +TclGenExpatEndCdataSectionHandler(
         3773  +    void *userData
         3774  +) {
  3785   3775     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  3786   3776     Tcl_Obj *cmdPtr;
  3787   3777     int result;
  3788   3778     TclHandlerSet *activeTclHandlerSet;
  3789   3779     CHandlerSet *activeCHandlerSet;
  3790   3780   
  3791   3781     if (expat->status != TCL_OK) {
................................................................................
  3837   3827         activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  3838   3828     }
  3839   3829     return;
  3840   3830   }
  3841   3831   
  3842   3832   
  3843   3833   static void
  3844         -generateModel (interp, rep, model)
  3845         -    Tcl_Interp  *interp;
  3846         -    Tcl_Obj     *rep;
  3847         -    XML_Content *model;
  3848         -{
         3834  +generateModel (
         3835  +	       Tcl_Interp  *interp,
         3836  +	       Tcl_Obj     *rep,
         3837  +	       XML_Content *model
         3838  +) {
  3849   3839       Tcl_Obj *cp, *detail;
  3850   3840       unsigned int      i;
  3851   3841   
  3852   3842   
  3853   3843       switch (model->type) {
  3854   3844       case XML_CTYPE_EMPTY:
  3855   3845           Tcl_ListObjAppendElement (interp, rep, Tcl_NewStringObj ("EMPTY", 5));
................................................................................
  3919   3909    * Side effects:
  3920   3910    *	Callback scripts are invoked.
  3921   3911    *
  3922   3912    *----------------------------------------------------------------------
  3923   3913    */
  3924   3914   
  3925   3915   static void
  3926         -TclGenExpatElementDeclHandler(userData, name, model)
  3927         -    void *userData;
  3928         -    const XML_Char *name;
  3929         -    XML_Content *model;
  3930         -{
         3916  +TclGenExpatElementDeclHandler(
         3917  +    void *userData,
         3918  +    const XML_Char *name,
         3919  +    XML_Content *model
         3920  +) {
  3931   3921     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  3932   3922     Tcl_Obj *cmdPtr;
  3933   3923     Tcl_Obj *content;
  3934   3924     int result;
  3935   3925     TclHandlerSet *activeTclHandlerSet;
  3936   3926     CHandlerSet *activeCHandlerSet;
  3937   3927     ExpatElemContent *eContent;
................................................................................
  4014   4004    * Side effects:
  4015   4005    *	Callback scripts are invoked.
  4016   4006    *
  4017   4007    *----------------------------------------------------------------------
  4018   4008    */
  4019   4009   
  4020   4010   static void
  4021         -TclGenExpatAttlistDeclHandler(userData, elname, name, type, dflt, isrequired)
  4022         -    void           *userData;
  4023         -    const XML_Char *elname;
  4024         -    const XML_Char *name;
  4025         -    const XML_Char *type;
  4026         -    const XML_Char *dflt;
  4027         -    int             isrequired;
  4028         -{
         4011  +TclGenExpatAttlistDeclHandler(
         4012  +    void           *userData,
         4013  +    const XML_Char *elname,
         4014  +    const XML_Char *name,
         4015  +    const XML_Char *type,
         4016  +    const XML_Char *dflt,
         4017  +    int             isrequired
         4018  +) {
  4029   4019     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  4030   4020     Tcl_Obj *cmdPtr;
  4031   4021     int result;
  4032   4022     TclHandlerSet *activeTclHandlerSet;
  4033   4023     CHandlerSet *activeCHandlerSet;
  4034   4024   
  4035   4025     TclExpatDispatchPCDATA(expat);
................................................................................
  4116   4106    * Side effects:
  4117   4107    *	Callback scripts are invoked.
  4118   4108    *
  4119   4109    *----------------------------------------------------------------------
  4120   4110    */
  4121   4111   
  4122   4112   static void
  4123         -TclGenExpatStartDoctypeDeclHandler(userData, doctypeName, sysid, pubid, has_internal_subset)
  4124         -    void *userData;
  4125         -    const XML_Char *doctypeName;
  4126         -    const XML_Char *sysid;
  4127         -    const XML_Char *pubid;
  4128         -    int   has_internal_subset;
  4129         -{
         4113  +TclGenExpatStartDoctypeDeclHandler(
         4114  +    void *userData,
         4115  +    const XML_Char *doctypeName,
         4116  +    const XML_Char *sysid,
         4117  +    const XML_Char *pubid,
         4118  +    int   has_internal_subset
         4119  +) {
  4130   4120     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  4131   4121     Tcl_Obj *cmdPtr;
  4132   4122     int result;
  4133   4123     TclHandlerSet *activeTclHandlerSet;
  4134   4124     CHandlerSet *activeCHandlerSet;
  4135   4125   
  4136   4126     TclExpatDispatchPCDATA(expat);
................................................................................
  4220   4210    * Side effects:
  4221   4211    *	Callback script is invoked.
  4222   4212    *
  4223   4213    *----------------------------------------------------------------------
  4224   4214    */
  4225   4215   
  4226   4216   static void
  4227         -TclGenExpatEndDoctypeDeclHandler(userData)
  4228         -    void *userData;
  4229         -{
         4217  +TclGenExpatEndDoctypeDeclHandler(
         4218  +    void *userData
         4219  +) {
  4230   4220     TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  4231   4221     Tcl_Obj *cmdPtr;
  4232   4222     int result;
  4233   4223     TclHandlerSet *activeTclHandlerSet;
  4234   4224     CHandlerSet *activeCHandlerSet;
  4235   4225     ExpatElemContent *eContent, *eContentSave;
  4236   4226   
................................................................................
  4309   4299    * Side effects:
  4310   4300    *	Callback script is invoked.
  4311   4301    *
  4312   4302    *----------------------------------------------------------------------
  4313   4303    */
  4314   4304   
  4315   4305   static void
  4316         -TclGenExpatXmlDeclHandler (userData, version, encoding, standalone)
  4317         -    void *userData;
  4318         -    const char *version;
  4319         -    const char *encoding;
  4320         -    int   standalone;
  4321         -{
         4306  +TclGenExpatXmlDeclHandler (
         4307  +    void *userData,
         4308  +    const char *version,
         4309  +    const char *encoding,
         4310  +    int   standalone
         4311  +) {
  4322   4312       TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  4323   4313       Tcl_Obj *cmdPtr;
  4324   4314       int result;
  4325   4315       TclHandlerSet *activeTclHandlerSet;
  4326   4316       CHandlerSet *activeCHandlerSet;
  4327   4317   
  4328   4318       if (expat->status != TCL_OK) {
................................................................................
  4402   4392    * Side Effects:
  4403   4393    *	Memory structures are freed.
  4404   4394    *
  4405   4395    *----------------------------------------------------------------------------
  4406   4396    */
  4407   4397   
  4408   4398   static void
  4409         -TclExpatDeleteCmd(clientData)
  4410         -     ClientData clientData;
  4411         -{
         4399  +TclExpatDeleteCmd(
         4400  +    ClientData clientData
         4401  +) {
  4412   4402     TclGenExpatInfo *expat = (TclGenExpatInfo *) clientData;
  4413   4403     TclHandlerSet *activeTclHandlerSet, *tmpTclHandlerSet;
  4414   4404     CHandlerSet *activeCHandlerSet, *tmpCHandlerSet;
  4415   4405   
  4416   4406     TclExpatFreeParser(expat);
  4417   4407   
  4418   4408     Tcl_DecrRefCount(expat->name);
................................................................................
  4511   4501     }
  4512   4502   
  4513   4503     FREE( (char*) expat);
  4514   4504   }
  4515   4505   
  4516   4506   
  4517   4507   int
  4518         -CheckExpatParserObj (interp, nameObj)
  4519         -    Tcl_Interp *interp;
  4520         -    Tcl_Obj *CONST nameObj;
  4521         -{
         4508  +CheckExpatParserObj (
         4509  +    Tcl_Interp *interp,
         4510  +    Tcl_Obj *const nameObj
         4511  +) {
  4522   4512       Tcl_CmdInfo info;
  4523         -
  4524   4513   
  4525   4514       if (!Tcl_GetCommandInfo (interp, Tcl_GetString(nameObj), &info)) {
  4526   4515           return 0;
  4527   4516       }
  4528   4517       if (!info.isNativeObjectProc || info.objProc != TclExpatInstanceCmd) {
  4529   4518           return 0;
  4530   4519       }
  4531   4520       return 1;
  4532   4521   }
  4533   4522   
  4534   4523   int
  4535         -CHandlerSetInstall (interp, expatObj, handlerSet)
  4536         -    Tcl_Interp *interp;
  4537         -    Tcl_Obj *CONST expatObj;
  4538         -    CHandlerSet *handlerSet;
  4539         -{
         4524  +CHandlerSetInstall (
         4525  +    Tcl_Interp *interp,
         4526  +    Tcl_Obj *const expatObj,
         4527  +    CHandlerSet *handlerSet
         4528  +) {
  4540   4529       Tcl_CmdInfo info;
  4541   4530       TclGenExpatInfo *expat;
  4542   4531       CHandlerSet *activeCHandlerSet;
  4543   4532   
  4544   4533       if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
  4545   4534           return 1;
  4546   4535       }
................................................................................
  4549   4538           activeCHandlerSet = expat->firstCHandlerSet;
  4550   4539           while (1) {
  4551   4540               if (strcmp (activeCHandlerSet->name, handlerSet->name) == 0) {
  4552   4541                   return 2;
  4553   4542               }
  4554   4543               if (activeCHandlerSet->nextHandlerSet == NULL) {
  4555   4544                   break;
  4556         -            }
  4557         -            else {
         4545  +            } else {
  4558   4546                   activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  4559   4547               }
  4560   4548           }
  4561   4549           activeCHandlerSet->nextHandlerSet = handlerSet;
  4562   4550       }
  4563   4551       else {
  4564   4552           expat->firstCHandlerSet = handlerSet;
................................................................................
  4566   4554       if (handlerSet->ignoreWhiteCDATAs) {
  4567   4555           expat->needWSCheck = 1;
  4568   4556       }
  4569   4557       return 0;
  4570   4558   }
  4571   4559   
  4572   4560   int
  4573         -CHandlerSetRemove (interp, expatObj, handlerSetName)
  4574         -    Tcl_Interp *interp;
  4575         -    Tcl_Obj *CONST expatObj;
  4576         -    char *handlerSetName;
  4577         -{
         4561  +CHandlerSetRemove (
         4562  +    Tcl_Interp *interp,
         4563  +    Tcl_Obj *const expatObj,
         4564  +    char *handlerSetName
         4565  +) {
  4578   4566       Tcl_CmdInfo info;
  4579   4567       TclGenExpatInfo *expat;
  4580   4568       CHandlerSet *activeCHandlerSet, *parentHandlerSet = NULL;
  4581   4569   
  4582   4570       if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
  4583   4571           return 1;
  4584   4572       }
................................................................................
  4606   4594           parentHandlerSet = activeCHandlerSet;
  4607   4595           activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  4608   4596       }
  4609   4597       return 2;
  4610   4598   }
  4611   4599   
  4612   4600   CHandlerSet *
  4613         -CHandlerSetGet (interp, expatObj, handlerSetName)
  4614         -    Tcl_Interp *interp;
  4615         -    Tcl_Obj *CONST expatObj;
  4616         -    char *handlerSetName;
  4617         -{
         4601  +CHandlerSetGet (
         4602  +    Tcl_Interp *interp,
         4603  +    Tcl_Obj *const expatObj,
         4604  +    char *handlerSetName
         4605  +) {
  4618   4606       Tcl_CmdInfo info;
  4619   4607       TclGenExpatInfo *expat;
  4620   4608       CHandlerSet *activeCHandlerSet;
  4621   4609   
  4622   4610       if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
  4623   4611           return NULL;
  4624   4612       }
................................................................................
  4633   4621           }
  4634   4622           activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  4635   4623       }
  4636   4624       return NULL;
  4637   4625   }
  4638   4626   
  4639   4627   void *
  4640         -CHandlerSetGetUserData (interp, expatObj, handlerSetName)
  4641         -    Tcl_Interp *interp;
  4642         -    Tcl_Obj *CONST expatObj;
  4643         -    char *handlerSetName;
  4644         -{
         4628  +CHandlerSetGetUserData (
         4629  +    Tcl_Interp *interp,
         4630  +    Tcl_Obj *const expatObj,
         4631  +    char *handlerSetName
         4632  +) {
  4645   4633       Tcl_CmdInfo info;
  4646   4634       TclGenExpatInfo *expat;
  4647   4635       CHandlerSet *activeCHandlerSet;
  4648   4636   
  4649   4637       if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
  4650   4638           return NULL;
  4651   4639       }
................................................................................
  4660   4648           }
  4661   4649           activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  4662   4650       }
  4663   4651       return NULL;
  4664   4652   }
  4665   4653   
  4666   4654   TclGenExpatInfo *
  4667         -GetExpatInfo (interp, expatObj)
  4668         -    Tcl_Interp *interp;
  4669         -    Tcl_Obj *CONST expatObj;
  4670         -{
         4655  +GetExpatInfo (
         4656  +    Tcl_Interp *interp,
         4657  +    Tcl_Obj *const expatObj
         4658  +) {
  4671   4659       Tcl_CmdInfo info;
  4672   4660       if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
  4673   4661           return NULL;
  4674   4662       }
  4675   4663       return (TclGenExpatInfo *) info.objClientData;
  4676   4664   }

Changes to generic/tclexpat.h.

    10     10   
    11     11   typedef struct CHandlerSet {
    12     12       struct CHandlerSet *nextHandlerSet;
    13     13       char *name;                     /* refname of the handler set */
    14     14       int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */
    15     15   
    16     16       void *userData;                 /* Handler set specific Data Structure;
    17         -                                       the C handler set extention has to
           17  +                                       the C handler set extension has to
    18     18                                          malloc the needed structure in his
    19     19                                          init func and has to provide a
    20     20                                          cleanup func (to free it). */
    21     21   
    22     22       CHandlerSet_userDataReset        resetProc;
    23     23       CHandlerSet_userDataFree         freeProc;
    24     24       CHandlerSet_parserReset          parserResetProc;
................................................................................
   130    130       int parsingState;           /* 0 == freshly (re-)initialized
   131    131                                      1 == initParserProcs called
   132    132                                      2 == parsing an input chunk */
   133    133       XML_Char nsSeparator;       
   134    134       int paramentityparsing;     
   135    135       int noexpand;
   136    136       int useForeignDTD;
   137         -
          137  +    const char *currentmarkup;  /* Used to transfer data for method */
          138  +    int currentmarkuplen;       /* currentmarkup */
          139  + 
   138    140       TclHandlerSet *firstTclHandlerSet;
   139    141       CHandlerSet *firstCHandlerSet;
   140    142   } TclGenExpatInfo;
   141    143   
   142    144   /*--------------------------------------------------------------------------
   143    145   |   Function prototypes
   144    146   |
   145    147   \-------------------------------------------------------------------------*/
   146    148   
   147         -#if defined(_MSC_VER) || defined(BUILD_tdom)
          149  +#if defined(_MSC_VER) || defined(BUILD_tdom) || defined(__MINGW32__) 
   148    150   #  undef TCL_STORAGE_CLASS
   149    151   #  define TCL_STORAGE_CLASS DLLEXPORT
   150    152   #endif
   151    153   
   152         -EXTERN int TclExpatObjCmd _ANSI_ARGS_((ClientData dummy,
   153         -                                       Tcl_Interp *interp,
   154         -                                       int objc, Tcl_Obj *CONST objv[]));
   155         -EXTERN int CheckExpatParserObj _ANSI_ARGS_((Tcl_Interp *interp,
   156         -                                            Tcl_Obj *CONST nameObj));
   157         -EXTERN int CHandlerSetInstall _ANSI_ARGS_((Tcl_Interp *interp,
   158         -                                           Tcl_Obj *CONST expatObj,
   159         -                                           CHandlerSet *handlerSet));
   160         -EXTERN int CHandlerSetRemove _ANSI_ARGS_((Tcl_Interp *interp,
   161         -                                          Tcl_Obj *CONST expatObj,
   162         -                                          char *handlerSetName));
   163         -EXTERN CHandlerSet * CHandlerSetCreate _ANSI_ARGS_((char *name));
   164         -EXTERN CHandlerSet * CHandlerSetGet _ANSI_ARGS_((Tcl_Interp *interp,
   165         -                                               Tcl_Obj *CONST expatObj,
   166         -                                               char *handlerSetName));
   167         -EXTERN void * CHandlerSetGetUserData _ANSI_ARGS_((Tcl_Interp *interp,
   168         -                                               Tcl_Obj *CONST expatObj,
   169         -                                               char *handlerSetName));
          154  +EXTERN Tcl_ObjCmdProc TclExpatObjCmd;
          155  +
          156  +EXTERN int CheckExpatParserObj (Tcl_Interp *interp,
          157  +				Tcl_Obj *const nameObj);
          158  +EXTERN int CHandlerSetInstall (Tcl_Interp *interp,
          159  +			       Tcl_Obj *const expatObj,
          160  +			       CHandlerSet *handlerSet);
          161  +EXTERN int CHandlerSetRemove (Tcl_Interp *interp,
          162  +			      Tcl_Obj *const expatObj,
          163  +			      char *handlerSetName);
          164  +EXTERN CHandlerSet * CHandlerSetCreate (char *name);
          165  +EXTERN CHandlerSet * CHandlerSetGet (Tcl_Interp *interp,
          166  +                                     Tcl_Obj *const expatObj,
          167  +				     char *handlerSetName);
          168  +EXTERN void * CHandlerSetGetUserData (Tcl_Interp *interp,
          169  +                                      Tcl_Obj *const expatObj,
          170  +				      char *handlerSetName);
   170    171   
   171         -EXTERN TclGenExpatInfo * GetExpatInfo _ANSI_ARGS_((Tcl_Interp *interp,
   172         -                                                   Tcl_Obj *CONST expatObj));
          172  +EXTERN TclGenExpatInfo * GetExpatInfo (Tcl_Interp *interp,
          173  +				       Tcl_Obj *const expatObj);

Added generic/tclpull.c.

            1  +/*----------------------------------------------------------------------------
            2  +|   Copyright (c) 2018  Rolf Ade (rolf@pointsman.de)
            3  +|-----------------------------------------------------------------------------
            4  +|
            5  +|
            6  +|   The contents of this file are subject to the Mozilla Public License
            7  +|   Version 1.1 (the "License"); you may not use this file except in
            8  +|   compliance with the License. You may obtain a copy of the License at
            9  +|   http://www.mozilla.org/MPL/
           10  +|
           11  +|   Software distributed under the License is distributed on an "AS IS"
           12  +|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
           13  +|   License for the specific language governing rights and limitations
           14  +|   under the License.
           15  +|
           16  +|   Contributor(s):
           17  +|
           18  +|
           19  +|   written by Rolf Ade
           20  +|   February 2018
           21  +|
           22  +\---------------------------------------------------------------------------*/
           23  +
           24  +#ifndef TDOM_NO_PULL
           25  +
           26  +#include <tdom.h>
           27  +#include <fcntl.h>
           28  +#ifdef _MSC_VER
           29  +#include <io.h>
           30  +#else
           31  +#include <unistd.h>
           32  +#endif
           33  +
           34  +#ifndef O_BINARY
           35  +#ifdef _O_BINARY
           36  +#define O_BINARY _O_BINARY
           37  +#else
           38  +#define O_BINARY 0
           39  +#endif
           40  +#endif
           41  +
           42  +#ifndef TDOM_EXPAT_READ_SIZE
           43  +# define TDOM_EXPAT_READ_SIZE (1024*8)
           44  +#endif
           45  +
           46  +/* For information about why this work-around for a certain expat
           47  + * version is necessary see
           48  + * https://github.com/libexpat/libexpat/issues/204 */
           49  +#if (XML_MAJOR_VERSION == 2) && (XML_MINOR_VERSION == 2) && (XML_MICRO_VERSION == 5)
           50  +# define EXPAT_RESUME_BUG
           51  +#endif
           52  +
           53  +/* #define DEBUG */
           54  +/*----------------------------------------------------------------------------
           55  +|   Debug Macros
           56  +|
           57  +\---------------------------------------------------------------------------*/
           58  +#ifdef DEBUG
           59  +# define DBG(x) x
           60  +#else
           61  +# define DBG(x) 
           62  +#endif
           63  +
           64  +typedef enum {
           65  +    PULLPARSERSTATE_READY,
           66  +    PULLPARSERSTATE_START_DOCUMENT,
           67  +    PULLPARSERSTATE_END_DOCUMENT,
           68  +    PULLPARSERSTATE_START_TAG,
           69  +    PULLPARSERSTATE_END_TAG,
           70  +    PULLPARSERSTATE_TEXT,
           71  +    PULLPARSERSTATE_PARSE_ERROR
           72  +} PullParserState;
           73  +
           74  +typedef enum {
           75  +    PULLPARSEMODE_NORMAL,
           76  +    PULLPARSEMODE_SKIP,
           77  +    PULLPARSEMODE_FIND
           78  +} PullParseMode;
           79  +    
           80  +typedef struct tDOM_PullParserInfo 
           81  +{
           82  +    XML_Parser      parser;
           83  +    Tcl_Obj        *inputString;
           84  +    Tcl_Channel     inputChannel;
           85  +    int             inputfd;
           86  +    PullParserState state;
           87  +    PullParserState nextState;
           88  +    PullParserState next2State;
           89  +    Tcl_DString    *cdata;
           90  +    Tcl_HashTable  *elmCache;
           91  +    Tcl_Obj        *currentElm;
           92  +    const char    **atts;
           93  +    Tcl_Obj        *channelReadBuf;
           94  +    Tcl_Obj        *start_tag;
           95  +    Tcl_Obj        *end_tag;
           96  +    Tcl_Obj        *text;
           97  +    int             ignoreWhiteSpaces;
           98  +    PullParseMode   mode;
           99  +    int             skipDepth;
          100  +    char           *findElement;
          101  +#ifdef EXPAT_RESUME_BUG
          102  +    long            elmStartCounter;
          103  +#endif
          104  +} tDOM_PullParserInfo;
          105  +
          106  +#define SetResult(str) Tcl_ResetResult(interp); \
          107  +                     Tcl_SetStringObj(Tcl_GetObjResult(interp), (str), -1)
          108  +
          109  +DBG(
          110  +static void
          111  +printParserState (
          112  +    XML_Parser parser
          113  +    )
          114  +{
          115  +    XML_ParsingStatus pstatus;
          116  +    
          117  +    XML_GetParsingStatus (parser, &pstatus);
          118  +    switch (pstatus.parsing) {
          119  +    case XML_INITIALIZED:
          120  +        fprintf (stderr, "parser status: XML_INITIALIZED\n");
          121  +        break;
          122  +    case XML_PARSING:
          123  +        fprintf (stderr, "parser status: XML_PARSING\n");
          124  +        break;
          125  +    case XML_FINISHED:
          126  +        fprintf (stderr, "parser status: XML_FINISHED\n");
          127  +        break;
          128  +    case XML_SUSPENDED:
          129  +        fprintf (stderr, "parser status: XML_SUSPENDED\n");
          130  +        break;
          131  +    default:
          132  +        fprintf (stderr, "unexpected parser status: %d\n",
          133  +                 pstatus.parsing);
          134  +        break;
          135  +    }
          136  +}
          137  +)
          138  +
          139  +static void
          140  +characterDataHandler (
          141  +    void        *userData,
          142  +    const char  *s,
          143  +    int          len
          144  +)
          145  +{
          146  +    tDOM_PullParserInfo *pullInfo = userData;
          147  +
          148  +    DBG(fprintf(stderr, "cdata handler called\n"));
          149  +    Tcl_DStringAppend (pullInfo->cdata, s, len);    
          150  +}
          151  +
          152  +static void
          153  +endElement (
          154  +    void        *userData,
          155  +    const char  *name
          156  +)
          157  +{
          158  +    tDOM_PullParserInfo *pullInfo = userData;
          159  +    XML_ParsingStatus status;
          160  +    int reportStartTag = 0, reportText = 0, hnew;
          161  +    Tcl_HashEntry *h;
          162  +
          163  +    DBG(fprintf(stderr, "endElement tag %s\n", name));
          164  +
          165  +    if (pullInfo->mode == PULLPARSEMODE_SKIP) {
          166  +        if (pullInfo->skipDepth > 0) {
          167  +            pullInfo->skipDepth--;
          168  +            return;
          169  +        }
          170  +        pullInfo->mode = PULLPARSEMODE_NORMAL;
          171  +        XML_SetCharacterDataHandler (pullInfo->parser, characterDataHandler);
          172  +    }
          173  +            
          174  +    XML_GetParsingStatus (pullInfo->parser, &status);
          175  +    if (status.parsing == XML_SUSPENDED) {
          176  +        reportStartTag = 1;
          177  +    }
          178  +
          179  +    if (Tcl_DStringLength (pullInfo->cdata) > 0) {
          180  +        if (pullInfo->ignoreWhiteSpaces) {
          181  +            char *pc; int len;
          182  +            len = Tcl_DStringLength(pullInfo->cdata);
          183  +            for (pc = Tcl_DStringValue (pullInfo->cdata);
          184  +                 len > 0;
          185  +                 len--, pc++) 
          186  +            {
          187  +                if ( (*pc != ' ')  &&
          188  +                     (*pc != '\t') &&
          189  +                     (*pc != '\n') &&
          190  +                     (*pc != '\r') ) {
          191  +                    reportText = 1;
          192  +                    break;
          193  +                }
          194  +            }
          195  +        } else {
          196  +            reportText = 1;
          197  +        }
          198  +    }
          199  +
          200  +    if (reportStartTag && reportText) {
          201  +        /* This happens if in mixed content an empty element written
          202  +         * with the empty element syntax (<foo/>) follows text. */
          203  +        DBG(fprintf(stderr, "schedule 2 events\n"));
          204  +        pullInfo->state = PULLPARSERSTATE_TEXT;
          205  +        pullInfo->nextState= PULLPARSERSTATE_START_TAG;
          206  +        pullInfo->next2State = PULLPARSERSTATE_END_TAG;
          207  +    } else if (reportStartTag) {
          208  +        /* This happens if not in mixed content and the parser saw an
          209  +         * empty element written with the empty element syntax. */
          210  +        DBG(fprintf(stderr, "schedule 1 event (reportStartTag)\n"));
          211  +        pullInfo->state = PULLPARSERSTATE_START_TAG;
          212  +        pullInfo->nextState = PULLPARSERSTATE_END_TAG;
          213  +#ifdef EXPAT_RESUME_BUG
          214  +        DBG(fprintf(stderr, "EXPAT_RESUME_BUG\n"));
          215  +        if (pullInfo->elmStartCounter == 1) {
          216  +            pullInfo->next2State = PULLPARSERSTATE_END_DOCUMENT;
          217  +        }
          218  +#endif        
          219  +    } else if (reportText) {
          220  +        DBG(fprintf(stderr, "schedule 1 event (reportText)\n"));
          221  +        pullInfo->state = PULLPARSERSTATE_TEXT;
          222  +        pullInfo->nextState = PULLPARSERSTATE_END_TAG;
          223  +    } else {
          224  +        pullInfo->state = PULLPARSERSTATE_END_TAG;
          225  +    }
          226  +
          227  +    h = Tcl_FindHashEntry (pullInfo->elmCache, name);
          228  +    if (h == NULL) {
          229  +        /* The start tag entry creation was skipped during a
          230  +         * find-element, create it now. */
          231  +        h = Tcl_CreateHashEntry (pullInfo->elmCache, name, &hnew);
          232  +        DBG(fprintf(stderr, "endElement: create tag hash table entry %s\n", name));
          233  +        pullInfo->currentElm = Tcl_NewStringObj (name, -1);
          234  +        Tcl_IncrRefCount (pullInfo->currentElm);
          235  +        Tcl_SetHashValue (h, pullInfo->currentElm);
          236  +    }
          237  +    pullInfo->currentElm = (Tcl_Obj *) Tcl_GetHashValue(h);
          238  +    XML_StopParser(pullInfo->parser, 1);
          239  +}
          240  +
          241  +static void
          242  +startElement(
          243  +    void         *userData,
          244  +    const char   *name,
          245  +    const char  **atts
          246  +)
          247  +{
          248  +    tDOM_PullParserInfo *pullInfo = userData;
          249  +    int hnew;
          250  +    Tcl_HashEntry *h;
          251  +    
          252  +    DBG(fprintf(stderr, "startElement tag %s\n", name));
          253  +
          254  +#ifdef EXPAT_RESUME_BUG
          255  +    pullInfo->elmStartCounter++;
          256  +#endif
          257  +
          258  +    switch (pullInfo->mode) {
          259  +    case PULLPARSEMODE_SKIP:
          260  +        DBG(fprintf (stderr, "PULLPARSEMODE_SKIP\n"));
          261  +        pullInfo->skipDepth++;
          262  +        return;
          263  +    case PULLPARSEMODE_FIND:
          264  +        DBG(fprintf (stderr, "PULLPARSEMODE_FIND this %s search for %s\n",
          265  +                     name, pullInfo->findElement));
          266  +        if (strcmp (name, pullInfo->findElement) != 0) {
          267  +            return;
          268  +        }
          269  +        pullInfo->mode = PULLPARSEMODE_NORMAL;
          270  +        XML_SetCharacterDataHandler (pullInfo->parser, characterDataHandler);
          271  +        XML_SetEndElementHandler (pullInfo->parser, endElement);
          272  +        break;
          273  +    case PULLPARSEMODE_NORMAL:
          274  +        break;
          275  +    }
          276  +    if (Tcl_DStringLength (pullInfo->cdata) > 0) {
          277  +        if (pullInfo->ignoreWhiteSpaces) {
          278  +            char *pc; int len, wso = 1;
          279  +            len = Tcl_DStringLength(pullInfo->cdata);
          280  +            for (pc = Tcl_DStringValue (pullInfo->cdata);
          281  +                 len > 0;
          282  +                 len--, pc++) 
          283  +            {
          284  +                if ( (*pc != ' ')  &&
          285  +                     (*pc != '\t') &&
          286  +                     (*pc != '\n') &&
          287  +                     (*pc != '\r') ) {
          288  +                    wso = 0;
          289  +                    break;
          290  +                }
          291  +            }
          292  +            if (wso) {
          293  +                Tcl_DStringSetLength (pullInfo->cdata, 0);
          294  +                pullInfo->state = PULLPARSERSTATE_START_TAG;
          295  +            } else {
          296  +                DBG(fprintf(stderr, "schedule TEXT event\n"));
          297  +                pullInfo->state = PULLPARSERSTATE_TEXT;
          298  +                pullInfo->nextState = PULLPARSERSTATE_START_TAG;
          299  +            }
          300  +        } else {
          301  +            DBG(fprintf(stderr, "schedule TEXT event\n"));
          302  +            pullInfo->state = PULLPARSERSTATE_TEXT;
          303  +            pullInfo->nextState = PULLPARSERSTATE_START_TAG;
          304  +        }
          305  +    } else {
          306  +        pullInfo->state = PULLPARSERSTATE_START_TAG;
          307  +    }
          308  +    h = Tcl_CreateHashEntry (pullInfo->elmCache, name, &hnew);
          309  +    if (hnew) {
          310  +        DBG(fprintf(stderr, "startElement: create tag hash table entry %s\n", name));
          311  +        pullInfo->currentElm = Tcl_NewStringObj (name, -1);
          312  +        Tcl_IncrRefCount (pullInfo->currentElm);
          313  +        Tcl_SetHashValue (h, pullInfo->currentElm);
          314  +    } else {
          315  +        pullInfo->currentElm = (Tcl_Obj *) Tcl_GetHashValue (h);
          316  +    }
          317  +    pullInfo->atts = atts;
          318  +
          319  +    XML_StopParser(pullInfo->parser, 1);
          320  +}
          321  +
          322  +static void
          323  +tDOM_PullParserDeleteCmd (
          324  +    ClientData clientdata
          325  +    )
          326  +{
          327  +    tDOM_PullParserInfo *pullInfo = clientdata;
          328  +    Tcl_HashEntry *entryPtr;
          329  +    Tcl_HashSearch search;
          330  +
          331  +    XML_ParserFree (pullInfo->parser);
          332  +    if (pullInfo->inputString) {
          333  +        Tcl_DecrRefCount (pullInfo->inputString);
          334  +    }
          335  +    if (pullInfo->inputfd) {
          336  +        close (pullInfo->inputfd);
          337  +    }
          338  +    Tcl_DStringFree (pullInfo->cdata);
          339  +    FREE (pullInfo->cdata);
          340  +    if (pullInfo->channelReadBuf) {
          341  +        Tcl_DecrRefCount (pullInfo->channelReadBuf);
          342  +    }
          343  +    entryPtr = Tcl_FirstHashEntry(pullInfo->elmCache, &search);
          344  +    while (entryPtr) {
          345  +        Tcl_DecrRefCount ((Tcl_Obj*) Tcl_GetHashValue (entryPtr));
          346  +        entryPtr = Tcl_NextHashEntry (&search);
          347  +    }
          348  +    Tcl_DeleteHashTable (pullInfo->elmCache);
          349  +    FREE (pullInfo->elmCache);
          350  +    Tcl_DecrRefCount(pullInfo->start_tag);
          351  +    Tcl_DecrRefCount(pullInfo->end_tag);
          352  +    Tcl_DecrRefCount(pullInfo->text);
          353  +    FREE (pullInfo);
          354  +}
          355  +
          356  +static void
          357  +tDOM_ReportXMLError (
          358  +    Tcl_Interp *interp,
          359  +    tDOM_PullParserInfo *pullInfo
          360  +    )
          361  +{
          362  +    char s[255];
          363  +
          364  +    Tcl_ResetResult (interp);
          365  +    sprintf(s, "%ld", XML_GetCurrentLineNumber(pullInfo->parser));
          366  +    Tcl_AppendResult(interp, "error \"",
          367  +                     XML_ErrorString(
          368  +                         XML_GetErrorCode(pullInfo->parser)),
          369  +                     "\" at line ", s, " character ", NULL);
          370  +    sprintf(s, "%ld", XML_GetCurrentColumnNumber(pullInfo->parser));
          371  +    Tcl_AppendResult(interp, s, NULL);
          372  +}
          373  +
          374  +static void
          375  +tDOM_CleanupInputSource (
          376  +    tDOM_PullParserInfo *pullInfo
          377  +    )
          378  +{
          379  +    if (pullInfo->inputString) {
          380  +        Tcl_DecrRefCount (pullInfo->inputString);
          381  +        pullInfo->inputString = NULL;
          382  +    }
          383  +    pullInfo->inputChannel = NULL;
          384  +    if (pullInfo->inputfd) {
          385  +        close (pullInfo->inputfd);
          386  +        pullInfo->inputfd = 0;
          387  +    }
          388  +}
          389  +
          390  +static int
          391  +tDOM_resumeParseing (
          392  +    Tcl_Interp *interp,
          393  +    tDOM_PullParserInfo *pullInfo
          394  +    ) 
          395  +{
          396  +    XML_ParsingStatus pstatus;
          397  +    int len, done, result;
          398  +    char *data;
          399  +    
          400  +
          401  +    switch (XML_ResumeParser (pullInfo->parser)) {
          402  +    case XML_STATUS_OK:
          403  +        if (pullInfo->inputString) {
          404  +            Tcl_DecrRefCount (pullInfo->inputString);
          405  +            pullInfo->inputString = NULL;
          406  +            pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
          407  +            break;
          408  +        }
          409  +        XML_GetParsingStatus (pullInfo->parser, &pstatus);
          410  +        if (pstatus.parsing == XML_FINISHED) {
          411  +            tDOM_CleanupInputSource (pullInfo);
          412  +            pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
          413  +            break;
          414  +        }
          415  +        if (pullInfo->inputChannel) {
          416  +            do {
          417  +                len = Tcl_ReadChars (pullInfo->inputChannel,
          418  +                                     pullInfo->channelReadBuf,
          419  +                                     1024, 0);
          420  +                done = (len < 1024);
          421  +                data = Tcl_GetStringFromObj (
          422  +                    pullInfo->channelReadBuf, &len
          423  +                    );
          424  +                result = XML_Parse (pullInfo->parser, data,
          425  +                                    len, done);
          426  +            } while (result == XML_STATUS_OK && !done);
          427  +        } else {
          428  +            /* inputfile */
          429  +            do {
          430  +                char *fbuf = 
          431  +                    XML_GetBuffer (pullInfo->parser,
          432  +                                   TDOM_EXPAT_READ_SIZE);
          433  +                len = read (pullInfo->inputfd, fbuf,
          434  +                            TDOM_EXPAT_READ_SIZE);
          435  +                done = (len < TDOM_EXPAT_READ_SIZE);
          436  +                result = XML_ParseBuffer (pullInfo->parser,
          437  +                                          len, done);
          438  +            } while (result == XML_STATUS_OK && !done);
          439  +        }
          440  +        if (result == XML_STATUS_ERROR) {
          441  +            tDOM_CleanupInputSource (pullInfo);
          442  +            tDOM_ReportXMLError (interp, pullInfo);
          443  +            pullInfo->state = PULLPARSERSTATE_PARSE_ERROR;
          444  +            return TCL_ERROR;
          445  +        }
          446  +        if (done && result == XML_STATUS_OK) {
          447  +            tDOM_CleanupInputSource (pullInfo);
          448  +            pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
          449  +        }
          450  +        /* If here result == XML_STATUS_SUSPENDED,
          451  +         * state was set in handler, just take care to
          452  +         * report */
          453  +        break;
          454  +    case XML_STATUS_ERROR:
          455  +        tDOM_CleanupInputSource (pullInfo);
          456  +        tDOM_ReportXMLError (interp, pullInfo);
          457  +        pullInfo->state = PULLPARSERSTATE_PARSE_ERROR;
          458  +        return TCL_ERROR;
          459  +    case XML_STATUS_SUSPENDED:
          460  +        /* Nothing to do here, state was set in handler, just
          461  +         * take care to report */
          462  +        break;
          463  +    }
          464  +    
          465  +    return TCL_OK;
          466  +}
          467  +
          468  +static int
          469  +tDOM_PullParserInstanceCmd (
          470  +    ClientData  clientdata,
          471  +    Tcl_Interp *interp,
          472  +    int         objc,
          473  +    Tcl_Obj    *const objv[]
          474  +    )
          475  +{
          476  +    tDOM_PullParserInfo *pullInfo = clientdata;
          477  +    int methodIndex, len, result, mode, fd;
          478  +    char *data;
          479  +    const char **atts;
          480  +    Tcl_Obj *resultPtr;
          481  +    Tcl_Channel channel;
          482  +    
          483  +    static const char *const methods[] = {
          484  +        "input", "inputchannel", "inputfile",
          485  +        "next", "state", "tag", "attributes",
          486  +        "text", "delete", "reset", "skip",
          487  +        "find-element", "line", "column", NULL
          488  +    };
          489  +
          490  +    enum method {
          491  +        m_input, m_inputchannel, m_inputfile,
          492  +        m_next, m_state, m_tag, m_attributes,
          493  +        m_text, m_delete, m_reset, m_skip,
          494  +        m_find_element, m_line, m_column
          495  +    };
          496  +
          497  +    if (objc == 1) {
          498  +        /* Default method call is next */
          499  +        methodIndex = m_next;
          500  +    } else {
          501  +        if (Tcl_GetIndexFromObj (interp, objv[1], methods, "method", 0,
          502  +                                 &methodIndex) != TCL_OK) {
          503  +            return TCL_ERROR;
          504  +        }
          505  +    }
          506  +    switch ((enum method) methodIndex) {
          507  +
          508  +    case m_input:
          509  +        if (objc != 3) {
          510  +            Tcl_WrongNumArgs (interp, 2, objv, "<xml>");
          511  +            return TCL_ERROR;
          512  +        }
          513  +        if (pullInfo->state != PULLPARSERSTATE_READY) {
          514  +            SetResult ("Can't change input while already parsing.");
          515  +            return TCL_ERROR;
          516  +        }
          517  +        Tcl_IncrRefCount (objv[2]);
          518  +        pullInfo->inputString = objv[2];
          519  +        pullInfo->state = PULLPARSERSTATE_START_DOCUMENT;
          520  +        break;
          521  +
          522  +    case m_inputchannel:
          523  +        if (objc != 3) {
          524  +            Tcl_WrongNumArgs (interp, 2, objv, "<channel>");
          525  +            return TCL_ERROR;
          526  +        }
          527  +        if (pullInfo->state != PULLPARSERSTATE_READY) {
          528  +            SetResult ("Can't change input while already parsing.");
          529  +            return TCL_ERROR;
          530  +        }
          531  +        channel = Tcl_GetChannel (interp, Tcl_GetString(objv[2]), &mode);
          532  +        if (channel == NULL) {
          533  +            Tcl_ResetResult (interp);
          534  +            Tcl_AppendResult (interp, "\"", Tcl_GetString(objv[2]),
          535  +                              "\" isn't a Tcl channel in this interpreter", 
          536  +                              NULL);
          537  +            return TCL_ERROR;
          538  +        }
          539  +        if (!(mode & TCL_READABLE)) {
          540  +            Tcl_ResetResult (interp);
          541  +            Tcl_AppendResult (interp, "channel \"", Tcl_GetString(objv[2]),
          542  +                              "wasn't opened for reading", NULL);
          543  +            return TCL_ERROR;
          544  +        }
          545  +        pullInfo->inputChannel = channel;
          546  +        if (pullInfo->channelReadBuf == NULL) {
          547  +            pullInfo->channelReadBuf = Tcl_NewObj ();
          548  +            Tcl_IncrRefCount (pullInfo->channelReadBuf);
          549  +            Tcl_SetObjLength (pullInfo->channelReadBuf, 6144);
          550  +        }
          551  +        pullInfo->state = PULLPARSERSTATE_START_DOCUMENT;
          552  +        break;
          553  +
          554  +    case m_inputfile:
          555  +        if (objc != 3) {
          556  +            Tcl_WrongNumArgs (interp, 2, objv, "<filename>");
          557  +            return TCL_ERROR;
          558  +        }
          559  +        if (pullInfo->state != PULLPARSERSTATE_READY) {
          560  +            SetResult ("Can't change input while already parsing.");
          561  +            return TCL_ERROR;
          562  +        }
          563  +        fd = open(Tcl_GetString(objv[2]), O_BINARY|O_RDONLY);
          564  +        if (fd < 0) {
          565  +            Tcl_ResetResult (interp);
          566  +            Tcl_AppendResult (interp, "error opening file \"",
          567  +                              Tcl_GetString(objv[2]), "\"", NULL);
          568  +            return TCL_ERROR;
          569  +        }
          570  +        pullInfo->inputfd = fd;
          571  +        pullInfo->state = PULLPARSERSTATE_START_DOCUMENT;
          572  +        break;
          573  +
          574  +    case m_next:
          575  +        if (objc != 2) {
          576  +            Tcl_WrongNumArgs (interp, 2, objv, "");
          577  +            return TCL_ERROR;
          578  +        }
          579  +        if (pullInfo->state == PULLPARSERSTATE_TEXT) {
          580  +            Tcl_DStringSetLength (pullInfo->cdata, 0);
          581  +        }
          582  +        if (pullInfo->next2State) {
          583  +            pullInfo->state = pullInfo->nextState;
          584  +            pullInfo->nextState = pullInfo->next2State;
          585  +            pullInfo->next2State = 0;
          586  +        } else if (pullInfo->nextState) {
          587  +            pullInfo->state = pullInfo->nextState;
          588  +            pullInfo->nextState = 0;
          589  +        } else {
          590  +            switch (pullInfo->state) {
          591  +            case PULLPARSERSTATE_READY:
          592  +                SetResult ("No input");
          593  +                return TCL_ERROR;
          594  +            case PULLPARSERSTATE_PARSE_ERROR:
          595  +                SetResult ("Parsing stopped with XML parsing error.");
          596  +                return TCL_ERROR;
          597  +            case PULLPARSERSTATE_END_DOCUMENT:
          598  +                SetResult ("No next event after END_DOCUMENT");
          599  +                return TCL_ERROR;
          600  +            case PULLPARSERSTATE_TEXT:
          601  +                /* Since PULLPARSERSTATE_TEXT always has nextState set
          602  +                 * this case is handled in the if part of this if else
          603  +                 * and this is never reached. It's just here to eat up
          604  +                 * this case in the switch. */
          605  +                break;
          606  +            case PULLPARSERSTATE_START_DOCUMENT:
          607  +                if (pullInfo->inputfd) {
          608  +                    do {
          609  +                        char *fbuf =
          610  +                            XML_GetBuffer (pullInfo->parser,
          611  +                                           TDOM_EXPAT_READ_SIZE);
          612  +                        len = read(pullInfo->inputfd, fbuf,
          613  +                                   TDOM_EXPAT_READ_SIZE);
          614  +                        result = XML_ParseBuffer (pullInfo->parser,
          615  +                                                  len, len == 0);
          616  +                    } while (result == XML_STATUS_OK);
          617  +                } else if (pullInfo->inputChannel) {
          618  +                    do {
          619  +                        len = Tcl_ReadChars (pullInfo->inputChannel,
          620  +                                             pullInfo->channelReadBuf,
          621  +                                             1024, 0);
          622  +                        data = Tcl_GetString (pullInfo->channelReadBuf);
          623  +                        result = XML_Parse (pullInfo->parser, data, len,
          624  +                                            len == 0);
          625  +                    } while (result == XML_STATUS_OK);
          626  +                } else {
          627  +                    data = Tcl_GetStringFromObj(pullInfo->inputString, &len);
          628  +                    result = XML_Parse (pullInfo->parser, data, len, 1);
          629  +                }
          630  +                switch (result) {
          631  +                case XML_STATUS_OK:
          632  +                    tDOM_CleanupInputSource (pullInfo);
          633  +                    pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
          634  +                    break;
          635  +                case XML_STATUS_ERROR:
          636  +                    tDOM_CleanupInputSource (pullInfo);
          637  +                    tDOM_ReportXMLError (interp, pullInfo);
          638  +                    pullInfo->state = PULLPARSERSTATE_PARSE_ERROR;
          639  +                    return TCL_ERROR;
          640  +                case XML_STATUS_SUSPENDED:
          641  +                    /* Nothing to do here, state was set in handler, just
          642  +                     * take care to report */
          643  +                    break;
          644  +                }
          645  +                break;
          646  +            default:
          647  +                DBG (printParserState(pullInfo->parser));
          648  +                if (tDOM_resumeParseing (interp, pullInfo) != TCL_OK) {
          649  +                    return TCL_ERROR;
          650  +                }
          651  +                DBG (printParserState(pullInfo->parser));
          652  +                break;
          653  +            }
          654  +        }
          655  +        /* Fall throu to reporting state */
          656  +    case m_state:
          657  +        if (objc != 2) {
          658  +            Tcl_WrongNumArgs (interp, 2, objv, "");
          659  +            return TCL_ERROR;
          660  +        }
          661  +        switch (pullInfo->state) {
          662  +        case PULLPARSERSTATE_READY:
          663  +            SetResult("READY");
          664  +            break;
          665  +        case PULLPARSERSTATE_PARSE_ERROR:
          666  +            SetResult("PARSE_ERROR");
          667  +            break;
          668  +        case PULLPARSERSTATE_START_DOCUMENT:
          669  +            SetResult("START_DOCUMENT");
          670  +            break;
          671  +        case PULLPARSERSTATE_END_DOCUMENT:
          672  +            SetResult("END_DOCUMENT");
          673  +            break;
          674  +        case PULLPARSERSTATE_START_TAG:
          675  +            Tcl_SetObjResult (interp, pullInfo->start_tag);
          676  +            break;
          677  +        case PULLPARSERSTATE_END_TAG:
          678  +            Tcl_SetObjResult (interp, pullInfo->end_tag);
          679  +            break;
          680  +        case PULLPARSERSTATE_TEXT:
          681  +            Tcl_SetObjResult (interp, pullInfo->text);
          682  +            break;
          683  +        }
          684  +        break;
          685  +
          686  +    case m_tag:
          687  +        if (objc != 2) {
          688  +            Tcl_WrongNumArgs (interp, 2, objv, "");
          689  +            return TCL_ERROR;
          690  +        }
          691  +        if (pullInfo->state != PULLPARSERSTATE_START_TAG
          692  +            && pullInfo->state != PULLPARSERSTATE_END_TAG) {
          693  +            SetResult("Invalid state");
          694  +            return TCL_ERROR;
          695  +        }
          696  +        Tcl_SetObjResult (interp, pullInfo->currentElm);
          697  +        break;
          698  +
          699  +    case m_attributes:
          700  +        if (objc != 2) {
          701  +            Tcl_WrongNumArgs (interp, 2, objv, "");
          702  +            return TCL_ERROR;
          703  +        }
          704  +        if (pullInfo->state != PULLPARSERSTATE_START_TAG) {
          705  +            SetResult("Invalid state - attribute method is only valid in state START_TAG.");
          706  +            return TCL_ERROR;
          707  +        }
          708  +        Tcl_ResetResult(interp);
          709  +        resultPtr = Tcl_GetObjResult(interp);
          710  +        atts = pullInfo->atts;
          711  +        while (atts[0] != NULL) {
          712  +            Tcl_ListObjAppendElement (interp, resultPtr,
          713  +                                      Tcl_NewStringObj(atts[0], -1));
          714  +            atts++;
          715  +        }
          716  +        break;
          717  +
          718  +    case m_text:
          719  +        if (objc != 2) {
          720  +            Tcl_WrongNumArgs (interp, 2, objv, "");
          721  +            return TCL_ERROR;
          722  +        }
          723  +        Tcl_ResetResult (interp);
          724  +        Tcl_SetStringObj (
          725  +            Tcl_GetObjResult (interp),
          726  +            Tcl_DStringValue (pullInfo->cdata),
          727  +            Tcl_DStringLength (pullInfo->cdata)
          728  +            );
          729  +        break;
          730  +
          731  +    case m_skip:
          732  +        if (objc != 2) {
          733  +            Tcl_WrongNumArgs (interp, 2, objv, "");
          734  +            return TCL_ERROR;
          735  +        }
          736  +        if (pullInfo->state != PULLPARSERSTATE_START_TAG) {
          737  +            SetResult("Invalid state - skip method is only valid in state START_TAG.");
          738  +            return TCL_ERROR;
          739  +        }
          740  +        if (pullInfo->nextState == PULLPARSERSTATE_END_TAG
          741  +            || pullInfo->next2State == PULLPARSERSTATE_END_TAG) {
          742  +            pullInfo->state = PULLPARSERSTATE_END_TAG;
          743  +#ifdef EXPAT_RESUME_BUG
          744  +            if (pullInfo->next2State == PULLPARSERSTATE_END_DOCUMENT) {
          745  +                pullInfo->nextState = PULLPARSERSTATE_END_DOCUMENT;
          746  +            } else {
          747  +                pullInfo->nextState = 0;
          748  +            }
          749  +#else            
          750  +            pullInfo->nextState = 0;
          751  +#endif            
          752  +            pullInfo->next2State = 0;
          753  +            Tcl_DStringSetLength (pullInfo->cdata, 0);
          754  +            Tcl_SetObjResult (interp, pullInfo->end_tag);
          755  +            break;
          756  +        }
          757  +        pullInfo->mode = PULLPARSEMODE_SKIP;
          758  +        pullInfo->skipDepth = 0;
          759  +        Tcl_DStringSetLength (pullInfo->cdata, 0);
          760  +        XML_SetCharacterDataHandler (pullInfo->parser, NULL);
          761  +        if (tDOM_resumeParseing (interp, pullInfo) != TCL_OK) {
          762  +            return TCL_ERROR;
          763  +        }
          764  +        Tcl_SetObjResult (interp, pullInfo->end_tag);
          765  +        break;
          766  +        
          767  +    case m_find_element:
          768  +        if (objc != 3) {
          769  +            Tcl_WrongNumArgs (interp, 2, objv, "elementName");
          770  +            return TCL_ERROR;
          771  +        }
          772  +        if (pullInfo->state != PULLPARSERSTATE_START_TAG
          773  +            && pullInfo->state != PULLPARSERSTATE_END_TAG
          774  +            && pullInfo->state != PULLPARSERSTATE_START_DOCUMENT) {
          775  +            SetResult("Invalid state - find-element method is only valid in states "
          776  +                      "START_DOCUMENT, START_TAG and END_TAG.");
          777  +            return TCL_ERROR;
          778  +        }
          779  +#ifdef EXPAT_RESUME_BUG
          780  +        if (pullInfo->state == PULLPARSERSTATE_END_TAG
          781  +            && pullInfo->nextState == PULLPARSERSTATE_END_DOCUMENT) {
          782  +            pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
          783  +            SetResult ("END_DOCUMENT");
          784  +            break;
          785  +        }
          786  +#endif
          787  +        pullInfo->mode = PULLPARSEMODE_FIND;
          788  +        /* As long as we don't evalute any tcl script code during a
          789  +         * pull parser method call this should be secure. */
          790  +        pullInfo->findElement = Tcl_GetString (objv[2]);
          791  +        Tcl_DStringSetLength (pullInfo->cdata, 0);
          792  +        XML_SetCharacterDataHandler (pullInfo->parser, NULL);
          793  +        XML_SetEndElementHandler (pullInfo->parser, NULL);
          794  +        if (pullInfo->state == PULLPARSERSTATE_START_DOCUMENT) {
          795  +            Tcl_Obj * thisObjv[2];
          796  +            Tcl_Obj * thisMethod = Tcl_NewStringObj ("next", 4);
          797  +            Tcl_IncrRefCount (thisMethod);
          798  +            thisObjv[0] = objv[0];
          799  +            thisObjv[1] = thisMethod;
          800  +            result = tDOM_PullParserInstanceCmd (pullInfo, interp, 2,
          801  +                                                 thisObjv);
          802  +            Tcl_DecrRefCount (thisMethod);
          803  +            if (result != TCL_OK) {
          804  +                return TCL_ERROR;
          805  +            }
          806  +        } else {
          807  +            if (tDOM_resumeParseing (interp, pullInfo) != TCL_OK) {
          808  +                return TCL_ERROR;
          809  +            }
          810  +        }
          811  +        if (pullInfo->state == PULLPARSERSTATE_START_TAG) {
          812  +            Tcl_SetObjResult (interp, pullInfo->start_tag);
          813  +        } else {
          814  +            SetResult ("END_DOCUMENT");
          815  +        }
          816  +        break;
          817  +
          818  +    case m_line:
          819  +    case m_column:
          820  +        if (objc != 2) {
          821  +            Tcl_WrongNumArgs (interp, 2, objv, "");
          822  +            return TCL_ERROR;
          823  +        }
          824  +        switch (pullInfo->state) {
          825  +        case PULLPARSERSTATE_READY:
          826  +            SetResult("No input");
          827  +            return TCL_ERROR;
          828  +        case PULLPARSERSTATE_TEXT:
          829  +            SetResult("Invalid state");
          830  +            return TCL_ERROR;
          831  +        case PULLPARSERSTATE_END_TAG:
          832  +        case PULLPARSERSTATE_START_TAG:
          833  +        case PULLPARSERSTATE_END_DOCUMENT:
          834  +        case PULLPARSERSTATE_PARSE_ERROR:
          835  +            if ((enum method) methodIndex == m_line) {
          836  +                Tcl_SetObjResult(interp,
          837  +                    Tcl_NewIntObj (XML_GetCurrentLineNumber(pullInfo->parser)));
          838  +            } else {
          839  +                Tcl_SetObjResult(interp,
          840  +                    Tcl_NewIntObj (XML_GetCurrentColumnNumber(pullInfo->parser)));
          841  +            }
          842  +            break;
          843  +        case PULLPARSERSTATE_START_DOCUMENT:
          844  +            Tcl_SetObjResult(interp, Tcl_NewIntObj (0));
          845  +            break;
          846  +        }
          847  +        break;
          848  +        
          849  +    case m_delete:
          850  +        if (objc != 2) {
          851  +            Tcl_WrongNumArgs (interp, 2, objv, "");
          852  +            return TCL_ERROR;
          853  +        }
          854  +        Tcl_DeleteCommand (interp, Tcl_GetString (objv[0]));
          855  +        break;
          856  +
          857  +    case m_reset:
          858  +        if (objc != 2) {
          859  +            Tcl_WrongNumArgs (interp, 2, objv, "");
          860  +            return TCL_ERROR;
          861  +        }
          862  +        tDOM_CleanupInputSource (pullInfo);
          863  +        pullInfo->state = PULLPARSERSTATE_READY;
          864  +        pullInfo->nextState = 0;
          865  +        Tcl_DStringSetLength (pullInfo->cdata, 0);
          866  +        if (XML_ParserReset (pullInfo->parser, NULL) != XML_TRUE) {
          867  +            SetResult ("Parser reset failed!");
          868  +            return TCL_ERROR;
          869  +        }
          870  +        XML_SetElementHandler (pullInfo->parser, startElement, endElement);
          871  +        XML_SetUserData (pullInfo->parser, pullInfo);
          872  +        break;
          873  +        
          874  +    }
          875  +
          876  +    return TCL_OK;
          877  +}
          878  +
          879  +
          880  +int
          881  +tDOM_PullParserCmd (
          882  +    ClientData  dummy,
          883  +    Tcl_Interp *interp,
          884  +    int         objc,
          885  +    Tcl_Obj    *const objv[]
          886  +    )
          887  +{
          888  +    tDOM_PullParserInfo *pullInfo;
          889  +    int flagIndex, ignoreWhiteSpaces = 0;
          890  +
          891  +    static const char *const flags[] = {
          892  +        "-ignorewhitecdata", NULL
          893  +    };
          894  +    
          895  +    enum flag {
          896  +        f_ignoreWhiteSpaces
          897  +    };
          898  +
          899  +    if (objc < 2 || objc > 3) {
          900  +        Tcl_WrongNumArgs (interp, 1, objv, "cmdName ?-ignorewhitecdata?");
          901  +        return TCL_ERROR;
          902  +    }
          903  +
          904  +    if (objc == 3) {
          905  +        if (Tcl_GetIndexFromObj (interp, objv[2], flags, "flag", 0,
          906  +                                 &flagIndex) != TCL_OK) {
          907  +            return TCL_ERROR;
          908  +        }
          909  +        switch ((enum flag) flagIndex) {
          910  +        case f_ignoreWhiteSpaces:
          911  +            ignoreWhiteSpaces = 1;
          912  +            break;
          913  +        }
          914  +    }
          915  +    
          916  +    pullInfo = (tDOM_PullParserInfo *) MALLOC(sizeof(tDOM_PullParserInfo));
          917  +    memset (pullInfo, 0, sizeof (tDOM_PullParserInfo));
          918  +
          919  +    pullInfo->parser = XML_ParserCreate_MM(NULL, MEM_SUITE, NULL);
          920  +    XML_SetUserData (pullInfo->parser, pullInfo);
          921  +    XML_SetElementHandler (pullInfo->parser, startElement, endElement);
          922  +    XML_SetCharacterDataHandler (pullInfo->parser, characterDataHandler);
          923  +    pullInfo->cdata = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
          924  +    Tcl_DStringInit (pullInfo->cdata);
          925  +    pullInfo->state = PULLPARSERSTATE_READY;
          926  +    pullInfo->start_tag = Tcl_NewStringObj("START_TAG", 9);
          927  +    Tcl_IncrRefCount (pullInfo->start_tag);
          928  +    pullInfo->end_tag = Tcl_NewStringObj("END_TAG", 7);
          929  +    Tcl_IncrRefCount (pullInfo->end_tag);
          930  +    pullInfo->text = Tcl_NewStringObj("TEXT", 4);
          931  +    Tcl_IncrRefCount (pullInfo->text);
          932  +    pullInfo->ignoreWhiteSpaces = ignoreWhiteSpaces;
          933  +    pullInfo->elmCache = (Tcl_HashTable *)MALLOC(sizeof (Tcl_HashTable));
          934  +    Tcl_InitHashTable(pullInfo->elmCache, TCL_STRING_KEYS);
          935  +    pullInfo->mode = PULLPARSEMODE_NORMAL;
          936  +#ifdef EXPAT_RESUME_BUG
          937  +    pullInfo->elmStartCounter = 0;
          938  +#endif
          939  +    
          940  +    Tcl_CreateObjCommand (interp, Tcl_GetString(objv[1]),
          941  +                          tDOM_PullParserInstanceCmd, (ClientData) pullInfo,
          942  +                          tDOM_PullParserDeleteCmd);
          943  +    Tcl_SetObjResult(interp, objv[1]);
          944  +    return TCL_OK;
          945  +}
          946  +
          947  +#endif /* ifndef TDOM_NO_PULL */

Added generic/tclpull.h.

            1  +
            2  +int tDOM_PullParserCmd (ClientData dummy, Tcl_Interp *interp, int objc,
            3  +                        Tcl_Obj *const objv[]);

Changes to generic/tdom.decls.

     7      7   
     8      8   library tdom
     9      9   interface tdom
    10     10   #hooks {}
    11     11   
    12     12   declare 0 generic {
    13     13       int TclExpatObjCmd (ClientData dummy, Tcl_Interp *interp, 
    14         -                        int objc, Tcl_Obj *CONST objv[])
           14  +                        int objc, Tcl_Obj *const objv[])
    15     15   }
    16     16   declare 1 generic {
    17         -    int CheckExpatParserObj (Tcl_Interp *interp, Tcl_Obj *CONST nameObj)
           17  +    int CheckExpatParserObj (Tcl_Interp *interp, Tcl_Obj *const nameObj)
    18     18   }
    19     19   declare 2 generic {
    20         -     int CHandlerSetInstall (Tcl_Interp *interp, Tcl_Obj *CONST expatObj,
           20  +     int CHandlerSetInstall (Tcl_Interp *interp, Tcl_Obj *const expatObj,
    21     21                                CHandlerSet *handlerSet)
    22     22   }
    23     23   declare 3 generic {
    24         -     int CHandlerSetRemove (Tcl_Interp *interp, Tcl_Obj *CONST expatObj,
           24  +     int CHandlerSetRemove (Tcl_Interp *interp, Tcl_Obj *const expatObj,
    25     25                               char *handlerSetName)
    26     26   }
    27     27   declare 4 generic {
    28     28        CHandlerSet * CHandlerSetCreate (char *name)
    29     29   }
    30     30   declare 5 generic {
    31         -     CHandlerSet * CHandlerSetGet (Tcl_Interp *interp, Tcl_Obj *CONST expatObj,
           31  +     CHandlerSet * CHandlerSetGet (Tcl_Interp *interp, Tcl_Obj *const expatObj,
    32     32                                      char *handlerSetName)
    33     33   }
    34     34   declare 6 generic {
    35     35        void * CHandlerSetGetUserData (Tcl_Interp *interp, 
    36         -                                    Tcl_Obj *CONST expatObj,
           36  +                                    Tcl_Obj *const expatObj,
    37     37                                       char *handlerSetName)
    38     38   }
    39     39   declare 7 generic {
    40     40        TclGenExpatInfo * GetExpatInfo (Tcl_Interp *interp,
    41         -                                     Tcl_Obj *CONST expatObj)
           41  +                                     Tcl_Obj *const expatObj)
    42     42   }
    43     43   declare 8 generic {
    44     44        XML_Size XML_GetCurrentLineNumber(XML_Parser parser)
    45     45   }
    46     46   declare 9 generic {
    47     47        XML_Size XML_GetCurrentColumnNumber(XML_Parser parser)
    48     48   }

Changes to generic/tdom.h.

    13     13   
    14     14   typedef struct CHandlerSet {
    15     15       struct CHandlerSet *nextHandlerSet;
    16     16       char *name;                     /* refname of the handler set */
    17     17       int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */
    18     18   
    19     19       void *userData;                 /* Handler set specific Data Structure;
    20         -                                       the C handler set extention has to
           20  +                                       the C handler set extension has to
    21     21                                          malloc the needed structure in his
    22     22                                          init func and has to provide a
    23     23                                          cleanup func (to free it). */
    24     24   
    25     25       CHandlerSet_userDataReset        resetProc;
    26     26       CHandlerSet_userDataFree         freeProc;
    27     27       CHandlerSet_parserReset          parserResetProc;

Changes to generic/tdomDecls.h.

     1      1   
     2         -/* This is generated by the getStubs.tcl tool (see the tcl distribution)
            2  +/* This is generated by the genStubs.tcl tool (see the tcl distribution)
     3      3      out of the tdom.decls file */
     4      4   
     5      5   
     6      6   /* !BEGIN!: Do not edit below this line. */
            7  +
            8  +#ifdef __cplusplus
            9  +extern "C" {
           10  +#endif
     7     11   
     8     12   /*
     9     13    * Exported function declarations:
    10     14    */
    11     15   
    12     16   /* 0 */
    13         -EXTERN int		TclExpatObjCmd _ANSI_ARGS_((ClientData dummy, 
    14         -				Tcl_Interp * interp, int objc, 
    15         -				Tcl_Obj *CONST objv[]));
           17  +EXTERN int		TclExpatObjCmd(ClientData dummy, Tcl_Interp *interp,
           18  +				int objc, Tcl_Obj *const objv[]);
    16     19   /* 1 */
    17         -EXTERN int		CheckExpatParserObj _ANSI_ARGS_((Tcl_Interp * interp, 
    18         -				Tcl_Obj *CONST nameObj));
           20  +EXTERN int		CheckExpatParserObj(Tcl_Interp *interp,
           21  +				Tcl_Obj *const nameObj);
    19     22   /* 2 */
    20         -EXTERN int		CHandlerSetInstall _ANSI_ARGS_((Tcl_Interp * interp, 
    21         -				Tcl_Obj *CONST expatObj, 
    22         -				CHandlerSet * handlerSet));
           23  +EXTERN int		CHandlerSetInstall(Tcl_Interp *interp,
           24  +				Tcl_Obj *const expatObj, 
           25  +				CHandlerSet *handlerSet);
    23     26   /* 3 */
    24         -EXTERN int		CHandlerSetRemove _ANSI_ARGS_((Tcl_Interp * interp, 
    25         -				Tcl_Obj *CONST expatObj, 
    26         -				char * handlerSetName));
           27  +EXTERN int		CHandlerSetRemove(Tcl_Interp *interp,
           28  +				Tcl_Obj *const expatObj, 
           29  +				char *handlerSetName);
    27     30   /* 4 */
    28         -EXTERN CHandlerSet *	CHandlerSetCreate _ANSI_ARGS_((char * name));
           31  +EXTERN CHandlerSet *	CHandlerSetCreate(char *name);
    29     32   /* 5 */
    30         -EXTERN CHandlerSet *	CHandlerSetGet _ANSI_ARGS_((Tcl_Interp * interp, 
    31         -				Tcl_Obj *CONST expatObj, 
    32         -				char * handlerSetName));
           33  +EXTERN CHandlerSet *	CHandlerSetGet(Tcl_Interp *interp,
           34  +				Tcl_Obj *const expatObj, 
           35  +				char *handlerSetName);
    33     36   /* 6 */
    34         -EXTERN void *		CHandlerSetGetUserData _ANSI_ARGS_((
    35         -				Tcl_Interp * interp, Tcl_Obj *CONST expatObj, 
    36         -				char * handlerSetName));
           37  +EXTERN void *		CHandlerSetGetUserData(Tcl_Interp *interp,
           38  +				Tcl_Obj *const expatObj,
           39  +				char *handlerSetName);
    37     40   /* 7 */
    38         -EXTERN TclGenExpatInfo * GetExpatInfo _ANSI_ARGS_((Tcl_Interp * interp, 
    39         -				Tcl_Obj *CONST expatObj));
           41  +EXTERN TclGenExpatInfo * GetExpatInfo(Tcl_Interp *interp,
           42  +				Tcl_Obj *const expatObj);
    40     43   /* 8 */
    41         -EXTERN XML_Size		XML_GetCurrentLineNumber _ANSI_ARGS_((
    42         -				XML_Parser parser));
           44  +EXTERN XML_Size		XML_GetCurrentLineNumber(XML_Parser parser);
    43     45   /* 9 */
    44         -EXTERN XML_Size		XML_GetCurrentColumnNumber _ANSI_ARGS_((
    45         -				XML_Parser parser));
           46  +EXTERN XML_Size		XML_GetCurrentColumnNumber(XML_Parser parser);
    46     47   /* 10 */
    47         -EXTERN XML_Index	XML_GetCurrentByteIndex _ANSI_ARGS_((
    48         -				XML_Parser parser));
           48  +EXTERN XML_Index	XML_GetCurrentByteIndex(XML_Parser parser);
    49     49   /* 11 */
    50         -EXTERN int		XML_GetCurrentByteCount _ANSI_ARGS_((
    51         -				XML_Parser parser));
           50  +EXTERN int		XML_GetCurrentByteCount(XML_Parser parser);
    52     51   /* 12 */
    53         -EXTERN enum XML_Status	XML_SetBase _ANSI_ARGS_((XML_Parser parser, 
    54         -				const XML_Char * base));
           52  +EXTERN enum XML_Status	XML_SetBase(XML_Parser parser, const XML_Char *base);
    55     53   /* 13 */
    56         -EXTERN const XML_Char *	 XML_GetBase _ANSI_ARGS_((XML_Parser parser));
           54  +EXTERN const XML_Char *	 XML_GetBase(XML_Parser parser);
    57     55   /* 14 */
    58         -EXTERN int		XML_GetSpecifiedAttributeCount _ANSI_ARGS_((
    59         -				XML_Parser parser));
           56  +EXTERN int		XML_GetSpecifiedAttributeCount(XML_Parser parser);
    60     57   /* 15 */
    61         -EXTERN int		XML_GetIdAttributeIndex _ANSI_ARGS_((
    62         -				XML_Parser parser));
           58  +EXTERN int		XML_GetIdAttributeIndex(XML_Parser parser);
    63     59   /* 16 */
    64         -EXTERN domNode *	tcldom_getNodeFromName _ANSI_ARGS_((
    65         -				Tcl_Interp * interp, char * nodeName, 
    66         -				char ** errMsg));
           60  +EXTERN domNode *	tcldom_getNodeFromName(Tcl_Interp *interp,
           61  +				char *nodeName, char **errMsg);
    67     62   /* 17 */
    68         -EXTERN domDocument *	tcldom_getDocumentFromName _ANSI_ARGS_((
    69         -				Tcl_Interp * interp, char * docName, 
    70         -				char ** errMsg));
           63  +EXTERN domDocument *	tcldom_getDocumentFromName(Tcl_Interp *interp,
           64  +				char *docName, char **errMsg);
    71     65   
    72     66   typedef struct TdomStubs {
    73     67       int magic;
    74         -    struct TdomStubHooks *hooks;
           68  +    void *hooks;
    75     69   
    76         -    int (*tclExpatObjCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 0 */
    77         -    int (*checkExpatParserObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST nameObj)); /* 1 */
    78         -    int (*cHandlerSetInstall) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj, CHandlerSet * handlerSet)); /* 2 */
    79         -    int (*cHandlerSetRemove) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj, char * handlerSetName)); /* 3 */
    80         -    CHandlerSet * (*cHandlerSetCreate) _ANSI_ARGS_((char * name)); /* 4 */
    81         -    CHandlerSet * (*cHandlerSetGet) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj, char * handlerSetName)); /* 5 */
    82         -    void * (*cHandlerSetGetUserData) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj, char * handlerSetName)); /* 6 */
    83         -    TclGenExpatInfo * (*getExpatInfo) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj)); /* 7 */
    84         -    XML_Size (*xML_GetCurrentLineNumber) _ANSI_ARGS_((XML_Parser parser)); /* 8 */
    85         -    XML_Size (*xML_GetCurrentColumnNumber) _ANSI_ARGS_((XML_Parser parser)); /* 9 */
    86         -    XML_Index (*xML_GetCurrentByteIndex) _ANSI_ARGS_((XML_Parser parser)); /* 10 */
    87         -    int (*xML_GetCurrentByteCount) _ANSI_ARGS_((XML_Parser parser)); /* 11 */
    88         -    enum XML_Status (*xML_SetBase) _ANSI_ARGS_((XML_Parser parser, const XML_Char * base)); /* 12 */
    89         -    const XML_Char * (*xML_GetBase) _ANSI_ARGS_((XML_Parser parser)); /* 13 */
    90         -    int (*xML_GetSpecifiedAttributeCount) _ANSI_ARGS_((XML_Parser parser)); /* 14 */
    91         -    int (*xML_GetIdAttributeIndex) _ANSI_ARGS_((XML_Parser parser)); /* 15 */
    92         -    domNode * (*tcldom_getNodeFromName) _ANSI_ARGS_((Tcl_Interp * interp, char * nodeName, char ** errMsg)); /* 16 */
    93         -    domDocument * (*tcldom_getDocumentFromName) _ANSI_ARGS_((Tcl_Interp * interp, char * docName, char ** errMsg)); /* 17 */
           70  +    int (*tclExpatObjCmd) (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 0 */
           71  +    int (*checkExpatParserObj) (Tcl_Interp *interp, Tcl_Obj *const nameObj); /* 1 */
           72  +    int (*cHandlerSetInstall) (Tcl_Interp *interp, Tcl_Obj *const expatObj, CHandlerSet *handlerSet); /* 2 */
           73  +    int (*cHandlerSetRemove) (Tcl_Interp *interp, Tcl_Obj *const expatObj, char *handlerSetName); /* 3 */
           74  +    CHandlerSet * (*cHandlerSetCreate) (char *name); /* 4 */
           75  +    CHandlerSet * (*cHandlerSetGet) (Tcl_Interp *interp, Tcl_Obj *const expatObj, char *handlerSetName); /* 5 */
           76  +    void * (*cHandlerSetGetUserData) (Tcl_Interp *interp, Tcl_Obj *const expatObj, char *handlerSetName); /* 6 */
           77  +    TclGenExpatInfo * (*getExpatInfo) (Tcl_Interp *interp, Tcl_Obj *const expatObj); /* 7 */
           78  +    XML_Size (*xML_GetCurrentLineNumber) (XML_Parser parser); /* 8 */
           79  +    XML_Size (*xML_GetCurrentColumnNumber) (XML_Parser parser); /* 9 */
           80  +    XML_Index (*xML_GetCurrentByteIndex) (XML_Parser parser); /* 10 */
           81  +    int (*xML_GetCurrentByteCount) (XML_Parser parser); /* 11 */
           82  +    enum XML_Status (*xML_SetBase) (XML_Parser parser, const XML_Char *base); /* 12 */
           83  +    const XML_Char * (*xML_GetBase) (XML_Parser parser); /* 13 */
           84  +    int (*xML_GetSpecifiedAttributeCount) (XML_Parser parser); /* 14 */
           85  +    int (*xML_GetIdAttributeIndex) (XML_Parser parser); /* 15 */
           86  +    domNode * (*tcldom_getNodeFromName) (Tcl_Interp *interp, char *nodeName, char **errMsg); /* 16 */
           87  +    domDocument * (*tcldom_getDocumentFromName) (Tcl_Interp *interp, char *docName, char **errMsg); /* 17 */
    94     88   } TdomStubs;
    95     89   
    96         -#ifdef __cplusplus
    97         -extern "C" {
    98         -#endif
    99         -extern TdomStubs *tdomStubsPtr;
           90  +extern const TdomStubs *tdomStubsPtr;
           91  +
   100     92   #ifdef __cplusplus
   101     93   }
   102     94   #endif
   103     95   
   104         -#if defined(USE_TDOM_STUBS) && !defined(USE_TDOM_STUB_PROCS)
           96  +#if defined(USE_TDOM_STUBS)
   105     97   
   106     98   /*
   107     99    * Inline function declarations:
   108    100    */
   109    101   
   110         -#ifndef TclExpatObjCmd
   111    102   #define TclExpatObjCmd \
   112    103   	(tdomStubsPtr->tclExpatObjCmd) /* 0 */
   113         -#endif
   114         -#ifndef CheckExpatParserObj
   115    104   #define CheckExpatParserObj \
   116    105   	(tdomStubsPtr->checkExpatParserObj) /* 1 */
   117         -#endif
   118         -#ifndef CHandlerSetInstall
   119    106   #define CHandlerSetInstall \
   120    107   	(tdomStubsPtr->cHandlerSetInstall) /* 2 */
   121         -#endif
   122         -#ifndef CHandlerSetRemove
   123    108   #define CHandlerSetRemove \
   124    109   	(tdomStubsPtr->cHandlerSetRemove) /* 3 */
   125         -#endif
   126         -#ifndef CHandlerSetCreate
   127    110   #define CHandlerSetCreate \
   128    111   	(tdomStubsPtr->cHandlerSetCreate) /* 4 */
   129         -#endif
   130         -#ifndef CHandlerSetGet
   131    112   #define CHandlerSetGet \
   132    113   	(tdomStubsPtr->cHandlerSetGet) /* 5 */
   133         -#endif
   134         -#ifndef CHandlerSetGetUserData
   135    114   #define CHandlerSetGetUserData \
   136    115   	(tdomStubsPtr->cHandlerSetGetUserData) /* 6 */
   137         -#endif
   138         -#ifndef GetExpatInfo
   139    116   #define GetExpatInfo \
   140    117   	(tdomStubsPtr->getExpatInfo) /* 7 */
   141         -#endif
   142         -#ifndef XML_GetCurrentLineNumber
   143    118   #define XML_GetCurrentLineNumber \
   144    119   	(tdomStubsPtr->xML_GetCurrentLineNumber) /* 8 */
   145         -#endif
   146         -#ifndef XML_GetCurrentColumnNumber
   147    120   #define XML_GetCurrentColumnNumber \
   148    121   	(tdomStubsPtr->xML_GetCurrentColumnNumber) /* 9 */
   149         -#endif
   150         -#ifndef XML_GetCurrentByteIndex
   151    122   #define XML_GetCurrentByteIndex \
   152    123   	(tdomStubsPtr->xML_GetCurrentByteIndex) /* 10 */
   153         -#endif
   154         -#ifndef XML_GetCurrentByteCount
   155    124   #define XML_GetCurrentByteCount \
   156    125   	(tdomStubsPtr->xML_GetCurrentByteCount) /* 11 */
   157         -#endif
   158         -#ifndef XML_SetBase
   159    126   #define XML_SetBase \
   160    127   	(tdomStubsPtr->xML_SetBase) /* 12 */
   161         -#endif
   162         -#ifndef XML_GetBase
   163    128   #define XML_GetBase \
   164    129   	(tdomStubsPtr->xML_GetBase) /* 13 */
   165         -#endif
   166         -#ifndef XML_GetSpecifiedAttributeCount
   167    130   #define XML_GetSpecifiedAttributeCount \
   168    131   	(tdomStubsPtr->xML_GetSpecifiedAttributeCount) /* 14 */
   169         -#endif
   170         -#ifndef XML_GetIdAttributeIndex
   171    132   #define XML_GetIdAttributeIndex \
   172    133   	(tdomStubsPtr->xML_GetIdAttributeIndex) /* 15 */
   173         -#endif
   174         -#ifndef tcldom_getNodeFromName
   175    134   #define tcldom_getNodeFromName \
   176    135   	(tdomStubsPtr->tcldom_getNodeFromName) /* 16 */
   177         -#endif
   178         -#ifndef tcldom_getDocumentFromName
   179    136   #define tcldom_getDocumentFromName \
   180    137   	(tdomStubsPtr->tcldom_getDocumentFromName) /* 17 */
   181         -#endif
   182    138   
   183         -#endif /* defined(USE_TDOM_STUBS) && !defined(USE_TDOM_STUB_PROCS) */
          139  +#endif /* defined(USE_TDOM_STUBS) */
   184    140   
   185    141   /* !END!: Do not edit above this line. */

Changes to generic/tdomStubInit.c.

     1      1   
     2         -/* This is generated by the getStubs.tcl tool (see the tcl distribution)
            2  +/* This is generated by the getStubs.tcl tool (see the Tcl distribution)
     3      3      out of the tdom.decls file */
     4      4      
     5      5   #ifdef USE_TCL_STUBS
     6      6   
     7      7   #include <dom.h>
     8      8   #include <tdom.h>
     9      9   
    10     10   /* !BEGIN!: Do not edit below this line. */
    11     11   
    12         -TdomStubs tdomStubs = {
           12  +const TdomStubs tdomStubs = {
    13     13       TCL_STUB_MAGIC,
    14         -    NULL,
           14  +    0,
    15     15       TclExpatObjCmd, /* 0 */
    16     16       CheckExpatParserObj, /* 1 */
    17     17       CHandlerSetInstall, /* 2 */
    18     18       CHandlerSetRemove, /* 3 */
    19     19       CHandlerSetCreate, /* 4 */
    20     20       CHandlerSetGet, /* 5 */
    21     21       CHandlerSetGetUserData, /* 6 */

Changes to generic/tdomStubLib.c.

    42     42    * Ensure that Tdom_InitStubs is built as an exported symbol.  The other stub
    43     43    * functions should be built as non-exported symbols.
    44     44    */
    45     45   
    46     46   #undef TCL_STORAGE_CLASS
    47     47   #define TCL_STORAGE_CLASS DLLEXPORT
    48     48   
    49         -TdomStubs *tdomStubsPtr;
           49  +const TdomStubs *tdomStubsPtr;
    50     50   
    51     51   /*----------------------------------------------------------------------------
    52     52   |   Tdom_InitStubs
    53     53   |
    54     54   \---------------------------------------------------------------------------*/
    55     55   
    56         -CONST char *
           56  +const char *
    57     57   Tdom_InitStubs (
    58     58       Tcl_Interp *interp, 
    59     59       char *version, 
    60     60       int exact
    61     61       )
    62     62   {
    63         -    CONST char *actualVersion;
           63  +    const char *actualVersion;
    64     64       ClientData clientData = NULL;
    65     65   
    66     66   #if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 0)
    67     67       Tcl_SetResult(interp, "Too old Tcl version. Binary extensions "
    68     68                     "to tDOM are not possible, with a that outdated "
    69     69                     "Tcl version.", TCL_STATIC);
    70     70       return NULL;

Changes to generic/tdominit.c.

    38     38   |   Includes
    39     39   |
    40     40   \---------------------------------------------------------------------------*/
    41     41   #include <tcl.h>
    42     42   #include <dom.h>
    43     43   #include <tdom.h>
    44     44   #include <tcldom.h>
           45  +#include <tclpull.h>
    45     46   
    46     47   extern TdomStubs tdomStubs;
    47     48   
    48     49   /*
    49     50    *----------------------------------------------------------------------------
    50     51    *
    51     52    * Tdom_Init --
................................................................................
    58     59    * Side effects:
    59     60    *	Defines "expat"/"dom" commands in the interpreter.
    60     61    *
    61     62    *----------------------------------------------------------------------------
    62     63    */
    63     64   
    64     65   int
    65         -Tdom_Init (interp)
    66         -     Tcl_Interp *interp; /* Interpreter to initialize. */
    67         -{
    68         -
           66  +Tdom_Init (
           67  +     Tcl_Interp *interp /* Interpreter to initialize. */
           68  +) {
           69  +        
    69     70   #ifdef USE_TCL_STUBS
    70     71       Tcl_InitStubs(interp, "8", 0);
    71     72   #endif
    72         -
           73  +        
    73     74       domModuleInitialize();
    74     75   
    75     76   #ifdef TCL_THREADS
    76     77       tcldom_initialize();
    77     78   #endif /* TCL_THREADS */
    78     79   
    79     80   #ifndef TDOM_NO_UNKNOWN_CMD
................................................................................
    86     87       Tcl_CreateObjCommand(interp, "domNode", tcldom_NodeObjCmd,  NULL, NULL );
    87     88       Tcl_CreateObjCommand(interp, "tdom",    TclTdomObjCmd,      NULL, NULL );
    88     89   
    89     90   #ifndef TDOM_NO_EXPAT    
    90     91       Tcl_CreateObjCommand(interp, "expat",       TclExpatObjCmd, NULL, NULL );
    91     92       Tcl_CreateObjCommand(interp, "xml::parser", TclExpatObjCmd, NULL, NULL );
    92     93   #endif
           94  +
           95  +#ifndef TDOM_NO_PULL
           96  +    Tcl_CreateObjCommand(interp, "tdom::pullparser", tDOM_PullParserCmd, NULL, NULL );    
           97  +#endif
    93     98       
    94     99   #ifdef USE_TCL_STUBS
    95    100       Tcl_PkgProvideEx(interp, PACKAGE_NAME, PACKAGE_VERSION, 
    96    101                        (ClientData) &tdomStubs);
    97    102   #else
    98    103       Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION);
    99    104   #endif
   100    105   
   101    106       return TCL_OK;
   102    107   }
   103    108   
   104    109   int
   105         -Tdom_SafeInit (interp)
   106         -     Tcl_Interp *interp;
   107         -{
          110  +Tdom_SafeInit (
          111  +     Tcl_Interp *interp
          112  +) {
   108    113       return Tdom_Init (interp);
   109    114   }
   110    115   
   111    116   /*
   112    117    * Load the AOLserver stub. This allows the library
   113    118    * to be loaded as AOLserver module.
   114    119    */
   115    120   
   116    121   #if defined (NS_AOLSERVER)
   117    122   # include "aolstub.cpp"
   118    123   #endif
   119    124   

Deleted generic/utf8conv.c.

     1         -/*---------------------------------------------------------------------------
     2         -|   Copyright (C) 1999  Jochen C. Loewer (loewerj@hotmail.com)
     3         -+----------------------------------------------------------------------------
     4         -|
     5         -|   $Id$
     6         -|
     7         -|
     8         -|   Functions, which (try) to convert UTF-8 encoded Unicode strings back 
     9         -|   to some 8bit encodings like ISO-8859-*, ... 
    10         -|
    11         -|
    12         -|   The contents of this file are subject to the Mozilla Public License
    13         -|   Version 1.1 (the "License"); you may not use this file except in
    14         -|   compliance with the License. You may obtain a copy of the License at
    15         -|   http://www.mozilla.org/MPL/
    16         -|
    17         -|   Software distributed under the License is distributed on an "AS IS"
    18         -|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
    19         -|   License for the specific language governing rights and limitations
    20         -|   under the License.
    21         -|
    22         -|   The Original Code is tDOM.
    23         -|
    24         -|   The Initial Developer of the Original Code is Jochen Loewer
    25         -|   Portions created by Jochen Loewer are Copyright (C) 1998, 1999
    26         -|   Jochen Loewer. All Rights Reserved.
    27         -|
    28         -|   Contributor(s):
    29         -|
    30         -|
    31         -|   $Log$
    32         -|   Revision 1.2  2004/08/14 14:42:27  rolf
    33         -|   Use 'Id' cvs keyword (instead of 'Header') in the file heads.
    34         -|
    35         -|   Revision 1.1.1.1  2002/02/22 01:05:35  rolf
    36         -|   tDOM0.7test with Jochens first set of patches
    37         -|
    38         -|
    39         -|
    40         -|   written by Jochen Loewer
    41         -|   November, 1999
    42         -|
    43         -\--------------------------------------------------------------------------*/
    44         -
    45         -
    46         -
    47         -/*---------------------------------------------------------------------------
    48         -|   Includes
    49         -|
    50         -\--------------------------------------------------------------------------*/
    51         -#include <tcl.h>
    52         -#include <stdlib.h>
    53         -#include <string.h>
    54         -#include <utf8conv.h>
    55         -
    56         -/*---------------------------------------------------------------------------
    57         -|   Defines
    58         -|
    59         -\--------------------------------------------------------------------------*/
    60         -#define DBG(x)
    61         -
    62         -#define ENC_END       0
    63         -#define ENC_IDENTITY  1
    64         -#define ENC_MAP       2
    65         -
    66         -#if defined(_MSC_VER)
    67         -# define STRCASECMP(a,b)  stricmp (a,b)
    68         -#else
    69         -# define STRCASECMP(a,b)  strcasecmp (a,b)
    70         -#endif
    71         -
    72         -
    73         -/*---------------------------------------------------------------------------
    74         -|   Static Globals
    75         -|
    76         -\--------------------------------------------------------------------------*/
    77         -#include "encodings.inc"
    78         -
    79         -
    80         -
    81         -/*---------------------------------------------------------------------------
    82         -|   tdom_GetEncoding  -  Looks up a encoding table for the given encoding
    83         -|                        name. If nothing was found NULL is returned.
    84         -|
    85         -\--------------------------------------------------------------------------*/
    86         -TEncoding * 
    87         -tdom_GetEncoding (
    88         -    char  * name
    89         -)
    90         -{
    91         -    TEncoding *encoding = TDOM_UnicodeTo8bitEncodings;
    92         -    
    93         -    while (encoding && encoding->name) {
    94         -        DBG(fprintf(stderr, "encoding=%x encoding->name='%s' name='%s'",
    95         -                             encoding, encoding->name, name);)
    96         -        if (STRCASECMP(encoding->name,name)==0) {
    97         -            return encoding;
    98         -        }
    99         -        encoding++;
   100         -    }
   101         -    return NULL;
   102         -}
   103         -
   104         -
   105         -/*---------------------------------------------------------------------------
   106         -|   tdom_GetEncodingName
   107         -|
   108         -\--------------------------------------------------------------------------*/
   109         -char *
   110         -tdom_GetEncodingName (TEncoding *encoding) 
   111         -{
   112         -    TEncoding *knownencoding = TDOM_UnicodeTo8bitEncodings;
   113         -    
   114         -    while (knownencoding && knownencoding->name) {
   115         -        if (knownencoding == encoding) {
   116         -            return (char*) knownencoding->name;
   117         -        }
   118         -        knownencoding++;
   119         -    }
   120         -    return NULL;
   121         -}
   122         -    
   123         -
   124         -/*---------------------------------------------------------------------------
   125         -|   tdom_Utf8to8Bit  -  Convert a UTF-8 encode string with byte length 
   126         -|                       *len to 8bit encoding using the specify encoding.
   127         -|
   128         -\--------------------------------------------------------------------------*/
   129         -void 
   130         -tdom_Utf8to8Bit (
   131         -    TEncoding  * encoding,
   132         -    const char * utf8_string,
   133         -    int        * len
   134         -)
   135         -{
   136         -    unsigned char  *in, *end, *out;
   137         -    TEncodingRule  *rule;
   138         -    int             byte;
   139         -    int             unicode;
   140         -        
   141         -        
   142         -    if (encoding == NULL) {
   143         -       /* don't convert; keep UTF-8 */
   144         -       return;
   145         -    }
   146         -         
   147         -    in  = (unsigned char*) utf8_string;
   148         -    out = (unsigned char*) utf8_string;
   149         -    end = in + *len;
   150         -    unicode = 0;
   151         -    
   152         -    while (in < end) {
   153         -
   154         -        byte = *in;
   155         -
   156         -        /* extract unicode character from (multiple) UTF-8 bytes */
   157         -
   158         -        if (byte < 0xC0) { 
   159         -            unicode = byte;
   160         -            in++;
   161         -        } else if (byte < 0xE0) {
   162         -            if ((in[1] & 0xC0) == 0x80) {
   163         -                unicode = ((byte & 0x1F) << 6) | (in[1] & 0x3F);
   164         -                in += 2;
   165         -            } else {
   166         -                unicode = byte; 
   167         -                in++;
   168         -            }
   169         -        } else if (byte < 0xF0) {
   170         -            if (((in[1] & 0xC0) == 0x80) && ((in[2] & 0xC0) == 0x80)) {
   171         -                unicode =  ((byte  & 0x0F) << 12)
   172         -                         | ((in[1] & 0x3F) << 6 )
   173         -                         | ((in[2] & 0x3F)      );
   174         -                in += 3;
   175         -            } else {
   176         -                unicode = byte; 
   177         -                in++; 
   178         -            }
   179         -        } else {
   180         -            /* ??? > 3 bytes UTF chars ??? */
   181         -            in++;
   182         -        }
   183         -
   184         -        /* convert unicode character to 8bit representation */
   185         -        rule = encoding->rules;
   186         -        while (rule && rule->type != ENC_END) {
   187         -            if (   (unicode >= rule->start_code) 
   188         -                && (unicode < (rule->start_code + rule->len)) ) {
   189         -
   190         -                if (rule->type == ENC_MAP) {
   191         -                    *out++ = rule->map[unicode - rule->start_code];
   192         -                } else {
   193         -                    *out++ = unicode & 0xFF;
   194         -                }
   195         -                break;
   196         -            }
   197         -            rule++;
   198         -        }
   199         -        if (rule->type == ENC_END) {
   200         -            /* no rule foun, use fallback */
   201         -            *out++ = encoding->fallback_char & 0x0FF;
   202         -        }
   203         -    }
   204         -    if (out < end) {
   205         -        *out = '\0';
   206         -    }
   207         -    *len = ( (char*)out - utf8_string);
   208         -}
   209         -

Deleted generic/utf8conv.h.

     1         -/*---------------------------------------------------------------------------
     2         -|   Copyright (C) 1999  Jochen C. Loewer (loewerj@hotmail.com)
     3         -+----------------------------------------------------------------------------
     4         -|
     5         -|   $Id$
     6         -|
     7         -|
     8         -|   Functions, which (try) to convert UTF-8 encoded Unicode strings back 
     9         -|   to some 8bit encodings like ISO-8859-*, ... 
    10         -|
    11         -|
    12         -|   The contents of this file are subject to the Mozilla Public License
    13         -|   Version 1.1 (the "License"); you may not use this file except in
    14         -|   compliance with the License. You may obtain a copy of the License at
    15         -|   http://www.mozilla.org/MPL/
    16         -|
    17         -|   Software distributed under the License is distributed on an "AS IS"
    18         -|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
    19         -|   License for the specific language governing rights and limitations
    20         -|   under the License.
    21         -|
    22         -|   The Original Code is tDOM.
    23         -|
    24         -|   The Initial Developer of the Original Code is Jochen Loewer
    25         -|   Portions created by Jochen Loewer are Copyright (C) 1998, 1999
    26         -|   Jochen Loewer. All Rights Reserved.
    27         -|
    28         -|   Contributor(s):
    29         -|
    30         -|
    31         -|   $Log$
    32         -|   Revision 1.3  2004/08/14 14:42:27  rolf
    33         -|   Use 'Id' cvs keyword (instead of 'Header') in the file heads.
    34         -|
    35         -|   Revision 1.2  2002/07/04 15:06:49  zoran
    36         -|   fixed reference to unsigned* to char since Sun compiler barfs at it.
    37         -|
    38         -|   Revision 1.1.1.1  2002/02/22 01:05:35  rolf
    39         -|   tDOM0.7test with Jochens first set of patches
    40         -|
    41         -|
    42         -|
    43         -|   written by Jochen Loewer
    44         -|   November, 1999
    45         -|
    46         -\--------------------------------------------------------------------------*/
    47         -
    48         -#ifndef __UTF8CONV_H__
    49         -#define __UTF8CONV_H__
    50         -
    51         -
    52         -/*---------------------------------------------------------------------------
    53         -|   Includes
    54         -|
    55         -\--------------------------------------------------------------------------*/
    56         -#include <tcl.h>
    57         -#include <stdlib.h>
    58         -#include <string.h>
    59         -
    60         -
    61         -/*---------------------------------------------------------------------------
    62         -|   Typedefs
    63         -|
    64         -\--------------------------------------------------------------------------*/
    65         -typedef struct {
    66         -    int             type;
    67         -    int             start_code;
    68         -    int             len;
    69         -    char          * map;
    70         -} TEncodingRule;
    71         -
    72         -typedef struct {
    73         -    const char    * name;
    74         -    int             fallback_char;
    75         -    TEncodingRule * rules;
    76         -} TEncoding;
    77         -
    78         -
    79         -             
    80         -/*--------------------------------------------------------------------------
    81         -|   Function prototypes
    82         -|
    83         -\-------------------------------------------------------------------------*/
    84         -TEncoding * tdom_GetEncoding (char *name);
    85         -char *      tdom_GetEncodingName (TEncoding *encoding);
    86         -void        tdom_Utf8to8Bit (TEncoding  *encoding, 
    87         -                             const char *utf8_string, int *len);
    88         -
    89         -#endif
    90         -
    91         -    

Changes to generic/xmlsimple.c.

    29     29   |
    30     30   |
    31     31   |   adopted/written by Jochen Loewer
    32     32   |   July 1999
    33     33   |
    34     34   |   ------------------------------------------------------------------------
    35     35   |
    36         -|   A parser for XML.
    37         -|
    38         -|   Copyright (C) 1998 D. Richard Hipp
    39         -|
    40         -|   This library is free software; you can redistribute it and/or
    41         -|   modify it under the terms of the GNU Library General Public
    42         -|   License as published by the Free Software Foundation; either
    43         -|   version 2 of the License, or (at your option) any later version.
    44         -|
    45         -|   This library is distributed in the hope that it will be useful,
    46         -|   but WITHOUT ANY WARRANTY; without even the implied warranty of
    47         -|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    48         -|   Library General Public License for more details.
    49         -|
    50         -|   You should have received a copy of the GNU Library General Public
    51         -|   License along with this library; if not, write to the
    52         -|   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    53         -|   Boston, MA  02111-1307, USA.
    54         -|
    55         -|   Author contact information:
    56         -|     drh@acm.org
    57         -|     http://www.hwaci.com/drh/
           36  +|   Partly based on a parser for XML (for TMML by R.Hipp 1998). 
           37  +|   This source code is released into the public domain by the author.
           38  +|   on 2002, December 17.
    58     39   |
    59     40   \---------------------------------------------------------------------------*/
    60     41   
    61     42   
    62     43   /*----------------------------------------------------------------------------
    63     44   |   Includes
    64     45   |
................................................................................
    77     58   #ifdef TDOM_NS
    78     59   # define RetError(m,p) *errStr=m; *pos=p; FREE((char*)activeNS); return TCL_ERROR;
    79     60   #else 
    80     61   # define RetError(m,p) *errStr=m; *pos=p; return TCL_ERROR;
    81     62   #endif
    82     63   #define SPACE(c)       ((c)==' ' || (c)=='\n' || (c)=='\t' || (c)=='\r')
    83     64   
    84         -/*---------------------------------------------------------------------------
    85         -|   type domActiveNS
    86         -|
    87         -\--------------------------------------------------------------------------*/
    88         -typedef struct _domActiveNS {
    89         -
    90         -    int    depth;
    91         -    domNS *namespace;
    92         -
    93         -} domActiveNS;
    94         -
    95     65   /*----------------------------------------------------------------------------
    96     66   |   Begin Character Entity Translator
    97     67   |
    98     68   |
    99     69   |   The next section of code implements routines used to translate
   100     70   |   character entity references into their corresponding strings.
   101     71   |
................................................................................
   188    158   \---------------------------------------------------------------------------*/
   189    159   static Er er_sequences[] = {
   190    160       { "amp",       "&",        0 },
   191    161       { "lt",        "<",        0 },
   192    162       { "gt",        ">",        0 },
   193    163       { "apos",      "'",        0 },
   194    164       { "quot",      "\"",       0 },
   195         -#if TclOnly8Bits
   196         -    { "nbsp",      "\240",     0 },
   197         -#else
   198    165       { "nbsp",      "\xC2\xA0",    0 },
   199         -#endif
   200    166   };
   201    167   
   202    168   
   203    169   /*----------------------------------------------------------------------------
   204    170   |   ErInit --
   205    171   |
   206    172   |       Initialize the entity reference hash table
................................................................................
   302    268                       }
   303    269                   }
   304    270                   if (!z[i] || (z[i]!=';')) {
   305    271                       return 0;
   306    272                       /* error */
   307    273                   }
   308    274                   from = i+1;
   309         -#if TclOnly8Bits
   310         -                z[to++] = value;
   311         -#else 
   312    275                   if (value < 0x80) {
   313    276                       z[to++] = value;
   314    277                   } else if (value <= 0x7FF) {
   315    278                       z[to++] = (char) ((value >> 6) | 0xC0);
   316    279                       z[to++] = (char) ((value | 0x80) & 0xBF);
   317    280                   } else if (value <= 0xFFFF) {
   318    281                       z[to++] = (char) ((value >> 12) | 0xE0);
   319    282                       z[to++] = (char) (((value >> 6) | 0x80) & 0xBF);
   320    283                       z[to++] = (char) ((value | 0x80) & 0xBF);
   321    284                   } else {
   322    285                       /* error */
   323    286                       return 0;
   324    287                   }
   325         -#endif
   326    288               } else {
   327    289                   while (z[i] && isalpha((unsigned char)z[i])) {
   328    290                      i++;
   329    291                   }
   330    292                   if (!z[i] || (z[i]!=';')) {
   331    293                       return 0;
   332    294                   }
................................................................................
   357    319       *newLen = to;
   358    320       return 1;
   359    321   }
   360    322   /*----------------------------------------------------------------------------
   361    323   |   End Of Character Entity Translator
   362    324   \---------------------------------------------------------------------------*/
   363    325   
   364         -
   365         -/*---------------------------------------------------------------------------
   366         -|   domIsNamespaceInScope
   367         -|
   368         -\--------------------------------------------------------------------------*/
   369         -static int
   370         -domIsNamespaceInScope (
   371         -    domActiveNS *NSstack,
   372         -    int          NSstackPos,
   373         -    const char  *prefix,
   374         -    const char  *namespaceURI
   375         -)
   376         -{
   377         -    int    i;
   378         -
   379         -    for (i = NSstackPos; i >= 0; i--) {
   380         -        if (NSstack[i].namespace->prefix[0] &&
   381         -            (strcmp(NSstack[i].namespace->prefix, prefix)==0)) {
   382         -            if (strcmp(NSstack[i].namespace->uri, namespaceURI)==0) {
   383         -                /* OK, exactly the same namespace declaration is in scope */
   384         -                return 1;
   385         -            } else {
   386         -                /* This prefix is currently assigned to another uri,
   387         -                   we need a new NS declaration, to override this one */
   388         -                return 0;
   389         -            }
   390         -        }
   391         -    }
   392         -    return 0;
   393         -}
   394         -
   395    326   /*----------------------------------------------------------------------------
   396    327   |   XML_SimpleParse (non recursive)
   397    328   |
   398    329   |       Parses the XML string starting at 'pos' and continuing to the
   399    330   |       first encountered error.
   400    331   |
   401    332   \---------------------------------------------------------------------------*/
................................................................................
   402    333   static int
   403    334   XML_SimpleParse (
   404    335       char        *xml,   /* XML string  */
   405    336       int         *pos,   /* Index of next unparsed character in xml */
   406    337       domDocument *doc,
   407    338       domNode     *parent_nodeOld,
   408    339       int          ignoreWhiteSpaces,
          340  +    int          keepCDATA,
   409    341       char       **errStr
   410    342   ) {
   411    343       register int   c;          /* Next character of the input file */
   412    344       register char *pn;
   413    345       register char *x, *start, *piSep;
   414    346       int            saved;
   415    347       int            hasContent;
................................................................................
   456    388                        (c != '\n') &&
   457    389                        (c != '\r') ) {
   458    390                       only_whites = 0;
   459    391                   }
   460    392                   x++;
   461    393               }
   462    394               if (!(only_whites && ignoreWhiteSpaces) && parent_node) {
   463         -                /*--------------------------------------------------------
   464         -                |   allocate new TEXT node
   465         -                 \-------------------------------------------------------*/
   466         -                tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
   467         -                memset(tnode, 0, sizeof(domTextNode));
   468         -                tnode->nodeType    = TEXT_NODE;
   469         -                tnode->nodeFlags   = 0;
   470         -                tnode->namespace   = 0;
   471         -                tnode->ownerDocument = doc;
   472         -                tnode->nodeNumber  = NODE_NO(doc);
   473         -                tnode->valueLength = (x - start);
   474         -                tnode->nodeValue   = (char*)MALLOC((x - start)+1);
   475         -                memmove(tnode->nodeValue, start, (x - start));
   476         -                *(tnode->nodeValue + (x - start)) = 0;
   477         -                if (ampersandSeen) {
   478         -                    if (!TranslateEntityRefs(tnode->nodeValue, 
   479         -                                             &(tnode->valueLength) )) {
   480         -                        RetError("Entity parsing error", (x - xml));
   481         -                    }
   482         -                }
   483         -                tnode->parentNode = parent_node;
   484         -                if (parent_node->firstChild)  {
   485         -                    parent_node->lastChild->nextSibling = (domNode*)tnode;
   486         -                    tnode->previousSibling = parent_node->lastChild;
   487         -                    parent_node->lastChild = (domNode*)tnode;
          395  +                if (parent_node->lastChild
          396  +                    && parent_node->lastChild->nodeType == TEXT_NODE) {
          397  +                    /* normalize text node, i.e. there are no adjacent
          398  +                     * text nodes */
          399  +                    tnode = (domTextNode*)parent_node->lastChild;
          400  +                    tnode->nodeValue = REALLOC(tnode->nodeValue,
          401  +                                               tnode->valueLength + x - start + 1);
          402  +                    memmove(tnode->nodeValue + tnode->valueLength,
          403  +                            start, x - start);
          404  +                    saved = tnode->valueLength;
          405  +                    tnode->valueLength += (x - start);
          406  +                    *(tnode->nodeValue + tnode->valueLength) = 0;
          407  +                    if (ampersandSeen) {
          408  +                        if (!TranslateEntityRefs(tnode->nodeValue + saved, 
          409  +                                                 &(tnode->valueLength) )) {
          410  +                            RetError("Entity parsing error", (x - xml));
          411  +                        }
          412  +                        tnode->valueLength += saved;
          413  +                    }
   488    414                   } else {
   489         -                    parent_node->firstChild = parent_node->lastChild = 
   490         -                        (domNode*)tnode;
          415  +                    /*--------------------------------------------------------
          416  +                      |   allocate new TEXT node
          417  +                      \-------------------------------------------------------*/
          418  +                    tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
          419  +                    memset(tnode, 0, sizeof(domTextNode));
          420  +                    tnode->nodeType    = TEXT_NODE;
          421  +                    tnode->nodeFlags   = 0;
          422  +                    tnode->ownerDocument = doc;
          423  +                    tnode->nodeNumber  = NODE_NO(doc);
          424  +                    tnode->valueLength = (x - start);
          425  +                    tnode->nodeValue   = (char*)MALLOC((x - start)+1);
          426  +                    memmove(tnode->nodeValue, start, (x - start));
          427  +                    *(tnode->nodeValue + (x - start)) = 0;
          428  +                    tnode->parentNode = parent_node;
          429  +                    if (parent_node->firstChild)  {
          430  +                        parent_node->lastChild->nextSibling = (domNode*)tnode;
          431  +                        tnode->previousSibling = parent_node->lastChild;
          432  +                        parent_node->lastChild = (domNode*)tnode;
          433  +                    } else {
          434  +                        parent_node->firstChild = parent_node->lastChild = 
          435  +                            (domNode*)tnode;
          436  +                    }
          437  +                    if (ampersandSeen) {
          438  +                        if (!TranslateEntityRefs(tnode->nodeValue, 
          439  +                                                 &(tnode->valueLength) )) {
          440  +                            RetError("Entity parsing error", (x - xml));
          441  +                        }
          442  +                    }
   491    443                   }
   492    444               }
   493    445   
   494    446           } else if (x[1]=='/') {
   495    447               /*------------------------------------------------------------
   496    448               |   read and check closing tag
   497    449               \-----------------------------------------------------------*/
................................................................................
   550    502                           /*----------------------------------------------------
   551    503                           |   allocate new COMMENT node for comments
   552    504                           \---------------------------------------------------*/
   553    505                           tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
   554    506                           memset(tnode, 0, sizeof(domTextNode));
   555    507                           tnode->nodeType      = COMMENT_NODE;
   556    508                           tnode->nodeFlags     = 0;
   557         -                        tnode->namespace     = 0;
   558    509                           tnode->ownerDocument = doc;
   559    510                           tnode->nodeNumber    = NODE_NO(doc);
   560    511                           tnode->parentNode    = parent_node;
   561    512                           tnode->valueLength   = x - start - 4;
   562    513                           tnode->nodeValue     = (char*)MALLOC(tnode->valueLength+1);
   563    514                           memmove(tnode->nodeValue, start+4, tnode->valueLength);
   564    515                           *(tnode->nodeValue + tnode->valueLength) = 0;
................................................................................
   617    568                              x[3]=='D' && x[4]=='A' &&
   618    569                              x[5]=='T' && x[6]=='A' && x[7]=='[' ) {
   619    570                       /*--------------------------------------------------------
   620    571                       |   read over a <![CDATA[ section
   621    572                       \-------------------------------------------------------*/
   622    573                       x += 8;
   623    574                       start = x;
   624         -                    while ( (*x!=0) &&
          575  +                    only_whites = 1;
          576  +                    while ( ((c=*x)!=0) &&
   625    577                               ((*x!=']') || (x[1]!=']') || (x[2]!='>'))) {
          578  +                        if (only_whites &&
          579  +                            (c != ' ')  &&
          580  +                            (c != '\t') &&
          581  +                            (c != '\n') &&
          582  +                            (c != '\r') ) {
          583  +                            only_whites = 0;
          584  +                        }
   626    585                           x++;
   627    586                       }
   628    587                       if (*x) {
   629         -                        if (parent_node && (x - start)) {
   630         -                            /*----------------------------------------------------
   631         -                            |   allocate new TEXT node for CDATA section data
   632         -                            \---------------------------------------------------*/
   633         -                            tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
   634         -                            memset(tnode, 0, sizeof(domTextNode));
   635         -                            tnode->nodeType      = TEXT_NODE;
   636         -                            tnode->nodeFlags     = 0;
   637         -                            tnode->namespace     = 0;
   638         -                            tnode->ownerDocument = doc;
   639         -                            tnode->nodeNumber    = NODE_NO(doc);
   640         -                            tnode->parentNode    = parent_node;
   641         -                            tnode->valueLength   = (x - start);
   642         -                            tnode->nodeValue     = (char*)MALLOC((x - start)+1);
   643         -                            memmove(tnode->nodeValue, start, (x - start));
   644         -                            *(tnode->nodeValue + (x - start)) = 0;
   645         -                            if (parent_node->firstChild)  {
   646         -                                parent_node->lastChild->nextSibling = (domNode*)tnode;
   647         -                                tnode->previousSibling = parent_node->lastChild;
   648         -                                parent_node->lastChild = (domNode*)tnode;
          588  +                        if (parent_node && ((x - start) || keepCDATA)) {
          589  +                            if (parent_node->lastChild
          590  +                                && parent_node->lastChild->nodeType == TEXT_NODE
          591  +                                && !keepCDATA) {
          592  +                                if ((x - start) && !(only_whites && ignoreWhiteSpaces)) {
          593  +                                    /* normalize text node, i.e. there
          594  +                                     * are no adjacent text nodes */
          595  +                                    tnode = (domTextNode*)parent_node->lastChild;
          596  +                                    tnode->nodeValue =
          597  +                                        REALLOC(tnode->nodeValue,
          598  +                                                tnode->valueLength + x - start + 1);
          599  +                                    memmove(tnode->nodeValue + tnode->valueLength,
          600  +                                            start, x - start);
          601  +                                    tnode->valueLength += (x - start);
          602  +                                    *(tnode->nodeValue + tnode->valueLength) = 0;
          603  +                                }
   649    604                               } else {
   650         -                                parent_node->firstChild = parent_node->lastChild = (domNode*)tnode;
          605  +                                if (!(only_whites && ignoreWhiteSpaces)
          606  +                                    && ((x - start) || keepCDATA)) {
          607  +                                    /*----------------------------------------------------
          608  +                                      |   allocate new node for CDATA section data
          609  +                                      \---------------------------------------------------*/
          610  +                                    tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
          611  +                                    memset(tnode, 0, sizeof(domTextNode));
          612  +                                    if (keepCDATA)
          613  +                                        tnode->nodeType      = CDATA_SECTION_NODE;
          614  +                                    else 
          615  +                                        tnode->nodeType      = TEXT_NODE;
          616  +                                    tnode->nodeFlags     = 0;
          617  +                                    tnode->ownerDocument = doc;
          618  +                                    tnode->nodeNumber    = NODE_NO(doc);
          619  +                                    tnode->parentNode    = parent_node;
          620  +                                    tnode->valueLength   = (x - start);
          621  +                                    tnode->nodeValue     = (char*)MALLOC((x - start)+1);
          622  +                                    memmove(tnode->nodeValue, start, (x - start));
          623  +                                    *(tnode->nodeValue + (x - start)) = 0;
          624  +                                    if (parent_node->firstChild)  {
          625  +                                        parent_node->lastChild->nextSibling = (domNode*)tnode;
          626  +                                        tnode->previousSibling = parent_node->lastChild;
          627  +                                        parent_node->lastChild = (domNode*)tnode;
          628  +                                    } else {
          629  +                                        parent_node->firstChild = parent_node->lastChild = (domNode*)tnode;
          630  +                                    }
          631  +                                }
   651    632                               }
   652    633                           }
   653    634                           x += 3;
   654    635                       } else {
   655    636                           RetError("Unterminated CDATA definition",(start-xml) );
   656    637                       }
   657    638                       continue;
................................................................................
  1022   1003   #endif
  1023   1004               if (*x=='/') {
  1024   1005                   hasContent = 0;
  1025   1006                   x++;
  1026   1007                   if (*x!='>') {
  1027   1008                       RetError("Syntax Error",(x - xml - 1) );
  1028   1009                   }
         1010  +#ifdef TDOM_NS 
         1011  +                /* pop active namespaces */
         1012  +                while ( (activeNSpos >= 0) &&
         1013  +                        (activeNS[activeNSpos].depth == depth) )
         1014  +                {
         1015  +                    activeNSpos--;
         1016  +                } 
         1017  +#endif                                   
  1029   1018               }
  1030   1019               if (x[1] == 0) {
  1031   1020   #ifdef TDOM_NS
  1032   1021                   FREE ((char *) activeNS);
  1033   1022   #endif                
  1034   1023                   return TCL_OK;
  1035   1024               }
................................................................................
  1060   1049   |       continuing to the first encountered error.
  1061   1050   |
  1062   1051   \---------------------------------------------------------------------------*/
  1063   1052   domDocument *
  1064   1053   XML_SimpleParseDocument (
  1065   1054       char    *xml,              /* Complete text of the file being parsed  */
  1066   1055       int      ignoreWhiteSpaces,
         1056  +    int      keepCDATA,
  1067   1057       char    *baseURI,
  1068         -    char    *extResolver,
         1058  +    Tcl_Obj *extResolver,
  1069   1059       int     *pos,
  1070   1060       char   **errStr
  1071   1061   ) {
  1072   1062       domDocument   *doc = domCreateDoc(baseURI, 0);
  1073   1063   
  1074   1064       if (extResolver) {
  1075         -        doc->extResolver = extResolver;
         1065  +        doc->extResolver = tdomstrdup (Tcl_GetString (extResolver));
  1076   1066       }
  1077   1067       
  1078   1068       *pos = 0;
  1079         -    XML_SimpleParse (xml, pos, doc, NULL, ignoreWhiteSpaces, errStr);
         1069  +    XML_SimpleParse (xml, pos, doc, NULL, ignoreWhiteSpaces, keepCDATA, errStr);
  1080   1070       domSetDocumentElement (doc);
  1081   1071   
  1082   1072       return doc;
  1083   1073   
  1084   1074   } /* XML_SimpleParseDocument */
  1085   1075   

Changes to generic/xmlsimple.h.

     1      1   
     2         -domDocument *  XML_SimpleParseDocument ( char *xml, int ignoreWhiteSpaces, 
     3         -                                         char *baseURI, char *extResolver,
            2  +domDocument *  XML_SimpleParseDocument ( char *xml, int ignoreWhiteSpaces,
            3  +                                         int keepCDATA,
            4  +                                         char *baseURI, Tcl_Obj *extResolver,
     4      5                                            int *pos, char **errStr );

Changes to lib/tdom.tcl.

    47     47       }
    48     48       namespace eval  xpathFunc {
    49     49       }
    50     50       namespace eval  xpathFuncHelper {
    51     51       }
    52     52   }
    53     53   
    54         -namespace eval ::tDOM { 
           54  +namespace eval ::tdom { 
    55     55       variable extRefHandlerDebug 0
    56     56       variable useForeignDTD ""
    57     57   
    58         -    namespace export xmlOpenFile xmlReadFile extRefHandler baseURL
           58  +    namespace export xmlOpenFile xmlReadFile xmlReadFileForSimple \
           59  +        extRefHandler baseURL
    59     60   }
    60     61   
    61     62   #----------------------------------------------------------------------------
    62     63   #   hasFeature (DOMImplementation method)
    63     64   #
    64     65   #
    65     66   #   @in  url    the URL, where to get the XML document
................................................................................
   636    637   # cp1251 koi8-u macDingbats iso8859-7 cp1252 iso8859-8 cp1253
   637    638   # iso8859-9 cp1254 cp1255 cp850 cp1256 cp932 identity cp1257 cp852
   638    639   # macJapan cp1258 shiftjis utf-8 cp855 cp936 symbol cp775 unicode
   639    640   # cp857
   640    641   # 
   641    642   # Just add more mappings (and mail them to the tDOM mailing list, please).
   642    643   
   643         -proc tDOM::IANAEncoding2TclEncoding {IANAName} {
          644  +proc tdom::IANAEncoding2TclEncoding {IANAName} {
   644    645       
   645    646       # First the most widespread encodings with there
   646    647       # preferred MIME name, to speed lookup in this
   647    648       # usual cases. Later the official names and the
   648    649       # aliases.
   649    650       #
   650    651       # For "official names for character sets that may be
................................................................................
   653    654       # (that's the source for the encoding names below)
   654    655       # 
   655    656       # Matching is case-insensitive
   656    657   
   657    658       switch [string tolower $IANAName] {
   658    659           "us-ascii"    {return ascii}
   659    660           "utf-8"       {return utf-8}
   660         -        "utf-16"      {return unicode; # not sure about this}
          661  +        "utf-16"      {return unicode}
   661    662           "iso-8859-1"  {return iso8859-1}
   662    663           "iso-8859-2"  {return iso8859-2}
   663    664           "iso-8859-3"  {return iso8859-3}
   664    665           "iso-8859-4"  {return iso8859-4}
   665    666           "iso-8859-5"  {return iso8859-5}
   666    667           "iso-8859-6"  {return iso8859-6}
   667    668           "iso-8859-7"  {return iso8859-7}
................................................................................
   731    732               # It's only laziness, that let me stop here.
   732    733               error "Unrecognized encoding name '$IANAName'"
   733    734           }
   734    735       }
   735    736   }
   736    737   
   737    738   #----------------------------------------------------------------------------
   738         -#   xmlOpenFile
          739  +#   xmlOpenFileWorker
   739    740   #
   740    741   #----------------------------------------------------------------------------
   741         -proc tDOM::xmlOpenFile {filename {encodingString {}}} {
          742  +proc tdom::xmlOpenFileWorker {filename {encodingString {}} {forSimple 0} {forRead 0}} {
   742    743   
          744  +    # This partly (mis-)use the encoding of a channel handed to [dom
          745  +    # parse -channel ..] as a marker: if the channel encoding is utf-8
          746  +    # then behind the scene Tcl_Read() is used, otherwise
          747  +    # Tcl_ReadChars(). This is used for the encodings understood (and
          748  +    # checked) by the used expat implementation: utf-8 and utf-16 (in
          749  +    # either byte order).
          750  +    
   743    751       set fd [open $filename]
   744    752   
   745    753       if {$encodingString != {}} {
   746    754           upvar $encodingString encString
   747    755       }
   748    756   
   749    757       # The autodetection of the encoding follows
................................................................................
   755    763           seek $fd 0 start
   756    764           set encString UTF-8
   757    765           return $fd
   758    766       }
   759    767       
   760    768       # First check for BOM
   761    769       switch [string range $firstBytes 0 3] {
   762         -        "feff" -
   763         -        "fffe" {
          770  +        "feff" {
   764    771               # feff: UTF-16, big-endian BOM
   765         -            # ffef: UTF-16, little-endian BOM
          772  +            if {$forSimple || $forRead} {
          773  +                error "UTF-16be is not supported"
          774  +            }
   766    775               seek $fd 0 start
   767         -            set encString UTF-16            
   768         -            fconfigure $fd -encoding identity
          776  +            set encString UTF-16be
          777  +            fconfigure $fd -encoding utf-8
          778  +            return $fd
          779  +        }
          780  +        "fffe" {
          781  +            # ffef: UTF-16, little-endian BOM
          782  +            set encString UTF-16le          
          783  +            if {$forSimple || $forRead} {
          784  +                seek $fd 2 start
          785  +                fconfigure $fd -encoding unicode
          786  +            } else {
          787  +                seek $fd 0 start
          788  +                fconfigure $fd -encoding utf-8
          789  +            }
   769    790               return $fd
   770    791           }
   771    792       }
   772         -
          793  +    
          794  +    
   773    795       # If the entity has a XML Declaration, the first four characters
   774    796       # must be "<?xm".
   775    797       switch $firstBytes {
   776    798           "3c3f786d" {
   777    799               # UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS,
   778    800               # EUC, or any other 7-bit, 8-bit, or mixed-width encoding which 
   779    801               # ensures that the characters of ASCII have their normal positions,
................................................................................
   810    832           "0000003c" -
   811    833           "0000003c" -
   812    834           "3c000000" -
   813    835           "00003c00" {
   814    836               # UCS-4
   815    837               error "UCS-4 not supported"
   816    838           }
   817         -        "003c003f" -
   818         -        "3c003f00" {
          839  +            "003c003f" {
   819    840               # UTF-16, big-endian, no BOM
   820         -            # UTF-16, little-endian, no BOM
          841  +            if {$forSimple} {
          842  +                error "UTF-16be is not supported by the simple parser"
          843  +            }
   821    844               seek $fd 0 start
   822         -            set encoding identity
   823         -            set encString UTF-16
          845  +            set encoding utf-8
          846  +            set encString UTF-16be
          847  +        }
          848  +        "3c003f00" {
          849  +            # UTF-16, little-endian, no BOM
          850  +            if {$forSimple} {
          851  +                seek $fd 2 start
          852  +                set encoding unicode
          853  +            } else {
          854  +                seek $fd 0 start
          855  +                set encoding utf-8
          856  +            }
          857  +            set encString UTF-16le          
   824    858           }
   825    859           "4c6fa794" {
   826    860               # EBCDIC in some flavor
   827    861               error "EBCDIC not supported"
   828    862           }
   829    863           default {
   830    864               # UTF-8 without an encoding declaration
   831    865               seek $fd 0 start
   832         -            set encoding identity
          866  +            set encoding utf-8
   833    867               set encString "UTF-8"
   834    868           }
   835    869       }
   836    870       fconfigure $fd -encoding $encoding
   837    871       return $fd
   838    872   }
          873  +
          874  +#----------------------------------------------------------------------------
          875  +#   xmlOpenFile
          876  +#
          877  +#----------------------------------------------------------------------------
          878  +proc tdom::xmlOpenFile {filename {encodingString {}}} {
          879  +
          880  +    if {$encodingString != {}} {
          881  +        upvar $encodingString encString
          882  +    }
          883  +    
          884  +    set fd [xmlOpenFileWorker $filename encString]
          885  +    return $fd
          886  +}
   839    887   
   840    888   #----------------------------------------------------------------------------
   841    889   #   xmlReadFile
   842    890   #
   843    891   #----------------------------------------------------------------------------
   844         -proc tDOM::xmlReadFile {filename {encodingString {}}} {
          892  +proc tdom::xmlReadFile {filename {encodingString {}}} {
          893  +
          894  +    if {$encodingString != {}} {
          895  +        upvar $encodingString encString
          896  +    }
          897  +    
          898  +    set fd [xmlOpenFileWorker $filename encString 0 1]
          899  +    set data [read $fd [file size $filename]]
          900  +    close $fd 
          901  +    return $data
          902  +}
          903  +
          904  +#----------------------------------------------------------------------------
          905  +#   xmlReadFileForSimple
          906  +#
          907  +#----------------------------------------------------------------------------
          908  +proc tdom::xmlReadFileForSimple {filename {encodingString {}}} {
   845    909   
   846    910       if {$encodingString != {}} {
   847    911           upvar $encodingString encString
   848    912       }
   849    913       
   850         -    set fd [xmlOpenFile $filename encString]
          914  +    set fd [xmlOpenFileWorker $filename encString 1]
   851    915       set data [read $fd [file size $filename]]
   852    916       close $fd 
   853    917       return $data
   854    918   }
   855    919   
   856    920   #----------------------------------------------------------------------------
   857    921   #   extRefHandler
................................................................................
   858    922   #   
   859    923   #   A very simple external entity resolver, included for convenience.
   860    924   #   Depends on the tcllib package uri and resolves only file URLs. 
   861    925   #
   862    926   #----------------------------------------------------------------------------
   863    927   
   864    928   if {![catch {package require uri}]} {
   865         -    proc tDOM::extRefHandler {base systemId publicId} {
          929  +    proc tdom::extRefHandler {base systemId publicId} {
   866    930           variable extRefHandlerDebug
   867    931           variable useForeignDTD
   868    932   
   869    933           if {$extRefHandlerDebug} {
   870         -            puts stderr "tDOM::extRefHandler called with:"
          934  +            puts stderr "tdom::extRefHandler called with:"
   871    935               puts stderr "\tbase:     '$base'"
   872    936               puts stderr "\tsystemId: '$systemId'"
   873    937               puts stderr "\tpublicId: '$publicId'"
   874    938           }
   875    939           if {$systemId == ""} {
   876    940               if {$useForeignDTD != ""} {
   877    941                   set systemId $useForeignDTD
   878    942               } else {
   879         -                error "::tDOM::useForeignDTD does\
          943  +                error "::tdom::useForeignDTD does\
   880    944                           not point to the foreign DTD"
   881    945               }
   882    946           }
   883    947           set absolutURI [uri::resolve $base $systemId]
   884    948           array set uriData [uri::split $absolutURI]
   885    949           switch $uriData(scheme) {
   886    950               file {
          951  +                if {$::tcl_platform(platform) eq "windows"} {
          952  +                    # Strip leading / for drive based paths
          953  +                    if {[string match /?:* $uriData(path)]} {
          954  +                        set uriData(path) [string range $uriData(path) 1 end]
          955  +                    }
          956  +                }
          957  +                # FIXME - path should be URL-decoded
   887    958                   return [list string $absolutURI [xmlReadFile $uriData(path)]]
   888    959               }
   889    960               default {
   890    961                   error "can only handle file URI's"
   891    962               }
   892    963           }
   893    964       }
................................................................................
   896    967   #----------------------------------------------------------------------------
   897    968   #   baseURL
   898    969   #   
   899    970   #   A simple convenience proc which returns an absolute URL for a given
   900    971   #   filename.
   901    972   #
   902    973   #----------------------------------------------------------------------------
          974  +proc tdom::baseURL {path} {
          975  +    # FIXME - path components need to be URL-encoded
          976  +
          977  +    # Note [file join] will return path as is if it is already absolute.
          978  +    # Also on Windows, it will change \ -> /. This is necessary because
          979  +    # file URIs must always use /, never \.
          980  +    set path [file join [pwd] $path]
   903    981   
   904         -proc tDOM::baseURL {path} {
   905         -    switch [file pathtype $path] {
   906         -        "relative" {
   907         -            return "file://[pwd]/$path"
   908         -        }
   909         -        default {
   910         -            return "file://$path"
          982  +    if {$::tcl_platform(platform) ne "windows"} {
          983  +        return "file://$path"
          984  +    } else {
          985  +        if {[string match //* $path]} {
          986  +            # UNC path
          987  +            return "file:$path"
          988  +        } else {
          989  +            # Drive based path
          990  +            return "file:///$path"
   911    991           }
   912    992       }
   913    993   }
          994  +
          995  +namespace eval ::tDOM { 
          996  +    variable extRefHandlerDebug 0
          997  +    variable useForeignDTD ""
          998  +
          999  +    namespace export xmlOpenFile xmlReadFile xmlReadFileForSimple \
         1000  +        extRefHandler baseURL
         1001  +}
         1002  +
         1003  +foreach cmd {
         1004  +    xmlOpenFile
         1005  +    xmlReadFile
         1006  +    xmlReadFileForSimple
         1007  +    extRefHandler
         1008  +    baseURL
         1009  +} {
         1010  +    interp alias {} tDOM::$cmd {} tdom::$cmd
         1011  +}
   914   1012   
   915   1013   # 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         -/* Copyright 2000, Clark Cooper
     2         -   All rights reserved.
     3         -
     4         -   This is free software. You are permitted to copy, distribute, or modify
     5         -   it under the terms of the MIT/X license (contained in the COPYING file
     6         -   with this distribution.)
     7         -*/
     8         -
     9         -/* Define to empty if the keyword does not work.  */
    10         -#undef const
    11         -
    12         -/* Define if you have a working `mmap' system call.  */
    13         -#undef HAVE_MMAP
    14         -
    15         -/* Define to `long' if <sys/types.h> doesn't define.  */
    16         -#undef off_t
    17         -
    18         -/* Define to `unsigned' if <sys/types.h> doesn't define.  */
    19         -#undef size_t
    20         -
    21         -/* Define if you have the ANSI C header files.  */
    22         -#define STDC_HEADERS 1
    23         -
    24         -/* Define if your processor stores words with the most significant
    25         -   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
    26         -//#undef WORDS_BIGENDIAN
    27         -#define WORDS_BIGENDIAN
    28         -
    29         -/* Define if you have the bcopy function.  */
    30         -#undef HAVE_BCOPY
    31         -
    32         -/* Define if you have the getpagesize function.  */
    33         -#undef HAVE_GETPAGESIZE
    34         -
    35         -/* Define if you have the memmove function.  */
    36         -#define HAVE_MEMMOVE 1
    37         -
    38         -/* Define if you have the <fcntl.h> header file.  */
    39         -// #undef HAVE_FCNTL_H
    40         -#define HAVE_FCNTL_H
    41         -
    42         -/* Define if you have the <unistd.h> header file.  */
    43         -#define HAVE_UNISTD_H 1
    44         -
    45         -#define XML_NS
    46         -#define XML_DTD
    47         -
    48         -#ifdef WORDS_BIGENDIAN
    49         -#define XML_BYTE_ORDER 21
    50         -#else
    51         -#define XML_BYTE_ORDER 12
    52         -#endif
    53         -
    54         -#define XML_CONTEXT_BYTES 1024
    55         -
    56         -#ifndef HAVE_MEMMOVE
    57         -#ifdef HAVE_BCOPY
    58         -#define memmove(d,s,l) bcopy((s),(d),(l))
    59         -#else
    60         -#define memmove(d,s,l) ;punting on memmove;
    61         -#endif
    62         -
    63         -#endif

Deleted mac/tDOM.exp.

     1         -Tdom_Init
     2         -Tdom_SafeInit
     3         -CHandlerSetCreate
     4         -CHandlerSetGet
     5         -CHandlerSetGetUserData
     6         -CHandlerSetInstall
     7         -CHandlerSetRemove
     8         -CheckExpatParserObj
     9         -GetExpatInfo
    10         -TclExpatObjCmd
    11         -XML_GetBase
    12         -XML_GetCurrentByteCount
    13         -XML_GetCurrentByteIndex
    14         -XML_GetCurrentColumnNumber
    15         -XML_GetCurrentLineNumber
    16         -XML_GetIdAttributeIndex
    17         -XML_GetSpecifiedAttributeCount
    18         -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         -if {[catch {package require Tcl 8.2}]} return
     2         -
     3         -package ifneeded tdom 0.7.8 [list load [file join $dir tDOM.0.7.8.dylib] Tdom]
     4         -
     5         -
     6         -package ifneeded tnc 0.3.0 "package require tdom;
     7         -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      1   
     2      2   Please go to ../unix directory and inspect the CONFIG file.
     3      3   There you will find example on how to configure and make
     4         -the library on Mac OSX using GNU configure/make tools.
            4  +the library on macOS using GNU configure/make tools.
     5      5   
     6      6   -EOF

Changes to tclconfig/README.txt.

     1         -The other files in this directory are the functional core of the Tcl
     2         -Extension Architecture (TEA). For more information on TEA see:
            1  +These files comprise the basic building blocks for a Tcl Extension
            2  +Architecture (TEA) extension.  For more information on TEA see:
     3      3   
     4      4   	http://www.tcl.tk/doc/tea/
     5      5   
     6         -The other files in this directory are out of the tclconfig directory
     7         -of:
            6  +This package is part of the Tcl project at SourceForge, and latest
            7  +sources should be available there:
            8  +
            9  +	http://tcl.sourceforge.net/
           10  +
           11  +This package is a freely available open source package.  You can do
           12  +virtually anything you like with it, such as modifying it, redistributing
           13  +it, and selling it either in whole or in part.
           14  +
           15  +CONTENTS
           16  +========
           17  +The following is a short description of the files you will find in
           18  +the sample extension.
           19  +
           20  +README.txt	This file
     8     21   
     9         -http://cvs.sourceforge.net/viewcvs.py/tcl/sampleextension/
           22  +install-sh	Program used for copying binaries and script files
           23  +		to their install locations.
    10     24   
    11         -from 2007-07-26 (TEA 3.6).
           25  +tcl.m4		Collection of Tcl autoconf macros.  Included by a package's
           26  +		aclocal.m4 to define TEA_* macros.

Changes to tclconfig/install-sh.

     1      1   #!/bin/sh
     2         -
     3         -#
     4      2   # install - install a program, script, or datafile
     5         -# This comes from X11R5; it is not part of GNU.
            3  +
            4  +scriptversion=2011-04-20.01; # UTC
            5  +
            6  +# This originates from X11R5 (mit/util/scripts/install.sh), which was
            7  +# later released in X11R6 (xc/config/util/install.sh) with the
            8  +# following copyright and license.
            9  +#
           10  +# Copyright (C) 1994 X Consortium
           11  +#
           12  +# Permission is hereby granted, free of charge, to any person obtaining a copy
           13  +# of this software and associated documentation files (the "Software"), to
           14  +# deal in the Software without restriction, including without limitation the
           15  +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
           16  +# sell copies of the Software, and to permit persons to whom the Software is
           17  +# furnished to do so, subject to the following conditions:
           18  +#
           19  +# The above copyright notice and this permission notice shall be included in
           20  +# all copies or substantial portions of the Software.
           21  +#
           22  +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
           23  +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
           24  +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
           25  +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
           26  +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
           27  +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
           28  +#
           29  +# Except as contained in this notice, the name of the X Consortium shall not
           30  +# be used in advertising or otherwise to promote the sale, use or other deal-
           31  +# ings in this Software without prior written authorization from the X Consor-
           32  +# tium.
           33  +#
           34  +#
           35  +# FSF changes to this file are in the public domain.
     6     36   #
     7         -# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
           37  +# Calling this script install-sh is preferred over install.sh, to prevent
           38  +# `make' implicit rules from creating a file called install from it
           39  +# when there is no Makefile.
     8     40   #
     9     41   # This script is compatible with the BSD install script, but was written
    10     42   # from scratch.
    11         -#
    12     43   
           44  +nl='
           45  +'
           46  +IFS=" ""	$nl"
    13     47   
    14     48   # set DOITPROG to echo to test this script
    15     49   
    16     50   # Don't use :- since 4.3BSD and earlier shells don't like it.
    17         -doit="${DOITPROG-}"
    18         -
    19         -
    20         -# put in absolute paths if you don't have them in your path; or use env. vars.
    21         -
    22         -mvprog="${MVPROG-mv}"
    23         -cpprog="${CPPROG-cp}"
    24         -chmodprog="${CHMODPROG-chmod}"
    25         -chownprog="${CHOWNPROG-chown}"
    26         -chgrpprog="${CHGRPPROG-chgrp}"
    27         -stripprog="${STRIPPROG-strip}"
    28         -rmprog="${RMPROG-rm}"
    29         -
    30         -instcmd="$mvprog"
    31         -chmodcmd=""
    32         -chowncmd=""
    33         -chgrpcmd=""
    34         -stripcmd=""
           51  +doit=${DOITPROG-}
           52  +if test -z "$doit"; then
           53  +  doit_exec=exec
           54  +else
           55  +  doit_exec=$doit
           56  +fi
           57  +
           58  +# Put in absolute file names if you don't have them in your path;
           59  +# or use environment vars.
           60  +
           61  +chgrpprog=${CHGRPPROG-chgrp}
           62  +chmodprog=${CHMODPROG-chmod}
           63  +chownprog=${CHOWNPROG-chown}
           64  +cmpprog=${CMPPROG-cmp}
           65  +cpprog=${CPPROG-cp}
           66  +mkdirprog=${MKDIRPROG-mkdir}
           67  +mvprog=${MVPROG-mv}
           68  +rmprog=${RMPROG-rm}
           69  +stripprog=${STRIPPROG-strip}
           70  +
           71  +posix_glob='?'
           72  +initialize_posix_glob='
           73  +  test "$posix_glob" != "?" || {
           74  +    if (set -f) 2>/dev/null; then
           75  +      posix_glob=
           76  +    else
           77  +      posix_glob=:
           78  +    fi
           79  +  }
           80  +'
           81  +
           82  +posix_mkdir=
           83  +
           84  +# Desired mode of installed file.
           85  +mode=0755
           86  +
           87  +chgrpcmd=
           88  +chmodcmd=$chmodprog
           89  +chowncmd=
           90  +mvcmd=$mvprog
    35     91   rmcmd="$rmprog -f"
    36         -mvcmd="$mvprog"
    37         -src=""
    38         -dst=""
    39         -
    40         -while [ x"$1" != x ]; do
    41         -    case $1 in
    42         -	-c) instcmd="$cpprog"
    43         -	    shift
    44         -	    continue;;
    45         -
    46         -	-m) chmodcmd="$chmodprog $2"
    47         -	    shift
    48         -	    shift
    49         -	    continue;;
    50         -
    51         -	-o) chowncmd="$chownprog $2"
    52         -	    shift
    53         -	    shift
    54         -	    continue;;
    55         -
    56         -	-g) chgrpcmd="$chgrpprog $2"
    57         -	    shift
    58         -	    shift
    59         -	    continue;;
    60         -
    61         -	-s) stripcmd="$stripprog"
    62         -	    shift
    63         -	    continue;;
    64         -
    65         -	*)  if [ x"$src" = x ]
    66         -	    then
    67         -		src=$1
    68         -	    else
    69         -		dst=$1
    70         -	    fi
    71         -	    shift
    72         -	    continue;;
    73         -    esac
           92  +stripcmd=
           93  +
           94  +src=
           95  +dst=
           96  +dir_arg=
           97  +dst_arg=
           98  +
           99  +copy_on_change=false
          100  +no_target_directory=
          101  +
          102  +usage="\
          103  +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
          104  +   or: $0 [OPTION]... SRCFILES... DIRECTORY
          105  +   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
          106  +   or: $0 [OPTION]... -d DIRECTORIES...
          107  +
          108  +In the 1st form, copy SRCFILE to DSTFILE.
          109  +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
          110  +In the 4th, create DIRECTORIES.
          111  +
          112  +Options:
          113  +     --help     display this help and exit.
          114  +     --version  display version info and exit.
          115  +
          116  +  -c            (ignored)
          117  +  -C            install only if different (preserve the last data modification time)
          118  +  -d            create directories instead of installing files.
          119  +  -g GROUP      $chgrpprog installed files to GROUP.
          120  +  -m MODE       $chmodprog installed files to MODE.
          121  +  -o USER       $chownprog installed files to USER.
          122  +  -s            $stripprog installed files.
          123  +  -S            $stripprog installed files.
          124  +  -t DIRECTORY  install into DIRECTORY.
          125  +  -T            report an error if DSTFILE is a directory.
          126  +
          127  +Environment variables override the default commands:
          128  +  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
          129  +  RMPROG STRIPPROG
          130  +"
          131  +
          132  +while test $# -ne 0; do
          133  +  case $1 in
          134  +    -c) ;;
          135  +
          136  +    -C) copy_on_change=true;;
          137  +
          138  +    -d) dir_arg=true;;
          139  +
          140  +    -g) chgrpcmd="$chgrpprog $2"
          141  +	shift;;
          142  +
          143  +    --help) echo "$usage"; exit $?;;
          144  +
          145  +    -m) mode=$2
          146  +	case $mode in
          147  +	  *' '* | *'	'* | *'
          148  +'*	  | *'*'* | *'?'* | *'['*)
          149  +	    echo "$0: invalid mode: $mode" >&2
          150  +	    exit 1;;
          151  +	esac
          152  +	shift;;
          153  +
          154  +    -o) chowncmd="$chownprog $2"
          155  +	shift;;
          156  +
          157  +    -s) stripcmd=$stripprog;;
          158  +
          159  +    -S) stripcmd="$stripprog $2"
          160  +	shift;;
          161  +
          162  +    -t) dst_arg=$2
          163  +	shift;;
          164  +
          165  +    -T) no_target_directory=true;;
          166  +
          167  +    --version) echo "$0 $scriptversion"; exit $?;;
          168  +
          169  +    --)	shift
          170  +	break;;
          171  +
          172  +    -*)	echo "$0: invalid option: $1" >&2
          173  +	exit 1;;
          174  +
          175  +    *)  break;;
          176  +  esac
          177  +  shift
    74    178   done
    75    179   
    76         -if [ x"$src" = x ]
    77         -then
    78         -	echo "install:  no input file specified"
    79         -	exit 1
          180  +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
          181  +  # When -d is used, all remaining arguments are directories to create.
          182  +  # When -t is used, the destination is already specified.
          183  +  # Otherwise, the last argument is the destination.  Remove it from $@.
          184  +  for arg
          185  +  do
          186  +    if test -n "$dst_arg"; then
          187  +      # $@ is not empty: it contains at least $arg.
          188  +      set fnord "$@" "$dst_arg"
          189  +      shift # fnord
          190  +    fi
          191  +    shift # arg
          192  +    dst_arg=$arg
          193  +  done
          194  +fi
          195  +
          196  +if test $# -eq 0; then
          197  +  if test -z "$dir_arg"; then
          198  +    echo "$0: no input file specified." >&2
          199  +    exit 1
          200  +  fi
          201  +  # It's OK to call `install-sh -d' without argument.
          202  +  # This can happen when creating conditional directories.
          203  +  exit 0
          204  +fi
          205  +
          206  +if test -z "$dir_arg"; then
          207  +  do_exit='(exit $ret); exit $ret'
          208  +  trap "ret=129; $do_exit" 1
          209  +  trap "ret=130; $do_exit" 2
          210  +  trap "ret=141; $do_exit" 13
          211  +  trap "ret=143; $do_exit" 15
          212  +
          213  +  # Set umask so as not to create temps with too-generous modes.
          214  +  # However, 'strip' requires both read and write access to temps.
          215  +  case $mode in
          216  +    # Optimize common cases.
          217  +    *644) cp_umask=133;;
          218  +    *755) cp_umask=22;;
          219  +
          220  +    *[0-7])
          221  +      if test -z "$stripcmd"; then
          222  +	u_plus_rw=
          223  +      else
          224  +	u_plus_rw='% 200'
          225  +      fi
          226  +      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
          227  +    *)
          228  +      if test -z "$stripcmd"; then
          229  +	u_plus_rw=
          230  +      else
          231  +	u_plus_rw=,u+rw
          232  +      fi
          233  +      cp_umask=$mode$u_plus_rw;;
          234  +  esac
    80    235   fi
    81    236   
    82         -if [ x"$dst" = x ]
    83         -then
    84         -	echo "install:  no destination specified"
          237  +for src
          238  +do
          239  +  # Protect names starting with `-'.
          240  +  case $src in
          241  +    -*) src=./$src;;
          242  +  esac
          243  +
          244  +  if test -n "$dir_arg"; then
          245  +    dst=$src
          246  +    dstdir=$dst
          247  +    test -d "$dstdir"
          248  +    dstdir_status=$?
          249  +  else
          250  +
          251  +    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
          252  +    # might cause directories to be created, which would be especially bad
          253  +    # if $src (and thus $dsttmp) contains '*'.
          254  +    if test ! -f "$src" && test ! -d "$src"; then
          255  +      echo "$0: $src does not exist." >&2
          256  +      exit 1
          257  +    fi
          258  +
          259  +    if test -z "$dst_arg"; then
          260  +      echo "$0: no destination specified." >&2
          261  +      exit 1
          262  +    fi
          263  +
          264  +    dst=$dst_arg
          265  +    # Protect names starting with `-'.
          266  +    case $dst in
          267  +      -*) dst=./$dst;;
          268  +    esac
          269  +
          270  +    # If destination is a directory, append the input filename; won't work
          271  +    # if double slashes aren't ignored.
          272  +    if test -d "$dst"; then
          273  +      if test -n "$no_target_directory"; then
          274  +	echo "$0: $dst_arg: Is a directory" >&2
    85    275   	exit 1
    86         -fi
          276  +      fi
          277  +      dstdir=$dst
          278  +      dst=$dstdir/`basename "$src"`
          279  +      dstdir_status=0
          280  +    else
          281  +      # Prefer dirname, but fall back on a substitute if dirname fails.
          282  +      dstdir=`
          283  +	(dirname "$dst") 2>/dev/null ||
          284  +	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
          285  +	     X"$dst" : 'X\(//\)[^/]' \| \
          286  +	     X"$dst" : 'X\(//\)$' \| \
          287  +	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
          288  +	echo X"$dst" |
          289  +	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
          290  +		   s//\1/
          291  +		   q
          292  +		 }
          293  +		 /^X\(\/\/\)[^/].*/{
          294  +		   s//\1/
          295  +		   q
          296  +		 }
          297  +		 /^X\(\/\/\)$/{
          298  +		   s//\1/
          299  +		   q
          300  +		 }
          301  +		 /^X\(\/\).*/{
          302  +		   s//\1/
          303  +		   q
          304  +		 }
          305  +		 s/.*/./; q'
          306  +      `
          307  +
          308  +      test -d "$dstdir"
          309  +      dstdir_status=$?
          310  +    fi
          311  +  fi
          312  +
          313  +  obsolete_mkdir_used=false
          314  +
          315  +  if test $dstdir_status != 0; then
          316  +    case $posix_mkdir in
          317  +      '')
          318  +	# Create intermediate dirs using mode 755 as modified by the umask.
          319  +	# This is like FreeBSD 'install' as of 1997-10-28.
          320  +	umask=`umask`
          321  +	case $stripcmd.$umask in
          322  +	  # Optimize common cases.
          323  +	  *[2367][2367]) mkdir_umask=$umask;;
          324  +	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
          325  +
          326  +	  *[0-7])
          327  +	    mkdir_umask=`expr $umask + 22 \
          328  +	      - $umask % 100 % 40 + $umask % 20 \
          329  +	      - $umask % 10 % 4 + $umask % 2
          330  +	    `;;
          331  +	  *) mkdir_umask=$umask,go-w;;
          332  +	esac
          333  +
          334  +	# With -d, create the new directory with the user-specified mode.
          335  +	# Otherwise, rely on $mkdir_umask.
          336  +	if test -n "$dir_arg"; then
          337  +	  mkdir_mode=-m$mode
          338  +	else
          339  +	  mkdir_mode=
          340  +	fi
          341  +
          342  +	posix_mkdir=false
          343  +	case $umask in
          344  +	  *[123567][0-7][0-7])
          345  +	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
          346  +	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
          347  +	    ;;
          348  +	  *)
          349  +	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
          350  +	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
          351  +
          352  +	    if (umask $mkdir_umask &&
          353  +		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
          354  +	    then
          355  +	      if test -z "$dir_arg" || {
          356  +		   # Check for POSIX incompatibilities with -m.
          357  +		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
          358  +		   # other-writeable bit of parent directory when it shouldn't.
          359  +		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
          360  +		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
          361  +		   case $ls_ld_tmpdir in
          362  +		     d????-?r-*) different_mode=700;;
          363  +		     d????-?--*) different_mode=755;;
          364  +		     *) false;;
          365  +		   esac &&
          366  +		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
          367  +		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
          368  +		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
          369  +		   }
          370  +		 }
          371  +	      then posix_mkdir=:
          372  +	      fi
          373  +	      rmdir "$tmpdir/d" "$tmpdir"
          374  +	    else
          375  +	      # Remove any dirs left behind by ancient mkdir implementations.
          376  +	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
          377  +	    fi
          378  +	    trap '' 0;;
          379  +	esac;;
          380  +    esac
          381  +
          382  +    if
          383  +      $posix_mkdir && (
          384  +	umask $mkdir_umask &&
          385  +	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
          386  +      )
          387  +    then :
          388  +    else
          389  +
          390  +      # The umask is ridiculous, or mkdir does not conform to POSIX,
          391  +      # or it failed possibly due to a race condition.  Create the
          392  +      # directory the slow way, step by step, checking for races as we go.
          393  +
          394  +      case $dstdir in
          395  +	/*) prefix='/';;
          396  +	-*) prefix='./';;
          397  +	*)  prefix='';;
          398  +      esac
          399  +
          400  +      eval "$initialize_posix_glob"
          401  +
          402  +      oIFS=$IFS
          403  +      IFS=/
          404  +      $posix_glob set -f
          405  +      set fnord $dstdir
          406  +      shift
          407  +      $posix_glob set +f
          408  +      IFS=$oIFS
          409  +
          410  +      prefixes=
          411  +
          412  +      for d
          413  +      do
          414  +	test -z "$d" && continue
          415  +
          416  +	prefix=$prefix$d
          417  +	if test -d "$prefix"; then
          418  +	  prefixes=
          419  +	else
          420  +	  if $posix_mkdir; then
          421  +	    (umask=$mkdir_umask &&
          422  +	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
          423  +	    # Don't fail if two instances are running concurrently.
          424  +	    test -d "$prefix" || exit 1
          425  +	  else
          426  +	    case $prefix in
          427  +	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
          428  +	      *) qprefix=$prefix;;
          429  +	    esac
          430  +	    prefixes="$prefixes '$qprefix'"
          431  +	  fi
          432  +	fi
          433  +	prefix=$prefix/
          434  +      done
          435  +
          436  +      if test -n "$prefixes"; then
          437  +	# Don't fail if two instances are running concurrently.
          438  +	(umask $mkdir_umask &&
          439  +	 eval "\$doit_exec \$mkdirprog $prefixes") ||
          440  +	  test -d "$dstdir" || exit 1
          441  +	obsolete_mkdir_used=true
          442  +      fi
          443  +    fi
          444  +  fi
          445  +
          446  +  if test -n "$dir_arg"; then
          447  +    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
          448  +    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
          449  +    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
          450  +      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
          451  +  else
          452  +
          453  +    # Make a couple of temp file names in the proper directory.
          454  +    dsttmp=$dstdir/_inst.$$_
          455  +    rmtmp=$dstdir/_rm.$$_
          456  +
          457  +    # Trap to clean up those temp files at exit.
          458  +    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
          459  +
          460  +    # Copy the file name to the temp name.
          461  +    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
          462  +
          463  +    # and set any options; do chmod last to preserve setuid bits.
          464  +    #
          465  +    # If any of these fail, we abort the whole thing.  If we want to
          466  +    # ignore errors from any of these, just make sure not to ignore
          467  +    # errors from the above "$doit $cpprog $src $dsttmp" command.
          468  +    #
          469  +    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
          470  +    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
          471  +    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
          472  +    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
          473  +
          474  +    # If -C, don't bother to copy if it wouldn't change the file.
          475  +    if $copy_on_change &&
          476  +       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
          477  +       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
          478  +
          479  +       eval "$initialize_posix_glob" &&
          480  +       $posix_glob set -f &&
          481  +       set X $old && old=:$2:$4:$5:$6 &&
          482  +       set X $new && new=:$2:$4:$5:$6 &&
          483  +       $posix_glob set +f &&
    87    484   
          485  +       test "$old" = "$new" &&
          486  +       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
          487  +    then
          488  +      rm -f "$dsttmp"
          489  +    else
          490  +      # Rename the file to the real destination.
          491  +      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
    88    492   
    89         -# If destination is a directory, append the input filename; if your system
    90         -# does not like double slashes in filenames, you may need to add some logic
          493  +      # The rename failed, perhaps because mv can't rename something else
          494  +      # to itself, or perhaps because mv is so ancient that it does not
          495  +      # support -f.
          496  +      {
          497  +	# Now remove or move aside any old file at destination location.
          498  +	# We try this two ways since rm can't unlink itself on some
          499  +	# systems and the destination file might be busy for other
          500  +	# reasons.  In this case, the final cleanup might fail but the new
          501  +	# file should still install successfully.
          502  +	{
          503  +	  test ! -f "$dst" ||
          504  +	  $doit $rmcmd -f "$dst" 2>/dev/null ||
          505  +	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
          506  +	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
          507  +	  } ||
          508  +	  { echo "$0: cannot unlink or rename $dst" >&2
          509  +	    (exit 1); exit 1
          510  +	  }
          511  +	} &&
    91    512   
    92         -if [ -d $dst ]
    93         -then
    94         -	dst="$dst"/`basename $src`
    95         -fi
          513  +	# Now rename the file to the real destination.
          514  +	$doit $mvcmd "$dsttmp" "$dst"
          515  +      }
          516  +    fi || exit 1
    96    517   
    97         -# Make a temp file name in the proper directory.
    98         -
    99         -dstdir=`dirname $dst`
   100         -dsttmp=$dstdir/#inst.$$#
   101         -
   102         -# Move or copy the file name to the temp name
          518  +    trap '' 0
          519  +  fi
          520  +done
   103    521   
   104         -$doit $instcmd $src $dsttmp
   105         -
   106         -# and set any options; do chmod last to preserve setuid bits
   107         -
   108         -if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
   109         -if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
   110         -if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
   111         -if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
   112         -
   113         -# Now rename the file to the real destination.
   114         -
   115         -$doit $rmcmd $dst
   116         -$doit $mvcmd $dsttmp $dst
   117         -
   118         -
   119         -exit 0
          522  +# Local variables:
          523  +# eval: (add-hook 'write-file-hooks 'time-stamp)
          524  +# time-stamp-start: "scriptversion="
          525  +# time-stamp-format: "%:y-%02m-%02d.%02H"
          526  +# time-stamp-time-zone: "UTC"
          527  +# time-stamp-end: "; # UTC"
          528  +# End:

Changes to tclconfig/tcl.m4.

     4      4   #	a Tcl extension.
     5      5   #
     6      6   # Copyright (c) 1999-2000 Ajuba Solutions.
     7      7   # Copyright (c) 2002-2005 ActiveState Corporation.
     8      8   #
     9      9   # See the file "license.terms" for information on usage and redistribution
    10     10   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    11         -#
    12         -# RCS: @(#) $Id$
    13     11   
    14     12   AC_PREREQ(2.57)
    15     13   
    16         -dnl TEA extensions pass us the version of TEA they think they
    17         -dnl are compatible with (must be set in TEA_INIT below)
    18         -dnl TEA_VERSION="3.6"
    19         -
    20     14   # Possible values for key variables defined:
    21     15   #
    22     16   # TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
    23     17   # TEA_PLATFORM        - windows unix
           18  +# TEA_TK_EXTENSION    - True if this is a Tk extension
    24     19   #
    25     20   
    26     21   #------------------------------------------------------------------------
    27     22   # TEA_PATH_TCLCONFIG --
    28     23   #
    29     24   #	Locate the tclConfig.sh file and perform a sanity check on
    30     25   #	the Tcl compile flags
................................................................................
    39     34   #
    40     35   #	Defines the following vars:
    41     36   #		TCL_BIN_DIR	Full path to the directory containing
    42     37   #				the tclConfig.sh file
    43     38   #------------------------------------------------------------------------
    44     39   
    45     40   AC_DEFUN([TEA_PATH_TCLCONFIG], [
    46         -    dnl Make sure we are initialized
           41  +    dnl TEA specific: Make sure we are initialized
    47     42       AC_REQUIRE([TEA_INIT])
    48     43       #
    49     44       # Ok, lets find the tcl configuration
    50     45       # First, look for one uninstalled.
    51     46       # the alternative search directory is invoked by --with-tcl
    52     47       #
    53     48   
    54     49       if test x"${no_tcl}" = x ; then
    55     50   	# we reset no_tcl in case something fails here
    56     51   	no_tcl=true
    57     52   	AC_ARG_WITH(tcl,
    58     53   	    AC_HELP_STRING([--with-tcl],
    59     54   		[directory containing tcl configuration (tclConfig.sh)]),
    60         -	    with_tclconfig=${withval})
           55  +	    with_tclconfig="${withval}")
    61     56   	AC_MSG_CHECKING([for Tcl configuration])
    62     57   	AC_CACHE_VAL(ac_cv_c_tclconfig,[
    63     58   
    64     59   	    # First check to see if --with-tcl was specified.
    65     60   	    if test x"${with_tclconfig}" != x ; then
    66         -		case ${with_tclconfig} in
           61  +		case "${with_tclconfig}" in
    67     62   		    */tclConfig.sh )
    68         -			if test -f ${with_tclconfig}; then
           63  +			if test -f "${with_tclconfig}"; then
    69     64   			    AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
    70         -			    with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
           65  +			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
    71     66   			fi ;;
    72     67   		esac
    73     68   		if test -f "${with_tclconfig}/tclConfig.sh" ; then
    74         -		    ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
           69  +		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
    75     70   		else
    76     71   		    AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
    77     72   		fi
    78     73   	    fi
    79     74   
    80     75   	    # then check for a private Tcl installation
    81     76   	    if test x"${ac_cv_c_tclconfig}" = x ; then
................................................................................
    88     83   			`ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
    89     84   			`ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
    90     85   			`ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
    91     86   			../../../tcl \
    92     87   			`ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
    93     88   			`ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
    94     89   			`ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
           90  +		    if test "${TEA_PLATFORM}" = "windows" \
           91  +			    -a -f "$i/win/tclConfig.sh" ; then
           92  +			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
           93  +			break
           94  +		    fi
    95     95   		    if test -f "$i/unix/tclConfig.sh" ; then
    96         -			ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
           96  +			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
    97     97   			break
    98     98   		    fi
    99     99   		done
   100    100   	    fi
   101    101   
   102    102   	    # on Darwin, check in Framework installation locations
   103    103   	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
   104    104   		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
   105    105   			`ls -d /Library/Frameworks 2>/dev/null` \
   106    106   			`ls -d /Network/Library/Frameworks 2>/dev/null` \
   107    107   			`ls -d /System/Library/Frameworks 2>/dev/null` \
          108  +			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
          109  +			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
          110  +			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
   108    111   			; do
   109    112   		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
   110         -			ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
          113  +			ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
   111    114   			break
   112    115   		    fi
   113    116   		done
   114    117   	    fi
   115    118   
   116         -	    # on Windows, check in common installation locations
          119  +	    # TEA specific: on Windows, check in common installation locations
   117    120   	    if test "${TEA_PLATFORM}" = "windows" \
   118    121   		-a x"${ac_cv_c_tclconfig}" = x ; then
   119    122   		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
   120    123   			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
   121    124   			; do
   122    125   		    if test -f "$i/tclConfig.sh" ; then
   123         -			ac_cv_c_tclconfig=`(cd $i; pwd)`
          126  +			ac_cv_c_tclconfig="`(cd $i; pwd)`"
   124    127   			break
   125    128   		    fi
   126    129   		done
   127    130   	    fi
   128    131   
   129    132   	    # check in a few common install locations
   130    133   	    if test x"${ac_cv_c_tclconfig}" = x ; then
   131    134   		for i in `ls -d ${libdir} 2>/dev/null` \
   132    135   			`ls -d ${exec_prefix}/lib 2>/dev/null` \
   133    136   			`ls -d ${prefix}/lib 2>/dev/null` \
   134    137   			`ls -d /usr/local/lib 2>/dev/null` \
   135    138   			`ls -d /usr/contrib/lib 2>/dev/null` \
          139  +			`ls -d /usr/pkg/lib 2>/dev/null` \
   136    140   			`ls -d /usr/lib 2>/dev/null` \
          141  +			`ls -d /usr/lib64 2>/dev/null` \
          142  +			`ls -d /usr/lib/tcl8.6 2>/dev/null` \
          143  +			`ls -d /usr/lib/tcl8.5 2>/dev/null` \
          144  +			`ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
          145  +			`ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
          146  +			`ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
          147  +			`ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
   137    148   			; do
   138    149   		    if test -f "$i/tclConfig.sh" ; then
   139         -			ac_cv_c_tclconfig=`(cd $i; pwd)`
          150  +			ac_cv_c_tclconfig="`(cd $i; pwd)`"
   140    151   			break
   141    152   		    fi
   142    153   		done
   143    154   	    fi
   144    155   
   145    156   	    # check in a few other private locations
   146    157   	    if test x"${ac_cv_c_tclconfig}" = x ; then
   147    158   		for i in \
   148    159   			${srcdir}/../tcl \
   149    160   			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
   150    161   			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
   151    162   			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
          163  +		    if test "${TEA_PLATFORM}" = "windows" \
          164  +			    -a -f "$i/win/tclConfig.sh" ; then
          165  +			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
          166  +			break
          167  +		    fi
   152    168   		    if test -f "$i/unix/tclConfig.sh" ; then
   153         -		    ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
   154         -		    break
   155         -		fi
          169  +			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
          170  +			break
          171  +		    fi
   156    172   		done
   157    173   	    fi
   158    174   	])
   159    175   
   160    176   	if test x"${ac_cv_c_tclconfig}" = x ; then
   161    177   	    TCL_BIN_DIR="# no Tcl configs found"
   162         -	    AC_MSG_WARN([Can't find Tcl configuration definitions])
   163         -	    exit 0
          178  +	    AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
   164    179   	else
   165    180   	    no_tcl=
   166         -	    TCL_BIN_DIR=${ac_cv_c_tclconfig}
          181  +	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
   167    182   	    AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
   168    183   	fi
   169    184       fi
   170    185   ])
   171    186   
   172    187   #------------------------------------------------------------------------
   173    188   # TEA_PATH_TKCONFIG --
................................................................................
   196    211   
   197    212       if test x"${no_tk}" = x ; then
   198    213   	# we reset no_tk in case something fails here
   199    214   	no_tk=true
   200    215   	AC_ARG_WITH(tk,
   201    216   	    AC_HELP_STRING([--with-tk],
   202    217   		[directory containing tk configuration (tkConfig.sh)]),
   203         -	    with_tkconfig=${withval})
          218  +	    with_tkconfig="${withval}")
   204    219   	AC_MSG_CHECKING([for Tk configuration])
   205    220   	AC_CACHE_VAL(ac_cv_c_tkconfig,[
   206    221   
   207    222   	    # First check to see if --with-tkconfig was specified.
   208    223   	    if test x"${with_tkconfig}" != x ; then
   209         -		case ${with_tkconfig} in
          224  +		case "${with_tkconfig}" in
   210    225   		    */tkConfig.sh )
   211         -			if test -f ${with_tkconfig}; then
          226  +			if test -f "${with_tkconfig}"; then
   212    227   			    AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
   213         -			    with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'`
          228  +			    with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
   214    229   			fi ;;
   215    230   		esac
   216    231   		if test -f "${with_tkconfig}/tkConfig.sh" ; then
   217         -		    ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
          232  +		    ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
   218    233   		else
   219    234   		    AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
   220    235   		fi
   221    236   	    fi
   222    237   
   223    238   	    # then check for a private Tk library
   224    239   	    if test x"${ac_cv_c_tkconfig}" = x ; then
................................................................................
   231    246   			`ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
   232    247   			`ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
   233    248   			`ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
   234    249   			../../../tk \
   235    250   			`ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
   236    251   			`ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
   237    252   			`ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
          253  +		    if test "${TEA_PLATFORM}" = "windows" \
          254  +			    -a -f "$i/win/tkConfig.sh" ; then
          255  +			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
          256  +			break
          257  +		    fi
   238    258   		    if test -f "$i/unix/tkConfig.sh" ; then
   239         -			ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
          259  +			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
   240    260   			break
   241    261   		    fi
   242    262   		done
   243    263   	    fi
   244    264   
   245    265   	    # on Darwin, check in Framework installation locations
   246    266   	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
   247    267   		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
   248    268   			`ls -d /Library/Frameworks 2>/dev/null` \
   249    269   			`ls -d /Network/Library/Frameworks 2>/dev/null` \
   250    270   			`ls -d /System/Library/Frameworks 2>/dev/null` \
          271  +			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
          272  +			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
          273  +			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
   251    274   			; do
   252    275   		    if test -f "$i/Tk.framework/tkConfig.sh" ; then
   253         -			ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)`
          276  +			ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
   254    277   			break
   255    278   		    fi
   256    279   		done
   257    280   	    fi
   258    281   
   259    282   	    # check in a few common install locations
   260    283   	    if test x"${ac_cv_c_tkconfig}" = x ; then
   261    284   		for i in `ls -d ${libdir} 2>/dev/null` \
   262    285   			`ls -d ${exec_prefix}/lib 2>/dev/null` \
   263    286   			`ls -d ${prefix}/lib 2>/dev/null` \
   264    287   			`ls -d /usr/local/lib 2>/dev/null` \
   265    288   			`ls -d /usr/contrib/lib 2>/dev/null` \
          289  +			`ls -d /usr/pkg/lib 2>/dev/null` \
   266    290   			`ls -d /usr/lib 2>/dev/null` \
          291  +			`ls -d /usr/lib64 2>/dev/null` \
          292  +			`ls -d /usr/lib/tk8.6 2>/dev/null` \
          293  +			`ls -d /usr/lib/tk8.5 2>/dev/null` \
          294  +			`ls -d /usr/local/lib/tk8.6 2>/dev/null` \
          295  +			`ls -d /usr/local/lib/tk8.5 2>/dev/null` \
          296  +			`ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
          297  +			`ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
   267    298   			; do
   268    299   		    if test -f "$i/tkConfig.sh" ; then
   269         -			ac_cv_c_tkconfig=`(cd $i; pwd)`
          300  +			ac_cv_c_tkconfig="`(cd $i; pwd)`"
   270    301   			break
   271    302   		    fi
   272    303   		done
   273    304   	    fi
   274    305   
   275         -	    # on Windows, check in common installation locations
          306  +	    # TEA specific: on Windows, check in common installation locations
   276    307   	    if test "${TEA_PLATFORM}" = "windows" \
   277    308   		-a x"${ac_cv_c_tkconfig}" = x ; then
   278    309   		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
   279    310   			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
   280    311   			; do
   281    312   		    if test -f "$i/tkConfig.sh" ; then
   282         -			ac_cv_c_tkconfig=`(cd $i; pwd)`
          313  +			ac_cv_c_tkconfig="`(cd $i; pwd)`"
   283    314   			break
   284    315   		    fi
   285    316   		done
   286    317   	    fi
   287    318   
   288    319   	    # check in a few other private locations
   289    320   	    if test x"${ac_cv_c_tkconfig}" = x ; then
   290    321   		for i in \
   291    322   			${srcdir}/../tk \
   292    323   			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
   293    324   			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
   294    325   			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
          326  +		    if test "${TEA_PLATFORM}" = "windows" \
          327  +			    -a -f "$i/win/tkConfig.sh" ; then
          328  +			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
          329  +			break
          330  +		    fi
   295    331   		    if test -f "$i/unix/tkConfig.sh" ; then
   296         -			ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
          332  +			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
   297    333   			break
   298    334   		    fi
   299    335   		done
   300    336   	    fi
   301    337   	])
   302    338   
   303    339   	if test x"${ac_cv_c_tkconfig}" = x ; then
   304    340   	    TK_BIN_DIR="# no Tk configs found"
   305         -	    AC_MSG_WARN([Can't find Tk configuration definitions])
   306         -	    exit 0
          341  +	    AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
   307    342   	else
   308    343   	    no_tk=
   309         -	    TK_BIN_DIR=${ac_cv_c_tkconfig}
          344  +	    TK_BIN_DIR="${ac_cv_c_tkconfig}"
   310    345   	    AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
   311    346   	fi
   312    347       fi
   313    348   ])
   314    349   
   315    350   #------------------------------------------------------------------------
   316    351   # TEA_LOAD_TCLCONFIG --
   317    352   #
   318    353   #	Load the tclConfig.sh file
   319    354   #
   320    355   # Arguments:
   321         -#	
          356  +#
   322    357   #	Requires the following vars to be set:
   323    358   #		TCL_BIN_DIR
   324    359   #
   325    360   # Results:
   326    361   #
   327         -#	Subst the following vars:
          362  +#	Substitutes the following vars:
   328    363   #		TCL_BIN_DIR
   329    364   #		TCL_SRC_DIR
   330    365   #		TCL_LIB_FILE
   331         -#
          366  +#		TCL_ZIP_FILE
          367  +#		TCL_ZIPFS_SUPPORT
   332    368   #------------------------------------------------------------------------
   333    369   
   334    370   AC_DEFUN([TEA_LOAD_TCLCONFIG], [
   335    371       AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
   336    372   
   337    373       if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
   338    374           AC_MSG_RESULT([loading])
................................................................................
   348    384       # If the TCL_BIN_DIR is the build directory (not the install directory),
   349    385       # then set the common variable name to the value of the build variables.
   350    386       # For example, the variable TCL_LIB_SPEC will be set to the value
   351    387       # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
   352    388       # instead of TCL_BUILD_LIB_SPEC since it will work with both an
   353    389       # installed and uninstalled version of Tcl.
   354    390       if test -f "${TCL_BIN_DIR}/Makefile" ; then
   355         -        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
   356         -        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
   357         -        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
          391  +        TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
          392  +        TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
          393  +        TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
   358    394       elif test "`uname -s`" = "Darwin"; then
   359    395   	# If Tcl was built as a framework, attempt to use the libraries
   360    396   	# from the framework at the given location so that linking works
   361         -	# against Tcl.framework installed in an arbitary location.
          397  +	# against Tcl.framework installed in an arbitrary location.
   362    398   	case ${TCL_DEFS} in
   363    399   	    *TCL_FRAMEWORK*)
   364    400   		if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
   365         -		    for i in "`cd ${TCL_BIN_DIR}; pwd`" \
   366         -			     "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
          401  +		    for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
          402  +			     "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
   367    403   			if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
   368         -			    TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
          404  +			    TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
   369    405   			    break
   370    406   			fi
   371    407   		    done
   372    408   		fi
   373    409   		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
   374         -		    TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
          410  +		    TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
   375    411   		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
   376    412   		fi
   377    413   		;;
   378    414   	esac
   379    415       fi
   380    416   
   381    417       # eval is required to do the TCL_DBGX substitution
   382    418       eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
   383    419       eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
   384    420       eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
   385    421       eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
   386    422   
   387    423       AC_SUBST(TCL_VERSION)
          424  +    AC_SUBST(TCL_PATCH_LEVEL)
   388    425       AC_SUBST(TCL_BIN_DIR)
   389    426       AC_SUBST(TCL_SRC_DIR)
   390    427   
   391    428       AC_SUBST(TCL_LIB_FILE)
   392    429       AC_SUBST(TCL_LIB_FLAG)
   393    430       AC_SUBST(TCL_LIB_SPEC)
   394    431   
   395    432       AC_SUBST(TCL_STUB_LIB_FILE)
   396    433       AC_SUBST(TCL_STUB_LIB_FLAG)
   397    434       AC_SUBST(TCL_STUB_LIB_SPEC)
   398    435   
          436  +    AC_MSG_CHECKING([platform])
          437  +    hold_cc=$CC; CC="$TCL_CC"
          438  +    AC_TRY_COMPILE(,[
          439  +	    #ifdef _WIN32
          440  +		#error win32
          441  +	    #endif
          442  +	], [
          443  +	    TEA_PLATFORM="unix"
          444  +	    CYGPATH=echo
          445  +	], [
          446  +	    TEA_PLATFORM="windows"
          447  +	    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)	]
          448  +    )
          449  +    CC=$hold_cc
          450  +    AC_MSG_RESULT($TEA_PLATFORM)
          451  +
          452  +    # The BUILD_$pkg is to define the correct extern storage class
          453  +    # handling when making this package
          454  +    AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
          455  +	    [Building extension source?])
          456  +    # Do this here as we have fully defined TEA_PLATFORM now
          457  +    if test "${TEA_PLATFORM}" = "windows" ; then
          458  +	EXEEXT=".exe"
          459  +	CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
          460  +    fi
          461  +
          462  +    # TEA specific:
          463  +    AC_SUBST(CLEANFILES)
   399    464       AC_SUBST(TCL_LIBS)
   400    465       AC_SUBST(TCL_DEFS)
   401    466       AC_SUBST(TCL_EXTRA_CFLAGS)
   402    467       AC_SUBST(TCL_LD_FLAGS)
   403    468       AC_SUBST(TCL_SHLIB_LD_LIBS)
   404    469   ])
   405    470   
   406    471   #------------------------------------------------------------------------
   407    472   # TEA_LOAD_TKCONFIG --
   408    473   #
   409    474   #	Load the tkConfig.sh file
   410    475   #
   411    476   # Arguments:
   412         -#	
          477  +#
   413    478   #	Requires the following vars to be set:
   414    479   #		TK_BIN_DIR
   415    480   #
   416    481   # Results:
   417    482   #
   418    483   #	Sets the following vars that should be in tkConfig.sh:
   419    484   #		TK_BIN_DIR
................................................................................
   436    501       # If the TK_BIN_DIR is the build directory (not the install directory),
   437    502       # then set the common variable name to the value of the build variables.
   438    503       # For example, the variable TK_LIB_SPEC will be set to the value
   439    504       # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
   440    505       # instead of TK_BUILD_LIB_SPEC since it will work with both an
   441    506       # installed and uninstalled version of Tcl.
   442    507       if test -f "${TK_BIN_DIR}/Makefile" ; then
   443         -        TK_LIB_SPEC=${TK_BUILD_LIB_SPEC}
   444         -        TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC}
   445         -        TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH}
          508  +        TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
          509  +        TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
          510  +        TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
   446    511       elif test "`uname -s`" = "Darwin"; then
   447    512   	# If Tk was built as a framework, attempt to use the libraries
   448    513   	# from the framework at the given location so that linking works
   449         -	# against Tk.framework installed in an arbitary location.
          514  +	# against Tk.framework installed in an arbitrary location.
   450    515   	case ${TK_DEFS} in
   451    516   	    *TK_FRAMEWORK*)
   452    517   		if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
   453         -		    for i in "`cd ${TK_BIN_DIR}; pwd`" \
   454         -			     "`cd ${TK_BIN_DIR}/../..; pwd`"; do
          518  +		    for i in "`cd "${TK_BIN_DIR}"; pwd`" \
          519  +			     "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
   455    520   			if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
   456         -			    TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}"
          521  +			    TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
   457    522   			    break
   458    523   			fi
   459    524   		    done
   460    525   		fi
   461    526   		if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
   462         -		    TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}"
          527  +		    TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
   463    528   		    TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
   464    529   		fi
   465    530   		;;
   466    531   	esac
   467    532       fi
   468    533   
   469    534       # eval is required to do the TK_DBGX substitution
   470    535       eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
   471    536       eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
   472    537       eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
   473    538       eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
   474    539   
   475         -    # Ensure windowingsystem is defined
          540  +    # TEA specific: Ensure windowingsystem is defined
   476    541       if test "${TEA_PLATFORM}" = "unix" ; then
   477    542   	case ${TK_DEFS} in
   478    543   	    *MAC_OSX_TK*)
   479    544   		AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
   480    545   		TEA_WINDOWINGSYSTEM="aqua"
   481    546   		;;
   482    547   	    *)
................................................................................
   495    560       AC_SUBST(TK_LIB_FLAG)
   496    561       AC_SUBST(TK_LIB_SPEC)
   497    562   
   498    563       AC_SUBST(TK_STUB_LIB_FILE)
   499    564       AC_SUBST(TK_STUB_LIB_FLAG)
   500    565       AC_SUBST(TK_STUB_LIB_SPEC)
   501    566   
          567  +    # TEA specific:
   502    568       AC_SUBST(TK_LIBS)
   503    569       AC_SUBST(TK_XINCLUDES)
   504    570   ])
          571  +
          572  +#------------------------------------------------------------------------
          573  +# TEA_PROG_TCLSH
          574  +#	Determine the fully qualified path name of the tclsh executable
          575  +#	in the Tcl build directory or the tclsh installed in a bin
          576  +#	directory. This macro will correctly determine the name
          577  +#	of the tclsh executable even if tclsh has not yet been
          578  +#	built in the build directory. The tclsh found is always
          579  +#	associated with a tclConfig.sh file. This tclsh should be used
          580  +#	only for running extension test cases. It should never be
          581  +#	or generation of files (like pkgIndex.tcl) at build time.
          582  +#
          583  +# Arguments:
          584  +#	none
          585  +#
          586  +# Results:
          587  +#	Substitutes the following vars:
          588  +#		TCLSH_PROG
          589  +#------------------------------------------------------------------------
          590  +
          591  +AC_DEFUN([TEA_PROG_TCLSH], [
          592  +    AC_MSG_CHECKING([for tclsh])
          593  +    if test -f "${TCL_BIN_DIR}/Makefile" ; then
          594  +        # tclConfig.sh is in Tcl build directory
          595  +        if test "${TEA_PLATFORM}" = "windows"; then
          596  +          if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" ; then
          597  +            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
          598  +          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}" ; then
          599  +            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}"
          600  +          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}" ; then
          601  +            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}"
          602  +          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}" ; then
          603  +            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}"
          604  +          fi
          605  +        else
          606  +            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
          607  +        fi
          608  +    else
          609  +        # tclConfig.sh is in install location
          610  +        if test "${TEA_PLATFORM}" = "windows"; then
          611  +            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
          612  +        else
          613  +            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
          614  +        fi
          615  +        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
          616  +              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
          617  +              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
          618  +        for i in $list ; do
          619  +            if test -f "$i/${TCLSH_PROG}" ; then
          620  +                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
          621  +                break
          622  +            fi
          623  +        done
          624  +        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
          625  +    fi
          626  +    AC_MSG_RESULT([${TCLSH_PROG}])
          627  +    AC_SUBST(TCLSH_PROG)
          628  +])
          629  +
          630  +#------------------------------------------------------------------------
          631  +# TEA_PROG_WISH
          632  +#	Determine the fully qualified path name of the wish executable
          633  +#	in the Tk build directory or the wish installed in a bin
          634  +#	directory. This macro will correctly determine the name
          635  +#	of the wish executable even if wish has not yet been
          636  +#	built in the build directory. The wish found is always
          637  +#	associated with a tkConfig.sh file. This wish should be used
          638  +#	only for running extension test cases. It should never be
          639  +#	or generation of files (like pkgIndex.tcl) at build time.
          640  +#
          641  +# Arguments:
          642  +#	none
          643  +#
          644  +# Results:
          645  +#	Substitutes the following vars:
          646  +#		WISH_PROG
          647  +#------------------------------------------------------------------------
          648  +
          649  +AC_DEFUN([TEA_PROG_WISH], [
          650  +    AC_MSG_CHECKING([for wish])
          651  +    if test -f "${TK_BIN_DIR}/Makefile" ; then
          652  +        # tkConfig.sh is in Tk build directory
          653  +        if test "${TEA_PLATFORM}" = "windows"; then
          654  +          if test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" ; then
          655  +            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
          656  +          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}s${EXEEXT}" ; then
          657  +            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}$s{EXEEXT}"
          658  +          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}" ; then
          659  +            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}"
          660  +          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}" ; then
          661  +            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}"
          662  +          fi
          663  +        else
          664  +            WISH_PROG="${TK_BIN_DIR}/wish"
          665  +        fi
          666  +    else
          667  +        # tkConfig.sh is in install location
          668  +        if test "${TEA_PLATFORM}" = "windows"; then
          669  +            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
          670  +        else
          671  +            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
          672  +        fi
          673  +        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
          674  +              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
          675  +              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
          676  +        for i in $list ; do
          677  +            if test -f "$i/${WISH_PROG}" ; then
          678  +                REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
          679  +                break
          680  +            fi
          681  +        done
          682  +        WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
          683  +    fi
          684  +    AC_MSG_RESULT([${WISH_PROG}])
          685  +    AC_SUBST(WISH_PROG)
          686  +])
   505    687   
   506    688   #------------------------------------------------------------------------
   507    689   # TEA_ENABLE_SHARED --
   508    690   #
   509    691   #	Allows the building of shared libraries
   510    692   #
   511    693   # Arguments:
   512    694   #	none
   513         -#	
          695  +#
   514    696   # Results:
   515    697   #
   516    698   #	Adds the following arguments to configure:
   517    699   #		--enable-shared=yes|no
          700  +#		--enable-stubs=yes|no
   518    701   #
   519    702   #	Defines the following vars:
   520    703   #		STATIC_BUILD	Used for building import/export libraries
   521    704   #				on Windows.
   522    705   #
   523    706   #	Sets the following vars:
   524    707   #		SHARED_BUILD	Value of 1 or 0
          708  +#               STUBS_BUILD     Value if 1 or 0
          709  +#               USE_TCL_STUBS   Value true: if SHARED_BUILD or --enable-stubs
          710  +#               USE_TCLOO_STUBS Value true: if SHARED_BUILD or --enable-stubs
          711  +#               USE_TK_STUBS    Value true: if SHARED_BUILD or --enable-stubs
          712  +#                                AND TEA_WINDOWING_SYSTEM != ""
   525    713   #------------------------------------------------------------------------
   526         -
   527    714   AC_DEFUN([TEA_ENABLE_SHARED], [
   528    715       AC_MSG_CHECKING([how to build libraries])
   529    716       AC_ARG_ENABLE(shared,
   530    717   	AC_HELP_STRING([--enable-shared],
   531    718   	    [build and link with shared libraries (default: on)]),
   532         -	[tcl_ok=$enableval], [tcl_ok=yes])
          719  +	[shared_ok=$enableval], [shared_ok=yes])
   533    720   
   534    721       if test "${enable_shared+set}" = set; then
   535    722   	enableval="$enable_shared"
   536         -	tcl_ok=$enableval
          723  +	shared_ok=$enableval
   537    724       else
   538         -	tcl_ok=yes
          725  +	shared_ok=yes
   539    726       fi
   540    727   
   541         -    if test "$tcl_ok" = "yes" ; then
          728  +    AC_ARG_ENABLE(stubs,
          729  +	AC_HELP_STRING([--enable-stubs],
          730  +	    [build and link with stub libraries. Always true for shared builds (default: on)]),
          731  +	[stubs_ok=$enableval], [stubs_ok=yes])
          732  +
          733  +    if test "${enable_stubs+set}" = set; then
          734  +	enableval="$enable_stubs"
          735  +	stubs_ok=$enableval
          736  +    else
          737  +	stubs_ok=yes
          738  +    fi
          739  +
          740  +    # Stubs are always enabled for shared builds
          741  +    if test "$shared_ok" = "yes" ; then
   542    742   	AC_MSG_RESULT([shared])
   543    743   	SHARED_BUILD=1
          744  +        STUBS_BUILD=1
   544    745       else
   545    746   	AC_MSG_RESULT([static])
   546    747   	SHARED_BUILD=0
   547         -	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
          748  +	AC_DEFINE(STATIC_BUILD, 1, [This a static build])
          749  +        if test "$stubs_ok" = "yes" ; then
          750  +          STUBS_BUILD=1
          751  +        else
          752  +          STUBS_BUILD=0
          753  +        fi
   548    754       fi
          755  +    if test "${STUBS_BUILD}" = "1" ; then
          756  +      AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
          757  +      AC_DEFINE(USE_TCLOO_STUBS, 1, [Use TclOO stubs])
          758  +      if test "${TEA_WINDOWINGSYSTEM}" != ""; then
          759  +        AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
          760  +      fi
          761  +    fi
          762  +
   549    763       AC_SUBST(SHARED_BUILD)
          764  +    AC_SUBST(STUBS_BUILD)
   550    765   ])
   551    766   
   552    767   #------------------------------------------------------------------------
   553    768   # TEA_ENABLE_THREADS --
   554    769   #
   555    770   #	Specify if thread support should be enabled.  If "yes" is specified
   556    771   #	as an arg (optional), threads are enabled by default, "no" means
................................................................................
   562    777   #
   563    778   #	Note that it is legal to have a thread enabled extension run in a
   564    779   #	threaded or non-threaded Tcl core, but a non-threaded extension may
   565    780   #	only run in a non-threaded Tcl core.
   566    781   #
   567    782   # Arguments:
   568    783   #	none
   569         -#	
          784  +#
   570    785   # Results:
   571    786   #
   572    787   #	Adds the following arguments to configure:
   573    788   #		--enable-threads
   574    789   #
   575    790   #	Sets the following vars:
   576    791   #		THREADS_LIBS	Thread library(s)
   577    792   #
   578    793   #	Defines the following vars:
   579    794   #		TCL_THREADS
   580    795   #		_REENTRANT
   581    796   #		_THREAD_SAFE
   582         -#
   583    797   #------------------------------------------------------------------------
   584    798   
   585    799   AC_DEFUN([TEA_ENABLE_THREADS], [
   586    800       AC_ARG_ENABLE(threads,
   587    801   	AC_HELP_STRING([--enable-threads],
   588         -	    [build with threads]),
          802  +	    [build with threads (default: on)]),
   589    803   	[tcl_ok=$enableval], [tcl_ok=yes])
   590    804   
   591    805       if test "${enable_threads+set}" = set; then
   592    806   	enableval="$enable_threads"
   593    807   	tcl_ok=$enableval
   594    808       else
   595    809   	tcl_ok=yes
................................................................................
   596    810       fi
   597    811   
   598    812       if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
   599    813   	TCL_THREADS=1
   600    814   
   601    815   	if test "${TEA_PLATFORM}" != "windows" ; then
   602    816   	    # We are always OK on Windows, so check what this platform wants:
   603         -    
          817  +
   604    818   	    # USE_THREAD_ALLOC tells us to try the special thread-based
   605    819   	    # allocator that significantly reduces lock contention
   606    820   	    AC_DEFINE(USE_THREAD_ALLOC, 1,
   607    821   		[Do we want to use the threaded memory allocator?])
   608    822   	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
   609    823   	    if test "`uname -s`" = "SunOS" ; then
   610    824   		AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
................................................................................
   685    899   # TEA_ENABLE_SYMBOLS --
   686    900   #
   687    901   #	Specify if debugging symbols should be used.
   688    902   #	Memory (TCL_MEM_DEBUG) debugging can also be enabled.
   689    903   #
   690    904   # Arguments:
   691    905   #	none
   692         -#	
          906  +#
   693    907   #	TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
   694    908   #	the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
   695    909   #	Requires the following vars to be set in the Makefile:
   696    910   #		CFLAGS_DEFAULT
   697    911   #		LDFLAGS_DEFAULT
   698         -#	
          912  +#
   699    913   # Results:
   700    914   #
   701    915   #	Adds the following arguments to configure:
   702    916   #		--enable-symbols
   703    917   #
   704    918   #	Defines the following vars:
   705    919   #		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
   706         -#				Sets to $(CFLAGS_OPTIMIZE) if false
          920  +#				Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
   707    921   #		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
   708    922   #				Sets to $(LDFLAGS_OPTIMIZE) if false
   709    923   #		DBGX		Formerly used as debug library extension;
   710    924   #				always blank now.
   711         -#
   712    925   #------------------------------------------------------------------------
   713    926   
   714    927   AC_DEFUN([TEA_ENABLE_SYMBOLS], [
   715         -    dnl Make sure we are initialized
          928  +    dnl TEA specific: Make sure we are initialized
   716    929       AC_REQUIRE([TEA_CONFIG_CFLAGS])
   717    930       AC_MSG_CHECKING([for build with symbols])
   718    931       AC_ARG_ENABLE(symbols,
   719    932   	AC_HELP_STRING([--enable-symbols],
   720    933   	    [build with debugging symbols (default: off)]),
   721    934   	[tcl_ok=$enableval], [tcl_ok=no])
   722    935       DBGX=""
   723    936       if test "$tcl_ok" = "no"; then
   724         -	CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
          937  +	CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
   725    938   	LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
   726    939   	AC_MSG_RESULT([no])
   727    940       else
   728    941   	CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
   729    942   	LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
   730    943   	if test "$tcl_ok" = "yes"; then
   731    944   	    AC_MSG_RESULT([yes (standard debugging)])
   732    945   	fi
   733    946       fi
          947  +    # TEA specific:
   734    948       if test "${TEA_PLATFORM}" != "windows" ; then
   735    949   	LDFLAGS_DEFAULT="${LDFLAGS}"
   736    950       fi
   737         -
   738         -    AC_SUBST(TCL_DBGX)
   739    951       AC_SUBST(CFLAGS_DEFAULT)
   740    952       AC_SUBST(LDFLAGS_DEFAULT)
          953  +    AC_SUBST(TCL_DBGX)
   741    954   
   742    955       if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
   743    956   	AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
   744    957       fi
   745    958   
   746    959       if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
   747    960   	if test "$tcl_ok" = "all"; then
................................................................................
   756    969   # TEA_ENABLE_LANGINFO --
   757    970   #
   758    971   #	Allows use of modern nl_langinfo check for better l10n.
   759    972   #	This is only relevant for Unix.
   760    973   #
   761    974   # Arguments:
   762    975   #	none
   763         -#	
          976  +#
   764    977   # Results:
   765    978   #
   766    979   #	Adds the following arguments to configure:
   767    980   #		--enable-langinfo=yes|no (default is yes)
   768    981   #
   769    982   #	Defines the following vars:
   770    983   #		HAVE_LANGINFO	Triggers use of nl_langinfo if defined.
   771         -#
   772    984   #------------------------------------------------------------------------
   773    985   
   774    986   AC_DEFUN([TEA_ENABLE_LANGINFO], [
   775    987       AC_ARG_ENABLE(langinfo,
   776    988   	AC_HELP_STRING([--enable-langinfo],
   777    989   	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
   778    990   	[langinfo_ok=$enableval], [langinfo_ok=yes])
................................................................................
   786    998   	AC_CACHE_VAL(tcl_cv_langinfo_h, [
   787    999   	    AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
   788   1000   		    [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
   789   1001   	AC_MSG_RESULT([$tcl_cv_langinfo_h])
   790   1002   	if test $tcl_cv_langinfo_h = yes; then
   791   1003   	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
   792   1004   	fi
   793         -    else 
         1005  +    else
   794   1006   	AC_MSG_RESULT([$langinfo_ok])
   795   1007       fi
   796   1008   ])
   797   1009   
   798   1010   #--------------------------------------------------------------------
   799   1011   # TEA_CONFIG_SYSTEM
   800   1012   #
   801   1013   #	Determine what the system is (some things cannot be easily checked
   802   1014   #	on a feature-driven basis, alas). This can usually be done via the
   803         -#	"uname" command, but there are a few systems, like Next, where
   804         -#	this doesn't work.
         1015  +#	"uname" command.
   805   1016   #
   806   1017   # Arguments:
   807   1018   #	none
   808   1019   #
   809   1020   # Results:
   810   1021   #	Defines the following var:
   811   1022   #
   812   1023   #	system -	System/platform/version identification code.
   813         -#
   814   1024   #--------------------------------------------------------------------
   815   1025   
   816   1026   AC_DEFUN([TEA_CONFIG_SYSTEM], [
   817   1027       AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
         1028  +	# TEA specific:
   818   1029   	if test "${TEA_PLATFORM}" = "windows" ; then
   819   1030   	    tcl_cv_sys_version=windows
   820         -	elif test -f /usr/lib/NextStep/software_version; then
   821         -	    tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
   822   1031   	else
   823   1032   	    tcl_cv_sys_version=`uname -s`-`uname -r`
   824   1033   	    if test "$?" -ne 0 ; then
   825   1034   		AC_MSG_WARN([can't find uname command])
   826   1035   		tcl_cv_sys_version=unknown
   827   1036   	    else
   828         -		# Special check for weird MP-RAS system (uname returns weird
   829         -		# results, and the version is kept in special file).
   830         -
   831         -		if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
   832         -		    tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
   833         -		fi
   834   1037   		if test "`uname -s`" = "AIX" ; then
   835   1038   		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
   836   1039   		fi
   837   1040   	    fi
   838   1041   	fi
   839   1042       ])
   840   1043       system=$tcl_cv_sys_version
................................................................................
   849   1052   # Arguments:
   850   1053   #	none
   851   1054   #
   852   1055   # Results:
   853   1056   #
   854   1057   #	Defines and substitutes the following vars:
   855   1058   #
   856         -#       DL_OBJS -       Name of the object file that implements dynamic
   857         -#                       loading for Tcl on this system.
   858         -#       DL_LIBS -       Library file(s) to include in tclsh and other base
   859         -#                       applications in order for the "load" command to work.
         1059  +#	DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
   860   1060   #       LDFLAGS -      Flags to pass to the compiler when linking object
   861   1061   #                       files into an executable application binary such
   862   1062   #                       as tclsh.
   863   1063   #       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
   864   1064   #                       that tell the run-time dynamic linker where to look
   865   1065   #                       for shared libraries such as libtcl.so.  Depends on
   866   1066   #                       the variable LIB_RUNTIME_DIR in the Makefile. Could
................................................................................
   873   1073   #                       of a shared library (may request position-independent
   874   1074   #                       code, among other things).
   875   1075   #       SHLIB_LD -      Base command to use for combining object files
   876   1076   #                       into a shared library.
   877   1077   #       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
   878   1078   #                       creating shared libraries.  This symbol typically
   879   1079   #                       goes at the end of the "ld" commands that build
   880         -#                       shared libraries. The value of the symbol is
         1080  +#                       shared libraries. The value of the symbol defaults to
   881   1081   #                       "${LIBS}" if all of the dependent libraries should
   882   1082   #                       be specified when creating a shared library.  If
   883   1083   #                       dependent libraries should not be specified (as on
   884   1084   #                       SunOS 4.x, where they cause the link to fail, or in
   885   1085   #                       general if Tcl and Tk aren't themselves shared
   886   1086   #                       libraries), then this symbol has an empty string
   887   1087   #                       as its value.
   888   1088   #       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
   889   1089   #                       extensions.  An empty string means we don't know how
   890   1090   #                       to use shared libraries on this platform.
   891   1091   #       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
   892         -#                       in a static or shared library name, using the $VERSION variable
         1092  +#                       in a static or shared library name, using the $PACKAGE_VERSION variable
   893   1093   #                       to put the version in the right place.  This is used
   894   1094   #                       by platforms that need non-standard library names.
   895         -#                       Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
   896         -#                       to have a version after the .so, and ${VERSION}.a
         1095  +#                       Examples:  ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
         1096  +#                       to have a version after the .so, and ${PACKAGE_VERSION}.a
   897   1097   #                       on AIX, since a shared library needs to have
   898   1098   #                       a .a extension whereas shared objects for loadable
   899   1099   #                       extensions have a .so extension.  Defaults to
   900         -#                       ${VERSION}${SHLIB_SUFFIX}.
   901         -#       TCL_NEEDS_EXP_FILE -
   902         -#                       1 means that an export file is needed to link to a
   903         -#                       shared library.
   904         -#       TCL_EXP_FILE -  The name of the installed export / import file which
   905         -#                       should be used to link to the Tcl shared library.
   906         -#                       Empty if Tcl is unshared.
   907         -#       TCL_BUILD_EXP_FILE -
   908         -#                       The name of the built export / import file which
   909         -#                       should be used to link to the Tcl shared library.
   910         -#                       Empty if Tcl is unshared.
         1100  +#                       ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
   911   1101   #	CFLAGS_DEBUG -
   912   1102   #			Flags used when running the compiler in debug mode
   913   1103   #	CFLAGS_OPTIMIZE -
   914   1104   #			Flags used when running the compiler in optimize mode
   915   1105   #	CFLAGS -	Additional CFLAGS added as necessary (usually 64-bit)
   916         -#
   917   1106   #--------------------------------------------------------------------
   918   1107   
   919   1108   AC_DEFUN([TEA_CONFIG_CFLAGS], [
   920         -    dnl Make sure we are initialized
         1109  +    dnl TEA specific: Make sure we are initialized
   921   1110       AC_REQUIRE([TEA_INIT])
   922   1111   
   923   1112       # Step 0.a: Enable 64 bit support?
   924   1113   
   925   1114       AC_MSG_CHECKING([if 64bit support is requested])
   926   1115       AC_ARG_ENABLE(64bit,
   927   1116   	AC_HELP_STRING([--enable-64bit],
................................................................................
   933   1122   
   934   1123       AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
   935   1124       AC_ARG_ENABLE(64bit-vis,
   936   1125   	AC_HELP_STRING([--enable-64bit-vis],
   937   1126   	    [enable 64bit Sparc VIS support (default: off)]),
   938   1127   	[do64bitVIS=$enableval], [do64bitVIS=no])
   939   1128       AC_MSG_RESULT([$do64bitVIS])
         1129  +    # Force 64bit on with VIS
         1130  +    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
   940   1131   
   941         -    if test "$do64bitVIS" = "yes"; then
   942         -	# Force 64bit on with VIS
   943         -	do64bit=yes
   944         -    fi
         1132  +    # Step 0.c: Check if visibility support is available. Do this here so
         1133  +    # that platform specific alternatives can be used below if this fails.
   945   1134   
   946         -    # Step 0.c: Cross-compiling options for Windows/CE builds?
         1135  +    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
         1136  +	tcl_cv_cc_visibility_hidden, [
         1137  +	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
         1138  +	AC_TRY_LINK([
         1139  +	    extern __attribute__((__visibility__("hidden"))) void f(void);
         1140  +	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
         1141  +	    tcl_cv_cc_visibility_hidden=no)
         1142  +	CFLAGS=$hold_cflags])
         1143  +    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
         1144  +	AC_DEFINE(MODULE_SCOPE,
         1145  +	    [extern __attribute__((__visibility__("hidden")))],
         1146  +	    [Compiler support for module scope symbols])
         1147  +	AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
         1148  +    ])
   947   1149   
   948         -    if test "${TEA_PLATFORM}" = "windows" ; then
         1150  +    # Step 0.d: Disable -rpath support?
         1151  +
         1152  +    AC_MSG_CHECKING([if rpath support is requested])
         1153  +    AC_ARG_ENABLE(rpath,
         1154  +	AC_HELP_STRING([--disable-rpath],
         1155  +	    [disable rpath support (default: on)]),
         1156  +	[doRpath=$enableval], [doRpath=yes])
         1157  +    AC_MSG_RESULT([$doRpath])
         1158  +
         1159  +    # TEA specific: Cross-compiling options for Windows/CE builds?
         1160  +
         1161  +    AS_IF([test "${TEA_PLATFORM}" = windows], [
   949   1162   	AC_MSG_CHECKING([if Windows/CE build is requested])
   950         -	AC_ARG_ENABLE(wince,[  --enable-wince          enable Win/CE support (where applicable)], [doWince=$enableval], [doWince=no])
         1163  +	AC_ARG_ENABLE(wince,
         1164  +	    AC_HELP_STRING([--enable-wince],
         1165  +		[enable Win/CE support (where applicable)]),
         1166  +	    [doWince=$enableval], [doWince=no])
   951   1167   	AC_MSG_RESULT([$doWince])
   952         -    fi
         1168  +    ])
   953   1169   
   954         -    # Step 1: set the variable "system" to hold the name and version number
         1170  +    # Set the variable "system" to hold the name and version number
   955   1171       # for the system.
   956   1172   
   957   1173       TEA_CONFIG_SYSTEM
   958   1174   
   959         -    # Step 2: check for existence of -ldl library.  This is needed because
   960         -    # Linux can use either -ldl or -ldld for dynamic loading.
   961         -
   962         -    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
   963         -
   964   1175       # Require ranlib early so we can override it in special cases below.
   965   1176   
   966   1177       AC_REQUIRE([AC_PROG_RANLIB])
   967   1178   
   968         -    # Step 3: set configuration options based on system name and version.
         1179  +    # Set configuration options based on system name and version.
   969   1180       # This is similar to Tcl's unix/tcl.m4 except that we've added a
   970         -    # "windows" case.
         1181  +    # "windows" case and removed some core-only vars.
   971   1182   
   972   1183       do64bit_ok=no
   973         -    LDFLAGS_ORIG="$LDFLAGS"
         1184  +    # default to '{$LIBS}' and set to "" on per-platform necessary basis
         1185  +    SHLIB_LD_LIBS='${LIBS}'
   974   1186       # When ld needs options to work in 64-bit mode, put them in
   975   1187       # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
   976   1188       # is disabled by the user. [Bug 1016796]
   977   1189       LDFLAGS_ARCH=""
   978         -    TCL_EXPORT_FILE_SUFFIX=""
   979   1190       UNSHARED_LIB_SUFFIX=""
         1191  +    # TEA specific: use PACKAGE_VERSION instead of VERSION
   980   1192       TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
   981   1193       ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
   982   1194       TCL_LIB_VERSIONS_OK=ok
   983   1195       CFLAGS_DEBUG=-g
   984         -    CFLAGS_OPTIMIZE=-O
   985         -    if test "$GCC" = "yes" ; then
         1196  +    AS_IF([test "$GCC" = yes], [
   986   1197   	CFLAGS_OPTIMIZE=-O2
   987         -	CFLAGS_WARNING="-Wall -Wno-implicit-int"
   988         -    else
         1198  +	CFLAGS_WARNING="-Wall"
         1199  +    ], [
         1200  +	CFLAGS_OPTIMIZE=-O
   989   1201   	CFLAGS_WARNING=""
   990         -    fi
   991         -    TCL_NEEDS_EXP_FILE=0
   992         -    TCL_BUILD_EXP_FILE=""
   993         -    TCL_EXP_FILE=""
   994         -dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.
   995         -dnl AC_CHECK_TOOL(AR, ar)
   996         -    AC_CHECK_PROG(AR, ar, ar)
         1202  +    ])
         1203  +    AC_CHECK_TOOL(AR, ar)
   997   1204       STLIB_LD='${AR} cr'
   998   1205       LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
         1206  +    AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
   999   1207       case $system in
         1208  +	# TEA specific:
  1000   1209   	windows)
  1001   1210   	    # This is a 2-stage check to make sure we have the 64-bit SDK
  1002   1211   	    # We have to know where the SDK is installed.
  1003   1212   	    # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
  1004   1213   	    # MACHINE is IX86 for LINK, but this is used by the manifest,
  1005   1214   	    # which requires x86|amd64|ia64.
  1006   1215   	    MACHINE="X86"
................................................................................
  1016   1225   			PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
  1017   1226   			;;
  1018   1227   		    ia64)
  1019   1228   			MACHINE="IA64"
  1020   1229   			PATH64="${MSSDK}/Bin/Win64"
  1021   1230   			;;
  1022   1231   		esac
  1023         -		if test ! -d "${PATH64}" ; then
         1232  +		if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then
  1024   1233   		    AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
  1025   1234   		    AC_MSG_WARN([Ensure latest Platform SDK is installed])
  1026   1235   		    do64bit="no"
  1027   1236   		else
  1028   1237   		    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
  1029   1238   		    do64bit_ok="yes"
  1030   1239   		fi
................................................................................
  1091   1300   
  1092   1301   	    if test "$GCC" != "yes" ; then
  1093   1302   	        if test "${SHARED_BUILD}" = "0" ; then
  1094   1303   		    runtime=-MT
  1095   1304   	        else
  1096   1305   		    runtime=-MD
  1097   1306   	        fi
         1307  +	        case "x`echo \${VisualStudioVersion}`" in
         1308  +	            x1[[4-9]]*)
         1309  +		        lflags="${lflags} -nodefaultlib:libucrt.lib"
         1310  +		        TEA_ADD_LIBS([ucrt.lib])
         1311  +	            ;;
         1312  +	            *)
         1313  +	            ;;
         1314  +	        esac
  1098   1315   
  1099   1316                   if test "$do64bit" != "no" ; then
  1100   1317   		    # All this magic is necessary for the Win64 SDK RC1 - hobbs
  1101   1318   		    CC="\"${PATH64}/cl.exe\""
  1102   1319   		    CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
  1103   1320   		    RC="\"${MSSDK}/bin/rc.exe\""
  1104         -		    lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
         1321  +		    lflags="${lflags} -nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
  1105   1322   		    LINKBIN="\"${PATH64}/link.exe\""
  1106   1323   		    CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
  1107   1324   		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
  1108   1325   		    # Avoid 'unresolved external symbol __security_cookie'
  1109   1326   		    # errors, c.f. http://support.microsoft.com/?id=894573
  1110   1327   		    TEA_ADD_LIBS([bufferoverflowU.lib])
  1111   1328   		elif test "$doWince" != "no" ; then
................................................................................
  1127   1344   			AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
  1128   1345   		    done
  1129   1346   		    AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
  1130   1347   		    AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
  1131   1348   		    CFLAGS_DEBUG="-nologo -Zi -Od"
  1132   1349   		    CFLAGS_OPTIMIZE="-nologo -Ox"
  1133   1350   		    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
  1134         -		    lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
         1351  +		    lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
  1135   1352   		    LINKBIN="\"${CEBINROOT}/link.exe\""
  1136   1353   		    AC_SUBST(CELIB_DIR)
  1137   1354   		else
  1138   1355   		    RC="rc"
  1139         -		    lflags="-nologo"
  1140         -    		    LINKBIN="link"
         1356  +		    lflags="${lflags} -nologo"
         1357  +		    LINKBIN="link"
  1141   1358   		    CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
  1142   1359   		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
  1143   1360   		fi
  1144   1361   	    fi
  1145   1362   
  1146   1363   	    if test "$GCC" = "yes"; then
  1147   1364   		# mingw gcc mode
  1148         -		RC="windres"
         1365  +		AC_CHECK_TOOL(RC, windres)
  1149   1366   		CFLAGS_DEBUG="-g"
  1150   1367   		CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
  1151         -		SHLIB_LD="$CC -shared"
         1368  +		SHLIB_LD='${CC} -shared'
  1152   1369   		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
  1153   1370   		LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
  1154   1371   		LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
         1372  +
         1373  +		AC_CACHE_CHECK(for cross-compile version of gcc,
         1374  +			ac_cv_cross,
         1375  +			AC_TRY_COMPILE([
         1376  +			    #ifdef _WIN32
         1377  +				#error cross-compiler
         1378  +			    #endif
         1379  +			], [],
         1380  +			ac_cv_cross=yes,
         1381  +			ac_cv_cross=no)
         1382  +		      )
         1383  +		      if test "$ac_cv_cross" = "yes"; then
         1384  +			case "$do64bit" in
         1385  +			    amd64|x64|yes)
         1386  +				CC="x86_64-w64-mingw32-gcc"
         1387  +				LD="x86_64-w64-mingw32-ld"
         1388  +				AR="x86_64-w64-mingw32-ar"
         1389  +				RANLIB="x86_64-w64-mingw32-ranlib"
         1390  +				RC="x86_64-w64-mingw32-windres"
         1391  +			    ;;
         1392  +			    *)
         1393  +				CC="i686-w64-mingw32-gcc"
         1394  +				LD="i686-w64-mingw32-ld"
         1395  +				AR="i686-w64-mingw32-ar"
         1396  +				RANLIB="i686-w64-mingw32-ranlib"
         1397  +				RC="i686-w64-mingw32-windres"
         1398  +			    ;;
         1399  +			esac
         1400  +		fi
         1401  +
  1155   1402   	    else
  1156   1403   		SHLIB_LD="${LINKBIN} -dll ${lflags}"
  1157   1404   		# link -lib only works when -lib is the first arg
  1158   1405   		STLIB_LD="${LINKBIN} -lib ${lflags}"
  1159   1406   		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
  1160   1407   		PATHTYPE=-w
  1161   1408   		# For information on what debugtype is most useful, see:
  1162   1409   		# http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
         1410  +		# and also
         1411  +		# http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
  1163   1412   		# This essentially turns it all on.
  1164         -		LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
         1413  +		LDFLAGS_DEBUG="-debug -debugtype:cv"
  1165   1414   		LDFLAGS_OPTIMIZE="-release"
  1166   1415   		if test "$doWince" != "no" ; then
  1167   1416   		    LDFLAGS_CONSOLE="-link ${lflags}"
  1168   1417   		    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
  1169   1418   		else
  1170   1419   		    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
  1171   1420   		    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
  1172   1421   		fi
  1173   1422   	    fi
  1174   1423   
  1175         -	    SHLIB_LD_LIBS='${LIBS}'
  1176   1424   	    SHLIB_SUFFIX=".dll"
  1177   1425   	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
  1178   1426   
  1179   1427   	    TCL_LIB_VERSIONS_OK=nodots
  1180         -	    # Bogus to avoid getting this turned off
  1181         -	    DL_OBJS="tclLoadNone.obj"
  1182   1428       	    ;;
  1183   1429   	AIX-*)
  1184         -	    if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
         1430  +	    AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
  1185   1431   		# AIX requires the _r compiler when gcc isn't being used
  1186   1432   		case "${CC}" in
  1187         -		    *_r)
         1433  +		    *_r|*_r\ *)
  1188   1434   			# ok ...
  1189   1435   			;;
  1190   1436   		    *)
  1191         -			CC=${CC}_r
         1437  +			# Make sure only first arg gets _r
         1438  +		    	CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
  1192   1439   			;;
  1193   1440   		esac
  1194   1441   		AC_MSG_RESULT([Using $CC for compiling with threads])
  1195         -	    fi
         1442  +	    ])
  1196   1443   	    LIBS="$LIBS -lc"
  1197   1444   	    SHLIB_CFLAGS=""
  1198         -	    SHLIB_LD_LIBS='${LIBS}'
  1199   1445   	    SHLIB_SUFFIX=".so"
  1200   1446   
  1201         -	    DL_OBJS="tclLoadDl.o"
  1202   1447   	    LD_LIBRARY_PATH_VAR="LIBPATH"
  1203   1448   
  1204         -	    # Check to enable 64-bit flags for compiler/linker on AIX 4+
  1205         -	    if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then
  1206         -		if test "$GCC" = "yes" ; then
         1449  +	    # Check to enable 64-bit flags for compiler/linker
         1450  +	    AS_IF([test "$do64bit" = yes], [
         1451  +		AS_IF([test "$GCC" = yes], [
  1207   1452   		    AC_MSG_WARN([64bit mode not supported with GCC on $system])
  1208         -		else 
         1453  +		], [
  1209   1454   		    do64bit_ok=yes
  1210   1455   		    CFLAGS="$CFLAGS -q64"
  1211   1456   		    LDFLAGS_ARCH="-q64"
  1212   1457   		    RANLIB="${RANLIB} -X64"
  1213   1458   		    AR="${AR} -X64"
  1214   1459   		    SHLIB_LD_FLAGS="-b64"
  1215         -		fi
  1216         -	    fi
         1460  +		])
         1461  +	    ])
  1217   1462   
  1218         -	    if test "`uname -m`" = "ia64" ; then
         1463  +	    AS_IF([test "`uname -m`" = ia64], [
  1219   1464   		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
  1220   1465   		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
  1221         -		# AIX-5 has dl* in libc.so
  1222         -		DL_LIBS=""
  1223         -		if test "$GCC" = "yes" ; then
         1466  +		AS_IF([test "$GCC" = yes], [
  1224   1467   		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
  1225         -		else
         1468  +		], [
  1226   1469   		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
  1227         -		fi
         1470  +		])
  1228   1471   		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
  1229         -	    else
  1230         -		if test "$GCC" = "yes" ; then
  1231         -		    SHLIB_LD="gcc -shared"
  1232         -		else
  1233         -		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
  1234         -		fi
  1235         -		SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
  1236         -		DL_LIBS="-ldl"
         1472  +	    ], [
         1473  +		AS_IF([test "$GCC" = yes], [
         1474  +		    SHLIB_LD='${CC} -shared -Wl,-bexpall'
         1475  +		], [
         1476  +		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
         1477  +		    LDFLAGS="$LDFLAGS -brtl"
         1478  +		])
         1479  +		SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
  1237   1480   		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
  1238   1481   		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
  1239         -		TCL_NEEDS_EXP_FILE=1
  1240         -		TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
  1241         -	    fi
  1242         -
  1243         -	    # AIX v<=4.1 has some different flags than 4.2+
  1244         -	    if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
  1245         -		AC_LIBOBJ([tclLoadAix])
  1246         -		DL_LIBS="-lld"
  1247         -	    fi
  1248         -
  1249         -	    # On AIX <=v4 systems, libbsd.a has to be linked in to support
  1250         -	    # non-blocking file IO.  This library has to be linked in after
  1251         -	    # the MATH_LIBS or it breaks the pow() function.  The way to
  1252         -	    # insure proper sequencing, is to add it to the tail of MATH_LIBS.
  1253         -	    # This library also supplies gettimeofday.
  1254         -	    #
  1255         -	    # AIX does not have a timezone field in struct tm. When the AIX
  1256         -	    # bsd library is used, the timezone global and the gettimeofday
  1257         -	    # methods are to be avoided for timezone deduction instead, we
  1258         -	    # deduce the timezone by comparing the localtime result on a
  1259         -	    # known GMT value.
  1260         -
  1261         -	    AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no)
  1262         -	    if test $libbsd = yes; then
  1263         -	    	MATH_LIBS="$MATH_LIBS -lbsd"
  1264         -	    	AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?])
  1265         -	    fi
         1482  +	    ])
  1266   1483   	    ;;
  1267   1484   	BeOS*)
  1268   1485   	    SHLIB_CFLAGS="-fPIC"
  1269         -	    SHLIB_LD="${CC} -nostart"
  1270         -	    SHLIB_LD_LIBS='${LIBS}'
         1486  +	    SHLIB_LD='${CC} -nostart'
  1271   1487   	    SHLIB_SUFFIX=".so"
  1272         -	    DL_OBJS="tclLoadDl.o"
  1273         -	    DL_LIBS="-ldl"
  1274   1488   
  1275   1489   	    #-----------------------------------------------------------
  1276   1490   	    # Check for inet_ntoa in -lbind, for BeOS (which also needs
  1277   1491   	    # -lsocket, even if the network functions are in -lnet which
  1278   1492   	    # is always linked to, for compatibility.
  1279   1493   	    #-----------------------------------------------------------
  1280   1494   	    AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
  1281   1495   	    ;;
  1282         -	BSD/OS-2.1*|BSD/OS-3*)
  1283         -	    SHLIB_CFLAGS=""
  1284         -	    SHLIB_LD="shlicc -r"
  1285         -	    SHLIB_LD_LIBS='${LIBS}'
  1286         -	    SHLIB_SUFFIX=".so"
  1287         -	    DL_OBJS="tclLoadDl.o"
  1288         -	    DL_LIBS="-ldl"
  1289         -	    CC_SEARCH_FLAGS=""
  1290         -	    LD_SEARCH_FLAGS=""
  1291         -	    ;;
  1292   1496   	BSD/OS-4.*)
  1293   1497   	    SHLIB_CFLAGS="-export-dynamic -fPIC"
  1294         -	    SHLIB_LD="cc -shared"
  1295         -	    SHLIB_LD_LIBS='${LIBS}'
         1498  +	    SHLIB_LD='${CC} -shared'
  1296   1499   	    SHLIB_SUFFIX=".so"
  1297         -	    DL_OBJS="tclLoadDl.o"
  1298         -	    DL_LIBS="-ldl"
  1299   1500   	    LDFLAGS="$LDFLAGS -export-dynamic"
  1300   1501   	    CC_SEARCH_FLAGS=""
  1301   1502   	    LD_SEARCH_FLAGS=""
  1302   1503   	    ;;
  1303         -	dgux*)
  1304         -	    SHLIB_CFLAGS="-K PIC"
  1305         -	    SHLIB_LD="cc -G"
  1306         -	    SHLIB_LD_LIBS=""
  1307         -	    SHLIB_SUFFIX=".so"
  1308         -	    DL_OBJS="tclLoadDl.o"
  1309         -	    DL_LIBS="-ldl"
         1504  +	CYGWIN_*)
         1505  +	    SHLIB_CFLAGS=""
         1506  +	    SHLIB_LD='${CC} -shared'
         1507  +	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$[@].a"
         1508  +	    SHLIB_SUFFIX=".dll"
         1509  +	    EXEEXT=".exe"
         1510  +	    do64bit_ok=yes
  1310   1511   	    CC_SEARCH_FLAGS=""
  1311   1512   	    LD_SEARCH_FLAGS=""
  1312   1513   	    ;;
         1514  +	Haiku*)
         1515  +	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
         1516  +	    SHLIB_CFLAGS="-fPIC"
         1517  +	    SHLIB_SUFFIX=".so"
         1518  +	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
         1519  +	    AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
         1520  +	    ;;
  1313   1521   	HP-UX-*.11.*)
  1314   1522   	    # Use updated header definitions where possible
  1315   1523   	    AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
  1316         -	    # Needed by Tcl, but not most extensions
         1524  +	    # TEA specific: Needed by Tcl, but not most extensions
  1317   1525   	    #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
  1318   1526   	    #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
  1319   1527   
  1320         -	    if test "`uname -m`" = "ia64" ; then
         1528  +	    AS_IF([test "`uname -m`" = ia64], [
  1321   1529   		SHLIB_SUFFIX=".so"
  1322         -	    else
         1530  +		# Use newer C++ library for C++ extensions
         1531  +		#if test "$GCC" != "yes" ; then
         1532  +		#   CPPFLAGS="-AA"
         1533  +		#fi
         1534  +	    ], [
  1323   1535   		SHLIB_SUFFIX=".sl"
  1324         -	    fi
         1536  +	    ])
  1325   1537   	    AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
  1326         -	    if test "$tcl_ok" = yes; then
  1327         -		SHLIB_CFLAGS="+z"
  1328         -		SHLIB_LD="ld -b"
  1329         -		SHLIB_LD_LIBS='${LIBS}'
  1330         -		DL_OBJS="tclLoadShl.o"
  1331         -		DL_LIBS="-ldld"
         1538  +	    AS_IF([test "$tcl_ok" = yes], [
  1332   1539   		LDFLAGS="$LDFLAGS -Wl,-E"
  1333   1540   		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
  1334   1541   		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
  1335   1542   		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
  1336         -	    fi
  1337         -	    if test "$GCC" = "yes" ; then
  1338         -		SHLIB_LD="gcc -shared"
  1339         -		SHLIB_LD_LIBS='${LIBS}'
         1543  +	    ])
         1544  +	    AS_IF([test "$GCC" = yes], [
         1545  +		SHLIB_LD='${CC} -shared'
  1340   1546   		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
  1341         -	    fi
  1342         -
  1343         -	    # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
  1344         -	    #CFLAGS="$CFLAGS +DAportable"
         1547  +	    ], [
         1548  +		CFLAGS="$CFLAGS -z"
         1549  +		# Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
         1550  +		#CFLAGS="$CFLAGS +DAportable"
         1551  +		SHLIB_CFLAGS="+z"
         1552  +		SHLIB_LD="ld -b"
         1553  +	    ])
  1345   1554   
  1346   1555   	    # Check to enable 64-bit flags for compiler/linker
  1347         -	    if test "$do64bit" = "yes" ; then
  1348         -		if test "$GCC" = "yes" ; then
  1349         -		    hpux_arch=`${CC} -dumpmachine`
  1350         -		    case $hpux_arch in
         1556  +	    AS_IF([test "$do64bit" = "yes"], [
         1557  +		AS_IF([test "$GCC" = yes], [
         1558  +		    case `${CC} -dumpmachine` in
  1351   1559   			hppa64*)
  1352   1560   			    # 64-bit gcc in use.  Fix flags for GNU ld.
  1353   1561   			    do64bit_ok=yes
  1354         -			    SHLIB_LD="${CC} -shared"
  1355         -			    SHLIB_LD_LIBS='${LIBS}'
  1356         -			    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
         1562  +			    SHLIB_LD='${CC} -shared'
         1563  +			    AS_IF([test $doRpath = yes], [
         1564  +				CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
  1357   1565   			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
  1358   1566   			    ;;
  1359   1567   			*)
  1360   1568   			    AC_MSG_WARN([64bit mode not supported with GCC on $system])
  1361   1569   			    ;;
  1362   1570   		    esac
  1363         -		else
         1571  +		], [
  1364   1572   		    do64bit_ok=yes
  1365   1573   		    CFLAGS="$CFLAGS +DD64"
  1366   1574   		    LDFLAGS_ARCH="+DD64"
  1367         -		fi
  1368         -	    fi
  1369         -	    ;;
  1370         -	HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
  1371         -	    SHLIB_SUFFIX=".sl"
  1372         -	    AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
  1373         -	    if test "$tcl_ok" = yes; then
  1374         -		SHLIB_CFLAGS="+z"
  1375         -		SHLIB_LD="ld -b"
  1376         -		SHLIB_LD_LIBS=""
  1377         -		DL_OBJS="tclLoadShl.o"
  1378         -		DL_LIBS="-ldld"
  1379         -		LDFLAGS="$LDFLAGS -Wl,-E"
  1380         -		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
  1381         -		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
  1382         -		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
  1383         -	    fi
  1384         -	    ;;
  1385         -	IRIX-5.*)
  1386         -	    SHLIB_CFLAGS=""
  1387         -	    SHLIB_LD="ld -shared -rdata_shared"
  1388         -	    SHLIB_LD_LIBS='${LIBS}'
  1389         -	    SHLIB_SUFFIX=".so"
  1390         -	    DL_OBJS="tclLoadDl.o"
  1391         -	    DL_LIBS=""
  1392         -	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  1393         -	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
  1394         -	    ;;
         1575  +		])
         1576  +	    ]) ;;
  1395   1577   	IRIX-6.*)
  1396   1578   	    SHLIB_CFLAGS=""
  1397   1579   	    SHLIB_LD="ld -n32 -shared -rdata_shared"
  1398         -	    SHLIB_LD_LIBS='${LIBS}'
  1399   1580   	    SHLIB_SUFFIX=".so"
  1400         -	    DL_OBJS="tclLoadDl.o"
  1401         -	    DL_LIBS=""
  1402         -	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  1403         -	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
  1404         -	    if test "$GCC" = "yes" ; then
         1581  +	    AS_IF([test $doRpath = yes], [
         1582  +		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
         1583  +		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
         1584  +	    AS_IF([test "$GCC" = yes], [
  1405   1585   		CFLAGS="$CFLAGS -mabi=n32"
  1406   1586   		LDFLAGS="$LDFLAGS -mabi=n32"
  1407         -	    else
         1587  +	    ], [
  1408   1588   		case $system in
  1409   1589   		    IRIX-6.3)
  1410   1590   			# Use to build 6.2 compatible binaries on 6.3.
  1411   1591   			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
  1412   1592   			;;
  1413   1593   		    *)
  1414   1594   			CFLAGS="$CFLAGS -n32"
  1415   1595   			;;
  1416   1596   		esac
  1417   1597   		LDFLAGS="$LDFLAGS -n32"
  1418         -	    fi
         1598  +	    ])
  1419   1599   	    ;;
  1420   1600   	IRIX64-6.*)
  1421   1601   	    SHLIB_CFLAGS=""
  1422   1602   	    SHLIB_LD="ld -n32 -shared -rdata_shared"
  1423         -	    SHLIB_LD_LIBS='${LIBS}'
  1424   1603   	    SHLIB_SUFFIX=".so"
  1425         -	    DL_OBJS="tclLoadDl.o"
  1426         -	    DL_LIBS=""
  1427         -	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  1428         -	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
         1604  +	    AS_IF([test $doRpath = yes], [
         1605  +		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
         1606  +		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
  1429   1607   
  1430   1608   	    # Check to enable 64-bit flags for compiler/linker
  1431   1609   
  1432         -	    if test "$do64bit" = "yes" ; then
  1433         -	        if test "$GCC" = "yes" ; then
         1610  +	    AS_IF([test "$do64bit" = yes], [
         1611  +	        AS_IF([test "$GCC" = yes], [
  1434   1612   	            AC_MSG_WARN([64bit mode not supported by gcc])
  1435         -	        else
         1613  +	        ], [
  1436   1614   	            do64bit_ok=yes
  1437   1615   	            SHLIB_LD="ld -64 -shared -rdata_shared"
  1438   1616   	            CFLAGS="$CFLAGS -64"
  1439   1617   	            LDFLAGS_ARCH="-64"
  1440         -	        fi
  1441         -	    fi
         1618  +	        ])
         1619  +	    ])
  1442   1620   	    ;;
  1443         -	Linux*)
         1621  +	Linux*|GNU*|NetBSD-Debian)
  1444   1622   	    SHLIB_CFLAGS="-fPIC"
  1445         -	    SHLIB_LD_LIBS='${LIBS}'
  1446   1623   	    SHLIB_SUFFIX=".so"
  1447   1624   
         1625  +	    # TEA specific:
  1448   1626   	    CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
  1449         -	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings 
  1450         -	    # when you inline the string and math operations.  Turn this off to
  1451         -	    # get rid of the warnings.
  1452         -	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"
  1453   1627   
  1454         -	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
  1455         -	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
  1456         -	    DL_OBJS="tclLoadDl.o"
  1457         -	    DL_LIBS="-ldl"
         1628  +	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
         1629  +	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'
  1458   1630   	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
  1459         -	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
         1631  +	    AS_IF([test $doRpath = yes], [
         1632  +		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
  1460   1633   	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
  1461         -	    if test "`uname -m`" = "alpha" ; then
  1462         -		CFLAGS="$CFLAGS -mieee"
  1463         -	    fi
  1464         -	    if test $do64bit = yes; then
         1634  +	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
         1635  +	    AS_IF([test $do64bit = yes], [
  1465   1636   		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
  1466   1637   		    hold_cflags=$CFLAGS
  1467   1638   		    CFLAGS="$CFLAGS -m64"
  1468   1639   		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
  1469   1640   		    CFLAGS=$hold_cflags])
  1470         -		if test $tcl_cv_cc_m64 = yes; then
         1641  +		AS_IF([test $tcl_cv_cc_m64 = yes], [
  1471   1642   		    CFLAGS="$CFLAGS -m64"
  1472   1643   		    do64bit_ok=yes
  1473         -		fi
  1474         -	    fi
         1644  +		])
         1645  +	   ])
  1475   1646   
  1476         -	    # The combo of gcc + glibc has a bug related
  1477         -	    # to inlining of functions like strtod(). The
  1478         -	    # -fno-builtin flag should address this problem
  1479         -	    # but it does not work. The -fno-inline flag
  1480         -	    # is kind of overkill but it works.
  1481         -	    # Disable inlining only when one of the
         1647  +	    # The combo of gcc + glibc has a bug related to inlining of
         1648  +	    # functions like strtod(). The -fno-builtin flag should address
         1649  +	    # this problem but it does not work. The -fno-inline flag is kind
         1650  +	    # of overkill but it works. Disable inlining only when one of the
  1482   1651   	    # files in compat/*.c is being linked in.
  1483         -	    if test x"${USE_COMPAT}" != x ; then
  1484         -	        CFLAGS="$CFLAGS -fno-inline"
  1485         -	    fi
  1486   1652   
  1487         -	    ;;
  1488         -	GNU*)
  1489         -	    SHLIB_CFLAGS="-fPIC"
  1490         -	    SHLIB_LD_LIBS='${LIBS}'
  1491         -	    SHLIB_SUFFIX=".so"
  1492         -
  1493         -	    SHLIB_LD="${CC} -shared"
  1494         -	    DL_OBJS=""
  1495         -	    DL_LIBS="-ldl"
  1496         -	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
  1497         -	    CC_SEARCH_FLAGS=""
  1498         -	    LD_SEARCH_FLAGS=""
  1499         -	    if test "`uname -m`" = "alpha" ; then
  1500         -		CFLAGS="$CFLAGS -mieee"
  1501         -	    fi
         1653  +	    AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
  1502   1654   	    ;;
  1503   1655   	Lynx*)
  1504   1656   	    SHLIB_CFLAGS="-fPIC"
  1505         -	    SHLIB_LD_LIBS='${LIBS}'
  1506   1657   	    SHLIB_SUFFIX=".so"
  1507   1658   	    CFLAGS_OPTIMIZE=-02
  1508         -	    SHLIB_LD="${CC} -shared "
  1509         -	    DL_OBJS="tclLoadDl.o"
  1510         -	    DL_LIBS="-mshared -ldl"
         1659  +	    SHLIB_LD='${CC} -shared'
  1511   1660   	    LD_FLAGS="-Wl,--export-dynamic"
  1512         -	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  1513         -	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  1514         -	    ;;
  1515         -	MP-RAS-02*)
  1516         -	    SHLIB_CFLAGS="-K PIC"
  1517         -	    SHLIB_LD="cc -G"
  1518         -	    SHLIB_LD_LIBS=""
  1519         -	    SHLIB_SUFFIX=".so"
  1520         -	    DL_OBJS="tclLoadDl.o"
  1521         -	    DL_LIBS="-ldl"
  1522         -	    CC_SEARCH_FLAGS=""
  1523         -	    LD_SEARCH_FLAGS=""
  1524         -	    ;;
  1525         -	MP-RAS-*)
  1526         -	    SHLIB_CFLAGS="-K PIC"
  1527         -	    SHLIB_LD="cc -G"
  1528         -	    SHLIB_LD_LIBS=""
  1529         -	    SHLIB_SUFFIX=".so"
  1530         -	    DL_OBJS="tclLoadDl.o"
  1531         -	    DL_LIBS="-ldl"
  1532         -	    LDFLAGS="$LDFLAGS -Wl,-Bexport"
  1533         -	    CC_SEARCH_FLAGS=""
  1534         -	    LD_SEARCH_FLAGS=""
  1535         -	    ;;
  1536         -	NetBSD-*|FreeBSD-[[1-2]].*)
  1537         -	    # NetBSD/SPARC needs -fPIC, -fpic will not do.
  1538         -	    SHLIB_CFLAGS="-fPIC"
  1539         -	    SHLIB_LD="ld -Bshareable -x"
  1540         -	    SHLIB_LD_LIBS='${LIBS}'
  1541         -	    SHLIB_SUFFIX=".so"
  1542         -	    DL_OBJS="tclLoadDl.o"
  1543         -	    DL_LIBS=""
  1544         -	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  1545         -	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
  1546         -	    AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
  1547         -		AC_EGREP_CPP(yes, [
  1548         -#ifdef __ELF__
  1549         -	yes
  1550         -#endif
  1551         -		], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
  1552         -	    if test $tcl_cv_ld_elf = yes; then
  1553         -		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
  1554         -	    else
  1555         -		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
  1556         -	    fi
  1557         -
  1558         -	    # Ancient FreeBSD doesn't handle version numbers with dots.
  1559         -
  1560         -	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
  1561         -	    TCL_LIB_VERSIONS_OK=nodots
         1661  +	    AS_IF([test $doRpath = yes], [
         1662  +		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
         1663  +		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
  1562   1664   	    ;;
  1563   1665   	OpenBSD-*)
  1564         -	    # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do.
  1565         -	    case `machine` in
  1566         -	    sparc|sparc64)
  1567         -		SHLIB_CFLAGS="-fPIC";;
         1666  +	    arch=`arch -s`
         1667  +	    case "$arch" in
         1668  +	    alpha|sparc64)
         1669  +		SHLIB_CFLAGS="-fPIC"
         1670  +		;;
  1568   1671   	    *)
  1569         -		SHLIB_CFLAGS="-fpic";;
         1672  +		SHLIB_CFLAGS="-fpic"
         1673  +		;;
  1570   1674   	    esac
  1571         -	    SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}"
  1572         -	    SHLIB_LD_LIBS='${LIBS}'
         1675  +	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
  1573   1676   	    SHLIB_SUFFIX=".so"
  1574         -	    DL_OBJS="tclLoadDl.o"
  1575         -	    DL_LIBS=""
  1576         -	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
         1677  +	    AS_IF([test $doRpath = yes], [
         1678  +		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
  1577   1679   	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
  1578         -	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
  1579         -	    AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
  1580         -		AC_EGREP_CPP(yes, [
  1581         -#ifdef __ELF__
  1582         -	yes
  1583         -#endif
  1584         -		], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
  1585         -	    if test $tcl_cv_ld_elf = yes; then
  1586         -		LDFLAGS=-Wl,-export-dynamic
  1587         -	    else
  1588         -		LDFLAGS=""
  1589         -	    fi
  1590         -
         1680  +	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
         1681  +	    LDFLAGS="-Wl,-export-dynamic"
         1682  +	    CFLAGS_OPTIMIZE="-O2"
         1683  +	    AS_IF([test "${TCL_THREADS}" = "1"], [
         1684  +		# On OpenBSD:	Compile with -pthread
         1685  +		#		Don't link with -lpthread
         1686  +		LIBS=`echo $LIBS | sed s/-lpthread//`
         1687  +		CFLAGS="$CFLAGS -pthread"
         1688  +	    ])
  1591   1689   	    # OpenBSD doesn't do version numbers with dots.
  1592   1690   	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
  1593   1691   	    TCL_LIB_VERSIONS_OK=nodots
  1594   1692   	    ;;
  1595         -	FreeBSD-*)
  1596         -	    # FreeBSD 3.* and greater have ELF.
         1693  +	NetBSD-*)
         1694  +	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
  1597   1695   	    SHLIB_CFLAGS="-fPIC"
  1598         -	    SHLIB_LD="ld -Bshareable -x"
  1599         -	    SHLIB_LD_LIBS='${LIBS}'
         1696  +	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
  1600   1697   	    SHLIB_SUFFIX=".so"
  1601         -	    DL_OBJS="tclLoadDl.o"
  1602         -	    DL_LIBS=""
  1603   1698   	    LDFLAGS="$LDFLAGS -export-dynamic"
  1604         -	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  1605         -	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
  1606         -	    if test "${TCL_THREADS}" = "1" ; then
         1699  +	    AS_IF([test $doRpath = yes], [
         1700  +		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
         1701  +	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
         1702  +	    AS_IF([test "${TCL_THREADS}" = "1"], [
  1607   1703   		# The -pthread needs to go in the CFLAGS, not LIBS
  1608   1704   		LIBS=`echo $LIBS | sed s/-pthread//`
  1609   1705   		CFLAGS="$CFLAGS -pthread"
  1610   1706   	    	LDFLAGS="$LDFLAGS -pthread"
  1611         -	    fi
         1707  +	    ])
         1708  +	    ;;
         1709  +	FreeBSD-*)
         1710  +	    # This configuration from FreeBSD Ports.
         1711  +	    SHLIB_CFLAGS="-fPIC"
         1712  +	    SHLIB_LD="${CC} -shared"
         1713  +	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
         1714  +	    SHLIB_SUFFIX=".so"
         1715  +	    LDFLAGS=""
         1716  +	    AS_IF([test $doRpath = yes], [
         1717  +		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
         1718  +		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
         1719  +	    AS_IF([test "${TCL_THREADS}" = "1"], [
         1720  +		# The -pthread needs to go in the LDFLAGS, not LIBS
         1721  +		LIBS=`echo $LIBS | sed s/-pthread//`
         1722  +		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
         1723  +		LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
  1612   1724   	    case $system in
  1613   1725   	    FreeBSD-3.*)
  1614         -	    	# FreeBSD-3 doesn't handle version numbers with dots.
  1615         -	    	UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
  1616         -	    	SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
  1617         -	    	TCL_LIB_VERSIONS_OK=nodots
         1726  +		# Version numbers are dot-stripped by system policy.
         1727  +		TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
         1728  +		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
         1729  +		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
         1730  +		TCL_LIB_VERSIONS_OK=nodots
  1618   1731   		;;
  1619   1732   	    esac
  1620   1733   	    ;;
  1621   1734   	Darwin-*)
  1622   1735   	    CFLAGS_OPTIMIZE="-Os"
  1623   1736   	    SHLIB_CFLAGS="-fno-common"
  1624   1737   	    # To avoid discrepancies between what headers configure sees during
................................................................................
  1626   1739   	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
  1627   1740   	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
  1628   1741   		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
  1629   1742   		if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
  1630   1743   	    CFLAGS="`echo " ${CFLAGS}" | \
  1631   1744   		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
  1632   1745   		if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
  1633         -	    if test $do64bit = yes; then
         1746  +	    AS_IF([test $do64bit = yes], [
  1634   1747   		case `arch` in
  1635   1748   		    ppc)
  1636   1749   			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
  1637   1750   				tcl_cv_cc_arch_ppc64, [
  1638   1751   			    hold_cflags=$CFLAGS
  1639   1752   			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
  1640   1753   			    AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
  1641   1754   				    tcl_cv_cc_arch_ppc64=no)
  1642   1755   			    CFLAGS=$hold_cflags])
  1643         -			if test $tcl_cv_cc_arch_ppc64 = yes; then
         1756  +			AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
  1644   1757   			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
  1645   1758   			    do64bit_ok=yes
  1646         -			fi;;
         1759  +			]);;
  1647   1760   		    i386)
  1648   1761   			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
  1649   1762   				tcl_cv_cc_arch_x86_64, [
  1650   1763   			    hold_cflags=$CFLAGS
  1651   1764   			    CFLAGS="$CFLAGS -arch x86_64"
  1652   1765   			    AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
  1653   1766   				    tcl_cv_cc_arch_x86_64=no)
  1654   1767   			    CFLAGS=$hold_cflags])
  1655         -			if test $tcl_cv_cc_arch_x86_64 = yes; then
         1768  +			AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
  1656   1769   			    CFLAGS="$CFLAGS -arch x86_64"
  1657   1770   			    do64bit_ok=yes
  1658         -			fi;;
         1771  +			]);;
  1659   1772   		    *)
  1660   1773   			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
  1661   1774   		esac
  1662         -	    else
         1775  +	    ], [
  1663   1776   		# Check for combined 32-bit and 64-bit fat build
  1664         -		echo "$CFLAGS " | grep -E -q -- '-arch (ppc64|x86_64) ' && \
  1665         -		    echo "$CFLAGS " | grep -E -q -- '-arch (ppc|i386) ' && \
  1666         -		    fat_32_64=yes
  1667         -	    fi
  1668         -	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
         1777  +		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
         1778  +		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
         1779  +		    fat_32_64=yes])
         1780  +	    ])
         1781  +	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
  1669   1782   	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
  1670   1783   	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
  1671   1784   		hold_ldflags=$LDFLAGS
  1672   1785   		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
  1673   1786   		AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
  1674   1787   		LDFLAGS=$hold_ldflags])
  1675         -	    if test $tcl_cv_ld_single_module = yes; then
         1788  +	    AS_IF([test $tcl_cv_ld_single_module = yes], [
  1676   1789   		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
  1677         -	    fi
  1678         -	    SHLIB_LD_LIBS='${LIBS}'
         1790  +	    ])
         1791  +	    # TEA specific: link shlib with current and compatibility version flags
         1792  +	    vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
         1793  +	    SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
  1679   1794   	    SHLIB_SUFFIX=".dylib"
  1680         -	    DL_OBJS="tclLoadDyld.o"
  1681         -	    DL_LIBS=""
  1682   1795   	    # Don't use -prebind when building for Mac OS X 10.4 or later only:
  1683         -	    test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
  1684         -		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4 && \
  1685         -		LDFLAGS="$LDFLAGS -prebind"
         1796  +	    AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
         1797  +		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
         1798  +		LDFLAGS="$LDFLAGS -prebind"])
  1686   1799   	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
  1687         -	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [
         1800  +	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
         1801  +		    tcl_cv_ld_search_paths_first, [
  1688   1802   		hold_ldflags=$LDFLAGS
  1689   1803   		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
  1690         -		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, tcl_cv_ld_search_paths_first=no)
         1804  +		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
         1805  +			tcl_cv_ld_search_paths_first=no)
  1691   1806   		LDFLAGS=$hold_ldflags])
  1692         -	    if test $tcl_cv_ld_search_paths_first = yes; then
         1807  +	    AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
  1693   1808   		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
  1694         -	    fi
         1809  +	    ])
         1810  +	    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
         1811  +		AC_DEFINE(MODULE_SCOPE, [__private_extern__],
         1812  +		    [Compiler support for module scope symbols])
         1813  +		tcl_cv_cc_visibility_hidden=yes
         1814  +	    ])
  1695   1815   	    CC_SEARCH_FLAGS=""
  1696   1816   	    LD_SEARCH_FLAGS=""
  1697   1817   	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
  1698         -
  1699         -	    # TEA specific: for Tk extensions, remove 64-bit arch flags from
  1700         -	    # CFLAGS et al. for combined 32 & 64 bit fat builds as neither
  1701         -	    # TkAqua nor TkX11 can be built for 64-bit at present.
  1702         -	    test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}" && for v in CFLAGS CPPFLAGS LDFLAGS; do
  1703         -		eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'; done
  1704         -	    ;;
  1705         -	NEXTSTEP-*)
  1706         -	    SHLIB_CFLAGS=""
  1707         -	    SHLIB_LD="cc -nostdlib -r"
  1708         -	    SHLIB_LD_LIBS=""
  1709         -	    SHLIB_SUFFIX=".so"
  1710         -	    DL_OBJS="tclLoadNext.o"
  1711         -	    DL_LIBS=""
  1712         -	    CC_SEARCH_FLAGS=""
  1713         -	    LD_SEARCH_FLAGS=""
         1818  +	    # TEA specific: for combined 32 & 64 bit fat builds of Tk
         1819  +	    # extensions, verify that 64-bit build is possible.
         1820  +	    AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
         1821  +		AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
         1822  +		    AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
         1823  +			for v in CFLAGS CPPFLAGS LDFLAGS; do
         1824  +			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
         1825  +			done
         1826  +			CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
         1827  +			LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
         1828  +			AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
         1829  +			    tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
         1830  +			for v in CFLAGS CPPFLAGS LDFLAGS; do
         1831  +			    eval $v'="$hold_'$v'"'
         1832  +			done])
         1833  +		])
         1834  +		AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
         1835  +		    AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
         1836  +			for v in CFLAGS CPPFLAGS LDFLAGS; do
         1837  +			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
         1838  +			done
         1839  +			CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
         1840  +			LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
         1841  +			AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
         1842  +			    tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
         1843  +			for v in CFLAGS CPPFLAGS LDFLAGS; do
         1844  +			    eval $v'="$hold_'$v'"'
         1845  +			done])
         1846  +		])
         1847  +		# remove 64-bit arch flags from CFLAGS et al. if configuration
         1848  +		# does not support 64-bit.
         1849  +		AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
         1850  +		    AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
         1851  +		    for v in CFLAGS CPPFLAGS LDFLAGS; do
         1852  +			eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
         1853  +		    done])
         1854  +	    ])
  1714   1855   	    ;;
  1715   1856   	OS/390-*)
  1716   1857   	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
  1717   1858   	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
  1718   1859   		[Should OS/390 do the right thing with sockets?])
  1719         -	    ;;      
  1720         -	OSF1-1.0|OSF1-1.1|OSF1-1.2)
  1721         -	    # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
  1722         -	    SHLIB_CFLAGS=""
  1723         -	    # Hack: make package name same as library name
  1724         -	    SHLIB_LD='ld -R -export $@:'
  1725         -	    SHLIB_LD_LIBS=""
  1726         -	    SHLIB_SUFFIX=".so"
  1727         -	    DL_OBJS="tclLoadOSF.o"
  1728         -	    DL_LIBS=""
  1729         -	    CC_SEARCH_FLAGS=""
  1730         -	    LD_SEARCH_FLAGS=""
  1731         -	    ;;
  1732         -	OSF1-1.*)
  1733         -	    # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
  1734         -	    SHLIB_CFLAGS="-fPIC"
  1735         -	    if test "$SHARED_BUILD" = "1" ; then
  1736         -	        SHLIB_LD="ld -shared"
  1737         -	    else
  1738         -	        SHLIB_LD="ld -non_shared"
  1739         -	    fi
  1740         -	    SHLIB_LD_LIBS=""
  1741         -	    SHLIB_SUFFIX=".so"
  1742         -	    DL_OBJS="tclLoadDl.o"
  1743         -	    DL_LIBS=""
  1744         -	    CC_SEARCH_FLAGS=""
  1745         -	    LD_SEARCH_FLAGS=""
  1746   1860   	    ;;
  1747   1861   	OSF1-V*)
  1748   1862   	    # Digital OSF/1
  1749   1863   	    SHLIB_CFLAGS=""
  1750         -	    if test "$SHARED_BUILD" = "1" ; then
         1864  +	    AS_IF([test "$SHARED_BUILD" = 1], [
  1751   1865   	        SHLIB_LD='ld -shared -expect_unresolved "*"'
  1752         -	    else
         1866  +	    ], [
  1753   1867   	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
  1754         -	    fi
  1755         -	    SHLIB_LD_LIBS=""
         1868  +	    ])
  1756   1869   	    SHLIB_SUFFIX=".so"
  1757         -	    DL_OBJS="tclLoadDl.o"
  1758         -	    DL_LIBS=""
  1759         -	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
  1760         -	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
  1761         -	    if test "$GCC" = "yes" ; then
  1762         -		CFLAGS="$CFLAGS -mieee"
  1763         -            else
  1764         -		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
  1765         -	    fi
         1870  +	    AS_IF([test $doRpath = yes], [
         1871  +		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
         1872  +		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
         1873  +	    AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
         1874  +		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
  1766   1875   	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
  1767         -	    if test "${TCL_THREADS}" = "1" ; then
         1876  +	    AS_IF([test "${TCL_THREADS}" = 1], [
  1768   1877   		CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
  1769   1878   		CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
  1770   1879   		LIBS=`echo $LIBS | sed s/-lpthreads//`
  1771         -		if test "$GCC" = "yes" ; then
         1880  +		AS_IF([test "$GCC" = yes], [
  1772   1881   		    LIBS="$LIBS -lpthread -lmach -lexc"
  1773         -		else
         1882  +		], [
  1774   1883   		    CFLAGS="$CFLAGS -pthread"
  1775   1884   		    LDFLAGS="$LDFLAGS -pthread"
  1776         -		fi
  1777         -	    fi
  1778         -
         1885  +		])
         1886  +	    ])
  1779   1887   	    ;;
  1780   1888   	QNX-6*)
  1781   1889   	    # QNX RTP
  1782   1890   	    # This may work for all QNX, but it was only reported for v6.
  1783   1891   	    SHLIB_CFLAGS="-fPIC"
  1784   1892   	    SHLIB_LD="ld -Bshareable -x"
  1785   1893   	    SHLIB_LD_LIBS=""
  1786   1894   	    SHLIB_SUFFIX=".so"
  1787         -	    DL_OBJS="tclLoadDl.o"
  1788         -	    # dlopen is in -lc on QNX
  1789         -	    DL_LIBS=""
  1790   1895   	    CC_SEARCH_FLAGS=""
  1791   1896   	    LD_SEARCH_FLAGS=""
  1792   1897   	    ;;
  1793   1898   	SCO_SV-3.2*)
  1794         -	    # Note, dlopen is available only on SCO 3.2.5 and greater. However,
  1795         -	    # this test works, since "uname -s" was non-standard in 3.2.4 and
  1796         -	    # below.
  1797         -	    if test "$GCC" = "yes" ; then
  1798         -	    	SHLIB_CFLAGS="-fPIC -melf"
  1799         -	    	LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
  1800         -	    else
  1801         -	    	SHLIB_CFLAGS="-Kpic -belf"
  1802         -	    	LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
  1803         -	    fi
         1899  +	    AS_IF([test "$GCC" = yes], [
         1900  +		SHLIB_CFLAGS="-fPIC -melf"
         1901  +		LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
         1902  +	    ], [
         1903  +		SHLIB_CFLAGS="-Kpic -belf"
         1904  +		LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
         1905  +	    ])
  1804   1906   	    SHLIB_LD="ld -G"
  1805   1907   	    SHLIB_LD_LIBS=""
  1806   1908   	    SHLIB_SUFFIX=".so"
  1807         -	    DL_OBJS="tclLoadDl.o"
  1808         -	    DL_LIBS=""
  1809   1909   	    CC_SEARCH_FLAGS=""
  1810   1910   	    LD_SEARCH_FLAGS=""
  1811   1911   	    ;;
  1812         -	SINIX*5.4*)
  1813         -	    SHLIB_CFLAGS="-K PIC"
  1814         -	    SHLIB_LD="cc -G"
  1815         -	    SHLIB_LD_LIBS=""
  1816         -	    SHLIB_SUFFIX=".so"
  1817         -	    DL_OBJS="tclLoadDl.o"
  1818         -	    DL_LIBS="-ldl"
  1819         -	    CC_SEARCH_FLAGS=""
  1820         -	    LD_SEARCH_FLAGS=""
  1821         -	    ;;
  1822         -	SunOS-4*)
  1823         -	    SHLIB_CFLAGS="-PIC"
  1824         -	    SHLIB_LD="ld"
  1825         -	    SHLIB_LD_LIBS=""
  1826         -	    SHLIB_SUFFIX=".so"
  1827         -	    DL_OBJS="tclLoadDl.o"
  1828         -	    DL_LIBS="-ldl"
  1829         -	    CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
  1830         -	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
  1831         -
  1832         -	    # SunOS can't handle version numbers with dots in them in library
  1833         -	    # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
  1834         -	    # requires an extra version number at the end of .so file names.
  1835         -	    # So, the library has to have a name like libtcl75.so.1.0
  1836         -
  1837         -	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
  1838         -	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
  1839         -	    TCL_LIB_VERSIONS_OK=nodots
  1840         -	    ;;
  1841   1912   	SunOS-5.[[0-6]])
  1842   1913   	    # Careful to not let 5.10+ fall into this case
  1843   1914   
  1844   1915   	    # Note: If _REENTRANT isn't defined, then Solaris
  1845   1916   	    # won't define thread-safe library routines.
  1846   1917   
  1847   1918   	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
  1848   1919   	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
  1849   1920   		[Do we really want to follow the standard? Yes we do!])
  1850   1921   
  1851   1922   	    SHLIB_CFLAGS="-KPIC"
  1852         -
  1853         -	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
  1854         -	    # symbols when dynamically loaded into tclsh.
  1855         -
  1856         -	    SHLIB_LD_LIBS='${LIBS}'
  1857   1923   	    SHLIB_SUFFIX=".so"
  1858         -	    DL_OBJS="tclLoadDl.o"
  1859         -	    DL_LIBS="-ldl"
  1860         -	    if test "$GCC" = "yes" ; then
  1861         -		SHLIB_LD="$CC -shared"
         1924  +	    AS_IF([test "$GCC" = yes], [
         1925  +		SHLIB_LD='${CC} -shared'
  1862   1926   		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
  1863   1927   		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
  1864         -	    else
         1928  +	    ], [
  1865   1929   		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
  1866   1930   		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
  1867   1931   		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
  1868         -	    fi
         1932  +	    ])
  1869   1933   	    ;;
  1870   1934   	SunOS-5*)
  1871   1935   	    # Note: If _REENTRANT isn't defined, then Solaris
  1872   1936   	    # won't define thread-safe library routines.
  1873   1937   
  1874   1938   	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
  1875   1939   	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
  1876   1940   		[Do we really want to follow the standard? Yes we do!])
  1877   1941   
  1878   1942   	    SHLIB_CFLAGS="-KPIC"
  1879   1943   
  1880   1944   	    # Check to enable 64-bit flags for compiler/linker
  1881         -	    if test "$do64bit" = "yes" ; then
         1945  +	    AS_IF([test "$do64bit" = yes], [
  1882   1946   		arch=`isainfo`
  1883         -		if test "$arch" = "sparcv9 sparc" ; then
  1884         -			if test "$GCC" = "yes" ; then
  1885         -			    if test "`gcc -dumpversion | awk -F. '{print [$]1}'`" -lt "3" ; then
  1886         -				AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
  1887         -			    else
  1888         -				do64bit_ok=yes
  1889         -				CFLAGS="$CFLAGS -m64 -mcpu=v9"
  1890         -				LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
  1891         -				SHLIB_CFLAGS="-fPIC"
  1892         -			    fi
  1893         -			else
         1947  +		AS_IF([test "$arch" = "sparcv9 sparc"], [
         1948  +		    AS_IF([test "$GCC" = yes], [
         1949  +			AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
         1950  +			    AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
         1951  +			], [
  1894   1952   			    do64bit_ok=yes
  1895         -			    if test "$do64bitVIS" = "yes" ; then
  1896         -				CFLAGS="$CFLAGS -xarch=v9a"
  1897         -			    	LDFLAGS_ARCH="-xarch=v9a"
  1898         -			    else
  1899         -				CFLAGS="$CFLAGS -xarch=v9"
  1900         -			    	LDFLAGS_ARCH="-xarch=v9"
  1901         -			    fi
  1902         -			    # Solaris 64 uses this as well
  1903         -			    #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
  1904         -			fi
  1905         -		elif test "$arch" = "amd64 i386" ; then
  1906         -		    if test "$GCC" = "yes" ; then
  1907         -			AC_MSG_WARN([64bit mode not supported with GCC on $system])
  1908         -		    else
         1953  +			    CFLAGS="$CFLAGS -m64 -mcpu=v9"
         1954  +			    LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
         1955  +			    SHLIB_CFLAGS="-fPIC"
         1956  +			])
         1957  +		    ], [
         1958  +			do64bit_ok=yes
         1959  +			AS_IF([test "$do64bitVIS" = yes], [
         1960  +			    CFLAGS="$CFLAGS -xarch=v9a"
         1961  +			    LDFLAGS_ARCH="-xarch=v9a"
         1962  +			], [
         1963  +			    CFLAGS="$CFLAGS -xarch=v9"
         1964  +			    LDFLAGS_ARCH="-xarch=v9"
         1965  +			])
         1966  +			# Solaris 64 uses this as well
         1967  +			#LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
         1968  +		    ])
         1969  +		], [AS_IF([test "$arch" = "amd64 i386"], [
         1970  +		    AS_IF([test "$GCC" = yes], [
         1971  +			case $system in
         1972  +			    SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
         1973  +				do64bit_ok=yes
         1974  +				CFLAGS="$CFLAGS -m64"
         1975  +				LDFLAGS="$LDFLAGS -m64";;
         1976  +			    *)
         1977  +				AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
         1978  +			esac
         1979  +		    ], [
  1909   1980   			do64bit_ok=yes
  1910         -			CFLAGS="$CFLAGS -xarch=amd64"
  1911         -			LDFLAGS="$LDFLAGS -xarch=amd64"
  1912         -		    fi
  1913         -		else
  1914         -		    AC_MSG_WARN([64bit mode not supported for $arch])
  1915         -		fi
  1916         -	    fi
  1917         -	    
  1918         -	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
  1919         -	    # symbols when dynamically loaded into tclsh.
         1981  +			case $system in
         1982  +			    SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
         1983  +				CFLAGS="$CFLAGS -m64"
         1984  +				LDFLAGS="$LDFLAGS -m64";;
         1985  +			    *)
         1986  +				CFLAGS="$CFLAGS -xarch=amd64"
         1987  +				LDFLAGS="$LDFLAGS -xarch=amd64";;
         1988  +			esac
         1989  +		    ])
         1990  +		], [AC_MSG_WARN([64bit mode not supported for $arch])])])
         1991  +	    ])
  1920   1992   
  1921         -	    SHLIB_LD_LIBS='${LIBS}'
  1922   1993   	    SHLIB_SUFFIX=".so"
  1923         -	    DL_OBJS="tclLoadDl.o"
  1924         -	    DL_LIBS="-ldl"
  1925         -	    if test "$GCC" = "yes" ; then
  1926         -		SHLIB_LD="$CC -shared"
         1994  +	    AS_IF([test "$GCC" = yes], [
         1995  +		SHLIB_LD='${CC} -shared'
  1927   1996   		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
  1928   1997   		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
  1929         -		if test "$do64bit_ok" = "yes" ; then
  1930         -		    # We need to specify -static-libgcc or we need to
  1931         -		    # add the path to the sparv9 libgcc.
  1932         -		    # JH: static-libgcc is necessary for core Tcl, but may
  1933         -		    # not be necessary for extensions.
  1934         -		    SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
  1935         -		    # for finding sparcv9 libgcc, get the regular libgcc
  1936         -		    # path, remove so name and append 'sparcv9'
  1937         -		    #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
  1938         -		    #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
  1939         -		fi
  1940         -	    else
  1941         -		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
         1998  +		AS_IF([test "$do64bit_ok" = yes], [
         1999  +		    AS_IF([test "$arch" = "sparcv9 sparc"], [
         2000  +			# We need to specify -static-libgcc or we need to
         2001  +			# add the path to the sparv9 libgcc.
         2002  +			# JH: static-libgcc is necessary for core Tcl, but may
         2003  +			# not be necessary for extensions.
         2004  +			SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
         2005  +			# for finding sparcv9 libgcc, get the regular libgcc
         2006  +			# path, remove so name and append 'sparcv9'
         2007  +			#v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
         2008  +			#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
         2009  +		    ], [AS_IF([test "$arch" = "amd64 i386"], [
         2010  +			# JH: static-libgcc is necessary for core Tcl, but may
         2011  +			# not be necessary for extensions.
         2012  +			SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
         2013  +		    ])])
         2014  +		])
         2015  +	    ], [
         2016  +		case $system in
         2017  +		    SunOS-5.[[1-9]][[0-9]]*)
         2018  +			# TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
         2019  +			SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
         2020  +		    *)
         2021  +			SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
         2022  +		esac
  1942   2023   		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
  1943   2024   		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
  1944         -	    fi
         2025  +	    ])
  1945   2026   	    ;;
  1946   2027   	UNIX_SV* | UnixWare-5*)
  1947   2028   	    SHLIB_CFLAGS="-KPIC"
  1948         -	    SHLIB_LD="cc -G"
         2029  +	    SHLIB_LD='${CC} -G'
  1949   2030   	    SHLIB_LD_LIBS=""
  1950   2031   	    SHLIB_SUFFIX=".so"
  1951         -	    DL_OBJS="tclLoadDl.o"
  1952         -	    DL_LIBS="-ldl"
  1953   2032   	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
  1954   2033   	    # that don't grok the -Bexport option.  Test that it does.
  1955   2034   	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
  1956   2035   		hold_ldflags=$LDFLAGS
  1957   2036   		LDFLAGS="$LDFLAGS -Wl,-Bexport"
  1958   2037   		AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
  1959   2038   	        LDFLAGS=$hold_ldflags])
  1960         -	    if test $tcl_cv_ld_Bexport = yes; then
         2039  +	    AS_IF([test $tcl_cv_ld_Bexport = yes], [
  1961   2040   		LDFLAGS="$LDFLAGS -Wl,-Bexport"
  1962         -	    fi
         2041  +	    ])
  1963   2042   	    CC_SEARCH_FLAGS=""
  1964   2043   	    LD_SEARCH_FLAGS=""
  1965   2044   	    ;;
  1966   2045       esac
  1967   2046   
  1968         -    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
         2047  +    AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
  1969   2048   	AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
  1970         -    fi
         2049  +    ])
  1971   2050   
  1972   2051   dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
  1973   2052   dnl # until the end of configure, as configure's compile and link tests use
  1974   2053   dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
  1975   2054   dnl # preprocessing tests use only CPPFLAGS.
  1976   2055       AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
  1977   2056   
  1978         -    # Step 4: disable dynamic loading if requested via a command-line switch.
  1979         -
  1980         -    AC_ARG_ENABLE(load,
  1981         -	AC_HELP_STRING([--enable-load],
  1982         -	    [allow dynamic loading and "load" command (default: on)]),
  1983         -	[tcl_ok=$enableval], [tcl_ok=yes])
  1984         -    if test "$tcl_ok" = "no"; then
  1985         -	DL_OBJS=""
  1986         -    fi
  1987         -
  1988         -    if test "x$DL_OBJS" != "x" ; then
  1989         -	BUILD_DLTEST="\$(DLTEST_TARGETS)"
  1990         -    else
  1991         -	echo "Can't figure out how to do dynamic loading or shared libraries"
  1992         -	echo "on this system."
  1993         -	SHLIB_CFLAGS=""
  1994         -	SHLIB_LD=""
  1995         -	SHLIB_SUFFIX=""
  1996         -	DL_OBJS="tclLoadNone.o"
  1997         -	DL_LIBS=""
  1998         -	LDFLAGS="$LDFLAGS_ORIG"
  1999         -	CC_SEARCH_FLAGS=""
  2000         -	LD_SEARCH_FLAGS=""
  2001         -	BUILD_DLTEST=""
  2002         -    fi
         2057  +    # Add in the arch flags late to ensure it wasn't removed.
         2058  +    # Not necessary in TEA, but this is aligned with core
  2003   2059       LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
  2004   2060   
  2005   2061       # If we're running gcc, then change the C flags for compiling shared
  2006   2062       # libraries to the right flags for gcc, instead of those for the
  2007   2063       # standard manufacturer compiler.
  2008   2064   
  2009         -    if test "$DL_OBJS" != "tclLoadNone.o" ; then
  2010         -	if test "$GCC" = "yes" ; then
  2011         -	    case $system in
  2012         -		AIX-*)
  2013         -		    ;;
  2014         -		BSD/OS*)
  2015         -		    ;;
  2016         -		IRIX*)
  2017         -		    ;;
  2018         -		NetBSD-*|FreeBSD-*)
  2019         -		    ;;
  2020         -		Darwin-*)
  2021         -		    ;;
  2022         -		SCO_SV-3.2*)
  2023         -		    ;;
  2024         -		windows)
  2025         -		    ;;
  2026         -		*)
  2027         -		    SHLIB_CFLAGS="-fPIC"
  2028         -		    ;;
  2029         -	    esac
  2030         -	fi
  2031         -    fi
  2032         -
  2033         -    if test "$SHARED_LIB_SUFFIX" = "" ; then
  2034         -	SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
  2035         -    fi
  2036         -    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
  2037         -	UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
  2038         -    fi
  2039         -
  2040         -    AC_SUBST(DL_LIBS)
         2065  +    AS_IF([test "$GCC" = yes], [
         2066  +	case $system in
         2067  +	    AIX-*) ;;
         2068  +	    BSD/OS*) ;;
         2069  +	    CYGWIN_*|MINGW32_*|MINGW64_*) ;;
         2070  +	    IRIX*) ;;
         2071  +	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
         2072  +	    Darwin-*) ;;
         2073  +	    SCO_SV-3.2*) ;;
         2074  +	    windows) ;;
         2075  +	    *) SHLIB_CFLAGS="-fPIC" ;;
         2076  +	esac])
         2077  +
         2078  +    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
         2079  +	AC_DEFINE(MODULE_SCOPE, [extern],
         2080  +	    [No Compiler support for module scope symbols])
         2081  +    ])
         2082  +
         2083  +    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
         2084  +    # TEA specific: use PACKAGE_VERSION instead of VERSION
         2085  +    SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
         2086  +    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
         2087  +    # TEA specific: use PACKAGE_VERSION instead of VERSION
         2088  +    UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
         2089  +
         2090  +    if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
         2091  +	AC_CACHE_CHECK(for SEH support in compiler,
         2092  +	    tcl_cv_seh,
         2093  +	AC_TRY_RUN([
         2094  +#define WIN32_LEAN_AND_MEAN
         2095  +#include <windows.h>
         2096  +#undef WIN32_LEAN_AND_MEAN
         2097  +
         2098  +	    int main(int argc, char** argv) {
         2099  +		int a, b = 0;
         2100  +		__try {
         2101  +		    a = 666 / b;
         2102  +		}
         2103  +		__except (EXCEPTION_EXECUTE_HANDLER) {
         2104  +		    return 0;
         2105  +		}
         2106  +		return 1;
         2107  +	    }
         2108  +	],
         2109  +	    tcl_cv_seh=yes,
         2110  +	    tcl_cv_seh=no,
         2111  +	    tcl_cv_seh=no)
         2112  +	)
         2113  +	if test "$tcl_cv_seh" = "no" ; then
         2114  +	    AC_DEFINE(HAVE_NO_SEH, 1,
         2115  +		    [Defined when mingw does not support SEH])
         2116  +	fi
         2117  +
         2118  +	#
         2119  +	# Check to see if the excpt.h include file provided contains the
         2120  +	# definition for EXCEPTION_DISPOSITION; if not, which is the case
         2121  +	# with Cygwin's version as of 2002-04-10, define it to be int,
         2122  +	# sufficient for getting the current code to work.
         2123  +	#
         2124  +	AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
         2125  +	    tcl_cv_eh_disposition,
         2126  +	    AC_TRY_COMPILE([
         2127  +#	    define WIN32_LEAN_AND_MEAN
         2128  +#	    include <windows.h>
         2129  +#	    undef WIN32_LEAN_AND_MEAN
         2130  +	    ],[
         2131  +		EXCEPTION_DISPOSITION x;
         2132  +	    ],
         2133  +		tcl_cv_eh_disposition=yes,
         2134  +		tcl_cv_eh_disposition=no)
         2135  +	)
         2136  +	if test "$tcl_cv_eh_disposition" = "no" ; then
         2137  +	AC_DEFINE(EXCEPTION_DISPOSITION, int,
         2138  +		[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
         2139  +	fi
         2140  +
         2141  +	# Check to see if winnt.h defines CHAR, SHORT, and LONG
         2142  +	# even if VOID has already been #defined. The win32api
         2143  +	# used by mingw and cygwin is known to do this.
         2144  +
         2145  +	AC_CACHE_CHECK(for winnt.h that ignores VOID define,
         2146  +	    tcl_cv_winnt_ignore_void,
         2147  +	    AC_TRY_COMPILE([
         2148  +#define VOID void
         2149  +#define WIN32_LEAN_AND_MEAN
         2150  +#include <windows.h>
         2151  +#undef WIN32_LEAN_AND_MEAN
         2152  +	    ], [
         2153  +		CHAR c;
         2154  +		SHORT s;
         2155  +		LONG l;
         2156  +	    ],
         2157  +        tcl_cv_winnt_ignore_void=yes,
         2158  +        tcl_cv_winnt_ignore_void=no)
         2159  +	)
         2160  +	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
         2161  +	    AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
         2162  +		    [Defined when cygwin/mingw ignores VOID define in winnt.h])
         2163  +	fi
         2164  +    fi
         2165  +
         2166  +	# See if the compiler supports casting to a union type.
         2167  +	# This is used to stop gcc from printing a compiler
         2168  +	# warning when initializing a union member.
         2169  +
         2170  +	AC_CACHE_CHECK(for cast to union support,
         2171  +	    tcl_cv_cast_to_union,
         2172  +	    AC_TRY_COMPILE([],
         2173  +	    [
         2174  +		  union foo { int i; double d; };
         2175  +		  union foo f = (union foo) (int) 0;
         2176  +	    ],
         2177  +	    tcl_cv_cast_to_union=yes,
         2178  +	    tcl_cv_cast_to_union=no)
         2179  +	)
         2180  +	if test "$tcl_cv_cast_to_union" = "yes"; then
         2181  +	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
         2182  +		    [Defined when compiler supports casting to union type.])
         2183  +	fi
  2041   2184   
  2042   2185       AC_SUBST(CFLAGS_DEBUG)
  2043   2186       AC_SUBST(CFLAGS_OPTIMIZE)
  2044   2187       AC_SUBST(CFLAGS_WARNING)
  2045   2188   
  2046   2189       AC_SUBST(STLIB_LD)
  2047   2190       AC_SUBST(SHLIB_LD)
................................................................................
  2064   2207   #	Note that #include lines must begin in leftmost column for
  2065   2208   #	some compilers to recognize them as preprocessor directives,
  2066   2209   #	and some build environments have stdin not pointing at a
  2067   2210   #	pseudo-terminal (usually /dev/null instead.)
  2068   2211   #
  2069   2212   # Arguments:
  2070   2213   #	none
  2071         -#	
         2214  +#
  2072   2215   # Results:
  2073   2216   #
  2074   2217   #	Defines only one of the following vars:
  2075   2218   #		HAVE_SYS_MODEM_H
  2076   2219   #		USE_TERMIOS
  2077   2220   #		USE_TERMIO
  2078   2221   #		USE_SGTTY
  2079         -#
  2080   2222   #--------------------------------------------------------------------
  2081   2223   
  2082   2224   AC_DEFUN([TEA_SERIAL_PORT], [
  2083   2225       AC_CHECK_HEADERS(sys/modem.h)
  2084   2226       AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
  2085   2227       AC_TRY_RUN([
  2086   2228   #include <termios.h>
................................................................................
  2171   2313       case $tcl_cv_api_serial in
  2172   2314   	termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
  2173   2315   	termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
  2174   2316   	sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
  2175   2317       esac
  2176   2318   ])
  2177   2319   
  2178         -#--------------------------------------------------------------------
  2179         -# TEA_MISSING_POSIX_HEADERS
  2180         -#
  2181         -#	Supply substitutes for missing POSIX header files.  Special
  2182         -#	notes:
  2183         -#	    - stdlib.h doesn't define strtol, strtoul, or
  2184         -#	      strtod insome versions of SunOS
  2185         -#	    - some versions of string.h don't declare procedures such
  2186         -#	      as strstr
  2187         -#
  2188         -# Arguments:
  2189         -#	none
  2190         -#	
  2191         -# Results:
  2192         -#
  2193         -#	Defines some of the following vars:
  2194         -#		NO_DIRENT_H
  2195         -#		NO_ERRNO_H
  2196         -#		NO_VALUES_H
  2197         -#		HAVE_LIMITS_H or NO_LIMITS_H
  2198         -#		NO_STDLIB_H
  2199         -#		NO_STRING_H
  2200         -#		NO_SYS_WAIT_H
  2201         -#		NO_DLFCN_H
  2202         -#		HAVE_SYS_PARAM_H
  2203         -#
  2204         -#		HAVE_STRING_H ?
  2205         -#
  2206         -# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
  2207         -# CHECK on limits.h
  2208         -#--------------------------------------------------------------------
  2209         -
  2210         -AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
  2211         -    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
  2212         -    AC_TRY_LINK([#include <sys/types.h>
  2213         -#include <dirent.h>], [
  2214         -#ifndef _POSIX_SOURCE
  2215         -#   ifdef __Lynx__
  2216         -	/*
  2217         -	 * Generate compilation error to make the test fail:  Lynx headers
  2218         -	 * are only valid if really in the POSIX environment.
  2219         -	 */
  2220         -
  2221         -	missing_procedure();
  2222         -#   endif
  2223         -#endif
  2224         -DIR *d;
  2225         -struct dirent *entryPtr;
  2226         -char *p;
  2227         -d = opendir("foobar");
  2228         -entryPtr = readdir(d);
  2229         -p = entryPtr->d_name;
  2230         -closedir(d);
  2231         -], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
  2232         -
  2233         -    if test $tcl_cv_dirent_h = no; then
  2234         -	AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
  2235         -    fi
  2236         -
  2237         -    AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
  2238         -    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
  2239         -    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
  2240         -    AC_CHECK_HEADER(limits.h,
  2241         -	[AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
  2242         -	[AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
  2243         -    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
  2244         -    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
  2245         -    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
  2246         -    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
  2247         -    if test $tcl_ok = 0; then
  2248         -	AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
  2249         -    fi
  2250         -    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
  2251         -    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
  2252         -    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
  2253         -
  2254         -    # See also memmove check below for a place where NO_STRING_H can be
  2255         -    # set and why.
  2256         -
  2257         -    if test $tcl_ok = 0; then
  2258         -	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
  2259         -    fi
  2260         -
  2261         -    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
  2262         -    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
  2263         -
  2264         -    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
  2265         -    AC_HAVE_HEADERS(sys/param.h)
  2266         -])
  2267         -
  2268   2320   #--------------------------------------------------------------------
  2269   2321   # TEA_PATH_X
  2270   2322   #
  2271   2323   #	Locate the X11 header files and the X11 library archive.  Try
  2272   2324   #	the ac_path_x macro first, but if it doesn't find the X stuff
  2273   2325   #	(e.g. because there's no xmkmf program) then check through
  2274   2326   #	a list of possible directories.  Under some conditions the
................................................................................
  2276   2328   #	no include files, so double-check its result just to be safe.
  2277   2329   #
  2278   2330   #	This should be called after TEA_CONFIG_CFLAGS as setting the
  2279   2331   #	LIBS line can confuse some configure macro magic.
  2280   2332   #
  2281   2333   # Arguments:
  2282   2334   #	none
  2283         -#	
         2335  +#
  2284   2336   # Results:
  2285   2337   #
  2286   2338   #	Sets the following vars:
  2287   2339   #		XINCLUDES
  2288   2340   #		XLIBSW
  2289   2341   #		PKG_LIBS (appends to)
  2290         -#
  2291   2342   #--------------------------------------------------------------------
  2292   2343   
  2293   2344   AC_DEFUN([TEA_PATH_X], [
  2294   2345       if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
  2295   2346   	TEA_PATH_UNIX_X
  2296   2347       fi
  2297   2348   ])
  2298   2349   
  2299   2350   AC_DEFUN([TEA_PATH_UNIX_X], [
  2300   2351       AC_PATH_X
  2301   2352       not_really_there=""
  2302   2353       if test "$no_x" = ""; then
  2303   2354   	if test "$x_includes" = ""; then
  2304         -	    AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
         2355  +	    AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
  2305   2356   	else
  2306         -	    if test ! -r $x_includes/X11/Intrinsic.h; then
         2357  +	    if test ! -r $x_includes/X11/Xlib.h; then
  2307   2358   		not_really_there="yes"
  2308   2359   	    fi
  2309   2360   	fi
  2310   2361       fi
  2311   2362       if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
  2312   2363   	AC_MSG_CHECKING([for X11 header files])
  2313   2364   	found_xincludes="no"
  2314         -	AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
         2365  +	AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
  2315   2366   	if test "$found_xincludes" = "no"; then
  2316   2367   	    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"
  2317   2368   	    for i in $dirs ; do
  2318         -		if test -r $i/X11/Intrinsic.h; then
         2369  +		if test -r $i/X11/Xlib.h; then
  2319   2370   		    AC_MSG_RESULT([$i])
  2320   2371   		    XINCLUDES=" -I$i"
  2321   2372   		    found_xincludes="yes"
  2322   2373   		    break
  2323   2374   		fi
  2324   2375   	    done
  2325   2376   	fi
  2326   2377       else
  2327   2378   	if test "$x_includes" != ""; then
  2328   2379   	    XINCLUDES="-I$x_includes"
  2329   2380   	    found_xincludes="yes"
  2330   2381   	fi
  2331   2382       fi
  2332         -    if test found_xincludes = "no"; then
         2383  +    if test "$found_xincludes" = "no"; then
  2333   2384   	AC_MSG_RESULT([couldn't find any!])
  2334   2385       fi
  2335   2386   
  2336   2387       if test "$no_x" = yes; then
  2337   2388   	AC_MSG_CHECKING([for X11 libraries])
  2338   2389   	XLIBSW=nope
  2339   2390   	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"
  2340   2391   	for i in $dirs ; do
  2341         -	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then
         2392  +	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
  2342   2393   		AC_MSG_RESULT([$i])
  2343   2394   		XLIBSW="-L$i -lX11"
  2344   2395   		x_libraries="$i"
  2345   2396   		break
  2346   2397   	    fi
  2347   2398   	done
  2348   2399       else
................................................................................
  2355   2406       if test "$XLIBSW" = nope ; then
  2356   2407   	AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
  2357   2408       fi
  2358   2409       if test "$XLIBSW" = nope ; then
  2359   2410   	AC_MSG_RESULT([could not find any!  Using -lX11.])
  2360   2411   	XLIBSW=-lX11
  2361   2412       fi
         2413  +    # TEA specific:
  2362   2414       if test x"${XLIBSW}" != x ; then
  2363   2415   	PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
  2364   2416       fi
  2365   2417   ])
  2366   2418   
  2367   2419   #--------------------------------------------------------------------
  2368   2420   # TEA_BLOCKING_STYLE
  2369   2421   #
  2370   2422   #	The statements below check for systems where POSIX-style
  2371         -#	non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. 
         2423  +#	non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
  2372   2424   #	On these systems (mostly older ones), use the old BSD-style
  2373   2425   #	FIONBIO approach instead.
  2374   2426   #
  2375   2427   # Arguments:
  2376   2428   #	none
  2377         -#	
         2429  +#
  2378   2430   # Results:
  2379   2431   #
  2380   2432   #	Defines some of the following vars:
  2381   2433   #		HAVE_SYS_IOCTL_H
  2382   2434   #		HAVE_SYS_FILIO_H
  2383   2435   #		USE_FIONBIO
  2384   2436   #		O_NONBLOCK
  2385         -#
  2386   2437   #--------------------------------------------------------------------
  2387   2438   
  2388   2439   AC_DEFUN([TEA_BLOCKING_STYLE], [
  2389   2440       AC_CHECK_HEADERS(sys/ioctl.h)
  2390   2441       AC_CHECK_HEADERS(sys/filio.h)
  2391   2442       TEA_CONFIG_SYSTEM
  2392   2443       AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
  2393   2444       case $system in
  2394         -	# There used to be code here to use FIONBIO under AIX.  However, it
  2395         -	# was reported that FIONBIO doesn't work under AIX 3.2.5.  Since
  2396         -	# using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
  2397         -	# code (JO, 5/31/97).
  2398         -
  2399   2445   	OSF*)
  2400         -	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
  2401         -	    AC_MSG_RESULT([FIONBIO])
  2402         -	    ;;
  2403         -	SunOS-4*)
  2404   2446   	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
  2405   2447   	    AC_MSG_RESULT([FIONBIO])
  2406   2448   	    ;;
  2407   2449   	*)
  2408   2450   	    AC_MSG_RESULT([O_NONBLOCK])
  2409   2451   	    ;;
  2410   2452       esac
  2411   2453   ])
  2412   2454   
  2413   2455   #--------------------------------------------------------------------
  2414         -# TEA_TIME_HANLDER
         2456  +# TEA_TIME_HANDLER
  2415   2457   #
  2416   2458   #	Checks how the system deals with time.h, what time structures
  2417   2459   #	are used on the system, and what fields the structures have.
  2418   2460   #
  2419   2461   # Arguments:
  2420   2462   #	none
  2421         -#	
         2463  +#
  2422   2464   # Results:
  2423   2465   #
  2424   2466   #	Defines some of the following vars:
  2425   2467   #		USE_DELTA_FOR_TZ
  2426   2468   #		HAVE_TM_GMTOFF
  2427   2469   #		HAVE_TM_TZADJ
  2428   2470   #		HAVE_TIMEZONE_VAR
  2429         -#
  2430   2471   #--------------------------------------------------------------------
  2431   2472   
  2432   2473   AC_DEFUN([TEA_TIME_HANDLER], [
  2433   2474       AC_CHECK_HEADERS(sys/time.h)
  2434   2475       AC_HEADER_TIME
  2435   2476       AC_STRUCT_TIMEZONE
  2436   2477   
................................................................................
  2486   2527   #	and if the problem exists use a substitute procedure
  2487   2528   #	"fixstrtod" (provided by Tcl) that corrects the error.
  2488   2529   #	Also, on Compaq's Tru64 Unix 5.0,
  2489   2530   #	strtod(" ") returns 0.0 instead of a failure to convert.
  2490   2531   #
  2491   2532   # Arguments:
  2492   2533   #	none
  2493         -#	
         2534  +#
  2494   2535   # Results:
  2495   2536   #
  2496   2537   #	Might defines some of the following vars:
  2497   2538   #		strtod (=fixstrtod)
  2498         -#
  2499   2539   #--------------------------------------------------------------------
  2500   2540   
  2501   2541   AC_DEFUN([TEA_BUGGY_STRTOD], [
  2502   2542       AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
  2503   2543       if test "$tcl_strtod" = 1; then
  2504   2544   	AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
  2505   2545   	    AC_TRY_RUN([
................................................................................
  2527   2567   	    AC_LIBOBJ([fixstrtod])
  2528   2568   	    USE_COMPAT=1
  2529   2569   	    AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
  2530   2570   	fi
  2531   2571       fi
  2532   2572   ])
  2533   2573   
  2534         -#--------------------------------------------------------------------
  2535         -# TEA_TCL_LINK_LIBS
  2536         -#
  2537         -#	Search for the libraries needed to link the Tcl shell.
  2538         -#	Things like the math library (-lm) and socket stuff (-lsocket vs.
  2539         -#	-lnsl) are dealt with here.
  2540         -#
  2541         -# Arguments:
  2542         -#	Requires the following vars to be set in the Makefile:
  2543         -#		DL_LIBS
  2544         -#		LIBS
  2545         -#		MATH_LIBS
  2546         -#	
  2547         -# Results:
  2548         -#
  2549         -#	Subst's the following var:
  2550         -#		TCL_LIBS
  2551         -#		MATH_LIBS
  2552         -#
  2553         -#	Might append to the following vars:
  2554         -#		LIBS
  2555         -#
  2556         -#	Might define the following vars:
  2557         -#		HAVE_NET_ERRNO_H
  2558         -#
  2559         -#--------------------------------------------------------------------
  2560         -
  2561         -AC_DEFUN([TEA_TCL_LINK_LIBS], [
  2562         -    #--------------------------------------------------------------------
  2563         -    # On a few very rare systems, all of the libm.a stuff is
  2564         -    # already in libc.a.  Set compiler flags accordingly.
  2565         -    # Also, Linux requires the "ieee" library for math to work
  2566         -    # right (and it must appear before "-lm").
  2567         -    #--------------------------------------------------------------------
  2568         -
  2569         -    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
  2570         -    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
  2571         -
  2572         -    #--------------------------------------------------------------------
  2573         -    # Interactive UNIX requires -linet instead of -lsocket, plus it
  2574         -    # needs net/errno.h to define the socket-related error codes.
  2575         -    #--------------------------------------------------------------------
  2576         -
  2577         -    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
  2578         -    AC_CHECK_HEADER(net/errno.h, [
  2579         -	AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
  2580         -
  2581         -    #--------------------------------------------------------------------
  2582         -    #	Check for the existence of the -lsocket and -lnsl libraries.
  2583         -    #	The order here is important, so that they end up in the right
  2584         -    #	order in the command line generated by make.  Here are some
  2585         -    #	special considerations:
  2586         -    #	1. Use "connect" and "accept" to check for -lsocket, and
  2587         -    #	   "gethostbyname" to check for -lnsl.
  2588         -    #	2. Use each function name only once:  can't redo a check because
  2589         -    #	   autoconf caches the results of the last check and won't redo it.
  2590         -    #	3. Use -lnsl and -lsocket only if they supply procedures that
  2591         -    #	   aren't already present in the normal libraries.  This is because
  2592         -    #	   IRIX 5.2 has libraries, but they aren't needed and they're
  2593         -    #	   bogus:  they goof up name resolution if used.
  2594         -    #	4. On some SVR4 systems, can't use -lsocket without -lnsl too.
  2595         -    #	   To get around this problem, check for both libraries together
  2596         -    #	   if -lsocket doesn't work by itself.
  2597         -    #--------------------------------------------------------------------
  2598         -
  2599         -    tcl_checkBoth=0
  2600         -    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
  2601         -    if test "$tcl_checkSocket" = 1; then
  2602         -	AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
  2603         -	    LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
  2604         -    fi
  2605         -    if test "$tcl_checkBoth" = 1; then
  2606         -	tk_oldLibs=$LIBS
  2607         -	LIBS="$LIBS -lsocket -lnsl"
  2608         -	AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
  2609         -    fi
  2610         -    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
  2611         -	    [LIBS="$LIBS -lnsl"])])
  2612         -    
  2613         -    # Don't perform the eval of the libraries here because DL_LIBS
  2614         -    # won't be set until we call TEA_CONFIG_CFLAGS
  2615         -
  2616         -    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
  2617         -    AC_SUBST(TCL_LIBS)
  2618         -    AC_SUBST(MATH_LIBS)
  2619         -])
  2620         -
  2621   2574   #--------------------------------------------------------------------
  2622   2575   # TEA_TCL_EARLY_FLAGS
  2623   2576   #
  2624   2577   #	Check for what flags are needed to be passed so the correct OS
  2625   2578   #	features are available.
  2626   2579   #
  2627   2580   # Arguments:
  2628   2581   #	None
  2629         -#	
         2582  +#
  2630   2583   # Results:
  2631   2584   #
  2632   2585   #	Might define the following vars:
  2633   2586   #		_ISOC99_SOURCE
  2634   2587   #		_LARGEFILE64_SOURCE
  2635   2588   #		_LARGEFILE_SOURCE64
  2636         -#
  2637   2589   #--------------------------------------------------------------------
  2638   2590   
  2639   2591   AC_DEFUN([TEA_TCL_EARLY_FLAG],[
  2640   2592       AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
  2641   2593   	AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
  2642   2594   	    AC_TRY_COMPILE([[#define ]$1[ 1
  2643   2595   ]$2], $3,
................................................................................
  2668   2620   #--------------------------------------------------------------------
  2669   2621   # TEA_TCL_64BIT_FLAGS
  2670   2622   #
  2671   2623   #	Check for what is defined in the way of 64-bit features.
  2672   2624   #
  2673   2625   # Arguments:
  2674   2626   #	None
  2675         -#	
         2627  +#
  2676   2628   # Results:
  2677   2629   #
  2678   2630   #	Might define the following vars:
  2679   2631   #		TCL_WIDE_INT_IS_LONG
  2680   2632   #		TCL_WIDE_INT_TYPE
  2681   2633   #		HAVE_STRUCT_DIRENT64
  2682   2634   #		HAVE_STRUCT_STAT64
  2683   2635   #		HAVE_TYPE_OFF64_T
  2684         -#
  2685   2636   #--------------------------------------------------------------------
  2686   2637   
  2687   2638   AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
  2688   2639       AC_MSG_CHECKING([for 64-bit integer type])
  2689   2640       AC_CACHE_VAL(tcl_cv_type_64bit,[
  2690   2641   	tcl_cv_type_64bit=none
  2691   2642   	# See if the compiler knows natively about __int64
  2692   2643   	AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
  2693   2644   	    tcl_type_64bit=__int64, tcl_type_64bit="long long")
  2694   2645   	# See if we should use long anyway  Note that we substitute in the
  2695   2646   	# type that is our current guess for a 64-bit type inside this check
  2696   2647   	# program, so it should be modified only carefully...
  2697         -        AC_TRY_COMPILE(,[switch (0) { 
  2698         -            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; 
         2648  +        AC_TRY_COMPILE(,[switch (0) {
         2649  +            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
  2699   2650           }],tcl_cv_type_64bit=${tcl_type_64bit})])
  2700   2651       if test "${tcl_cv_type_64bit}" = none ; then
  2701   2652   	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
  2702   2653   	AC_MSG_RESULT([using long])
  2703   2654       elif test "${tcl_cv_type_64bit}" = "__int64" \
  2704   2655   		-a "${TEA_PLATFORM}" = "windows" ; then
  2705         -	# We actually want to use the default tcl.h checks in this
  2706         -	# case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
         2656  +	# TEA specific: We actually want to use the default tcl.h checks in
         2657  +	# this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
  2707   2658   	AC_MSG_RESULT([using Tcl header defaults])
  2708   2659       else
  2709   2660   	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
  2710   2661   	    [What type should be used to define wide integers?])
  2711   2662   	AC_MSG_RESULT([${tcl_cv_type_64bit}])
  2712   2663   
  2713   2664   	# Now check for auxiliary declarations
  2714   2665   	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
  2715   2666   	    AC_TRY_COMPILE([#include <sys/types.h>
  2716         -#include <sys/dirent.h>],[struct dirent64 p;],
         2667  +#include <dirent.h>],[struct dirent64 p;],
  2717   2668   		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
  2718   2669   	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
  2719   2670   	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
  2720   2671   	fi
  2721   2672   
  2722   2673   	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
  2723   2674   	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
................................................................................
  2777   2728   # EXEEXT
  2778   2729   #	Select the executable extension based on the host type.  This
  2779   2730   #	is a lightweight replacement for AC_EXEEXT that doesn't require
  2780   2731   #	a compiler.
  2781   2732   #------------------------------------------------------------------------
  2782   2733   
  2783   2734   AC_DEFUN([TEA_INIT], [
  2784         -    # TEA extensions pass this us the version of TEA they think they
  2785         -    # are compatible with.
  2786         -    TEA_VERSION="3.6"
         2735  +    TEA_VERSION="3.13"
  2787   2736   
  2788         -    AC_MSG_CHECKING([for correct TEA configuration])
         2737  +    AC_MSG_CHECKING([TEA configuration])
  2789   2738       if test x"${PACKAGE_NAME}" = x ; then
  2790   2739   	AC_MSG_ERROR([
  2791         -The PACKAGE_NAME variable must be defined by your TEA configure.in])
         2740  +The PACKAGE_NAME variable must be defined by your TEA configure.ac])
  2792   2741       fi
  2793         -    if test x"$1" = x ; then
  2794         -	AC_MSG_ERROR([
  2795         -TEA version not specified.])
  2796         -    elif test "$1" != "${TEA_VERSION}" ; then
  2797         -	AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
  2798         -    else
  2799         -	AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
         2742  +    AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
         2743  +
         2744  +    # If the user did not set CFLAGS, set it now to keep macros
         2745  +    # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
         2746  +    if test "${CFLAGS+set}" != "set" ; then
         2747  +	CFLAGS=""
  2800   2748       fi
         2749  +
  2801   2750       case "`uname -s`" in
  2802         -	*win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)
  2803         -	    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
         2751  +	*win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
         2752  +	    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
  2804   2753   	    EXEEXT=".exe"
  2805   2754   	    TEA_PLATFORM="windows"
  2806   2755   	    ;;
         2756  +	*CYGWIN_*)
         2757  +	    EXEEXT=".exe"
         2758  +	    # CYGPATH and TEA_PLATFORM are determined later in LOAD_TCLCONFIG
         2759  +	    ;;
  2807   2760   	*)
  2808   2761   	    CYGPATH=echo
  2809         -	    EXEEXT=""
  2810         -	    TEA_PLATFORM="unix"
         2762  +	    # Maybe we are cross-compiling....
         2763  +	    case ${host_alias} in
         2764  +		*mingw32*)
         2765  +		EXEEXT=".exe"
         2766  +		TEA_PLATFORM="windows"
         2767  +		;;
         2768  +	    *)
         2769  +		EXEEXT=""
         2770  +		TEA_PLATFORM="unix"
         2771  +		;;
         2772  +	    esac
  2811   2773   	    ;;
  2812   2774       esac
  2813   2775   
  2814   2776       # Check if exec_prefix is set. If not use fall back to prefix.
  2815   2777       # Note when adjusted, so that TEA_PREFIX can correct for this.
  2816   2778       # This is needed for recursive configures, since autoconf propagates
  2817   2779       # $prefix, but not $exec_prefix (doh!).
  2818   2780       if test x$exec_prefix = xNONE ; then
  2819   2781   	exec_prefix_default=yes
  2820   2782   	exec_prefix=$prefix
  2821   2783       fi
         2784  +
         2785  +    AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
  2822   2786   
  2823   2787       AC_SUBST(EXEEXT)
  2824   2788       AC_SUBST(CYGPATH)
  2825   2789   
  2826   2790       # This package name must be replaced statically for AC_SUBST to work
  2827   2791       AC_SUBST(PKG_LIB_FILE)
  2828   2792       # Substitute STUB_LIB_FILE in case package creates a stub library too.
................................................................................
  2833   2797       AC_SUBST(PKG_STUB_SOURCES)
  2834   2798       AC_SUBST(PKG_STUB_OBJECTS)
  2835   2799       AC_SUBST(PKG_TCL_SOURCES)
  2836   2800       AC_SUBST(PKG_HEADERS)
  2837   2801       AC_SUBST(PKG_INCLUDES)
  2838   2802       AC_SUBST(PKG_LIBS)
  2839   2803       AC_SUBST(PKG_CFLAGS)
         2804  +
         2805  +    # Configure the installer.
         2806  +    TEA_INSTALLER
  2840   2807   ])
  2841   2808   
  2842   2809   #------------------------------------------------------------------------
  2843   2810   # TEA_ADD_SOURCES --
  2844   2811   #
  2845   2812   #	Specify one or more source files.  Users should check for
  2846   2813   #	the right platform before adding to their list.
................................................................................
  2863   2830   	    [\$]*)
  2864   2831   		# allow $-var names
  2865   2832   		PKG_SOURCES="$PKG_SOURCES $i"
  2866   2833   		PKG_OBJECTS="$PKG_OBJECTS $i"
  2867   2834   		;;
  2868   2835   	    *)
  2869   2836   		# check for existence - allows for generic/win/unix VPATH
         2837  +		# To add more dirs here (like 'src'), you have to update VPATH
         2838  +		# in Makefile.in as well
  2870   2839   		if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
  2871   2840   		    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
         2841  +		    -a ! -f "${srcdir}/macosx/$i" \
  2872   2842   		    ; then
  2873   2843   		    AC_MSG_ERROR([could not find source file '$i'])
  2874   2844   		fi
  2875   2845   		PKG_SOURCES="$PKG_SOURCES $i"
  2876   2846   		# this assumes it is in a VPATH dir
  2877   2847   		i=`basename $i`
  2878   2848   		# handle user calling this before or after TEA_SETUP_COMPILER
................................................................................
  2908   2878   #------------------------------------------------------------------------
  2909   2879   AC_DEFUN([TEA_ADD_STUB_SOURCES], [
  2910   2880       vars="$@"
  2911   2881       for i in $vars; do
  2912   2882   	# check for existence - allows for generic/win/unix VPATH
  2913   2883   	if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
  2914   2884   	    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
         2885  +	    -a ! -f "${srcdir}/macosx/$i" \
  2915   2886   	    ; then
  2916   2887   	    AC_MSG_ERROR([could not find stub source file '$i'])
  2917   2888   	fi
  2918   2889   	PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
  2919   2890   	# this assumes it is in a VPATH dir
  2920   2891   	i=`basename $i`
  2921   2892   	# handle user calling this before or after TEA_SETUP_COMPILER
................................................................................
  3046   3017   #	Defines and substs the following vars:
  3047   3018   #		PKG_CFLAGS
  3048   3019   #------------------------------------------------------------------------
  3049   3020   AC_DEFUN([TEA_ADD_CFLAGS], [
  3050   3021       PKG_CFLAGS="$PKG_CFLAGS $@"
  3051   3022       AC_SUBST(PKG_CFLAGS)
  3052   3023   ])
         3024  +
         3025  +#------------------------------------------------------------------------
         3026  +# TEA_ADD_CLEANFILES --
         3027  +#
         3028  +#	Specify one or more CLEANFILES.
         3029  +#
         3030  +# Arguments:
         3031  +#	one or more file names to clean target
         3032  +#
         3033  +# Results:
         3034  +#
         3035  +#	Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
         3036  +#------------------------------------------------------------------------
         3037  +AC_DEFUN([TEA_ADD_CLEANFILES], [
         3038  +    CLEANFILES="$CLEANFILES $@"
         3039  +])
  3053   3040   
  3054   3041   #------------------------------------------------------------------------
  3055   3042   # TEA_PREFIX --
  3056   3043   #
  3057   3044   #	Handle the --prefix=... option by defaulting to what Tcl gave
  3058   3045   #
  3059   3046   # Arguments:
................................................................................
  3088   3075       fi
  3089   3076   ])
  3090   3077   
  3091   3078   #------------------------------------------------------------------------
  3092   3079   # TEA_SETUP_COMPILER_CC --
  3093   3080   #
  3094   3081   #	Do compiler checks the way we want.  This is just a replacement
  3095         -#	for AC_PROG_CC in TEA configure.in files to make them cleaner.
         3082  +#	for AC_PROG_CC in TEA configure.ac files to make them cleaner.
  3096   3083   #
  3097   3084   # Arguments:
  3098   3085   #	none
  3099   3086   #
  3100   3087   # Results:
  3101   3088   #
  3102   3089   #	Sets up CC var and other standard bits we need to make executables.
  3103   3090   #------------------------------------------------------------------------
  3104   3091   AC_DEFUN([TEA_SETUP_COMPILER_CC], [
  3105   3092       # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
  3106   3093       # in this macro, they need to go into TEA_SETUP_COMPILER instead.
  3107   3094   
  3108         -    # If the user did not set CFLAGS, set it now to keep
  3109         -    # the AC_PROG_CC macro from adding "-g -O2".
  3110         -    if test "${CFLAGS+set}" != "set" ; then
  3111         -	CFLAGS=""
  3112         -    fi
  3113         -
  3114   3095       AC_PROG_CC
  3115   3096       AC_PROG_CPP
  3116   3097   
  3117         -    AC_PROG_INSTALL
  3118         -
  3119   3098       #--------------------------------------------------------------------
  3120   3099       # Checks to see if the make program sets the $MAKE variable.
  3121   3100       #--------------------------------------------------------------------
  3122   3101   
  3123   3102       AC_PROG_MAKE_SET
  3124   3103   
  3125   3104       #--------------------------------------------------------------------
  3126   3105       # Find ranlib
  3127   3106       #--------------------------------------------------------------------
  3128   3107   
  3129         -    AC_PROG_RANLIB
         3108  +    AC_CHECK_TOOL(RANLIB, ranlib)
  3130   3109   
  3131   3110       #--------------------------------------------------------------------
  3132   3111       # Determines the correct binary file extension (.o, .obj, .exe etc.)
  3133   3112       #--------------------------------------------------------------------
  3134   3113   
  3135   3114       AC_OBJEXT
  3136   3115       AC_EXEEXT
................................................................................
  3170   3149       fi
  3171   3150   
  3172   3151       #--------------------------------------------------------------------
  3173   3152       # Common compiler flag setup
  3174   3153       #--------------------------------------------------------------------
  3175   3154   
  3176   3155       AC_C_BIGENDIAN
  3177         -    if test "${TEA_PLATFORM}" = "unix" ; then
  3178         -	TEA_TCL_LINK_LIBS
  3179         -	TEA_MISSING_POSIX_HEADERS
  3180         -	# Let the user call this, because if it triggers, they will
  3181         -	# need a compat/strtod.c that is correct.  Users can also
  3182         -	# use Tcl_GetDouble(FromObj) instead.
  3183         -	#TEA_BUGGY_STRTOD
  3184         -    fi
  3185   3156   ])
  3186   3157   
  3187   3158   #------------------------------------------------------------------------
  3188   3159   # TEA_MAKE_LIB --
  3189   3160   #
  3190   3161   #	Generate a line that can be used to build a shared/unshared library
  3191   3162   #	in a platform independent manner.
................................................................................
  3201   3172   #	CFLAGS -	Done late here to note disturb other AC macros
  3202   3173   #       MAKE_LIB -      Command to execute to build the Tcl library;
  3203   3174   #                       differs depending on whether or not Tcl is being
  3204   3175   #                       compiled as a shared library.
  3205   3176   #	MAKE_SHARED_LIB	Makefile rule for building a shared library
  3206   3177   #	MAKE_STATIC_LIB	Makefile rule for building a static library
  3207   3178   #	MAKE_STUB_LIB	Makefile rule for building a stub library
         3179  +#	VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
         3180  +#	VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
  3208   3181   #------------------------------------------------------------------------
  3209   3182   
  3210   3183   AC_DEFUN([TEA_MAKE_LIB], [
  3211   3184       if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
  3212   3185   	MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
  3213   3186   	MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
  3214         -	MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
         3187  +	AC_EGREP_CPP([manifest needed], [
         3188  +#if defined(_MSC_VER) && _MSC_VER >= 1400
         3189  +print("manifest needed")
         3190  +#endif
         3191  +	], [
         3192  +	# Could do a CHECK_PROG for mt, but should always be with MSVC8+
         3193  +	VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi"
         3194  +	VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi"
         3195  +	MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
         3196  +	TEA_ADD_CLEANFILES([*.manifest])
         3197  +	])
         3198  +	MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\[$]@ \$(PKG_STUB_OBJECTS)"
  3215   3199       else
  3216   3200   	MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
  3217   3201   	MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
  3218   3202   	MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
  3219   3203       fi
  3220   3204   
  3221   3205       if test "${SHARED_BUILD}" = "1" ; then
................................................................................
  3230   3214       # substituted. (@@@ Might not be necessary anymore)
  3231   3215       #--------------------------------------------------------------------
  3232   3216   
  3233   3217       if test "${TEA_PLATFORM}" = "windows" ; then
  3234   3218   	if test "${SHARED_BUILD}" = "1" ; then
  3235   3219   	    # We force the unresolved linking of symbols that are really in
  3236   3220   	    # the private libraries of Tcl and Tk.
  3237         -	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
  3238   3221   	    if test x"${TK_BIN_DIR}" != x ; then
  3239   3222   		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
  3240   3223   	    fi
  3241         -	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
         3224  +	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
         3225  +	    if test "$GCC" = "yes"; then
         3226  +		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
         3227  +	    fi
         3228  +	    eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
  3242   3229   	else
  3243         -	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
         3230  +	    eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
         3231  +	    if test "$GCC" = "yes"; then
         3232  +		PKG_LIB_FILE=lib${PKG_LIB_FILE}
         3233  +	    fi
  3244   3234   	fi
  3245   3235   	# Some packages build their own stubs libraries
  3246         -	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
         3236  +	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
  3247   3237   	if test "$GCC" = "yes"; then
  3248   3238   	    PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
  3249   3239   	fi
  3250   3240   	# These aren't needed on Windows (either MSVC or gcc)
  3251   3241   	RANLIB=:
  3252   3242   	RANLIB_STUB=:
  3253   3243       else
  3254   3244   	RANLIB_STUB="${RANLIB}"
  3255   3245   	if test "${SHARED_BUILD}" = "1" ; then
  3256   3246   	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
  3257   3247   	    if test x"${TK_BIN_DIR}" != x ; then
  3258   3248   		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
  3259   3249   	    fi
  3260         -	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
         3250  +	    eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
  3261   3251   	    RANLIB=:
  3262   3252   	else
  3263         -	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
         3253  +	    eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
  3264   3254   	fi
  3265   3255   	# Some packages build their own stubs libraries
  3266         -	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
         3256  +	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
  3267   3257       fi
  3268   3258   
  3269   3259       # These are escaped so that only CFLAGS is picked up at configure time.
  3270   3260       # The other values will be substituted at make time.
  3271   3261       CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
  3272   3262       if test "${SHARED_BUILD}" = "1" ; then
  3273   3263   	CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
................................................................................
  3274   3264       fi
  3275   3265   
  3276   3266       AC_SUBST(MAKE_LIB)
  3277   3267       AC_SUBST(MAKE_SHARED_LIB)
  3278   3268       AC_SUBST(MAKE_STATIC_LIB)
  3279   3269       AC_SUBST(MAKE_STUB_LIB)
  3280   3270       AC_SUBST(RANLIB_STUB)
         3271  +    AC_SUBST(VC_MANIFEST_EMBED_DLL)
         3272  +    AC_SUBST(VC_MANIFEST_EMBED_EXE)
  3281   3273   ])
  3282   3274   
  3283   3275   #------------------------------------------------------------------------
  3284   3276   # TEA_LIB_SPEC --
  3285   3277   #
  3286   3278   #	Compute the name of an existing object library located in libdir
  3287   3279   #	from the given base name and produce the appropriate linker flags.
................................................................................
  3321   3313       for i in \
  3322   3314   	    `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
  3323   3315   	    `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
  3324   3316   	    `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
  3325   3317   	    `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
  3326   3318   	    `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
  3327   3319   	    `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
         3320  +	    `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
         3321  +	    `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
  3328   3322   	    `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
  3329   3323   	    `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
  3330   3324   	if test -f "$i" ; then
  3331   3325   	    tea_lib_name_dir=`dirname $i`
  3332   3326   	    $1_LIB_NAME=`basename $i`
  3333   3327   	    $1_LIB_PATH_NAME=$i
  3334   3328   	    break
................................................................................
  3356   3350   #
  3357   3351   #	Locate the private Tcl include files
  3358   3352   #
  3359   3353   # Arguments:
  3360   3354   #
  3361   3355   #	Requires:
  3362   3356   #		TCL_SRC_DIR	Assumes that TEA_LOAD_TCLCONFIG has
  3363         -#				 already been called.
         3357  +#				already been called.
  3364   3358   #
  3365   3359   # Results:
  3366   3360   #
  3367         -#	Substs the following vars:
         3361  +#	Substitutes the following vars:
  3368   3362   #		TCL_TOP_DIR_NATIVE
  3369         -#		TCL_GENERIC_DIR_NATIVE
  3370         -#		TCL_UNIX_DIR_NATIVE
  3371         -#		TCL_WIN_DIR_NATIVE
  3372         -#		TCL_BMAP_DIR_NATIVE
  3373         -#		TCL_TOOL_DIR_NATIVE
  3374         -#		TCL_PLATFORM_DIR_NATIVE
  3375         -#		TCL_BIN_DIR_NATIVE
  3376   3363   #		TCL_INCLUDES
  3377   3364   #------------------------------------------------------------------------
  3378   3365   
  3379   3366   AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
         3367  +    # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
         3368  +    AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
  3380   3369       AC_MSG_CHECKING([for Tcl private include files])
  3381   3370   
  3382   3371       TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
  3383   3372       TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
  3384         -    TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
  3385         -    TCL_UNIX_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
  3386         -    TCL_WIN_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
  3387         -    TCL_BMAP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/bitmaps\"
  3388         -    TCL_TOOL_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/tools\"
  3389         -    TCL_COMPAT_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/compat\"
  3390   3373   
  3391         -    if test "${TEA_PLATFORM}" = "windows"; then
  3392         -	TCL_PLATFORM_DIR_NATIVE=${TCL_WIN_DIR_NATIVE}
         3374  +    # Check to see if tcl<Plat>Port.h isn't already with the public headers
         3375  +    # Don't look for tclInt.h because that resides with tcl.h in the core
         3376  +    # sources, but the <plat>Port headers are in a different directory
         3377  +    if test "${TEA_PLATFORM}" = "windows" -a \
         3378  +	-f "${ac_cv_c_tclh}/tclWinPort.h"; then
         3379  +	result="private headers found with public headers"
         3380  +    elif test "${TEA_PLATFORM}" = "unix" -a \
         3381  +	-f "${ac_cv_c_tclh}/tclUnixPort.h"; then
         3382  +	result="private headers found with public headers"
  3393   3383       else
  3394         -	TCL_PLATFORM_DIR_NATIVE=${TCL_UNIX_DIR_NATIVE}
  3395         -    fi
  3396         -    # We want to ensure these are substituted so as not to require
  3397         -    # any *_NATIVE vars be defined in the Makefile
  3398         -    TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
  3399         -    if test "`uname -s`" = "Darwin"; then
  3400         -        # If Tcl was built as a framework, attempt to use
  3401         -        # the framework's Headers and PrivateHeaders directories
  3402         -        case ${TCL_DEFS} in
  3403         -	    *TCL_FRAMEWORK*)
  3404         -	        if test -d "${TCL_BIN_DIR}/Headers" -a -d "${TCL_BIN_DIR}/PrivateHeaders"; then
  3405         -	        TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"; else
  3406         -	        TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"; fi
  3407         -	        ;;
  3408         -	esac
  3409         -    else
  3410         -	if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
  3411         -	    AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
         3384  +	TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
         3385  +	if test "${TEA_PLATFORM}" = "windows"; then
         3386  +	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
         3387  +	else
         3388  +	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
         3389  +	fi
         3390  +	# Overwrite the previous TCL_INCLUDES as this should capture both
         3391  +	# public and private headers in the same set.
         3392  +	# We want to ensure these are substituted so as not to require
         3393  +	# any *_NATIVE vars be defined in the Makefile
         3394  +	TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
         3395  +	if test "`uname -s`" = "Darwin"; then
         3396  +            # If Tcl was built as a framework, attempt to use
         3397  +            # the framework's Headers and PrivateHeaders directories
         3398  +            case ${TCL_DEFS} in
         3399  +	    	*TCL_FRAMEWORK*)
         3400  +		    if test -d "${TCL_BIN_DIR}/Headers" -a \
         3401  +			    -d "${TCL_BIN_DIR}/PrivateHeaders"; then
         3402  +			TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
         3403  +		    else
         3404  +			TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
         3405  +		    fi
         3406  +	            ;;
         3407  +	    esac
         3408  +	    result="Using ${TCL_INCLUDES}"
         3409  +	else
         3410  +	    if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
         3411  +		AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
         3412  +	    fi
         3413  +	    result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
  3412   3414   	fi
  3413   3415       fi
  3414   3416   
  3415         -
  3416   3417       AC_SUBST(TCL_TOP_DIR_NATIVE)
  3417         -    AC_SUBST(TCL_GENERIC_DIR_NATIVE)
  3418         -    AC_SUBST(TCL_UNIX_DIR_NATIVE)
  3419         -    AC_SUBST(TCL_WIN_DIR_NATIVE)
  3420         -    AC_SUBST(TCL_BMAP_DIR_NATIVE)
  3421         -    AC_SUBST(TCL_TOOL_DIR_NATIVE)
  3422         -    AC_SUBST(TCL_PLATFORM_DIR_NATIVE)
  3423   3418   
  3424   3419       AC_SUBST(TCL_INCLUDES)
  3425         -    AC_MSG_RESULT([Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}])
         3420  +    AC_MSG_RESULT([${result}])
  3426   3421   ])
  3427   3422   
  3428   3423   #------------------------------------------------------------------------
  3429   3424   # TEA_PUBLIC_TCL_HEADERS --
  3430   3425   #
  3431   3426   #	Locate the installed public Tcl header files
  3432   3427   #
................................................................................
  3437   3432   #	CYGPATH must be set
  3438   3433   #
  3439   3434   # Results:
  3440   3435   #
  3441   3436   #	Adds a --with-tclinclude switch to configure.
  3442   3437   #	Result is cached.
  3443   3438   #
  3444         -#	Substs the following vars:
         3439  +#	Substitutes the following vars:
  3445   3440   #		TCL_INCLUDES
  3446   3441   #------------------------------------------------------------------------
  3447   3442   
  3448   3443   AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
  3449   3444       AC_MSG_CHECKING([for Tcl public headers])
  3450   3445   
  3451   3446       AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
................................................................................
  3456   3451   	if test x"${with_tclinclude}" != x ; then
  3457   3452   	    if test -f "${with_tclinclude}/tcl.h" ; then
  3458   3453   		ac_cv_c_tclh=${with_tclinclude}
  3459   3454   	    else
  3460   3455   		AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
  3461   3456   	    fi
  3462   3457   	else
         3458  +	    list=""
  3463   3459   	    if test "`uname -s`" = "Darwin"; then
  3464   3460   		# If Tcl was built as a framework, attempt to use
  3465   3461   		# the framework's Headers directory
  3466   3462   		case ${TCL_DEFS} in
  3467   3463   		    *TCL_FRAMEWORK*)
  3468   3464   			list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
  3469   3465   			;;
................................................................................
  3526   3522   #
  3527   3523   #	Requires:
  3528   3524   #		TK_SRC_DIR	Assumes that TEA_LOAD_TKCONFIG has
  3529   3525   #				 already been called.
  3530   3526   #
  3531   3527   # Results:
  3532   3528   #
  3533         -#	Substs the following vars:
         3529  +#	Substitutes the following vars:
  3534   3530   #		TK_INCLUDES
  3535   3531   #------------------------------------------------------------------------
  3536   3532   
  3537   3533   AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
         3534  +    # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
         3535  +    AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
  3538   3536       AC_MSG_CHECKING([for Tk private include files])
  3539   3537   
  3540   3538       TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
  3541   3539       TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
  3542         -    TK_UNIX_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
  3543         -    TK_WIN_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
  3544         -    TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
  3545         -    TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
  3546         -    if test "${TEA_PLATFORM}" = "windows"; then
  3547         -	TK_PLATFORM_DIR_NATIVE=${TK_WIN_DIR_NATIVE}
         3540  +
         3541  +    # Check to see if tk<Plat>Port.h isn't already with the public headers
         3542  +    # Don't look for tkInt.h because that resides with tk.h in the core
         3543  +    # sources, but the <plat>Port headers are in a different directory
         3544  +    if test "${TEA_PLATFORM}" = "windows" -a \
         3545  +	-f "${ac_cv_c_tkh}/tkWinPort.h"; then
         3546  +	result="private headers found with public headers"
         3547  +    elif test "${TEA_PLATFORM}" = "unix" -a \
         3548  +	-f "${ac_cv_c_tkh}/tkUnixPort.h"; then
         3549  +	result="private headers found with public headers"
  3548   3550       else
  3549         -	TK_PLATFORM_DIR_NATIVE=${TK_UNIX_DIR_NATIVE}
  3550         -    fi
  3551         -    # We want to ensure these are substituted so as not to require
  3552         -    # any *_NATIVE vars be defined in the Makefile
  3553         -    TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
  3554         -    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
  3555         -	-o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
  3556         -	TK_INCLUDES="${TK_INCLUDES} -I${TK_XLIB_DIR_NATIVE}"
  3557         -    fi
  3558         -    if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
  3559         -	TK_INCLUDES="${TK_INCLUDES} -I${TK_SRC_DIR_NATIVE}/macosx"
  3560         -    fi
  3561         -    if test "`uname -s`" = "Darwin"; then
  3562         -        # If Tk was built as a framework, attempt to use
  3563         -        # the framework's Headers and PrivateHeaders directories
  3564         -        case ${TK_DEFS} in
  3565         -	    *TK_FRAMEWORK*)
  3566         -	        if test -d "${TK_BIN_DIR}/Headers" -a -d "${TK_BIN_DIR}/PrivateHeaders"; then
  3567         -	        TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"; fi
  3568         -	        ;;
  3569         -	esac
  3570         -    else
  3571         -	if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
  3572         -	    AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
         3551  +	TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
         3552  +	TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
         3553  +	if test "${TEA_PLATFORM}" = "windows"; then
         3554  +	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
         3555  +	else
         3556  +	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
         3557  +	fi
         3558  +	# Overwrite the previous TK_INCLUDES as this should capture both
         3559  +	# public and private headers in the same set.
         3560  +	# We want to ensure these are substituted so as not to require
         3561  +	# any *_NATIVE vars be defined in the Makefile
         3562  +	TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
         3563  +	# Detect and add ttk subdir
         3564  +	if test -d "${TK_SRC_DIR}/generic/ttk"; then
         3565  +	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
         3566  +	fi
         3567  +	if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
         3568  +	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
         3569  +	fi
         3570  +	if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
         3571  +	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
         3572  +	fi
         3573  +	if test "`uname -s`" = "Darwin"; then
         3574  +	    # If Tk was built as a framework, attempt to use
         3575  +	    # the framework's Headers and PrivateHeaders directories
         3576  +	    case ${TK_DEFS} in
         3577  +		*TK_FRAMEWORK*)
         3578  +			if test -d "${TK_BIN_DIR}/Headers" -a \
         3579  +				-d "${TK_BIN_DIR}/PrivateHeaders"; then
         3580  +			    TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
         3581  +			else
         3582  +			    TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
         3583  +			fi
         3584  +			;;
         3585  +	    esac
         3586  +	    result="Using ${TK_INCLUDES}"
         3587  +	else
         3588  +	    if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
         3589  +	       AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
         3590  +	    fi
         3591  +	    result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
  3573   3592   	fi
  3574   3593       fi
  3575   3594   
  3576   3595       AC_SUBST(TK_TOP_DIR_NATIVE)
  3577         -    AC_SUBST(TK_UNIX_DIR_NATIVE)
  3578         -    AC_SUBST(TK_WIN_DIR_NATIVE)
  3579         -    AC_SUBST(TK_GENERIC_DIR_NATIVE)
  3580   3596       AC_SUBST(TK_XLIB_DIR_NATIVE)
  3581         -    AC_SUBST(TK_PLATFORM_DIR_NATIVE)
  3582   3597   
  3583   3598       AC_SUBST(TK_INCLUDES)
  3584         -    AC_MSG_RESULT([Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}])
         3599  +    AC_MSG_RESULT([${result}])
  3585   3600   ])
  3586   3601   
  3587   3602   #------------------------------------------------------------------------
  3588   3603   # TEA_PUBLIC_TK_HEADERS --
  3589   3604   #
  3590   3605   #	Locate the installed public Tk header files
  3591   3606   #
................................................................................
  3596   3611   #	CYGPATH must be set
  3597   3612   #
  3598   3613   # Results:
  3599   3614   #
  3600   3615   #	Adds a --with-tkinclude switch to configure.
  3601   3616   #	Result is cached.
  3602   3617   #
  3603         -#	Substs the following vars:
         3618  +#	Substitutes the following vars:
  3604   3619   #		TK_INCLUDES
  3605   3620   #------------------------------------------------------------------------
  3606   3621   
  3607   3622   AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
  3608   3623       AC_MSG_CHECKING([for Tk public headers])
  3609   3624   
  3610   3625       AC_ARG_WITH(tkinclude, [  --with-tkinclude        directory containing the public Tk header files], with_tkinclude=${withval})
................................................................................
  3615   3630   	if test x"${with_tkinclude}" != x ; then
  3616   3631   	    if test -f "${with_tkinclude}/tk.h" ; then
  3617   3632   		ac_cv_c_tkh=${with_tkinclude}
  3618   3633   	    else
  3619   3634   		AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
  3620   3635   	    fi
  3621   3636   	else
         3637  +	    list=""
  3622   3638   	    if test "`uname -s`" = "Darwin"; then
  3623   3639   		# If Tk was built as a framework, attempt to use
  3624   3640   		# the framework's Headers directory.
  3625   3641   		case ${TK_DEFS} in
  3626   3642   		    *TK_FRAMEWORK*)
  3627   3643   			list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
  3628   3644   			;;
................................................................................
  3632   3648   	    # Look in the source dir only if Tk is not installed,
  3633   3649   	    # and in that situation, look there before installed locations.
  3634   3650   	    if test -f "${TK_BIN_DIR}/Makefile" ; then
  3635   3651   		list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
  3636   3652   	    fi
  3637   3653   
  3638   3654   	    # Check order: pkg --prefix location, Tk's --prefix location,
  3639         -	    # relative to directory of tkConfig.sh, Tcl's --prefix location, 
         3655  +	    # relative to directory of tkConfig.sh, Tcl's --prefix location,
  3640   3656   	    # relative to directory of tclConfig.sh.
  3641   3657   
  3642   3658   	    eval "temp_includedir=${includedir}"
  3643   3659   	    list="$list \
  3644   3660   		`ls -d ${temp_includedir}        2>/dev/null` \
  3645   3661   		`ls -d ${TK_PREFIX}/include      2>/dev/null` \
  3646   3662   		`ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
  3647   3663   		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
  3648   3664   		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
  3649   3665   	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
  3650   3666   		list="$list /usr/local/include /usr/include"
         3667  +		if test x"${TK_INCLUDE_SPEC}" != x ; then
         3668  +		    d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
         3669  +		    list="$list `ls -d ${d} 2>/dev/null`"
         3670  +		fi
  3651   3671   	    fi
  3652   3672   	    for i in $list ; do
  3653   3673   		if test -f "$i/tk.h" ; then
  3654   3674   		    ac_cv_c_tkh=$i
  3655   3675   		    break
  3656   3676   		fi
  3657   3677   	    done
................................................................................
  3670   3690   
  3671   3691       INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
  3672   3692   
  3673   3693       TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
  3674   3694   
  3675   3695       AC_SUBST(TK_INCLUDES)
  3676   3696   
  3677         -    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
  3678         -	-o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
         3697  +    if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
  3679   3698   	# On Windows and Aqua, we need the X compat headers
  3680   3699   	AC_MSG_CHECKING([for X11 header files])
  3681   3700   	if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
  3682   3701   	    INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
  3683   3702   	    TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
  3684   3703   	    AC_SUBST(TK_XINCLUDES)
  3685   3704   	fi
  3686   3705   	AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
  3687   3706       fi
  3688   3707   ])
  3689   3708   
  3690         -#------------------------------------------------------------------------
  3691         -# TEA_PROG_TCLSH
  3692         -#	Determine the fully qualified path name of the tclsh executable
  3693         -#	in the Tcl build directory or the tclsh installed in a bin
  3694         -#	directory. This macro will correctly determine the name
  3695         -#	of the tclsh executable even if tclsh has not yet been
  3696         -#	built in the build directory. The tclsh found is always
  3697         -#	associated with a tclConfig.sh file. This tclsh should be used
  3698         -#	only for running extension test cases. It should never be
  3699         -#	or generation of files (like pkgIndex.tcl) at build time.
  3700         -#
  3701         -# Arguments
  3702         -#	none
  3703         -#
  3704         -# Results
  3705         -#	Subst's the following values:
  3706         -#		TCLSH_PROG
  3707         -#------------------------------------------------------------------------
  3708         -
  3709         -AC_DEFUN([TEA_PROG_TCLSH], [
  3710         -    AC_MSG_CHECKING([for tclsh])
  3711         -    if test -f "${TCL_BIN_DIR}/Makefile" ; then
  3712         -        # tclConfig.sh is in Tcl build directory
  3713         -        if test "${TEA_PLATFORM}" = "windows"; then
  3714         -            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
  3715         -        else
  3716         -            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
  3717         -        fi
  3718         -    else
  3719         -        # tclConfig.sh is in install location
  3720         -        if test "${TEA_PLATFORM}" = "windows"; then
  3721         -            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
  3722         -        else
  3723         -            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
  3724         -        fi
  3725         -        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
  3726         -              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
  3727         -              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
  3728         -        for i in $list ; do
  3729         -            if test -f "$i/${TCLSH_PROG}" ; then
  3730         -                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
  3731         -                break
  3732         -            fi
  3733         -        done
  3734         -        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
  3735         -    fi
  3736         -    AC_MSG_RESULT([${TCLSH_PROG}])
  3737         -    AC_SUBST(TCLSH_PROG)
  3738         -])
  3739         -
  3740         -#------------------------------------------------------------------------
  3741         -# TEA_PROG_WISH
  3742         -#	Determine the fully qualified path name of the wish executable
  3743         -#	in the Tk build directory or the wish installed in a bin
  3744         -#	directory. This macro will correctly determine the name
  3745         -#	of the wish executable even if wish has not yet been
  3746         -#	built in the build directory. The wish found is always
  3747         -#	associated with a tkConfig.sh file. This wish should be used
  3748         -#	only for running extension test cases. It should never be
  3749         -#	or generation of files (like pkgIndex.tcl) at build time.
  3750         -#
  3751         -# Arguments
  3752         -#	none
  3753         -#
  3754         -# Results
  3755         -#	Subst's the following values:
  3756         -#		WISH_PROG
  3757         -#------------------------------------------------------------------------
  3758         -
  3759         -AC_DEFUN([TEA_PROG_WISH], [
  3760         -    AC_MSG_CHECKING([for wish])
  3761         -    if test -f "${TK_BIN_DIR}/Makefile" ; then
  3762         -        # tkConfig.sh is in Tk build directory
  3763         -        if test "${TEA_PLATFORM}" = "windows"; then
  3764         -            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
  3765         -        else
  3766         -            WISH_PROG="${TK_BIN_DIR}/wish"
  3767         -        fi
  3768         -    else
  3769         -        # tkConfig.sh is in install location
  3770         -        if test "${TEA_PLATFORM}" = "windows"; then
  3771         -            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
  3772         -        else
  3773         -            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
  3774         -        fi
  3775         -        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
  3776         -              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
  3777         -              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
  3778         -        for i in $list ; do
  3779         -            if test -f "$i/${WISH_PROG}" ; then
  3780         -                REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
  3781         -                break
  3782         -            fi
  3783         -        done
  3784         -        WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
  3785         -    fi
  3786         -    AC_MSG_RESULT([${WISH_PROG}])
  3787         -    AC_SUBST(WISH_PROG)
  3788         -])
  3789         -
  3790   3709   #------------------------------------------------------------------------
  3791   3710   # TEA_PATH_CONFIG --
  3792   3711   #
  3793   3712   #	Locate the ${1}Config.sh file and perform a sanity check on
  3794   3713   #	the ${1} compile flags.  These are used by packages like
  3795   3714   #	[incr Tk] that load *Config.sh files from more than Tcl and Tk.
  3796   3715   #
................................................................................
  3875   3794   	    # check in a few common install locations
  3876   3795   	    if test x"${ac_cv_c_$1config}" = x ; then
  3877   3796   		for i in `ls -d ${libdir} 2>/dev/null` \
  3878   3797   			`ls -d ${exec_prefix}/lib 2>/dev/null` \
  3879   3798   			`ls -d ${prefix}/lib 2>/dev/null` \
  3880   3799   			`ls -d /usr/local/lib 2>/dev/null` \
  3881   3800   			`ls -d /usr/contrib/lib 2>/dev/null` \
         3801  +			`ls -d /usr/pkg/lib 2>/dev/null` \
  3882   3802   			`ls -d /usr/lib 2>/dev/null` \
         3803  +			`ls -d /usr/lib64 2>/dev/null` \
  3883   3804   			; do
  3884   3805   		    if test -f "$i/$1Config.sh" ; then
  3885   3806   			ac_cv_c_$1config=`(cd $i; pwd)`
  3886   3807   			break
  3887   3808   		    fi
  3888   3809   		done
  3889   3810   	    fi
................................................................................
  3903   3824   
  3904   3825   #------------------------------------------------------------------------
  3905   3826   # TEA_LOAD_CONFIG --
  3906   3827   #
  3907   3828   #	Load the $1Config.sh file
  3908   3829   #
  3909   3830   # Arguments:
  3910         -#	
         3831  +#
  3911   3832   #	Requires the following vars to be set:
  3912   3833   #		$1_BIN_DIR
  3913   3834   #
  3914   3835   # Results:
  3915   3836   #
  3916         -#	Subst the following vars:
         3837  +#	Substitutes the following vars:
  3917   3838   #		$1_SRC_DIR
  3918   3839   #		$1_LIB_FILE
  3919   3840   #		$1_LIB_SPEC
  3920         -#
  3921   3841   #------------------------------------------------------------------------
  3922   3842   
  3923   3843   AC_DEFUN([TEA_LOAD_CONFIG], [
  3924   3844       AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
  3925   3845   
  3926   3846       if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
  3927   3847           AC_MSG_RESULT([loading])
................................................................................
  3940   3860       #
  3941   3861   
  3942   3862       if test -f "${$1_BIN_DIR}/Makefile" ; then
  3943   3863   	AC_MSG_WARN([Found Makefile - using build library specs for $1])
  3944   3864           $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
  3945   3865           $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
  3946   3866           $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
         3867  +        $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
         3868  +        $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
  3947   3869       fi
  3948   3870   
  3949   3871       AC_SUBST($1_VERSION)
  3950   3872       AC_SUBST($1_BIN_DIR)
  3951   3873       AC_SUBST($1_SRC_DIR)
  3952   3874   
  3953   3875       AC_SUBST($1_LIB_FILE)
  3954   3876       AC_SUBST($1_LIB_SPEC)
  3955   3877   
  3956   3878       AC_SUBST($1_STUB_LIB_FILE)
  3957   3879       AC_SUBST($1_STUB_LIB_SPEC)
  3958   3880       AC_SUBST($1_STUB_LIB_PATH)
         3881  +
         3882  +    # Allow the caller to prevent this auto-check by specifying any 2nd arg
         3883  +    AS_IF([test "x$2" = x], [
         3884  +	# Check both upper and lower-case variants
         3885  +	# If a dev wanted non-stubs libs, this function could take an option
         3886  +	# to not use _STUB in the paths below
         3887  +	AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
         3888  +	    [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
         3889  +	    [TEA_LOAD_CONFIG_LIB($1_STUB)])
         3890  +    ])
         3891  +])
         3892  +
         3893  +#------------------------------------------------------------------------
         3894  +# TEA_LOAD_CONFIG_LIB --
         3895  +#
         3896  +#	Helper function to load correct library from another extension's
         3897  +#	${PACKAGE}Config.sh.
         3898  +#
         3899  +# Results:
         3900  +#	Adds to LIBS the appropriate extension library
         3901  +#------------------------------------------------------------------------
         3902  +AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
         3903  +    AC_MSG_CHECKING([For $1 library for LIBS])
         3904  +    # This simplifies the use of stub libraries by automatically adding
         3905  +    # the stub lib to your path.  Normally this would add to SHLIB_LD_LIBS,
         3906  +    # but this is called before CONFIG_CFLAGS.  More importantly, this adds
         3907  +    # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
         3908  +    if test "x${$1_LIB_SPEC}" != "x" ; then
         3909  +	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
         3910  +	    TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
         3911  +	    AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
         3912  +	else
         3913  +	    TEA_ADD_LIBS([${$1_LIB_SPEC}])
         3914  +	    AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
         3915  +	fi
         3916  +    else
         3917  +	AC_MSG_RESULT([file not found])
         3918  +    fi
         3919  +])
         3920  +
         3921  +#------------------------------------------------------------------------
         3922  +# TEA_EXPORT_CONFIG --
         3923  +#
         3924  +#	Define the data to insert into the ${PACKAGE}Config.sh file
         3925  +#
         3926  +# Arguments:
         3927  +#
         3928  +#	Requires the following vars to be set:
         3929  +#		$1
         3930  +#
         3931  +# Results:
         3932  +#	Substitutes the following vars:
         3933  +#------------------------------------------------------------------------
         3934  +
         3935  +AC_DEFUN([TEA_EXPORT_CONFIG], [
         3936  +    #--------------------------------------------------------------------
         3937  +    # These are for $1Config.sh
         3938  +    #--------------------------------------------------------------------
         3939  +
         3940  +    # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
         3941  +    eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
         3942  +    if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
         3943  +	eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
         3944  +	eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
         3945  +    else
         3946  +	eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
         3947  +	eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
         3948  +    fi
         3949  +    $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
         3950  +    $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
         3951  +    $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
         3952  +    $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
         3953  +    $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
         3954  +    $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
         3955  +
         3956  +    AC_SUBST($1_BUILD_LIB_SPEC)
         3957  +    AC_SUBST($1_LIB_SPEC)
         3958  +    AC_SUBST($1_BUILD_STUB_LIB_SPEC)
         3959  +    AC_SUBST($1_STUB_LIB_SPEC)
         3960  +    AC_SUBST($1_BUILD_STUB_LIB_PATH)
         3961  +    AC_SUBST($1_STUB_LIB_PATH)
         3962  +
         3963  +    AC_SUBST(MAJOR_VERSION)
         3964  +    AC_SUBST(MINOR_VERSION)
         3965  +    AC_SUBST(PATCHLEVEL)
  3959   3966   ])
         3967  +
  3960   3968   
  3961   3969   #------------------------------------------------------------------------
  3962   3970   # TEA_PATH_CELIB --
  3963   3971   #
  3964   3972   #	Locate Keuchel's celib emulation layer for targeting Win/CE
  3965   3973   #
  3966   3974   # Arguments:
................................................................................
  4021   4029   	    CELIB_DIR=${ac_cv_c_celibconfig}
  4022   4030   	    CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
  4023   4031   	    AC_MSG_RESULT([found $CELIB_DIR])
  4024   4032   	fi
  4025   4033       fi
  4026   4034   ])
  4027   4035   
         4036  +#------------------------------------------------------------------------
         4037  +# TEA_INSTALLER --
         4038  +#
         4039  +#	Configure the installer.
         4040  +#
         4041  +# Arguments:
         4042  +#	none
         4043  +#
         4044  +# Results:
         4045  +#	Substitutes the following vars:
         4046  +#		INSTALL
         4047  +#		INSTALL_DATA_DIR
         4048  +#		INSTALL_DATA
         4049  +#		INSTALL_PROGRAM
         4050  +#		INSTALL_SCRIPT
         4051  +#		INSTALL_LIBRARY
         4052  +#------------------------------------------------------------------------
         4053  +
         4054  +AC_DEFUN([TEA_INSTALLER], [
         4055  +    INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
         4056  +    INSTALL_DATA_DIR='${INSTALL} -d -m 755'
         4057  +    INSTALL_DATA='${INSTALL} -m 644'
         4058  +    INSTALL_PROGRAM='${INSTALL} -m 755'
         4059  +    INSTALL_SCRIPT='${INSTALL} -m 755'
         4060  +
         4061  +    TEA_CONFIG_SYSTEM
         4062  +    case $system in
         4063  +	HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
         4064  +	      *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
         4065  +    esac
         4066  +
         4067  +    AC_SUBST(INSTALL)
         4068  +    AC_SUBST(INSTALL_DATA_DIR)
         4069  +    AC_SUBST(INSTALL_DATA)
         4070  +    AC_SUBST(INSTALL_PROGRAM)
         4071  +    AC_SUBST(INSTALL_SCRIPT)
         4072  +    AC_SUBST(INSTALL_LIBRARY)
         4073  +])
         4074  +
         4075  +###
         4076  +# Tip 430 - ZipFS Modifications
         4077  +###
         4078  +#------------------------------------------------------------------------
         4079  +# SC_ZIPFS_SUPPORT
         4080  +#	Locate a zip encoder installed on the system path, or none.
         4081  +#
         4082  +# Arguments:
         4083  +#	none
         4084  +#
         4085  +# Results:
         4086  +#	Substitutes the following vars:
         4087  +#		TCL_ZIP_FILE
         4088  +#		TCL_ZIPFS_SUPPORT
         4089  +#		TCL_ZIPFS_FLAG
         4090  +#		ZIP_PROG
         4091  +#------------------------------------------------------------------------
         4092  +
         4093  +#------------------------------------------------------------------------
         4094  +# SC_PROG_ZIP
         4095  +#	Locate a zip encoder installed on the system path, or none.
         4096  +#
         4097  +# Arguments:
         4098  +#	none
         4099  +#
         4100  +# Results:
         4101  +#	Substitutes the following vars:
         4102  +#		ZIP_PROG
         4103  +#       ZIP_PROG_OPTIONS
         4104  +#       ZIP_PROG_VFSSEARCH
         4105  +#       ZIP_INSTALL_OBJS
         4106  +#------------------------------------------------------------------------
         4107  +AC_DEFUN([TEA_ZIPFS_SUPPORT], [
         4108  +    AC_MSG_CHECKING([for zipfs support])
         4109  +    ZIP_PROG=""
         4110  +    ZIP_PROG_OPTIONS=""
         4111  +    ZIP_PROG_VFSSEARCH=""
         4112  +    INSTALL_MSGS=""
         4113  +    # If our native tclsh processes the "install" command line option
         4114  +    # we can use it to mint zip files
         4115  +    AS_IF([$TCLSH_PROG install],[
         4116  +      ZIP_PROG=${TCLSH_PROG}
         4117  +      ZIP_PROG_OPTIONS="install mkzip"
         4118  +      ZIP_PROG_VFSSEARCH="."
         4119  +      AC_MSG_RESULT([Can use Native Tclsh for Zip encoding])
         4120  +    ])
         4121  +    if test "x$ZIP_PROG" = "x" ; then
         4122  +        AC_CACHE_VAL(ac_cv_path_zip, [
         4123  +        search_path=`echo ${PATH} | sed -e 's/:/ /g'`
         4124  +        for dir in $search_path ; do
         4125  +            for j in `ls -r $dir/zip 2> /dev/null` \
         4126  +                `ls -r $dir/zip 2> /dev/null` ; do
         4127  +            if test x"$ac_cv_path_zip" = x ; then
         4128  +                if test -f "$j" ; then
         4129  +                ac_cv_path_zip=$j
         4130  +                break
         4131  +                fi
         4132  +            fi
         4133  +            done
         4134  +        done
         4135  +        ])
         4136  +        if test -f "$ac_cv_path_zip" ; then
         4137  +            ZIP_PROG="$ac_cv_path_zip "
         4138  +            AC_MSG_RESULT([$ZIP_PROG])
         4139  +            ZIP_PROG_OPTIONS="-rq"
         4140  +            ZIP_PROG_VFSSEARCH="."
         4141  +            AC_MSG_RESULT([Found INFO Zip in environment])
         4142  +            # Use standard arguments for zip
         4143  +        fi
         4144  +    fi
         4145  +    if test "x$ZIP_PROG" = "x" ; then
         4146  +	    # It is not an error if an installed version of Zip can't be located.
         4147  +        ZIP_PROG=""
         4148  +        ZIP_PROG_OPTIONS=""
         4149  +        ZIP_PROG_VFSSEARCH=""
         4150  +        TCL_ZIPFS_SUPPORT=0
         4151  +        TCL_ZIPFS_FLAG=
         4152  +    else
         4153  +        # ZIPFS Support
         4154  +       eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
         4155  +       if test ${TCL_ZIP_FILE} = "" ; then
         4156  +          TCL_ZIPFS_SUPPORT=0
         4157  +          TCL_ZIPFS_FLAG=
         4158  +          INSTALL_LIBRARIES=install-libraries
         4159  +          INSTALL_MSGS=install-msgs
         4160  +       else
         4161  +           if test ${SHARED_BUILD} = 1 ; then
         4162  +              TCL_ZIPFS_SUPPORT=1
         4163  +              INSTALL_LIBRARIES=install-libraries-zipfs-shared
         4164  +           else
         4165  +              TCL_ZIPFS_SUPPORT=2
         4166  +              INSTALL_LIBRARIES=install-libraries-zipfs-static
         4167  +           fi
         4168  +          TCL_ZIPFS_FLAG=-DTCL_ZIPFS_SUPPORT
         4169  +       fi
         4170  +    fi
         4171  +
         4172  +    AC_SUBST(TCL_ZIP_FILE)
         4173  +    AC_SUBST(TCL_ZIPFS_SUPPORT)
         4174  +    AC_SUBST(TCL_ZIPFS_FLAG)
         4175  +    AC_SUBST(ZIP_PROG)
         4176  +    AC_SUBST(ZIP_PROG_OPTIONS)
         4177  +    AC_SUBST(ZIP_PROG_VFSSEARCH)
         4178  +    AC_SUBST(INSTALL_LIBRARIES)
         4179  +    AC_SUBST(INSTALL_MSGS)
         4180  +])
  4028   4181   
  4029   4182   # Local Variables:
  4030   4183   # mode: autoconf
  4031   4184   # End:

Changes to tdom.m4.

   158    158           AC_MSG_RESULT([yes])
   159    159           TEA_ADD_SOURCES([generic/domalloc.c])
   160    160       else
   161    161           AC_MSG_RESULT([no])
   162    162           AC_DEFINE(USE_NORMAL_ALLOCATOR)
   163    163       fi
   164    164   ])
          165  +
          166  +#------------------------------------------------------------------------
          167  +# TDOM_ENABLE_LESS_NS --
          168  +#
          169  +#   Building with lower limit of different XML namespace declarations
          170  +#   per document.
          171  +#
          172  +# Arguments:
          173  +#   None
          174  +#   
          175  +# Results:
          176  +#
          177  +#   Adds the following arguments to configure:
          178  +#       --enable-lessns=yes|no
          179  +#
          180  +#   Defines the following vars:
          181  +#
          182  +#   Sets the following vars:
          183  +#
          184  +#------------------------------------------------------------------------
          185  +
          186  +AC_DEFUN(TDOM_ENABLE_LESS_NS, [
          187  +    AC_MSG_CHECKING([whether to enable lower limit for XML ns declarations per document])
          188  +    AC_ARG_ENABLE(lessns,
          189  +        AC_HELP_STRING([--enable-lessns],
          190  +            [build with lower limit for XML ns declarations (default: off)]),
          191  +        [tcl_ok=$enableval], [tcl_ok=no])
          192  +
          193  +    if test "${enable_lessns+set}" = set; then
          194  +        enableval="$enable_lessns"
          195  +        tcl_ok=$enableval
          196  +    else
          197  +        tcl_ok=no
          198  +    fi
          199  +
          200  +    if test "$tcl_ok" = "yes" ; then
          201  +        AC_MSG_RESULT([yes])
          202  +        AC_DEFINE(TDOM_LESS_NS)
          203  +    else
          204  +        AC_MSG_RESULT([no])
          205  +    fi
          206  +])
          207  +
          208  +#------------------------------------------------------------------------
          209  +# TDOM_ENABLE_HTML5 --
          210  +#
          211  +#   Building with gumbo support for HTML5 parsing (dom parse -html5)
          212  +#
          213  +# Arguments:
          214  +#   None
          215  +#   
          216  +# Results:
          217  +#
          218  +#   Adds the following arguments to configure:
          219  +#       --enable-html5=yes|no
          220  +#
          221  +#   Defines the following vars:
          222  +#
          223  +#   Sets the following vars:
          224  +#
          225  +#------------------------------------------------------------------------
          226  +
          227  +AC_DEFUN(TDOM_ENABLE_HTML5, [
          228  +    AC_MSG_CHECKING([whether to enable support for HTML5 parsing (using gumbo)])
          229  +    AC_ARG_ENABLE(html5,
          230  +        AC_HELP_STRING([--enable-html5],
          231  +            [build with HTML5 parsing support (default: off)]),
          232  +        [tcl_ok=$enableval], [tcl_ok=no])
          233  +
          234  +    if test "${enable_html5+set}" = set; then
          235  +        enableval="$enable_html5"
          236  +        tcl_ok=$enableval
          237  +    else
          238  +        tcl_ok=no
          239  +    fi
          240  +    HTML5_LIBS=""
          241  +    HTML5_INCLUDES=""
          242  +    if test "$tcl_ok" = "yes" ; then
          243  +        # Check if pkg-config is available
          244  +        PKGCONFIG=no
          245  +        pkg-config --version > /dev/null 2>&1 && PKGCONFIG=yes
          246  +        if test "$PKGCONFIG" = no; then
          247  +            tcl_ok=no
          248  +	    AC_MSG_ERROR([cannot find pkg-config needed for --enable-html5.])
          249  +        fi
          250  +    fi
          251  +    if test "$tcl_ok" = "yes" ; then
          252  +        HAVEGUMBO=`pkg-config --exists gumbo && echo "1"`
          253  +        if test "$HAVEGUMBO" = "1" ; then
          254  +            AC_MSG_RESULT([yes])
          255  +            AC_DEFINE(TDOM_HAVE_GUMBO)
          256  +            if test "${TEA_PLATFORM}" = "windows" ; then
          257  +                HTML5_LIBS="-Wl,-Bstatic `pkg-config --static --libs gumbo` -Wl,-Bdynamic"
          258  +            else
          259  +                HTML5_LIBS="`pkg-config --libs gumbo`"
          260  +            fi
          261  +            HTML5_INCLUDES="`pkg-config --cflags gumbo`"
          262  +        else
          263  +            AC_MSG_ERROR([The required lib gumbo not found])
          264  +        fi
          265  +    else    
          266  +        AC_MSG_RESULT([no])
          267  +    fi
          268  +])
   165    269   
   166    270   #------------------------------------------------------------------------
   167    271   # TDOM_PATH_AOLSERVER
   168    272   #
   169    273   #   Allows the building with support for AOLserver 
   170    274   #
   171    275   # Arguments:
................................................................................
   211    315               fi
   212    316           fi
   213    317           AC_MSG_RESULT([found AOLserver in $AOL_DIR])
   214    318           AC_DEFINE(NS_AOLSERVER)
   215    319           AC_DEFINE(USE_NORMAL_ALLOCATOR)
   216    320       fi
   217    321   ])
          322  +
          323  +#------------------------------------------------------------------------
          324  +# TDOM_PATH_EXPAT
          325  +#
          326  +#   Allows the building against a shared, system-wide expat library In
          327  +#   doubt, it falls back to the bundled expat copy
          328  +#
          329  +# Arguments:
          330  +#   none
          331  +#
          332  +# Results:
          333  +#
          334  +#   Adds the following arguments to configure:
          335  +#       --with-expat=...
          336  +#
          337  +#   Defines the following vars:
          338  +#
          339  +#   Sets the following vars:
          340  +#
          341  +#------------------------------------------------------------------------
          342  +
          343  +AC_DEFUN(TDOM_PATH_EXPAT, [
          344  +    AC_MSG_CHECKING([for expat])
          345  +    AC_ARG_WITH(expat,
          346  +        AC_HELP_STRING([--with-expat],
          347  +            [directory with expat installation]), , [with_expat=no])
          348  +
          349  +    AC_CACHE_VAL(ac_cv_c_expat,[
          350  +        case $with_expat in
          351  +            no) ;;
          352  +            yes)
          353  +                for f in /usr/local /usr; do
          354  +                    if test -f "$f/include/expat.h" ; then
          355  +                        ac_cv_c_expat=`(cd $f; pwd)`
          356  +                        break
          357  +                    fi
          358  +                done
          359  +                ;;
          360  +            *)                
          361  +                if test -f "$with_expat/include/expat.h"; then
          362  +                    ac_cv_c_expat=`(cd $with_expat; pwd)`
          363  +                else                  
          364  +                     AC_MSG_ERROR([${with_expat} directory doesn't contain expat.h])
          365  +                fi
          366  +        esac             
          367  +    ])
          368  +    if test x"${ac_cv_c_expat}" = x ; then
          369  +        AC_MSG_RESULT([Using bundled expat distribution])
          370  +        TEA_ADD_SOURCES([expat/xmlrole.c \
          371  +                         expat/xmltok.c \
          372  +                         expat/xmlparse.c \
          373  +                         expat/loadlibrary.c])
          374  +        TEA_ADD_INCLUDES([-I${srcdir}/expat])
          375  +        AC_DEFINE([XML_POOR_ENTROPY], 1,
          376  +          [Define to use poor entropy in lack of better source.])
          377  +    else
          378  +        AC_MSG_RESULT([Using shared expat found in ${ac_cv_c_expat}])
          379  +        TEA_ADD_INCLUDES(-I${ac_cv_c_expat}/include)
          380  +        TEA_ADD_LIBS([-lexpat])
          381  +    fi
          382  +])
          383  +
          384  +#------------------------------------------------------------------------
          385  +# TDOM_EXPAT_ENTROPY
          386  +#
          387  +#   Only useful if building with the included expat. Allows to
          388  +#   determine the source of entropy used by the lib. If the argument
          389  +#   is something else then the default "auto", this argument value
          390  +#   will be a #define. Use XML_POOR_ENTROPY to fall back to the old
          391  +#   expat hash table salting. The default is to determine the best
          392  +#   available source and to use this.
          393  +#
          394  +# Arguments:
          395  +#   none
          396  +#
          397  +# Results:
          398  +#
          399  +#   Adds the following arguments to configure:
          400  +#       --with-entropy=...
          401  +#
          402  +#   Defines the following vars:
          403  +#
          404  +#   Sets the following vars:
          405  +#
          406  +#------------------------------------------------------------------------
          407  +
          408  +AC_DEFUN(TDOM_EXPAT_ENTROPY, [
          409  +    AC_MSG_NOTICE([checking which source of entropy to use])
          410  +    AC_ARG_WITH(entropy,
          411  +        AC_HELP_STRING([--with-entropy],
          412  +            [source of entropy to use]), , [with_entropy=auto])
          413  +
          414  +        case $with_entropy in
          415  +            no) 
          416  +                AC_DEFINE([XML_POOR_ENTROPY], 1,
          417  +                          [Define to use poor entropy.])
          418  +            ;;
          419  +            auto)
          420  +                AC_MSG_CHECKING([for arc4random_buf (BSD or libbsd)])
          421  +                AC_LINK_IFELSE([AC_LANG_SOURCE([
          422  +                  #include <stdlib.h>  /* for arc4random_buf on BSD, for NULL */
          423  +                  #if defined(HAVE_LIBBSD)
          424  +                  # include <bsd/stdlib.h>
          425  +                  #endif
          426  +                  int main() {
          427  +                    arc4random_buf(NULL, 0U);
          428  +                    return 0;
          429  +                  }
          430  +                ])], [
          431  +                    AC_DEFINE([HAVE_ARC4RANDOM_BUF], [1],
          432  +                        [`arc4random_buf' function.])
          433  +                    AC_MSG_RESULT([yes])
          434  +                ], [
          435  +                    AC_MSG_RESULT([no])
          436  +
          437  +                    AC_MSG_CHECKING([for arc4random (BSD, macOS or libbsd)])
          438  +                    AC_LINK_IFELSE([AC_LANG_SOURCE([
          439  +                      #if defined(HAVE_LIBBSD)
          440  +                      # include <bsd/stdlib.h>
          441  +                      #else
          442  +                      # include <stdlib.h>
          443  +                      #endif
          444  +                      int main() {
          445  +                          arc4random();
          446  +                          return 0;
          447  +                      }
          448  +                    ])], [
          449  +                        AC_DEFINE([HAVE_ARC4RANDOM], [1],
          450  +                            [`arc4random' function.])
          451  +                        AC_MSG_RESULT([yes])
          452  +                    ], [
          453  +                        AC_MSG_RESULT([no])
          454  +                    ])
          455  +                ])
          456  +
          457  +
          458  +                AC_MSG_CHECKING([for getrandom (Linux 3.17+, glibc 2.25+)])
          459  +                AC_LINK_IFELSE([AC_LANG_SOURCE([
          460  +                  #include <stdlib.h>  /* for NULL */
          461  +                  #include <sys/random.h>
          462  +                  int main() {
          463  +                    return getrandom(NULL, 0U, 0U);
          464  +                  }
          465  +                ])], [
          466  +                    AC_DEFINE([HAVE_GETRANDOM], [1],
          467  +                        [`getrandom' function.])
          468  +                    AC_MSG_RESULT([yes])
          469  +                ], [
          470  +                    AC_MSG_RESULT([no])
          471  +
          472  +                    AC_MSG_CHECKING([for syscall SYS_getrandom (Linux 3.17+)])
          473  +                    AC_LINK_IFELSE([AC_LANG_SOURCE([
          474  +                      #include <stdlib.h>  /* for NULL */
          475  +                      #include <unistd.h>  /* for syscall */
          476  +                      #include <sys/syscall.h>  /* for SYS_getrandom */
          477  +                      int main() {
          478  +                        syscall(SYS_getrandom, NULL, 0, 0);
          479  +                        return 0;
          480  +                      }
          481  +                    ])], [
          482  +                        AC_DEFINE([HAVE_SYSCALL_GETRANDOM], [1],
          483  +                            [`syscall' and `SYS_getrandom'.])
          484  +                        AC_MSG_RESULT([yes])
          485  +                    ], [
          486  +                        AC_MSG_RESULT([no])
          487  +                    ])
          488  +                ])
          489  +                AC_DEFINE([XML_DEV_URANDOM], 1,
          490  +                          [include code reading entropy from `/dev/urandom'.])
          491  +                AC_DEFINE([XML_POOR_ENTROPY], 1,
          492  +                          [Define to use poor entropy in lack of better source.])
          493  +            ;;
          494  +            HAVE_GETRANDOM)
          495  +                AC_DEFINE([HAVE_GETRANDOM], 1,
          496  +                          [Linux + glibc >=2.25])
          497  +            ;;
          498  +            HAVE_SYSCALL_GETRANDOM)
          499  +                AC_DEFINE([HAVE_SYSCALL_GETRANDOM], 1,
          500  +                          [Linux + glibc <2.25])
          501  +            ;;
          502  +            HAVE_ARC4RANDOM_BUF)
          503  +                AC_DEFINE([HAVE_ARC4RANDOM_BUF], 1,
          504  +                          [BSD / macOS >=10.7])
          505  +            ;;
          506  +            HAVE_ARC4RANDOM)
          507  +                AC_DEFINE([HAVE_ARC4RANDOM], 1,
          508  +                          [BSD / macOS <10.7])
          509  +            ;;
          510  +            XML_DEV_URANDOM)
          511  +                AC_DEFINE([XML_DEV_URANDOM], 1,
          512  +                          [Linux / BSD / macOS (/dev/urandom).])
          513  +            ;;
          514  +            XML_POOR_ENTROPY)
          515  +                AC_DEFINE([XML_POOR_ENTROPY], 1,
          516  +                          [Define to use poor entropy in lack of better source.])
          517  +            ;;
          518  +            *)
          519  +                AC_MSG_ERROR([${with_entropy} not known.])
          520  +        esac             
          521  +])
   218    522   
   219    523   #------------------------------------------------------------------------
   220    524   # TDOM_PATH_CONFIG --
   221    525   #
   222    526   #	Locate the tdomConfig.sh file
   223    527   #
   224    528   # Arguments:
................................................................................
   234    538   #------------------------------------------------------------------------
   235    539   
   236    540   AC_DEFUN(TDOM_PATH_CONFIG, [
   237    541       if test x"${no_tdom}" = x ; then
   238    542   	    AC_MSG_CHECKING([for tDOM configuration])
   239    543   	    AC_ARG_WITH(tdom, 
   240    544                   AC_HELP_STRING([--with-tdom],
   241         -                    [directory containig tDOM configuration (tdomConfig.sh)]),
          545  +                    [directory containing tDOM configuration (tdomConfig.sh)]),
   242    546                   with_tdomconfig=${withval})
   243    547   
   244    548   	    no_tdom=true
   245    549           if test "${TEA_PLATFORM}" = "windows" ; then
   246    550               tdom_bindir=win
   247    551           else
   248    552               tdom_bindir=unix

Added tests/JSONTestSuite.tcl.

            1  +# The code in this file refers to the work done by:
            2  +#
            3  +# Parsing JSON is a Minefield
            4  +# http://seriot.ch/parsing_json.php
            5  +# https://github.com/nst/JSONTestSuite
            6  +#
            7  +# The dir argument should point to the test_parsing directory of that
            8  +# repository
            9  +
           10  +package require tdom
           11  +
           12  +if {$argc > 1} {
           13  +    error "usage: $argv0 ?testdir?"
           14  +}
           15  +
           16  +if {$argc} {
           17  +    set path [lindex $argv 0]
           18  +    if {[file isdirectory $path]} {
           19  +        set dir $path
           20  +    } else {
           21  +        set file $path
           22  +    }
           23  +} else {
           24  +    set path ""
           25  +    set dir [pwd]
           26  +}
           27  +
           28  +set skipfile [list]
           29  +# Not all chars allowed in JSON strings are allowed as element names
           30  +# or in XML char data.
           31  +foreach file {
           32  +    y_string_escaped_control_character.json
           33  +    y_string_null_escape.json
           34  +    y_string_allowed_escapes.json
           35  +    y_object_empty_key.json
           36  +    y_object_escaped_null_in_key.json
           37  +} {
           38  +    lappend skipfile $file
           39  +}
           40  +# UTF-8 edge cases and outside of BMP chars, for which tcl IO already
           41  +# did the wrong thing. Or misuse of tcl internal string rep as if it
           42  +# would be canonical UTF-8 (which it is not).
           43  +foreach file {
           44  +    y_string_nonCharacterInUTF-8_U+FFFF.json
           45  +    y_string_nonCharacterInUTF-8_U+1FFFF.json
           46  +    n_string_unescaped_crtl_char.json    
           47  +} {
           48  +    lappend skipfile $file
           49  +}
           50  +
           51  +foreach test [glob -directory $path "n_*"] {
           52  +    if {[file tail $test] in $skipfile} continue
           53  +    set fd [open $test]
           54  +    set input [read $fd]
           55  +    close $fd
           56  +    set result [catch {dom parse -json -jsonroot json -- $input}]
           57  +    if {!$result} {
           58  +        puts $test
           59  +    }
           60  +}
           61  +
           62  +foreach test [glob -directory $path "y_*"] {
           63  +    if {[file tail $test] in $skipfile} continue
           64  +    set fd [open $test]
           65  +    set input [read $fd]
           66  +    close $fd
           67  +    set result [catch {dom parse -json -jsonroot json -- $input} errMsg]
           68  +    if {$result} {
           69  +        puts "$test $errMsg"
           70  +    }
           71  +}
           72  +
           73  +# The 'some say so, some so' cases. Ignore result, just ensure no seg
           74  +# fault */
           75  +foreach test [glob -directory $path "i_*"] {
           76  +    set fd [open $test]
           77  +    set input [read $fd]
           78  +    close $fd
           79  +    catch {dom parse -json -jsonroot json -- $input}
           80  +}

Added tests/OASIS-suite.tcl.

            1  +# Helper script to run xslt 1.0 conformance test suite created by the
            2  +# OASIS XSLT / XPath Conformance Technical Committee. 
            3  +
            4  +catch {source uri.tcl}
            5  +package require uri
            6  +package require tdom
            7  +
            8  +# The following is not needed, given, that tDOM is correctly
            9  +# installed. This code only ensures, that the tDOM script library gets
           10  +# sourced, if the script is called with a tcldomsh out of the build
           11  +# dir of a complete tDOM source installation.
           12  +if {[info commands ::tdom::xmlReadFile] == ""} {
           13  +    # tcldomsh without the script library. Source the lib.
           14  +    source [file join [file dir [info script]] ../lib tdom.tcl]
           15  +}
           16  +
           17  +# Import the tDOM helper procs
           18  +namespace import tdom::*
           19  +
           20  +set catalogfile ""
           21  +set loglevel 0
           22  +set skip [list]
           23  +set match [list]
           24  +set matchgroup [list]
           25  +set matchfile [list]
           26  +set matchcatalog [list]
           27  +set verbose 0
           28  +
           29  +proc putsUsage {{channel stderr}} {
           30  +    puts $channel "usage: $::argv0 ?options? path/to/catalog.xml"
           31  +    puts $channel "where options can be:"
           32  +    puts $channel "-loglevel <int>"
           33  +    puts $channel "-skip patternlist"
           34  +    puts $channel "-match patternlist"
           35  +    puts $channel "-matchgroup patternlist"
           36  +    puts $channel "-matchfile patternlist"
           37  +    puts $channel "-matchcatalog patternlist"
           38  +    puts $channel "-verbose <boolean>"
           39  +}
           40  +
           41  +proc processArgs {argc argv} {
           42  +    variable catalogfile
           43  +    variable skip
           44  +    variable match
           45  +    variable matchgroup
           46  +    variable matchfile
           47  +    variable matchcatalog
           48  +    variable loglevel
           49  +    variable verbose
           50  +    
           51  +    if {$argc == 0 || $argc % 2 == 0} {
           52  +        putsUsage
           53  +        exit 1
           54  +    }
           55  +    
           56  +    foreach {option value} $argv {
           57  +        if {$value eq ""} {
           58  +            break
           59  +        }
           60  +        switch $option {
           61  +            "-match" {
           62  +                set match $value
           63  +            }
           64  +            "-matchgroup" {
           65  +                set matchgroup $value
           66  +            }
           67  +            "-matchfile" {
           68  +                set matchfile $value
           69  +            }
           70  +            "-skip" {
           71  +                set skip $value
           72  +            }
           73  +            "-matchcatalog" {
           74  +                set matchcatalog $value
           75  +            }
           76  +            "-loglevel" {
           77  +                if {[string is integer -strict $value]} {
           78  +                    set loglevel $value
           79  +                } else {
           80  +                    putsUsage
           81  +                    exit 1
           82  +                }
           83  +            }
           84  +            "-verbose" {
           85  +                if {[string is boolean -strict $value]} {
           86  +                    set verbose $value
           87  +                } else {
           88  +                    putsUsage
           89  +                    exit 1
           90  +                }
           91  +            }
           92  +            default {
           93  +                puts stderr "Unknown option \"$option\""
           94  +                putsUsage
           95  +                exit 1
           96  +            }
           97  +        }
           98  +    }
           99  +    set catalogfile [lindex $argv end]
          100  +}
          101  +
          102  +set compareOK 0
          103  +set compareDIFF 0
          104  +set compareFAILED 0
          105  +set failedOK 0
          106  +set failedXML 0
          107  +set failedXSLT 0
          108  +set failedProcessing 0
          109  +set notFailed 0
          110  +
          111  +proc extRefHandler {base systemId publicId} {
          112  +    variable usageCounter
          113  +
          114  +    set absolutURI [uri::resolve $base $systemId]
          115  +    incr usageCounter($absolutURI)
          116  +    if {$usageCounter($absolutURI) > 10} {
          117  +        error "Cirular import/include?"
          118  +    }
          119  +    switch $systemId {
          120  +        "notfound.xml" {
          121  +            return [list string $absolutURI "<notfound/>"]
          122  +        }
          123  +    }
          124  +    array set uriData [uri::split $absolutURI]
          125  +    switch $uriData(scheme) {
          126  +        file {
          127  +            if {[catch {
          128  +                set xmlstr [xmlReadFile $uriData(path)]
          129  +            }]} {
          130  +                set pathlist [file split $uriData(path)]
          131  +                set file [findFile [lindex $pathlist end] [lrange $pathlist 0 end-1]]
          132  +                if {$file ne ""} {
          133  +                    set xmlstr [xmlReadFile $file]
          134  +                }
          135  +                error "not resolved external entity. Base: $base SystemID: $systemId"
          136  +            }
          137  +            return [list string $absolutURI [xmlReadFile $uriData(path)]]
          138  +        }
          139  +        default {
          140  +            error "can only handle file URI's"
          141  +        }
          142  +    }
          143  +}
          144  +
          145  +
          146  +# This is the callback proc for xslt:message elements. This proc is
          147  +# called once every time an xslt:message element is encountered during
          148  +# processing the stylesheet. The callback proc simply sends the text
          149  +# message to stderr.
          150  +proc xsltmsgcmd {msg terminate} {
          151  +    variable loglevel
          152  +    if {$loglevel >= 0} {
          153  +        puts stderr "xslt message: '$msg'"
          154  +    }
          155  +}
          156  +
          157  +proc readCatalog {catalogPath} {
          158  +    variable catalogDir
          159  +    variable infoset
          160  +
          161  +    set fd [open $catalogPath]
          162  +    set doc [dom parse -channel $fd]
          163  +    close $fd
          164  +    set catalogDir [file dirname $catalogPath]
          165  +    set infosetxsl [file join $catalogDir .. TOOLS infoset.xsl]
          166  +    set infosetdoc [dom parse -keepEmpties [xmlReadFile $infosetxsl]]
          167  +    set infoset [$infosetdoc toXSLTcmd]
          168  +    return $doc
          169  +}
          170  +
          171  +proc checkAgainstPattern {patternlist text} {
          172  +    if {![llength $patternlist]} {
          173  +        return 1
          174  +    }
          175  +    foreach pattern $patternlist {
          176  +        if {[string match $pattern $text]} {
          177  +            return 1
          178  +        }
          179  +    }
          180  +    return 0
          181  +}
          182  +
          183  +proc skip {id} {
          184  +    variable skip
          185  +
          186  +    if {![llength $skip]} {
          187  +        return 0
          188  +    }
          189  +    return [checkAgainstPattern $skip $id]
          190  +}
          191  +
          192  +proc matchcatalog {testcatalog} {
          193  +    variable matchcatalog
          194  +
          195  +    if {![llength $matchcatalog]} {
          196  +        return 1
          197  +    }
          198  +    return [checkAgainstPattern $matchcatalog $testcatalog]
          199  +}
          200  +
          201  +proc log {level text {detail ""}} {
          202  +    variable loglevel
          203  +
          204  +    if {$level <= $loglevel} {
          205  +        puts $text
          206  +    }
          207  +    if {$detail ne "" && $level < $loglevel} {
          208  +        puts $detail
          209  +    }
          210  +}
          211  +
          212  +proc findFile {filename path} {
          213  +    # The Microsoft testcatalog includes tests for which the physical
          214  +    # file name differ in case from the file name given by the test
          215  +    # definition. This proc tries to identify the correct file name in
          216  +    # such a case.
          217  +
          218  +    log 3 "findFile called with $filename $path"
          219  +    set filelist [glob -nocomplain -tails -directory $path *]
          220  +    set nocasequal [lsearch -exact -nocase $filelist $filename]
          221  +    if {[llength $nocasequal] == 1} {
          222  +        if {$nocasequal >= 0} {
          223  +            return [file join $path [lindex $filelist $nocasequal]]
          224  +        }
          225  +    }
          226  +    return ""
          227  +}
          228  +
          229  +proc runTest {testcase} {
          230  +    variable catalogDir
          231  +    variable majorpath
          232  +    variable matchgroup
          233  +    variable matchfile
          234  +    variable match
          235  +    variable infoset
          236  +    variable compareOK
          237  +    variable compareDIFF
          238  +    variable compareFAILED
          239  +    variable failedOK
          240  +    variable failedXML
          241  +    variable failedXSLT
          242  +    variable failedProcessing
          243  +    variable notFailed
          244  +    variable verbose
          245  +    variable usageCounter
          246  +    
          247  +    set filepath [$testcase selectNodes string(file-path)]
          248  +    if {![checkAgainstPattern $matchgroup $filepath]} {
          249  +        return
          250  +    }
          251  +    set scenario [$testcase selectNodes scenario]
          252  +    if {[llength $scenario] != 1 } {
          253  +        log 0 "Non-standard scenario!"
          254  +        log 0 [$testcase asXML]
          255  +        return
          256  +    }
          257  +    set operation [$scenario @operation]
          258  +    switch $operation {
          259  +        "standard" -
          260  +        "execution-error" {}
          261  +        default {
          262  +            log 0 "Non-standard scenario!"
          263  +            log 0 [$testcase asXML]
          264  +            return
          265  +        }
          266  +    }
          267  +    set xmlfile [$scenario selectNodes \
          268  +                     {string(input-file[@role="principal-data"])}]
          269  +    set xslfile [$scenario selectNodes \
          270  +                     {string(input-file[@role="principal-stylesheet"])}]
          271  +    set testid [$testcase @id "<no-id>"]
          272  +    if {![checkAgainstPattern $match $testid]} {
          273  +        return
          274  +    }
          275  +    if {[skip $testid]} {
          276  +        log 1 "Skipping test id $testid (filepath: $filepath)"
          277  +        return
          278  +    }
          279  +
          280  +    if {![checkAgainstPattern $matchfile $xslfile]} {
          281  +        log 1 "Skipping xslfile $xslfile"
          282  +        return
          283  +    }
          284  +    if {$verbose} {
          285  +        puts [$testcase @id "<no-id>!!"]
          286  +    }
          287  +    set xmlfile [file join $catalogDir $majorpath $filepath $xmlfile]
          288  +    if {![file readable $xmlfile]} {
          289  +        set xmlfile [findFile $xmlfile \
          290  +                         [file join $catalogDir $majorpath $filepath]]
          291  +        if {$xmlfile eq ""} {
          292  +            log 0 "Couldn't find xmlfile \
          293  +                  [$scenario selectNodes \
          294  +                     {string(input-file[@role="principal-data"])}]"
          295  +            return
          296  +        }
          297  +    }
          298  +    if {![file readable $xslfile]} {
          299  +        set xslfile [findFile $xslfile \
          300  +                         [file join $catalogDir $majorpath $filepath]]
          301  +        if {$xslfile eq ""} {
          302  +            log 0 "Couldn't find xslfile \
          303  +                  [$scenario selectNodes \
          304  +                     {string(input-file[@role="principal-stylesheet"])}]"
          305  +            return
          306  +        }
          307  +    }
          308  +    set xslfile [file join $catalogDir $majorpath $filepath $xslfile]
          309  +    set xmlout [$scenario selectNodes \
          310  +                    {string(output-file[@role="principal" and @compare="XML"])}]
          311  +    set xmloutfile ""
          312  +    if {$xmlout ne ""} {
          313  +        set xmloutfile [file join $catalogDir $majorpath "REF_OUT" $filepath \
          314  +                            $xmlout]
          315  +    }
          316  +    array unset usageCounter
          317  +    if {[catch {
          318  +        set xmldoc [dom parse -baseurl [baseURL $xmlfile] \
          319  +                        -externalentitycommand extRefHandler \
          320  +                        -keepEmpties \
          321  +                        [xmlReadFile $xmlfile] ]
          322  +    } errMsg]} {
          323  +        incr failedXML
          324  +        log 0 "Unable to parse xml file '$xmlfile'. Reason:\n$errMsg"
          325  +        return
          326  +    }
          327  +    dom setStoreLineColumn 1
          328  +    if {[catch {
          329  +        set xsltdoc [dom parse -baseurl [baseURL $xslfile] \
          330  +                         -externalentitycommand extRefHandler \
          331  +                         -keepEmpties \
          332  +                         [xmlReadFile $xslfile] ]
          333  +    } errMsg]} {
          334  +        dom setStoreLineColumn 0
          335  +        incr failedXSLT
          336  +        log 0 "Unable to parse xsl file '$xslfile'. Reason:\n$errMsg"
          337  +        return
          338  +    }
          339  +    dom setStoreLineColumn 0
          340  +    set resultDoc ""
          341  +    if {[catch {$xmldoc xslt -xsltmessagecmd xsltmsgcmd $xsltdoc resultDoc} \
          342  +             errMsg]} {
          343  +        if {$operation eq "execution-error"} {
          344  +            incr failedOK
          345  +            log 2 $errMsg
          346  +        } else {
          347  +            incr failedProcessing
          348  +            log 0 $errMsg
          349  +        }
          350  +    } else {
          351  +        if {$operation eq "execution-error"} {
          352  +            incr notFailed
          353  +            log 0 "$xslfile - test should have failed, but didn't."
          354  +        }
          355  +    }
          356  +    if {$xmloutfile ne "" && [llength [info commands $resultDoc]]} {
          357  +        if {![catch {
          358  +            set refdoc [dom parse -keepEmpties [xmlReadFile $xmloutfile]]
          359  +        } errMsg]} {
          360  +            set refinfosetdoc [$infoset $refdoc]
          361  +            set resultinfosetdoc [$infoset $resultDoc]
          362  +            if {[$refinfosetdoc asXML -indent none] 
          363  +                ne [$resultinfosetdoc asXML -indent none]} {
          364  +                incr compareDIFF
          365  +                log 1 "Result and ref differ."
          366  +                log 2 "Ref:"
          367  +                log 2 [$refinfosetdoc asXML]
          368  +                log 2 "Result:"
          369  +                log 2 [$resultinfosetdoc asXML]
          370  +            } else {
          371  +                incr compareOK
          372  +            }
          373  +            $refinfosetdoc delete
          374  +            $resultinfosetdoc delete
          375  +        } else {
          376  +            incr compareFAILED
          377  +            log 3 "Unable to parse REF doc. Reason:\n$errMsg"
          378  +        }
          379  +    }
          380  +    $xmldoc delete
          381  +    $xsltdoc delete
          382  +    catch {$resultDoc delete}
          383  +}
          384  +
          385  +proc runTests {catalogRoot} {
          386  +    variable majorpath
          387  +    variable compareOK
          388  +    variable compareDIFF
          389  +    variable compareFAILED
          390  +    variable failedOK
          391  +    variable failedXML
          392  +    variable failedXSLT
          393  +    variable failedProcessing
          394  +    variable notFailed
          395  +    
          396  +    foreach testcatalog [$catalogRoot selectNodes test-catalog] {
          397  +        if {![matchcatalog [$testcatalog @submitter]]} {
          398  +            continue
          399  +        }
          400  +        set majorpath [$testcatalog selectNodes string(major-path)]
          401  +        foreach testcase [$testcatalog selectNodes test-case] {
          402  +            runTest $testcase
          403  +        }
          404  +    }
          405  +    # Always output the summary
          406  +    variable loglevel 0
          407  +    log 0 "Finished."
          408  +    log 0 "XML parse failed: $failedXML"
          409  +    log 0 "XSLT parse failed: $failedXSLT"
          410  +    log 0 "Processing failed: $failedProcessing"
          411  +    log 0 "Compare OK: $compareOK"
          412  +    log 0 "Compare FAIL: $compareDIFF"
          413  +    log 0 "Compare BROKEN: $compareFAILED"
          414  +    log 0 "Not found errors: $notFailed"
          415  +    log 0 "Failed OK: $failedOK"
          416  +}
          417  +
          418  +processArgs $argc $argv
          419  +set catalogDoc [readCatalog $catalogfile]
          420  +runTests [$catalogDoc documentElement]
          421  +
          422  +proc exit args {}

Changes to tests/all-bench.tcl.

    94     94           }
    95     95       }
    96     96   }
    97     97   
    98     98   
    99     99   if {[llength $interpPaths] == 0} {
   100    100       lappend interpPaths [file dirname [info nameofexecutable]]
   101         -    puts $interpPaths
   102    101   }
   103    102   
   104         -puts [bench::locate $interpPattern $interpPaths]
   105         -
   106         -set interps [bench::versions [bench::locate $interpPattern $interpPaths]]
          103  +set interps [bench::locate $interpPattern $interpPaths]
   107    104   
   108    105   if {![llength $interps]} {
   109    106       puts stderr "No interpreters found"
   110    107       exit 1
   111    108   }
   112    109   
   113    110   if {[llength $benchFlags]} {
................................................................................
   119    116   set benchfiles [glob -nocomplain [file join [file dir [info script]] \
   120    117                                         $benchFilePattern]]
   121    118   if {![llength $benchfiles]} {
   122    119       puts stderr "No benchmark files found."
   123    120       exit 1
   124    121   }
   125    122   
   126         -set run $cmd
   127         -lappend run $interps $benchfiles
   128         -set results [eval $run]
          123  +set results ""
          124  +foreach interp $interps {
          125  +    set run $cmd
          126  +    lappend run $interp $benchfiles
          127  +    set results [::bench::merge $results [eval $run]]
          128  +}
   129    129   if {$norm ne ""} {
   130    130       set results [::bench::norm $results $norm]
   131    131   }
   132    132   puts [::bench::out::text $results]

Changes to tests/all.tcl.

    12     12   source [file join [file dir [info script]] loadtdom.tcl]
    13     13   
    14     14   if {$tcl_version >= 8.1} {
    15     15       if {[lsearch [info proc ::tcltest::testConstraint] \
    16     16               ::tcltest::testConstraint] == -1} {
    17     17           set ::tcltest::testConfig(need_i18n) 1
    18     18           set ::tcltest::testConstraints(need_i18n) 1
    19         -        if {[info procs ::tDOM::extRefHandler] != ""} {
           19  +        if {[info procs ::tdom::extRefHandler] != ""} {
    20     20               set ::tcltest::testConfig(need_uri) 1
    21     21               set ::tcltest::testConstraints(need_uri) 1
    22     22           }
    23         -   } else {
           23  +    } else {
    24     24           ::tcltest::testConstraint need_i18n 1
    25         -       if {[info procs ::tDOM::extRefHandler] != ""} {
    26         -           ::tcltest::testConstraint need_uri 1
    27         -       }
           25  +        if {[info procs ::tdom::extRefHandler] != ""} {
           26  +            ::tcltest::testConstraint need_uri 1
           27  +        }
    28     28       }
    29     29   }
    30     30   
           31  +::tcltest::testConstraint needExpand 1
           32  +if {$tcl_version < 8.5} {
           33  +    ::tcltest::testConstraint needExpand 0
           34  +}
           35  +    
    31     36   set timeCmd {clock format [clock seconds]}
    32     37   
    33     38   set ::tcltest::testSingleFile false
    34     39   
    35     40   puts stdout "Tcl $tcl_patchLevel tests running in interp:  [info nameofexecutable]"
    36     41   
    37     42   if {$tcl_version < 8.2} {

Changes to tests/comment.test.

    81     81       $parser parse {<?xml version="1.0"?>
    82     82   <!DOCTYPE Test>
    83     83   <Test>surrounding <!--This is a comment--> PCDATA</Test>
    84     84   }
    85     85       list $::comment $::result $::element
    86     86   } {{This is a comment} {surrounding  PCDATA} 0}
    87     87   
    88         -test comment-1.3 {Simple comment, no white space} {
           88  +test comment-1.4 {Simple comment, no white space} {
    89     89       set ::result {}
    90     90       set ::comment {}
    91     91       set ::element 0
    92     92   
    93     93       catch {rename xml::comment-1.3 {}}
    94     94       set parser [xml::parser comment-1.3 \
    95     95   	-elementstartcommand Estart \
................................................................................
    99     99       $parser parse {<?xml version="1.0"?>
   100    100   <!DOCTYPE Test>
   101    101   <Test><!--comment--></Test>
   102    102   }
   103    103       list $::comment $::result $::element
   104    104   } {comment {} 0}
   105    105   
   106         -test comment-1.4 {comment, with nested element} {
          106  +test comment-1.5 {comment, with nested element} {
   107    107       set ::result {}
   108    108       set ::comment {}
   109    109       set ::element 0
   110    110   
   111    111       catch {rename xml::comment-1.4 {}}
   112    112       set parser [xml::parser comment-1.4 \
   113    113   	-elementstartcommand Estart \

Added tests/data/xmlspec-v20.dtd.

            1  +<!-- ............................................................... -->
            2  +<!-- XML specification DTD ......................................... -->
            3  +<!-- ............................................................... -->
            4  +
            5  +<!--
            6  +TYPICAL INVOCATION:
            7  +#  <!DOCTYPE spec PUBLIC
            8  +#       "-//W3C//DTD Specification V2.0//EN"
            9  +#       "http://www.w3.org/XML/1998/06/xmlspec-v20.dtd">
           10  +
           11  +PURPOSE:
           12  +  This DTD was developed for use with the XML family of W3C
           13  +  specifications.  It is an XML-compliant DTD based in part on
           14  +  the TEI Lite and Sweb DTDs.
           15  +
           16  +DEPENDENCIES:
           17  +  None.
           18  +
           19  +CHANGE HISTORY:
           20  +  The list of changes is at the end of the DTD.
           21  +
           22  +  For all details, see the design report at:
           23  +
           24  +#   <http://www.w3.org/XML/1998/06/NOTE-xmlspec-v20.htm>
           25  +
           26  +  The "typical invocation" FPI always gets updated to reflect the date
           27  +  of the most recent changes.
           28  +
           29  +  Search this file for "#" in the first column to see change history
           30  +  comments.
           31  +
           32  +MAINTAINER:
           33  +  Eve Maler
           34  +  Arbortext, Inc.
           35  +  elm@arbortext.com
           36  +  voice: +1 781 529 1012
           37  +  fax:   +1 781 529 1099
           38  +-->
           39  +
           40  +<!-- ............................................................... -->
           41  +<!-- Entities for characters and symbols ........................... -->
           42  +<!-- ............................................................... -->
           43  +
           44  +<!--
           45  +#1998-03-10: maler: Added &ldquo; and &rdquo;.
           46  +#                   Used 8879:1986-compatible decimal character
           47  +#                   references.
           48  +#                   Merged charent.mod file back into main file.
           49  +#1998-05-14: maler: Fixed ldquo and rdquo.  Gave mdash a real number.
           50  +#1998-12-03: maler: Escaped the leading ampersands.
           51  +-->
           52  +
           53  +<!ENTITY lt     "&#38;#60;">
           54  +<!ENTITY gt     "&#62;">
           55  +<!ENTITY amp    "&#38;#38;">
           56  +<!ENTITY apos   "&#39;">
           57  +<!ENTITY quot   "&#34;">
           58  +<!ENTITY nbsp   "&#160;">
           59  +<!ENTITY mdash  "&#38;#x2014;">
           60  +<!ENTITY ldquo  "&#38;#x201C;">
           61  +<!ENTITY rdquo  "&#38;#x201D;">
           62  +
           63  +<!-- ............................................................... -->
           64  +<!-- Entities for classes of standalone elements ................... -->
           65  +<!-- ............................................................... -->
           66  +
           67  +<!--
           68  +#1997-10-16: maler: Added table to %illus.class;.
           69  +#1997-11-28: maler: Added htable to %illus.class;.
           70  +#1997-12-29: maler: IGNOREd table.
           71  +#1998-03-10: maler: Removed SGML Open-specific %illus.class;.
           72  +#                   Added "local" entities for customization.
           73  +#1998-05-14: maler: Added issue to %note.class;.
           74  +#                   Removed %[local.]statusp.class;.
           75  +#1998-05-21: maler: Added constraintnote to %note.class;.
           76  +#1998-08-22: maler: Changed htable to table in %illus.class;.
           77  +#                   Added definitions to %illus.class;.
           78  +-->
           79  +
           80  +<!ENTITY % local.p.class        "">
           81  +<!ENTITY % p.class              "p
           82  +                                %local.p.class;">
           83  +
           84  +<!ENTITY % local.list.class     "">
           85  +<!ENTITY % list.class           "ulist|olist|slist|glist
           86  +                                %local.list.class;">
           87  +
           88  +<!ENTITY % local.speclist.class "">
           89  +<!ENTITY % speclist.class       "orglist|blist
           90  +                                %local.speclist.class;">
           91  +
           92  +<!ENTITY % local.note.class     "">
           93  +<!ENTITY % note.class           "note|issue|wfcnote|vcnote
           94  +                                |constraintnote %local.note.class;">
           95  +
           96  +<!ENTITY % local.illus.class    "">
           97  +<!ENTITY % illus.class          "eg|graphic|scrap|table|definitions
           98  +                                %local.illus.class;">
           99  +
          100  +<!-- ............................................................... -->
          101  +<!-- Entities for classes of phrase-level elements ................. -->
          102  +<!-- ............................................................... -->
          103  +
          104  +<!--
          105  +#1997-12-29: maler: Added xspecref to %ref.class;.
          106  +#1998-03-10: maler: Added %ednote.class;.
          107  +#                   Added "local" entities for customization.
          108  +-->
          109  +
          110  +<!ENTITY % local.annot.class    "">
          111  +<!ENTITY % annot.class          "footnote
          112  +                                %local.annot.class;">
          113  +
          114  +<!ENTITY % local.termdef.class  "">
          115  +<!ENTITY % termdef.class        "termdef|term
          116  +                                %local.termdef.class;">
          117  +
          118  +<!ENTITY % local.emph.class     "">
          119  +<!ENTITY % emph.class           "emph|quote
          120  +                                %local.emph.class;">
          121  +
          122  +<!ENTITY % local.ref.class      "">
          123  +<!ENTITY % ref.class            "bibref|specref|termref|titleref
          124  +                                |xspecref|xtermref
          125  +                                %local.ref.class;">
          126  +
          127  +<!ENTITY % local.loc.class      "">
          128  +<!ENTITY % loc.class            "loc
          129  +                                %local.loc.class;">
          130  +
          131  +<!ENTITY % local.tech.class     "">
          132  +<!ENTITY % tech.class           "kw|nt|xnt|code
          133  +                                %local.tech.class;">
          134  +
          135  +<!ENTITY % local.ednote.class   "">
          136  +<!ENTITY % ednote.class         "ednote
          137  +                                %local.ednote.class;">
          138  +
          139  +<!-- ............................................................... -->
          140  +<!-- Entities for mixtures of standalone elements .................. -->
          141  +<!-- ............................................................... -->
          142  +
          143  +<!--
          144  +#1997-09-30: maler: Created %p.mix; to eliminate p from self.
          145  +#1997-09-30: maler: Added %speclist.class; to %obj.mix; and %p.mix;.
          146  +#1997-09-30: maler: Added %note.class; to %obj.mix; and %p.mix;.
          147  +#1997-10-16: maler: Created %entry.mix;.  Note that some elements
          148  +#                   left out here are still allowed in termdef,
          149  +#                   which entry can contain through %p.pcd.mix;.
          150  +#1997-11-28: maler: Added %p.class; to %statusobj.mix;.
          151  +#1998-03-10: maler: Added %ednote.class; to all mixtures, except
          152  +#                   %p.mix; and %statusobj.mix;, because paragraphs
          153  +#                   and status paragraphs will contain ednote
          154  +#                   through %p.pcd.mix;.
          155  +#1998-03-23: maler: Added %termdef.mix; (broken out from
          156  +#                    %termdef.pcd.mix;).
          157  +#1998-05-14: maler: Removed %statusobj.mix; and all mentions of
          158  +#                   %statusp.mix;.
          159  +-->
          160  +
          161  +<!ENTITY % div.mix
          162  +        "%p.class;|%list.class;|%speclist.class;|%note.class;
          163  +        |%illus.class;|%ednote.class;">
          164  +<!ENTITY % obj.mix
          165  +        "%p.class;|%list.class;|%speclist.class;|%note.class;
          166  +        |%illus.class;|%ednote.class;">
          167  +<!ENTITY % p.mix
          168  +        "%list.class;|%speclist.class;|%note.class;|%illus.class;">
          169  +<!ENTITY % entry.mix
          170  +        "%list.class;|note|eg|graphic|%ednote.class;">
          171  +<!ENTITY % hdr.mix
          172  +        "%p.class;|%list.class;|%ednote.class;">
          173  +<!ENTITY % termdef.mix
          174  +        "%note.class;|%illus.class;">
          175  +
          176  +<!-- ............................................................... -->
          177  +<!-- Entities for mixtures of #PCDATA and phrase-level elements .... -->
          178  +<!-- ............................................................... -->
          179  +
          180  +<!--    Note that %termdef.pcd.mix contains %note.class;
          181  +        and %illus.class;, considered standalone elements. -->
          182  +
          183  +<!--
          184  +#1997-09-30: maler: Added scrap and %note.class; to %termdef.pcd.mix;.
          185  +#1997-11-28: maler: Added %loc.class; to %p.pcd.mix;.
          186  +#1998-03-10: maler: Added %ednote.class; to all mixtures.
          187  +#1998-03-23: maler: Moved some %termdef.pcd.mix; stuff out to
          188  +#                   %termdef.mix;.
          189  +#1998-05-14: maler: Removed %statusp.pcd.mix;.
          190  +#1998-05-21: maler: Added constraint element to %eg.pcd.mix;.
          191  +#1999-07-02: maler: Added %loc.class; to %head.pcd.mix;,
          192  +#                   %label.pcd.mix;, %eg.pcd.mix;, %termdef.pcd.mix;,
          193  +#                   %tech.pcd.mix; (net: all PCD mixes have it).
          194  +#                   Removed unused %loc.pcd.mix;.
          195  +-->
          196  +
          197  +<!ENTITY % p.pcd.mix
          198  +        "#PCDATA|%annot.class;|%termdef.class;|%emph.class;
          199  +        |%ref.class;|%tech.class;|%loc.class;|%ednote.class;">
          200  +<!ENTITY % head.pcd.mix
          201  +        "#PCDATA|%annot.class;|%emph.class;|%tech.class;
          202  +        |%loc.class;|%ednote.class;">
          203  +<!ENTITY % label.pcd.mix
          204  +        "#PCDATA|%annot.class;|%termdef.class;|%emph.class;
          205  +        |%tech.class;|%loc.class;|%ednote.class;">
          206  +<!ENTITY % eg.pcd.mix
          207  +        "#PCDATA|%annot.class;|%emph.class;|%loc.class;
          208  +        |%ednote.class;|constraint">
          209  +<!ENTITY % termdef.pcd.mix
          210  +        "#PCDATA|term|%emph.class;|%ref.class;|%tech.class;
          211  +        |%loc.class;|%ednote.class;">
          212  +<!ENTITY % bibl.pcd.mix
          213  +        "#PCDATA|%emph.class;|%ref.class;|%loc.class;|%ednote.class;">
          214  +<!ENTITY % tech.pcd.mix
          215  +        "#PCDATA|%loc.class;|%ednote.class;">
          216  +
          217  +<!-- ............................................................... -->
          218  +<!-- Entities for customizable content models ...................... -->
          219  +<!-- ............................................................... -->
          220  +
          221  +<!--
          222  +#1998-03-10: maler: Added customization entities.
          223  +#1998-05-14: maler: Allowed prevlocs and latestloc in either order.
          224  +#1999-07-02: maler: Made version optional; added copyright element.
          225  +-->
          226  +
          227  +<!ENTITY % spec.mdl
          228  +        "header, front?, body, back?">
          229  +
          230  +<!ENTITY % header.mdl
          231  +        "title, subtitle?, version?, w3c-designation, w3c-doctype,
          232  +        pubdate, notice*, publoc, ((prevlocs, latestloc?) |
          233  +        (latestloc, prevlocs?))?, authlist, copyright?, status,
          234  +        abstract, pubstmt?, sourcedesc?, langusage, revisiondesc">
          235  +
          236  +<!ENTITY % pubdate.mdl
          237  +        "day?, month, year">
          238  +
          239  +<!-- ............................................................... -->
          240  +<!-- Entities for common attributes ................................ -->
          241  +<!-- ............................................................... -->
          242  +
          243  +<!--    key attribute:
          244  +        Optionally provides a sorting or indexing key, for cases when
          245  +        the element content is inappropriate for this purpose. -->
          246  +<!ENTITY % key.att
          247  +        'key                    CDATA           #IMPLIED'>
          248  +
          249  +<!--    def attribute:
          250  +        Points to the element where the relevant definition can be
          251  +        found, using the IDREF mechanism.  %def.att; is for optional
          252  +        def attributes, and %def-req.att; is for required def
          253  +        attributes. -->
          254  +<!ENTITY % def.att
          255  +        'def                    IDREF           #IMPLIED'>
          256  +<!ENTITY % def-req.att
          257  +        'def                    IDREF           #REQUIRED'>
          258  +
          259  +<!--    ref attribute:
          260  +        Points to the element where more information can be found,
          261  +        using the IDREF mechanism.  %ref.att; is for optional
          262  +        ref attributes, and %ref-req.att; is for required ref
          263  +        attributes. -->
          264  +<!ENTITY % ref.att
          265  +        'ref                    IDREF           #IMPLIED'>
          266  +<!ENTITY % ref-req.att
          267  +        'ref                    IDREF           #REQUIRED'>
          268  +
          269  +<!--
          270  +#1998-03-23: maler: Added show and actuate attributes to href.
          271  +#                   Added semi-common xml:space attribute.
          272  +#1998-08-22: maler: Used new xlink:form and #IMPLIED features.
          273  +#1999-07-02: maler: Reorganized XLink-related entities completely;
          274  +#                   added xmlns:xlink attribute to the mix.
          275  +-->
          276  +
          277  +<!--    xmlns:xlink and xlink:form attributes:
          278  +        xmlns:xlink declares the association of the xlink prefix
          279  +        with the namespace created by the XLink specification.
          280  +        xlink:form potentially identifies an element as an XLink
          281  +        "simple" linking element.  When a value for href is supplied,
          282  +        xlink:form should be understood to have the value "simple".
          283  +        When a value for href is not supplied, xlink:form should be
          284  +        understood to have the value "none". -->
          285  +<!ENTITY % simple-xlink.att
          286  +        'xmlns:xlink            CDATA           #FIXED
          287  +                                                "http://www.w3.org/TR/WD-xlink"
          288  +        xlink:form              CDATA           #IMPLIED '>
          289  +
          290  +<!--    href attributes:
          291  +        The href attribute is required to have a value when xlink:form
          292  +        has the (implicit or explicit) value "simple".  Some elements
          293  +        are links only if the authors chooses to make them so. -->
          294  +<!ENTITY % href.att
          295  +        'href                   CDATA           #IMPLIED '>
          296  +<!ENTITY % href-req.att
          297  +        'href                    CDATA           #REQUIRED '>
          298  +
          299  +<!--    show and actuate attributes:
          300  +        These attributes offer hints to the display engine about how to
          301  +        handle traversal to a link end indicated by an href locator.  The
          302  +        auto-embed combination should have the effect of an HTML IMG SRC=.
          303  +        The user-replace combination should have the effect of an HTML
          304  +        A HREF=.  The user-new combination should have the effect of an
          305  +        HTML A HREF= TARGET=NEW.
          306  +        -->
          307  +<!ENTITY % auto-embed.att
          308  +        'show                   CDATA           #FIXED "embed"
          309  +        actuate                 CDATA           #FIXED "auto" '>
          310  +<!ENTITY % user-replace.att
          311  +        'show                   CDATA           #FIXED "replace"
          312  +        actuate                 CDATA           #FIXED "user" '>
          313  +<!ENTITY % user-new.att
          314  +        'show                   CDATA           #FIXED "new"
          315  +        actuate                 CDATA           #FIXED "user" '>
          316  +
          317  +<!--    xml:space attribute:
          318  +        Indicates that the element contains white space
          319  +        that the formatter or other application should retain,
          320  +        as appropriate to its function. -->
          321  +<!ENTITY % xmlspace.att
          322  +        'xml:space              (default
          323  +                                |preserve)      #FIXED "preserve" '>
          324  +
          325  +<!--    Common attributes:
          326  +        Every element has an ID attribute (sometimes required,
          327  +        but usually optional) for links, and a Role attribute
          328  +        for extending the useful life of the DTD by allowing
          329  +        authors to make subclasses for any element. %common.att;
          330  +        is for common attributes where the ID is optional, and
          331  +        %common-idreq.att; is for common attributes where the
          332  +        ID is required. -->
          333  +<!ENTITY % common.att
          334  +        'id                     ID              #IMPLIED
          335  +        role                    NMTOKEN         #IMPLIED'>
          336  +<!ENTITY % common-idreq.att
          337  +        'id                     ID              #REQUIRED
          338  +        role                    NMTOKEN         #IMPLIED'>
          339  +
          340  +<!-- ............................................................... -->
          341  +<!-- Common elements ............................................... -->
          342  +<!-- ............................................................... -->
          343  +
          344  +<!--    head: Title on divisions, productions, and the like -->
          345  +<!ELEMENT head (%head.pcd.mix;)*>
          346  +<!ATTLIST head %common.att;>
          347  +
          348  +<!-- ............................................................... -->
          349  +<!-- Major specification structure ................................. -->
          350  +<!-- ............................................................... -->
          351  +
          352  +<!--
          353  +#1998-03-10: maler: Made spec content model easily customizable.
          354  +#1999-07-02: maler: Added doctype atts and status att.
          355  +-->
          356  +
          357  +<!ELEMENT spec (%spec.mdl;)>
          358  +<!--    doctype attributes:
          359  +        Indicates the type of document, so that the appropriate
          360  +        stylesheet or workflow routing can be applied.  Should
          361  +        *not* generate any text (such as the "REC-" or "NOTE-"
          362  +        prefix on the W3C designation content).  No default.  If
          363  +        w3c-doctype is "other", other-doctype should be filled in.
          364  +        status attribute:
          365  +        Indicates the stage of review of the document.  May affect
          366  +        the stylesheet's treatment of ednotes (e.g., whether to
          367  +        output them).  No default. -->
          368  +
          369  +<!ATTLIST spec
          370  +        %common.att;
          371  +        w3c-doctype     (rec
          372  +                        |pr
          373  +                        |wd
          374  +                        |note
          375  +                        |other)                 #IMPLIED
          376  +        other-doctype   CDATA                   #IMPLIED
          377  +        status          (int-review
          378  +                        |ext-review
          379  +                        |final)                 #IMPLIED
          380  +>
          381  +
          382  +<!ELEMENT front (div1+)>
          383  +<!ATTLIST front %common.att;>
          384  +
          385  +<!ELEMENT body (div1+)>
          386  +<!ATTLIST body %common.att;>
          387  +
          388  +<!--
          389  +#1997-09-30: maler: Added inform-div1 to back content.
          390  +-->
          391  +
          392  +<!ELEMENT back ((div1+, inform-div1*) | inform-div1+)>
          393  +<!ATTLIST back %common.att;>
          394  +
          395  +<!ELEMENT div1 (head, (%div.mix;)*, div2*)>
          396  +<!ATTLIST div1 %common.att;>
          397  +
          398  +<!--
          399  +#1997-09-30: maler: Added inform-div1 declarations.
          400  +-->
          401  +
          402  +<!--    inform-div1: Non-normative division in back matter -->
          403  +<!ELEMENT inform-div1 (head, (%div.mix;)*, div2*)>
          404  +<!ATTLIST inform-div1 %common.att;>
          405  +
          406  +<!ELEMENT div2 (head, (%div.mix;)*, div3*)>
          407  +<!ATTLIST div2 %common.att;>
          408  +
          409  +<!ELEMENT div3 (head, (%div.mix;)*, div4*)>
          410  +<!ATTLIST div3 %common.att;>
          411  +
          412  +<!ELEMENT div4 (head, (%div.mix;)*)>
          413  +<!ATTLIST div4 %common.att;>
          414  +
          415  +<!-- ............................................................... -->
          416  +<!-- Specification header .......................................... -->
          417  +<!-- ............................................................... -->
          418  +
          419  +<!--
          420  +#1998-03-10: maler: Made header content model easily customizable.
          421  +-->
          422  +
          423  +<!ELEMENT header (%header.mdl;)>
          424  +<!ATTLIST header %common.att;>
          425  +
          426  +<!--    Example of title: "Extensible Cheese Language (XCL)" -->
          427  +<!ELEMENT title (#PCDATA)>
          428  +<!ATTLIST title %common.att;>
          429  +
          430  +<!--    Example of subtitle: "A Cheesy Specification" -->
          431  +<!ELEMENT subtitle (#PCDATA)>
          432  +<!ATTLIST subtitle %common.att;>
          433  +
          434  +<!--    Example of version: "Version 666.0" -->
          435  +<!ELEMENT version (#PCDATA)>
          436  +<!ATTLIST version %common.att;>
          437  +
          438  +<!--    Example of w3c-designation: "WD-xcl-19991231" -->
          439  +<!ELEMENT w3c-designation (#PCDATA)>
          440  +<!ATTLIST w3c-designation %common.att;>
          441  +
          442  +<!--    Example of w3c-doctype: "World Wide Web Consortium Working
          443  +        Draft" -->
          444  +<!ELEMENT w3c-doctype (#PCDATA)>
          445  +<!ATTLIST w3c-doctype %common.att;>
          446  +
          447  +<!--
          448  +#1998-03-10: maler: Made pubdate content model easily customizable.
          449  +-->
          450  +
          451  +<!ELEMENT pubdate (%pubdate.mdl;)>
          452  +<!ATTLIST pubdate %common.att;>
          453  +
          454  +<!ELEMENT day (#PCDATA)>
          455  +<!ATTLIST day %common.att;>
          456  +
          457  +<!ELEMENT month (#PCDATA)>
          458  +<!ATTLIST month %common.att;>
          459  +
          460  +<!ELEMENT year (#PCDATA)>
          461  +<!ATTLIST year %common.att;>
          462  +
          463  +<!--
          464  +#1999-07-02: maler: Declared copyright element.
          465  +-->
          466  +
          467  +<!ELEMENT copyright (%hdr.mix;)+>
          468  +<!ATTLIST copyright %common.att;>
          469  +
          470  +<!--    Example of notice: "This draft is for public comment..." -->
          471  +<!ELEMENT notice (%hdr.mix;)+>
          472  +<!ATTLIST notice %common.att;>
          473  +
          474  +<!ELEMENT publoc (loc+)>
          475  +<!ATTLIST publoc %common.att;>
          476  +
          477  +<!ELEMENT prevlocs (loc+)>
          478  +<!ATTLIST prevlocs %common.att;>
          479  +
          480  +<!ELEMENT latestloc (loc+)>
          481  +<!ATTLIST latestloc %common.att;>
          482  +
          483  +<!--      loc (defined in "Phrase-level elements" below) -->
          484  +
          485  +<!ELEMENT authlist (author+)>
          486  +<!ATTLIST authlist %common.att;>
          487  +
          488  +<!--
          489  +#1997-09-30: maler: Made affiliation optional.
          490  +#1998-03-10: maler: Made email optional.
          491  +-->
          492  +
          493  +<!ELEMENT author (name, affiliation?, email?)>
          494  +<!ATTLIST author %common.att;>
          495  +
          496  +<!ELEMENT name (#PCDATA)>
          497  +<!ATTLIST name
          498  +        %common.att;
          499  +        %key.att;>
          500  +
          501  +<!ELEMENT affiliation (#PCDATA)>
          502  +<!ATTLIST affiliation %common.att;>
          503  +
          504  +<!--
          505  +#1999-07-02: maler: Added show/actuate attributes and default values.
          506  +-->
          507  +
          508  +
          509  +<!ELEMENT email (#PCDATA)>
          510  +<!--    href attribute:
          511  +        email functions as a hypertext reference through this
          512  +        required attribute.  Typically the reference would use
          513  +        the mailto: scheme.  E.g.:
          514  +
          515  +<email href="mailto:elm@arbortext.com">elm@arbortext.com</email>
          516  +        -->
          517  +
          518  +<!ATTLIST email
          519  +        %common.att;
          520  +        %simple-xlink.att;
          521  +        %href-req.att;
          522  +        %user-new.att;>
          523  +
          524  +<!--
          525  +#1998-05-15: maler: Changed status content from %statusobj.mix;
          526  +#                   to plain %obj.mix;.  statusp is obsolete.
          527  +-->
          528  +
          529  +<!ELEMENT status (%obj.mix;)+>
          530  +<!ATTLIST status %common.att;>
          531  +
          532  +<!ELEMENT abstract (%hdr.mix;)*>
          533  +<!ATTLIST abstract %common.att;>
          534  +
          535  +<!ELEMENT pubstmt (%hdr.mix;)+>
          536  +<!ATTLIST pubstmt %common.att;>
          537  +
          538  +<!ELEMENT sourcedesc (%hdr.mix;)+>
          539  +<!ATTLIST sourcedesc %common.att;>
          540  +
          541  +<!ELEMENT langusage (language+)>
          542  +<!ATTLIST langusage %common.att;>
          543  +
          544  +<!ELEMENT language (#PCDATA)>
          545  +<!ATTLIST language %common.att;>
          546  +
          547  +<!ELEMENT revisiondesc (%hdr.mix;)+>
          548  +<!ATTLIST revisiondesc %common.att;>
          549  +
          550  +<!-- ............................................................... -->
          551  +<!-- Paragraph ..................................................... -->
          552  +<!-- ............................................................... -->
          553  +
          554  +<!--
          555  +#1997-09-30: maler: Changed from %obj.mix; to %p.mix;.
          556  +#1997-12-29: maler: Changed order of %p.mix; and %p.pcd.mix;
          557  +#                   references.
          558  +#1997-12-29: maler: Changed order of %statusobj.mix; and
          559  +#                   %statusp.pcd.mix; references.
          560  +#1998-05-14: maler: Removed statusp declarations.
          561  +-->
          562  +
          563  +<!ELEMENT p (%p.pcd.mix;|%p.mix;)*>
          564  +<!ATTLIST p %common.att;>
          565  +
          566  +<!-- ............................................................... -->
          567  +<!-- Regular lists ................................................. -->
          568  +<!-- ............................................................... -->
          569  +
          570  +<!--    ulist: Unordered list, typically bulleted. -->
          571  +<!ELEMENT ulist (item+)>
          572  +<!--    spacing attribute:
          573  +        Use "normal" to get normal vertical spacing for items;
          574  +        use "compact" to get less spacing.  The default is dependent
          575  +        on the stylesheet. -->
          576  +<!ATTLIST ulist
          577  +        %common.att;
          578  +        spacing         (normal|compact)        #IMPLIED>
          579  +
          580  +<!--    olist: Ordered list, typically numbered. -->
          581  +<!ELEMENT olist (item+)>
          582  +<!--    spacing attribute:
          583  +        Use "normal" to get normal vertical spacing for items;
          584  +        use "compact" to get less spacing.  The default is dependent
          585  +        on the stylesheet. -->
          586  +<!ATTLIST olist
          587  +        %common.att;
          588  +        spacing         (normal|compact)        #IMPLIED>
          589  +
          590  +<!ELEMENT item (%obj.mix;)+>
          591  +<!ATTLIST item %common.att;>
          592  +
          593  +<!--    slist: Simple list, typically with no mark. -->
          594  +<!ELEMENT slist (sitem+)>
          595  +<!ATTLIST slist %common.att;>
          596  +
          597  +<!ELEMENT sitem (%p.pcd.mix;)*>
          598  +<!ATTLIST sitem %common.att;>
          599  +
          600  +<!--    glist: Glossary list, typically two-column. -->
          601  +<!ELEMENT glist (gitem+)>
          602  +<!ATTLIST glist %common.att;>
          603  +
          604  +<!ELEMENT gitem (label, def)>
          605  +<!ATTLIST gitem %common.att;>
          606  +
          607  +<!ELEMENT label (%label.pcd.mix;)*>
          608  +<!ATTLIST label %common.att;>
          609  +
          610  +<!ELEMENT def (%obj.mix;)*>
          611  +<!ATTLIST def %common.att;>
          612  +
          613  +<!-- ............................................................... -->
          614  +<!-- Special lists ................................................. -->
          615  +<!-- ............................................................... -->
          616  +
          617  +<!--    blist: Bibliography list. -->
          618  +<!ELEMENT blist (bibl+)>
          619  +<!ATTLIST blist %common.att;>
          620  +
          621  +<!--
          622  +#1999-07-02: maler: Added show/actuate attributes and default values.
          623  +-->
          624  +
          625  +<!ELEMENT bibl (%bibl.pcd.mix;)*>
          626  +<!--    href attribute:
          627  +        bibl optionally functions as a hypertext reference to the
          628  +        referred-to resource through this attribute.  E.g.:
          629  +
          630  +        <bibl href="http://www.my.com/doc.htm">My Document</bibl>
          631  +        -->
          632  +<!ATTLIST bibl
          633  +        %common.att;
          634  +        %simple-xlink.att;
          635  +        %href.att;
          636  +        %user-replace.att;
          637  +        %key.att;>
          638  +
          639  +<!--    orglist: Organization member list. -->
          640  +<!ELEMENT orglist (member+)>
          641  +<!ATTLIST orglist %common.att;>
          642  +
          643  +<!--
          644  +#1997-09-30: maler: Added optional affiliation.
          645  +-->
          646  +
          647  +<!ELEMENT member (name, affiliation?, role?)>
          648  +<!ATTLIST member %common.att;>
          649  +
          650  +<!--      name (defined in "Specification header" above) -->
          651  +<!--      affiliation (defined in "Specification header" above) -->
          652  +
          653  +<!ELEMENT role (#PCDATA)>
          654  +<!ATTLIST role %common.att;>
          655  +
          656  +<!-- ............................................................... -->
          657  +<!-- Notes ......................................................... -->
          658  +<!-- ............................................................... -->
          659  +
          660  +<!ELEMENT note (%obj.mix;)+>
          661  +<!ATTLIST note %common.att;>
          662  +
          663  +<!--
          664  +#1998-05-14: maler: Declared issue element.
          665  +-->
          666  +
          667  +<!ELEMENT issue (%obj.mix;)+>
          668  +<!ATTLIST issue %common-idreq.att;>
          669  +
          670  +<!--    wfcnote: Well-formedness constraint note. -->
          671  +<!ELEMENT wfcnote (head, (%obj.mix;)+)>
          672  +<!--    ID attribute:
          673  +        wfcnote must have an ID so that it can be pointed to
          674  +        from a wfc element in a production. -->
          675  +<!ATTLIST wfcnote
          676  +        %common-idreq.att;>
          677  +
          678  +<!--    vcnote: Validity constraint note. -->
          679  +<!ELEMENT vcnote (head, (%obj.mix;)+)>
          680  +<!--    ID attribute:
          681  +        vcnote must have an ID so that it can be pointed to
          682  +        from a vc element in a production. -->
          683  +<!ATTLIST vcnote
          684  +        %common-idreq.att;>
          685  +
          686  +<!--
          687  +#1998-05-21: maler: Declared generic constraintnote element.
          688  +-->
          689  +
          690  +<!--    constraintnote: Generic constraint note. -->
          691  +<!ELEMENT constraintnote (head, (%obj.mix;)+)>
          692  +<!--    ID attribute:
          693  +        constraintnote must have an ID so that it can be
          694  +        pointed to from a constraint element in a production. -->
          695  +<!--    type attribute:
          696  +        constraintnote must have a type value keyword so that
          697  +        it can be correctly characterized in the specification. -->
          698  +<!ATTLIST constraintnote
          699  +        %common-idreq.att;
          700  +        type            NMTOKEN         #REQUIRED>
          701  +
          702  +<!-- ............................................................... -->
          703  +<!-- Basic display elements ........................................ -->
          704  +<!-- ............................................................... -->
          705  +
          706  +<!--
          707  +#1998-03-23: maler: Added xml:space attribute.
          708  +-->
          709  +
          710  +<!--    eg: Example element, with whitespace respected. -->
          711  +<!ELEMENT eg (%eg.pcd.mix;)*>
          712  +<!ATTLIST eg
          713  +        %common.att;
          714  +        %xmlspace.att;>
          715  +
          716  +<!--    graphic: Displayed graphic.  Graphic data should be
          717  +        displayed at the point where it is referenced. -->
          718  +<!ELEMENT graphic EMPTY>
          719  +<!--    source attribute:
          720  +        The graphic data must reside at the location pointed to.
          721  +        This is a hypertext reference, but for practical purposes,
          722  +        for now it should just be a pathname. -->
          723  +<!ATTLIST graphic
          724  +        %common.att;
          725  +        %simple-xlink.att;
          726  +        xml:attributes          NMTOKENS        #FIXED "href source"
          727  +        source                  CDATA           #REQUIRED
          728  +        %auto-embed.att;
          729  +        alt                     CDATA           #IMPLIED>
          730  +
          731  +<!-- ............................................................... -->
          732  +<!-- EBNF .......................................................... -->
          733  +<!-- ............................................................... -->
          734  +
          735  +<!--
          736  +#1997-11-28: maler: Added prodgroup to scrap and defined it.
          737  +#1998-05-21: maler: Added constraint to prod.
          738  +#1999-07-02: maler: Added prodrecap to scrap; broadened scrap model.
          739  +#                   Added headstyle attribute to scrap.
          740  +-->
          741  +
          742  +<!--    scrap: Collection of EBNF language productions. -->
          743  +<!ELEMENT scrap (head, (prodgroup | prod | bnf | prodrecap)+)>
          744  +<!--    lang attribute:
          745  +        The scrap can link to a description of the language used,
          746  +        found in a language element in the header.
          747  +        headstyle attribute:
          748  +        Allows a scrap title to be suppressed from output.  To be
          749  +        used only when a scrap title directly next to a section
          750  +        title is distracting or repetetive. -->
          751  +<!ATTLIST scrap
          752  +        %common.att;
          753  +        lang            IDREF           #IMPLIED
          754  +        headstyle       (show|suppress) "show"
          755  +>
          756  +
          757  +<!--    prodgroup: Sub-collection of productions, needed for
          758  +        formatting reasons. -->
          759  +<!ELEMENT prodgroup (prod+)>
          760  +<!--    pcw<n> attributes:
          761  +        Presentational attributes to control the width
          762  +        of the "pseudo-table" columns used to output
          763  +        groups of productions. -->
          764  +<!ATTLIST prodgroup
          765  +        %common.att;
          766  +        pcw1            CDATA           #IMPLIED
          767  +        pcw2            CDATA           #IMPLIED
          768  +        pcw3            CDATA           #IMPLIED
          769  +        pcw4            CDATA           #IMPLIED
          770  +        pcw5            CDATA           #IMPLIED
          771  +>
          772  +
          773  +<!--    prod: EBNF language production. -->
          774  +<!ELEMENT prod (lhs, (rhs, (com|wfc|vc|constraint)*)+)>
          775  +<!--    ID attribute:
          776  +        The production must have an ID so that cross-references
          777  +        (specref) and mentions of nonterminals (nt) can link to
          778  +        it. -->
          779  +<!ATTLIST prod
          780  +        %common-idreq.att;>
          781  +
          782  +<!--    lhs: Left-hand side of production. -->
          783  +<!ELEMENT lhs (#PCDATA)>
          784  +<!ATTLIST lhs %common.att;>
          785  +
          786  +<!--    rhs: Right-hand side of production; may have many
          787  +        "right-hand sides," one to a line. -->
          788  +<!ELEMENT rhs (#PCDATA|nt|xnt|com)*>
          789  +<!ATTLIST rhs %common.att;>
          790  +
          791  +<!--      nt and xnt (defined in "Phrase-level elements" below) -->
          792  +
          793  +<!--
          794  +#1997-11-28: maler: Added loc and bibref to com content.
          795  +-->
          796  +
          797  +<!--    com: Production comment. -->
          798  +<!ELEMENT com (#PCDATA|loc|bibref)*>
          799  +<!ATTLIST com %common.att;>
          800  +
          801  +<!--    wfc: Reference to a well-formedness constraint; should
          802  +        generate the head of the wfcnote pointed to. -->
          803  +<!ELEMENT wfc EMPTY>
          804  +<!--    def attribute:
          805  +        Each well formedness tagline in a production must link to the
          806  +        wfcnote that defines it. -->
          807  +<!ATTLIST wfc
          808  +        %def-req.att;
          809  +        %common.att;>
          810  +
          811  +<!--    vc: Reference to a validity constraint; should generate
          812  +        the head of the vcnote pointed to. -->
          813  +<!ELEMENT vc EMPTY>
          814  +<!--    def attribute:
          815  +        Each validity tagline in a production must link to the vcnote
          816  +        that defines it. -->
          817  +<!ATTLIST vc
          818  +        %def-req.att;
          819  +        %common.att;>
          820  +
          821  +<!--
          822  +#1998-05-21: maler: Declared generic constraint element.
          823  +-->
          824  +
          825  +<!--    constraint: Reference to a generic constraint; should
          826  +        generate the head of the constraintnote pointed to. -->
          827  +<!ELEMENT constraint EMPTY>
          828  +<!--    def attribute:
          829  +        Each constraint tagline in a production must link to the
          830  +        constraint note that defines it. -->
          831  +<!ATTLIST constraint
          832  +        %def-req.att;
          833  +        %common.att;>
          834  +
          835  +<!--
          836  +#1998-03-23: maler: Added xml:space attribute.
          837  +-->
          838  +
          839  +<!--    bnf: Un-marked-up EBNF production, with whitespace
          840  +        respected. -->
          841  +<!ELEMENT bnf (%eg.pcd.mix;)*>
          842  +<!ATTLIST bnf
          843  +        %common.att;
          844  +        %xmlspace.att;>
          845  +
          846  +<!--
          847  +#1999-07-02: maler: Declared prodrecap.
          848  +-->
          849  +
          850  +<!--    prodrecap: Reference to production or bnf that appears
          851  +        in its "normative" form elsewhere in the spec; should
          852  +        generate a copy of the original production, without
          853  +        a production number next to it. -->
          854  +<!ELEMENT prodrecap EMPTY>
          855  +<!ATTLIST prodrecap
          856  +        %common.att;
          857  +        %ref-req.att;>
          858  +
          859  +<!-- ............................................................... -->
          860  +<!-- Table ......................................................... -->
          861  +<!-- ............................................................... -->
          862  +
          863  +<!--
          864  +#1997-10-16: maler: Added table mechanism.
          865  +#1997-11-28: maler: Added non-null system ID to entity declaration.
          866  +#                   Added HTML table module.
          867  +#1997-12-29: maler: IGNOREd SGML Open table model.
          868  +#1998-03-10: maler: Removed SGML Open table model.
          869  +#                   Merged html-tbl.mod file into main file.
          870  +#                   Added %common.att; to all HTML table elements.
          871  +#1998-05-14: maler: Replaced table model with full HTML 4.0 model.
          872  +#                   Removed htable in favor of table.
          873  +#                   Removed htbody in favor of tbody.
          874  +-->
          875  +
          876  +<!ENTITY % cellhalign.att
          877  +        'align          (left|center
          878  +                        |right|justify
          879  +                        |char)          #IMPLIED
          880  +        char            CDATA           #IMPLIED
          881  +        charoff         CDATA           #IMPLIED'>
          882  +
          883  +<!ENTITY % cellvalign.att
          884  +        'valign         (top|middle
          885  +                        |bottom
          886  +                        |baseline)      #IMPLIED'>
          887  +
          888  +<!ENTITY % thtd.att
          889  +        'abbr           CDATA           #IMPLIED
          890  +        axis            CDATA           #IMPLIED
          891  +        headers         IDREFS          #IMPLIED
          892  +        scope           (row
          893  +                        |col
          894  +                        |rowgroup
          895  +                        |colgroup)      #IMPLIED
          896  +        rowspan         NMTOKEN         "1"
          897  +        colspan         NMTOKEN         "1"'>
          898  +
          899  +<!ENTITY % width.att
          900  +        'width          CDATA           #IMPLIED'>
          901  +
          902  +<!ENTITY % span.att
          903  +        'span           NMTOKEN         "1"'>
          904  +
          905  +<!--    table: HTML-based geometric table model. -->
          906  +<!ELEMENT table
          907  +        (caption?, (col*|colgroup*), thead?, tfoot?, tbody+)>
          908  +<!ATTLIST table
          909  +        %common.att;
          910  +        %width.att;
          911  +        summary         CDATA           #IMPLIED
          912  +        border          CDATA           #IMPLIED
          913  +        frame           (void|above
          914  +                        |below|hsides
          915  +                        |lhs|rhs
          916  +                        |vsides|box
          917  +                        |border)        #IMPLIED
          918  +        rules           (none|groups
          919  +                        |rows|cols
          920  +                        |all)           #IMPLIED
          921  +        cellspacing     CDATA           #IMPLIED
          922  +        cellpadding     CDATA           #IMPLIED>
          923  +
          924  +<!ELEMENT caption (%p.pcd.mix;)*>
          925  +<!ATTLIST caption %common.att;>
          926  +
          927  +<!ELEMENT col EMPTY>
          928  +<!ATTLIST col
          929  +        %common.att;
          930  +        %span.att;
          931  +        %width.att;
          932  +        %cellhalign.att;
          933  +        %cellvalign.att;>
          934  +
          935  +<!ELEMENT colgroup (col)*>
          936  +<!ATTLIST colgroup
          937  +        %common.att;
          938  +        %span.att;
          939  +        %width.att;
          940  +        %cellhalign.att;
          941  +        %cellvalign.att;>
          942  +
          943  +<!ELEMENT thead (tr)+>
          944  +<!ATTLIST thead
          945  +        %common.att;
          946  +        %cellhalign.att;
          947  +        %cellvalign.att;>
          948  +
          949  +<!ELEMENT tfoot (tr)+>
          950  +<!ATTLIST tfoot
          951  +        %common.att;
          952  +        %cellhalign.att;
          953  +        %cellvalign.att;>
          954  +
          955  +<!ELEMENT tbody (tr)+>
          956  +<!ATTLIST tbody
          957  +        %common.att;
          958  +        %cellhalign.att;
          959  +        %cellvalign.att;>
          960  +
          961  +<!ELEMENT tr (th|td)+>
          962  +<!ATTLIST tr
          963  +        %common.att;
          964  +        %cellhalign.att;
          965  +        %cellvalign.att;>
          966  +
          967  +<!ELEMENT th (%p.pcd.mix;|%p.mix;)*>
          968  +<!ATTLIST th
          969  +        %common.att;
          970  +        %thtd.att;
          971  +        %cellhalign.att;
          972  +        %cellvalign.att;>
          973  +
          974  +<!ELEMENT td (%p.pcd.mix;|%p.mix;)*>
          975  +<!ATTLIST td
          976  +        %common.att;
          977  +        %thtd.att;
          978  +        %cellhalign.att;
          979  +        %cellvalign.att;>
          980  +
          981  +<!-- ............................................................... -->
          982  +<!-- IDL structures for DOM specifications ......................... -->
          983  +<!-- ............................................................... -->
          984  +
          985  +<!-- ............................................................... -->
          986  +<!-- Specialized entities for classes .............................. -->
          987  +
          988  +<!ENTITY % idl-desc.class
          989  +        "p|note">
          990  +
          991  +<!ENTITY % idl-tdef.class
          992  +        "typedef|constant|exception|reference|group">
          993  +
          994  +<!ENTITY % idl-mod.class
          995  +        "module|interface">
          996  +
          997  +<!ENTITY % idl-struct.class
          998  +        "struct|enum|sequence|union|typename">
          999  +
         1000  +<!ENTITY % idl-meth.class
         1001  +        "method|attribute">
         1002  +
         1003  +<!-- ............................................................... -->
         1004  +<!-- Specialized entities for mixtures ............................. -->
         1005  +
         1006  +<!--    Quick reference to content model mixtures:
         1007  +
         1008  +                        desc tdef mod struct meth
         1009  +group                     x    x   x    x      x
         1010  +definitions, module       x    x   x
         1011  +interface                 x    x               x
         1012  +typedef, case, component                x
         1013  +-->
         1014  +
         1015  +<!ENTITY % idl-grp.mix
         1016  +        "%idl-desc.class;|%idl-tdef.class;|%idl-mod.class;
         1017  +        |%idl-struct.class;|%idl-meth.class;">
         1018  +
         1019  +<!ENTITY % idl-defn.mix
         1020  +        "%idl-desc.class;|%idl-tdef.class;|%idl-mod.class;">
         1021  +
         1022  +<!ENTITY % idl-intfc.mix
         1023  +        "%idl-desc.class;|%idl-tdef.class;|%idl-meth.class;">
         1024  +
         1025  +<!ENTITY % idl-type.mix
         1026  +        "%idl-struct.class;">
         1027  +
         1028  +<!-- ............................................................... -->
         1029  +<!-- Specialized entities for common attributes .................... -->
         1030  +
         1031  +<!--    name attribute:
         1032  +        Provides a name.  Required. -->
         1033  +<!ENTITY % idl-name.att
         1034  +        'name                   CDATA           #REQUIRED'>
         1035  +
         1036  +<!--    type attribute:
         1037  +        Provides a type.  Required. -->
         1038  +<!ENTITY % idl-type.att
         1039  +        'type                   CDATA           #REQUIRED'>
         1040  +
         1041  +<!-- ............................................................... -->
         1042  +<!-- Common IDL element ............................................ -->
         1043  +
         1044  +<!ELEMENT descr ((%obj.mix;)*)>
         1045  +<!ATTLIST descr %common.att;>
         1046  +
         1047  +<!-- ............................................................... -->
         1048  +<!-- IDL definition elements ....................................... -->
         1049  +
         1050  +<!--    definitions: Top-level element for definitions. -->
         1051  +<!ELEMENT definitions (%idl-defn.mix;)+>
         1052  +<!ATTLIST definitions %common.att;>
         1053  +
         1054  +<!--    group: Element used to group a set of definitions. -->
         1055  +
         1056  +<!ELEMENT group (descr, (%idl-grp.mix;)*)>
         1057  +<!ATTLIST group
         1058  +        %common.att;
         1059  +        %idl-name.att;>
         1060  +
         1061  +<!--    interface: Definition of an interface. -->
         1062  +<!ELEMENT interface (descr, (%idl-intfc.mix;)*)>
         1063  +<!ATTLIST interface
         1064  +        %common.att;
         1065  +        %idl-name.att;
         1066  +        inherits        CDATA           #IMPLIED>
         1067  +
         1068  +<!--    module: Definition of a module. -->
         1069  +<!ELEMENT module (descr, (%idl-defn.mix;)*)>
         1070  +<!ATTLIST module
         1071  +        %common.att;
         1072  +        %idl-name.att;>
         1073  +
         1074  +<!--    reference: Reference to some other declaration. -->
         1075  +<!ELEMENT reference EMPTY>
         1076  +<!ATTLIST reference
         1077  +        %common.att;
         1078  +        declaration     IDREF           #REQUIRED>
         1079  +
         1080  +<!--    typedef: Definition of a named type. -->
         1081  +<!ELEMENT typedef (descr, (%idl-type.mix;))>
         1082  +<!ATTLIST typedef
         1083  +        %common.att;
         1084  +        %idl-name.att;
         1085  +        array.size      NMTOKEN         #IMPLIED>
         1086  +
         1087  +<!--    struct: Declaration of a struct type. -->
         1088  +<!ELEMENT struct (descr, component+)>
         1089  +<!ATTLIST struct
         1090  +        %common.att;
         1091  +        %idl-name.att;>
         1092  +
         1093  +<!--    component: Declaration of a structural member. -->
         1094  +<!ELEMENT component (%idl-type.mix;)>
         1095  +<!ATTLIST component
         1096  +        %common.att;
         1097  +        %idl-name.att;>
         1098  +
         1099  +<!--    union: Declaration of a union type. -->
         1100  +<!ELEMENT union (descr, case+)>
         1101  +<!ATTLIST union
         1102  +        %common.att;
         1103  +        %idl-name.att;
         1104  +        switch.type     CDATA           #REQUIRED>
         1105  +
         1106  +<!ELEMENT case (descr, (%idl-type.mix;))>
         1107  +<!ATTLIST case
         1108  +        %common.att;
         1109  +        labels          CDATA           #REQUIRED>
         1110  +
         1111  +<!--    enum: Declaration of an enum type. -->
         1112  +<!ELEMENT enum (descr, enumerator+)>
         1113  +<!ATTLIST enum
         1114  +        %common.att;
         1115  +        %idl-name.att;>
         1116  +
         1117  +<!ELEMENT enumerator (descr)>
         1118  +<!ATTLIST enumerator
         1119  +        %common.att;
         1120  +        %idl-name.att;>
         1121  +
         1122  +<!--    sequence: Declaration of a sequence type (not named). -->
         1123  +<!ELEMENT sequence (sequence*)>
         1124  +<!ATTLIST sequence
         1125  +        %common.att;
         1126  +        %idl-type.att;
         1127  +        size            NMTOKEN         #IMPLIED>
         1128  +
         1129  +<!--    constant: Declaration of a named constant. -->
         1130  +<!ELEMENT constant (descr)>
         1131  +<!ATTLIST constant
         1132  +        %common.att;
         1133  +        %idl-name.att;
         1134  +        %idl-type.att;
         1135  +        value           CDATA           #REQUIRED>
         1136  +
         1137  +<!--    exception: Declaration of an exception. -->
         1138  +<!ELEMENT exception (descr, component*)>
         1139  +<!ATTLIST exception
         1140  +        %common.att;
         1141  +        %idl-name.att;>
         1142  +<!-- component (defined under struct, above)-->
         1143  +
         1144  +<!--    attribute: Declaration of an attribute (data member). -->
         1145  +<!ELEMENT attribute (descr)>
         1146  +<!ATTLIST attribute
         1147  +        %common.att;
         1148  +        %idl-name.att;
         1149  +        %idl-type.att;
         1150  +        readonly        (yes
         1151  +                        |no)            "no">
         1152  +
         1153  +<!--    method: Declaration of a method. -->
         1154  +<!ELEMENT method (descr, parameters, returns, raises)>
         1155  +<!ATTLIST method
         1156  +        %common.att;
         1157  +        %idl-name.att;>
         1158  +
         1159  +<!ELEMENT parameters (param*)>
         1160  +<!ATTLIST parameters %common.att;>
         1161  +
         1162  +<!ELEMENT param (descr)>
         1163  +<!ATTLIST param
         1164  +        %common.att;
         1165  +        %idl-name.att;
         1166  +        %idl-type.att;
         1167  +        attr            (in
         1168  +                        |out
         1169  +                        |inout)         "inout">
         1170  +
         1171  +<!ELEMENT returns (descr)>
         1172  +<!ATTLIST returns
         1173  +        %common.att;
         1174  +        %idl-type.att;>
         1175  +
         1176  +<!ELEMENT raises (exception*)>
         1177  +<!-- exception (defined under constant, above)-->
         1178  +
         1179  +<!ELEMENT typename (#PCDATA)>
         1180  +<!ATTLIST typename %common.att;>
         1181  +
         1182  +<!-- ............................................................... -->
         1183  +<!-- Phrase-level elements ......................................... -->
         1184  +<!-- ............................................................... -->
         1185  +
         1186  +<!--    bibref: Reference to a bibliography list entry; should
         1187  +        generate, in square brackets, "key" on bibl. -->
         1188  +<!ELEMENT bibref EMPTY>
         1189  +<!--    ref attribute:
         1190  +        A bibliography reference must link to the bibl element that
         1191  +        describes the resource. -->
         1192  +<!ATTLIST bibref
         1193  +        %common.att;
         1194  +        %ref-req.att;>
         1195  +
         1196  +<!ELEMENT code (%tech.pcd.mix;)*>
         1197  +<!ATTLIST code %common.att;>
         1198  +
         1199  +<!--
         1200  +#1998-03-10: maler: Declared ednote and related elements.
         1201  +#1999-07-02: maler: Changed edtext content from #PCDATA to %p.pcd.mix;.
         1202  +-->
         1203  +
         1204  +<!--    ednote: Editorial note for communication among editors. -->
         1205  +<!ELEMENT ednote (name?, date?, edtext)>
         1206  +<!ATTLIST ednote %common.att;>
         1207  +
         1208  +<!ELEMENT date (#PCDATA)>
         1209  +<!ATTLIST date %common.att;>
         1210  +
         1211  +<!ELEMENT edtext (%p.pcd.mix;)*>
         1212  +<!ATTLIST edtext %common.att;>
         1213  +
         1214  +<!ELEMENT emph (#PCDATA)>
         1215  +<!ATTLIST emph %common.att;>
         1216  +
         1217  +<!--    footnote: Both footnote content and call to footnote. -->
         1218  +<!ELEMENT footnote (%obj.mix;)+>
         1219  +<!ATTLIST footnote %common.att;>
         1220  +
         1221  +<!ELEMENT kw (%tech.pcd.mix;)*>
         1222  +<!ATTLIST kw %common.att;>
         1223  +
         1224  +<!--
         1225  +#1999-07-02: maler: Added show/actuate attributes and default values.
         1226  +-->
         1227  +
         1228  +<!--    loc: Generic link to a Web resource, similar to HTML's A. -->
         1229  +<!ELEMENT loc (#PCDATA)>
         1230  +<!--    href attribute:
         1231  +        The purpose of a loc element is to function as a A-like
         1232  +        hypertext link to a resource.  (Ideally, the content of loc
         1233  +        will also mention the URI of the resource, so that readers of
         1234  +        the printed version will be able to locate the resource.) E.g.:
         1235  +
         1236  +<loc href="http://www.my.com/doc.htm">http://www.my.com/doc.htm</loc>
         1237  +        -->
         1238  +<!ATTLIST loc
         1239  +        %common.att;
         1240  +        %simple-xlink.att;
         1241  +        %href-req.att;
         1242  +        %user-replace.att;>
         1243  +
         1244  +<!--    nt: Mention of a nonterminal in text, along with a link to
         1245  +        the production in the current document that defines it. -->
         1246  +<!ELEMENT nt (#PCDATA)>
         1247  +<!--    def attribute:
         1248  +        The nonterminal must link to the production that defines
         1249  +        it. -->
         1250  +<!ATTLIST nt
         1251  +        %common.att;
         1252  +        %def-req.att;>
         1253  +
         1254  +<!--
         1255  +#1998-03-10: maler: Declared quote.
         1256  +-->
         1257  +
         1258  +<!--    quote: Scare quotes and other purely presentational quotes. -->
         1259  +<!ELEMENT quote (%p.pcd.mix;)*>
         1260  +<!ATTLIST quote %common.att;>
         1261  +
         1262  +<!--    specref: Reference to a div, olist item, prod, or issue
         1263  +        in the current document; should generate italic "[n.n],
         1264  +        Section Title" for div, "n" for numbered item, "[n]" for
         1265  +        production, or "Issue n" for issue. -->
         1266  +<!ELEMENT specref EMPTY>
         1267  +<!--    ref attribute:
         1268  +        The purpose of a specref element is to link to a div, item
         1269  +        in an olist, or production in the current spec. -->
         1270  +<!ATTLIST specref
         1271  +        %common.att;
         1272  +        %ref-req.att;>
         1273  +
         1274  +<!--    term: The term in text that is being defined in text. -->
         1275  +<!ELEMENT term (#PCDATA)>
         1276  +<!ATTLIST term %common.att;>
         1277  +
         1278  +<!--    termdef: Definition of a term in text. -->
         1279  +<!ELEMENT termdef (%termdef.pcd.mix;|%termdef.mix;)*>
         1280  +<!--    ID attribute:
         1281  +        A term definition must have an ID so that it can be linked
         1282  +        to from termref elements. -->
         1283  +<!--    term attribute:
         1284  +        The canonical form of the term or phrase being defined must
         1285  +        appear in this attribute, even if the term or phrase also
         1286  +        appears in the element content in identical form (e.g., in
         1287  +        the term element). -->
         1288  +<!ATTLIST termdef
         1289  +        %common-idreq.att;
         1290  +        term            CDATA           #REQUIRED>
         1291  +
         1292  +<!--    termref: Mention of a term, along with a link to the
         1293  +        definition in the current document. -->
         1294  +<!ELEMENT termref (#PCDATA)>
         1295  +<!--    ref attribute:
         1296  +        A term reference must link to the termdef element that
         1297  +        defines the term. -->
         1298  +<!ATTLIST termref
         1299  +        %common.att;
         1300  +        %def-req.att;>
         1301  +
         1302  +<!--
         1303  +#1999-07-02: maler: Added show/actuate attributes and default values.
         1304  +-->
         1305  +
         1306  +<!--    titleref: Citation of another document, which can also
         1307  +        link to that document if it is a Web resource. -->
         1308  +<!ELEMENT titleref (#PCDATA)>
         1309  +<!--    href attribute:
         1310  +        A title reference can optionally function as a hypertext
         1311  +        link to the resource with this title.  E.g.:
         1312  +
         1313  +<loc href="http://www.my.com/doc.htm">http://www.my.com/doc.htm</loc>
         1314  +        -->
         1315  +
         1316  +<!ATTLIST titleref
         1317  +        %common.att;
         1318  +        %simple-xlink.att;
         1319  +        %href.att;
         1320  +        %user-new.att;>
         1321  +
         1322  +<!--
         1323  +#1999-07-02: maler: Added show/actuate attributes and default values.
         1324  +-->
         1325  +
         1326  +<!--    nt: Mention of a nonterminal in text, along with a link to
         1327  +        the production in another document that defines it. -->
         1328  +<!ELEMENT xnt (#PCDATA)>
         1329  +<!--    href attribute:
         1330  +        The nonterminal must hyperlink to a resource that serves
         1331  +        to define it (e.g., a production in a related XML
         1332  +        specification).  E.g.:
         1333  +
         1334  +<xnt href="http://www.w3.org/TR/spec.htm#prod3">Name</xnt>
         1335  +        -->
         1336  +
         1337  +<!ATTLIST xnt
         1338  +        %common.att;
         1339  +        %simple-xlink.att;
         1340  +        %href-req.att;
         1341  +        %user-new.att;>
         1342  +
         1343  +<!--
         1344  +#1997-12-29: maler: Declared xspecref.
         1345  +#1999-07-02: maler: Added show/actuate attributes and default values.
         1346  +-->
         1347  +
         1348  +<!--    specref: Reference to a div, olist item, prod, or issue
         1349  +        in a related specification document; should generate
         1350  +        no special text. -->
         1351  +<!ELEMENT xspecref (#PCDATA)>
         1352  +<!--    href attribute:
         1353  +        The spec reference must hyperlink to the resource to
         1354  +        cross-refer to (e.g., a section in a related XML
         1355  +        specification).  E.g.:
         1356  +
         1357  +<xspecref href="http://www.w3.org/TR/spec.htm#sec2">
         1358  +the section on constraints</xspecref>
         1359  +        -->
         1360  +
         1361  +<!ATTLIST xspecref
         1362  +        %common.att;
         1363  +        %simple-xlink.att;
         1364  +        %href-req.att;
         1365  +        %user-new.att;>
         1366  +
         1367  +<!--
         1368  +#1999-07-02: maler: Added show/actuate attributes and default values.
         1369  +-->
         1370  +
         1371  +<!--    termref: Mention of a term, along with a link to the
         1372  +        definition in a related document. -->
         1373  +<!ELEMENT xtermref (#PCDATA)>
         1374  +<!--    href attribute:
         1375  +        The term reference must hyperlink to the resource that
         1376  +        serves to define the term (e.g., a term definition in
         1377  +        a related XML specification).  E.g.:
         1378  +
         1379  +<xtermref href="http://www.w3.org/TR/spec.htm#term5">
         1380  +entity
         1381  +</xtermref>
         1382  +        -->
         1383  +
         1384  +<!ATTLIST xtermref
         1385  +        %common.att;
         1386  +        %simple-xlink.att;
         1387  +        %href-req.att;
         1388  +        %user-new.att;>
         1389  +
         1390  +<!-- ............................................................... -->
         1391  +<!-- Unused elements for ADEPT ..................................... -->
         1392  +<!-- ............................................................... -->
         1393  +
         1394  +<!--
         1395  +#1997-09-30: maler: Added unusued elements.
         1396  +#1997-10-14: maler: Fixed div to move nested div to the mixture.
         1397  +#1998-05-14: maler: Added key-term, htable, and htbody.
         1398  +#1998-11-30: maler: Added para, listitem, itemizedlist, and orderedlist.
         1399  +-->
         1400  +
         1401  +<!--    The following elements are purposely declared but never
         1402  +        referenced.  Declaring them allows them to be pasted from
         1403  +        an HTML document, an earlier version of an XMLspec document,
         1404  +        or a DocBook document into a document using this DTD in ADEPT.
         1405  +        The ATD Context Transformation mechanism will try to convert
         1406  +        them to the appropriate element for this DTD.  While this
         1407  +        conversion will not work for all fragments, it does allow many
         1408  +        cases to work reasonably well. -->
         1409  +
         1410  +<!ELEMENT div
         1411  +        (head?, (%div.mix;|ul|ol|h1|h2|h3|h4|h5|h6|div)*)>
         1412  +<!ELEMENT h1 (%head.pcd.mix;|em|a)*>
         1413  +<!ELEMENT h2 (%head.pcd.mix;|em|a)*>
         1414  +<!ELEMENT h3 (%head.pcd.mix;|em|a)*>
         1415  +<!ELEMENT h4 (%head.pcd.mix;|em|a)*>
         1416  +<!ELEMENT h5 (%head.pcd.mix;|em|a)*>
         1417  +<!ELEMENT h6 (%head.pcd.mix;|em|a)*>
         1418  +<!ELEMENT pre (%eg.pcd.mix;|em)*>
         1419  +<!ELEMENT ul (item|li)*>
         1420  +<!ELEMENT ol (item|li)*>
         1421  +<!ELEMENT li (#PCDATA|%obj.mix;)*>
         1422  +<!ELEMENT em (#PCDATA)>
         1423  +<!ELEMENT a (#PCDATA)>
         1424  +
         1425  +<!ELEMENT key-term (#PCDATA)>
         1426  +<!ELEMENT htable
         1427  +        (caption?, (col*|colgroup*), thead?, tfoot?, tbody+)>
         1428  +<!ELEMENT htbody (tr)+>
         1429  +<!ELEMENT statusp (%p.pcd.mix;|%p.mix;)*>
         1430  +
         1431  +<!ELEMENT itemizedlist (listitem*)>
         1432  +<!ELEMENT orderedlist (listitem*)>
         1433  +<!ELEMENT listitem (para*)>
         1434  +<!ELEMENT para (#PCDATA)>
         1435  +
         1436  +<!-- ............................................................... -->
         1437  +<!-- Change history ................................................ -->
         1438  +<!-- ............................................................... -->
         1439  +
         1440  +<!--
         1441  +#1997-08-18: maler
         1442  +#- Did a major revision.
         1443  +#1997-09-10: maler
         1444  +#- Updated FPI.
         1445  +#- Removed namekey element and put key attribute on name element.
         1446  +#- Made statusp element and supporting entities.
         1447  +#- Added slist element with sitem+ content.
         1448  +#- Required head on scrap and added new bnf subelement.
         1449  +#- Added an xnt element and allowed it and nt in regular text and rhs.
         1450  +#- Removed the ntref element.
         1451  +#- Added back the com element to the content of rhs.
         1452  +#- Added a key attribute to bibl.
         1453  +#- Removed the ident element.
         1454  +#- Added a term element to be used inside termdef.
         1455  +#- Added an xtermref element parallel to termref.
         1456  +#- Beefed up DTD comments.
         1457  +#1997-09-12: maler
         1458  +#- Allowed term element in general text.
         1459  +#- Changed bibref to EMPTY.
         1460  +#- Added ref.class to termdef.pcd.mix.
         1461  +#1997-09-14: maler
         1462  +#- Changed main attribute of xtermref from def to href.
         1463  +#- Added termdef.class to label contents.
         1464  +#1997-09-30: maler
         1465  +#- Added character entity module and added new entities.
         1466  +#- Removed p from appearing directly in self; created %p.mix;.
         1467  +#- Added inform-div (non-normative division) element.
         1468  +#- Fixed xtermref comment to mention href, not ref.
         1469  +#- Extended orglist model to allow optional affiliation.
         1470  +#- Modified author to make affiliation optional.
         1471  +#- Added %speclist.class; and %note.class; to %obj.mix; and %p.mix;.
         1472  +#- Added %note.class; and %illus.class; to %termdef.pcd.mix;.
         1473  +#- Added unused HTML elements.
         1474  +#- Put empty system ID next to public ID in entity declarations.
         1475  +#1997-10-14: maler
         1476  +#- Fixed "unused" div content model to move nested div to mixture.
         1477  +#1997-10-16: maler
         1478  +#- Added SGML Open Exchange tables.
         1479  +#1997-11-28: maler
         1480  +#- Added support for prodgroup and its attributes.
         1481  +#- Added support for HTML tables.
         1482  +#- Added loc and bibref to content of com.
         1483  +#- Added loc to general p content models.
         1484  +#- Allowed p as alternative to statusp in status.
         1485  +#- Added non-null system IDs to external parameter entity declarations.
         1486  +#- (Modified the SGML Open table module to make it XML-compliant.)
         1487  +#- (Modified the character entity module.)
         1488  +#1997-12-29: maler
         1489  +#- Moved #PCDATA occurrences to come before GIs in content models.
         1490  +#- Removed use of the SGML Open table module.
         1491  +#- Added xspecref element.
         1492  +#- Ensured that all FPIs contain 4-digit year.
         1493  +#- (Modified the character entity module.)
         1494  +#1998-03-10: maler
         1495  +#- Merged the character entity and table modules into the main file.
         1496  +#- Added ldquo and rdquo entities.
         1497  +#- Added common attributes to prodgroup.
         1498  +#- Made the email element in header optional.
         1499  +#- Removed reference to the SGML Open table model.
         1500  +#- Added ednote element.
         1501  +#- Added quote element.
         1502  +#- Updated XLink usage to reflect 3 March 1998 WD.
         1503  +#- Added "local" entities to the class entities for customization.
         1504  +#- Parameterized several content models to allow for customization.
         1505  +#1998-03-23: maler
         1506  +#- Cleaned up some comments and removed some others.
         1507  +#- Added xml:space semi-common attribute to eg and bnf elements.
         1508  +#- Added show and embed attributes on all the uses of href.
         1509  +#- Added %common.att; to all HTML table elements.
         1510  +#- Added a real URI to the "typical invocation" comment.
         1511  +#1998-05-14: maler
         1512  +#- Fixed mdash, ldquo, and rdquo character entities.
         1513  +#- Switched to the full HTML 4.0 table model.
         1514  +#- Removed htable/htbody elements and replaced them with table/tbody.
         1515  +#- Added issue element to %note.class; and declared it.
         1516  +#- Allowed prevlocs and latestloc in either order.
         1517  +#- Added key-term, htable, htbody, and statusp as unused elements.
         1518  +#- Removed real statusp element in favor of plain p.
         1519  +#1998-05-21: maler
         1520  +#- Declared generic constraint and constraintnote elements.
         1521  +#- Added constraintnote to %note.class;.
         1522  +#- Added constraint to %eg.pcd.mix; and prod content model.
         1523  +#1998-08-22: maler
         1524  +#- Fixed %illus.class; to mention table instead of htable.
         1525  +#- Added definitions to %illus.class; for DOM model.
         1526  +#- Added DOM definitions element and its substructure.
         1527  +#- Updated XLink usage in %href.att; to use xlink:form and #IMPLIED.
         1528  +#- Added clarifying comments to href-using elements.
         1529  +#1998-11-30: maler
         1530  +#- Added new unused elements to support DocBook translation.
         1531  +#- Updated maler phone numbers.
         1532  +#1998-12-3: maler
         1533  +#- Fixed character entities with respect to escaping of ampersands.
         1534  +#- Added many more explanatory comments.
         1535  +#1999-07-02: maler
         1536  +#- Added %loc.class; to all PCD mixes that didn't already have it.
         1537  +#- Removed unused %loc.pcd.mix;.
         1538  +#- Made version in spec header optional.
         1539  +#- Added three new attributes to spec.
         1540  +#- Broadened content of edtext.
         1541  +#- Added optional copyright element to header.
         1542  +#- Reorganized XLink-related parameter entities; added xmlns:xlink.
         1543  +#- Changed edtext content from #PCDATA to %p.pcd.mix;.
         1544  +#- Added show/actuate atts and default values to all href elements.
         1545  +#- Changed versioning scheme from 8-digit dates to version numbers.
         1546  +#- Added w3c-doctype, other-doctype, status atts to spec element.
         1547  +#- Added prodrecap element inside scrap.
         1548  +#- Added headstyle attribute to scrap.
         1549  +-->
         1550  +
         1551  +<!-- ............................................................... -->
         1552  +<!-- End of XML specification DTD .................................. -->
         1553  +<!-- ............................................................... -->

Deleted tests/defs.tcl.

     1         -# defs.tcl --
     2         -#
     3         -#	This file contains support code for the Tcl/Tk test suite.It is
     4         -#	It is normally sourced by the individual files in the test suite
     5         -#	before they run their tests.  This improved approach to testing
     6         -#	was designed and initially implemented by Mary Ann May-Pumphrey
     7         -#	of Sun Microsystems.
     8         -#
     9         -# Copyright (c) 1990-1994 The Regents of the University of California.
    10         -# Copyright (c) 1994-1996 Sun Microsystems, Inc.
    11         -# Copyright (c) 1998-1999 by Scriptics Corporation.
    12         -# All rights reserved.
    13         -# 
    14         -# RCS: @(#) $Id$
    15         -
    16         -# Initialize wish shell
    17         -
    18         -if {[info exists tk_version]} {
    19         -    tk appname tktest
    20         -    wm title . tktest
    21         -} else {
    22         -
    23         -    # Ensure that we have a minimal auto_path so we don't pick up extra junk.
    24         -
    25         -    set auto_path [list [info library]]
    26         -}
    27         -
    28         -# create the "tcltest" namespace for all testing variables and procedures
    29         -
    30         -namespace eval tcltest {
    31         -    set procList [list test cleanupTests dotests saveState restoreState \
    32         -	    normalizeMsg makeFile removeFile makeDirectory removeDirectory \
    33         -	    viewFile bytestring set_iso8859_1_locale restore_locale \
    34         -	    safeFetch threadReap]
    35         -    if {[info exists tk_version]} {
    36         -	lappend procList setupbg dobg bgReady cleanupbg fixfocus
    37         -    }
    38         -    foreach proc $procList {
    39         -	namespace export $proc
    40         -    }
    41         -
    42         -    # ::tcltest::verbose defaults to "b"
    43         -
    44         -    variable verbose "b"
    45         -
    46         -    # match defaults to the empty list
    47         -
    48         -    variable match {}
    49         -
    50         -    # skip defaults to the empty list
    51         -
    52         -    variable skip {}
    53         -
    54         -    # Tests should not rely on the current working directory.
    55         -    # Files that are part of the test suite should be accessed relative to
    56         -    # ::tcltest::testsDir.
    57         -
    58         -    set originalDir [pwd]
    59         -    set tDir [file join $originalDir [file dirname [info script]]]
    60         -    cd $tDir
    61         -    variable testsDir [pwd]
    62         -    cd $originalDir
    63         -
    64         -    # Count the number of files tested (0 if all.tcl wasn't called).
    65         -    # The all.tcl file will set testSingleFile to false, so stats will
    66         -    # not be printed until all.tcl calls the cleanupTests proc.
    67         -    # The currentFailure var stores the boolean value of whether the
    68         -    # current test file has had any failures.  The failFiles list
    69         -    # stores the names of test files that had failures.
    70         -
    71         -    variable numTestFiles 0
    72         -    variable testSingleFile true
    73         -    variable currentFailure false
    74         -    variable failFiles {}
    75         -
    76         -    # Tests should remove all files they create.  The test suite will
    77         -    # check the current working dir for files created by the tests.
    78         -    # ::tcltest::filesMade keeps track of such files created using the
    79         -    # ::tcltest::makeFile and ::tcltest::makeDirectory procedures.
    80         -    # ::tcltest::filesExisted stores the names of pre-existing files.
    81         -
    82         -    variable filesMade {}
    83         -    variable filesExisted {}
    84         -
    85         -    # ::tcltest::numTests will store test files as indices and the list
    86         -    # of files (that should not have been) left behind by the test files.
    87         -
    88         -    array set ::tcltest::createdNewFiles {}
    89         -
    90         -    # initialize ::tcltest::numTests array to keep track fo the number of
    91         -    # tests that pass, fial, and are skipped.
    92         -
    93         -    array set numTests [list Total 0 Passed 0 Skipped 0 Failed 0]
    94         -
    95         -    # initialize ::tcltest::skippedBecause array to keep track of
    96         -    # constraints that kept tests from running
    97         -
    98         -    array set ::tcltest::skippedBecause {}
    99         -
   100         -    # tests that use thread need to know which is the main thread
   101         -
   102         -    variable ::tcltest::mainThread 1
   103         -    if {[info commands testthread] != {}} {
   104         -	set ::tcltest::mainThread [testthread names]
   105         -    }
   106         -}
   107         -
   108         -# If there is no "memory" command (because memory debugging isn't
   109         -# enabled), generate a dummy command that does nothing.
   110         -
   111         -if {[info commands memory] == ""} {
   112         -    proc memory args {}
   113         -}
   114         -
   115         -# ::tcltest::initConfig --
   116         -#
   117         -# Check configuration information that will determine which tests
   118         -# to run.  To do this, create an array ::tcltest::testConfig.  Each
   119         -# element has a 0 or 1 value.  If the element is "true" then tests
   120         -# with that constraint will be run, otherwise tests with that constraint
   121         -# will be skipped.  See the README file for the list of built-in
   122         -# constraints defined in this procedure.
   123         -#
   124         -# Arguments:
   125         -#	none
   126         -#
   127         -# Results:
   128         -#	The ::tcltest::testConfig array is reset to have an index for
   129         -#	each built-in test constraint.
   130         -
   131         -proc ::tcltest::initConfig {} {
   132         -
   133         -    global tcl_platform tcl_interactive tk_version
   134         -
   135         -    catch {unset ::tcltest::testConfig}
   136         -
   137         -    # The following trace procedure makes it so that we can safely refer to
   138         -    # non-existent members of the ::tcltest::testConfig array without causing an
   139         -    # error.  Instead, reading a non-existent member will return 0.  This is
   140         -    # necessary because tests are allowed to use constraint "X" without ensuring
   141         -    # that ::tcltest::testConfig("X") is defined.
   142         -
   143         -    trace variable ::tcltest::testConfig r ::tcltest::safeFetch
   144         -
   145         -    proc ::tcltest::safeFetch {n1 n2 op} {
   146         -	if {($n2 != {}) && ([info exists ::tcltest::testConfig($n2)] == 0)} {
   147         -	    set ::tcltest::testConfig($n2) 0
   148         -	}
   149         -    }
   150         -
   151         -    set ::tcltest::testConfig(unixOnly) \
   152         -	    [expr {$tcl_platform(platform) == "unix"}]
   153         -    set ::tcltest::testConfig(macOnly) \
   154         -	    [expr {$tcl_platform(platform) == "macintosh"}]
   155         -    set ::tcltest::testConfig(pcOnly) \
   156         -	    [expr {$tcl_platform(platform) == "windows"}]
   157         -
   158         -    set ::tcltest::testConfig(unix) $::tcltest::testConfig(unixOnly)
   159         -    set ::tcltest::testConfig(mac) $::tcltest::testConfig(macOnly)
   160         -    set ::tcltest::testConfig(pc) $::tcltest::testConfig(pcOnly)
   161         -
   162         -    set ::tcltest::testConfig(unixOrPc) \
   163         -	    [expr {$::tcltest::testConfig(unix) || $::tcltest::testConfig(pc)}]
   164         -    set ::tcltest::testConfig(macOrPc) \
   165         -	    [expr {$::tcltest::testConfig(mac) || $::tcltest::testConfig(pc)}]
   166         -    set ::tcltest::testConfig(macOrUnix) \
   167         -	    [expr {$::tcltest::testConfig(mac) || $::tcltest::testConfig(unix)}]
   168         -
   169         -    set ::tcltest::testConfig(nt) [expr {$tcl_platform(os) == "Windows NT"}]
   170         -    set ::tcltest::testConfig(95) [expr {$tcl_platform(os) == "Windows 95"}]
   171         -
   172         -    # The following config switches are used to mark tests that should work,
   173         -    # but have been temporarily disabled on certain platforms because they don't
   174         -    # and we haven't gotten around to fixing the underlying problem.
   175         -
   176         -    set ::tcltest::testConfig(tempNotPc) [expr {!$::tcltest::testConfig(pc)}]
   177         -    set ::tcltest::testConfig(tempNotMac) [expr {!$::tcltest::testConfig(mac)}]
   178         -    set ::tcltest::testConfig(tempNotUnix) [expr {!$::tcltest::testConfig(unix)}]
   179         -
   180         -    # The following config switches are used to mark tests that crash on
   181         -    # certain platforms, so that they can be reactivated again when the
   182         -    # underlying problem is fixed.
   183         -
   184         -    set ::tcltest::testConfig(pcCrash) [expr {!$::tcltest::testConfig(pc)}]
   185         -    set ::tcltest::testConfig(macCrash) [expr {!$::tcltest::testConfig(mac)}]
   186         -    set ::tcltest::testConfig(unixCrash) [expr {!$::tcltest::testConfig(unix)}]
   187         -
   188         -    # Set the "fonts" constraint for wish apps
   189         -
   190         -    if {[info exists tk_version]} {
   191         -	set ::tcltest::testConfig(fonts) 1
   192         -	catch {destroy .e}
   193         -	entry .e -width 0 -font {Helvetica -12} -bd 1
   194         -	.e insert end "a.bcd"
   195         -	if {([winfo reqwidth .e] != 37) || ([winfo reqheight .e] != 20)} {
   196         -	    set ::tcltest::testConfig(fonts) 0
   197         -	}
   198         -	destroy .e
   199         -	catch {destroy .t}
   200         -	text .t -width 80 -height 20 -font {Times -14} -bd 1
   201         -	pack .t
   202         -	.t insert end "This is\na dot."
   203         -	update
   204         -	set x [list [.t bbox 1.3] [.t bbox 2.5]]
   205         -	destroy .t
   206         -	if {[string match {{22 3 6 15} {31 18 [34] 15}} $x] == 0} {
   207         -	    set ::tcltest::testConfig(fonts) 0
   208         -	}
   209         -    }
   210         -
   211         -    # Skip empty tests
   212         -
   213         -    set ::tcltest::testConfig(emptyTest) 0
   214         -
   215         -    # By default, tests that expost known bugs are skipped.
   216         -
   217         -    set ::tcltest::testConfig(knownBug) 0
   218         -
   219         -    # By default, non-portable tests are skipped.
   220         -
   221         -    set ::tcltest::testConfig(nonPortable) 0
   222         -
   223         -    # Some tests require user interaction.
   224         -
   225         -    set ::tcltest::testConfig(userInteraction) 0
   226         -
   227         -    # Some tests must be skipped if the interpreter is not in interactive mode
   228         -
   229         -    set ::tcltest::testConfig(interactive) $tcl_interactive
   230         -
   231         -    # Some tests must be skipped if you are running as root on Unix.
   232         -    # Other tests can only be run if you are running as root on Unix.
   233         -
   234         -    set ::tcltest::testConfig(root) 0
   235         -    set ::tcltest::testConfig(notRoot) 1
   236         -    set user {}
   237         -    if {$tcl_platform(platform) == "unix"} {
   238         -	catch {set user [exec whoami]}
   239         -	if {$user == ""} {
   240         -	    catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
   241         -	}
   242         -	if {($user == "root") || ($user == "")} {
   243         -	    set ::tcltest::testConfig(root) 1
   244         -	    set ::tcltest::testConfig(notRoot) 0
   245         -	}
   246         -    }
   247         -
   248         -    # Set nonBlockFiles constraint: 1 means this platform supports
   249         -    # setting files into nonblocking mode.
   250         -
   251         -    if {[catch {set f [open defs r]}]} {
   252         -	set ::tcltest::testConfig(nonBlockFiles) 1
   253         -    } else {
   254         -	if {[catch {fconfigure $f -blocking off}] == 0} {
   255         -	    set ::tcltest::testConfig(nonBlockFiles) 1
   256         -	} else {
   257         -	    set ::tcltest::testConfig(nonBlockFiles) 0
   258         -	}
   259         -	close $f
   260         -    }
   261         -
   262         -    # Set asyncPipeClose constraint: 1 means this platform supports
   263         -    # async flush and async close on a pipe.
   264         -    #
   265         -    # Test for SCO Unix - cannot run async flushing tests because a
   266         -    # potential problem with select is apparently interfering.
   267         -    # (Mark Diekhans).
   268         -
   269         -    if {$tcl_platform(platform) == "unix"} {
   270         -	if {[catch {exec uname -X | fgrep {Release = 3.2v}}] == 0} {
   271         -	    set ::tcltest::testConfig(asyncPipeClose) 0
   272         -	} else {
   273         -	    set ::tcltest::testConfig(asyncPipeClose) 1
   274         -	}
   275         -    } else {
   276         -	set ::tcltest::testConfig(asyncPipeClose) 1
   277         -    }
   278         -
   279         -    # Test to see if we have a broken version of sprintf with respect
   280         -    # to the "e" format of floating-point numbers.
   281         -
   282         -    set ::tcltest::testConfig(eformat) 1
   283         -    if {[string compare "[format %g 5e-5]" "5e-05"] != 0} {
   284         -	set ::tcltest::testConfig(eformat) 0
   285         -    }
   286         -
   287         -    # Test to see if execed commands such as cat, echo, rm and so forth are
   288         -    # present on this machine.
   289         -
   290         -    set ::tcltest::testConfig(unixExecs) 1
   291         -    if {$tcl_platform(platform) == "macintosh"} {
   292         -	set ::tcltest::testConfig(unixExecs) 0
   293         -    }
   294         -    if {($::tcltest::testConfig(unixExecs) == 1) && \
   295         -	    ($tcl_platform(platform) == "windows")} {
   296         -	if {[catch {exec cat defs}] == 1} {
   297         -	    set ::tcltest::testConfig(unixExecs) 0
   298         -	}
   299         -	if {($::tcltest::testConfig(unixExecs) == 1) && \
   300         -		([catch {exec echo hello}] == 1)} {
   301         -	    set ::tcltest::testConfig(unixExecs) 0
   302         -	}
   303         -	if {($::tcltest::testConfig(unixExecs) == 1) && \
   304         -		([catch {exec sh -c echo hello}] == 1)} {
   305         -	    set ::tcltest::testConfig(unixExecs) 0
   306         -	}
   307         -	if {($::tcltest::testConfig(unixExecs) == 1) && \
   308         -		([catch {exec wc defs}] == 1)} {
   309         -	    set ::tcltest::testConfig(unixExecs) 0
   310         -	}
   311         -	if {$::tcltest::testConfig(unixExecs) == 1} {
   312         -	    exec echo hello > removeMe
   313         -	    if {[catch {exec rm removeMe}] == 1} {
   314         -		set ::tcltest::testConfig(unixExecs) 0
   315         -	    }
   316         -	}
   317         -	if {($::tcltest::testConfig(unixExecs) == 1) && \
   318         -		([catch {exec sleep 1}] == 1)} {
   319         -	    set ::tcltest::testConfig(unixExecs) 0
   320         -	}
   321         -	if {($::tcltest::testConfig(unixExecs) == 1) && \
   322         -		([catch {exec fgrep unixExecs defs}] == 1)} {
   323         -	    set ::tcltest::testConfig(unixExecs) 0
   324         -	}
   325         -	if {($::tcltest::testConfig(unixExecs) == 1) && \
   326         -		([catch {exec ps}] == 1)} {
   327         -	    set ::tcltest::testConfig(unixExecs) 0
   328         -	}
   329         -	if {($::tcltest::testConfig(unixExecs) == 1) && \
   330         -		([catch {exec echo abc > removeMe}] == 0) && \
   331         -		([catch {exec chmod 644 removeMe}] == 1) && \
   332         -		([catch {exec rm removeMe}] == 0)} {
   333         -	    set ::tcltest::testConfig(unixExecs) 0
   334         -	} else {
   335         -	    catch {exec rm -f removeMe}
   336         -	}
   337         -	if {($::tcltest::testConfig(unixExecs) == 1) && \
   338         -		([catch {exec mkdir removeMe}] == 1)} {
   339         -	    set ::tcltest::testConfig(unixExecs) 0
   340         -	} else {
   341         -	    catch {exec rm -r removeMe}
   342         -	}
   343         -    }
   344         -}
   345         -
   346         -::tcltest::initConfig
   347         -
   348         -
   349         -# ::tcltest::processCmdLineArgs --
   350         -#
   351         -#	Use command line args to set the verbose, skip, and
   352         -#	match variables.  This procedure must be run after
   353         -#	constraints are initialized, because some constraints can be
   354         -#	overridden.
   355         -#
   356         -# Arguments:
   357         -#	none
   358         -#
   359         -# Results:
   360         -#	::tcltest::verbose is set to <value>
   361         -
   362         -proc ::tcltest::processCmdLineArgs {} {
   363         -    global argv
   364         -
   365         -    # The "argv" var doesn't exist in some cases, so use {}
   366         -    # The "argv" var doesn't exist in some cases.
   367         -
   368         -    if {(![info exists argv]) || ([llength $argv] < 2)} {
   369         -	set flagArray {}
   370         -    } else {
   371         -	set flagArray $argv
   372         -    }
   373         -
   374         -    if {[catch {array set flag $flagArray}]} {
   375         -	puts stderr "Error:  odd number of command line args specified:"
   376         -	puts stderr "        $argv"
   377         -	exit
   378         -    }
   379         -    
   380         -    # Allow for 1-char abbreviations, where applicable (e.g., -match == -m).
   381         -    # Note that -verbose cannot be abbreviated to -v in wish because it
   382         -    # conflicts with the wish option -visual.
   383         -
   384         -    foreach arg {-verbose -match -skip -constraints} {
   385         -	set abbrev [string range $arg 0 1]
   386         -	if {([info exists flag($abbrev)]) && \
   387         -		([lsearch -exact $flagArray $arg] < \
   388         -		[lsearch -exact $flagArray $abbrev])} {
   389         -	    set flag($arg) $flag($abbrev)
   390         -	}
   391         -    }
   392         -
   393         -    # Set ::tcltest::workingDir to [pwd].
   394         -    # Save the names of files that already exist in ::tcltest::workingDir.
   395         -
   396         -    set ::tcltest::workingDir [pwd]
   397         -    foreach file [glob -nocomplain [file join $::tcltest::workingDir *]] {
   398         -	lappend ::tcltest::filesExisted [file tail $file]
   399         -    }
   400         -
   401         -    # Set ::tcltest::verbose to the arg of the -verbose flag, if given
   402         -
   403         -    if {[info exists flag(-verbose)]} {
   404         -	set ::tcltest::verbose $flag(-verbose)
   405         -    }
   406         -
   407         -    # Set ::tcltest::match to the arg of the -match flag, if given
   408         -
   409         -    if {[info exists flag(-match)]} {
   410         -	set ::tcltest::match $flag(-match)
   411         -    }
   412         -
   413         -    # Set ::tcltest::skip to the arg of the -skip flag, if given
   414         -
   415         -    if {[info exists flag(-skip)]} {
   416         -	set ::tcltest::skip $flag(-skip)
   417         -    }
   418         -
   419         -    # Use the -constraints flag, if given, to turn on constraints that are
   420         -    # turned off by default: userInteractive knownBug nonPortable.  This
   421         -    # code fragment must be run after constraints are initialized.
   422         -
   423         -    if {[info exists flag(-constraints)]} {
   424         -	foreach elt $flag(-constraints) {
   425         -	    set ::tcltest::testConfig($elt) 1
   426         -	}
   427         -    }
   428         -}
   429         -
   430         -::tcltest::processCmdLineArgs
   431         -
   432         -
   433         -# ::tcltest::cleanupTests --
   434         -#
   435         -# Remove files and dirs created using the makeFile and makeDirectory
   436         -# commands since the last time this proc was invoked.
   437         -#
   438         -# Print the names of the files created without the makeFile command
   439         -# since the tests were invoked.
   440         -#
   441         -# Print the number tests (total, passed, failed, and skipped) since the
   442         -# tests were invoked.
   443         -#
   444         -
   445         -proc ::tcltest::cleanupTests {{calledFromAllFile 0}} {
   446         -    set tail [file tail [info script]]
   447         -
   448         -    # Remove files and directories created by the :tcltest::makeFile and
   449         -    # ::tcltest::makeDirectory procedures.
   450         -    # Record the names of files in ::tcltest::workingDir that were not
   451         -    # pre-existing, and associate them with the test file that created them.
   452         -
   453         -    if {!$calledFromAllFile} {
   454         -
   455         -	foreach file $::tcltest::filesMade {
   456         -	    if {[file exists $file]} {
   457         -		catch {file delete -force $file}
   458         -	    }
   459         -	}
   460         -	set currentFiles {}
   461         -	foreach file [glob -nocomplain [file join $::tcltest::workingDir *]] {
   462         -	    lappend currentFiles [file tail $file]
   463         -	}
   464         -	set newFiles {}
   465         -	foreach file $currentFiles {
   466         -	    if {[lsearch -exact $::tcltest::filesExisted $file] == -1} {
   467         -		lappend newFiles $file
   468         -	    }
   469         -	}
   470         -	set ::tcltest::filesExisted $currentFiles
   471         -	if {[llength $newFiles] > 0} {
   472         -	    set ::tcltest::createdNewFiles($tail) $newFiles
   473         -	}
   474         -    }
   475         -
   476         -    if {$calledFromAllFile || $::tcltest::testSingleFile} {
   477         -
   478         -	# print stats
   479         -
   480         -	puts -nonewline stdout "$tail:"
   481         -	foreach index [list "Total" "Passed" "Skipped" "Failed"] {
   482         -	    puts -nonewline stdout "\t$index\t$::tcltest::numTests($index)"
   483         -	}
   484         -	puts stdout ""
   485         -
   486         -	# print number test files sourced
   487         -	# print names of files that ran tests which failed
   488         -
   489         -	if {$calledFromAllFile} {
   490         -	    puts stdout "Sourced $::tcltest::numTestFiles Test Files."
   491         -	    set ::tcltest::numTestFiles 0
   492         -	    if {[llength $::tcltest::failFiles] > 0} {
   493         -		puts stdout "Files with failing tests: $::tcltest::failFiles"
   494         -		set ::tcltest::failFiles {}
   495         -	    }
   496         -	}
   497         -
   498         -	# if any tests were skipped, print the constraints that kept them
   499         -	# from running.
   500         -
   501         -	set constraintList [array names ::tcltest::skippedBecause]
   502         -	if {[llength $constraintList] > 0} {
   503         -	    puts stdout "Number of tests skipped for each constraint:"
   504         -	    foreach constraint [lsort $constraintList] {
   505         -		puts stdout \
   506         -			"\t$::tcltest::skippedBecause($constraint)\t$constraint"
   507         -		unset ::tcltest::skippedBecause($constraint)
   508         -	    }
   509         -	}
   510         -
   511         -	# report the names of test files in ::tcltest::createdNewFiles, and
   512         -	# reset the array to be empty.
   513         -
   514         -	set testFilesThatTurded [lsort [array names ::tcltest::createdNewFiles]]
   515         -	if {[llength $testFilesThatTurded] > 0} {
   516         -	    puts stdout "Warning: test files left files behind:"
   517         -	    foreach testFile $testFilesThatTurded {
   518         -		puts "\t$testFile:\t$::tcltest::createdNewFiles($testFile)"
   519         -		unset ::tcltest::createdNewFiles($testFile)
   520         -	    }
   521         -	}
   522         -
   523         -	# reset filesMade, filesExisted, and numTests
   524         -
   525         -	set ::tcltest::filesMade {}
   526         -	foreach index [list "Total" "Passed" "Skipped" "Failed"] {
   527         -	    set ::tcltest::numTests($index) 0
   528         -	}
   529         -
   530         -	# exit only if running Tk in non-interactive mode
   531         -
   532         -	global tk_version tcl_interactive
   533         -	if {[info exists tk_version] && !$tcl_interactive} {
   534         -	    exit
   535         -	}
   536         -    } else {
   537         -
   538         -	# if we're deferring stat-reporting until all files are sourced,
   539         -	# then add current file to failFile list if any tests in this file
   540         -	# failed
   541         -
   542         -	incr ::tcltest::numTestFiles
   543         -	if {($::tcltest::currentFailure) && \
   544         -		([lsearch -exact $::tcltest::failFiles $tail] == -1)} {
   545         -	    lappend ::tcltest::failFiles $tail
   546         -	}
   547         -	set ::tcltest::currentFailure false
   548         -    }
   549         -}
   550         -
   551         -
   552         -# test --
   553         -#
   554         -# This procedure runs a test and prints an error message if the test fails.
   555         -# If ::tcltest::verbose has been set, it also prints a message even if the
   556         -# test succeeds.  The test will be skipped if it doesn't match the
   557         -# ::tcltest::match variable, if it matches an element in
   558         -# ::tcltest::skip, or if one of the elements of "constraints" turns
   559         -# out not to be true.
   560         -#
   561         -# Arguments:
   562         -# name -		Name of test, in the form foo-1.2.
   563         -# description -		Short textual description of the test, to
   564         -#			help humans understand what it does.
   565         -# constraints -		A list of one or more keywords, each of
   566         -#			which must be the name of an element in
   567         -#			the array "::tcltest::testConfig".  If any of these
   568         -#			elements is zero, the test is skipped.
   569         -#			This argument may be omitted.
   570         -# script -		Script to run to carry out the test.  It must
   571         -#			return a result that can be checked for
   572         -#			correctness.
   573         -# expectedAnswer -	Expected result from script.
   574         -
   575         -proc ::tcltest::test {name description script expectedAnswer args} {
   576         -    incr ::tcltest::numTests(Total)
   577         -
   578         -    # skip the test if it's name matches an element of skip
   579         -
   580         -    foreach pattern $::tcltest::skip {
   581         -	if {[string match $pattern $name]} {
   582         -	    incr ::tcltest::numTests(Skipped)
   583         -	    return
   584         -	}
   585         -    }
   586         -    # skip the test if it's name doesn't match any element of match
   587         -
   588         -    if {[llength $::tcltest::match] > 0} {
   589         -	set ok 0
   590         -	foreach pattern $::tcltest::match {
   591         -	    if {[string match $pattern $name]} {
   592         -		set ok 1
   593         -		break
   594         -	    }
   595         -        }
   596         -	if {!$ok} {
   597         -	    incr ::tcltest::numTests(Skipped)
   598         -	    return
   599         -	}
   600         -    }
   601         -    set i [llength $args]
   602         -    if {$i == 0} {
   603         -	set constraints {}
   604         -    } elseif {$i == 1} {
   605         -
   606         -	# "constraints" argument exists;  shuffle arguments down, then
   607         -	# make sure that the constraints are satisfied.
   608         -
   609         -	set constraints $script
   610         -	set script $expectedAnswer
   611         -	set expectedAnswer [lindex $args 0]
   612         -	set doTest 0
   613         -	if {[string match {*[$\[]*} $constraints] != 0} {
   614         -
   615         -	    # full expression, e.g. {$foo > [info tclversion]}
   616         -
   617         -	    catch {set doTest [uplevel #0 expr $constraints]}
   618         -
   619         -	} elseif {[regexp {[^.a-zA-Z0-9 ]+} $constraints] != 0} {
   620         -
   621         -	    # something like {a || b} should be turned into 
   622         -	    # $::tcltest::testConfig(a) || $::tcltest::testConfig(b).
   623         -
   624         - 	    regsub -all {[.a-zA-Z0-9]+} $constraints \
   625         -		    {$::tcltest::testConfig(&)} c
   626         -	    catch {set doTest [eval expr $c]}
   627         -	} else {
   628         -
   629         -	    # just simple constraints such as {unixOnly fonts}.
   630         -
   631         -	    set doTest 1
   632         -	    foreach constraint $constraints {
   633         -		if {![info exists ::tcltest::testConfig($constraint)]
   634         -			|| !$::tcltest::testConfig($constraint)} {
   635         -		    set doTest 0
   636         -
   637         -		    # store the constraint that kept the test from running
   638         -
   639         -		    set constraints $constraint
   640         -		    break
   641         -		}
   642         -	    }
   643         -	}
   644         -	if {$doTest == 0} {
   645         -	    incr ::tcltest::numTests(Skipped)
   646         -	    if {[string first s $::tcltest::verbose] != -1} {
   647         -		puts stdout "++++ $name SKIPPED: $constraints"
   648         -	    }
   649         -
   650         -	    # add the constraint to the list of constraints the kept tests
   651         -	    # from running
   652         -
   653         -	    if {[info exists ::tcltest::skippedBecause($constraints)]} {
   654         -		incr ::tcltest::skippedBecause($constraints)
   655         -	    } else {
   656         -		set ::tcltest::skippedBecause($constraints) 1
   657         -	    }
   658         -	    return	
   659         -	}
   660         -    } else {
   661         -	error "wrong # args: must be \"test name description ?constraints? script expectedAnswer\""
   662         -    }
   663         -    memory tag $name
   664         -    set code [catch {uplevel $script} actualAnswer]
   665         -    if {$code != 0 || [string compare $actualAnswer $expectedAnswer] != 0} {
   666         -	incr ::tcltest::numTests(Failed)
   667         -	set ::tcltest::currentFailure true
   668         -	if {[string first b $::tcltest::verbose] == -1} {
   669         -	    set script ""
   670         -	}
   671         -	puts stdout "\n==== $name $description FAILED"
   672         -	if {$script != ""} {
   673         -	    puts stdout "==== Contents of test case:"
   674         -	    puts stdout $script
   675         -	}
   676         -	if {$code != 0} {
   677         -	    if {$code == 1} {
   678         -		puts stdout "==== Test generated error:"
   679         -		puts stdout $actualAnswer
   680         -	    } elseif {$code == 2} {
   681         -		puts stdout "==== Test generated return exception;  result was:"
   682         -		puts stdout $actualAnswer
   683         -	    } elseif {$code == 3} {
   684         -		puts stdout "==== Test generated break exception"
   685         -	    } elseif {$code == 4} {
   686         -		puts stdout "==== Test generated continue exception"
   687         -	    } else {
   688         -		puts stdout "==== Test generated exception $code;  message was:"
   689         -		puts stdout $actualAnswer
   690         -	    }
   691         -	} else {
   692         -	    puts stdout "---- Result was:\n$actualAnswer"
   693         -	}
   694         -	puts stdout "---- Result should have been:\n$expectedAnswer"
   695         -	puts stdout "==== $name FAILED\n" 
   696         -    } else { 
   697         -	incr ::tcltest::numTests(Passed)
   698         -	if {[string first p $::tcltest::verbose] != -1} {
   699         -	    puts stdout "++++ $name PASSED"
   700         -	}
   701         -    }
   702         -}
   703         -
   704         -# ::tcltest::dotests --
   705         -#
   706         -#	takes two arguments--the name of the test file (such
   707         -#	as "parse.test"), and a pattern selecting the tests you want to
   708         -#	execute.  It sets ::tcltest::matching to the second argument, calls
   709         -#	"source" on the file specified in the first argument, and restores
   710         -#	::tcltest::matching to its pre-call value at the end.
   711         -#
   712         -# Arguments:
   713         -#	file    name of tests file to source
   714         -#	args    pattern selecting the tests you want to execute
   715         -#
   716         -# Results:
   717         -#	none
   718         -
   719         -proc ::tcltest::dotests {file args} {
   720         -    set savedTests $::tcltest::match
   721         -    set ::tcltest::match $args
   722         -    source $file
   723         -    set ::tcltest::match $savedTests
   724         -}
   725         -
   726         -proc ::tcltest::openfiles {} {
   727         -    if {[catch {testchannel open} result]} {
   728         -	return {}
   729         -    }
   730         -    return $result
   731         -}
   732         -
   733         -proc ::tcltest::leakfiles {old} {
   734         -    if {[catch {testchannel open} new]} {
   735         -        return {}
   736         -    }
   737         -    set leak {}
   738         -    foreach p $new {
   739         -    	if {[lsearch $old $p] < 0} {
   740         -	    lappend leak $p
   741         -	}
   742         -    }
   743         -    return $leak
   744         -}
   745         -
   746         -set ::tcltest::saveState {}
   747         -
   748         -proc ::tcltest::saveState {} {
   749         -    uplevel #0 {set ::tcltest::saveState [list [info procs] [info vars]]}
   750         -}
   751         -
   752         -proc ::tcltest::restoreState {} {
   753         -    foreach p [info procs] {
   754         -	if {[lsearch [lindex $::tcltest::saveState 0] $p] < 0} {
   755         -	    rename $p {}
   756         -	}
   757         -    }
   758         -    foreach p [uplevel #0 {info vars}] {
   759         -	if {[lsearch [lindex $::tcltest::saveState 1] $p] < 0} {
   760         -	    uplevel #0 "unset $p"
   761         -	}
   762         -    }
   763         -}
   764         -
   765         -proc ::tcltest::normalizeMsg {msg} {
   766         -    regsub "\n$" [string tolower $msg] "" msg
   767         -    regsub -all "\n\n" $msg "\n" msg
   768         -    regsub -all "\n\}" $msg "\}" msg
   769         -    return $msg
   770         -}
   771         -
   772         -# makeFile --
   773         -#
   774         -# Create a new file with the name <name>, and write <contents> to it.
   775         -#
   776         -# If this file hasn't been created via makeFile since the last time
   777         -# cleanupTests was called, add it to the $filesMade list, so it will
   778         -# be removed by the next call to cleanupTests.
   779         -#
   780         -proc ::tcltest::makeFile {contents name} {
   781         -    set fd [open $name w]
   782         -    fconfigure $fd -translation lf
   783         -    if {[string index $contents [expr {[string length $contents] - 1}]] == "\n"} {
   784         -	puts -nonewline $fd $contents
   785         -    } else {
   786         -	puts $fd $contents
   787         -    }
   788         -    close $fd
   789         -
   790         -    set fullName [file join [pwd] $name]
   791         -    if {[lsearch -exact $::tcltest::filesMade $fullName] == -1} {
   792         -	lappend ::tcltest::filesMade $fullName
   793         -    }
   794         -}
   795         -
   796         -proc ::tcltest::removeFile {name} {
   797         -    file delete $name
   798         -}
   799         -
   800         -# makeDirectory --
   801         -#
   802         -# Create a new dir with the name <name>.
   803         -#
   804         -# If this dir hasn't been created via makeDirectory since the last time
   805         -# cleanupTests was called, add it to the $directoriesMade list, so it will
   806         -# be removed by the next call to cleanupTests.
   807         -#
   808         -proc ::tcltest::makeDirectory {name} {
   809         -    file mkdir $name
   810         -
   811         -    set fullName [file join [pwd] $name]
   812         -    if {[lsearch -exact $::tcltest::filesMade $fullName] == -1} {
   813         -	lappend ::tcltest::filesMade $fullName
   814         -    }
   815         -}
   816         -
   817         -proc ::tcltest::removeDirectory {name} {
   818         -    file delete -force $name
   819         -}
   820         -
   821         -proc ::tcltest::viewFile {name} {
   822         -    global tcl_platform
   823         -    if {($tcl_platform(platform) == "macintosh") || \
   824         -		($::tcltest::testConfig(unixExecs) == 0)} {
   825         -	set f [open $name]
   826         -	set data [read -nonewline $f]
   827         -	close $f
   828         -	return $data
   829         -    } else {
   830         -	exec cat $name
   831         -    }
   832         -}
   833         -
   834         -#
   835         -# Construct a string that consists of the requested sequence of bytes,
   836         -# as opposed to a string of properly formed UTF-8 characters.  
   837         -# This allows the tester to 
   838         -# 1. Create denormalized or improperly formed strings to pass to C procedures 
   839         -#    that are supposed to accept strings with embedded NULL bytes.
   840         -# 2. Confirm that a string result has a certain pattern of bytes, for instance
   841         -#    to confirm that "\xe0\0" in a Tcl script is stored internally in 
   842         -#    UTF-8 as the sequence of bytes "\xc3\xa0\xc0\x80".
   843         -#
   844         -# Generally, it's a bad idea to examine the bytes in a Tcl string or to
   845         -# construct improperly formed strings in this manner, because it involves
   846         -# exposing that Tcl uses UTF-8 internally.
   847         -
   848         -proc ::tcltest::bytestring {string} {
   849         -    encoding convertfrom identity $string
   850         -}
   851         -
   852         -# Locate tcltest executable
   853         -
   854         -if {![info exists tk_version]} {
   855         -    set tcltest [info nameofexecutable]
   856         -
   857         -    if {$tcltest == "{}"} {
   858         -	set tcltest {}
   859         -    }
   860         -}
   861         -
   862         -set ::tcltest::testConfig(stdio) 0
   863         -catch {
   864         -    catch {file delete -force tmp}
   865         -    set f [open tmp w]
   866         -    puts $f {
   867         -	exit
   868         -    }
   869         -    close $f
   870         -
   871         -    set f [open "|[list $tcltest tmp]" r]
   872         -    close $f
   873         -    
   874         -    set ::tcltest::testConfig(stdio) 1
   875         -}
   876         -catch {file delete -force tmp}
   877         -
   878         -# Deliberately call the socket with the wrong number of arguments.  The error
   879         -# message you get will indicate whether sockets are available on this system.
   880         -
   881         -catch {socket} msg
   882         -set ::tcltest::testConfig(socket) \
   883         -	[expr {$msg != "sockets are not available on this system"}]
   884         -
   885         -#
   886         -# Internationalization / ISO support procs     -- dl
   887         -#
   888         -
   889         -if {[info commands testlocale]==""} {
   890         -
   891         -    # No testlocale command, no tests...
   892         -    # (it could be that we are a sub interp and we could just load
   893         -    # the Tcltest package but that would interfere with tests
   894         -    # that tests packages/loading in slaves...)
   895         -
   896         -    set ::tcltest::testConfig(hasIsoLocale) 0
   897         -} else {
   898         -    proc ::tcltest::set_iso8859_1_locale {} {
   899         -	set ::tcltest::previousLocale [testlocale ctype]
   900         -	testlocale ctype $::tcltest::isoLocale
   901         -    }
   902         -
   903         -    proc ::tcltest::restore_locale {} {
   904         -	testlocale ctype $::tcltest::previousLocale
   905         -    }
   906         -
   907         -    if {![info exists ::tcltest::isoLocale]} {
   908         -	set ::tcltest::isoLocale fr
   909         -        switch $tcl_platform(platform) {
   910         -	    "unix" {
   911         -
   912         -		# Try some 'known' values for some platforms:
   913         -
   914         -		switch -exact -- $tcl_platform(os) {
   915         -		    "FreeBSD" {
   916         -			set ::tcltest::isoLocale fr_FR.ISO_8859-1
   917         -		    }
   918         -		    HP-UX {
   919         -			set ::tcltest::isoLocale fr_FR.iso88591
   920         -		    }
   921         -		    Linux -
   922         -		    IRIX {
   923         -			set ::tcltest::isoLocale fr
   924         -		    }
   925         -		    default {
   926         -
   927         -			# Works on SunOS 4 and Solaris, and maybe others...
   928         -			# define it to something else on your system
   929         -			#if you want to test those.
   930         -
   931         -			set ::tcltest::isoLocale iso_8859_1
   932         -		    }
   933         -		}
   934         -	    }
   935         -	    "windows" {
   936         -		set ::tcltest::isoLocale French
   937         -	    }
   938         -	}
   939         -    }
   940         -
   941         -    set ::tcltest::testConfig(hasIsoLocale) \
   942         -	    [string length [::tcltest::set_iso8859_1_locale]]
   943         -    ::tcltest::restore_locale
   944         -} 
   945         -
   946         -#
   947         -# procedures that are Tk specific
   948         -#
   949         -
   950         -if {[info exists tk_version]} {
   951         -
   952         -    # If the main window isn't already mapped (e.g. because the tests are
   953         -    # being run automatically) , specify a precise size for it so that the
   954         -    # user won't have to position it manually.
   955         -
   956         -    if {![winfo ismapped .]} {
   957         -	wm geometry . +0+0
   958         -	update
   959         -    }
   960         -
   961         -    # The following code can be used to perform tests involving a second
   962         -    # process running in the background.
   963         -    
   964         -    # Locate the tktest executable
   965         -
   966         -    set ::tcltest::tktest [info nameofexecutable]
   967         -    if {$::tcltest::tktest == "{}"} {
   968         -	set ::tcltest::tktest {}
   969         -	puts stdout \
   970         -		"Unable to find tktest executable, skipping multiple process tests."
   971         -    }
   972         -
   973         -    # Create background process
   974         -    
   975         -    proc ::tcltest::setupbg args {
   976         -	if {$::tcltest::tktest == ""} {
   977         -	    error "you're not running tktest so setupbg should not have been called"
   978         -	}
   979         -	if {[info exists ::tcltest::fd] && ($::tcltest::fd != "")} {
   980         -	    cleanupbg
   981         -	}
   982         -	
   983         -	# The following code segment cannot be run on Windows in Tk8.1b2
   984         -	# This bug is logged as a pipe bug (bugID 1495).
   985         -
   986         -	global tcl_platform
   987         -	if {$tcl_platform(platform) != "windows"} {
   988         -	    set ::tcltest::fd [open "|[list $::tcltest::tktest -geometry +0+0 -name tktest] $args" r+]
   989         -	    puts $::tcltest::fd "puts foo; flush stdout"
   990         -	    flush $::tcltest::fd
   991         -	    if {[gets $::tcltest::fd data] < 0} {
   992         -		error "unexpected EOF from \"$::tcltest::tktest\""
   993         -	    }
   994         -	    if {[string compare $data foo]} {
   995         -		error "unexpected output from background process \"$data\""
   996         -	    }
   997         -	    fileevent $::tcltest::fd readable bgReady
   998         -	}
   999         -    }
  1000         -    
  1001         -    # Send a command to the background process, catching errors and
  1002         -    # flushing I/O channels
  1003         -
  1004         -    proc ::tcltest::dobg {command} {
  1005         -	puts $::tcltest::fd "catch [list $command] msg; update; puts \$msg; puts **DONE**; flush stdout"
  1006         -	flush $::tcltest::fd
  1007         -	set ::tcltest::bgDone 0
  1008         -	set ::tcltest::bgData {}
  1009         -	tkwait variable ::tcltest::bgDone
  1010         -	set ::tcltest::bgData
  1011         -    }
  1012         -
  1013         -    # Data arrived from background process.  Check for special marker
  1014         -    # indicating end of data for this command, and make data available
  1015         -    # to dobg procedure.
  1016         -
  1017         -    proc ::tcltest::bgReady {} {
  1018         -	set x [gets $::tcltest::fd]
  1019         -	if {[eof $::tcltest::fd]} {
  1020         -	    fileevent $::tcltest::fd readable {}
  1021         -	    set ::tcltest::bgDone 1
  1022         -	} elseif {$x == "**DONE**"} {
  1023         -	    set ::tcltest::bgDone 1
  1024         -	} else {
  1025         -	    append ::tcltest::bgData $x
  1026         -	}
  1027         -    }
  1028         -
  1029         -    # Exit the background process, and close the pipes
  1030         -
  1031         -    proc ::tcltest::cleanupbg {} {
  1032         -	catch {
  1033         -	    puts $::tcltest::fd "exit"
  1034         -	    close $::tcltest::fd
  1035         -	}
  1036         -	set ::tcltest::fd ""
  1037         -    }
  1038         -
  1039         -    # Clean up focus after using generate event, which
  1040         -    # can leave the window manager with the wrong impression
  1041         -    # about who thinks they have the focus. (BW)
  1042         -    
  1043         -    proc ::tcltest::fixfocus {} {
  1044         -	catch {destroy .focus}
  1045         -	toplevel .focus
  1046         -	wm geometry .focus +0+0
  1047         -	entry .focus.e
  1048         -	.focus.e insert 0 "fixfocus"
  1049         -	pack .focus.e
  1050         -	update
  1051         -	focus -force .focus.e
  1052         -	destroy .focus
  1053         -    }
  1054         -}
  1055         -
  1056         -# threadReap --
  1057         -#
  1058         -#	Kill all threads except for the main thread.
  1059         -#	Do nothing if testthread is not defined.
  1060         -#
  1061         -# Arguments:
  1062         -#	none.
  1063         -#
  1064         -# Results:
  1065         -#	Returns the number of existing threads.
  1066         -
  1067         -if {[info commands testthread] != {}} {
  1068         -    proc ::tcltest::threadReap {} {
  1069         -	testthread errorproc ThreadNullError
  1070         -	while {[llength [testthread names]] > 1} {
  1071         -	    foreach tid [testthread names] {
  1072         -		if {$tid != $::tcltest::mainThread} {
  1073         -		    catch {testthread send -async $tid {testthread exit}}
  1074         -		    update
  1075         -		}
  1076         -	    }
  1077         -	}
  1078         -	testthread errorproc ThreadError
  1079         -	return [llength [testthread names]]
  1080         -    }
  1081         -} else {
  1082         -    proc ::tcltest::threadReap {} {
  1083         -	return 1
  1084         -    }   
  1085         -}
  1086         -
  1087         -# Need to catch the import because it fails if defs.tcl is sourced
  1088         -# more than once.
  1089         -
  1090         -catch {namespace import ::tcltest::*}
  1091         -return

Added tests/dom.bench.

            1  +# -*- tcl -*-
            2  +# Tcl Benchmark File
            3  +#
            4  +# This file contains a number of benchmarks for the dom methods.
            5  +# This allow developers to monitor/gauge/track package performance.
            6  +#
            7  +# (c) 2013 Rolf Ade <rolf@pointsman.de>
            8  +
            9  +
           10  +# ### ### ### ######### ######### ######### ###########################
           11  +## Setting up the environment ...
           12  +
           13  +package require tdom 
           14  +
           15  +# ### ### ### ######### ######### ######### ###########################
           16  +## Benchmarks.
           17  +
           18  +dom createNodeCmd elementNode e1
           19  +
           20  +foreach nrOf {1 10 100 1000} {
           21  +
           22  +    bench -desc "getElementsByTagName: $nrOf returned nodes" -pre {
           23  +        dom createDocument root doc
           24  +        $doc documentElement root
           25  +        $root appendFromScript {
           26  +            for {set x 0} {$x < $nrOf} {incr x} {
           27  +                e1
           28  +            }
           29  +        }
           30  +    } -body {
           31  +        $doc getElementsByTagName e1
           32  +    } -post {
           33  +        $doc delete
           34  +    }
           35  +
           36  +}
           37  +
           38  +foreach nrOf {1 10 100 1000} {
           39  +
           40  +    bench -desc "getElementsByTagName: $nrOf returned node tokens" -pre {
           41  +        dom createDocument root doc
           42  +        $doc documentElement root
           43  +        $root appendFromScript {
           44  +            for {set x 0} {$x < $nrOf} {incr x} {
           45  +                e1
           46  +            }
           47  +        }
           48  +        dom setObjectCommands token
           49  +    } -body {
           50  +        $doc getElementsByTagName e1
           51  +    } -post {
           52  +        dom setObjectCommands automatic
           53  +        $doc delete
           54  +    }
           55  +
           56  +}
           57  +
           58  +proc cloneImitated {source target} {
           59  +    foreach att [$source attributes] {
           60  +        $target setAttribute $att [$source @$att]
           61  +    }
           62  +    set targetDoc [$target ownerDocument]
           63  +    foreach child [$source childNodes] {
           64  +        switch [$child nodeType] {
           65  +            "ELEMENT_NODE" {
           66  +                set targetChild [$targetDoc createElement [$child nodeName]]
           67  +            }
           68  +            "TEXT_NODE" {
           69  +                set targetChild [$targetDoc createTextNode [$child nodeValue]]
           70  +            }
           71  +            "CDATA_SECTION_NODE" {
           72  +                set targetChild [$targetDoc createCDATASection \
           73  +                                     [$child nodeValue]]
           74  +            }
           75  +            "PROCESSING_INSTRUCTION_NODE" {
           76  +                set targetChild [$targetDoc createProcessingInstruction \
           77  +                                     [$child nodeName] [$child nodeValue]]
           78  +            }
           79  +            "COMMENT_NODE" {
           80  +                set targetChild [$targetDoc createComment [$child nodeValue]]
           81  +            }
           82  +            default {
           83  +                error "Unexpected node type [$child nodeType]"
           84  +            }
           85  +        }
           86  +        $target appendChild $targetChild
           87  +        cloneImitated $child $targetChild
           88  +    }
           89  +}
           90  +
           91  +proc cloneImitated2 {source target} {
           92  +    foreach att [$source attributes] {
           93  +        $target setAttribute $att [$source @$att]
           94  +    }
           95  +    set targetDoc [$target ownerDocument]
           96  +    foreach child [$source childNodes] {
           97  +        switch [$child nodeType] {
           98  +            "ELEMENT_NODE" {
           99  +                $targetDoc createElement [$child nodeName] targetChild
          100  +            }
          101  +            "TEXT_NODE" {
          102  +                $targetDoc createTextNode [$child nodeValue] targetChild
          103  +            }
          104  +            "CDATA_SECTION_NODE" {
          105  +                $targetDoc createCDATASection [$child nodeValue] targetChild
          106  +            }
          107  +            "PROCESSING_INSTRUCTION_NODE" {
          108  +                $targetDoc createProcessingInstruction [$child nodeName] \
          109  +                    targetChild
          110  +            }
          111  +            "COMMENT_NODE" {
          112  +                $targetDoc createComment [$child nodeValue] targetChild
          113  +            }
          114  +            default {
          115  +                error "Unexpected node type [$child nodeType]"
          116  +            }
          117  +        }
          118  +        $target appendChild $targetChild
          119  +        cloneImitated2 $child $targetChild
          120  +    }
          121  +}
          122  +
          123  +proc cloneImitatedToken {source target} {
          124  +    foreach att [domNode $source attributes] {
          125  +        domNode $target setAttribute $att [domNode $source @$att]
          126  +    }
          127  +    set targetDoc [domNode $target ownerDocument]
          128  +    foreach child [domNode $source childNodes] {
          129  +        switch [domNode $child nodeType] {
          130  +            "ELEMENT_NODE" {
          131  +                set targetChild [$targetDoc createElement \
          132  +                                     [domNode $child nodeName]]
          133  +            }
          134  +            "TEXT_NODE" {
          135  +                set targetChild [$targetDoc createTextNode \
          136  +                                     [domNode $child nodeValue]]
          137  +            }
          138  +            "CDATA_SECTION_NODE" {
          139  +                set targetChild [$targetDoc createCDATASection \
          140  +                                     [domNode $child nodeValue]]
          141  +            }
          142  +            "PROCESSING_INSTRUCTION_NODE" {
          143  +                set targetChild [$targetDoc createProcessingInstruction \
          144  +                                     [domNode $child nodeName] \
          145  +                                     [domNode $child nodeValue]]
          146  +            }
          147  +            "COMMENT_NODE" {
          148  +                set targetChild [$targetDoc createComment \
          149  +                                     [domNode $child nodeValue]]
          150  +            }
          151  +            default {
          152  +                error "Unexpected node type [domNode $child nodeType]"
          153  +            }
          154  +        }
          155  +        domNode $target appendChild $targetChild
          156  +        cloneImitatedToken $child $targetChild
          157  +    }
          158  +}
          159  +
          160  +bench -desc "clone dom tree without clone method - cmds" -pre {
          161  +    set fd [open [file join [file dir [info script]] ../tests/data/mondial-europe.xml]]
          162  +    fconfigure $fd -encoding utf-8
          163  +    set doc [dom parse -channel $fd]
          164  +    close $fd
          165  +    set root [$doc documentElement]
          166  +    set clone [dom createDocument [$root nodeName]]
          167  +    set cloneRoot [$clone documentElement]
          168  +} -iters 5 -body {
          169  +    cloneImitated $root $cloneRoot
          170  +} -post {
          171  +    $doc delete
          172  +    $clone delete
          173  +}
          174  +
          175  +bench -desc "clone dom tree without clone method - cmds 2" -pre {
          176  +    set fd [open [file join [file dir [info script]] ../tests/data/mondial-europe.xml]]
          177  +    fconfigure $fd -encoding utf-8
          178  +    set doc [dom parse -channel $fd]
          179  +    close $fd
          180  +    set root [$doc documentElement]
          181  +    set clone [dom createDocument [$root nodeName]]
          182  +    set cloneRoot [$clone documentElement]
          183  +} -iters 5 -body {
          184  +    cloneImitated2 $root $cloneRoot
          185  +} -post {
          186  +    $doc delete
          187  +    $clone delete
          188  +}
          189  +
          190  +bench -desc "clone dom tree without clone method - token" -pre {
          191  +    set fd [open [file join [file dir [info script]] ../tests/data/mondial-europe.xml]]
          192  +    fconfigure $fd -encoding utf-8
          193  +    set doc [dom parse -channel $fd]
          194  +    close $fd
          195  +    set root [$doc documentElement]
          196  +    set clone [dom createDocument [$root nodeName]]
          197  +    set cloneRoot [$clone documentElement]
          198  +    dom setObjectCommands token
          199  +} -iters 5 -body {
          200  +    cloneImitatedToken $root $cloneRoot
          201  +} -post {
          202  +    $doc delete
          203  +    $clone delete
          204  +    dom setObjectCommands automatic
          205  +}
          206  +
          207  +foreach nrOf {1 10 100 1000} {
          208  +
          209  +    bench -desc "Create document node: $nrOf"  -pre {
          210  +        set doclist [list]
          211  +    } -body {
          212  +        lappend doclist [dom createDocumentNode]
          213  +    } -post {
          214  +        foreach doc $doclist {
          215  +            $doc delete
          216  +        }
          217  +    }
          218  +
          219  +}

Changes to tests/dom.test.

     9      9   #    dom-4.*:  parse -useForeignDTD
    10     10   #    dom-5.*:  external entities
    11     11   #    dom-6.*:  use in slave interpreter
    12     12   #    dom-7.*:  setNameCheck, setTextCheck
    13     13   #    dom-8.*:  createDocumentNode, documentNodes
    14     14   #    dom-9.*:  setObjectCommands
    15     15   #    dom-10.*: createNodeCmd
           16  +#    dom-11.*: featureinfo
           17  +#    dom-12.*: -feedbackAfter
    16     18   #
    17     19   # Copyright (c) 2002, 2003, 2004 Rolf Ade.
    18     20   
    19     21   source [file join [file dir [info script]] loadtdom.tcl]
    20     22   
    21     23   test dom-1.1 {createDocument with root node name not a XML Name} {
    22     24       list [catch {dom createDocument "root node"} msg] $msg
    23         -} "1 {invalid root element name}"
           25  +} "1 {Invalid root element name 'root node'}"
    24     26   
    25     27   test dom-1.2 {createDocument with root node name not a XML Name} {
    26     28       list [catch {dom createDocument "1root"} msg] $msg
    27         -} "1 {invalid root element name}"
           29  +} "1 {Invalid root element name '1root'}"
    28     30   
    29     31   test dom-1.3 {createDocument - root name us-ascii} {
    30     32       dom createDocument "root" doc 
    31     33       set root [$doc documentElement]
    32     34       set result [$root nodeName]
    33     35       $doc delete
    34     36       set result
................................................................................
    68     70       set result [$root namespaceURI]
    69     71       $doc delete
    70     72       set result
    71     73   } "http://foo.bar"    
    72     74   
    73     75   test dom-1.9 {createDocumentNS with root name not a NCName} {
    74     76       list [catch {dom createDocumentNS "http://foo.bar" "foo bar" doc} msg] $msg
    75         -} "1 {invalid local name}"
           77  +} "1 {Invalid root element name 'foo bar'}"
    76     78   
    77     79   test dom-1.10 {createDocumentNS with root name not a NCName} {
    78     80       list [catch {dom createDocumentNS "http://foo.bar" "a:b:c" doc} msg] $msg
    79         -} "1 {invalid local name}"
           81  +} "1 {Invalid root element name 'a:b:c'}"
    80     82   
    81     83   test dom-1.11 {createDocumentNS with root name not a NCName} {
    82     84       list [catch {dom createDocumentNS "http://foo.bar" "a b:b" doc} msg] $msg
    83         -} "1 {invalid prefix name}"
           85  +} "1 {Invalid root element name 'a b:b'}"
    84     86   
    85     87   test dom-1.12 {createDocumentNS with root name not a NCName} {
    86     88       list [catch {dom createDocumentNS "http://foo.bar" "a:a b" doc} msg] $msg
    87         -} "1 {invalid local name}"
           89  +} "1 {Invalid root element name 'a:a b'}"
    88     90   
    89     91   test dom-1.13 {createDocumentNS - check root name} {
    90     92       set doc [dom createDocumentNS "http://foo.bar" foo:root]
    91     93       set root [$doc documentElement]
    92     94       set result [$root nodeName]
    93     95       $doc delete
    94     96       set result
................................................................................
   111    113       }
   112    114       set nrOfCommands [llength [info commands]]
   113    115       set doc [dom createDocument root]
   114    116       rename $doc fooCmd
   115    117       fooCmd delete
   116    118       expr {[llength [info commands]] == $nrOfCommands}
   117    119   } {1}
          120  +
          121  +test dom-1.16 {createDocumentNS - empty namespace, no prefix} {
          122  +    dom createDocumentNS "" doc doc
          123  +    set result [$doc asXML -indent none]
          124  +    $doc delete
          125  +    set result
          126  +} {<doc/>}
          127  +
          128  +test dom-1.17 {createDocumentNS -  namespace, no prefix} {
          129  +    dom createDocumentNS "uri" doc doc
          130  +    set result [$doc asXML -indent none]
          131  +    $doc delete
          132  +    set result
          133  +} {<doc xmlns="uri"/>}
          134  +
          135  +test dom-1.18 {createDocumentNS -  namespace, no prefix} {
          136  +    dom createDocumentNS "uri" doc doc
          137  +    set result [$doc selectNodes -namespaces {ns uri} count(/ns:doc)]
          138  +    $doc delete
          139  +    set result
          140  +} 1
          141  +
          142  +test dom-1.19 {createDocumentNS - namespace, prefix} {
          143  +    dom createDocumentNS "uri" n1:doc doc
          144  +    set result [$doc selectNodes -namespaces {ns uri} count(/ns:doc)]
          145  +    $doc delete
          146  +    set result
          147  +} 1
          148  +
          149  +test dom-1.20 {createDocumentNS - empty namespace, prefix} {
          150  +    catch {dom createDocumentNS "" n1:doc doc} errMsg
          151  +    set errMsg
          152  +} {Missing URI in Namespace declaration}
          153  +
          154  +test dom-1.21 {Explicit delete of scoped doc with domDoc cmd} {} {
          155  +    dom createDocument test doc
          156  +    domDoc $doc delete
          157  +    unset doc
          158  +} {}    
          159  +
          160  +proc dom-1.22 {doc} {
          161  +    $doc delete
          162  +}
          163  +test dom-1.22 {Explicit delete of scoped doc in proc call from scope} {} {
          164  +    dom createDocument test doc
          165  +    dom-1.22 $doc
          166  +    unset doc
          167  +} {}    
          168  +
          169  +test dom-1.23 {Explicit delete of scoped doc} {
          170  +    dom createDocument test doc
          171  +    $doc delete
          172  +    unset doc
          173  +} {}    
          174  +
          175  +test dom-1.24 {Explicit delete of scoped doc} {
          176  +    dom createDocument test doc
          177  +    set result [catch {set doc foo} errMsg]
          178  +    lappend result $errMsg
          179  +    $doc delete
          180  +    unset doc
          181  +    set result
          182  +} {1 {can't set "doc": var is read-only}}
   118    183   
   119    184   test dom-2.1 {Don't quash white space at start or end of non white space content} {
   120    185       set doc [dom parse {<root>
   121    186       some content
   122    187       </root>}]
   123    188       set root [$doc documentElement]
   124    189       $root text
................................................................................
   203    268       close $fd
   204    269       $doc delete
   205    270       info exists -keepEmpties
   206    271   } -cleanup {
   207    272       removeFile dom.xml
   208    273   } -result 0
   209    274   
   210         -test dom-2.8 {parse method: bogus option} {
          275  +test dom-2.8 {parse method: bogus option} -body {
   211    276       set result [catch {set doc [dom parse -bogusOption foo <root/>]} errMsg]
   212    277       lappend result $errMsg
   213         -} {1 {bad option "-bogusOption": must be -keepEmpties, -simple, -html, -feedbackAfter, -channel, -baseurl, -externalentitycommand, -useForeignDTD, or -paramentityparsing}}
          278  +} -match regexp -result {1 {bad option "-bogusOption": must be .*}}
   214    279   
   215    280   test dom-2.9 {parse method: bogus option} -setup {
   216    281       set xmlFile [makeFile {<root>    </root>} dom.xml]
   217    282   } -body {
   218    283       catch {unset -keepEmpties}
   219    284       set fd [open $xmlFile]
   220    285       set result [catch {set doc [dom parse -channel $fd -bogusOption]} errMsg]
   221    286       close $fd
   222    287       lappend result $errMsg
   223    288   } -cleanup {
   224    289       removeFile dom.xml
   225         -} -result {1 {bad option "-bogusOption": must be -keepEmpties, -simple, -html, -feedbackAfter, -channel, -baseurl, -externalentitycommand, -useForeignDTD, or -paramentityparsing}}
          290  +} -match regexp -result {1 {bad option "-bogusOption": must be .*}}
   226    291   
   227    292   set dom_dtd "
   228    293       <!ELEMENT root EMPTY>
   229    294       <!ATTLIST root lang CDATA #FIXED \"en\">"
   230    295   
   231    296   proc extRefResolver {base systemId publicId} {
   232    297       global dom_dtd
   233    298   
   234    299       if {$publicId == "DOMCMDTEST"} {
   235    300           return [list string $base $dom_dtd]
   236    301       } else {
   237         -        return [::tDOM::extRefHandler $base $systemId $publicId]
          302  +        return [::tdom::extRefHandler $base $systemId $publicId]
   238    303       }
   239    304   }
   240    305   
   241    306   test dom-2.10 {parse method: -paramentityparsing default is 'always'} {
   242    307       set doc [dom parse -externalentitycommand extRefResolver {
   243    308           <!DOCTYPE root PUBLIC "DOMCMDTEST" "dummysystemID">
   244    309           <root/>
................................................................................
   327    392       set result [catch {set doc [dom parse \
   328    393               -externalentitycommand extRefResolver {
   329    394           <!DOCTYPE root PUBLIC "DOMCMDTEST" "dummysystemID">
   330    395           <root/>
   331    396       }]} errMsg]
   332    397       lappend result $errMsg
   333    398   } {1 {error "syntax error" in entity "dummysystemID" at line 1 character 20
   334         -"<!ATTLIST root lang # <--Error-- FIXED "en">"}}
          399  +"<!ATTLIST root lang # <--Error-- FIXED "en">", referenced at line 2 character 58}}
   335    400   
   336    401   test dom-2.18 {parse document with nodes before and after the documentElement} {
   337    402       set doc [dom parse {<!-- First comment -->
   338    403   <doc>
   339    404     <!-- Front comment -->
   340    405     <inner/>
   341    406     <!-- Back comment -->
................................................................................
   452    517   </doc><!-- Last comment -->}
   453    518   
   454    519   test dom-2.26 {Not well-formed input} {
   455    520       catch {dom parse {<xsl:transform       
   456    521           xmlns:xsl="http://www.w3.org/1999/XSL/Transform        
   457    522                      <http://www.w3.org/1999/XSL/Transform> "/>}}
   458    523   } 1
          524  +
          525  +test dom-2.27 {parse -ignorexmlns} {
          526  +    set result [list]
          527  +    set doc [dom parse {<doc xmlns="foo.bar"><child/></doc>}]
          528  +    set root [$doc documentElement]
          529  +    lappend result [$root localName]
          530  +    lappend result [$root namespaceURI]
          531  +    set child [$root firstChild]
          532  +    lappend result [$child localName]
          533  +    lappend result [$child namespaceURI]
          534  +    lappend result [$doc selectNodes count(/doc/child)]
          535  +    $doc delete
          536  +    set doc [dom parse -ignorexmlns {<doc xmlns="foo.bar"><child/></doc>}]
          537  +    set root [$doc documentElement]
          538  +    lappend result [$root nodeName]
          539  +    lappend result [$root namespaceURI]
          540  +    set child [$root firstChild]
          541  +    lappend result [$child nodeName]
          542  +    lappend result [$child namespaceURI]
          543  +    lappend result [$doc selectNodes count(/doc/child)]
          544  +    $doc delete
          545  +    set result
          546  +} {doc foo.bar child foo.bar 0 doc {} child {} 1}
          547  +
          548  +test dom-2.28 {parse document with undeclared xml prefix} {
          549  +    catch {dom parse {<doc><foo:e/></doc>}} errMsg
          550  +    string range $errMsg 0 30
          551  +} {Namespace prefix is not defined}
          552  +
          553  +test dom-2.29 {parse not well-formed document with undeclared xml prefix} {
          554  +    catch {dom parse {<foo:e/>}} errMsg
          555  +    string range $errMsg 0 30
          556  +} {Namespace prefix is not defined}
          557  +
          558  +test dom-2.30 {parse document with undeclared xml prefix} {
          559  +    catch {dom parse {<foo:e><a/></foo:e>}} errMsg
          560  +    string range $errMsg 0 30
          561  +} {Namespace prefix is not defined}
          562  +
          563  +proc dom-2.31 {base systemId publicId} {
          564  +    switch $publicId {
          565  +        "e1" {
          566  +            # Not well-formed
          567  +            set data "<foo:e/>"
          568  +        }
          569  +        default {
          570  +            error "unknown public ID"
          571  +        }
          572  +    }
          573  +    return [list "string" $base $data]
          574  +}
          575  +test dom-2.31 {parse document with undeclared xml prefix} {
          576  +    catch {dom parse -externalentitycommand dom-2.31 \
          577  +                {<!DOCTYPE doc [<!ENTITY e1 PUBLIC "e1" "e1.xml">]>
          578  +                    <doc>&e1;</doc>}
          579  +    } errMsg
          580  +    string range $errMsg 0 30
          581  +} {Namespace prefix is not defined}
          582  +    
          583  +test dom-2.32 {parse document with undeclared xml prefix and -ignorexmlns} {
          584  +    set doc [dom parse -ignorexmlns {<foo:e><a/></foo:e>}]
          585  +    set result [[$doc documentElement] nodeName]
          586  +    $doc delete
          587  +    set result
          588  +} {foo:e}
          589  +
          590  +test dom-2.33 {end of options option} {
          591  +    set doc [dom parse -json -- -0.123]
          592  +    set result [$doc asXML -indent none]
          593  +    $doc delete
          594  +    set result
          595  +} -0.123
          596  +
          597  +test dom-2.34 {XML prefix declaration with empty namespace} {
          598  +    catch {dom parse {<foo:doc xmlns:foo=""><e1/></foo:doc>}} errMsg
          599  +    set errMsg
          600  +} {Missing URI in Namespace declaration, referenced at line 1 character 22}
          601  +
          602  +test dom-2.35 {-keepCDATA} {
          603  +    set doc [dom parse -keepCDATA {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
          604  +    set result [$doc asXML -indent none]
          605  +    $doc delete
          606  +    set result
          607  +} {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}
          608  +
          609  +test dom-2.36 {-keepCDATA} {
          610  +    set doc [dom parse -keepCDATA {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
          611  +    set root [$doc documentElement]
          612  +    set result [list]
          613  +    foreach child [$root childNodes] {
          614  +        lappend result [$child nodeType]
          615  +    }
          616  +    $doc delete
          617  +    set result
          618  +} {TEXT_NODE CDATA_SECTION_NODE TEXT_NODE}
          619  +
          620  +test dom-2.37 {-keepCDATA} {
          621  +    set doc [dom parse -keepCDATA {<doc><e><![CDATA[one]]></e></doc>}]
          622  +    set result [list]
          623  +    foreach child [$doc selectNodes doc/e/node()] {
          624  +        lappend result [$child nodeType]
          625  +    }
          626  +    $doc delete
          627  +    set result
          628  +} {CDATA_SECTION_NODE}
          629  +
          630  +test dom-2.38 {-keepCDATA} {
          631  +    set doc [dom parse -keepCDATA {<doc><e><![CDATA[one]]><![CDATA[two]]></e></doc>}]
          632  +    set result [list]
          633  +    foreach child [$doc selectNodes doc/e/node()] {
          634  +        lappend result [$child nodeType]
          635  +    }
          636  +    $doc delete
          637  +    set result
          638  +} {CDATA_SECTION_NODE CDATA_SECTION_NODE}
          639  +
          640  +test dom-2.39 {-keepCDATA} {
          641  +    set doc [dom parse -keepCDATA {<doc><e><![CDATA[]]></e></doc>}]
          642  +    set result [$doc selectNodes count(doc/e/node())]
          643  +    $doc delete
          644  +    set result
          645  +} 0
          646  +
          647  +test dom-2.40 {-keepCDATA white space only CDATA section} {
          648  +    set doc [dom parse -keepCDATA {<doc><e><![CDATA[
          649  +    ]]></e></doc>}]
          650  +    set result [$doc selectNodes count(doc/e/node())]
          651  +    $doc delete
          652  +    set result
          653  +} 0
          654  +
          655  +test dom-2.41 {-keepCDATA and -keepEmpties} {
          656  +    set doc [dom parse -keepCDATA -keepEmpties {<doc><e><![CDATA[]]></e></doc>}]
          657  +    set result [$doc selectNodes count(doc/e/node())]
          658  +    $doc delete
          659  +    set result
          660  +} 1
          661  +
          662  +test dom-2.42 {namespaces} {
          663  +    set doc [dom parse {
          664  +        <help><br xmlns:xsi="a"/><em xmlns:xsi="a">notes</em></help>
          665  +    }]
          666  +    $doc delete
          667  +} {}
   459    668   
   460    669   test dom-3.1 {isName} {
   461    670       dom isName ":foo"
   462    671   } {1}
   463    672   
   464    673   test dom-3.2 {isName} {
   465    674       dom isName "_foo"
................................................................................
   841   1050   
   842   1051   test dom-4.1 {-useForeignDTD 0} {
   843   1052       set doc [dom parse -useForeignDTD 0 {<root/>}]
   844   1053       $doc delete
   845   1054   } {}
   846   1055   
   847   1056   test dom-4.2 {-useForeignDTD 1 with document with internal subset} {need_uri} {
   848         -    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
   849         -    set ::tDOM::useForeignDTD "data/domCmd1.dtd"
         1057  +    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
         1058  +    set ::tdom::useForeignDTD "data/domCmd1.dtd"
   850   1059       set doc [dom parse \
   851   1060               -useForeignDTD 1 \
   852   1061               -baseurl $baseURI \
   853         -            -externalentitycommand ::tDOM::extRefHandler {
         1062  +            -externalentitycommand ::tdom::extRefHandler {
   854   1063   <!DOCTYPE root [
   855   1064       <!ATTLIST root fixed CDATA #FIXED "toThat">
   856   1065   ]>
   857   1066   <root/>}]
   858   1067       set root [$doc documentElement]
   859   1068       set result [$root @fixed]
   860   1069       $doc delete
   861   1070       set result
   862   1071   } {toThat}
   863   1072   
   864   1073   test dom-4.3 {-useForeignDTD 1 with document with internal subset} {need_uri} {
   865         -    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
   866         -    set ::tDOM::useForeignDTD "data/domCmd1.dtd"
         1074  +    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
         1075  +    set ::tdom::useForeignDTD "data/domCmd1.dtd"
   867   1076       set doc [dom parse \
   868   1077               -useForeignDTD 1 \
   869   1078               -baseurl $baseURI \
   870         -            -externalentitycommand ::tDOM::extRefHandler {
         1079  +            -externalentitycommand ::tdom::extRefHandler {
   871   1080   <!DOCTYPE root [
   872   1081       <!ATTLIST root fixed2 CDATA #FIXED "toThat">
   873   1082   ]>
   874   1083   <root/>}]
   875   1084       set root [$doc documentElement]
   876   1085       set result [$root @fixed]
   877   1086       lappend result [$root @fixed2]
   878   1087       $doc delete
   879   1088       set result
   880   1089   } {toThis toThat}
   881   1090   
   882   1091   test dom-4.4 {-useForeignDTD 1 with document without document declaration} {need_uri} {
   883         -    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
   884         -    set ::tDOM::useForeignDTD "data/domCmd1.dtd"
         1092  +    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
         1093  +    set ::tdom::useForeignDTD "data/domCmd1.dtd"
   885   1094       set doc [dom parse \
   886   1095               -useForeignDTD 1 \
   887   1096               -baseurl $baseURI \
   888         -            -externalentitycommand ::tDOM::extRefHandler <root/>]
         1097  +            -externalentitycommand ::tdom::extRefHandler <root/>]
   889   1098       set root [$doc documentElement]
   890   1099       set result [$root @fixed]
   891   1100       $doc delete
   892   1101       set result
   893   1102   } {toThis}
   894   1103   
   895   1104   test dom-4.5 {-useForeignDTD 1 does not overwrite a given external subset} {need_uri} {
   896         -    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
   897         -    set ::tDOM::useForeignDTD "data/domCmd1.dtd"
         1105  +    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
         1106  +    set ::tdom::useForeignDTD "data/domCmd1.dtd"
   898   1107       set doc [dom parse \
   899   1108               -useForeignDTD 1 \
   900   1109               -baseurl $baseURI \
   901         -            -externalentitycommand ::tDOM::extRefHandler {
         1110  +            -externalentitycommand ::tdom::extRefHandler {
   902   1111   <!DOCTYPE root SYSTEM "data/domCmd2.dtd">
   903   1112   <root/>}]
   904   1113       set root [$doc documentElement]
   905   1114       set result [$root @fixed]
   906   1115       $doc delete
   907   1116       set result
   908   1117   } {toThat}
................................................................................
   909   1118   
   910   1119   test dom-4.6 {-useForeignDTD with nonboolean arg} {need_uri} {
   911   1120       set result [catch {set doc [dom parse -useForeignDTD foo <root/>]} errMsg]
   912   1121       lappend result $errMsg
   913   1122   } {1 {expected boolean value but got "foo"}}
   914   1123   
   915   1124   test dom-5.1 {document with external subset} {need_uri} {
   916         -    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
         1125  +    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
   917   1126       set doc [dom parse \
   918   1127               -baseurl $baseURI \
   919         -            -externalentitycommand ::tDOM::extRefHandler {
         1128  +            -externalentitycommand ::tdom::extRefHandler {
   920   1129   <!DOCTYPE root SYSTEM "data/domCmd2.dtd">
   921   1130   <root/>}]
   922   1131       set root [$doc documentElement]
   923   1132       set result [$root @fixed]
   924   1133       $doc delete
   925   1134       set result
   926   1135   } {toThat}
................................................................................
   936   1145                    -baseurl "dummy" \
   937   1146                    -externalentitycommand [list dom-5.2 thisDoc] {
   938   1147                        <!DOCTYPE root SYSTEM "">
   939   1148                        <root/>}]
   940   1149       $doc delete
   941   1150       set ::dom-5_2
   942   1151   } {thisDoc}
         1152  +
         1153  +proc dom-5.3 {base systemId publicId} {
         1154  +    switch $publicId {
         1155  +        "e1" {
         1156  +            # Not well-formed
         1157  +            set data "<e,1/>"
         1158  +        }
         1159  +        default {
         1160  +            error "unknown public ID"
         1161  +        }
         1162  +    }
         1163  +    return [list "string" $base $data]
         1164  +}
         1165  +test dom-5.3 {-externalentitycommand - nested external entities} -body {
         1166  +    set result [catch {
         1167  +        dom parse -externalentitycommand dom-5.3 \
         1168  +            {<!DOCTYPE doc [
         1169  +                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
         1170  +                            ]>
         1171  +                <doc>&e1;</doc>}
         1172  +    } msg]
         1173  +    list $result $msg
         1174  +} -result [list 1 {error "not well-formed (invalid token)" in entity "e1.xml" at line 1 character 2
         1175  +"<e, <--Error-- 1/>", referenced at line 4 character 21}]
         1176  +
         1177  +proc dom-5.4 {base systemId publicId} {
         1178  +    switch $publicId {
         1179  +        "e1" {
         1180  +            set data "<e1>&e2;</e1>"
         1181  +        }
         1182  +        "e2" {
         1183  +            set data "<e,2/>"
         1184  +        }
         1185  +        default {
         1186  +            error "unknown public ID"
         1187  +        }
         1188  +    }
         1189  +    return [list "string" $base $data]
         1190  +}
         1191  +test dom-5.4 {-externalentitycommand - nested external entities} -body {
         1192  +    set result [catch {
         1193  +        dom parse -externalentitycommand dom-5.4 \
         1194  +            {<!DOCTYPE doc [
         1195  +                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
         1196  +                            <!ENTITY e2 PUBLIC "e2" "e2.xml">
         1197  +                            ]>
         1198  +                <doc>&e1;</doc>}
         1199  +    } msg]
         1200  +    list $result $msg
         1201  +} -result [list 1 {error "not well-formed (invalid token)" in entity "e2.xml" at line 1 character 2
         1202  +"<e, <--Error-- 2/>", referenced in entity "e1.xml" at line 1 character 4, referenced at line 5 character 21}]
         1203  +
         1204  +proc dom-5.5 {base systemId publicId} {
         1205  +    switch $publicId {
         1206  +        "e1" {
         1207  +            set data "<e1>&e2;</e1>"
         1208  +        }
         1209  +        "e2" {
         1210  +            set data "<e2>&e3;</e2>"
         1211  +        }
         1212  +        "e3" {
         1213  +            # Not well-formed
         1214  +            set data "<e,3/>"
         1215  +        }
         1216  +        default {
         1217  +            error "unknown public ID"
         1218  +        }
         1219  +    }
         1220  +    return [list "string" $base $data]
         1221  +}
         1222  +test dom-5.5 {-externalentitycommand - nested external entities} -body {
         1223  +    set result [catch {
         1224  +        dom parse -externalentitycommand dom-5.5 \
         1225  +            {<!DOCTYPE doc [
         1226  +                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
         1227  +                            <!ENTITY e2 PUBLIC "e2" "e2.xml">
         1228  +                            <!ENTITY e3 PUBLIC "e3" "e3.xml">
         1229  +                            ]>
         1230  +                <doc>&e1;</doc>}
         1231  +    } msg]
         1232  +    list $result $msg
         1233  +} -result [list 1 {error "not well-formed (invalid token)" in entity "e3.xml" at line 1 character 2
         1234  +"<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}]
         1235  +
         1236  +proc dom-5.6 {base systemId publicId} {
         1237  +    switch $publicId {
         1238  +        "e1" {
         1239  +            set data [open $::e1]
         1240  +        }
         1241  +        default {
         1242  +            error "unknown public ID"
         1243  +        }
         1244  +    }
         1245  +    lappend ::openChannels $data
         1246  +    return [list "channel" $base $data]
         1247  +}
         1248  +test dom-5.6 {-externalentitycommand - nested external entities} -setup {
         1249  +    set e1 [makeFile "<e,1/>" e1.xml]
         1250  +    set openChannels [list]
         1251  +} -body {
         1252  +    set result [catch {
         1253  +        dom parse -externalentitycommand dom-5.6 \
         1254  +            {<!DOCTYPE doc [
         1255  +                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
         1256  +                            ]>
         1257  +                <doc>&e1;</doc>}
         1258  +    } msg]
         1259  +    list $result $msg
         1260  +} -cleanup {
         1261  +    foreach channel $openChannels {close $channel}
         1262  +    removeFile e1.xml
         1263  +} -result [list 1 {error "not well-formed (invalid token)" in entity "e1.xml" at line 1 character 2, referenced at line 4 character 21}]
         1264  +
         1265  +proc dom-5.7 {base systemId publicId} {
         1266  +    switch $publicId {
         1267  +        "e1" {
         1268  +            set data [open $::e1]
         1269  +        }
         1270  +        "e2" {
         1271  +            set data [open $::e2]
         1272  +        }
         1273  +        default {
         1274  +            error "unknown public ID"
         1275  +        }
         1276  +    }
         1277  +    lappend ::openChannels $data
         1278  +    return [list "channel" $base $data]
         1279  +}
         1280  +test dom-5.7 {-externalentitycommand - nested external entities} -setup {
         1281  +    set e1 [makeFile "<e1>&e2;</e1>" e1.xml]
         1282  +    set e2 [makeFile "<e,2/>" e2.xml]
         1283  +    set openChannels [list]
         1284  +} -body {
         1285  +    set result [catch {
         1286  +        dom parse -externalentitycommand dom-5.7 \
         1287  +            {<!DOCTYPE doc [
         1288  +                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
         1289  +                            <!ENTITY e2 PUBLIC "e2" "e2.xml">
         1290  +                            ]>
         1291  +                <doc>&e1;</doc>}
         1292  +    } msg]
         1293  +    list $result $msg
         1294  +} -cleanup {
         1295  +    foreach channel $openChannels {close $channel}
         1296  +    removeFile e1.xml
         1297  +    removeFile e2.xml
         1298  +} -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}]
         1299  +
         1300  +proc dom-5.8 {base systemId publicId} {
         1301  +    switch $publicId {
         1302  +        "e1" {
         1303  +            set data [open $::e1]
         1304  +        }
         1305  +        "e2" {
         1306  +            set data [open $::e2]
         1307  +        }
         1308  +        "e3" {
         1309  +            set data [open $::e3]
         1310  +        }
         1311  +        default {
         1312  +            error "unknown public ID"
         1313  +        }
         1314  +    }
         1315  +    lappend ::openChannels $data
         1316  +    return [list "channel" $base $data]
         1317  +}
         1318  +test dom-5.8 {-externalentitycommand - nested external entities} -setup {
         1319  +    set e1 [makeFile "<e1>&e2;</e1>" e1.xml]
         1320  +    set e2 [makeFile "<e2>&e3;</e2>" e2.xml]
         1321  +    set e3 [makeFile "<e,3/>" e3.xml]
         1322  +    set openChannels [list]
         1323  +} -body {
         1324  +    set result [catch {
         1325  +        dom parse -externalentitycommand dom-5.8 \
         1326  +            {<!DOCTYPE doc [
         1327  +                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
         1328  +                            <!ENTITY e2 PUBLIC "e2" "e2.xml">
         1329  +                            <!ENTITY e3 PUBLIC "e3" "e3.xml">
         1330  +                            ]>
         1331  +                <doc>&e1;</doc>}
         1332  +    } msg]
         1333  +    list $result $msg
         1334  +} -cleanup {
         1335  +    foreach channel $openChannels {close $channel}
         1336  +    removeFile e1.xml
         1337  +    removeFile e2.xml
         1338  +    removeFile e3.xml
         1339  +} -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}]
         1340  +
         1341  +test dom-5.9 {Wrong option after -externalentitycommand} -body {
         1342  +    set result [catch {dom parse -externalentitycommand ::tdom::extRefHandler \
         1343  +                           -useForeignDTD foo}]
         1344  +} -result 1
   943   1345   
   944   1346   test dom-6.1 {use in slave interpreter} {
   945   1347       set slave [interp create]
   946   1348       load {} tdom $slave
   947   1349       interp eval $slave {
   948   1350           dom parse <root>foo</root> doc
   949   1351           $doc documentElement root
................................................................................
  1125   1527               nodeCmds::t "foo\u0003bar"
  1126   1528           }
  1127   1529       }} errMsg]
  1128   1530       dom setTextCheck 1
  1129   1531       $doc delete
  1130   1532       lappend result $errMsg
  1131   1533   } [list 1 "Invalid text value 'foo\u0003bar'"]
         1534  +
         1535  +test dom-7.19 {setNameCheck / createDocument} {
         1536  +    dom setNameCheck 0
         1537  +    dom createDocument "foo bar" doc
         1538  +    set result [$doc asXML -indent none]
         1539  +    $doc delete
         1540  +    dom setNameCheck 1
         1541  +    set result
         1542  +} {<foo bar/>}
         1543  +    
  1132   1544   
  1133   1545   test dom-8.1 {createDocumentNode} {
  1134   1546       set result [catch {dom createDocumentNode foo bar}]
  1135   1547   } {1}
  1136   1548   
  1137   1549   test dom-8.2 {createDocumentNode} {
  1138   1550       set docNode [dom createDocumentNode]
................................................................................
  1179   1591       $doc delete
  1180   1592       $docNode appendFromList $listRep
  1181   1593       set result [$docNode asXML -indent none]
  1182   1594       $docNode delete
  1183   1595       set result
  1184   1596   } {<root><child1/><child2/>some text<child3/></root>}
  1185   1597   
         1598  +test dom-8.7 {createDocumentNode} {
         1599  +    dom createDocumentNode docNode
         1600  +    dom createDocumentNode docNode
         1601  +    $docNode delete
         1602  +    set result ""
         1603  +} ""
         1604  +
         1605  +test dom-8.8 {createDocumentNode} {
         1606  +    dom createDocumentNode -jsonType ARRAY docNode
         1607  +    set result [$docNode jsonType]
         1608  +    $docNode delete
         1609  +    set result
         1610  +} ARRAY
         1611  +
         1612  +test dom-8.9 {createDocumentNode} {
         1613  +    set docNode [dom createDocumentNode -jsonType NUMBER]
         1614  +    set result [$docNode jsonType]
         1615  +    $docNode delete
         1616  +    set result
         1617  +} NUMBER
         1618  +
         1619  +test dom-8.10 {createDocumentNode} {
         1620  +    catch {dom createDocumentNode -foo NULL docNode} errMsg
         1621  +    set errMsg
         1622  +} {bad option "-foo": must be -jsonType}
         1623  +
         1624  +test dom-8.10 {createDocumentNode} {
         1625  +    catch {dom createDocumentNode -foo NULL docNode} errMsg
         1626  +    set errMsg
         1627  +} {bad option "-foo": must be -jsonType}
         1628  +
         1629  +test dom-8.11 {createDocumentNode} {
         1630  +    catch {dom createDocumentNode -jsonType FOO docNode} errMsg
         1631  +    set errMsg
         1632  +} {bad jsonType "FOO": must be NONE, ARRAY, OBJECT, NULL, TRUE, FALSE, STRING, or NUMBER}
         1633  +
  1186   1634   test dom-9.1 {setObjectCommands} {
  1187   1635       dom setObjectCommands
  1188   1636   } {automatic}
  1189   1637   
  1190   1638   test dom-9.2 {setObjectCommands} {
  1191   1639       dom setObjectCommands automatic
  1192   1640   } {automatic}
................................................................................
  1220   1668       set doc [dom parse <root><child1/><child2/></root>]
  1221   1669       set root [domDoc $doc documentElement]
  1222   1670       set result [expr {$nrOfCmds == [llength [info commands]]}]
  1223   1671       dom setObjectCommands command
  1224   1672       set docCmd [domNode $root ownerDocument]
  1225   1673       lappend result [expr {$nrOfCmds + 1 == [llength [info commands]]}]
  1226   1674       $docCmd delete
         1675  +    dom setObjectCommands automatic
  1227   1676       set result
  1228   1677   } {1 1}
  1229   1678   
         1679  +test dom-9.6 {node token with result var argument} {
         1680  +    dom setObjectCommands token
         1681  +    set doc [dom parse <root><child1/><child2/></root>]
         1682  +    domDoc $doc documentElement var
         1683  +    domNode $var firstChild var
         1684  +    domNode $var nextSibling var
         1685  +    domDoc $doc delete
         1686  +    dom setObjectCommands automatic
         1687  +} {automatic}
         1688  +
         1689  +
         1690  +test dom-9.7 {Attempt to use the token to an already freed node} {
         1691  +    dom setObjectCommands token
         1692  +    set doc [dom createDocument one]
         1693  +    set top [domDoc $doc documentElement]
         1694  +    set elem [domDoc $doc createElement one]
         1695  +    domNode $elem delete
         1696  +    set result [catch {domNode $elem asList} errMsg]
         1697  +    lappend result $errMsg
         1698  +    domDoc $doc delete
         1699  +    dom setObjectCommands automatic
         1700  +    set result
         1701  +} {1 {Parameter "" is not a domNode.}}
         1702  +    
  1230   1703   catch {namespace delete nodeCmds}
  1231   1704   
  1232   1705   namespace eval nodeCmds {
  1233   1706       dom createNodeCmd elementNode e1
  1234   1707       dom createNodeCmd elementNode e2
  1235   1708       dom createNodeCmd commentNode c
  1236   1709       dom createNodeCmd textNode    t
  1237   1710       dom createNodeCmd cdataNode   cdata
  1238   1711       dom createNodeCmd piNode      pi
  1239   1712       dom createNodeCmd parserNode  parser
         1713  +    dom createNodeCmd -tagName foo elementNode bar
  1240   1714   }
  1241   1715   
  1242   1716   test dom-10.1 {createNodeCmd} {
  1243   1717       llength [info commands nodeCmds::*]
  1244         -} {7}
         1718  +} {8}
  1245   1719   
  1246   1720   namespace eval nodeCmds {
  1247   1721       rename e1 {}
  1248   1722       rename e2 {}
  1249   1723       rename c {}
  1250   1724       rename t {}
  1251   1725       rename cdata {}
  1252   1726       rename pi {}
  1253   1727       rename parser {}
         1728  +    rename bar {}
  1254   1729   }
  1255   1730   
  1256   1731   test dom-10.2 {createNodeCmd} {
  1257   1732       llength [info commands nodeCmds::*]
  1258   1733   } {0}
  1259   1734   
  1260   1735   namespace eval nodeCmds {
................................................................................
  1291   1766       $doc delete
  1292   1767       lappend result [catch {
  1293   1768           nodeCmds::e1 {
  1294   1769               nodeCmds::t "Some text"
  1295   1770           }} errMsg]
  1296   1771       lappend result $errMsg
  1297   1772   } {{<docRoot><e1>Some text</e1></docRoot>} 1 {called outside domNode context}}
         1773  +
         1774  +namespace eval nodeCmds {
         1775  +    dom createNodeCmd -tagName foo elementNode bar
         1776  +}
         1777  +test dom-10.6 {createNodeCmd - option -tagName} {
         1778  +    set doc [dom createDocumentNode]
         1779  +    $doc appendFromScript {
         1780  +        nodeCmds::bar {}
         1781  +    }
         1782  +    set result [$doc asXML -indent none]
         1783  +    $doc delete
         1784  +    set result
         1785  +} {<foo/>}
  1298   1786   
  1299   1787   namespace delete nodeCmds
         1788  +
         1789  +test dom-11.1 {featureinfo - expatversion} -body {
         1790  +    dom featureinfo expatversion
         1791  +} -match regexp -result {expat_.*}
         1792  +
         1793  +test dom-11.2 {featureinfo - invalid arg} -body {
         1794  +    catch {dom featureinfo foo} errMsg
         1795  +} -result 1
         1796  +
         1797  +test dom-11.3 {featureinfo - expatmajorversion} -body {
         1798  +    dom featureinfo expatmajorversion
         1799  +} -match regexp -result {(1|2)}
         1800  +
         1801  +test dom-11.4 {featureinfo - dtd} -body {
         1802  +    dom featureinfo dtd
         1803  +} -match regexp -result {(0|1)}
         1804  +
         1805  +test dom-11.5 {featureinfo - jsonmaxnesting} {
         1806  +    dom featureinfo jsonmaxnesting
         1807  +} 2000
         1808  +
         1809  +test dom-11.6 {featureinfo - versionhash} {
         1810  +    regexp {^[0-9a-fA-F]+$} [dom featureinfo versionhash]
         1811  +} 1
         1812  +
         1813  +proc ::dom::domParseFeedback {} {
         1814  +    return -code break
         1815  +}
         1816  +test dom-12.1 {-feedbackAfter -- cmd returns TCL_BREAK} -body {
         1817  +    dom parse -feedbackAfter 1 {<doc><e1/><e1/><e1/></doc>}
         1818  +} -result ""
         1819  +
         1820  +proc ::dom::domParseFeedback {} {
         1821  +    error "Error in feedback cmd."
         1822  +}
         1823  +test dom-12.2 {-feedbackAfter -- cmd returns TCL_ERROR} -body {
         1824  +    set result [catch {
         1825  +        dom parse -feedbackAfter 1 {<doc><e1/><e1/><e1/></doc>}
         1826  +    } msg]
         1827  +    list $result $msg
         1828  +} -result [list 1 "Error in feedback cmd."]
         1829  +
         1830  +proc ::dom::domParseFeedback {} {
         1831  +    # Update progess dialog, check for cancel etc.
         1832  +    return
         1833  +}
         1834  +test dom-12.3 {-feedbackAfter} -body {
         1835  +    set doc [dom parse -feedbackAfter 1 {<doc><e1/><e1/><e1/></doc>}]
         1836  +    $doc selectNodes count(//*)
         1837  +} -result 4
         1838  +test dom-12.4 {-feedbackAfter and -channel} -setup {
         1839  +    set xmlFile [makeFile {<doc><e1/><e1/><e1/></doc>} dom.xml]
         1840  +} -body {
         1841  +    set fd [open $xmlFile]
         1842  +    set doc [dom parse -channel $fd -feedbackAfter 1]
         1843  +    close $fd
         1844  +    $doc selectNodes count(//*)
         1845  +} -cleanup {
         1846  +    removeFile dom.xml
         1847  +} -result 4
         1848  +proc extRefResolver-12.5 {base systemId publicId} {
         1849  +    switch $publicId {
         1850  +        "a" {
         1851  +            set data "<e1/>"
         1852  +        }
         1853  +        "b" {
         1854  +            set data "<e1/><e1/>"
         1855  +        }
         1856  +        default {
         1857  +            error "unknown public ID"
         1858  +        }
         1859  +    }
         1860  +    return [list "string" $base $data]
         1861  +}
         1862  +test dom-12.5 {-feedbackAfter and external entities} -body {
         1863  +    set doc [dom parse -externalentitycommand extRefResolver-12.5 \
         1864  +                 -feedbackAfter 1 {
         1865  +                     <!DOCTYPE doc [
         1866  +                                    <!ENTITY a PUBLIC "a" "a.xml">
         1867  +                                    <!ENTITY b PUBLIC "b" "b.xml">
         1868  +                                    ]>
         1869  +                     <doc>&a;&b;</doc>}]
         1870  +    $doc selectNodes count(//*)
         1871  +} -result 4
         1872  +
         1873  +set cancel 0
         1874  +proc extRefResolver-12.6 {base systemId publicId} {
         1875  +    global cancel
         1876  +    switch $publicId {
         1877  +        "a" {
         1878  +            set cancel 1
         1879  +            set data "<e1/><e1/>"
         1880  +        }
         1881  +        "b" {
         1882  +            set data "<e1/>"
         1883  +        }
         1884  +        default {
         1885  +            error "unknown public ID"
         1886  +        }
         1887  +    }
         1888  +    return [list "string" $base $data]
         1889  +}
         1890  +proc ::dom::domParseFeedback {} {
         1891  +    global cancel
         1892  +    if {$cancel} {
         1893  +        return -code break
         1894  +    }
         1895  +}
         1896  +test dom-12.6 {-feedbackAfter and external entities, with cancel} -body {
         1897  +    dom parse -externalentitycommand extRefResolver-12.6 \
         1898  +        -feedbackAfter 1 {
         1899  +            <!DOCTYPE doc [
         1900  +                           <!ENTITY a PUBLIC "a" "a.xml">
         1901  +                           <!ENTITY b PUBLIC "b" "b.xml">
         1902  +                          ]>
         1903  +            <doc>&a;&b;</doc>}
         1904  +} -result ""
         1905  +proc ::dom::domParseFeedback {} {
         1906  +    global cancel
         1907  +    if {$cancel} {
         1908  +        error "Error in feedback cmd."
         1909  +    }
         1910  +}
         1911  +test dom-12.7 {-feedbackAfter and external entities, with error} -body {
         1912  +    set result [catch {dom parse -externalentitycommand extRefResolver-12.6 \
         1913  +                           -feedbackAfter 1 {
         1914  +                               <!DOCTYPE doc [
         1915  +                                              <!ENTITY a PUBLIC "a" "a.xml">
         1916  +                                              <!ENTITY b PUBLIC "b" "b.xml">
         1917  +                                             ]>
         1918  +                               <doc>&a;&b;</doc>}} msg]
         1919  +    list $result $msg
         1920  +} -result [list 1 "Error in feedback cmd."]
         1921  +
         1922  +test dom-12.8 {-feedbackAfter without -feedbackcmd} -setup {
         1923  +    catch {rename ::dom::domParseFeedback ""}
         1924  +} -body {
         1925  +    set result [catch {dom parse -feedbackAfter 100 <doc/>} msg]
         1926  +    list $result $msg
         1927  +} -result {1 {If -feedbackAfter is used, -feedbackcmd must also be used.}}
         1928  +
         1929  +proc feedbackcmd-12.9 {} {
         1930  +    return -code break
         1931  +}
         1932  +test dom-12.9 {-feedbackAfter with -feedbackcmd -- cmd returns TCL_BREAK} -body {
         1933  +    dom parse -feedbackAfter 1 -feedbackcmd feedbackcmd-12.9 \
         1934  +        {<doc><e1/><e1/><e1/></doc>}
         1935  +} -result ""
         1936  +
         1937  +proc feedbackcmd-12.10 {} {
         1938  +    error "Error in feedback cmd."
         1939  +}
         1940  +test dom-12.10 {-feedbackAfter with -feedbackcmd -- cmd returns TCL_ERROR} -body {
         1941  +    set result [catch {
         1942  +        dom parse -feedbackAfter 1 -feedbackcmd feedbackcmd-12.10 \
         1943  +            {<doc><e1/><e1/><e1/></doc>}
         1944  +    } msg]
         1945  +    list $result $msg
         1946  +} -result [list 1 "Error in feedback cmd."]
         1947  +
         1948  +proc feedbackcmd-12.11 {} {
         1949  +    # Update progess dialog, check for cancel etc.
         1950  +    return
         1951  +}
         1952  +test dom-12.11 {-feedbackAfter with -feedbackcmd} -body {
         1953  +    set doc [dom parse -feedbackAfter 1 -feedbackcmd feedbackcmd-12.11 \
         1954  +                 {<doc><e1/><e1/><e1/></doc>}]
         1955  +    $doc selectNodes count(//*)
         1956  +} -result 4
         1957  +test dom-12.12 {-feedbackAfter with -feedbackcmd and -channel} -setup {
         1958  +    set xmlFile [makeFile {<doc><e1/><e1/><e1/></doc>} dom.xml]
         1959  +} -body {
         1960  +    set fd [open $xmlFile]
         1961  +    set doc [dom parse -channel $fd -feedbackAfter 1 \
         1962  +                 -feedbackcmd feedbackcmd-12.11]
         1963  +    close $fd
         1964  +    $doc selectNodes count(//*)
         1965  +} -cleanup {
         1966  +    removeFile dom.xml
         1967  +} -result 4
         1968  +test dom-12.13 {-feedbackAfter with -feedbackcmd and external entities} -body {
         1969  +    set doc [dom parse -externalentitycommand extRefResolver-12.5 \
         1970  +                 -feedbackcmd feedbackcmd-12.11 \
         1971  +                 -feedbackAfter 1 {
         1972  +                     <!DOCTYPE doc [
         1973  +                                    <!ENTITY a PUBLIC "a" "a.xml">
         1974  +                                    <!ENTITY b PUBLIC "b" "b.xml">
         1975  +                                    ]>
         1976  +                     <doc>&a;&b;</doc>}]
         1977  +    $doc selectNodes count(//*)
         1978  +} -result 4
         1979  +
         1980  +set cancel 0
         1981  +proc feedbackcmd-12.14 {} {
         1982  +    global cancel
         1983  +    if {$cancel} {
         1984  +        return -code break
         1985  +    }
         1986  +}
         1987  +test dom-12.14 {-feedbackAfter with -feedbackcmd and external entities, with cancel} -body {
         1988  +    dom parse -externalentitycommand extRefResolver-12.6 \
         1989  +        -feedbackcmd feedbackcmd-12.14 \
         1990  +        -feedbackAfter 1 {
         1991  +            <!DOCTYPE doc [
         1992  +                           <!ENTITY a PUBLIC "a" "a.xml">
         1993  +                           <!ENTITY b PUBLIC "b" "b.xml">
         1994  +                          ]>
         1995  +            <doc>&a;&b;</doc>}
         1996  +} -result ""
         1997  +set cancel 0
         1998  +proc feedbackcmd-12.15 {} {
         1999  +    global cancel
         2000  +    if {$cancel} {
         2001  +        error "Error in feedback cmd."
         2002  +    }
         2003  +}
         2004  +test dom-12.15 {-feedbackAfter with -feedbackcmd and external entities, with error} -body {
         2005  +    set result [catch {dom parse -externalentitycommand extRefResolver-12.6 \
         2006  +                           -feedbackcmd feedbackcmd-12.15 \
         2007  +                           -feedbackAfter 1 {
         2008  +                               <!DOCTYPE doc [
         2009  +                                              <!ENTITY a PUBLIC "a" "a.xml">
         2010  +                                              <!ENTITY b PUBLIC "b" "b.xml">
         2011  +                                             ]>
         2012  +                               <doc>&a;&b;</doc>}} msg]
         2013  +    list $result $msg
         2014  +} -result [list 1 "Error in feedback cmd."]
         2015  +proc feedbackcmd-12.16 {} {
         2016  +    incr ::feedbackcmd-12.16
         2017  +}
         2018  +test dom-12.16 {-feedbackcmd setting interp result w/ invalid XML} -body {
         2019  +    set ::feedbackcmd-12.16 0
         2020  +    set result [catch {dom parse -feedbackcmd feedbackcmd-12.16 \
         2021  +                           -feedbackAfter 1 {<doc><e1/><e1/><e1></doc}} msg]
         2022  +    list $result $msg
         2023  +} -result [list 1 {error "unclosed token" at line 1 character 19
         2024  +"<doc><e1/><e1/><e1>< <--Error-- /doc"}]
  1300   2025   
  1301   2026   # cleanup
  1302   2027   ::tcltest::cleanupTests
  1303   2028   return

Changes to tests/domDoc.test.

    27     27   #    domDoc-21.*: baseURI
    28     28   #    domDoc-22.*: appendFromScript
    29     29   #    domDoc-23.*: getElementsByTagNameNS
    30     30   #    domDoc-24.*: cdataSectionElements
    31     31   #    domDoc-25.*: selectNodesNamespaces
    32     32   #    domDoc-26.*: fragments list
    33     33   #    domDoc-27.*: deleteXPathCache
           34  +#    domDoc-28.*: createElementNS
    34     35   #
    35     36   # Copyright (c) 2004 - 2007 Rolf Ade.
    36     37   
    37     38   source [file join [file dir [info script]] loadtdom.tcl]
    38     39   
    39     40   test domDoc-1.1 {asXML -escapeNonASCII} {need_i18n} {
    40         -    set doc [dom parse [tDOM::xmlReadFile \
           41  +    set doc [dom parse [tdom::xmlReadFile \
    41     42               [file join [file dir [info script]] data/i18n_1.xml]]]
    42     43       set result [$doc asXML -escapeNonASCII]
    43     44       $doc delete
    44     45       set result
    45     46   } {<test>&#1072;&#1073;&#1074;&#1075;&#1076;&#1077;&#1078;&#1079;&#1080;&#1081;</test>
    46     47   }
    47     48   
    48     49   test domDoc-1.2 {asXML -escapeNonASCII; comments and PI's are not altered} {need_i18n} {
    49         -    set doc [dom parse [tDOM::xmlReadFile \
           50  +    set doc [dom parse [tdom::xmlReadFile \
    50     51               [file join [file dir [info script]] data/i18n_2.xml]]]
    51     52       set result [$doc asXML -indent none -escapeNonASCII]
    52     53       $doc delete
    53     54       set result
    54     55   } "<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?>
    55     56   german umlauts: &#228;&#246;&#252;&#223;
    56     57   </root>"
................................................................................
   114    115   
   115    116   test domDoc-1.10 {asXML - unknown option} {
   116    117       set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
   117    118       set errMsg ""
   118    119       catch {$doc asXML -fooOption 1} errMsg
   119    120       $doc delete
   120    121       set errMsg
   121         -} {bad option "-fooOption": must be -indent, -channel, -escapeNonASCII, -doctypeDeclaration, or -escapeAllQuot}
          122  +} {bad option "-fooOption": must be -indent, -channel, -escapeNonASCII, -doctypeDeclaration, -xmlDeclaration, -encString, -escapeAllQuot, -indentAttrs, -nogtescape, or -noEmptyElementTag}
   122    123   
   123    124   test domDoc-1.11 {asXML - non boolean value to -doctypeDeclaration} {
   124    125       set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
   125    126       set errMsg ""
   126    127       catch {$doc asXML -doctypeDeclaration foo} errMsg
   127    128       $doc delete
   128    129       set errMsg
................................................................................
   207    208       set result
   208    209   } {<doc>
   209    210       <!--Comment 1-->
   210    211       <e1/>
   211    212       <!--Comment 2-->
   212    213   </doc>
   213    214   }
          215  +
          216  +test domDoc-1.21 {asXML -indentAttrs} {
          217  +    set doc [dom parse {<Element attr1="val1" attr2="val2"/>}]
          218  +    set result [$doc asXML -indentAttrs 4]
          219  +    $doc delete
          220  +    set result
          221  +} {<Element
          222  +    attr1="val1"
          223  +    attr2="val2"/>
          224  +}
          225  +
          226  +test domDoc-1.22 {asXML} {
          227  +    set doc [dom createDocument doc]
          228  +    set result [$doc asXML]
          229  +    $doc delete
          230  +    set result
          231  +} {<doc/>
          232  +}
          233  +
          234  +test domDoc-1.23 {asXML -xmlDeclaration} {
          235  +    set doc [dom createDocument doc]
          236  +    set result [$doc asXML -xmlDeclaration 1]
          237  +    $doc delete
          238  +    set result
          239  +} {<?xml version="1.0"?>
          240  +<doc/>
          241  +}
          242  +
          243  +test domDoc-1.23 {asXML -xmlDeclaration} {
          244  +    set doc [dom createDocument doc]
          245  +    set result [$doc asXML -xmlDeclaration 1]
          246  +    $doc delete
          247  +    set result
          248  +} {<?xml version="1.0"?>
          249  +<doc/>
          250  +}
          251  +
          252  +test domDoc-1.24 {asXML just -encString without -xmlDeclaration} {
          253  +    set doc [dom createDocument doc]
          254  +    set result [$doc asXML -encString foo]
          255  +    $doc delete
          256  +    set result
          257  +} {<doc/>
          258  +}
          259  +
          260  +test domDoc-1.25 {asXML -xmlDeclaration -encString} {
          261  +    set doc [dom createDocument doc]
          262  +    set result [$doc asXML -xmlDeclaration 1 -encString foo]
          263  +    $doc delete
          264  +    set result
          265  +} {<?xml version="1.0" encoding="foo"?>
          266  +<doc/>
          267  +} 
          268  +
          269  +test domDoc-1.26 {asXML -xmlDeclaration, encoding set by encoding method} {
          270  +    set doc [dom createDocument doc]
          271  +    $doc encoding "foo"
          272  +    set result [$doc asXML -xmlDeclaration 1]
          273  +    $doc delete
          274  +    set result
          275  +} {<?xml version="1.0" encoding="foo"?>
          276  +<doc/>
          277  +}    
          278  +
          279  +test domDoc-1.27 {asXML -xmlDeclaration -encString} {
          280  +    set doc [dom createDocument doc]
          281  +    set result [catch {
          282  +        [$doc asXML -xmlDeclaration 1 -encString foo \
          283  +             -encString bar -wrongOption]
          284  +    }]
          285  +    $doc delete
          286  +    set result
          287  +} 1 
          288  +
          289  +test domDoc-1.28 {asXML -xmlDeclaration not xml compliant -encString} {
          290  +    set doc [dom createDocument doc]
          291  +    set result [$doc asXML -xmlDeclaration 1 -encString 1\u2345]
          292  +    $doc delete
          293  +    set result
          294  +} [subst -nocommands -novariables {<?xml version="1.0" encoding="1\u2345"?>
          295  +<doc/>
          296  +}]
          297  +
          298  +test domDoc-1.29 {asXML -nogtescape} {
          299  +    set doc [dom parse {<doc attr="foo>bar">></doc>}]
          300  +    set result [$doc asXML -nogtescape -indent none]
          301  +    $doc delete
          302  +    set result
          303  +} {<doc attr="foo>bar">></doc>}
          304  +
          305  +test domDoc-1.30 {asXML -noEmptyElementTag} {
          306  +    set doc [dom parse {<doc><elm/></doc>}]
          307  +    set result [$doc asXML -noEmptyElementTag -indent none]
          308  +    $doc delete
          309  +    set result
          310  +} {<doc><elm></elm></doc>}
          311  +
          312  +test domDoc-1.31 {asXML '"' in attribute value} {
          313  +    # emacs: "
          314  +    set doc [dom createDocument doc]
          315  +    set root [$doc documentElement]
          316  +    $root setAttribute attr "foo\"bar"
          317  +    set result [$doc asXML -indent none]
          318  +    $doc delete
          319  +    set result
          320  +} {<doc attr="foo&quot;bar"/>}
   214    321   
   215    322   set doc [dom parse <root/>]
   216    323   
   217    324   test domDoc-2.1 {publicId - no publicId there} {
   218    325       $doc publicId
   219    326   } {}
   220    327   
................................................................................
   353    460       set result [catch {$xsltCmd -bogusOption foo $doc resultDoc} errMsg]
   354    461       lappend result $errMsg
   355    462       lappend result [catch {$xsltCmd $doc resultDoc}]
   356    463       lappend result [$resultDoc asXML -indent none]
   357    464       $resultDoc delete
   358    465       rename $xsltCmd {}
   359    466       set result
   360         -} {1 {bad option "-bogusOption": must be -parameters, -ignoreUndeclaredParameters, or -xsltmessagecmd} 0 {param1Default param2Default param3Default }}
          467  +} {1 {bad option "-bogusOption": must be -parameters, -ignoreUndeclaredParameters, -maxApplyDepth, or -xsltmessagecmd} 0 {param1Default param2Default param3Default }}
   361    468   
   362    469   test domDoc-3.4 {toXSLTcmd} {
   363    470       set xslt [dom parse -keepEmpties $xslt1]
   364    471       set xsltCmd [$xslt toXSLTcmd]
   365    472   
   366    473       set result [catch {$xsltCmd -xsltmessagecmd msgCmd1} errMsg]
   367    474       rename $xsltCmd {}
   368    475       lappend result $errMsg
   369         -} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}
          476  +} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-maxApplyDepth int? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}
   370    477   
   371    478   test domDoc-3.5 {toXSLTcmd} {
   372    479       set xslt [dom parse -keepEmpties $xslt1]
   373    480       set xsltCmd [$xslt toXSLTcmd]
   374    481   
   375    482       set result [catch {$xsltCmd $doc resultDoc bogus} errMsg]
   376    483       rename $xsltCmd {}
   377    484       lappend result $errMsg
   378         -} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}
          485  +} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-maxApplyDepth int? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}
   379    486   
   380    487   test domDoc-3.6 {toXSLTcmd} {
   381    488       set xslt [dom parse -keepEmpties $xslt1]
   382    489       set xsltCmd [$xslt toXSLTcmd]
   383    490   
   384    491       set result [catch {$xsltCmd -parameters {param1 foo} -parameters {param2 foo} $doc resultDoc} errMsg]
   385    492       rename $xsltCmd {}
................................................................................
   719    826       }
   720    827       $elemNode setAttribute id "new"
   721    828       [$doc getElementById "new"] getAttribute name
   722    829   } -cleanup {
   723    830       $doc delete
   724    831   } -result that
   725    832   
   726         -test domDoc-10.3 {getElementById} -setup $getElementByIdSetup -body {
   727         -    set root [$doc documentElement]
   728         -    set elemNode [$root selectNodes {elem[2]}]
   729         -    if {![$elemNode hasAttribute id]} {
   730         -        error "error in the test code"
   731         -    }
   732         -    $elemNode setAttribute id "new"
   733         -    [$doc getElementById "new"] getAttribute name
   734         -} -cleanup {
   735         -    $doc delete
   736         -} -result that
   737         -
   738    833   test domDoc-10.4 {getElementById} -setup $getElementByIdSetup -body {
   739    834       set root [$doc documentElement]
   740    835       set elemNode [$root selectNodes {elem[2]}]
   741    836       if {![$elemNode hasAttribute id]} {
   742    837           error "error in the test code"
   743    838       }
   744    839       $root removeChild $elemNode
................................................................................
  1001   1096       lappend result [$node nodeName]
  1002   1097       lappend result [$doc selectNodes -namespaces {} doc typeVar]
  1003   1098       lappend result $typeVar
  1004   1099       $doc delete
  1005   1100       set result
  1006   1101   } [list tdom:doc tdom:doc "" empty]
  1007   1102   
         1103  +test domDoc-20.6 {selectNodes with -namespaces option} {
         1104  +    set doc [dom createDocumentNS "http://tdom.org" tdom:doc]
         1105  +    set node [$doc selectNodes \
         1106  +                  -namespaces {foo bar} \
         1107  +                  -namespaces {a b c d} \
         1108  +                  -namespaces {tdom http://tdom.org} \
         1109  +                  tdom:doc]
         1110  +    set result [$node nodeName]
         1111  +    set node [$doc selectNodes \
         1112  +                  -namespaces {myPrefix http://tdom.org} \
         1113  +                  myPrefix:doc]
         1114  +    lappend result [$node nodeName]
         1115  +    lappend result [$doc selectNodes -namespaces {} doc typeVar]
         1116  +    lappend result $typeVar
         1117  +    $doc delete
         1118  +    set result
         1119  +} [list tdom:doc tdom:doc "" empty]
         1120  +
         1121  +test domDoc-20.7 {selectNodes with -namespaces option} {
         1122  +    set doc [dom createDocumentNS "http://tdom.org" tdom:doc]
         1123  +    catch {set node [$doc selectNodes \
         1124  +                         -namespaces {foo bar} \
         1125  +                         -namespaces {a b c d} \
         1126  +                         -namespaces {wrong_not_pair} \
         1127  +                         tdom:doc]} errMsg
         1128  +    $doc delete
         1129  +    set errMsg
         1130  +} {The "-namespaces" option requires a 'prefix namespace' pairs list as argument}
         1131  +
  1008   1132   test domDoc-21.1 {baseURI} {
  1009   1133       set doc [dom createDocumentNode]
  1010   1134       set result [$doc baseURI]
  1011   1135       $doc delete
  1012   1136       set result
  1013   1137   } {}
  1014   1138   
................................................................................
  1037   1161       lappend result [[$doc documentElement] nodeName]
  1038   1162       $doc delete
  1039   1163       set result
  1040   1164   } {<e1/> e1}
  1041   1165   
  1042   1166   test domDoc-22.2 {appendFromScript} {
  1043   1167       set doc [dom parse <root/>]
  1044         -    namespace eval nodeCmds {
  1045         -        $doc appendFromScript {
  1046         -            e1
  1047         -            e2
  1048         -        }
         1168  +    $doc appendFromScript {
         1169  +        nodeCmds::e1
         1170  +        nodeCmds::e2
  1049   1171       }
         1172  +    # namespace eval nodeCmds {
         1173  +    #     $doc appendFromScript {
         1174  +    #         e1
         1175  +    #         e2
         1176  +    #     }
         1177  +    # }
  1050   1178       set result [$doc asXML -indent none]
  1051   1179       foreach node [$doc selectNodes *] {
  1052   1180           lappend result [$node parentNode]
  1053   1181           lappend result [expr {$doc == [$node ownerDocument]}]
  1054   1182       }
  1055   1183       $doc delete
  1056   1184       set result
................................................................................
  1221   1349       $doc documentElement root
  1222   1350       set node [$root firstChild]
  1223   1351       $doc cdataSectionElements child 1
  1224   1352       set result [$node asXML -indent none]
  1225   1353       $doc delete
  1226   1354       set result
  1227   1355   } {<child><![CDATA[some text]]></child>}
         1356  +
         1357  +test domDoc-24.17 {cdataSectionElements} {
         1358  +    set doc [dom parse {<doc><child>some text <b>more text</b> text again</child></doc>}]
         1359  +    $doc cdataSectionElements child 1
         1360  +    set result [$doc asXML -indent none]
         1361  +    $doc delete
         1362  +    set result
         1363  +} {<doc><child><![CDATA[some text ]]><b>more text</b><![CDATA[ text again]]></child></doc>}
         1364  +
  1228   1365   
  1229   1366   test domDoc-25.1 {selectNodesNamespaces} {
  1230   1367       set doc [dom createDocument foo]
  1231   1368       set result [$doc selectNodesNamespaces]
  1232   1369       $doc delete
  1233   1370       set result
  1234   1371   } {}
................................................................................
  1295   1432       set node [$doc selectNodes default1:root/default2:elem1]
  1296   1433       set result [list [$node prefix] [$node localName]]
  1297   1434       set node [$doc selectNodes default1:root/default2:elem1/elem11]
  1298   1435       lappend result [$node nodeName] [$node namespaceURI]
  1299   1436       $doc delete
  1300   1437       set result
  1301   1438   } {{} elem1 elem11 {}}
         1439  +
         1440  +test domDoc-25.7.1 {selectNodesNamespaces} {
         1441  +    set doc [dom parse {<root xmlns="rootdefaultNS">
         1442  +        <elem1 xmlns="elem1NS"/>
         1443  +        <elem2 xmlns="elem2NS"/>
         1444  +        </root>}]
         1445  +    $doc documentElement root
         1446  +    $root firstChild elem1
         1447  +    $doc createElement elem11 elem11
         1448  +    $elem1 appendChild $elem11
         1449  +    $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
         1450  +    set node [$doc selectNodes default1:root/default2:elem1]
         1451  +    set result [list [$node prefix] [$node localName]]
         1452  +    set node [$doc selectNodes default1:root/default2:elem1/elem11]
         1453  +    lappend result [$node nodeName] [$node namespaceURI]
         1454  +    $doc delete
         1455  +    set result
         1456  +} {{} elem1 elem11 {}}
  1302   1457   
  1303   1458   test domDoc-25.8 {selectNodesNamespaces} {
  1304   1459       set doc [dom parse {<root xmlns="rootdefaultNS">
  1305   1460           <elem1 xmlns="elem1NS"><elem11 xmlns=""/></elem1>
  1306   1461           <elem2 xmlns="elem2NS"/>
  1307   1462           </root>}]
  1308   1463       $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
................................................................................
  1358   1513       lappend result [$doc deleteXPathCache foo/bar]
  1359   1514       lappend result [$doc deleteXPathCache 2+2]
  1360   1515       lappend result [$doc deleteXPathCache]
  1361   1516       $doc selectNodes -cache 1 2+2
  1362   1517       $doc delete
  1363   1518       set result
  1364   1519   } {{} {} {} {}}
         1520  +
         1521  +test domDoc-28.1 {createElementNS} {
         1522  +    set doc [dom createDocument doc]
         1523  +    set newElem [$doc createElementNS uri ns:e]
         1524  +    $doc documentElement root
         1525  +    $root appendChild $newElem
         1526  +    set result [$doc asXML -indent none]
         1527  +    $doc delete
         1528  +    set result
         1529  +} {<doc><ns:e xmlns:ns="uri"/></doc>}
         1530  +
         1531  +test domDoc-28.2 {createElementNS} {
         1532  +    set doc [dom createDocument doc]
         1533  +    set newElem [$doc createElementNS uri ns:e]
         1534  +    $newElem setAttributeNS uri ns:att value
         1535  +    $doc documentElement root
         1536  +    $root appendChild $newElem
         1537  +    set result [$doc selectNodes -namespaces {ns uri} string(/doc/ns:e/@ns:att)]
         1538  +    $doc delete
         1539  +    set result
         1540  +} {value}
         1541  +
         1542  +test domDoc-28.3 {createElementNS} {
         1543  +    set doc [dom createDocument doc]
         1544  +    catch {$doc createElementNS "" e} errMsg
         1545  +    $doc delete
         1546  +    set errMsg
         1547  +} {Missing URI in Namespace declaration}
         1548  +
  1365   1549   
  1366   1550   # cleanup
  1367   1551   ::tcltest::cleanupTests
  1368   1552   return

Changes to tests/domNode.bench.

   202    202       } -body {
   203    203           $doc selectNodes -cache 1 count(/root/e1)
   204    204       } -post {
   205    205           $doc delete
   206    206       }
   207    207   
   208    208   }
          209  +
          210  +foreach nrOf {1 10 100 1000} {
          211  +
          212  +    bench -desc "getElementsByTagName: $nrOf returned nodes" -pre {
          213  +        dom createDocument root doc
          214  +        $doc documentElement root
          215  +        $root appendFromScript {
          216  +            for {set x 0} {$x < $nrOf} {incr x} {
          217  +                e1
          218  +            }
          219  +        }
          220  +    } -body {
          221  +        $doc getElementsByTagName e1
          222  +    } -post {
          223  +        $doc delete
          224  +    }
          225  +
          226  +}
          227  +
          228  +foreach nrOf {1 10 100 1000} {
          229  +
          230  +    bench -desc "getElementsByTagName: $nrOf returned node tokens" -pre {
          231  +        dom createDocument root doc
          232  +        $doc documentElement root
          233  +        $root appendFromScript {
          234  +            for {set x 0} {$x < $nrOf} {incr x} {
          235  +                e1
          236  +            }
          237  +        }
          238  +        dom setObjectCommands token
          239  +    } -body {
          240  +        $doc getElementsByTagName e1
          241  +    } -post {
          242  +        dom setObjectCommands automatic
          243  +        $doc delete
          244  +    }
          245  +
          246  +}
          247  +
          248  +
          249  +bench -desc "firstChild node cmd" -pre {
          250  +    dom parse <root><e/></root> doc
          251  +    $doc documentElement root
          252  +} -body {
          253  +    $root firstChild
          254  +} -post {
          255  +    $doc delete
          256  +}
          257  +
          258  +bench -desc "firstChild node token" -pre {
          259  +    dom parse <root><e/></root> doc
          260  +    $doc documentElement root
          261  +    dom setObjectCommands token
          262  +} -body {
          263  +    $root firstChild
          264  +} -post {
          265  +    $doc delete
          266  +    dom setObjectCommands automatic
          267  +}
          268  +
          269  +bench -desc "firstChild node token from node token" -pre {
          270  +    dom parse <root><e/></root> doc
          271  +    dom setObjectCommands token
          272  +    $doc documentElement root
          273  +} -body {
          274  +    domNode $root firstChild
          275  +} -post {
          276  +    $doc delete
          277  +    dom setObjectCommands automatic
          278  +}
   209    279   
   210    280   dom parse <root/> doc
   211    281   $doc documentElement root
   212    282   
   213    283   bench -desc "Check for text-only element - xpath - empty"  -body {
   214    284       for {set x 0} {$x < 100} {incr x} {
   215    285           $doc selectNodes -cache 1 {count(node()) = 1 and node() = text()}

Changes to tests/domNode.test.

    17     17   #    domNode-11.*: disableOutputEscaping 
    18     18   #    domNode-12.*: cloneNode
    19     19   #    domNode-13.*: appendFromScript
    20     20   #    domNode-14.*: appendFromList  
    21     21   #    domNode-15.*: delete
    22     22   #    domNode-16.*: getAttribute
    23     23   #    domNode-17.*: nodeType
    24         -#    domNode-18.*: attributes
           24  +#    domNode-18.*: attributes, attributeNames
    25     25   #    domNode-19.*: removeAttribute, removeAttributeNS
    26     26   #    domNode-20.*: parentNode
    27     27   #    domNode-21.*: hasChildNodes
    28     28   #    domNode-22.*: localName, prefix
    29     29   #    domNode-23.*: replaceChild
    30     30   #    domNode-24.*: getLine, getColumn
    31     31   #    domNode-25.*: hasAttribute, hasAttributeNS
................................................................................
    47     47   #
    48     48   # Copyright (c) 2002 - 2005 Rolf Ade.
    49     49   #
    50     50   # RCS: @(#) $Id$
    51     51   
    52     52   source [file join [file dir [info script]] loadtdom.tcl]
    53     53   
    54         -test domNode-1.1 {to less arguments to domNode command} {
           54  +testConstraint threaded [info exists tcl_platform(threaded)]
           55  +
           56  +test domNode-1.1 {too less arguments to nodecmd} {
    55     57       set doc [dom createDocument "root"]
    56     58       set root [$doc documentElement]
    57     59       set result [catch {$root}]
    58     60       $doc delete
    59     61       set result
    60     62   } {1}
    61     63   
    62         -test domNode-1.2 {to less arguments to domNode command} {
           64  +test domNode-1.2 {too less arguments to domNode token} {
    63     65       set doc [dom createDocument "root"]
    64     66       set root [$doc documentElement]
    65     67       set result [catch {domNode $root}]
    66     68       $doc delete
    67     69       set result
    68     70   } {1}
    69     71   
    70         -test domNode-1.3 {to less arguments to domNode command} {
           72  +test domNode-1.3 {too less arguments to domNode command} {
    71     73       catch {domNode}
    72     74   } {1}
    73     75   
    74     76   test domNode-1.4 {rename of domNodeObj cmd} {knownBug} {
    75     77       set doc [dom createDocument "root"]
    76     78       set root [$doc documentElement]
    77     79       rename $root my_domNode
................................................................................
    78     80       set result [llength [info commands my_domNode]]
    79     81       $doc delete
    80     82       lappend result [llength [info commands my_domNode]]
    81     83       catch {my_domNode nodeName} errMsg
    82     84       lappend result $errMsg
    83     85   } {1 0}    
    84     86   
           87  +test domNode-1.5 {domNode command: invalid token} {
           88  +    set xml {<doc><e>1</e><e>2</e></doc>}
           89  +
           90  +    set doc [dom parse $xml]
           91  +    set root [domDoc $doc documentElement]
           92  +    set invalidToken [domNode $root firstChild]
           93  +    lappend invalidToken foo
           94  +    set result [catch {domNode $invalidToken selectNodes string(.)}]
           95  +    $doc delete
           96  +    set result
           97  +} {1}
           98  +
           99  +test domNode-1.6 {domNode command: invalid token} {
          100  +    set xml {<doc><e>1</e><e>2</e></doc>}
          101  +
          102  +    set doc [dom parse $xml]
          103  +    set root [domDoc $doc documentElement]
          104  +    set invalidToken [domNode $root firstChild]
          105  +    append invalidToken "\n"
          106  +    set result [catch {domNode $invalidToken selectNodes string(.)}]
          107  +    $doc delete
          108  +    set result
          109  +} {1}
          110  +
          111  +proc domNode-1.7-traceproc {args} {
          112  +    error "error in nodeObjVar trace"
          113  +}
          114  +
          115  +test domNode-1.7 {error in trace on nodeObjVar} {
          116  +    set xml {<doc><e>1</e><e>2</e></doc>}
          117  +
          118  +    set doc [dom parse $xml]
          119  +    set root [$doc documentElement]
          120  +    trace add variable resultVar write domNode-1.7-traceproc
          121  +    set result [catch {$root firstChild resultVar} errMsg]
          122  +    lappend result $errMsg
          123  +    trace remove variable resultVar write domNode-1.7-traceproc
          124  +    $doc delete
          125  +    set result
          126  +} {1 {can't set "resultVar": error in nodeObjVar trace}}
          127  +
    85    128   set doc [dom parse {<root xmlns="rootdefaultNS">
    86    129       <elem1 xmlns="elem1NS"><elem11/></elem1>
    87    130       <elem2 xmlns="elem2NS"/>
    88    131       </root>}]
    89    132   set root [$doc documentElement]
    90    133   
    91    134   test domNode-2.1 {selectNodes - -namespace option: syntax} {
................................................................................
   168    211       set r2 [catch {$root selectNodes -cache 1}]
   169    212       set r3 [catch {$root selectNodes -cache 0}]
   170    213       set r4 [catch {$root selectNodes ""}]
   171    214       set r5 [catch {$root selectNodes -cache 1 ""}]
   172    215       set r6 [catch {$root selectNodes -cache 0 ""}]
   173    216       list $r1 $r2 $r3 $r4 $r5 $r6
   174    217   } {1 1 1 1 1 1}
          218  +
          219  +test domNode-2.12 {selectNodes - -cache option} {
          220  +     # Second usage of an invalid XPath expr with -cache 1
          221  +     # See 97c0994ae4
          222  +     catch {$root selectNodes -cache 1 "/foo bar"}
          223  +     catch {$root selectNodes -cache 1 "/foo bar"}
          224  +} 1
   175    225   
   176    226   $doc delete
   177    227   
   178    228   test domNode-3.1 {repetitived documentElement with objVar, then delete} {
   179    229       dom createDocument "root" doc 
   180    230       $doc documentElement root
   181    231       $doc delete
................................................................................
   349    399       $root setAttributeNS uri1 p1:a1 1 uri1 p1:a2 2 uri2 p2:a3 3 "" a4 4
   350    400       set result [$root asXML]
   351    401       $doc delete
   352    402       set result
   353    403   } {<p1:root xmlns:p1="uri1" xmlns:p2="uri2" p1:a1="1" p1:a2="2" p2:a3="3" a4="4"/>
   354    404   }
   355    405   
          406  +test domNode-4.17 {setAttributeNS - set multiple Attribute with NS atts undermixed at once} {
          407  +    set doc [dom createDocumentNS uri1 "p1:root"]
          408  +    set root [$doc documentElement]
          409  +    $root setAttributeNS "" xmlns:p2 uri2
          410  +    $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
          411  +    set result [$root asXML]
          412  +    $doc delete
          413  +    set result
          414  +} {<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"/>
          415  +}
          416  +
          417  +test domNode-4.18 {setAttributeNS - prefixed attribute name with empty namespace} {
          418  +    set doc [dom createDocument "root"]
          419  +    set root [$doc documentElement]
          420  +    catch {$root setAttributeNS "" ns:att attvalue} errMsg
          421  +    $doc delete
          422  +    set errMsg
          423  +} {For all prefixed attributes with prefixes other than 'xml' or 'xmlns' you have to provide a namespace URI}
          424  +
   356    425   test domNode-5.1 {removeChild} {
   357    426       dom parse {<root><child/></root>} doc
   358    427       $doc documentElement root
   359    428       $root removeChild [$root firstChild]
   360    429       set result [$doc asXML -indent none]
   361    430       $doc delete
   362    431       set result
................................................................................
   566    635           b "<existing_report_two>...</existing_report_two>"
   567    636       } {
   568    637           lappend fileList [makeFile $content $name]
   569    638       }
   570    639   } -body {
   571    640       set docs {}
   572    641       foreach rf $fileList {
   573         -        set doc [dom parse -baseurl [tDOM::baseURL $rf] \
   574         -                     -externalentitycommand ::tDOM::extRefHandler \
          642  +        set doc [dom parse -baseurl [tdom::baseURL $rf] \
          643  +                     -externalentitycommand ::tdom::extRefHandler \
   575    644                        -keepEmpties \
   576         -                     [tDOM::xmlReadFile $rf] ]
          645  +                     [tdom::xmlReadFile $rf] ]
   577    646           lappend docs $doc
   578    647       }
   579    648       set resultDoc [dom createDocument new_report]
   580    649       set root [$resultDoc documentElement]
   581    650       foreach doc $docs {
   582    651           $root appendChild [$doc documentElement]
   583    652       }
................................................................................
  1178   1247       set result
  1179   1248   } {<root><e1/></root>}
  1180   1249   
  1181   1250   test domNode-13.2 {appendFromScript - elementNode} {
  1182   1251       set doc [dom createDocument root]
  1183   1252       set root [$doc documentElement]
  1184   1253       namespace eval nodeCmds {
  1185         -        $root appendFromScript {
         1254  +        $::root appendFromScript {
  1186   1255               e1
  1187   1256               e2
  1188   1257           }
  1189   1258       }
  1190   1259       set result [$root asXML -indent none]
  1191   1260       $doc delete
  1192   1261       set result
  1193   1262   } {<root><e1/><e2/></root>}
  1194   1263   
  1195   1264   test domNode-13.3 {appendFromScript - elementNode} {
  1196   1265       set doc [dom createDocument root]
  1197   1266       set root [$doc documentElement]
  1198   1267       namespace eval nodeCmds {
  1199         -        $root appendFromScript {
         1268  +        $::root appendFromScript {
  1200   1269               e1 {
  1201   1270                   e2 {
  1202   1271                       e1
  1203   1272                   }
  1204   1273               }
  1205   1274               e2
  1206   1275           }
................................................................................
  1210   1279       set result
  1211   1280   } {<root><e1><e2><e1/></e2></e1><e2/></root>}
  1212   1281   
  1213   1282   test domNode-13.4 {appendFromScript - elementNode with attributes as options} {
  1214   1283       set doc [dom createDocument root]
  1215   1284       set root [$doc documentElement]
  1216   1285       namespace eval nodeCmds {
  1217         -        $root appendFromScript {
         1286  +        $::root appendFromScript {
  1218   1287               e1 -attr1 attr1Value -attr2 "attr 2 Value"
  1219   1288           }
  1220   1289       }
  1221   1290       set result [$root asXML -indent none]
  1222   1291       $doc delete
  1223   1292       set result
  1224   1293   } {<root><e1 attr1="attr1Value" attr2="attr 2 Value"/></root>}
  1225   1294   
  1226   1295   test domNode-13.5 {appendFromScript - elementNode with attributes as list} {
  1227   1296       set doc [dom createDocument root]
  1228   1297       set root [$doc documentElement]
  1229   1298       set attlist [list -a1 "some & value" -a2 "another attvalue"]
  1230   1299       namespace eval nodeCmds {
  1231         -        $root appendFromScript {
  1232         -            e1 $attlist {}
         1300  +        $::root appendFromScript {
         1301  +            e1 $::attlist {}
  1233   1302           }
  1234   1303       }
  1235   1304       set result [$root asXML -indent none]
  1236   1305       $doc delete
  1237   1306       set result
  1238   1307   } {<root><e1 a1="some &amp; value" a2="another attvalue"/></root>}
  1239   1308   
  1240   1309   test domNode-13.6 {appendFromScript - textnode, commentnode, cdatanode, pinode} {
  1241   1310       set doc [dom createDocument root]
  1242   1311       set root [$doc documentElement]
  1243   1312       namespace eval nodeCmds {
  1244         -        $root appendFromScript {
         1313  +        $::root appendFromScript {
  1245   1314               t foo
  1246   1315               c "my comment"
  1247   1316               cdata {&"<>;} ;# emacs: "
  1248   1317               pi mypi "some pi data"
  1249   1318           }
  1250   1319       }
  1251   1320       set result [$root asXML -indent none]
................................................................................
  1255   1324   
  1256   1325   # emacs: "
  1257   1326   
  1258   1327   test domNode-13.7 {appendFromScript - textnode} {
  1259   1328       set doc [dom createDocument root]
  1260   1329       set root [$doc documentElement]
  1261   1330       namespace eval nodeCmds {
  1262         -        $root appendFromScript {
         1331  +        $::root appendFromScript {
  1263   1332               t "<p>Some <b>important</b> stuff</p>"
  1264   1333           }
  1265   1334       }
  1266   1335       set result [$root asXML -indent none]
  1267   1336       $doc delete
  1268   1337       set result
  1269   1338   } {<root>&lt;p&gt;Some &lt;b&gt;important&lt;/b&gt; stuff&lt;/p&gt;</root>}
  1270   1339   
  1271   1340   test domNode-13.8 {appendFromScript - textnode with -disableOutputEscaping} {
  1272   1341       set doc [dom createDocument root]
  1273   1342       set root [$doc documentElement]
  1274   1343       namespace eval nodeCmds {
  1275         -        $root appendFromScript {
         1344  +        $::root appendFromScript {
  1276   1345               t -disableOutputEscaping "<p>Some <b>important</b> stuff</p>"
  1277   1346           }
  1278   1347       }
  1279   1348       set result [$root asXML -indent none]
  1280   1349       $doc delete
  1281   1350       set result
  1282   1351   } {<root><p>Some <b>important</b> stuff</p></root>}
................................................................................
  1358   1427           dom createNodeCmd elementNode thisCmds::thisE
  1359   1428       }
  1360   1429       set result [llength [info commands nodeCmds::thisE]]
  1361   1430       lappend result [llength [info commands nodeCmds::thisCmds::thisE]]
  1362   1431       set doc [dom createDocument root]
  1363   1432       set root [$doc documentElement]
  1364   1433       namespace eval nodeCmds {
  1365         -        $root appendFromScript {
         1434  +        $::root appendFromScript {
  1366   1435               thisCmds::thisE
  1367   1436           }
  1368   1437       }
  1369   1438       lappend result [$doc asXML -indent none]
  1370   1439       $doc delete
  1371   1440       set result
  1372   1441   } {0 1 <root><thisE/></root>}
  1373   1442   
  1374   1443   set nsname "tricky nsname"
  1375   1444   namespace eval nodeCmds::$nsname { }
  1376   1445   
  1377   1446   test domNode-13.15 {qualified nodeCmds name} {
  1378   1447       namespace eval nodeCmds {
  1379         -        dom createNodeCmd elementNode ${nsname}::thisE
         1448  +        dom createNodeCmd elementNode ${::nsname}::thisE
  1380   1449       }
  1381   1450       set result [llength [info commands nodeCmds::thisE]]
  1382   1451       lappend result [llength [info commands nodeCmds::${nsname}::thisE]]
  1383   1452       set doc [dom createDocument root]
  1384   1453       set root [$doc documentElement]
  1385   1454       namespace eval nodeCmds {
  1386         -        $root appendFromScript {
  1387         -            ${nsname}::thisE
         1455  +        $::root appendFromScript {
         1456  +            ${::nsname}::thisE
  1388   1457           }
  1389   1458       }
  1390   1459       lappend result [$doc asXML -indent none]
  1391   1460       $doc delete
  1392   1461       set result
  1393   1462   } {0 1 <root><thisE/></root>}
  1394   1463   
  1395   1464   test domNode-13.16 {Invalid attribute name} {
  1396   1465       set doc [dom createDocument root]
  1397   1466       set root [$doc documentElement]
  1398   1467       set result [catch {
  1399   1468           namespace eval nodeCmds {
  1400         -            $root appendFromScript {
         1469  +            $::root appendFromScript {
  1401   1470                   e1 att1 att1Value "invalid attname" value {}
  1402   1471               }
  1403   1472           }
  1404   1473       } errMsg]
  1405   1474       lappend result $errMsg
  1406   1475       $doc delete
  1407   1476       set result
................................................................................
  1408   1477   } {1 {Invalid attribute name 'invalid attname'}}
  1409   1478   
  1410   1479   test domNode-13.17 {Invalid attribute value} {
  1411   1480       set doc [dom createDocument root]
  1412   1481       set root [$doc documentElement]
  1413   1482       set result [catch {
  1414   1483           namespace eval nodeCmds {
  1415         -            $root appendFromScript {
         1484  +            $::root appendFromScript {
  1416   1485                   e1 att1 att1Value att2 "invalid \u0003 value" {}
  1417   1486               }
  1418   1487           }
  1419   1488       } errMsg]
  1420   1489       lappend result $errMsg
  1421   1490       $doc delete
  1422   1491       set result
................................................................................
  1429   1498   dom setNameCheck 1
  1430   1499   
  1431   1500   test domNode-13.18 {Invalid attribute name - check disabled} {
  1432   1501       set doc [dom createDocument root]
  1433   1502       set root [$doc documentElement]
  1434   1503       set result [catch {
  1435   1504           namespace eval nodeCmds {
  1436         -            $root appendFromScript {
         1505  +            $::root appendFromScript {
  1437   1506                   e1 att1 att1Value "invalid attname" value {}
  1438   1507               }
  1439   1508           }
  1440   1509       }]
  1441   1510       $doc delete
  1442   1511       set result
  1443   1512   } {0}
................................................................................
  1449   1518   dom setTextCheck 1
  1450   1519   
  1451   1520   test domNode-13.19 {Invalid attribute value - check disabled} {
  1452   1521       set doc [dom createDocument root]
  1453   1522       set root [$doc documentElement]
  1454   1523       set result [catch {
  1455   1524           namespace eval nodeCmds {
  1456         -            $root appendFromScript {
         1525  +            $::root appendFromScript {
  1457   1526                   e1 att1 att1Value att2 "invalid \u0003 value" {}
  1458   1527               }
  1459   1528           }
  1460   1529       }]
  1461   1530       $doc delete
  1462   1531       set result
  1463   1532   } 0
................................................................................
  1471   1540   dom setNameCheck 1
  1472   1541   
  1473   1542   test domNode-13.20 {Invalid att name, invalid att value, checks disabled} {
  1474   1543       set doc [dom createDocument root]
  1475   1544       set root [$doc documentElement]
  1476   1545       set result [catch {
  1477   1546           namespace eval nodeCmds {
  1478         -            $root appendFromScript {
         1547  +            $::root appendFromScript {
  1479   1548                   e1 att1 att1Value "invalid attName" "invalid \u0003 value" {}
  1480   1549               }
  1481   1550           }
  1482   1551       }]
  1483   1552       $doc delete
  1484   1553       set result
  1485   1554   } 0
................................................................................
  1489   1558   }
  1490   1559   
  1491   1560   test domNode-13.21 {Invalid comment value} {
  1492   1561       set doc [dom createDocument root]
  1493   1562       set root [$doc documentElement]
  1494   1563       set result [catch {
  1495   1564           namespace eval nodeCmds {
  1496         -            $root appendFromScript {
         1565  +            $::root appendFromScript {
  1497   1566                   c "invalid -- comment"
  1498   1567               }
  1499   1568           }
  1500   1569       } errMsg]
  1501   1570       lappend result $errMsg
  1502   1571       $doc delete
  1503   1572       set result
................................................................................
  1504   1573   } {1 {Invalid comment value 'invalid -- comment'}}
  1505   1574   
  1506   1575   test domNode-13.22 {Invalid CDATA section value} {
  1507   1576       set doc [dom createDocument root]
  1508   1577       set root [$doc documentElement]
  1509   1578       set result [catch {
  1510   1579           namespace eval nodeCmds {
  1511         -            $root appendFromScript {
         1580  +            $::root appendFromScript {
  1512   1581                   cdata "invalid comment ]]>"
  1513   1582               }
  1514   1583           }
  1515   1584       } errMsg]
  1516   1585       lappend result $errMsg
  1517   1586       $doc delete
  1518   1587       set result
................................................................................
  1519   1588   } {1 {Invalid CDATA section value 'invalid comment ]]>'}}
  1520   1589   
  1521   1590   test domNode-13.23 {Invalid text node} {
  1522   1591       set doc [dom createDocument root]
  1523   1592       set root [$doc documentElement]
  1524   1593       set result [catch {
  1525   1594           namespace eval nodeCmds {
  1526         -            $root appendFromScript {
         1595  +            $::root appendFromScript {
  1527   1596                   t "invalid text \u0004"
  1528   1597               }
  1529   1598           }
  1530   1599       } errMsg]
  1531   1600       lappend result $errMsg
  1532   1601       $doc delete
  1533   1602       set result
................................................................................
  1534   1603   } [list 1 "Invalid text value 'invalid text \u0004'"]
  1535   1604   
  1536   1605   test domNode-13.24 {Invalid processing instruction} {
  1537   1606       set doc [dom createDocument root]
  1538   1607       set root [$doc documentElement]
  1539   1608       set result [catch {
  1540   1609           namespace eval nodeCmds {
  1541         -            $root appendFromScript {
         1610  +            $::root appendFromScript {
  1542   1611                   pi  Xml "data"
  1543   1612               }
  1544   1613           }
  1545   1614       } errMsg]
  1546   1615       lappend result $errMsg
  1547   1616       $doc delete
  1548   1617       set result
................................................................................
  1549   1618   } [list 1 "Invalid processing instruction name 'Xml'"]
  1550   1619   
  1551   1620   test domNode-13.25 {Invalid processing instruction} {
  1552   1621       set doc [dom createDocument root]
  1553   1622       set root [$doc documentElement]
  1554   1623       set result [catch {
  1555   1624           namespace eval nodeCmds {
  1556         -            $root appendFromScript {
         1625  +            $::root appendFromScript {
  1557   1626                   pi  Xmll "data ?>"
  1558   1627               }
  1559   1628           }
  1560   1629       } errMsg]
  1561   1630       lappend result $errMsg
  1562   1631       $doc delete
  1563   1632       set result
  1564   1633   } [list 1 "Invalid processing instruction value 'data ?>'"]
  1565   1634   
  1566   1635   test domNode-13.26 {appendFromScript with default namespace in scope} {
  1567   1636       set doc [dom parse {<doc xmlns="http://www.stock.org/stock"/>}]
  1568   1637       set root [$doc documentElement]
  1569   1638       namespace eval nodeCmds {
  1570         -        $root appendFromScript {
         1639  +        $::root appendFromScript {
  1571   1640               e1
  1572   1641           }
  1573   1642       }
  1574   1643       set result [$doc asXML -indent none]
  1575   1644       $doc delete
  1576   1645       set result
  1577   1646   } {<doc xmlns="http://www.stock.org/stock"><e1 xmlns=""/></doc>}
................................................................................
  1752   1821       foreach node [$root selectNodes node()] {
  1753   1822           $node delete
  1754   1823       }
  1755   1824       set result [llength [$root childNodes]]
  1756   1825       $doc delete
  1757   1826       set result
  1758   1827   } {0}
         1828  +
         1829  +test domNode-15.5 {delete - threaded} -constraints {
         1830  +    threaded
         1831  +} -setup {
         1832  +    set xml {
         1833  +        <root>
         1834  +        <child>
         1835  +        <attr1>one</attr1>
         1836  +        <attr2>two</attr2>
         1837  +        <attr3>three</attr3>
         1838  +        </child>
         1839  +        </root>
         1840  +    }
         1841  +    set doc [dom parse $xml]
         1842  +    dom attachDocument $doc doc_
         1843  +    $doc documentElement root
         1844  +} -body {
         1845  +    foreach node [$root selectNodes {//attr1 | //attr2}] {
         1846  +        [$node firstChild] delete
         1847  +    }
         1848  +    set result ""
         1849  +} -cleanup {
         1850  +    dom detachDocument $doc
         1851  +    dom detachDocument $doc_
         1852  +} -result ""
         1853  +
         1854  +test domNode-15.6 {delete - threaded} -constraints {
         1855  +    threaded
         1856  +} -setup {
         1857  +    set xml {
         1858  +        <root><a/><a/><a/><a/><a/><a/><a/>
         1859  +        <a/><a/><a/><a/><a/><a/><a/><a/></root>
         1860  +    }
         1861  +    set doc [dom parse $xml]
         1862  +    dom attachDocument $doc doc_
         1863  +    $doc documentElement root
         1864  +} -body {
         1865  +    foreach node [$root selectNodes a] {
         1866  +        $node delete
         1867  +    }
         1868  +    set result ""
         1869  +} -cleanup {
         1870  +    dom detachDocument $doc
         1871  +    dom detachDocument $doc_
         1872  +} -result ""
  1759   1873   
  1760   1874   set doc [dom parse {<root attr1="bingbaz" attr2="ab &amp; zu" attr3=""/>}]
  1761   1875   set root [$doc documentElement]
  1762   1876   
  1763   1877   test domNode-16.1 {getAttribute} {
  1764   1878       $root getAttribute attr1
  1765   1879   } {bingbaz}
................................................................................
  1803   1917   test domNode-16.11 {getAttribute shortcut with default} {
  1804   1918       $root @notPresent "expect this given default value"
  1805   1919   } {expect this given default value}
  1806   1920   
  1807   1921   test domNode-16.12 {getAttribute shortcut - attr dosen't exists and no default} {
  1808   1922       catch {$root @notPresent}
  1809   1923   } {1}
  1810         -
  1811   1924   $doc delete
  1812   1925   
  1813         -# Yea, it's the same string as above. I just love to have the
  1814         -# data near by the tests, to reduce confusion and silly errors
         1926  +set doc [dom parse {<root attr1="bingbaz"
         1927  +    foo:attr1="ns attr"
         1928  +    xmlns:foo="http://tdom.org/ns1"
         1929  +    worble2="second attr with 2 in it's name"
         1930  +    xmlns="uri2"/>}]
         1931  +set root [$doc documentElement]
         1932  +test domNode-16.13 {getAttribute} {
         1933  +    $root getAttribute xmlns
         1934  +} {uri2}
         1935  +test domNode-16.14 {getAttribute} {
         1936  +    $root getAttribute xmlns:foo
         1937  +} {http://tdom.org/ns1}
         1938  +$doc delete
         1939  +
  1815   1940   set xml {
  1816   1941   <root>
  1817   1942     text node <b>text</b><!-- comment1 -->
  1818   1943     <elem1>text<?pi data?><empty/>
  1819   1944        <child>text</child>
  1820   1945    </elem1><!-- comment2 --><?pi data?>text
  1821   1946   </root>}
................................................................................
  1871   1996   test domNode-18.6 {attributes} {
  1872   1997       $root attributes *brab*
  1873   1998   } {}
  1874   1999   
  1875   2000   test domNode-18.7 {attributes} {
  1876   2001       [$root firstChild] attributes
  1877   2002   } {}
         2003  +
         2004  +test domNode-18.1.1 {attributeNames} {
         2005  +    $root attributeNames
         2006  +} {xmlns:foo attr1 attr2 attr3 foo:attr1 worble2}
         2007  +
         2008  +test domNode-18.2.1 {attributeNames} {
         2009  +    $root attributeNames *
         2010  +} {xmlns:foo attr1 attr2 attr3 foo:attr1 worble2}
         2011  +
         2012  +test domNode-18.3.1 {attributeNames} {
         2013  +    $root attributeNames attr*
         2014  +} {attr1 attr2 attr3}
         2015  +
         2016  +test domNode-18.4.1 {attributeNames} {
         2017  +    $root attributeNames *2*
         2018  +} {attr2 worble2}
         2019  +
         2020  +test domNode-18.5.1 {attributeNames} {
         2021  +    $root attributeNames worble2
         2022  +} {worble2}
         2023  +
         2024  +test domNode-18.6.1 {attributeNames} {
         2025  +    $root attributeNames *brab*
         2026  +} {}
         2027  +
         2028  +test domNode-18.7.1 {attributeNames} {
         2029  +    [$root firstChild] attributeNames
         2030  +} {}
  1878   2031   
  1879   2032   # Hmmm. This two following tests are mostly there to document the
  1880   2033   # behavior of the method, as it is.  It may debatable if they should
  1881   2034   # behave this way. The optional attribute name pattern is a tDOM
  1882   2035   # DOM extension there is nothing in the rec, which could help to argue.
  1883   2036   # Therefore, it's the way, it is.
  1884   2037   
  1885         -test domNode-18.7 {attributes} {
         2038  +test domNode-18.8 {attributes} {
  1886   2039       $root attributes *tdom*
  1887   2040   } {}
  1888   2041   
  1889         -test domNode-18.8 {attributes} {
         2042  +test domNode-18.9 {attributes} {
  1890   2043       $root attributes foo*
  1891   2044   } {{attr1 foo http://tdom.org/ns}}
  1892   2045   
  1893         -# still the doc from befor 18.1
         2046  +test domNode-18.9.1 {attributeNames} {
         2047  +    $root attributeNames foo:*
         2048  +} {foo:attr1}
         2049  +
         2050  +$doc delete
         2051  +set doc [dom parse {<root attr1="bingbaz"
         2052  +    foo:attr1="ns attr"
         2053  +    xmlns:foo="http://tdom.org/ns1"
         2054  +    worble2="second attr with 2 in it's name"
         2055  +    xmlns="uri2"/>}]
         2056  +set root [$doc documentElement]
         2057  +test domNode-18.10 {attributes} {
         2058  +    $root attributes
         2059  +} {{foo foo {}} {xmlns {} {}} attr1 {attr1 foo http://tdom.org/ns1} worble2}
         2060  +$doc delete
         2061  +
         2062  +set doc [dom parse {<root attr1="bingbaz"
         2063  +                          attr2="ab &amp; zu"
         2064  +                          attr3=""
         2065  +                          foo:attr1="ns attr"
         2066  +                          xmlns:foo="http://tdom.org/ns"
         2067  +                          worble2="second attr with 2 in it's name">
         2068  +text child</root>}]
         2069  +set root [$doc documentElement]
  1894   2070   test domNode-19.1 {removeAttribute} {
  1895   2071       $root removeAttribute attr1
  1896   2072       $root attributes attr1
  1897   2073   } {}
  1898   2074   
         2075  +$doc delete
         2076  +set doc [dom parse {<root attr2="ab &amp; zu"
         2077  +                          attr3=""
         2078  +                          foo:attr1="ns attr"
         2079  +                          xmlns:foo="http://tdom.org/ns"
         2080  +                          worble2="second attr with 2 in it's name"
         2081  +                          xmlns:bar="http://tdom.org/bar"
         2082  +                          thisatt="thisatt value no ns"
         2083  +                          bar:thisatt="thisatt value">
         2084  +text child</root>}]
         2085  +set root [$doc documentElement]
  1899   2086   test domNode-19.2 {removeAttribute} {
  1900   2087       catch {$root removeAttribute attr1} errMsg
  1901   2088       set errMsg
  1902   2089   } {can't remove attribute 'attr1'}
  1903   2090   
  1904   2091   test domNode-19.3 {removeAttribute} {
  1905   2092       catch {$root removeAttribute} 
................................................................................
  1913   2100       $root removeAttributeNS http://tdom.org/ns attr1
  1914   2101       $root hasAttributeNS http://tdom.org/ns attr1
  1915   2102   } {0}
  1916   2103   
  1917   2104   test domNode-19.6 {removeAttributeNS} {
  1918   2105       catch {$root removeAttributeNS http://tdom.org attr1}
  1919   2106   } {1}
         2107  +
         2108  +test domNode-19.7 {removeAttributeNS} {
         2109  +     catch {$root removeAttributeNS http://tdom.org/bar thisatt}
         2110  +} {0}
  1920   2111   
  1921   2112   $doc delete
  1922   2113   
  1923   2114   set doc [dom parse <root><firstL><secondL1/><secondL2/></firstL></root>]
  1924   2115   set root [$doc documentElement]
  1925   2116   
  1926   2117   test domNode-20.1 {parentNode} {
................................................................................
  2223   2414       set firstChild [$root firstChild]
  2224   2415       catch {$root start $firstChild foo}
  2225   2416   } {1}
  2226   2417   
  2227   2418   test domNode-30.3 {precedes} {
  2228   2419       set result [catch {$root precedes notaNode} errMsg]
  2229   2420       lappend result $errMsg
  2230         -} {1 {parameter not a domNode!}}
         2421  +} {1 {Parameter "notaNode" is not a domNode.}}
  2231   2422   
  2232   2423   test domNode-30.4 {precedes} {
  2233   2424       set firstChild [$root firstChild]
  2234   2425       $root precedes $firstChild
  2235   2426   } {1}
  2236   2427   
  2237   2428   test domNode-30.5 {precedes} {
................................................................................
  2741   2932       set result
  2742   2933   } {1 <root><child/></root>}
  2743   2934   
  2744   2935   test domNode-33.4 {insertBeforeFromScript - insert more then one node} {
  2745   2936       set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
  2746   2937       $doc documentElement root
  2747   2938       namespace eval nodeCmds {
  2748         -        $root insertBeforeFromScript {
         2939  +        $::root insertBeforeFromScript {
  2749   2940               e1
  2750   2941               e2 {
  2751   2942                   t new
  2752   2943               }
  2753   2944               e1
  2754         -        } [lindex [$root childNodes] 1]
         2945  +        } [lindex [$::root childNodes] 1]
  2755   2946       }
  2756   2947       set result [$doc asXML -indent none]
  2757   2948       $doc delete
  2758   2949       set result
  2759   2950   } {<doc><foo/><e1/><e2>new</e2><e1/><bar/><grill/></doc>}
  2760   2951   
  2761   2952   test domNode-33.5 {insertBeforeFromScript - insert more then one node} {
  2762   2953       set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
  2763   2954       $doc documentElement root
  2764   2955       namespace eval nodeCmds {
  2765         -        $root insertBeforeFromScript {
         2956  +        $::root insertBeforeFromScript {
  2766   2957               e1
  2767   2958               e2 {
  2768   2959                   t new
  2769   2960               }
  2770   2961               e1
  2771         -        } [lindex [$root childNodes] 1]
         2962  +        } [lindex [$::root childNodes] 1]
  2772   2963       }
  2773   2964       set result ""
  2774   2965       foreach node [$root childNodes] {
  2775   2966           append result "[$node nodeName] "
  2776   2967       }
  2777   2968       $doc delete
  2778   2969       set result
  2779   2970   } {foo e1 e2 e1 bar grill }
  2780   2971   
  2781   2972   test domNode-33.6 {insertBeforeFromScript - insert more then one node} {
  2782   2973       set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
  2783   2974       $doc documentElement root
  2784   2975       namespace eval nodeCmds {
  2785         -        $root insertBeforeFromScript {
         2976  +        $::root insertBeforeFromScript {
  2786   2977               e1
  2787   2978               e2 {
  2788   2979                   t new
  2789   2980               }
  2790   2981               e1
  2791         -        } [lindex [$root childNodes] 1]
         2982  +        } [lindex [$::root childNodes] 1]
  2792   2983       }
  2793   2984       set result ""
  2794   2985       set node [$root lastChild]
  2795   2986       while {$node != ""} {
  2796   2987           append result "[$node nodeName] "
  2797   2988           set node [$node previousSibling]
  2798   2989       }
................................................................................
  2800   2991       set result
  2801   2992   } {grill bar e1 e2 e1 foo }
  2802   2993   
  2803   2994   test domNode-33.7 {insertBeforeFromScript - error in script} {
  2804   2995       set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
  2805   2996       $doc documentElement root
  2806   2997       catch {namespace eval nodeCmds {
  2807         -        $root insertBeforeFromScript {
         2998  +        $::root insertBeforeFromScript {
  2808   2999               e1
  2809   3000               e2 {
  2810   3001                   t new
  2811   3002               }
  2812   3003               e1
  2813   3004               this is wrong
  2814         -        } [lindex [$root childNodes] 2]
         3005  +        } [lindex [$::root childNodes] 2]
  2815   3006       }}
  2816   3007       set result [$doc asXML -indent none]
  2817   3008       $doc delete
  2818   3009       set result
  2819   3010   } {<doc><foo/><bar/><grill/></doc>}
  2820   3011   
  2821   3012   test domNode-33.8 {insertBeforeFromScript - wrong reference node} {
................................................................................
  2829   3020       set result
  2830   3021   } {1 NOT_FOUND_ERR}
  2831   3022   
  2832   3023   test domNode-34.1 {getBaseURI} {need_uri} {
  2833   3024       makeFile <y/> domNode-34.1-e1.xml [file join [file dir [info script]] data]
  2834   3025       makeFile <y/> domNode-34.1-e2.xml [file join [file dir [info script]] data]
  2835   3026   
  2836         -    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
         3027  +    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
  2837   3028       set doc [dom parse \
  2838   3029                    -baseurl $baseURI \
  2839         -                 -externalentitycommand ::tDOM::extRefHandler {
         3030  +                 -externalentitycommand ::tdom::extRefHandler {
  2840   3031                        <!DOCTYPE x [
  2841   3032                                     <!ENTITY a SYSTEM "data/domNode-34.1-e1.xml">
  2842   3033                                     <!ENTITY b SYSTEM "data/domNode-34.1-e2.xml">
  2843   3034                                    ]>
  2844   3035                        <x>
  2845   3036                        &a;
  2846   3037                        &b;
................................................................................
  2861   3052       set result
  2862   3053   } {1}
  2863   3054   
  2864   3055   test domNode-34.2 {getBaseURI} {need_uri} {
  2865   3056       makeFile <y/> domNode-34.1-e1.xml [file join [file dir [info script]] data]
  2866   3057       makeFile <y/> domNode-34.1-e2.xml [file join [file dir [info script]] data]
  2867   3058   
  2868         -    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
         3059  +    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
  2869   3060       set doc [dom parse \
  2870   3061                    -baseurl $baseURI \
  2871         -                 -externalentitycommand ::tDOM::extRefHandler {
         3062  +                 -externalentitycommand ::tdom::extRefHandler {
  2872   3063                        <!DOCTYPE x [
  2873   3064                                     <!ENTITY a SYSTEM "data/domNode-34.1-e1.xml">
  2874   3065                                     <!ENTITY b SYSTEM "data/domNode-34.1-e2.xml">
  2875   3066                                    ]>
  2876   3067                        <x>
  2877   3068                        &a;
  2878   3069                        &b;
  2879   3070                        <y/>
  2880   3071                        </x>}]
  2881   3072       $doc delete
  2882   3073       set doc [dom parse \
  2883   3074                    -baseurl $baseURI \
  2884         -                 -externalentitycommand ::tDOM::extRefHandler {
         3075  +                 -externalentitycommand ::tdom::extRefHandler {
  2885   3076                        <!DOCTYPE x [
  2886   3077                                     <!ENTITY a SYSTEM "data/domNode-34.1-e1.xml">
  2887   3078                                     <!ENTITY b SYSTEM "data/domNode-34.1-e2.xml">
  2888   3079                                    ]>
  2889   3080                        <x>
  2890   3081                        &a;
  2891   3082                        &b;
................................................................................
  3182   3373       set result {}
  3183   3374       foreach toplevelcomment [$doc selectNodes /comment()] {
  3184   3375           lappend result [$toplevelcomment toXPath]
  3185   3376       }
  3186   3377       $doc delete
  3187   3378       set result
  3188   3379   } [list {/comment()[1]} {/comment()[2]} {/comment()[3]}]
         3380  +
         3381  +test domNode-38.3 {toXPath - syntax} -setup {
         3382  +    set doc [dom parse <doc/>]
         3383  +    set root [$doc documentElement]
         3384  +} -body {
         3385  +    catch {$root toXPath foo bar} errMsg
         3386  +    set errMsg
         3387  +} -cleanup {
         3388  +    $doc delete
         3389  +} -match regexp -result {wrong # args: should be "domNode(0x)?[[:xdigit:]]+ toXPath \?-legacy\?"}
         3390  +
         3391  +test domNode-38.4 {toXPath - default xml namespace} -setup {
         3392  +    set doc [dom parse {<root><foo xmlns="foo"/><foo/></root>}]
         3393  +    $doc selectNodesNamespaces {foo foo}
         3394  +    set root [$doc documentElement]
         3395  +    set foo1 [$root selectNodes foo:foo]
         3396  +    set xfo1 [$foo1 toXPath]
         3397  +} -body {
         3398  +    expr {$foo1 == [[$foo1 ownerDocument] selectNodes [$foo1 toXPath]]}
         3399  +} -cleanup {
         3400  +    $doc delete
         3401  +} -result 1
         3402  +
         3403  +test domNode-38.5 {toXPath - default xml namespace} -setup {
         3404  +    set doc [dom parse {
         3405  +<root xmlns="foo">
         3406  +    <!-- comment -->
         3407  +    <foo/>
         3408  +    some text    
         3409  +    <foo/>
         3410  +    <?mypi data?>
         3411  +    <foo/>
         3412  +</root>}]
         3413  +    set root [$doc documentElement]
         3414  +    $doc selectNodesNamespaces {foo foo}
         3415  +    set foo2 [$root selectNodes {foo:foo[2]}]
         3416  +} -body {
         3417  +    expr {$foo2 == [[$foo2 ownerDocument] selectNodes [$foo2 toXPath]]}
         3418  +} -cleanup {
         3419  +    $doc delete
         3420  +} -result 1
         3421  +
         3422  +test domNode-38.6 {toXPath - xml namespace} -setup {
         3423  +    set doc [dom parse {
         3424  +<root xmlns:foo="foo">
         3425  +    <!-- comment -->
         3426  +    <foo:foo/>
         3427  +    some text    
         3428  +    <foo:foo/>
         3429  +    <?mypi data?>
         3430  +    <foo:foo/>
         3431  +</root>}]
         3432  +    set root [$doc documentElement]
         3433  +    $doc selectNodesNamespaces {foo foo}
         3434  +    set foo2 [$root selectNodes {foo:foo[2]}]
         3435  +} -body {
         3436  +    expr {$foo2 == [[$foo2 ownerDocument] selectNodes [$foo2 toXPath]]}
         3437  +} -cleanup {
         3438  +    $doc delete
         3439  +} -result 1
         3440  +
         3441  +test domNode-38.7 {toXPath - pathological xml namespace} -setup {
         3442  +    set doc [dom parse {
         3443  +<root>
         3444  +    <!-- comment -->
         3445  +    <foo:foo xmlns:foo="foo"/>
         3446  +    some text    
         3447  +    <foo:foo xmlns:foo="bar"/>
         3448  +    <?mypi data?>
         3449  +    <foo:foo xmlns:foo="bar"/>
         3450  +    <foo:foo xmlns:foo="foo"/>
         3451  +</root>}]
         3452  +    set root [$doc documentElement]
         3453  +    $doc selectNodesNamespaces {foo foo}
         3454  +    set foo2 [$root selectNodes {foo:foo[2]}]
         3455  +} -body {
         3456  +    expr {$foo2 == [[$foo2 ownerDocument] selectNodes [$foo2 toXPath]]}
         3457  +} -cleanup {
         3458  +    $doc delete
         3459  +} -result 1
         3460  +
         3461  +test domNode-38.8 {toXPath - pathological xml namespace} -setup {
         3462  +    set doc [dom parse {
         3463  +<root>
         3464  +    <!-- comment -->
         3465  +    <foo:foo xmlns:foo="foo">
         3466  +        <bar/>
         3467  +        text
         3468  +        <bar xmlns=""/>
         3469  +    </foo:foo>
         3470  +    some text    
         3471  +    <foo:foo xmlns:foo="bar"/>
         3472  +    <?mypi data?>
         3473  +    <foo:foo xmlns:foo="bar"/>
         3474  +    <foo:foo xmlns:foo="foo">
         3475  +        <bar/>
         3476  +        <foo:foo xmlns:foo="bar"/>
         3477  +        text
         3478  +        <bar xmlns=""/>
         3479  +    </foo:foo>
         3480  +    <foo:foo xmlns:foo="foo"/>
         3481  +</root>}]
         3482  +} -body {
         3483  +    set result ""
         3484  +    foreach node [$doc selectNodes //node()] {
         3485  +        if {$node != [[$node ownerDocument] selectNodes [$node toXPath]]} {
         3486  +            set result [$node toXPath]
         3487  +            break
         3488  +        }
         3489  +    }
         3490  +    set result
         3491  +} -cleanup {
         3492  +    $doc delete
         3493  +} -result ""
         3494  +
         3495  +test domNode-38.9 {toXPath - really long element name} -constraints {
         3496  +    knownBug
         3497  +} -setup {
         3498  +    set doc [dom parse "<doc><[string repeat abc 100]/></doc>"]
         3499  +    set root [$doc documentElement]
         3500  +    set firstChild [$root firstChild]
         3501  +} -body {
         3502  +    $firstChild toXPath
         3503  +} -cleanup {
         3504  +    $doc delete
         3505  +} -result "/doc/[string repeat abc 100]"
  3189   3506   
  3190   3507   test domNode-39.1 {text} {
  3191   3508        set doc [dom parse {<root>text <b>bold</b> more text</root>}]
  3192   3509        $doc documentElement root
  3193   3510        set result [$root text]
  3194   3511        $doc delete
  3195   3512        set result

Added tests/domjson.test.

            1  +# Features covered: JSON parser
            2  +#
            3  +# This file contains a collection of tests for the JSON parser.
            4  +# Tested functionalities:
            5  +#    json-1.*: JSON syntax tests
            6  +#    json-2.*: Valid JSON, that could not parsed into DOM
            7  +#    json-3.*: JSON unescaping
            8  +#    json-4.*: Unicode
            9  +#    json-5.*: Max nesting
           10  +#    json-6.*: asJSON
           11  +#    json-7.*: jsonType
           12  +#    json-8.*: appendFromScript
           13  +#    json-9.*: cloneNode
           14  +# Copyright (c) 2017 Rolf Ade.
           15  +
           16  +source [file join [file dir [info script]] loadtdom.tcl]
           17  +
           18  +
           19  +namespace eval nodeCmds {
           20  +    dom createNodeCmd elementNode e1
           21  +    dom createNodeCmd -jsonType ARRAY elementNode jae1
           22  +    dom createNodeCmd elementNode e2
           23  +    dom createNodeCmd commentNode c
           24  +    dom createNodeCmd textNode    t
           25  +    dom createNodeCmd -jsonType TRUE textNode true
           26  +    dom createNodeCmd -jsonType FALSE textNode false
           27  +    dom createNodeCmd -jsonType NULL textNode null
           28  +    dom createNodeCmd -jsonType NUMBER textNode number
           29  +    dom createNodeCmd cdataNode   cdata
           30  +    dom createNodeCmd piNode      pi
           31  +}
           32  +
           33  +test json-1.1 {Parse JSON} {
           34  +    set doc [dom parse -json {{"a":"avalue","b":"bvalue","c":0.123}}]
           35  +    set result [$doc asXML -indent none]
           36  +    $doc delete
           37  +    set result
           38  +} "<a>avalue</a><b>bvalue</b><c>0.123</c>"
           39  +
           40  +test json-1.2 {Parse JSON} {
           41  +    set doc [dom parse -json { {"a" : [ "avalue" ] } }]
           42  +    set result [$doc asXML -indent none]
           43  +    $doc delete
           44  +    set result
           45  +} {<a>avalue</a>}
           46  +
           47  +test json-1.3 {Parse JSON} {
           48  +    set doc [dom parse -json {{"a":"a value","b":"1value"}}]
           49  +    set result [$doc asXML -indent none]
           50  +    $doc delete
           51  +    set result
           52  +} "<a>a value</a><b>1value</b>"
           53  +
           54  +test json-1.4 {Parse JSON - nested object} {
           55  +    set doc [dom parse -json {{"a":{"aa":"aavalue","bb":"bbvalue"},"b":"bvalue","c":0.123}}]
           56  +    set result [$doc asXML -indent none]
           57  +    $doc delete
           58  +    set result
           59  +} "<a><aa>aavalue</aa><bb>bbvalue</bb></a><b>bvalue</b><c>0.123</c>"
           60  +
           61  +test json-1.5 {Parse JSON - array} {
           62  +    set doc [dom parse -json {{"a": [1,2,3,4,"abc"]}}]
           63  +    set result [$doc asXML -indent none]
           64  +    $doc delete
           65  +    set result
           66  +} "<a>1234abc</a>"
           67  +
           68  +test json-1.6 {Parse JSON - true, false, null} {
           69  +    set doc [dom parse -json {{"a":true,"b":false,"c":null,"d":"true","e":""}}]
           70  +    set result [$doc asXML -indent none]
           71  +    $doc delete
           72  +    set result
           73  +} {<a>true</a><b>false</b><c>null</c><d>true</d><e></e>}
           74  +
           75  +test json-1.7 {Parse JSON - array in nested object} {
           76  +    set doc [dom parse -json {{"a":{"aa":[1,2,3,4,"abc"]},"b":"bvalue"}}]
           77  +    set result [$doc asXML -indent none]
           78  +    $doc delete
           79  +    set result
           80  +} "<a><aa>1234abc</aa></a><b>bvalue</b>"
           81  +
           82  +test json-1.8 {Parse JSON - true, false, null} {
           83  +    set doc [dom parse -json -jsonroot "JSONObject" {{"a":true,"b":false,"c":null,"d":"true","e":""}}]
           84  +    set result [$doc asXML -indent none]
           85  +    $doc delete
           86  +    set result
           87  +} {<JSONObject><a>true</a><b>false</b><c>null</c><d>true</d><e></e></JSONObject>}
           88  +
           89  +test json-1.9 {JSON syntax error} {
           90  +    set result [catch {dom parse -json {{"a" "a value"}}} errMsg]
           91  +    list $result $errMsg
           92  +} {1 {error "JSON syntax error" at position 5
           93  +"{"a" " <--Error-- a value"}"}}
           94  +
           95  +test json-1.10 {JSON syntax error} {
           96  +    set result [catch {dom parse -json {{"a":00.23}}} errMsg]
           97  +    list $result $errMsg
           98  +} {1 {error "JSON syntax error" at position 6
           99  +"{"a":00 <--Error-- .23}"}}
          100  +
          101  +test json-1.11 {JSON syntax error} {
          102  +    set result [catch {dom parse -json {{"a":-00.23}}} errMsg]
          103  +    list $result $errMsg
          104  +} {1 {error "JSON syntax error" at position 7
          105  +"{"a":-00 <--Error-- .23}"}}
          106  +
          107  +test json-1.12 {JSON syntax error} {
          108  +    set result [catch {dom parse -json {{"a":.23}}} errMsg]
          109  +    list $result $errMsg
          110  +} {1 {error "JSON syntax error" at position 5
          111  +"{"a":. <--Error-- 23}"}}
          112  +
          113  +test json-1.13 {JSON syntax error} {
          114  +    set result [catch {dom parse -json {{"a":-.23}}} errMsg]
          115  +    list $result $errMsg
          116  +} {1 {error "JSON syntax error" at position 6
          117  +"{"a":-. <--Error-- 23}"}}
          118  +
          119  +test json-1.14 {JSON syntax error} {
          120  +    set result [catch {dom parse -json {{"a":-}}} errMsg]
          121  +    list $result $errMsg
          122  +} {1 {error "JSON syntax error" at position 5
          123  +"{"a":- <--Error-- }"}}
          124  +
          125  +test json-1.15 {Parse JSON - nested object} {
          126  +    set doc [dom parse -json {["a",["aa","bb"],"b"]}]
          127  +    set result [$doc asXML -indent none]
          128  +    $doc delete
          129  +    set result
          130  +} "a<arraycontainer>aabb</arraycontainer>b"
          131  +
          132  +set notJsons {
          133  +    {{null}}
          134  +    {{1.23}}
          135  +    {{"string"}}
          136  +    {{"e":}}
          137  +}
          138  +test json-1.16 {Invalid input} {
          139  +    set result ""
          140  +    set ind 0
          141  +    foreach notJson $notJsons {
          142  +        if {![catch {dom parse -json $notJson docNode} errMsg]} {
          143  +            lappend result $errMsg
          144  +        }
          145  +    }
          146  +    set result
          147  +} ""
          148  +
          149  +test json-1.17 {Literal binary 0 (NUL, '\0') is not allowed in input} {
          150  +    catch {dom parse -json "\"a\u0000\""}
          151  +} 1
          152  +
          153  +test json-1.18 {Escaped binary 0 (NUL, '\0') is OK} {
          154  +    dom parse -json "\"a\\u0000\"" doc
          155  +    set result [$doc asJSON]
          156  +    $doc delete
          157  +    set result
          158  +} "\"a\\u0000\""
          159  +
          160  +test json-1.19 {Invalid input - uncompled \u escape} {
          161  +    catch {dom parse -json {"ab\u00"}}
          162  +} 1
          163  +
          164  +test json-1.20 {Escaped binary 0} {needExpand} {
          165  +    dom parse -json "\"a\\u0000\"" doc
          166  +    set textvalue [$doc selectNodes string(node())]
          167  +    set result [string length $textvalue]
          168  +    binary scan $textvalue c2 result2
          169  +    lappend result {*}$result2
          170  +    $doc delete
          171  +    set result
          172  +} {2 97 0}
          173  +
          174  +test json-2.1 {invalid xml name} {
          175  +    set doc [dom parse -json {{"a":"a value","1b":"1value", "a\nb":"a\nb", "":"empty string"}}]
          176  +    set result [$doc asXML -indent none]
          177  +    $doc delete
          178  +    set result
          179  +} {<a>a value</a><1b>1value</1b><a
          180  +b>a
          181  +b</a
          182  +b><>empty string</>}
          183  +
          184  +test json-3.1 {Unescaping} {
          185  +    set doc [dom parse -json {{"a":"a\nvalue","b":"value\tvalue"}}]
          186  +    set result [$doc asXML -indent none]
          187  +    $doc delete
          188  +    set result
          189  +} "<a>a
          190  +value</a><b>value\tvalue</b>"
          191  +
          192  +test json-3.2 {Unescaping} {
          193  +    set doc [dom parse -json {{"a":"a\nvalue", "b":"12\u0077\u2221ec"}}]
          194  +    set result [$doc asXML -indent none -escapeNonASCII]
          195  +    $doc delete
          196  +    set result
          197  +} "<a>a
          198  +value</a><b>12w&#8737;ec</b>"
          199  +
          200  +test json-3.3 {Unescaping} {
          201  +    set doc [dom parse -json {{"a":"\u0077\u2221"}}]
          202  +    set result [$doc asXML -indent none -escapeNonASCII]
          203  +    $doc delete
          204  +    set result
          205  +} "<a>w&#8737;</a>"
          206  +
          207  +test json-3.4 {unescaping} {
          208  +    set doc [dom parse -jsonroot json -json {["\\a"]}]
          209  +    set result [$doc asXML -indent none]
          210  +    $doc delete
          211  +    set result
          212  +} {<json>\a</json>}
          213  +
          214  +test json-3.4.1 {unescaping} {
          215  +    set doc [dom parse -jsonroot json -json {["\\a","\u0071"]}]
          216  +    set result [$doc asXML -indent none]
          217  +    $doc delete
          218  +    set result
          219  +} {<json>\aq</json>}
          220  +
          221  +test json-3.5 {unescaping} {
          222  +    set result [catch {dom parse -json {{"this":"a\lb"}}} errMsg]
          223  +    list $result $errMsg
          224  +} {1 {error "JSON syntax error" at position 11
          225  +"{"this":"a\l <--Error-- b"}"}}
          226  +
          227  +test json-3.6 {unescaping} {
          228  +    set doc [dom parse -json {{"this":"a\nbc"}}]
          229  +    set result [$doc asXML -indent none]
          230  +    $doc delete
          231  +    set result
          232  +} {<this>a
          233  +bc</this>} 
          234  +
          235  +test json-3.7 {unescaping} {
          236  +    set doc [dom parse -json {{"this":"a\u0077\t\u0078bc"}}]
          237  +    set result [$doc asXML -indent none]
          238  +    $doc delete
          239  +    set result
          240  +} "<this>aw\txbc</this>"
          241  +
          242  +test json-3.8 {unescaping} {
          243  +    set doc [dom parse -json {{"this":"a\u000b"}}]
          244  +    set result [$doc asXML -indent none]
          245  +    $doc delete
          246  +    set result
          247  +} "<this>a\u000b</this>"
          248  +
          249  +test json-3.9 {unescaping} {
          250  +    set doc [dom parse -json {{"this":"a\u0077","that":"\t\u0078bc"}}]
          251  +    set result [$doc asXML -indent none]
          252  +    $doc delete
          253  +    set result
          254  +} "<this>aw</this><that>\txbc</that>"
          255  +
          256  +test json-5.1 {-jsonmaxnesting 0} {
          257  +    set result [catch {dom parse -json -jsonmaxnesting 0 {{"this":"that"}}} errMsg]
          258  +    list $result $errMsg
          259  +} {1 {error "Maximum JSON object/array nesting depth exceeded" at position 0
          260  +"{ <--Error-- "this":"that"}"}}
          261  +
          262  +test json-5.2 {-jsonmaxnesting 0} {
          263  +    set result [catch {dom parse -json -jsonmaxnesting 0 {["this","that"]}} errMsg]
          264  +    list $result $errMsg
          265  +} {1 {error "Maximum JSON object/array nesting depth exceeded" at position 0
          266  +"[ <--Error-- "this","that"]"}}
          267  +
          268  +test json-5.3 {-jsonmaxnesting 0} {
          269  +    set result [catch {dom parse -jsonroot o -json -jsonmaxnesting 0 {["this","that"]}} errMsg]
          270  +    list $result $errMsg
          271  +} {1 {error "Maximum JSON object/array nesting depth exceeded" at position 0
          272  +"[ <--Error-- "this","that"]"}}
          273  +
          274  +test json-5.4 {-jsonmaxnesting} {
          275  +    set doc [dom parse -json -jsonmaxnesting 2 {{"this":{"foo":"that"}}}]
          276  +    set result [$doc asXML -indent none]
          277  +    $doc delete
          278  +    set result
          279  +} {<this><foo>that</foo></this>}
          280  +
          281  +test json-5.5 {-jsonmaxnesting} {
          282  +    set result [catch {dom parse -json -jsonmaxnesting 1 \
          283  +                           {{"this":{"foo":"that"}}}} errMsg]
          284  +    list $result $errMsg
          285  +} {1 {error "Maximum JSON object/array nesting depth exceeded" at position 8
          286  +"{"this":{ <--Error-- "foo":"that"}}"}}
          287  +
          288  +test json-5.6 {-jsonmaxnesting} {
          289  +    set doc [dom parse -json -jsonmaxnesting 2 {
          290  +        {
          291  +            "this": {
          292  +                "foo":"that",
          293  +                "bar":"grill"
          294  +            },
          295  +            "two": "value",
          296  +            "three": {
          297  +                "t1":"t1value",
          298  +                "t2":"t2value"
          299  +            },
          300  +            "four": ["a","b","c"]
          301  +        }}]
          302  +    set result [$doc asXML]
          303  +    $doc delete
          304  +    set result
          305  +} {<this>
          306  +    <foo>that</foo>
          307  +    <bar>grill</bar>
          308  +</this>
          309  +<two>value</two>
          310  +<three>
          311  +    <t1>t1value</t1>
          312  +    <t2>t2value</t2>
          313  +</three>
          314  +<four>abc</four>
          315  +}
          316  +
          317  +set jsons {
          318  +    {{"a":"avalue","b":"bvalue","c":0.123}}
          319  +    {{"a":["avalue"]}}
          320  +    {{"a":"a value","b":"1value"}}
          321  +    {{"a":{"aa":"aavalue","bb":"bbvalue"},"b":"bvalue","c":0.123}}
          322  +    {{"a":[1,2,3,4,"abc"]}}
          323  +    {{"a":true,"b":false,"c":null,"d":"true","e":""}}
          324  +    {{"a":{"aa":[1,2,3,4,"abc"]},"b":"bvalue"}}
          325  +    {{"a":true,"b":false,"c":null,"d":"true","e":""}}
          326  +    {["a",["aa","bb"],"b"]}
          327  +    {{"a":"a\nvalue","b":"value\tvalue"}}
          328  +    {["\\\\a"]}
          329  +    {["a\"b"]}
          330  +    {{"b":"a \"b c\" d","b":"a \"b c\" d"}}
          331  +    {{"this":"a\nbc"}}
          332  +    {{"this":{"foo":"that"}}}
          333  +    {{"this":{"foo":"that","bar":"grill"},"two":"value","three":{"t1":"t1value","t2":"t2value"},"four":["a","b","c"]}}
          334  +    {"only a string"}
          335  +    {null}
          336  +    {1.23}
          337  +    {true}
          338  +    {false}
          339  +    {{}}
          340  +    {[]}
          341  +    {[[]]}
          342  +    {[["x"]]}
          343  +    {""}
          344  +    {[[[[["a"]]]]]}
          345  +    {{"x":[{"id":"foo"}]}}
          346  +    {"http://foo.bar"}
          347  +}
          348  +test json-6.1 {asJSON} {
          349  +    set failedlist [list]
          350  +    set ind 0
          351  +    foreach json $jsons {
          352  +        set doc [dom parse -json $json]
          353  +        set out [$doc asJSON]
          354  +        if {$json ne $out} {
          355  +            lappend failedlist "$ind : '$json' : '$out'"
          356  +        }
          357  +        incr ind
          358  +    }
          359  +    set failedlist
          360  +} {}
          361  +
          362  +test json-6.2 {asJSON - slash will not be escaped while serializing} {
          363  +    set doc [dom parse -json {"http:\/\/foo.bar"}]
          364  +    set result [$doc asJSON]
          365  +    $doc delete
          366  +    set result
          367  +} {"http://foo.bar"}
          368  +
          369  +test json-6.3 {asJSON - docNode serialization} {
          370  +    dom createDocumentNode docNode
          371  +    set result [$docNode asJSON]
          372  +    $docNode delete
          373  +    set result
          374  +} {{}}
          375  +
          376  +test json-6.4 {asJSON - doc serialization} {
          377  +    dom createDocument root docNode
          378  +    set result [$docNode asJSON]
          379  +    $docNode delete
          380  +    set result
          381  +} {{"root":""}}
          382  +
          383  +test json-6.5 {asJSON - serialization of control characters} {
          384  +    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\""]
          385  +    set result [$doc asJSON]
          386  +    $doc delete
          387  +    set result
          388  +} {"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"}
          389  +
          390  +test json-7.1 {jsonType} {
          391  +    set doc [dom parse {<j>foo</j>}]
          392  +    set root [$doc documentElement]
          393  +    set result [list]
          394  +    lappend result [$root asJSON]
          395  +    lappend result [$root jsonType]
          396  +    $root jsonType ARRAY
          397  +    lappend result [$root asJSON]
          398  +    $doc delete
          399  +    set result
          400  +} {{"foo"} NONE {["foo"]}}
          401  +
          402  +test json-7.2 {jsonType} {
          403  +    set doc [dom createDocumentNode]
          404  +    set result [$doc jsonType]
          405  +    lappend result [$doc asJSON]
          406  +    lappend result [catch {$doc jsonType foo}]
          407  +    $doc jsonType ARRAY
          408  +    lappend result [$doc asJSON]
          409  +    $doc jsonType OBJECT
          410  +    lappend result [$doc asJSON]
          411  +    $doc delete
          412  +    set result
          413  +} {NONE {{}} 1 {[]} {{}}}
          414  +
          415  +test json-8.1 {appendFromScript} {
          416  +    set doc [dom createDocumentNode]
          417  +    $doc appendFromScript {
          418  +        nodeCmds::e1
          419  +    }
          420  +    set result [list]
          421  +    lappend result [$doc asJSON]
          422  +    set root [$doc documentElement]
          423  +    lappend result [$root asJSON]
          424  +    $doc removeChild [$doc firstChild]
          425  +    $doc appendFromScript {
          426  +        nodeCmds::jae1
          427  +    }
          428  +    lappend result [$doc asJSON]
          429  +    set root [$doc documentElement]
          430  +    lappend result [$root asJSON]
          431  +    lappend result [$root jsonType]
          432  +    $doc delete
          433  +    set result
          434  +} {{{"e1":""}} {{}} {{"jae1":[]}} {[]} ARRAY}
          435  +
          436  +test json-8.2 {appendFromScript} {
          437  +    set doc [dom createDocumentNode]
          438  +    $doc appendFromScript {
          439  +        nodeCmds::t "some string"
          440  +    }
          441  +    set result [$doc asJSON]
          442  +    $doc delete
          443  +    set result
          444  +} {"some string"}
          445  +
          446  +test json-8.3 {appendFromScript} {
          447  +    set doc [dom createDocumentNode]
          448  +    $doc appendFromScript {
          449  +        nodeCmds::t ""
          450  +        nodeCmds::true ""
          451  +        nodeCmds::false ""
          452  +        nodeCmds::null ""
          453  +    }
          454  +    set result [$doc asJSON]
          455  +    $doc delete
          456  +    set result
          457  +} {["",true,false,null]}
          458  +
          459  +test json-8.4 {appendFromScript - text node with type NUMBER} {
          460  +    set doc [dom createDocumentNode]
          461  +    $doc appendFromScript {
          462  +        nodeCmds::number ""
          463  +        nodeCmds::number "0"
          464  +        nodeCmds::number "123456789012345678901234567890.12345679e-0003"
          465  +        nodeCmds::number "42 "
          466  +        nodeCmds::number " 42"
          467  +        nodeCmds::number "-"
          468  +    }
          469  +    set result [$doc asJSON]
          470  +    $doc delete
          471  +    set result
          472  +} {["",0,123456789012345678901234567890.12345679e-0003,"42 "," 42","-"]}
          473  +
          474  +test json-8.5 {createNodeCmd - wrong jsonType} {
          475  +    catch {dom createNodeCmd -jsonType OBJECT textNode textNodeWithJsonTypeObject}
          476  +} 1
          477  +
          478  +test json-9.1 {cloneNode -deep} {
          479  +    dom parse -json {[["a",1,"b",{"foo":"bar","baz":"boo"},null],"",null]} doc
          480  +    dom createDocument some other
          481  +    $other documentElement root
          482  +    $root appendChild [[$doc firstChild] cloneNode -deep]
          483  +    set result [[$root firstChild] asJSON]
          484  +    $doc delete
          485  +    $other delete
          486  +    set result
          487  +} {["a",1,"b",{"foo":"bar","baz":"boo"},null]}
          488  +
          489  +test json-9.2 {cloneNode} {
          490  +    dom parse -json {[["a",1,"b",{"foo":"bar","baz":"boo"},null],"",null]} doc
          491  +    dom createDocument some other
          492  +    $other documentElement root
          493  +    $root appendChild [[$doc firstChild] cloneNode]
          494  +    set result [[$root firstChild] asJSON]
          495  +    $doc delete
          496  +    $other delete
          497  +    set result
          498  +} {[]}
          499  +
          500  +test json-9.3 {cloneNode} {
          501  +    dom parse -json {{"string":"bar","number":1,"boolean":true,"array":[1,2,3],"object":{"foo":"bar","baz":"boo"}}} doc
          502  +    dom createDocument some other
          503  +    $other documentElement root
          504  +    foreach child [$doc childNodes] {
          505  +        $root appendChild [$child cloneNode -deep]
          506  +    }
          507  +    set result [list]
          508  +    foreach child [$root childNodes] {
          509  +        lappend result [$child asJSON]
          510  +    }
          511  +    $doc delete
          512  +    $other delete
          513  +    set result
          514  +} {{"bar"} 1 true {[1,2,3]} {{"foo":"bar","baz":"boo"}}}

Changes to tests/domnamespace.test.

     1      1   # Features covered: Namespace related DOM actions.
     2      2   #
     3      3   # This file contains a collection of tests for some namespace related
     4      4   # actions.
     5      5   #
     6      6   #    domnamespace-1.*: misc tests
     7      7   #    domnamespace-2.*: moving namespaced nodes from one document to another
            8  +#    domnamespace-3.*: moving namespaced nodes within a document
            9  +#    domnamespace-4.*: createNodeCmd and namespaces
     8     10   #
     9     11   # Copyright (c) 2002 Rolf Ade.
    10     12   #
    11     13   # RCS: @(#) $Id$
    12     14   
    13     15   source [file join [file dir [info script]] loadtdom.tcl]
    14     16   
................................................................................
   220    222       $root2 appendChild $node
   221    223       set result [$root2 asXML -indent none]
   222    224       $doc1 delete
   223    225       $doc2 delete
   224    226       set result
   225    227   } {<root xmlns="NS2"><doc1elem xmlns=""><a xmlns:p="foo" p:b="c"/></doc1elem></root>}
   226    228   
   227         -test domnamespace-2.11 {moving nodes with namespaced attributes between documents} {
   228         -    set doc1 [dom parse {<root xmlns:p="foo"><doc1elem><a p:b="c"/></doc1elem></root>}]
   229         -    set root1 [$doc1 documentElement]
   230         -    set doc2 [dom parse {<root xmlns="NS2"/>}]
   231         -    set root2 [$doc2 documentElement]
   232         -
   233         -    set node [$root1 removeChild [$root1 firstChild]]
   234         -    $root2 appendChild $node
   235         -    set result [$root2 asXML -indent none]
   236         -    $doc1 delete
   237         -    $doc2 delete
   238         -    set result
   239         -} {<root xmlns="NS2"><doc1elem xmlns=""><a xmlns:p="foo" p:b="c"/></doc1elem></root>}
   240         -
   241    229   test domnamespace-2.12 {moving nodes with namespaced attributes between documents} {
   242    230       set doc1 [dom parse {<root xmlns:p="foo"><doc1elem><a p:b="c"/></doc1elem></root>}]
   243    231       set root1 [$doc1 documentElement]
   244    232       set doc2 [dom parse {<root xmlns="NS2"/>}]
   245    233       set root2 [$doc2 documentElement]
   246    234       
   247    235       set node [$root1 removeChild [$root1 firstChild]]
................................................................................
   278    266       [$root2 firstChild] appendChild $node
   279    267       set result [$root2 asXML -indent none]
   280    268       $doc1 delete
   281    269       $doc2 delete
   282    270       set result
   283    271   } {<root xmlns="NS2"><e xmlns=""><doc1elem xmlns="NS1"><a xmlns:p="foo" p:b="c"/></doc1elem></e></root>}
   284    272   
   285         -test domnamespace-2.14 {moving nodes with namespaced attributes between documents} {
          273  +test domnamespace-2.15 {moving nodes with namespaced attributes between documents} {
   286    274       set doc1 [dom parse {<root xmlns="NS1" xmlns:p="foo"><doc1elem><a p:b="c"/></doc1elem></root>}]
   287    275       set root1 [$doc1 documentElement]
   288    276       set doc2 [dom parse {<root xmlns="NS2"><e xmlns=""/></root>}]
   289    277       set root2 [$doc2 documentElement]
   290    278       
   291    279       set node [$root1 removeChild [$root1 firstChild]]
   292    280       [$root2 firstChild] appendChild $node
................................................................................
   296    284           lappend result [$node nodeName]
   297    285       }
   298    286       $doc1 delete
   299    287       $doc2 delete
   300    288       set result
   301    289   } {doc1elem a}
   302    290   
          291  +test domnamespace-2.16 {It is not recommended to create attributes that look like namespace declarations} {
          292  +    set doc [[dom parse {<test xmlns="foo"/>}] documentElement]
          293  +    set child [[dom parse {<item/>}] documentElement]
          294  +    $child setAttribute xmlns "foo"
          295  +    $doc appendChild $child
          296  +    $doc asXML -indent none
          297  +} {<test xmlns="foo"><item xmlns="" xmlns="foo"/></test>}
          298  +
          299  +test domnamespace-2.17 {It is not recommended to create xml namespace declarations} {
          300  +    set doc [[dom parse {<test xmlns="foo"/>}] documentElement]
          301  +    set child [[dom parse {<item/>}] documentElement]
          302  +    $child setAttributeNS "" xmlns "foo"
          303  +    $doc appendChild $child
          304  +    $doc asXML -indent none
          305  +} {<test xmlns="foo"><item xmlns="foo" xmlns=""/></test>}
          306  +
          307  +test domnamespace-3.1 {moving namespaced nodes within a document} {
          308  +    set doc [dom parse {<doc><e xmlns="foo"><ee/></e><e xmlns="bar"/></doc>}]
          309  +    set root [$doc documentElement]
          310  +    set nodeToMove [$doc selectNodes {/doc/node()[1]/node()[1]}]
          311  +    set newParent [$doc selectNodes {/doc/node()[2]}]
          312  +    $newParent appendChild $nodeToMove
          313  +    set result [$doc asXML -indent none]
          314  +    $doc delete
          315  +    set result
          316  +} {<doc><e xmlns="foo"/><e xmlns="bar"><ee xmlns="foo"/></e></doc>}
          317  +
          318  +
          319  +namespace eval nodeCmds {
          320  +    dom createNodeCmd -namespace foo.bar elementNode ns1:e1
          321  +    dom createNodeCmd -namespace foo.bar elementNode e1
          322  +    dom createNodeCmd textNode t
          323  +    dom createNodeCmd -tagName e1 elementNode e1NoNS
          324  +}
          325  +
          326  +test domnamespace-4.1 {createNodeCmd and namespace} {
          327  +    dom createDocument doc doc
          328  +    $doc documentElement root
          329  +    $root appendFromScript {
          330  +        nodeCmds::ns1:e1 {nodeCmds::t "this"}
          331  +    }
          332  +    set result [$doc asXML -indent none]
          333  +    $doc delete
          334  +    set result
          335  +} {<doc><ns1:e1 xmlns:ns1="foo.bar">this</ns1:e1></doc>}
          336  +
          337  +test domnamespace-4.2 {createNodeCmd and namespace} {
          338  +    dom createDocumentNS foo.bar ns1:doc doc
          339  +    $doc documentElement root
          340  +    $root appendFromScript {
          341  +        nodeCmds::ns1:e1 {nodeCmds::t "this"}
          342  +    }
          343  +    set result [$doc asXML -indent none]
          344  +    $doc delete
          345  +    set result
          346  +} {<ns1:doc xmlns:ns1="foo.bar"><ns1:e1>this</ns1:e1></ns1:doc>}
          347  +
          348  +test domnamespace-4.3 {createNodeCmd and namespace} {
          349  +    dom createDocumentNS foo.bar doc doc
          350  +    $doc documentElement root
          351  +    $root appendFromScript {
          352  +        nodeCmds::ns1:e1 {nodeCmds::t "this"}
          353  +    }
          354  +    set result [$doc asXML -indent none]
          355  +    $doc delete
          356  +    set result
          357  +} {<doc xmlns="foo.bar"><ns1:e1 xmlns:ns1="foo.bar">this</ns1:e1></doc>}
          358  +
          359  +test domnamespace-4.4 {createNodeCmd and namespace} {
          360  +    dom createDocumentNS foo.bar doc doc
          361  +    $doc documentElement root
          362  +    $root appendFromScript {
          363  +        nodeCmds::e1 {
          364  +            nodeCmds::e1NoNS att attValue {nodeCmds::t "this"}
          365  +        }
          366  +    }
          367  +    set result [$doc asXML -indent none]
          368  +    $doc delete
          369  +    set result
          370  +} {<doc xmlns="foo.bar"><e1><e1 xmlns="" att="attValue">this</e1></e1></doc>}
          371  +
          372  +test domnamespace-4.5 {createNodeCmd and namespace} {
          373  +    dom createDocumentNS foo.bar doc doc
          374  +    $doc documentElement root
          375  +    $root appendFromScript {
          376  +        nodeCmds::e1 {
          377  +            nodeCmds::e1NoNS att attValue {nodeCmds::t "this"}
          378  +        }
          379  +    }
          380  +    set result [$doc selectNodes -namespaces {fb foo.bar} string(/fb:doc/fb:e1/e1/@att)]
          381  +    $doc delete
          382  +    set result
          383  +} {attValue}
          384  +
          385  +    
   303    386   # cleanup
   304    387   ::tcltest::cleanupTests
   305    388   return

Changes to tests/entity.test.

     2      2   #
     3      3   # This file contains a collection of tests for the different kinds of 
     4      4   # entities.
     5      5   #
     6      6   #    entity-1.*:  parameter entities, character entities
     7      7   #    entity-2.*:  predefined entities
     8      8   #    entity-3.*:  -useForeignDTD
     9         -#    entity-4.*:  external parsed entites
            9  +#    entity-4.*:  external parsed entities
    10     10   #
    11     11   # Copyright (c) 1999-2000 Zveno Pty Ltd.
    12     12   # Copyright (c) 2000-2004 Rolf Ade
    13     13   #
    14     14   # $Id$
    15     15   
    16     16   source [file join [file dir [info script]] loadtdom.tcl]

Added tests/html5reader.test.

            1  +# Features covered: HTML parser
            2  +#
            3  +# This file contains a collection of tests for the HTML parser.
            4  +# Tested functionalities:
            5  +#    html5-1.*: Character encoding
            6  +#    html5-2.*: Parsing tests
            7  +#    html5-3.*: Bad data
            8  +#    html5-4.*: DOM building
            9  +#    html5-5.*: Namespaces
           10  +#
           11  +# Copyright (c) 2017 Rolf Ade.
           12  +
           13  +source [file join [file dir [info script]] loadtdom.tcl]
           14  +
           15  +testConstraint html5 [dom featureinfo html5]
           16  +
           17  +test html5-1.1 {HTML character entities} {need_i18n html5} {
           18  +    set doc [dom parse -html5 -ignorexmlns {<html><body>&nbsp;&iexcl;&Auml;&uuml;</body></html>}]
           19  +    set root [$doc documentElement]
           20  +    set body [$root selectNodes body]
           21  +    set result [$body text]
           22  +    $doc delete
           23  +    set result
           24  +} "\u00A0\u00A1\u00c4\u00fc"
           25  +
           26  +test html5-1.2 {character entities} {need_i18n html5} {
           27  +    set doc [dom parse -html5 -ignorexmlns {<html><body>&#214;&#xC4;&#xc4;</body></html>}]
           28  +    set root [$doc documentElement]
           29  +    set body [$root selectNodes body]
           30  +    set result [$body text]
           31  +    $doc delete
           32  +    set result
           33  +} "\u00d6\u00c4\u00c4"
           34  +
           35  +test html5-1.3 {character entities} {need_i18n html5} {
           36  +    set doc [dom parse -html5 -ignorexmlns {<html>&euro;&ni;</html>}]
           37  +    set root [$doc documentElement]
           38  +    set body [$root selectNodes body]
           39  +    set result [$body text]
           40  +    $doc delete
           41  +    set result
           42  +} "\u20ac\u220b"
           43  +
           44  +test html5-1.4 {invalid characters} {need_i18n html5} {
           45  +    set doc [dom parse -html5 -ignorexmlns {<html>&#1;&#2;&#3;&#4;foo;</html>}]
           46  +    set root [$doc documentElement]
           47  +    set body [$root selectNodes body]
           48  +    set result [$body text]
           49  +    $doc delete
           50  +    set result
           51  +} "\u0001\u0002\u0003\u0004foo;"
           52  +
           53  +test html5-2.1 {not closed p tags} {html5} {
           54  +    set doc [dom parse -html5 -ignorexmlns {
           55  +        <html><body><p>Para 1<p>Para 2<p>Para 3</body></html>
           56  +    }]
           57  +    set result [$doc asXML -indent none]
           58  +    $doc delete
           59  +    set result
           60  +} {<html><head/><body><p>Para 1</p><p>Para 2</p><p>Para 3
           61  +    </p></body></html>}
           62  +
           63  +test html5-2.2 {HTML parsing} {html5} {
           64  +    set doc [dom parse -html5 -ignorexmlns {
           65  +        <HTML><HEAD></HEAD>
           66  +        <BODY>
           67  +        <H1>HTML</H1>
           68  +        </BODY>
           69  +        </HTML>
           70  +    }]
           71  +    set result [$doc asXML -indent none]
           72  +    $doc delete
           73  +    set result
           74  +} {<html><head/><body><h1>HTML</h1></body></html>}
           75  +
           76  +test html5-2.3 {HTML parsing} {html5} {
           77  +    set doc [dom parse -html5 -ignorexmlns {
           78  +        <!-- comment -->
           79  +        <HTML><HEAD></HEAD>
           80  +        <BODY>
           81  +        <H1>HTML</H1>
           82  +        </BODY>
           83  +        </HTML>
           84  +    }]
           85  +    set result [$doc asXML -indent none]
           86  +    $doc delete
           87  +    set result
           88  +} {<!-- comment --><html><head/><body><h1>HTML</h1></body></html>}
           89  +
           90  +test html5-2.4 {HTML parsing} {html5} {
           91  +    set doc [dom parse -html5 -ignorexmlns {
           92  +        <!-- comment -->
           93  +        <HTML><HEAD></HEAD>
           94  +        <BODY>
           95  +        <H1>HTML</H1>
           96  +        </BODY>
           97  +        </HTML>
           98  +        <!-- comment -->
           99  +    }]
          100  +    $doc documentElement root
          101  +    set result [$root nodeName]
          102  +    $doc delete
          103  +    set result
          104  +} {html}
          105  +
          106  +test html5-2.5 {HTML parsing} {html5} {
          107  +    set doc [dom parse -html5 -ignorexmlns {<html> <head><title></title></head><body>
          108  +        <form>
          109  +        <select id="L" name="nls_language">
          110  +        <option value="">--</option>
          111  +        <option value="en_US" selected="on">en_US</option>
          112  +        <option value="es_ES">es_ES</option>
          113  +        <option value="de_DE">de_DE</option>
          114  +        </select>
          115  +        </form>
          116  +        </body></html>
          117  +    }]
          118  +    $doc asHTML
          119  +} {<html>
          120  +<head><title></title></head><body><form><select id="L" name="nls_language">
          121  +<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>
          122  +</select></form></body>
          123  +</html>}
          124  +
          125  +test html5-2.6 {HTML parsing} {html5} {
          126  +    set doc [dom parse -html5 -ignorexmlns {<html> <head><title></title></head><body>
          127  +        <form>
          128  +        <select id="L" name="nls_language">
          129  +        <option value="">--
          130  +        <option value="en_US" selected="on">en_US
          131  +        <option value="es_ES">es_ES
          132  +        <option value="de_DE">de_DE
          133  +        </select>
          134  +        </form>
          135  +        </body></html>
          136  +    }]
          137  +    $doc asHTML
          138  +} {<html>
          139  +<head><title></title></head><body><form><select id="L" name="nls_language">
          140  +<option value="">--
          141  +        </option><option value="en_US" selected="on">en_US
          142  +        </option><option value="es_ES">es_ES
          143  +        </option><option value="de_DE">de_DE
          144  +        </option>
          145  +</select></form></body>
          146  +</html>}
          147  +
          148  +test html5-2.7 {HTML parsing} {html5} {
          149  +    set doc [dom parse -html5 -ignorexmlns {<html> <head><title></title></head><body>
          150  +        <form>
          151  +        <select id="L" name="nls_language">
          152  +        <option value="">--
          153  +        <option value="en_US" selected>en_US
          154  +        <option value="de_DE">de_DE
          155  +        </select>
          156  +        </form>
          157  +        </body></html>
          158  +    }]
          159  +    $doc asHTML
          160  +} {<html>
          161  +<head><title></title></head><body><form><select id="L" name="nls_language">
          162  +<option value="">--
          163  +        </option><option value="en_US" selected="selected">en_US
          164  +        </option><option value="de_DE">de_DE
          165  +        </option>
          166  +</select></form></body>
          167  +</html>}
          168  +
          169  +test html5-2.8 {HTML parsing} {html5} {
          170  +    set doc [dom parse -html5 -ignorexmlns {<html> <head><title></title></head><body>
          171  +        <form>
          172  +        <select id="L" name="nls_language">
          173  +        <option value="">--
          174  +        <option selected value="en_US">en_US
          175  +        <option value="de_DE">de_DE
          176  +        </select>
          177  +        </form>
          178  +        </body></html>
          179  +    }]
          180  +    $doc asHTML
          181  +} {<html>
          182  +<head><title></title></head><body><form><select id="L" name="nls_language">
          183  +<option value="">--
          184  +        </option><option selected="selected" value="en_US">en_US
          185  +        </option><option value="de_DE">de_DE
          186  +        </option>
          187  +</select></form></body>
          188  +</html>}
          189  +
          190  +test html5-3.1 {Bad data} {html5} {
          191  +    set data {line 6 column 17 - Warning: <script> lacks "type" attribute
          192  +line 10 column 17 - Warning: <script> lacks "type" attribute
          193  +        line 11 column 17 - Warning: <table> lacks "summary" attribute}
          194  +    set doc [dom parse -html5 -ignorexmlns $data]
          195  +    set result [$doc asXML -indent none]
          196  +    $doc delete
          197  +    set result
          198  +} {<html><head/><body>line 6 column 17 - Warning: <script> lacks "type" attribute
          199  +line 10 column 17 - Warning: &lt;script&gt; lacks "type" attribute
          200  +        line 11 column 17 - Warning: &lt;table&gt; lacks "summary" attribute</script></body></html>}
          201  +
          202  +test html5-3.2 {Bad data} {html5} {
          203  +     set doc [dom parse -html5 -ignorexmlns {<a>}]
          204  +     set result [$doc asXML -indent none]
          205  +     $doc delete
          206  +     set result
          207  +} {<html><head/><body><a/></body></html>}
          208  +        
          209  +test html5-4.1 {Tag name case normalization} {html5} {
          210  +    set doc [dom parse -html5 -ignorexmlns {<HtmL><boDY></BODy></HTml>}]
          211  +    set result [$doc asXML -indent none]
          212  +    $doc delete
          213  +    set result
          214  +} {<html><head/><body/></html>}
          215  +
          216  +test html5-4.2 {Tag name case normalization} {html5} {
          217  +    set doc [dom parse -html5 -ignorexmlns {<HtmL><NotaHTML_Tag/></HTml>}]
          218  +    set result [$doc asXML -indent none]
          219  +    $doc delete
          220  +    set result
          221  +} {<html><head/><body><notahtml_tag/></body></html>}
          222  +
          223  +test html5-4.3 {Attribute normalization} {html5} {
          224  +    set doc [dom parse -html5 -ignorexmlns {<HtmL><Body Id='3' FOO="Bar" note=this GriLL></body></html>}]
          225  +    set result [$doc asXML -indent none]
          226  +    $doc delete
          227  +    set result
          228  +} {<html><head/><body id="3" foo="Bar" note="note" grill="grill"/></html>}
          229  +
          230  +test html5-4.4 {ID Attribute handling} {html5} {
          231  +    set doc [dom parse -html5 -ignorexmlns {<HtmL><p ID="1"/><p id="2"/><p/></html>}]
          232  +    set result [[$doc getElementById 1] getAttribute id]
          233  +    $doc delete
          234  +    set result
          235  +} {1}
          236  +
          237  +
          238  +set xhtml {h "http://www.w3.org/1999/xhtml"}
          239  +set svg {svg "http://www.w3.org/2000/svg"}
          240  +set mathml {mml "http://www.w3.org/1998/Math/MathML"}
          241  +set xlink  {xlink "http://www.w3.org/1999/xlink"}
          242  +
          243  +set html5 {<!doctype html>
          244  +<html>
          245  +  <body>
          246  +    <p>
          247  +      <svg xmlns="http://www.w3.org/2000/svg">
          248  +      <circle cx="30" cy="30" r="30" fill="green"></circle>
          249  +      </svg>
          250  +    <p>text</p>
          251  +    </body>
          252  +</html>}
          253  +test html5-5.1 {svg subtrees} {html5} {
          254  +    set doc [dom parse -html5 $html5]
          255  +    set result [$doc selectNodes -namespaces $xhtml {string(/h:html/h:body/h:p[2])}]
          256  +    $doc delete
          257  +    set result
          258  +} {text}
          259  +
          260  +set html5 {<!DOCTYPE html>
          261  +<html>
          262  +  <head>
          263  +    <title>HTML5 SVG demo</title>
          264  +  </head>
          265  +
          266  +  <body>
          267  +    <h1>HTML5 SVG Demo</h1>
          268  +
          269  +A nice green circle:
          270  +    <svg id="circle" height="200" xmlns="http://www.w3.org/2000/svg">
          271  +      <circle id="greencircle" cx="30" cy="30" r="30" fill="green" />
          272  +    </svg>
          273  +
          274  +    <hr>
          275  +    <address>Created by DKS. This is free code</address>
          276  +  </body>
          277  +</html>}
          278  +test html5-5.2 {svg subtrees} {html5} {
          279  +    set doc [dom parse -html5 $html5]
          280  +    set svg [$doc selectNodes -namespaces $svg //svg:circle]
          281  +    set result [$svg @fill]
          282  +    $doc delete
          283  +    set result
          284  +} {green}
          285  +
          286  +set html5 {<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
          287  +    <head>
          288  +        <title>Binomial Theorem</title>
          289  +    </head>
          290  +    <body>
          291  +        <p>Binomial Theorem:</p>
          292  +        <math XMLNS="http://www.w3.org/1998/Math/MathML" FOO="bar">
          293  +            <mrow>
          294  +                <MSUp>
          295  +                    <mfenced BAR="grill">
          296  +                        <mrow>
          297  +                            <mi>a</mi>
          298  +                            <mo>+</mo>
          299  +                            <mi>b</mi>
          300  +                        </mrow>
          301  +                    </mfenced>
          302  +                    <mn>2</mn>
          303  +                </msup>
          304  +                <mo>=</mo>
          305  +                <msup>
          306  +                    <mrow>
          307  +                        <mi>a</mi>
          308  +                    </mrow>
          309  +                    <mn>2</mn>
          310  +                </msup>
          311  +                <mo>+</mo>
          312  +                <msup>
          313  +                    <mrow>
          314  +                        <mi>b</mi>
          315  +                    </mrow>
          316  +                    <mn>2</mn>
          317  +                </msup>
          318  +                <mo>+</mo>
          319  +                <mrow>
          320  +                    <mn>2</mn>
          321  +                    <mi>a</mi>
          322  +                    <mi>b</mi>
          323  +                </mrow>
          324  +            </mrow>
          325  +        </math>
          326  +    </body>
          327  +</html>}
          328  +test html5-5.3 {mathml subtrees} {html5} {
          329  +    set doc [dom parse -html5 $html5]
          330  +    set mis [$doc selectNodes -namespaces $mathml //mml:mi]
          331  +    set result ""
          332  +    foreach mi $mis {
          333  +        append result [$mi text]
          334  +    }
          335  +    $doc delete
          336  +    set result
          337  +} {ababab}
          338  +
          339  +set html5 {<html>
          340  +  <body>
          341  +    <svg id="circle" height="60" width="60" 
          342  +     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
          343  +      <image id="image" x="0" y="0" height="60" width="60"  xlink:href="huge-red-circle.svg" />
          344  +    </svg>
          345  +</body>}
          346  +test html5-5.4 {xlink attribute} {html5} {
          347  +    set doc [dom parse -html5 $html5]
          348  +    set node [$doc selectNodes -namespaces $xlink {//*[@xlink:href]}]
          349  +    set result [$node getAttributeNS [lindex $xlink 1] href]
          350  +    $doc delete
          351  +    set result
          352  +} {huge-red-circle.svg}
          353  +
          354  +test html5-5.5 {xlink attribute} {html5} {
          355  +    set doc [dom parse -html5 -ignorexmlns $html5]
          356  +    set node [$doc getElementById "image"]
          357  +    set result [$node getAttribute "xlink:href"]
          358  +    $doc delete
          359  +    set result
          360  +} {huge-red-circle.svg}
          361  +
          362  +
          363  +# cleanup
          364  +::tcltest::cleanupTests
          365  +return
          366  +

Changes to tests/htmlreader.test.

    34     34   test html-1.3 {character entities} {need_i18n} {
    35     35       set doc [dom parse -html {<html>&euro;&ni;</html>}]
    36     36       set root [$doc documentElement]
    37     37       set result [$root text]
    38     38       $doc delete
    39     39       set result
    40     40   } "\u20ac\u220b"
           41  +
           42  +test html-1.4 {Invalid numeric character entity} {
           43  +    set doc [dom parse -html {<html>&#39xyz</html>}]
           44  +    set root [$doc documentElement]
           45  +    set result [$root text]
           46  +    $doc delete
           47  +    set result
           48  +} "&#39xyz"
           49  +
           50  +test html-1.5 {Numeric character entity} {
           51  +    set doc [dom parse -html {<html>&#123456789012345678;</html>}]
           52  +    set root [$doc documentElement]
           53  +    set result [$root text]
           54  +    $doc delete
           55  +    set result
           56  +} "&#123456789012345678;"
           57  +
           58  +test html-1.6 {Numeric character entity} {
           59  +    set doc [dom parse -html {<html>&#xabcdef;</html>}]
           60  +    set root [$doc documentElement]
           61  +    set result [$root text]
           62  +    $doc delete
           63  +    set result
           64  +} "&#xabcdef;"
    41     65   
    42     66   test html-2.1 {not closed p tags} {
    43     67       set doc [dom parse -html {
    44     68           <html><body><p>Para 1<p>Para 2<p>Para 3</body></html>
    45     69       }]
    46     70       set result [$doc asXML -indent none]
    47     71       $doc delete

Changes to tests/i18n.test.

     2      2   #
     3      3   # Copyright (c) 2002 Rolf Ade.
     4      4   #
     5      5   # RCS: @(#) $Id$
     6      6   
     7      7   source [file join [file dir [info script]] loadtdom.tcl]
     8      8   
            9  +testConstraint beyondBMP [expr {[dom featureinfo TCL_UTF_MAX] > 3}]
           10  +testConstraint 8.6 [package vsatisfies [package present Tcl] 8.6]
           11  +
     9     12   test i18n-1.1 {parse utf-8 string} {need_i18n} {
    10     13       set russian "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
    11     14       set doc [dom parse "<test>$russian</test>"]
    12     15       set root [$doc documentElement]
    13     16       set text [$root text]
    14     17       $doc delete
    15     18       string compare $text "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
................................................................................
    23     26       set root [$doc documentElement]
    24     27       set text [$root text]
    25     28       $doc delete
    26     29       string compare $text "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
    27     30   } {0}
    28     31       
    29     32   test i18n-1.3 {parse utf-8 readFile} {need_i18n} {
    30         -    set doc [dom parse [::tDOM::xmlReadFile [file join [pwd] [file dir [info script]] data/i18n_1.xml]]]
           33  +    set doc [dom parse [::tdom::xmlReadFile [file join [pwd] [file dir [info script]] data/i18n_1.xml]]]
    31     34       set root [$doc documentElement]
    32     35       set text [$root text]
    33     36       $doc delete
    34     37       string compare $text "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
    35     38   } {0}
    36     39       
           40  +test i18n-1.4 {pcdata outside BMP} -body {
           41  +    set doc [dom parse "<doc>&#x1F46E;&#x1F47E;&#x1F494;</doc>"]
           42  +    set result [$doc asXML -indent none -escapeNonASCII]
           43  +    $doc delete
           44  +    set result
           45  +} -result "<doc>&#128110;&#128126;&#128148;</doc>"
           46  +
           47  +test i18n-1.5 {pcdata outside BMP} -body {
           48  +    set doc [dom parse "<doc>&#x1F46E;&#x1F47E;&#x1F494;</doc>"]
           49  +    set result [$doc selectNodes string-length(/doc)]
           50  +    $doc delete
           51  +    set result
           52  +} -result 3
           53  +
           54  +test i18n-1.6 {pcdata outside BMP} -constraints {
           55  +    8.6
           56  +    beyondBMP
           57  +} -body {
           58  +    set doc [dom parse "<doc>\U1F46E\U1F47E\U1F494</doc>"]
           59  +    set result [$doc asXML -indent none -escapeNonASCII]
           60  +    $doc delete
           61  +    set result
           62  +} -result "<doc>&#128110;&#128126;&#128148;</doc>"
           63  +
           64  +test i18n-1.7 {pcdata outside BMP} -body {
           65  +    set doc [dom parse "<doc>&#x1F46E;&#x1F47E;&#x1F494;</doc>"]
           66  +    set result [dom isBMPCharData [$doc selectNodes string(/doc)]]
           67  +    $doc delete
           68  +    set result
           69  +} -result 0
           70  +
           71  +test i18n-1.8 {pcdata outside BMP} -constraints {
           72  +    beyondBMP
           73  +    8.6
           74  +} -body {
           75  +    set doc [dom parse "<doc>\U1F46E\U1F47E\U1F494</doc>"]
           76  +    set result [$doc asXML -indent none]
           77  +    $doc delete
           78  +    set result
           79  +} -result "<doc>&#128110;&#128126;&#128148;</doc>"
           80  +
           81  +test i18n-1.10 {pcdata outside unicode} -body {
           82  +    set doc [dom parse "<doc>&#x10FFFF;</doc>"]
           83  +    set result [$doc asXML -indent none -escapeNonASCII]
           84  +    $doc delete
           85  +    set result
           86  +} -result "<doc>&#1114111;</doc>"
           87  +
           88  +test i18n-1.11 {pcdata outside unicode} -body {
           89  +    set result [catch {dom parse "<doc>&#x110000;</doc>"} msg]
           90  +    set msg
           91  +} -match glob -result "*reference to invalid character number*"
    37     92   
    38     93   # cleanup
    39     94   ::tcltest::cleanupTests
    40     95   return
    41     96   

Changes to tests/loadtdom.tcl.

     2      2   #
     3      3   # This file is [source]d by all.tcl and all test files, to ensure, that
     4      4   # the tcltest package and the lastest tdom build is present.
     5      5   #
     6      6   # RCS: @(#) $Id$
     7      7   #
     8      8   
     9         -if {[lsearch [namespace children] ::tcltest] == -1} {
    10         -    if {$tcl_version < 8.2} {
    11         -        puts stderr "sourcing def.tcl"
    12         -        source [file join [file dir [info script]] defs.tcl]
    13         -        set auto_path [pwd]
    14         -    } else {
    15         -        package require tcltest
    16         -        namespace import ::tcltest::*
            9  +package require tcltest
           10  +namespace import ::tcltest::*
           11  +if {[catch {package require -exact tdom 0.9.1}]} {
           12  +    if {[catch {load [file join [file dir [info script]] ../unix/libtdom0.9.1.so]}]} {
           13  +        error "Unable to load the appropriate tDOM version!"
    17     14       }
    18     15   }
    19         -
    20         -if {[catch {package present -exact tdom 0.8.3}]} {
    21         -    package require -exact tdom 0.8.3
    22         -} else {
    23         -    if {[lsearch [namespace children] ::tDOM] == -1} {
    24         -        # tcldomsh without the script library. Source the lib.
    25         -        source [file join [file dir [info script]] ../lib tdom.tcl]
    26         -    }
           16  +if {[info commands ::tdom::xmlReadFile] == ""} {
           17  +    # tcldomsh without the script library. Source the lib.
           18  +    source [file join [file dir [info script]] ../lib tdom.tcl]
    27     19   }
    28     20   

Changes to tests/parser.test.

     7      7   #    parser-3.*: return code 'continue' from callback
     8      8   #    parser-4.*: return code 'error' from callback
     9      9   #    parser-5.*: parse input from channel
    10     10   #    parser-6.*: reuse parser 
    11     11   #    parser-7.*: parser reset
    12     12   #    parser-8.*: parser free
    13     13   #    parser-9.*: parser parse
           14  +#    parser-10.*: return code 'return' from callback
           15  +#    parser-11.*: parser input from filename
           16  +#    parser-12.*: parser currentmarkup
    14     17   #
    15     18   # Copyright (c) 1999-2000 Zveno Pty Ltd.
    16         -# Copyright (c) 2002-2005 Rolf Ade
           19  +# Copyright (c) 2002-2015 Rolf Ade
    17     20   #
    18     21   # $Id$
    19     22   
    20     23   source [file join [file dir [info script]] loadtdom.tcl]
    21     24   
    22     25   proc parray arrayName {
    23     26       upvar #0 $arrayName arr
................................................................................
    53     56   	    }
    54     57   	    break {
    55     58   		return -code break
    56     59   	    }
    57     60   	    error {
    58     61   		return -code error "error condition in callback"
    59     62   	    }
           63  +            return {
           64  +                return -code return
           65  +            }
    60     66   	    default {
    61     67   		return -code $atts(class) 
    62     68   	    }
    63     69   	}
    64     70       }
    65     71   }
    66     72   catch {unset ended}
................................................................................
   171    177       set ::esh_1_13_2 0
   172    178       catch {rename parser-1.13 {}}
   173    179       set p [expat parser-1.13 -elementstartcommand esh_1_13_1]
   174    180       $p configure -elementstartcommand esh_1_13_2
   175    181       $p parse {<root><a/><b/></root>}
   176    182       list $::esh_1_13_1 $::esh_1_13_2
   177    183   } {0 3}
          184  +
          185  +test parser-1.14 {parser get} {
          186  +    catch {rename parser-1.14 {}}
          187  +    set parser [expat parser-1.14]
          188  +    set result [catch {$parser get}]
          189  +    $parser free
          190  +    set result
          191  +} {1}
          192  +test parser-1.15 {parser get} {
          193  +    catch {rename parser-1.15 {}}
          194  +    set parser [expat parser-1.15]
          195  +    set result [catch {$parser get foo bar}]
          196  +    $parser free
          197  +    set result
          198  +} {1}
          199  +test parser-1.16 {parser get} {
          200  +    catch {rename parser-1.16 {}}
          201  +    set parser [expat parser-1.16]
          202  +    set result [$parser get -currentbytecount]
          203  +    $parser free
          204  +    set result
          205  +} {0}
          206  +
          207  +test parser-1.17 {parser delete} {
          208  +    expat parser-1.17
          209  +    parser-1.17 delete
          210  +} {}
   178    211   
   179    212   # Test break return code from callback
   180    213   
   181    214   test parser-2.1 {break in callback} {
   182    215       catch {unset ::started}
   183    216   
   184    217       catch {rename parser-2.1 {}}
................................................................................
   347    380       set p [::xml::parser parser-4.1 -elementstartcommand Start]
   348    381       set errcode [catch {$p parse {<?xml version="1.0"?>
   349    382   <Test>
   350    383   <Element>Should see this data</Element>
   351    384   <Element class="error"/>
   352    385   <Element>Should not see this data</Element>
   353    386   </Test>
   354         -}} result]
          387  +    }} result]
   355    388       list $errcode $::started(Element)
   356    389   } {1 2}
   357    390   
   358    391   test parser-4.2 {error in callback} {
   359    392       catch {unset ::started}
   360    393   
   361    394       catch {rename parser-4.2 {}}
................................................................................
   414    447       set result [catch {$parser parsechannel $fd}]
   415    448       close $fd
   416    449       set result
   417    450   } -cleanup {
   418    451       removeFile parser.xml
   419    452   } -result 1
   420    453   
          454  +proc elementstart-5.4 {args} {
          455  +    error "Error raised by elementstart-5.4"
          456  +}
          457  +
          458  +test parser-5.4 {parse channel - error raised in handler} {
          459  +    catch {parser-5.4 free}
          460  +    ::xml::parser parser-5.4 -elementstartcommand elementstart-5.4
          461  +    set file [file join [pwd] [file dir [info script]] data/books.xml]
          462  +    catch {parser-5.4 parsefile $file} errMsg
          463  +    parser-5.4 free
          464  +    set errMsg
          465  +} "Error raised by elementstart-5.4"
          466  +
   421    467   test parser-6.1 {reuse parser} {
   422    468       catch {rename parser-6.1 {}}
   423    469       set parser [expat parser-6.1 -baseurl file:///foo/bar]
   424    470       set result [$parser cget -baseurl]
   425    471       $parser parse <data/>
   426    472       lappend result [$parser cget -baseurl]
   427    473       $parser configure -baseurl file:///bar/foo
................................................................................
   467    513   
   468    514   test parser-8.1 {parser free called from within callback proc} {
   469    515       set parser [expat -elementstartcommand elementstart]
   470    516       set result [catch {$parser parse <root>foo</root>} errMsg]
   471    517       lappend result $errMsg
   472    518       $parser free
   473    519       set result
   474         -} {1 {parser freeing not allowed from within callback}}
          520  +} {1 {parser delete not allowed from within callback}}
   475    521   
   476    522   proc elementstart {args} {
   477    523       global parser
   478    524   
   479    525       $parser parse {<root>foo bar</root>}
   480    526   }
   481    527   
   482         -test parser-9.1 {try to use the parser form within one of its callbacks} {
          528  +test parser-9.1 {try to use the parser from within one of its callbacks} {
   483    529       set parser [expat -elementstartcommand elementstart]
   484    530       set result [catch {$parser parse <root>foo</root>} errMsg]
   485    531       lappend result $errMsg
   486    532       $parser free
   487    533       set result
   488    534   } {1 {Parser already in use.}}
   489    535   
................................................................................
   493    539       $parser parse {<root>foo bar</root>}
   494    540   }
   495    541   
   496    542   proc elementstart {args} {
   497    543       calledFromElementstart
   498    544   }
   499    545   
   500         -test parser-9.2 {try to use the parser form within one of its callbacks} {
          546  +test parser-9.2 {try to use the parser from within one of its callbacks} {
   501    547       set parser [expat -elementstartcommand elementstart]
   502    548       set result [catch {$parser parse <root>foo</root>} errMsg]
   503    549       lappend result $errMsg
   504    550       $parser free
   505    551       set result
   506    552   } {1 {Parser already in use.}}
   507    553   
          554  +
          555  +test parser-10.1 {return -code return in callback} {
          556  +    catch {unset ::started}
          557  +
          558  +    catch {rename parser-10.1 {}}
          559  +    set p [::xml::parser parser-10.1 -elementstartcommand Start]
          560  +    set errcode [catch {$p parse {<?xml version="1.0"?>
          561  +<Test>
          562  +<Element>Should see this data</Element>
          563  +<Element class="return"/>
          564  +<Element>Should not see this data</Element>
          565  +</Test>
          566  +}} result]
          567  +    list $errcode $::started(Element)
          568  +} {0 2}
          569  +
          570  +test parser-10.2 {return -code return in callback} {
          571  +    catch {unset ::started}
          572  +
          573  +    catch {rename parser-10.2 {}}
          574  +    set p [::xml::parser parser-10.2 -elementstartcommand Start]
          575  +    set errcode [catch {$p parse {<?xml version="1.0"?>
          576  +<Test>
          577  +<Element>Should see this data</Element>
          578  +<Element class="return"/>
          579  +<Element>Should not see this data</Element>
          580  +</Test>}} errMsg]
          581  +    set result [list $errcode $::started(Element)]
          582  +    $p reset
          583  +    catch {unset ::started}
          584  +    set errcode [catch {$p parse {<?xml version="1.0"?>
          585  +<Test>
          586  +<Element>Should see this data</Element>
          587  +<Element class="ok"/>
          588  +<Element>Should see this data</Element>
          589  +</Test>}} errMsg]
          590  +    lappend result $errcode $::started(Element)
          591  +} {0 2 0 3}
          592  +
          593  +test parser-11.1 {parse parsefile} {
          594  +    catch {unset ::count}
          595  +
          596  +    catch {rename parser-11.1 {}}
          597  +    set parser [::xml::parser parser-11.1 -elementstartcommand Count]
          598  +    set file [file join [pwd] [file dir [info script]] data/books.xml]
          599  +    $parser parsefile $file
          600  +    set ::count
          601  +} {42}
          602  +
          603  +proc elementstart-11.2 {args} {
          604  +    error "Error raised by elementstart-11.2"
          605  +}
          606  +
          607  +test parser-11.2 {parse parsefile - error raised in handler} {
          608  +    catch {parser-11.2 free}
          609  +    ::xml::parser parser-11.2 -elementstartcommand elementstart-11.2
          610  +    set file [file join [pwd] [file dir [info script]] data/books.xml]
          611  +    catch {parser-11.2 parsefile $file} errMsg
          612  +    parser-11.2 free
          613  +    set errMsg
          614  +} "Error raised by elementstart-11.2"
          615  +
          616  +proc elementstart-12.1 {parser args} {
          617  +    global result
          618  +    append result [$parser currentmarkup]
          619  +}
          620  +
          621  +proc elementend-12.1 {parser args} {
          622  +    global result
          623  +    append result [$parser currentmarkup]
          624  +}
          625  +
          626  +test parser-12.1 {currentmarkup method} {
          627  +    catch {unset result}
          628  +    set result ""
          629  +    set p [expat parser-12.1 -noexpand]
          630  +    $p configure \
          631  +        -elementstartcommand [list elementstart-12.1 $p] \
          632  +        -elementendcommand [list elementend-12.1 $p]
          633  +    $p parse {<root rootatt="rootatt">text<a
          634  +        a_att1="a_att1"
          635  +        a_att2 = "a_att2"/><b>more text</b></root>}
          636  +    $p free
          637  +    set result
          638  +} {<root rootatt="rootatt"><a
          639  +        a_att1="a_att1"
          640  +        a_att2 = "a_att2"/><b></b></root>}
          641  +
          642  +proc characterdata-12.2 {parser data} {
          643  +    global result
          644  +    append result [$parser currentmarkup]
          645  +}
          646  +test parser-12.2 {currentmarkup method} {
          647  +    catch {unset result}
          648  +    set result ""
          649  +    set p [expat parser-12.2]
          650  +    $p configure \
          651  +        -characterdatacommand [list characterdata-12.2 $p] 
          652  +    $p parse {<root rootatt="rootatt">text<a
          653  +        a_att1="a_att1"
          654  +        a_att2 = "a_att2"/><b>more text</b></root>}
          655  +    $p free
          656  +    set result
          657  +} {}
          658  +
          659  +test parser-12.3 {currentmarkup method} {
          660  +    set p [expat parser-12.3]
          661  +    set result [$p currentmarkup]
          662  +    $p free
          663  +    set result
          664  +} {}
          665  +
          666  +proc elementstart-12.4 {parser handlerset args} {
          667  +    global result
          668  +    append result "$handlerset: [$parser currentmarkup]\n"
          669  +}
          670  +proc elementend-12.4 {parser handlerset args} {
          671  +    global result
          672  +    append result "$handlerset: [$parser currentmarkup]\n"
          673  +}
          674  +test parser-12.4 {currentmarkup method - multiple handler set} {
          675  +    catch {unset result}
          676  +    set result ""
          677  +    set p [expat parser-12.4]
          678  +    $p configure \
          679  +        -elementstartcommand [list elementstart-12.4 $p default] \
          680  +        -elementendcommand [list elementend-12.4 $p default] \
          681  +        -handlerset "additional" \
          682  +        -elementstartcommand [list elementstart-12.4 $p "additional"] \
          683  +        -elementendcommand [list elementend-12.4 $p "additional"]
          684  +    $p parse {<root rootatt="rootatt">text<a
          685  +        a_att1="a_att1"
          686  +        a_att2 = "a_att2"/><b>more text</b></root>}
          687  +    $p free
          688  +    set result
          689  +} {default: <root rootatt="rootatt">
          690  +additional: <root rootatt="rootatt">
          691  +default: <a
          692  +        a_att1="a_att1"
          693  +        a_att2 = "a_att2"/>
          694  +additional: <a
          695  +        a_att1="a_att1"
          696  +        a_att2 = "a_att2"/>
          697  +default: 
          698  +additional: 
          699  +default: <b>
          700  +additional: <b>
          701  +default: </b>
          702  +additional: </b>
          703  +default: </root>
          704  +additional: </root>
          705  +}
          706  +
          707  +proc elementstart-12.5 {parser args} {
          708  +    global result
          709  +    append result "[$parser currentmarkup]"
          710  +}
          711  +test parser-12.5 {currentmarkup method - empty element shortcut -elementstartcommand} {
          712  +    catch {unset result}
          713  +    set result ""
          714  +    set p [expat parser-12.5]
          715  +    $p configure \
          716  +        -elementstartcommand [list elementstart-12.5 $p] 
          717  +    $p parse {<root><elem/></root>}
          718  +    $p free
          719  +    set result
          720  +} {<root><elem/>}
          721  +
          722  +proc elementend-12.6 {parser args} {
          723  +    global result
          724  +    if {[$parser currentmarkup] eq ""} {
          725  +        append result "<elementend called, but currentmarkup return empty string>"
          726  +    }
          727  +    append result "[$parser currentmarkup]"
          728  +}
          729  +test parser-12.6 {currentmarkup method - empty element shortcut -elementendcommand} {
          730  +    catch {unset result}
          731  +    set result ""
          732  +    set p [expat parser-12.6]
          733  +    $p configure \
          734  +        -elementendcommand [list elementend-12.6 $p] 
          735  +    $p parse {<root><elem/></root>}
          736  +    $p free
          737  +    set result
          738  +} {<elementend called, but currentmarkup return empty string></root>}
          739  +    
   508    740   foreach parser [info commands xmlparser*] {
   509    741       $parser free
   510    742   }
   511    743   foreach parser [info commands parser-*] {
   512    744       $parser free
   513    745   }
          746  +
          747  +proc elementdeclcommand-12.7 {parser args} {
          748  +    global result
          749  +    append result "elementdeclcommand: [$parser currentmarkup]"
          750  +}
          751  +
          752  +proc entitydeclcommand-12.7 {parser args} {
          753  +    global result
          754  +    append result "entitydeclcommand: [$parser currentmarkup]"
          755  +}
          756  +
          757  +test parser-12.7 {currentmarkup method - not for doctype markup handler} {
          758  +    catch {unset result}
          759  +    set result ""
          760  +    set p [expat parser-12.7]
          761  +    $p configure \
          762  +        -elementdeclcommand [list elementdeclcommand-12.7 $p] \
          763  +        -entitydeclcommand [list entitydeclcommand-12.7 $p]
          764  +    $p parse {<!DOCTYPE test [
          765  +<!ELEMENT test (#PCDATA) >
          766  +<!ENTITY % xx '&#37;zz;'>
          767  +<!ENTITY % zz '&#60;!ENTITY tricky "error-prone" >' >
          768  +%xx;
          769  +]>
          770  +<test>This sample shows a &tricky; method.</test>}
          771  +    $p free
          772  +    set result
          773  +} {elementdeclcommand: entitydeclcommand: entitydeclcommand: }
          774  +
          775  +proc pi-12.8 {parser args} {
          776  +    global result
          777  +    append result "pi: [$parser currentmarkup]"
          778  +}
          779  +test parser-12.8 {currentmarkup method - processing instruction} {
          780  +    catch {unset result}
          781  +    set result ""
          782  +    set p [expat parser-12.8]
          783  +    $p configure \
          784  +        -processinginstructioncommand [list pi-12.8 $p]
          785  +    $p parse {<doc><?xml-stylesheet type="text/xsl" href="style.xsl"?></doc>}
          786  +    $p free
          787  +    set result
          788  +} {pi: <?xml-stylesheet type="text/xsl" href="style.xsl"?>}
          789  +
          790  +proc comment-12.9 {parser args} {
          791  +    global result
          792  +    append result "comment: [$parser currentmarkup]"
          793  +}
          794  +test parser-12.9 {currentmarkup method - comment} {
          795  +    catch {unset result}
          796  +    set result ""
          797  +    set p [expat parser-12.9]
          798  +    $p configure \
          799  +        -commentcommand [list comment-12.9 $p]
          800  +    $p parse {<doc><!-- A comment --></doc>}
          801  +    $p free
          802  +    set result
          803  +} {comment: <!-- A comment -->}
          804  +
   514    805   
   515    806   # cleanup
   516    807   ::tcltest::cleanupTests
   517    808   return

Changes to tests/pcdata.test.

    76     76       $parser parse {<?xml version="1.0"?>
    77     77   <!DOCTYPE Test>
    78     78   <Test>This is &lt;PCDATA&gt;</Test>
    79     79   }
    80     80       list $::result $::pcdataCounter
    81     81   } {{This is <PCDATA>} 1}
    82     82   
    83         -test pcdata-1.3 {keep all PCDATA for not white space only PCDATA content} {
           83  +test pcdata-1.4 {keep all PCDATA for not white space only PCDATA content} {
    84     84       set ::result {}
    85     85   
    86     86       catch {rename xml::pcdata-1.4 {}}
    87     87       set parser [xml::parser xml::pcdata-1.4 \
    88     88                       -characterdatacommand pcdata \
    89     89                       -ignorewhitecdata 1]
    90     90       $parser parse {<root>

Changes to tests/pi.test.

    14     14   proc PI {target data args} {
    15     15       lappend ::result $target $data
    16     16   }
    17     17   
    18     18   test pi-1.1 {PI} {
    19     19       set ::result {}
    20     20   
    21         -    catch {rename xml::pi-1.1 {}}
    22     21       set parser [xml::parser pi-1.1 \
    23     22   	-processinginstructioncommand PI]
    24     23       $parser parse {<?xml version="1.0"?>
    25     24   <!DOCTYPE Test>
    26     25   <Test><?Test This is a processing instruction?></Test>
    27     26   }
           27  +    $parser free
    28     28       set ::result
    29     29   } {Test {This is a processing instruction}}
    30     30   
    31     31   test pi-1.2 {PI: missing trailing ?} {
    32     32       set ::result {}
    33     33   
    34         -    catch {rename xml::pi-1.2 {}}
    35     34       set parser [xml::parser pi-1.2 \
    36     35   	-processinginstructioncommand PI]
    37     36       set returncode [catch {$parser parse {<?xml version="1.0"?>
    38     37   <!DOCTYPE Test>
    39     38   <Test><?Test This is a syntax error></Test>
    40     39   }} msg]
    41         -
           40  +    $parser free
    42     41       list $returncode [regexp {error "unclosed token" at.+} $msg]
    43     42   } {1 1}
    44     43   
    45     44   test pi-2.1 {PI with special characters} {
    46     45       set ::result {}
    47     46   
    48         -    catch {rename xml::pi-2.1 {}}
    49     47       set parser [xml::parser pi-2.1 \
    50     48   	-processinginstructioncommand PI]
    51     49       $parser parse {<?xml version="1.0"?>
    52     50   <!DOCTYPE Test>
    53     51   <Test><?Test [if !VMLRender]?></Test>
    54     52   }
           53  +    $parser free
    55     54       set ::result
    56     55   } {Test {[if !VMLRender]}}
    57     56   
    58         -foreach parser [info commands pi-*] {
    59         -    $parser free
    60         -}
    61         -
    62     57   # cleanup
    63     58   ::tcltest::cleanupTests
    64     59   return

Added tests/pullparser.test.

            1  +# Features covered: Pull parser
            2  +#
            3  +# This file contains a collection of tests for the pull parser
            4  +# interface.
            5  +# Tested functionalities:
            6  +#    pp-1.*: Basics, interface
            7  +#    pp-2.*: Compare dom / pull parsing
            8  +#    pp-3.*: skip method
            9  +#    pp-4.*: find-element method
           10  +#    pp-5.*: CDATA section handling
           11  +#    pp-6.*: line/column methods
           12  +#
           13  +# Copyright (c) 2017-2018 Rolf Ade.
           14  +
           15  +source [file join [file dir [info script]] loadtdom.tcl]
           16  +
           17  +test pp-1.1 {Create} {
           18  +    tdom::pullparser pp
           19  +    pp delete
           20  +} {}
           21  +
           22  +test pp-1.2 {Invalid create} {
           23  +    catch {tdom::pullparser pp foo}
           24  +} 1
           25  +
           26  +test pp-1.3 {Reset freshly created parser} {
           27  +    tdom::pullparser pp
           28  +    pp reset
           29  +    pp reset
           30  +    pp delete
           31  +} {}
           32  +
           33  +test pp-1.4 {State after creation} {
           34  +    tdom::pullparser pp
           35  +    set result [pp state]
           36  +    lappend result [pp state]
           37  +    pp delete
           38  +    set result
           39  +} {READY READY}
           40  +
           41  +proc walkDOM {node} {
           42  +    set str ""
           43  +    switch [$node nodeType] {
           44  +        "ELEMENT_NODE" {
           45  +            append str [$node nodeName]
           46  +            # Because the dom builder arranges attributes so that the
           47  +            # xmlns attributes come first we need to ensure a unify
           48  +            # attribute order for comparsion.
           49  +            set attpairs [list]
           50  +            foreach att [$node attributes] {
           51  +                if {[llength $att] == 3} {
           52  +                    if {[lindex $att 2] eq ""} {
           53  +                        lappend attpairs [list \
           54  +                            xmlns:[lindex $att 0] \
           55  +                            [$node getAttribute xmlns:[lindex $att 0]]]
           56  +                    } else {
           57  +                        lappend attpairs [list \
           58  +                            [lindex $att 1]:[lindex $att 0] \
           59  +                            [$node getAttribute [lindex $att 1]:[lindex $att 0]]]
           60  +                    }
           61  +                } else {
           62  +                    lappend attpairs [list $att [$node getAttribute $att]]
           63  +                }
           64  +            }
           65  +            foreach {name value} [lsort -index 0 $attpairs] {
           66  +                append str $name $value
           67  +            }
           68  +            foreach child [$node childNodes] {
           69  +                append str [walkDOM $child]
           70  +            }
           71  +            append str /[$node nodeName]
           72  +        }
           73  +        "TEXT_NODE" {
           74  +            append str [$node nodeValue]
           75  +        }
           76  +        default {
           77  +            # Ignore anything else
           78  +        }
           79  +    }
           80  +    return $str
           81  +}
           82  +
           83  +proc loopPull {} {
           84  +    while {[set state [pp next]] ne "END_DOCUMENT"} {
           85  +        switch $state {
           86  +            "START_TAG" {
           87  +                append pullstr [pp tag]
           88  +                set attpairs [list]
           89  +                foreach {attname attvalue} [pp attributes] {
           90  +                    lappend attpairs [list $attname $attvalue]
           91  +                }
           92  +                foreach {name value} [lsort -index 0 $attpairs] {
           93  +                    append pullstr $name $value
           94  +                }
           95  +            }
           96  +            "TEXT" {
           97  +                append pullstr [pp text]
           98  +            }
           99  +            "END_TAG" {
          100  +                append pullstr /[pp tag]
          101  +            }
          102  +        }
          103  +    }
          104  +    return $pullstr
          105  +}
          106  +
          107  +proc comparewithDOM {data {inputMethod input}} {
          108  +    if {$inputMethod eq "input"} {
          109  +        dom parse $data doc
          110  +    } elseif {$inputMethod eq "inputchannel"} {
          111  +        dom parse -channel $data doc
          112  +    } else {
          113  +        dom parse -keepEmpties [::tdom::xmlReadFile $data] doc
          114  +    }
          115  +    set domstr [walkDOM [$doc documentElement]]
          116  +    $doc delete
          117  +    tdom::pullparser pp
          118  +    pp $inputMethod $data
          119  +    set pullstr [loopPull]
          120  +    if {$domstr eq $pullstr} {
          121  +        return 1
          122  +    } else {
          123  +        puts "*** DOM str:"
          124  +        puts $domstr
          125  +        puts "*** Pull str:"
          126  +        puts $pullstr
          127  +        return 0
          128  +    }
          129  +    pp delete
          130  +}
          131  +
          132  +proc fdata {file} {
          133  +    file join [file dir [info script]] data/$file
          134  +}
          135  +
          136  +test pp-2.1 {dom/pull comparsion: mondial-europe.xml} {
          137  +    comparewithDOM [fdata mondial-europe.xml] inputfile
          138  +} 1
          139  +
          140  +test pp-2.2 {dom/pull comparsion: books.xml} {
          141  +    comparewithDOM [fdata books.xml] inputfile
          142  +} 1
          143  +
          144  +test pp-2.3 {dom/pull comparsion: i18n_1.xml} {
          145  +    comparewithDOM [fdata i18n_1.xml] inputfile
          146  +} 1
          147  +
          148  +test pp-2.4 {dom/pull comparsion: i18n_2.xml} {
          149  +    comparewithDOM [fdata i18n_2.xml] inputfile
          150  +} 1
          151  +
          152  +test pp-2.5 {dom/pull comparsion: REC-xslt-19991116.xml} {
          153  +    comparewithDOM [fdata REC-xslt-19991116.xml] inputfile
          154  +} 1
          155  +
          156  +test pp-2.6 {dom/pull comparsion: xslt_1.xsl} {
          157  +    comparewithDOM [fdata xslt_1.xsl] inputfile
          158  +} 1
          159  +
          160  +test pp-2.7 {dom/pull comparsion} {
          161  +    comparewithDOM {<p>This specification defines the syntax and semantics of XSLT, which
          162  +is a language for transforming XML documents into other XML
          163  +        documents.</p>}
          164  +} 1
          165  +
          166  +test pp-2.8 {dom/pull comparsion} {
          167  +    comparewithDOM {<p><termdef> (see <specref/>), which is
          168  +referred to in </termdef></p>}
          169  +} 1
          170  +
          171  +test pp-2.9 {dom/pull comparsion} {
          172  +    comparewithDOM {<p>This specification defines the syntax and semantics of the XSLT
          173  +language.  A transformation in the XSLT language is expressed as a
          174  +well-formed XML document <bibref/>conforming </p>}
          175  +} 1
          176  +
          177  +
          178  +proc loopPullE {} {
          179  +    while {[set state [pullparser next]] ne "END_DOCUMENT"} {
          180  +        switch $state {
          181  +            "START_TAG" {
          182  +                append pullstr [pullparser tag]
          183  +                foreach {attname attvalue} [pullparser attributes] {
          184  +                    append pullstr $attname $attvalue
          185  +                }
          186  +            }
          187  +            "TEXT" {
          188  +                append pullstr [pullparser text]
          189  +            }
          190  +            "END_TAG" {
          191  +                append pullstr /[pullparser tag]
          192  +            }
          193  +        }
          194  +    }
          195  +    return $pullstr
          196  +}
          197  +
          198  +proc elementstart {name atts} {
          199  +    global expatstr
          200  +
          201  +    append expatstr $name
          202  +    foreach {attname attvalue} $atts {
          203  +        append expatstr $attname $attvalue
          204  +    }
          205  +}
          206  +
          207  +proc elementend {name} {
          208  +    global expatstr
          209  +
          210  +    append expatstr /$name
          211  +}
          212  +
          213  +proc cdata {cdata} {
          214  +    global expatstr
          215  +
          216  +    append expatstr $cdata
          217  +}
          218  +
          219  +proc comparewithExpat {data {inputMethod ""}} {
          220  +    global expatstr
          221  +
          222  +    set expatstr ""
          223  +    expat pushparser \
          224  +        -elementstartcommand elementstart \
          225  +        -elementendcommand elementend \
          226  +        -characterdatacommand cdata
          227  +    pushparser parse$inputMethod $data
          228  +    tdom::pullparser pullparser
          229  +    pullparser input$inputMethod $data
          230  +    set pullstr [loopPullE]
          231  +    if {$expatstr eq $pullstr} {
          232  +        return 1
          233  +    } else {
          234  +        puts $expatstr
          235  +        puts $pullstr
          236  +        return 0
          237  +    }
          238  +    pushparser free
          239  +    pullparser delete
          240  +}
          241  +
          242  +
          243  +test pp-2.10 {expat/pull comparsion: mondial-europe.xml} {
          244  +    comparewithExpat [fdata mondial-europe.xml] file
          245  +} 1
          246  +
          247  +test pp-2.11 {expat/pull comparsion: books.xml} {
          248  +    comparewithExpat [fdata books.xml] file
          249  +} 1
          250  +
          251  +test pp-2.12 {expat/pull comparsion: i18n_1.xml} {
          252  +    comparewithExpat [fdata i18n_1.xml] file
          253  +} 1
          254  +
          255  +test pp-2.13 {expat/pull comparsion: i18n_2.xml} {
          256  +    comparewithExpat [fdata i18n_2.xml] file
          257  +} 1
          258  +
          259  +test pp-2.14 {expat/pull comparsion: REC-xslt-19991116.xml} {
          260  +    comparewithExpat [fdata REC-xslt-19991116.xml] file
          261  +} 1
          262  +
          263  +test pp-2.15 {expat/pull comparsion: xslt_1.xsl} {
          264  +    comparewithExpat [fdata xslt_1.xsl] file
          265  +} 1
          266  +
          267  +test pp-2.16 {expat/pull comparsion} {
          268  +    comparewithExpat {<p>This specification defines the syntax and semantics of XSLT, which
          269  +is a language for transforming XML documents into other XML
          270  +        documents.</p>}
          271  +} 1
          272  +
          273  +test pp-2.17 {expat/pull comparsion} {
          274  +    comparewithExpat {<p><termdef> (see <specref/>), which is
          275  +referred to in </termdef></p>}
          276  +} 1
          277  +
          278  +test pp-2.18 {expat/pull comparsion} {
          279  +    comparewithExpat {<p>This specification defines the syntax and semantics of the XSLT
          280  +language.  A transformation in the XSLT language is expressed as a
          281  +well-formed XML document <bibref/>conforming </p>}
          282  +} 1
          283  +
          284  +test pp-3.1 {skip} {
          285  +    tdom::pullparser pp
          286  +    pp input <doc/>
          287  +    set result [pp next]
          288  +    lappend result [pp tag]
          289  +    lappend result [pp skip]
          290  +    lappend result [pp tag]
          291  +    lappend result [pp next]
          292  +    pp delete
          293  +    set result
          294  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          295  +
          296  +test pp-3.1.1 {skip} {
          297  +    tdom::pullparser pp
          298  +    pp input {<doc><e/></doc>}
          299  +    set result [pp next]
          300  +    lappend result [pp tag]
          301  +    lappend result [pp next]
          302  +    lappend result [pp tag]
          303  +    lappend result [pp skip]
          304  +    lappend result [pp tag]
          305  +    lappend result [pp next]
          306  +    lappend result [pp tag]
          307  +    lappend result [pp next]
          308  +    pp delete
          309  +    set result
          310  +} {START_TAG doc START_TAG e END_TAG e END_TAG doc END_DOCUMENT}
          311  +
          312  +test pp-3.1.2 {skip} {
          313  +    tdom::pullparser pp
          314  +    pp input {<doc>text<e/>text</doc>}
          315  +    set result [pp next]
          316  +    lappend result [pp tag]
          317  +    lappend result [pp next]
          318  +    lappend result [pp text]
          319  +    lappend result [pp next]
          320  +    lappend result [pp tag]
          321  +    lappend result [pp skip]
          322  +    lappend result [pp tag]
          323  +    lappend result [pp next]
          324  +    lappend result [pp text]
          325  +    lappend result [pp next]
          326  +    lappend result [pp tag]
          327  +    lappend result [pp next]
          328  +    pp delete
          329  +    set result
          330  +} {START_TAG doc TEXT text START_TAG e END_TAG e TEXT text END_TAG doc END_DOCUMENT}
          331  +
          332  +test pp-3.1.3 {skip} {
          333  +    tdom::pullparser pp
          334  +    pp input {<doc>text<e>bar<b><c/><c>baz</c></b><b>text</b></e>text</doc>}
          335  +    set result [pp next]
          336  +    lappend result [pp tag]
          337  +    lappend result [pp next]
          338  +    lappend result [pp text]
          339  +    lappend result [pp next]
          340  +    lappend result [pp tag]
          341  +    lappend result [pp skip]
          342  +    lappend result [pp tag]
          343  +    lappend result [pp next]
          344  +    lappend result [pp text]
          345  +    lappend result [pp next]
          346  +    lappend result [pp tag]
          347  +    lappend result [pp next]
          348  +    pp delete
          349  +    set result
          350  +} {START_TAG doc TEXT text START_TAG e END_TAG e TEXT text END_TAG doc END_DOCUMENT}
          351  +
          352  +test pp-3.1.4 {skip} {
          353  +    tdom::pullparser pp
          354  +    pp input <doc></doc>
          355  +    set result [pp next]
          356  +    lappend result [pp tag]
          357  +    lappend result [pp skip]
          358  +    lappend result [pp tag]
          359  +    lappend result [pp next]
          360  +    pp delete
          361  +    set result
          362  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          363  +
          364  +test pp-3.1.5 {skip} {
          365  +    tdom::pullparser pp
          366  +    pp input {<doc> </doc>}
          367  +    set result [pp next]
          368  +    lappend result [pp tag]
          369  +    lappend result [pp skip]
          370  +    lappend result [pp tag]
          371  +    lappend result [pp next]
          372  +    pp delete
          373  +    set result
          374  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          375  +
          376  +test pp-3.1.5 {skip} {
          377  +    tdom::pullparser pp -ignorewhitecdata
          378  +    pp input {<doc> </doc>}
          379  +    set result [pp next]
          380  +    lappend result [pp tag]
          381  +    lappend result [pp skip]
          382  +    lappend result [pp tag]
          383  +    lappend result [pp next]
          384  +    pp delete
          385  +    set result
          386  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          387  +
          388  +test pp-3.2 {skip} {
          389  +    tdom::pullparser pp
          390  +    pp input {<doc><e/></doc>}
          391  +    set result [pp next]
          392  +    lappend result [pp tag]
          393  +    lappend result [pp skip]
          394  +    lappend result [pp tag]
          395  +    lappend result [pp next]
          396  +    pp delete
          397  +    set result
          398  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          399  +
          400  +test pp-3.3 {skip} {
          401  +    tdom::pullparser pp
          402  +    pp input {<doc>foo bar<e/></doc>}
          403  +    set result [pp next]
          404  +    lappend result [pp tag]
          405  +    lappend result [pp skip]
          406  +    lappend result [pp tag]
          407  +    lappend result [pp next]
          408  +    pp delete
          409  +    set result
          410  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          411  +
          412  +test pp-3.4 {skip} {
          413  +    tdom::pullparser pp
          414  +    pp input {<doc>foo bar<e/><e>bar<e/></e><e></e></doc>}
          415  +    set result [pp next]
          416  +    lappend result [pp tag]
          417  +    lappend result [pp skip]
          418  +    lappend result [pp tag]
          419  +    lappend result [pp next]
          420  +    pp delete
          421  +    set result
          422  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          423  +
          424  +test pp-3.5 {skip} {
          425  +    tdom::pullparser pp
          426  +    pp input {<doc>foo bar<e/><e>bar<e/></e><e></e></doc>}
          427  +    set result [list]
          428  +    while {[set state [pp next]] ne "END_DOCUMENT"} {
          429  +        lappend result $state
          430  +        if {$state eq "START_TAG"} {
          431  +            lappend result [pp tag]
          432  +            if {[pp tag] eq "e"} {
          433  +                pp skip
          434  +                continue
          435  +            }
          436  +        }
          437  +        if {[pp state] eq "END_TAG"} {
          438  +            lappend result [pp tag]
          439  +        }
          440  +    }
          441  +    pp delete
          442  +    set result
          443  +} {START_TAG doc TEXT START_TAG e START_TAG e START_TAG e END_TAG doc}
          444  +
          445  +test pp-3.6 {skip} {
          446  +    tdom::pullparser pp
          447  +    pp input {<doc>foo bar<e/><e>bar<e/></e><e></e>baz</doc>}
          448  +    set result [list]
          449  +    while {[set state [pp next]] ne "END_DOCUMENT"} {
          450  +        lappend result $state
          451  +        if {$state eq "START_TAG"} {
          452  +            lappend result [pp tag]
          453  +            if {[pp tag] eq "e"} {
          454  +                pp skip
          455  +                continue
          456  +            }
          457  +        }
          458  +        if {[pp state] eq "END_TAG"} {
          459  +            lappend result [pp tag]
          460  +        }
          461  +        if {[pp state] eq "TEXT"} {
          462  +            lappend result [pp text]
          463  +        }
          464  +    }
          465  +    pp delete
          466  +    set result
          467  +} {START_TAG doc TEXT {foo bar} START_TAG e START_TAG e START_TAG e TEXT baz END_TAG doc}
          468  +
          469  +test pp-3.7 {skip} {
          470  +    tdom::pullparser pp
          471  +    pp input {<doc>foo bar<e/><e>bar</wrong><e></e></doc>}
          472  +    set result [pp next]
          473  +    lappend result [pp next]; # TEXT "foo bar"
          474  +    lappend result [pp next]; # START_TAG
          475  +    lappend result [pp tag];  # e
          476  +    lappend result [pp next]; # END_TAG
          477  +    lappend result [pp tag];  # e
          478  +    lappend result [pp next]; # START_TAG
          479  +    lappend result [pp tag];  # e
          480  +    lappend result [catch {pp skip} errMsg]
          481  +    lappend result $errMsg
          482  +    pp delete
          483  +    set result
          484  +} {START_TAG TEXT START_TAG e END_TAG e START_TAG e 1 {error "mismatched tag" at line 1 character 24}}
          485  +
          486  +test pp-3.8 {skip} {
          487  +    tdom::pullparser pp
          488  +    pp input {<doc>foo bar<e/><e>bar</e></doc>}
          489  +    set result [pp next]
          490  +    lappend result [pp skip]
          491  +    lappend result [pp tag]
          492  +    lappend result [pp next]
          493  +    lappend result [catch {pp next} errMsg]
          494  +    lappend result $errMsg
          495  +    pp delete
          496  +    set result
          497  +} {START_TAG END_TAG doc END_DOCUMENT 1 {No next event after END_DOCUMENT}}
          498  +
          499  +test pp-4.1 {find-element} {
          500  +    tdom::pullparser pp
          501  +    pp input {<doc><a>foo bar</a><b>baz</b><c>grill</c><d>here</d></doc>}
          502  +    set result [pp next]
          503  +    lappend result [pp tag]
          504  +    lappend result [pp next]
          505  +    lappend result [pp tag]
          506  +    lappend result [pp find-element d]
          507  +    lappend result [pp tag]
          508  +    lappend result [pp next]
          509  +    lappend result [pp text]
          510  +    lappend result [pp next]
          511  +    lappend result [pp tag]    
          512  +    while {[pp next] ne "END_DOCUMENT"} {}
          513  +    pp delete
          514  +    set result
          515  +} {START_TAG doc START_TAG a START_TAG d TEXT here END_TAG d}
          516  +
          517  +test pp-4.2 {find-element} {
          518  +    tdom::pullparser pp
          519  +    pp input {<doc><a>foo bar</a><b>baz</b><c>grill</c><d></d></doc>}
          520  +    set result [pp next]
          521  +    lappend result [pp tag]
          522  +    lappend result [pp next]
          523  +    lappend result [pp tag]
          524  +    lappend result [pp find-element d]
          525  +    lappend result [pp tag]
          526  +    lappend result [pp next]
          527  +    lappend result [pp tag]    
          528  +    while {[pp next] ne "END_DOCUMENT"} {}
          529  +    pp delete
          530  +    set result
          531  +} {START_TAG doc START_TAG a START_TAG d END_TAG d}
          532  +
          533  +test pp-4.3 {find-element} {
          534  +    tdom::pullparser pp
          535  +    pp input {<doc><a>foo bar</a><b>baz</b><c>grill</c>some<d/></doc>}
          536  +    set result [pp next]
          537  +    lappend result [pp tag]
          538  +    lappend result [pp next]
          539  +    lappend result [pp tag]
          540  +    lappend result [pp find-element d]
          541  +    lappend result [pp tag]
          542  +    lappend result [pp next]
          543  +    lappend result [pp tag]    
          544  +    while {[pp next] ne "END_DOCUMENT"} {}
          545  +    pp delete
          546  +    set result
          547  +} {START_TAG doc START_TAG a START_TAG d END_TAG d}
          548  +
          549  +test pp-4.4 {find-element} {
          550  +    tdom::pullparser pp
          551  +    pp input {<doc><a><b><c><d>grill</d></c></b></a></doc>}
          552  +    set result [pp next]
          553  +    lappend result [pp tag]
          554  +    lappend result [pp find-element d]
          555  +    lappend result [pp tag]
          556  +    lappend result [pp next]
          557  +    lappend result [pp text]
          558  +    lappend result [pp next]
          559  +    lappend result [pp tag]    
          560  +    lappend result [pp next]
          561  +    lappend result [pp tag]    
          562  +    while {[pp next] ne "END_DOCUMENT"} {}
          563  +    pp delete
          564  +    set result
          565  +} {START_TAG doc START_TAG d TEXT grill END_TAG d END_TAG c}
          566  +
          567  +test pp-4.5 {find-element} {
          568  +    tdom::pullparser pp
          569  +    pp input {<doc><a><b><c><d></d></c></b></a></doc>}
          570  +    set result [pp next]
          571  +    lappend result [pp tag]
          572  +    lappend result [pp find-element d]
          573  +    lappend result [pp tag]
          574  +    lappend result [pp next]
          575  +    lappend result [pp tag]    
          576  +    lappend result [pp next]
          577  +    lappend result [pp tag]    
          578  +    while {[pp next] ne "END_DOCUMENT"} {}
          579  +    pp delete
          580  +    set result
          581  +} {START_TAG doc START_TAG d END_TAG d END_TAG c}
          582  +
          583  +test pp-4.6 {find-element} {
          584  +    tdom::pullparser pp
          585  +    pp input {<doc><a><b><c><d/></c></b></a></doc>}
          586  +    set result [pp next]
          587  +    lappend result [pp tag]
          588  +    lappend result [pp find-element d]
          589  +    lappend result [pp tag]
          590  +    lappend result [pp next]
          591  +    lappend result [pp tag]    
          592  +    lappend result [pp next]
          593  +    lappend result [pp tag]    
          594  +    while {[pp next] ne "END_DOCUMENT"} {}
          595  +    pp delete
          596  +    set result
          597  +} {START_TAG doc START_TAG d END_TAG d END_TAG c}
          598  +
          599  +
          600  +test pp-4.7 {find-element} {
          601  +    tdom::pullparser pp
          602  +    pp input {<doc><a><b/></a><a><b><c/></b></a><a><b/></a></doc>}
          603  +    set result [pp next]
          604  +    lappend result [pp tag]
          605  +    lappend result [pp find-element b]
          606  +    lappend result [pp tag]
          607  +    lappend result [pp find-element c]
          608  +    lappend result [pp tag]
          609  +    lappend result [pp find-element a]
          610  +    lappend result [pp tag]
          611  +    while {[pp next] ne "END_DOCUMENT"} {}
          612  +    pp delete
          613  +    set result
          614  +} {START_TAG doc START_TAG b START_TAG c START_TAG a}
          615  +
          616  +test pp-4.8 {find-element} {
          617  +    tdom::pullparser pp
          618  +    pp input {<doc/>}
          619  +    set result [pp next]
          620  +    lappend result [pp tag]
          621  +    lappend result [pp next]
          622  +    lappend result [pp tag]
          623  +    lappend result [pp find-element b]
          624  +    pp delete
          625  +    set result
          626  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          627  +
          628  +test pp-4.8.1 {find-element} {
          629  +    tdom::pullparser pp
          630  +    pp input {<doc></doc>}
          631  +    set result [pp next]
          632  +    lappend result [pp tag]
          633  +    lappend result [pp next]
          634  +    lappend result [pp tag]
          635  +    lappend result [pp find-element b]
          636  +    pp delete
          637  +    set result
          638  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          639  +
          640  +test pp-4.8.2 {find-element} {
          641  +    tdom::pullparser pp
          642  +    pp input {<doc> </doc>}
          643  +    set result [pp next]
          644  +    lappend result [pp tag]
          645  +    lappend result [pp next]
          646  +    lappend result [pp next]
          647  +    lappend result [pp tag]
          648  +    lappend result [pp find-element b]
          649  +    pp delete
          650  +    set result
          651  +} {START_TAG doc TEXT END_TAG doc END_DOCUMENT}
          652  +
          653  +test pp-4.8.3 {find-element} {
          654  +    tdom::pullparser pp -ignorewhitecdata
          655  +    pp input {<doc> </doc>}
          656  +    set result [pp next]
          657  +    lappend result [pp tag]
          658  +    lappend result [pp next]
          659  +    lappend result [pp tag]
          660  +    lappend result [pp find-element b]
          661  +    pp delete
          662  +    set result
          663  +} {START_TAG doc END_TAG doc END_DOCUMENT}
          664  +
          665  +test pp-4.9 {find-element} {
          666  +    tdom::pullparser pp
          667  +    pp input {<doc><a><b/></a><a><b><c/></b></a><a><b/></a></doc>}
          668  +    set result [pp next]; # START_TAG
          669  +    lappend result [pp tag]; # doc
          670  +    lappend result [pp next]; # START_TAG
          671  +    lappend result [pp tag]; # a
          672  +    lappend result [pp find-element b]; # START_TAG
          673  +    lappend result [pp tag]; #b 
          674  +    lappend result [pp find-element c]; # START_TAG
          675  +    lappend result [pp tag]; #c
          676  +    lappend result [pp next]; # END_TAG
          677  +    lappend result [pp tag]; # c
          678  +    lappend result [pp find-element a]; # START_TAG
          679  +    lappend result [pp tag]; # a
          680  +    while {[pp next] ne "END_DOCUMENT"} {}
          681  +    pp delete
          682  +    set result
          683  +} {START_TAG doc START_TAG a START_TAG b START_TAG c END_TAG c START_TAG a}
          684  +
          685  +test pp-4.10 {find-element} {
          686  +    tdom::pullparser pp
          687  +    pp input {<doc>foo<a/>bar<b>grill<a/>baz</b></doc>}
          688  +    set result [pp next]; # START_TAG
          689  +    lappend result [pp tag]; # doc
          690  +    lappend result [pp find-element a]; # START_TAG
          691  +    lappend result [pp tag]; # a
          692  +    lappend result [pp next]; # END_TAG
          693  +    lappend result [pp tag]; # a
          694  +    lappend result [pp find-element a]; # START_TAG
          695  +    lappend result [pp tag]; #a 
          696  +    lappend result [pp next]; # END_TAG
          697  +    lappend result [pp tag]; # a 
          698  +    lappend result [pp next]; # TEXT 
          699  +    lappend result [pp text]; # baz 
          700  +    lappend result [pp next]; # END_TAG 
          701  +    lappend result [pp tag]; # b
          702  +    while {[pp next] ne "END_DOCUMENT"} {}
          703  +    pp delete
          704  +    set result
          705  +} {START_TAG doc START_TAG a END_TAG a START_TAG a END_TAG a TEXT baz END_TAG b}
          706  +
          707  +test pp-4.11 {find-element} {
          708  +    tdom::pullparser pp
          709  +    pp input {<doc>foo<a/>bar<b>grill<a/>baz</b></doc>}
          710  +    set result [pp state]
          711  +    lappend result [pp find-element a]; # START_TAG
          712  +    lappend result [pp tag]; # a
          713  +    lappend result [pp next]; # END_TAG
          714  +    lappend result [pp tag]; # a
          715  +    lappend result [pp find-element a]; # START_TAG
          716  +    lappend result [pp tag]; #a 
          717  +    lappend result [pp next]; # END_TAG
          718  +    lappend result [pp tag]; # a 
          719  +    lappend result [pp next]; # TEXT 
          720  +    lappend result [pp text]; # baz 
          721  +    lappend result [pp next]; # END_TAG 
          722  +    lappend result [pp tag]; # b
          723  +    while {[pp next] ne "END_DOCUMENT"} {}
          724  +    pp delete
          725  +    set result
          726  +} {START_DOCUMENT START_TAG a END_TAG a START_TAG a END_TAG a TEXT baz END_TAG b}
          727  +
          728  +test pp-4.12 {find-element} {
          729  +    tdom::pullparser pp
          730  +    pp input {<doc>foo<a/>bar<b>grill<a/>baz</b></doc>}
          731  +    set result [pp state]
          732  +    pp find-element a
          733  +    lappend result [pp find-element a]; # START_TAG
          734  +    lappend result [pp tag]; #a 
          735  +    lappend result [pp next]; # END_TAG
          736  +    lappend result [pp tag]; # a 
          737  +    lappend result [pp next]; # TEXT 
          738  +    lappend result [pp text]; # baz 
          739  +    lappend result [pp next]; # END_TAG 
          740  +    lappend result [pp tag]; # b
          741  +    while {[pp next] ne "END_DOCUMENT"} {}
          742  +    pp delete
          743  +    set result
          744  +} {START_DOCUMENT START_TAG a END_TAG a TEXT baz END_TAG b}
          745  +
          746  +test pp-4.13 {find-element} {
          747  +    tdom::pullparser pp
          748  +    pp input {<doc/>}
          749  +    set result [pp state]
          750  +    lappend result [pp find-element a]
          751  +    pp delete
          752  +    set result
          753  +} {START_DOCUMENT END_DOCUMENT}    
          754  +
          755  +test pp-4.14 {find-element} {
          756  +    tdom::pullparser pp
          757  +    pp input {<doc>foo bar<e/><e>bar</e></doc>}
          758  +    set result [pp next]
          759  +    lappend result [pp skip]
          760  +    lappend result [pp tag]
          761  +    lappend result [pp find-element b]
          762  +    lappend result [catch {pp next} errMsg]
          763  +    lappend result $errMsg
          764  +    pp delete
          765  +    set result
          766  +} {START_TAG END_TAG doc END_DOCUMENT 1 {No next event after END_DOCUMENT}}
          767  +    
          768  +test pp-5.1 {CDATA section} {
          769  +    tdom::pullparser pp
          770  +    pp input {<doc><![CDATA[ some text  ]]></doc>}
          771  +    set result [pp state]
          772  +    lappend result [pp next]
          773  +    lappend result [pp tag]
          774  +    lappend result [pp next]
          775  +    lappend result [pp text]
          776  +    lappend result [pp next]
          777  +    lappend result [pp tag]
          778  +    lappend result [pp next]
          779  +    
          780  +    pp delete
          781  +    set result
          782  +} {START_DOCUMENT START_TAG doc TEXT { some text  } END_TAG doc END_DOCUMENT}
          783  +
          784  +test pp-5.2 {CDATA section inside of text} {
          785  +    tdom::pullparser pp
          786  +    pp input {<doc>before<![CDATA[ some text  ]]>after</doc>}
          787  +    set result [pp state]
          788  +    lappend result [pp next]
          789  +    lappend result [pp tag]
          790  +    lappend result [pp next]
          791  +    lappend result [pp text]
          792  +    lappend result [pp next]
          793  +    lappend result [pp tag]
          794  +    lappend result [pp next]
          795  +    
          796  +    pp delete
          797  +    set result
          798  +} {START_DOCUMENT START_TAG doc TEXT {before some text  after} END_TAG doc END_DOCUMENT}
          799  +
          800  +test pp-5.3 {CDATA section after text} {
          801  +    tdom::pullparser pp
          802  +    pp input {<doc>before<![CDATA[ some text  ]]></doc>}
          803  +    set result [pp state]
          804  +    lappend result [pp next]
          805  +    lappend result [pp tag]
          806  +    lappend result [pp next]
          807  +    lappend result [pp text]
          808  +    lappend result [pp next]
          809  +    lappend result [pp tag]
          810  +    lappend result [pp next]
          811  +    
          812  +    pp delete
          813  +    set result
          814  +} {START_DOCUMENT START_TAG doc TEXT {before some text  } END_TAG doc END_DOCUMENT}
          815  +
          816  +test pp-5.4 {CDATA section before text} {
          817  +    tdom::pullparser pp
          818  +    pp input {<doc><![CDATA[ some text  ]]>after</doc>}
          819  +    set result [pp state]
          820  +    lappend result [pp next]
          821  +    lappend result [pp tag]
          822  +    lappend result [pp next]
          823  +    lappend result [pp text]
          824  +    lappend result [pp next]
          825  +    lappend result [pp tag]
          826  +    lappend result [pp next]
          827  +    
          828  +    pp delete
          829  +    set result
          830  +} {START_DOCUMENT START_TAG doc TEXT { some text  after} END_TAG doc END_DOCUMENT}
          831  +
          832  +test pp-5.5 {White space only CDATA section inside text} {
          833  +    tdom::pullparser pp
          834  +    pp input {<doc>before <![CDATA[  ]]> after</doc>}
          835  +    set result [pp state]
          836  +    lappend result [pp next]
          837  +    lappend result [pp tag]
          838  +    lappend result [pp next]
          839  +    lappend result [pp text]
          840  +    lappend result [pp next]
          841  +    lappend result [pp tag]
          842  +    lappend result [pp next]
          843  +    
          844  +    pp delete
          845  +    set result
          846  +} {START_DOCUMENT START_TAG doc TEXT {before    after} END_TAG doc END_DOCUMENT}
          847  +
          848  +test pp-5.6 {White space only CDATA section inside text with -ignorewhitecdata} {
          849  +    tdom::pullparser pp -ignorewhitecdata
          850  +    pp input {<doc>before <![CDATA[  ]]> after</doc>}
          851  +    set result [pp state]
          852  +    lappend result [pp next]
          853  +    lappend result [pp tag]
          854  +    lappend result [pp next]
          855  +    lappend result [pp text]
          856  +    lappend result [pp next]
          857  +    lappend result [pp tag]
          858  +    lappend result [pp next]
          859  +    
          860  +    pp delete
          861  +    set result
          862  +} {START_DOCUMENT START_TAG doc TEXT {before    after} END_TAG doc END_DOCUMENT}
          863  +
          864  +test pp-5.6 {White space only CDATA section inside text with -ignorewhitecdata} {
          865  +    tdom::pullparser pp -ignorewhitecdata
          866  +    pp input {<doc>before <![CDATA[  ]]> after</doc>}
          867  +    set result [pp state]
          868  +    lappend result [pp next]
          869  +    lappend result [pp tag]
          870  +    lappend result [pp next]
          871  +    lappend result [pp text]
          872  +    lappend result [pp next]
          873  +    lappend result [pp tag]
          874  +    lappend result [pp next]
          875  +    
          876  +    pp delete
          877  +    set result
          878  +} {START_DOCUMENT START_TAG doc TEXT {before    after} END_TAG doc END_DOCUMENT}
          879  +
          880  +test pp-5.7 {White space only CDATA section inside white space only text w/ -ignorewhitecdata} {
          881  +    tdom::pullparser pp -ignorewhitecdata
          882  +    pp input {<doc> <![CDATA[  ]]>
          883  +        </doc>}
          884  +    set result [pp state]
          885  +    lappend result [pp next]
          886  +    lappend result [pp tag]
          887  +    lappend result [pp next]
          888  +    lappend result [pp tag]
          889  +    lappend result [pp next]
          890  +    
          891  +    pp delete
          892  +    set result
          893  +} {START_DOCUMENT START_TAG doc END_TAG doc END_DOCUMENT}
          894  +
          895  +test pp-5.8 {White space only CDATA section before text w/ -ignorewhitecdata} {
          896  +    tdom::pullparser pp -ignorewhitecdata
          897  +    pp input {<doc> <![CDATA[  ]]> after</doc>}
          898  +    set result [pp state]
          899  +    lappend result [pp next]
          900  +    lappend result [pp tag]
          901  +    lappend result [pp next]
          902  +    lappend result [pp text]
          903  +    lappend result [pp next]
          904  +    lappend result [pp tag]
          905  +    lappend result [pp next]
          906  +    
          907  +    pp delete
          908  +    set result
          909  +} {START_DOCUMENT START_TAG doc TEXT {    after} END_TAG doc END_DOCUMENT}
          910  +
          911  +test pp-5.9 {Successive CDATA sections} {
          912  +    tdom::pullparser pp
          913  +    pp input {<doc> <![CDATA[one]]><![CDATA[two]]><![CDATA[  ]]> after</doc>}
          914  +    set result [pp state]
          915  +    lappend result [pp next]
          916  +    lappend result [pp tag]
          917  +    lappend result [pp next]
          918  +    lappend result [pp text]
          919  +    lappend result [pp next]
          920  +    lappend result [pp tag]
          921  +    lappend result [pp next]
          922  +    
          923  +    pp delete
          924  +    set result
          925  +} {START_DOCUMENT START_TAG doc TEXT { onetwo   after} END_TAG doc END_DOCUMENT}
          926  +
          927  +test pp-6.1 {line} {
          928  +    tdom::pullparser pp
          929  +    set result [catch {pp line}]
          930  +    pp input {<doc> <![CDATA[one]]><![CDATA[two]]><![CDATA[  ]]> after</doc>}
          931  +    lappend result [pp line]
          932  +    lappend result [pp next]
          933  +    lappend result [pp tag]
          934  +    lappend result [pp line]
          935  +    lappend result [pp next]
          936  +    lappend result [pp text]
          937  +    lappend result [pp next]
          938  +    lappend result [pp tag]
          939  +    lappend result [pp line]
          940  +    lappend result [pp next]
          941  +    lappend result [pp line]
          942  +    pp delete
          943  +    set result
          944  +} {1 0 START_TAG doc 1 TEXT { onetwo   after} END_TAG doc 1 END_DOCUMENT 1}
          945  +
          946  +test pp-6.2 {column} {
          947  +    tdom::pullparser pp
          948  +    set result [catch {pp column}]
          949  +    pp input {<doc> <![CDATA[one]]><![CDATA[two]]><![CDATA[  ]]> after</doc>}
          950  +    lappend result [pp column]
          951  +    lappend result [pp next]
          952  +    lappend result [pp tag]
          953  +    lappend result [pp column]
          954  +    lappend result [pp next]
          955  +    lappend result [pp text]
          956  +    lappend result [pp next]
          957  +    lappend result [pp tag]
          958  +    lappend result [pp column]
          959  +    lappend result [pp next]
          960  +    lappend result [pp column]
          961  +    pp delete
          962  +    set result
          963  +} {1 0 START_TAG doc 5 TEXT { onetwo   after} END_TAG doc 62 END_DOCUMENT 62}
          964  +
          965  +test pp-6.3 {column} {
          966  +    tdom::pullparser pp
          967  +    pp input {<doc>foo<b>bar</b>grill</doc>}
          968  +    set result [list]
          969  +    while {[pp next] ne "END_DOCUMENT"} {
          970  +        if {[pp state] eq "TEXT"} {
          971  +            lappend result [pp text]
          972  +        } else {
          973  +            lappend result [pp tag]
          974  +            lappend result [pp column]
          975  +        }
          976  +    }
          977  +    pp delete
          978  +    set result
          979  +} {doc 5 foo b 11 bar b 18 grill doc 29}
          980  +
          981  +test pp-6.4 {line/column} {
          982  +    tdom::pullparser pp
          983  +    pp input {<doc>foo
          984  +<b>bar
          985  +</b>grill</doc>}
          986  +    set result [list]
          987  +    while {[pp next] ne "END_DOCUMENT"} {
          988  +        if {[pp state] eq "TEXT"} {
          989  +            lappend result [pp text]
          990  +        } else {
          991  +            lappend result [pp tag]
          992  +            lappend result [pp line]/[pp column]
          993  +        }
          994  +    }
          995  +    pp delete
          996  +    set result
          997  +} {doc 1/5 {foo
          998  +} b 2/3 {bar
          999  +} b 3/4 grill doc 3/15}
         1000  +
         1001  +test pp-6.5 {column} {
         1002  +    tdom::pullparser pp
         1003  +    pp input {<doc att="attvalue">foo<b att="boo">bar</b>grill</doc>}
         1004  +    set result [list]
         1005  +    while {[pp next] ne "END_DOCUMENT"} {
         1006  +        if {[pp state] eq "TEXT"} {
         1007  +            lappend result [pp text]
         1008  +        } else {
         1009  +            lappend result [pp tag]
         1010  +            lappend result [pp column]
         1011  +        }
         1012  +    }
         1013  +    lappend result [pp column]
         1014  +    pp delete
         1015  +    set result
         1016  +} {doc 20 foo b 36 bar b 43 grill doc 54 54}
         1017  +
         1018  +test pp-6.6 {line/column after parsing error} {
         1019  +    tdom::pullparser pp
         1020  +    pp input {<doc>an
         1021  +        < xml error </doc>}
         1022  +    pp next
         1023  +    set result [catch {pp skip}]
         1024  +    lappend result [pp line]/[pp column]
         1025  +    pp delete
         1026  +    set result
         1027  +} {1 2/9}

Added tests/pushpull.bench.

            1  +# -*- tcl -*-
            2  +#
            3  +# This file contains a number of benchmarks for push (expat) and pull
            4  +# (tdom::pullparser) parser.
            5  +#
            6  +# (c) 2018 Rolf Ade <rolf@pointsman.de>
            7  +#
            8  +
            9  +
           10  +# ### ### ### ######### ######### ######### ###########################
           11  +## Setting up the environment ...
           12  +
           13  +package require tdom 
           14  +
           15  +# ### ### ### ######### ######### ######### ###########################
           16  +## Benchmarks.
           17  +
           18  +
           19  +proc loopPullE {} {
           20  +    while {[set state [pullparser next]] ne "END_DOCUMENT"} {
           21  +        switch $state {
           22  +            "START_TAG" {
           23  +                append pullstr [pullparser tag]
           24  +                foreach {attname attvalue} [pullparser attributes] {
           25  +                    append pullstr $attname $attvalue
           26  +                }
           27  +            }
           28  +            "TEXT" {
           29  +                append pullstr [pullparser text]
           30  +            }
           31  +            "END_TAG" {
           32  +                append pullstr /[pullparser tag]
           33  +            }
           34  +        }
           35  +    }
           36  +    return $pullstr
           37  +}
           38  +
           39  +expat pushparserCanonical \
           40  +    -elementstartcommand elementstart \
           41  +    -elementendcommand elementend \
           42  +    -characterdatacommand cdata
           43  +
           44  +
           45  +proc elementstart {name atts} {
           46  +    global expatstr
           47  +
           48  +    append expatstr $name
           49  +    foreach {attname attvalue} $atts {
           50  +        append expatstr $attname $attvalue
           51  +    }
           52  +}
           53  +
           54  +proc elementend {name} {
           55  +    global expatstr
           56  +
           57  +    append expatstr /$name
           58  +}
           59  +
           60  +proc cdata {cdata} {
           61  +    global expatstr
           62  +
           63  +    append expatstr $cdata
           64  +}
           65  +
           66  +expat pushparserTricky \
           67  +    -elementstartcommand elementstart \
           68  +    -elementendcommand elementend \
           69  +    -characterdatacommand cdata
           70  +
           71  +
           72  +proc dopull {} {
           73  +    while {[set state [pullparser next]] ne "END_DOCUMENT"} {
           74  +        switch $state {
           75  +            "START_TAG" {
           76  +                append pullstr [pullparser tag]
           77  +                foreach {attname attvalue} [pullparser attributes] {
           78  +                    append pullstr $attname $attvalue
           79  +                }
           80  +            }
           81  +            "TEXT" {
           82  +                append pullstr [pullparser text]
           83  +            }
           84  +            "END_TAG" {
           85  +                append pullstr /[pullparser tag]
           86  +            }
           87  +        }
           88  +    }
           89  +    return $pullstr
           90  +}
           91  +bench -desc "push/canonical mondial-europe.xml" -iters 5 -body {
           92  +    set expatstr ""
           93  +    pushparserCanonical parsefile ../tests/data/mondial-europe.xml
           94  +    pushparserCanonical reset
           95  +} -post {
           96  +    pushparserCanonical free
           97  +}
           98  +
           99  +bench -desc "push/tricky mondial-europe.xml" -iters 5 -body {
          100  +    set expatstr ""
          101  +    pushparserTricky parsefile ../tests/data/mondial-europe.xml
          102  +    pushparserTricky reset
          103  +} -post {
          104  +    pushparserTricky free
          105  +}
          106  +
          107  +tdom::pullparser pullparser
          108  +
          109  +bench -desc "pull mondial-europe.xml" -iters 5 -body {
          110  +    pullparser inputfile ../tests/data/mondial-europe.xml
          111  +    dopull
          112  +    pullparser reset
          113  +} -post {
          114  +    pullparser delete
          115  +}

Changes to tests/stackedhdl.test.

    29     29   proc CDataHandler {data} {
    30     30       if {![info exists ::cdata]} {
    31     31           set ::cdata [string length $data]
    32     32       } else {
    33     33           incr ::cdata [string length $data]
    34     34       }
    35     35   }
           36  +
           37  +catch {unset started}
           38  +proc Start {name atList} {
           39  +    array set atts $atList
           40  +
           41  +    if {![info exists ::started($name)]} {
           42  +	set ::started($name) 1
           43  +    } else {
           44  +	incr ::started($name)
           45  +    }
           46  +    if {[info exists atts(class)]} {
           47  +	switch $atts(class) {
           48  +	    continue {
           49  +		return -code continue
           50  +	    }
           51  +	    break {
           52  +		return -code break
           53  +	    }
           54  +	    error {
           55  +		return -code error "error condition in callback"
           56  +	    }
           57  +            return {
           58  +                return -code return
           59  +            }
           60  +	    default {
           61  +		return -code $atts(class) 
           62  +	    }
           63  +	}
           64  +    }
           65  +}
    36     66   
    37     67   test stackedhdl-1.1 {two handlers for element start} {
    38     68       catch {unset ::count} 
    39     69       catch {unset ::charcount}
    40     70       set p [expat -elementstartcommand Count \
    41     71                    -handlerset charcount -elementstartcommand CharCount]
    42     72       $p parse {<root><a/><a></a></root>}
................................................................................
    80    110       $p configure -elementstartcommand Count -elementendcommand Count
    81    111       $p configure -handlerset charcount -elementstartcommand CharCount \
    82    112                    -elementendcommand CharCount
    83    113       $p parse {<root><a/><a></a></root>}
    84    114       list $::count $::charcount
    85    115   } {6 12}
    86    116   
    87         -test stackedhdl-1.6 {two handlers for element start} {
    88         -    catch {unset ::count} 
    89         -    catch {unset ::charcount}
    90         -    set p [expat]
    91         -    $p configure -handlerset charcount -elementstartcommand CharCount \
    92         -                 -elementendcommand CharCount
    93         -    $p configure -elementstartcommand Count -elementendcommand Count
    94         -    $p parse {<root><a/><a></a></root>}
    95         -    list $::count $::charcount
    96         -} {6 12}
    97         -
    98    117   test stackedhdl-1.6 {two handlers for element start} {
    99    118       catch {unset ::count} 
   100    119       catch {unset ::charcount}
   101    120       set p [expat]
   102    121       $p configure -handlerset charcount -elementstartcommand CharCount \
   103    122                    -elementendcommand CharCount
   104    123       $p configure -elementstartcommand Count -elementendcommand Count
................................................................................
   170    189       $p free
   171    190       set root [$doc documentElement]
   172    191       set result [list $::count [llength [$root childNodes]]]
   173    192       $doc delete
   174    193       set result
   175    194   } {3 2}
   176    195   
          196  +test stackedhdl-2.3 {return -code return with tcl and C coded handler} -setup {
          197  +    catch {unset started}
          198  +} -body {
          199  +    set p [expat -elementstartcommand Start]
          200  +    tdom $p enable
          201  +    set resultcode [catch {$p parse {<doc><e/><e class="return"/><e/></doc>}}]
          202  +    set result [list $resultcode $::started(e) [[tdom $p getdoc] asXML -indent none]]
          203  +    $p free
          204  +    set result
          205  +} -result {0 2 {<doc><e/><e class="return"/></doc>}}
          206  +
          207  +test stackedhdl-2.4 {return -code error with tcl and C coded handler} -setup {
          208  +    catch {unset started}
          209  +} -body {
          210  +    set p [expat -elementstartcommand Start]
          211  +    tdom $p enable
          212  +    set resultcode [catch {$p parse {<doc><e/><e class="error"/><e/></doc>}} msg]
          213  +    set result [list $resultcode $msg $::started(e) [[tdom $p getdoc] asXML -indent none]]
          214  +    $p free
          215  +    set result
          216  +} -result {1 {error condition in callback} 2 {<doc><e/><e class="error"/></doc>}}
          217  +
          218  +test stackedhdl-2.5 {return -code return with tcl and C coded handler} -setup {
          219  +    catch {unset started}
          220  +} -body {
          221  +    set p [expat -elementstartcommand Start]
          222  +    tdom $p enable
          223  +    set resultcode [catch {$p parse {<doc><e/><e class="return"/><e/></doc>}}]
          224  +    set result [list $resultcode $::started(e) [[tdom $p getdoc] asXML -indent none]]
          225  +    $p reset
          226  +    catch {unset started}
          227  +    set resultcode [catch {$p parse {<doc><e/><e/><e/></doc>}}]
          228  +    lappend result $resultcode $::started(e) [[tdom $p getdoc] asXML -indent none]
          229  +    $p free
          230  +    set result
          231  +} -result {0 2 {<doc><e/><e class="return"/></doc>} 0 3 <doc><e/><e/><e/></doc>}
          232  +
          233  +test stackedhdl-2.6 {return -code error with tcl and C coded handler} -setup {
          234  +    catch {unset started}
          235  +} -body {
          236  +    set p [expat -elementstartcommand Start]
          237  +    tdom $p enable
          238  +    set resultcode [catch {$p parse {<doc><e/><e class="error"/><e/></doc>}} msg]
          239  +    set result [list $resultcode $msg $::started(e) [[tdom $p getdoc] asXML -indent none]]
          240  +    $p reset
          241  +    catch {unset started}
          242  +    set resultcode [catch {$p parse {<doc><e/><e/><e/></doc>}}]
          243  +    lappend result $resultcode $::started(e) [[tdom $p getdoc] asXML -indent none]
          244  +    $p free
          245  +    set result
          246  +} -result {1 {error condition in callback} 2 {<doc><e/><e class="error"/></doc>} 0 3 <doc><e/><e/><e/></doc>}
          247  +
   177    248   test stackedhdl-3.1 {don't request the DOM tree from a tdom enabled parser} {
   178    249       set p [expat]
   179    250       tdom $p enable
   180    251       $p parse {<root><a/><a>boo</a></root>}
   181    252       $p free
   182    253   } {}
   183    254   

Added tests/tdomcmd.bench.

            1  +# -*- tcl -*-
            2  +#
            3  +# This file contains benchmarks for DOM doc creation with dom and tdom
            4  +#
            5  +# (c) 2018 Rolf Ade <rolf@pointsman.de>
            6  +#
            7  +
            8  +
            9  +# ### ### ### ######### ######### ######### ###########################
           10  +## Setting up the environment ...
           11  +
           12  +package require tdom 
           13  +
           14  +# ### ### ### ######### ######### ######### ###########################
           15  +## Benchmarks.
           16  +
           17  +
           18  +bench -desc "dom mondial-europe.xml" -iters 20 -ipre {
           19  +    set fd [open ../tests/data/mondial-europe.xml]
           20  +} -body {
           21  +    set doc [dom parse -channel $fd]
           22  +} -ipost {
           23  +    close $fd
           24  +    $doc delete
           25  +}
           26  +
           27  +bench -desc "tdom mondial-europe.xml" -iters 20 -ipre {
           28  +    set p [expat]
           29  +    tdom $p enable
           30  +} -body {
           31  +    $p parsefile ../tests/data/mondial-europe.xml
           32  +    set doc [tdom $p getdoc]
           33  +} -ipost {
           34  +    $doc delete
           35  +    $p free
           36  +}
           37  +
           38  +bench -desc "tdom mondial-europe.xml / reuse parser" -iters 20 -pre {
           39  +    set p [expat]
           40  +    tdom $p enable
           41  +} -body {
           42  +    $p parsefile ../tests/data/mondial-europe.xml
           43  +    set doc [tdom $p getdoc]
           44  +} -ipost {
           45  +    $doc delete
           46  +    $p reset
           47  +} -post {
           48  +    $p free
           49  +}
           50  +
           51  +bench -desc "dom REC-xslt-19991116.xml" -iters 20 -ipre {
           52  +    set fd [open ../tests/data/REC-xslt-19991116.xml]
           53  +} -body {
           54  +    set doc [dom parse -channel $fd]
           55  +} -ipost {
           56  +    close $fd
           57  +    $doc delete
           58  +}
           59  +
           60  +bench -desc "tdom REC-xslt-19991116.xml" -iters 20 -ipre {
           61  +    set p [expat]
           62  +    tdom $p enable
           63  +} -body {
           64  +    $p parsefile ../tests/data/REC-xslt-19991116.xml
           65  +    set doc [tdom $p getdoc]
           66  +} -ipost {
           67  +    $doc delete
           68  +    $p free
           69  +}
           70  +
           71  +bench -desc "tdom REC-xslt-19991116.xml / reuse parser" -iters 20 -pre {
           72  +    set p [expat]
           73  +    tdom $p enable
           74  +} -body {
           75  +    $p parsefile ../tests/data/REC-xslt-19991116.xml
           76  +    set doc [tdom $p getdoc]
           77  +} -ipost {
           78  +    $doc delete
           79  +    $p reset
           80  +} -post {
           81  +    $p free
           82  +}
           83  +
           84  +if {![catch {package require tnc}]} {
           85  +
           86  +    proc extresolver {base systemId publicId} {
           87  +        switch $publicId {
           88  +            "-//W3C//DTD Specification V2.0//EN" {
           89  +                set fd [open [file join [file dir [info script]] \
           90  +                                  data/xmlspec-v20.dtd]]
           91  +                set xmlspec [read $fd]
           92  +                close $fd
           93  +                return [list "string" "" $xmlspec]
           94  +            }
           95  +            default {
           96  +                puts stderr "Unexpected systemId '$systemId'"
           97  +                return ""
           98  +            }
           99  +        }
          100  +    }
          101  +    
          102  +    bench -desc "tdom REC-xslt-19991116.xml / tnc " -iters 20 -ipre {
          103  +        set p [expat -externalentitycommand extresolver \
          104  +                   -paramentityparsing always]
          105  +        tdom $p enable
          106  +        tnc $p enable
          107  +    } -body {
          108  +        $p parsefile ../tests/data/REC-xslt-19991116.xml
          109  +        set doc [tdom $p getdoc]
          110  +    } -ipost {
          111  +        $doc delete
          112  +        $p free
          113  +    }
          114  +
          115  +
          116  +    bench -desc "tdom REC-xslt-19991116.xml / tnc / reuse parse" -iters 20 -pre {
          117  +        set p [expat -externalentitycommand extresolver \
          118  +                   -paramentityparsing always]
          119  +        tdom $p enable
          120  +        tnc $p enable
          121  +    } -body {
          122  +        $p parsefile ../tests/data/REC-xslt-19991116.xml
          123  +        set doc [tdom $p getdoc]
          124  +    } -ipost {
          125  +        $doc delete
          126  +        $p reset
          127  +        $p configure -paramentityparsing always
          128  +    } -post {
          129  +        $p free
          130  +    }
          131  +}

Changes to tests/tdomcmd.test.

    36     36                           incr x
    37     37                           set data [lindex $args $x]
    38     38                           set haveData 1
    39     39                       }
    40     40                       "-keepEmpties" {
    41     41                           tdom $::_main_parser keepEmpties 1
    42     42                       }
           43  +                    "-keepCDATA" {
           44  +                        tdom $::_main_parser keepCDATA 1
           45  +                    }
    43     46                       "-baseurl" {
    44     47                           incr x
    45     48                           $::_main_parser configure -baseurl [lindex $args $x]
    46     49                       }
    47     50                       "-externalentitycommand" {
    48     51                           incr x
    49     52                           $::_main_parser configure -externalentitycommand \
................................................................................
    99    102   # source [file join [file dir [info script]] xslt.test]
   100    103   
   101    104   rename dom {}
   102    105   rename _dom dom
   103    106   
   104    107   $_main_parser free
   105    108   
   106         -test tdomcmd-1.1 {no doc avaliable} {
          109  +test tdomcmd-1.1 {no doc available} {
   107    110       set parser [expat]
   108    111       tdom $parser enable
   109    112       set result [catch {tdom $parser getdoc} errMsg]
   110    113       $parser free
   111    114       lappend result $errMsg
   112         -} {1 {No DOM tree avaliable.}}
          115  +} {1 {No DOM tree available.}}
   113    116   
   114    117   test tdomcmd-1.2 {request dom tree in the middle of parsing} {
   115    118       set parser [expat -final 0]
   116    119       tdom $parser enable
   117    120       $parser parse {<root>}
   118    121       set result [catch {tdom $parser getdoc} errMsg]
   119    122       lappend result $errMsg
................................................................................
   122    125       lappend result $errMsg
   123    126       $parser configure -final 1
   124    127       $parser parse {}
   125    128       lappend result [catch {set doc [tdom $parser getdoc]} errMsg]
   126    129       $doc delete
   127    130       $parser free
   128    131       set result
   129         -} {1 {No DOM tree avaliable.} 1 {No DOM tree avaliable.} 0}
          132  +} {1 {No DOM tree available.} 1 {No DOM tree available.} 0}
          133  +
          134  +proc es-tdomcmd-1.3 {parser name attlist} {
          135  +    tdom $parser enable
          136  +}
          137  +
          138  +test tdomcmd-1.3 {Try to tdom enable a parser from its parsing callback} {
          139  +    set p [expat]
          140  +    $p configure -elementstartcommand [list es-tdomcmd-1.3 $p]
          141  +    set result [catch {$p parse {<x><y/></x>}}]
          142  +    $p free
          143  +    set result
          144  +} {1}
          145  +    
          146  +test tdomcmd-1.4 {keepCDATA} {
          147  +    set parser [expat]
          148  +    set result [catch {tdom $parser keepCDATA 1}]
          149  +    $parser free
          150  +    set result
          151  +} 1
   130    152   
   131    153   # cleanup
   132    154   ::tcltest::cleanupTests
   133    155   return

Changes to tests/xmlsimple.test.

    84     84   } 1
    85     85   
    86     86   test simple-1.11 {simple doesn't catch all not wellformed input} {
    87     87        catch {dom parse -simple {<xsl:transform 
    88     88            xmlns:xsl="http://www.w3.org/1999/XSL/Transform
    89     89                       <http://www.w3.org/1999/XSL/Transform> "/>}}
    90     90   } 0
           91  +
           92  +test simple-1.12 {CDATA section} {
           93  +    set doc [dom parse -simple {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
           94  +    set result [$doc selectNodes count(doc/node())]
           95  +    $doc delete
           96  +    set result
           97  +} 1
           98  +
           99  +test simple-1.13 {CDATA section} {
          100  +    set doc [dom parse -simple {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
          101  +    set root [$doc documentElement]
          102  +    set result [list]
          103  +    foreach child [$root childNodes] {
          104  +        lappend result [$child nodeType]
          105  +    }
          106  +    $doc delete
          107  +    set result
          108  +} {TEXT_NODE}
          109  +
          110  +test simple-1.14 {CDATA section} {
          111  +    set doc [dom parse -simple {<doc>&lt;foo &amp; &gt;<![CDATA[test of & <bad> format]]>&apos; bar &quot;</doc>}]
          112  +    set result [$doc selectNodes string(doc)]
          113  +    $doc delete
          114  +    set result
          115  +} {<foo & >test of & <bad> format' bar "}
          116  +# emacs: "
          117  +
          118  +test simple-1.15 {-keepCDATA} {
          119  +    set doc [dom parse -simple -keepCDATA {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
          120  +    set result [$doc asXML -indent none]
          121  +    $doc delete
          122  +    set result
          123  +} {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}
          124  +
          125  +test simple-1.16 {-keepCDATA} {
          126  +    set doc [dom parse -simple -keepCDATA {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
          127  +    set root [$doc documentElement]
          128  +    set result [list]
          129  +    foreach child [$root childNodes] {
          130  +        lappend result [$child nodeType]
          131  +    }
          132  +    $doc delete
          133  +    set result
          134  +} {TEXT_NODE CDATA_SECTION_NODE TEXT_NODE}
          135  +
          136  +test simple-1.17 {-keepCDATA} {
          137  +    set doc [dom parse -simple -keepCDATA {<doc><e><![CDATA[one]]></e></doc>}]
          138  +    set result [list]
          139  +    foreach child [$doc selectNodes doc/e/node()] {
          140  +        lappend result [$child nodeType]
          141  +    }
          142  +    $doc delete
          143  +    set result
          144  +} {CDATA_SECTION_NODE}
          145  +
          146  +test simple-1.18 {-keepCDATA} {
          147  +    set doc [dom parse -simple -keepCDATA {<doc><e><![CDATA[one]]><![CDATA[two]]></e></doc>}]
          148  +    set result [list]
          149  +    foreach child [$doc selectNodes doc/e/node()] {
          150  +        lappend result [$child nodeType]
          151  +    }
          152  +    $doc delete
          153  +    set result
          154  +} {CDATA_SECTION_NODE CDATA_SECTION_NODE}
          155  +
          156  +test simple-1.19 {-keepCDATA} {
          157  +    set doc [dom parse -simple -keepCDATA {<doc><e><![CDATA[]]></e></doc>}]
          158  +    set result [$doc selectNodes count(doc/e/node())]
          159  +    $doc delete
          160  +    set result
          161  +} 0
          162  +
          163  +test simple-1.20 {-keepCDATA white space only CDATA section} {
          164  +    set doc [dom parse -simple -keepCDATA {<doc><e><![CDATA[
          165  +    ]]></e></doc>}]
          166  +    set result [$doc selectNodes count(doc/e/node())]
          167  +    $doc delete
          168  +    set result
          169  +} 0
          170  +
          171  +test simple-1.21 {-keepCDATA and -keepEmpties} {
          172  +    set doc [dom parse -simple -keepCDATA -keepEmpties {<doc><e><![CDATA[]]></e></doc>}]
          173  +    set result [$doc selectNodes count(doc/e/node())]
          174  +    $doc delete
          175  +    set result
          176  +} 1
          177  +
          178  +test simple-1.22 {namespaces} {
          179  +    set doc [dom parse -simple {
          180  +        <help><br xmlns:xsi="a"/><em xmlns:xsi="a">notes</em></help>
          181  +    }]
          182  +    $doc delete
          183  +} {}
    91    184   
    92    185   test simple-2.1 {XML build in entities} {
    93    186       set doc [dom parse -simple {<doc>&lt;&gt;&amp;&apos;&quot;</doc>}]
    94    187       set root [$doc documentElement]
    95    188       set result [$root text]
    96    189       $doc delete
    97    190       set result
    98    191   } {<>&'"}
    99         -
   100    192   # emacs: "
   101    193   
   102    194   test simple-2.2 {character entities} {
   103    195       set doc [dom parse -simple {<doc>&#65;&#x42;</doc>}]
   104    196       set root [$doc documentElement]
   105    197       set result [$root text]
   106    198       $doc delete

Changes to tests/xpath.bench.

    50     50   bench -desc "path with predicate - cached" -pre {
    51     51       set doc [dom parse <root/>]
    52     52   } -body {
    53     53       $doc selectNodes -cache 1 {/foo/bar/baz[not(grill) and @some='foo']}
    54     54   }
    55     55   
    56     56   
           57  +namespace eval ::dom {
           58  +    namespace eval  xpathFunc {
           59  +    }
           60  +}
           61  +
           62  +proc ::dom::xpathFunc::myfunc {args} {
           63  +    return "foo"
           64  +}
           65  +
           66  +dom createNodeCmd elementNode e1
           67  +
           68  +foreach nrOf {1 10 20 30 40 50 60} {
           69  +
           70  +    bench -desc "Tcl scripted XPath func with $nrOf nodes in the current nodelist" -pre {
           71  +        dom createDocument root doc
           72  +        $doc documentElement root
           73  +        $root appendFromScript {
           74  +            for {set x 0} {$x < $nrOf} {incr x} {
           75  +                e1
           76  +            }
           77  +        }
           78  +    } -body {
           79  +        $root selectNodes {e1[myfunc() = '']}
           80  +    } -post {
           81  +        $doc delete
           82  +    }
           83  +
           84  +}
           85  +
           86  +dom createNodeCmd elementNode e2
           87  +
           88  +dom createDocument root doc
           89  +$doc documentElement root
           90  +$root appendFromScript {
           91  +    e2
           92  +    for {set x 1} {$x < 1000} {incr x} {
           93  +        e1
           94  +    }
           95  +}
           96  +
           97  +bench -desc "Select unique element between 1000, at first, with pred" -body {
           98  +    $root selectNodes -cache 1 {e2[1]}
           99  +} -post {
          100  +    $doc delete
          101  +}
          102  +
          103  +bench -desc "Select unique element between 1000, at first, without pred" -pre {
          104  +    dom createDocument root doc
          105  +    $doc documentElement root
          106  +    $root appendFromScript {
          107  +        e2
          108  +        for {set x 1} {$x < 1000} {incr x} {
          109  +            e1
          110  +        }
          111  +    }
          112  +} -body {
          113  +    $root selectNodes -cache 1 {e2}
          114  +} -post {
          115  +    $doc delete
          116  +}
          117  +
          118  +bench -desc "Select unique element between 1000, at first, with last() pred" -pre {
          119  +    dom createDocument root doc
          120  +    $doc documentElement root
          121  +    $root appendFromScript {
          122  +        e2
          123  +        for {set x 1} {$x < 1000} {incr x} {
          124  +            e1
          125  +        }
          126  +    }
          127  +} -body {
          128  +    $root selectNodes -cache 1 {e2[last()]}
          129  +} -post {
          130  +    $doc delete
          131  +}
          132  +
          133  +bench -desc "Select unique element between 1000, at 500, with pred" -pre {
          134  +    dom createDocument root doc
          135  +    $doc documentElement root
          136  +    $root appendFromScript {
          137  +        for {set x 1} {$x < 500} {incr x} {
          138  +            e1
          139  +        }
          140  +        e2
          141  +        for {set x 501} {$x <= 1000} {incr x} {
          142  +            e1
          143  +        }
          144  +    }
          145  +} -body {
          146  +    $root selectNodes -cache 1 {e2[1]}
          147  +} -post {
          148  +    $doc delete
          149  +}
          150  +
          151  +bench -desc "Select unique element between 1000, at 500, without pred" -pre {
          152  +    dom createDocument root doc
          153  +    $doc documentElement root
          154  +    $root appendFromScript {
          155  +        for {set x 1} {$x < 500} {incr x} {
          156  +            e1
          157  +        }
          158  +        e2
          159  +        for {set x 501} {$x <= 1000} {incr x} {
          160  +            e1
          161  +        }
          162  +    }
          163  +} -body {
          164  +    $root selectNodes -cache 1 {e2}
          165  +} -post {
          166  +    $doc delete
          167  +}
          168  +
          169  +bench -desc "Select unique element between 1000, at 500, with last()" -pre {
          170  +    dom createDocument root doc
          171  +    $doc documentElement root
          172  +    $root appendFromScript {
          173  +        for {set x 1} {$x < 500} {incr x} {
          174  +            e1
          175  +        }
          176  +        e2
          177  +        for {set x 501} {$x <= 1000} {incr x} {
          178  +            e1
          179  +        }
          180  +    }
          181  +} -body {
          182  +    $root selectNodes -cache 1 {e2[last()]}
          183  +} -post {
          184  +    $doc delete
          185  +}
          186  +
          187  +bench -desc "Select unique element between 1000, at 1000, with pred" -pre {
          188  +    dom createDocument root doc
          189  +    $doc documentElement root
          190  +    $root appendFromScript {
          191  +        for {set x 1} {$x < 1000} {incr x} {
          192  +            e1
          193  +        }
          194  +        e2
          195  +    }
          196  +} -body {
          197  +    $root selectNodes -cache 1 {e2[1]}
          198  +} -post {
          199  +    $doc delete
          200  +}
          201  +
          202  +bench -desc "Select unique element between 1000, at 1000, without pred" -pre {
          203  +    dom createDocument root doc
          204  +    $doc documentElement root
          205  +    $root appendFromScript {
          206  +        for {set x 1} {$x < 1000} {incr x} {
          207  +            e1
          208  +        }
          209  +        e2
          210  +    }
          211  +} -body {
          212  +    $root selectNodes -cache 1 {e2}
          213  +} -post {
          214  +    $doc delete
          215  +}
    57    216   
          217  +bench -desc "Select unique element between 1000, at 1000, with last()" -pre {
          218  +    dom createDocument root doc
          219  +    $doc documentElement root
          220  +    $root appendFromScript {
          221  +        for {set x 1} {$x < 1000} {incr x} {
          222  +            e1
          223  +        }
          224  +        e2
          225  +    }
          226  +} -body {
          227  +    $root selectNodes -cache 1 {e2[last()]}
          228  +} -post {
          229  +    $doc delete
          230  +}

Changes to tests/xpath.test.

     1      1   # Features covered: XPath capabilities
     2      2   #
     3      3   # This file contains a collection of tests for the XPath engine of
     4      4   # tDOM.
     5      5   # Tested commands and object commands:
     6      6   #    xpath-1.*: Function tests
     7      7   #    xpath-2.*: i18n
     8         -#    xpath-3.*: NaN/Inf
            8  +#    xpath-3.*: NaN/Inf, number conversion
     9      9   #    xpath-4.*: Tcl coded XPath functions and additional Tcl coded
    10     10   #               XPath functions
    11     11   #    xpath-5.*: XPath lexer/parser tests
    12     12   #    xpath-6.*: Doc order after modifying tree
    13     13   #    xpath-7.*: Asorted XPath expressions, which are not occur in the xslt 
    14     14   #               tests outside this tcltest based test suite
    15     15   #
................................................................................
   199    199       $root selectNodes {-2.2 div (-23.7 div 0)}
   200    200   } {0}
   201    201   
   202    202   test xpath-3.20 {Infinity divided by Infinity} {
   203    203       $root selectNodes {(2 div 0) div (3 div 0)}
   204    204   } {NaN}
   205    205   
   206         -test xpath-3.21 {Infinity divided by postive number} {
          206  +test xpath-3.21 {Infinity divided by positive number} {
   207    207       $root selectNodes {(2.7 div 0) div 23}
   208    208   } {Infinity}
   209    209   
   210    210   test xpath-3.22 {Infinity divided by negative number} {
   211    211       $root selectNodes {(2.7 div 0) div -23}
   212    212   } {-Infinity}
   213    213   
   214         -test xpath-3.23 {-Infinity divided by postive number} {
          214  +test xpath-3.23 {-Infinity divided by positive number} {
   215    215       $root selectNodes {(-2.7 div 0) div 23}
   216    216   } {-Infinity}
   217    217   
   218    218   test xpath-3.24 {-Infinity divided by negative number} {
   219    219       $root selectNodes {(-2.7 div 0) div -23}
   220    220   } {Infinity}
   221    221   
................................................................................
   260    260   } {NaN}
   261    261   
   262    262   test xpath-3.35 {Infinity minus -Infinity} {
   263    263       $root selectNodes {(1 div 0) - (-1 div 0)}
   264    264   } {Infinity}
   265    265   
   266    266   $doc delete
          267  +
          268  +set doc [dom parse {<a>
          269  +    <b>
          270  +        <number>1</number>
          271  +    </b>
          272  +    <b>
          273  +        <number>4</number>
          274  +    </b>
          275  +    <b>
          276  +        <number>6</number>
          277  +    </b>
          278  +    <b>
          279  +        <number>7</number>
          280  +    </b>
          281  +    <b>
          282  +        <number>0xA</number>
          283  +    </b>
          284  +    <b>
          285  +        <number>0xB</number>
          286  +    </b>
          287  +    </a>}]
          288  +test xpath-3.36 {number conversion} {
          289  +    $doc selectNodes {count(/a/b[number>4])}
          290  +} {2}
          291  +
          292  +test xpath-3.37 {number conversion} {
          293  +    $doc selectNodes {count(/a/b[4<number])}
          294  +} {2}
          295  +
          296  +test xpath-3.38 {mod by a float that casts to integer 0} {
          297  +    $doc selectNodes { 2 mod 0.2}
          298  +} {NaN}
          299  +
          300  +$doc delete
   267    301   
   268    302   set doc [dom parse {<root xmlns:myNS="myNS">Foo</root>}]
   269    303   set root [$doc documentElement]
   270    304   
   271    305   test xpath-4.1 {function-available} {
   272    306       $root selectNodes function-available('count')
   273    307   } {1}
................................................................................
   302    336   test xpath-4.5 {tcl coded additional XPath function} {
   303    337       $root selectNodes {mycontains(., 'bo')}
   304    338   } {0}
   305    339   
   306    340   test xpath-4.6 {tcl coded additional XPath function - error reported} {
   307    341       catch {$root selectNodes {mycontains(., 'bo', 'ba')}} errMsg
   308    342       set errMsg
   309         -} {Tcl error while executing XPATH extension function 'mycontains':
          343  +} {Tcl error while executing XPath extension function 'mycontains':
   310    344   mycontains(): wrong # of args!}
   311    345   
   312    346   proc ::dom::xpathFunc::wrongreturn {ctxNode pos nodeListNode nodeList args} {
   313    347       return [list footype "foo"]
   314    348   }
   315    349   
   316    350   test xpath-4.7 {tcl coded additional XPath function - unknown return type} {
   317    351       catch {$root selectNodes {wrongreturn('foo')}} errMsg
   318    352       set errMsg
   319         -} {Unknown type of return value "footype" from tcl coded XPath function "wrongreturn"!}
          353  +} {Unknown type of return value "footype" from Tcl coded XPath function "wrongreturn"!}
   320    354   
   321    355   proc ::dom::xpathFunc::returnnumber {ctxNode pos nodeListNode nodeList args} {
   322    356       return [list number "42"]
   323    357   }
   324    358   
   325    359   test xpath-4.8 {tcl coded additional XPath function - return number} {
   326    360       $root selectNodes {returnnumber()}
................................................................................
   444    478       errorStack1
   445    479       return [list string "Not reached"]
   446    480   }
   447    481   
   448    482   test xpath-4.18 {error stack in tcl coded additional XPath function} {
   449    483       set result [catch {$root selectNodes errorStack()} errMsg]
   450    484       lappend result $errMsg
   451         -} {1 {Tcl error while executing XPATH extension function 'errorStack':
          485  +} {1 {Tcl error while executing XPath extension function 'errorStack':
   452    486   Some error}}
          487  +
          488  +proc ::dom::xpathFunc::stringReturn {args} {return x}
          489  +
          490  +test xpath-4.19 {tcl coded additional XPath function - return implicit string result} {
          491  +    $root selectNodes stringReturn(.)
          492  +} {x}
          493  +
          494  +test xpath-4.20 {tcl coded additional XPath function - return implicit string result} {
          495  +    $root selectNodes stringReturn()
          496  +} {x}
          497  +
          498  +proc ::dom::xpathFunc::ctxNode {ctxNode args} {
          499  +    return [list "nodes" $ctxNode]
          500  +}
          501  +
          502  +test xpath-4.21 {tcl coded additional XPath function - return node} {
          503  +    $root selectNodes {string(ctxNode()/node())} 
          504  +} {Foo}
          505  +
          506  +dom parse {<doc>
          507  +<e>1</e>
          508  +<e>2</e>
          509  +<e>3</e>
          510  +<e>4</e>
          511  +<e>5</e>
          512  +    </doc>} doc1
          513  +
          514  +proc ::dom::xpathFunc::useXPath {ctxNode pos nodeListNode nodeList args} {
          515  +
          516  +    if {[llength $args] != 2} {
          517  +        error "useXPath(): wrong # of args!"
          518  +    }
          519  +    foreach { arg1Typ arg1Value } $args break
          520  +    if {$arg1Typ ne "nodes" || [llength $arg1Value] != 1} {
          521  +        error "wrong argument: expecting one node"
          522  +    }
          523  +    set result [list]
          524  +    for {set i 5} {$i > 0} {incr i -2} {
          525  +        lappend result [$arg1Value selectNodes {*[position()=$i]}]
          526  +    }
          527  +    for {set i 1} {$i < 6} {incr i 2} {
          528  +        lappend result [$arg1Value selectNodes {*[position()=$i]}]
          529  +    }
          530  +    # Result will be a XPath result set, that means in document order
          531  +    # and de-duplicated.
          532  +    return [list "nodes" $result]
          533  +}
          534  +
          535  +test xpath-4.22 {tcl coded additional XPath function - use XPath on the document in the function} {
          536  +    set result [list]
          537  +    foreach node [$doc1 selectNodes useXPath(/doc)] {
          538  +        lappend result [$node text]
          539  +    }
          540  +    join $result " "
          541  +} {1 3 5}
          542  +
          543  +$doc1 delete
   453    544   
   454    545   test xpath-5.1 {erroneous XPath expr: missing right brace in predicate} {
   455    546       set result [catch {$root selectNodes {*[1}} errMsg]
   456    547       list $result $errMsg
   457    548   } {1 {Predicate: Expected "RBRACKET" for '*[1' 
   458    549   
   459    550   Parsed symbols:
   460         -     0 WCARDNAME        0    0.000     0  *
   461         -     1 LBRACKET         0    0.000     1  
   462         -     2 INTNUMBER        1    1.000     2  }}
          551  +     0 WCARDNAME        0 00000.000     0  *
          552  +     1 LBRACKET         0 00000.000     1  
          553  +     2 INTNUMBER        1 00001.000     2  }}
   463    554   
   464    555   test xpath-5.2 {erroneous XPath expr: missing right brace in predicate} {
   465    556       set result [catch {$root selectNodes {*[1][@attr}} errMsg]
   466    557       list $result $errMsg
   467    558   } {1 {Predicate: Expected "RBRACKET" for '*[1][@attr' 
   468    559   
   469    560   Parsed symbols:
   470         -     0 WCARDNAME        0    0.000     0  *
   471         -     1 LBRACKET         0    0.000     1  
   472         -     2 INTNUMBER        1    1.000     2  
   473         -     3 RBRACKET         0    0.000     3  
   474         -     4 LBRACKET         0    0.000     4  
   475         -     5 ATTRIBUTE        0    0.000     9  attr}}
          561  +     0 WCARDNAME        0 00000.000     0  *
          562  +     1 LBRACKET         0 00000.000     1  
          563  +     2 INTNUMBER        1 00001.000     2  
          564  +     3 RBRACKET         0 00000.000     3  
          565  +     4 LBRACKET         0 00000.000     4  
          566  +     5 ATTRIBUTE        0 00000.000     9  attr}}
   476    567   
   477    568   test xpath-5.3 {erroneous XPath expr: missing left brace in predicate} {
   478    569       catch {$root selectNodes {*1]}}
   479    570   } {1}
   480    571   
   481    572   test xpath-5.4 {erroneous XPath expr} {
   482    573       catch {$root selectNodes {myNS: bar}} errMsg
................................................................................
   715    806   
   716    807   test xpath-5.27 {erroneous XPath expr} {
   717    808       set doc [dom parse {<!--yes-->  <doc><e1/></doc><?foo bar?>}]
   718    809       set result [catch {$doc selectNodes {/[position()=1]}} errMsg]
   719    810       $doc delete
   720    811       set result
   721    812   } {1}
          813  +
          814  +test xpath-5.28 {afl-fuzz found seg faulting 'xpath expr'} {
          815  +    set doc [dom parse <a/>]
          816  +    set result [catch {$doc selectNodes {@a//b::*}}]
          817  +    $doc delete
          818  +    set result
          819  +} {1}
          820  +
          821  +test xpath-5.29 {afl-fuzz found seg faulting 'xpath expr'} {
          822  +    set doc [dom parse <a/>]
          823  +    set result [catch {$doc selectNodes {a[1=a::a]}}]
          824  +    $doc delete
          825  +    set result
          826  +} {1}
          827  +
          828  +test xpath-5.30 {afl-fuzz found seg faulting 'xpath expr'} {
          829  +    set doc [dom parse <a/>]
          830  +    set result [catch {$doc selectNodes [string repeate 9 239]@d}]
          831  +    $doc delete
          832  +    set result
          833  +} {1}
          834  +
          835  +test xpath-5.31 {Limits} {
          836  +    set doc [dom parse <a/>]
          837  +    set result [$doc selectNodes {999999999999999 + 999999999999999}]
          838  +    $doc delete
          839  +    set result
          840  +} {1999999999999998.0}
          841  +
          842  +test xpath-5.32 {Limits} {
          843  +    set doc [dom parse <a/>]
          844  +    set result [$doc selectNodes {9999999999999999999 + 9999999999999999999}]
          845  +    $doc delete
          846  +    set result
          847  +} {2e+19}
          848  +
          849  +test xpath-5.33 {afl-fuzz found seg faulting 'xpath expr'} {
          850  +    set doc [dom parse <a/>]
          851  +    set result [catch {$doc selectNodes "[string repeat Q 1380](1)"}]
          852  +    $doc delete
          853  +    set result
          854  +} {1}
          855  +
          856  +test xpath-5.34 {tcl var resolution in expr} {
          857  +    set doc [dom parse {<doc><e att="1"/><e att="2"/><e att="3"/></doc>}]
          858  +    set which 2
          859  +    # Tcl var value is always seen as string by the xpath engine. Any
          860  +    # non empty string is always true
          861  +    set node [$doc selectNodes {/doc/e[$which]}]
          862  +    set result [llength $node]
          863  +    # If another xpath data type is needed, cast explicitly
          864  +    set node [$doc selectNodes {/doc/e[number($which)]}]
          865  +    lappend result [llength $node]
          866  +    lappend result [$node @att]
          867  +    set which ""
          868  +    # Empty string is false, by xpath converting rules
          869  +    set node [$doc selectNodes {/doc/e[$which]}]
          870  +    lappend result [llength $node]
          871  +    $doc delete
          872  +    set result
          873  +} {3 1 2 0}
          874  +
          875  +test xpath-5.35 {tcl var resolution in xpath expr} {
          876  +    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
          877  +    set node [$doc documentElement] 
          878  +    set i 2
          879  +    set result [list]
          880  +    lappend result [$node selectNodes -cache 1 {string(*[position()=$i])}]
          881  +    set i 3
          882  +    lappend result [$node selectNodes -cache 1 {string(*[position()=$i])}]
          883  +    $doc delete
          884  +    set result
          885  +} {2 2}
          886  +
          887  +test xpath-5.36 {tcl var resolution in xpath expr} {
          888  +    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
          889  +    set node [$doc documentElement] 
          890  +    set i 2
          891  +    set result [list]
          892  +    lappend result [$node selectNodes {string(*[position()=$i])}]
          893  +    set i 3
          894  +    lappend result [$node selectNodes {string(*[position()=$i])}]
          895  +    $doc delete
          896  +    set result
          897  +} {2 3}
          898  +
          899  +proc xpath-5.37 {node} {
          900  +    set i 4
          901  +    return [$node selectNodes -cache 1 {string(*[position()=$i])}]
          902  +}
          903  +test xpath-5.37 {tcl var resolution in xpath expr} {
          904  +    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
          905  +    set node [$doc documentElement] 
          906  +    set i 2
          907  +    set result [list]
          908  +    lappend result [$node selectNodes -cache 1 {string(*[position()=$i])}]
          909  +    lappend result [xpath-5.37 $node]
          910  +    set i 3
          911  +    $doc delete
          912  +    set result
          913  +} {2 2}
          914  +
          915  +test xpath-5.38 {tcl var resolution in xpath expr} {
          916  +    set doc [dom parse <doc/>]
          917  +    set xpath "/doc"
          918  +    for {set i 1} {$i <= 20} {incr i} {
          919  +        set var$i $i
          920  +        append xpath "/e\[position()=\$var$i\]"
          921  +    }
          922  +    set result [$doc selectNodes $xpath]
          923  +    $doc delete
          924  +} {}
          925  +
          926  +test xpath-5.39 {tcl var resolution in xpath expr} {
          927  +    set xml {
          928  +        <doc>
          929  +        <e att="a" elm="1"/>
          930  +        <e att="a" elm="2"/>
          931  +        <e att="b" elm="3"/>
          932  +        <e att="b" elm="4"/>
          933  +        </doc>
          934  +    }
          935  +    set doc [dom parse $xml]
          936  +    set attvalue "b"
          937  +    set pos 2
          938  +    set result [[$doc selectNodes {/doc/e[@att=$attvalue][position()=$pos]}] asXML -indent none]
          939  +    $doc delete
          940  +    set result
          941  +} {<e att="b" elm="4"/>}
          942  +
          943  +test xpath-5.40 {tcl var resolution in xpath expr} {
          944  +    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
          945  +    # What this test tests depend on NUM_STATIC_TOKENS. Which is 20 in
          946  +    # the tcl core distribution at the time, this test was written.
          947  +    unset -nocomplain a
          948  +    for {set i 0} {$i < 25} {} {
          949  +        set a($i) [incr i]
          950  +    }
          951  +    set a(25) 2
          952  +    set xpath "string(/doc/e\[position()="
          953  +    for {set i 0} {$i < 26} {incr i} {
          954  +        append xpath "\$a("
          955  +    }
          956  +    append xpath 0
          957  +    for {set i 0} {$i < 26} {incr i} {
          958  +        append xpath ")"
          959  +    }
          960  +    append xpath "\])"
          961  +    set result [$doc selectNodes $xpath]
          962  +    lappend result [$doc selectNodes -cache 1 $xpath]
          963  +    $doc delete
          964  +    unset a
          965  +    set result
          966  +} {2 2}
          967  +
          968  +test xpath-5.41 {tcl var resolution in xpath expr} {
          969  +    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
          970  +    # What this test tests depend on NUM_STATIC_TOKENS.
          971  +    unset -nocomplain a
          972  +    for {set i 0} {$i < 25} {} {
          973  +        set a($i) [incr i]
          974  +    }
          975  +    set a(25) 2
          976  +    set xpath "/doc"
          977  +    for {set i 1} {$i <= 20} {incr i} {
          978  +        set var$i $i
          979  +        append xpath "/e\[position()=\$var$i\]"
          980  +    }
          981  +    append xpath "/e\[position()="
          982  +    for {set i 0} {$i < 26} {incr i} {
          983  +        append xpath "\$a("
          984  +    }
          985  +    append xpath 0
          986  +    for {set i 0} {$i < 26} {incr i} {
          987  +        append xpath ")"
          988  +    }
          989  +    append xpath "\]"
          990  +    set result [$doc selectNodes $xpath]
          991  +    append result [$doc selectNodes -cache 1 $xpath]
          992  +    $doc delete
          993  +    unset a
          994  +    set result
          995  +} ""
          996  +
          997  +test xpath-5.42 {tcl var resolution in xpath expr} {
          998  +    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
          999  +    # What this test tests depend on NUM_STATIC_TOKENS.
         1000  +    unset -nocomplain a
         1001  +    for {set i 0} {$i < 25} {} {
         1002  +        set a($i) [incr i]
         1003  +    }
         1004  +    set a(25) 2
         1005  +    set xpath "/doc/e\[position()="
         1006  +    for {set i 0} {$i < 26} {incr i} {
         1007  +        append xpath "\$a("
         1008  +    }
         1009  +    append xpath 0
         1010  +    for {set i 0} {$i < 26} {incr i} {
         1011  +        append xpath ")"
         1012  +    }
         1013  +    append xpath "\]"
         1014  +    for {set i 1} {$i <= 20} {incr i} {
         1015  +        set var$i $i
         1016  +        append xpath "/e\[position()=\$var$i\]"
         1017  +    }
         1018  +    set result [$doc selectNodes $xpath]
         1019  +    append result [$doc selectNodes -cache 1 $xpath]
         1020  +    $doc delete
         1021  +    unset a
         1022  +    set result
         1023  +} ""
         1024  +
         1025  +test xpath-5.43 {XPath is commutative} {
         1026  +    set xml {
         1027  +<doc>
         1028  +  <e>
         1029  +    <ee>eins</ee>
         1030  +  </e>
         1031  +  <e>
         1032  +    <ee>zwei</ee>
         1033  +  </e>
         1034  +</doc>}
         1035  +    set doc [dom parse $xml]
         1036  +    set result [expr {[$doc selectNodes {doc/e[ee='zwei']}]
         1037  +                      == [$doc selectNodes {doc/e['zwei'=ee]}]}]
         1038  +    lappend result [llength [$doc selectNodes {doc/e[ee='zwei']}]]
         1039  +    lappend result [$doc selectNodes {string(doc/e[ee='zwei'])}]
         1040  +    $doc delete
         1041  +    set result
         1042  +} {1 1 zwei}
         1043  +
         1044  +test xpath-5.44 {Element name injected with tcl variable} {
         1045  +    set doc [dom parse -json {{"member name with spaces":"the value"}}]
         1046  +    set nodeName "member name with spaces"
         1047  +    set node [$doc selectNodes %nodeName]
         1048  +    set result [list]
         1049  +    lappend result [$node nodeName]
         1050  +    lappend result [$doc selectNodes string(%nodeName)]
         1051  +    set node [$doc selectNodes /%nodeName]
         1052  +    lappend result [$node nodeName]
         1053  +    $doc delete
         1054  +    set result
         1055  +} {{member name with spaces} {the value} {member name with spaces}}
         1056  +
         1057  +test xpath-5.45 {Element name injected with tcl variable} {
         1058  +    set doc [dom parse -json {{"a":{"with spaces":"the value"},"a":{"with spaces":"another value"}}}]
         1059  +    set nodeName "with spaces"
         1060  +    set node [$doc selectNodes {a[%nodeName='another value']}]
         1061  +    set result [list]
         1062  +    lappend result [$node nodeName]
         1063  +    lappend result [$doc selectNodes {string(a[%nodeName='another value'])}]
         1064  +    $doc delete
         1065  +    set result
         1066  +} {a {another value}}
         1067  +
         1068  +test xpath-5.46 {Element name injected with tcl variable - wrong xpath syntax} {
         1069  +    set doc [dom parse -json {{"a":{"with spaces":"the value"},"a":{"with spaces":"another value"}}}]
         1070  +    set result [catch {$doc selectNodes {a[b %nodeName='another value']}} errMsg]
         1071  +    lappend result $errMsg
         1072  +    $doc delete
         1073  +    set result
         1074  +} {1 {Predicate: Expected "RBRACKET" for 'a[b %nodeName='another value']' 
         1075  +
         1076  +Parsed symbols:
         1077  +     0 WCARDNAME        0 00000.000     0  a
         1078  +     1 LBRACKET         0 00000.000     1  
         1079  +     2 WCARDNAME        0 00000.000     2  b
         1080  +-->  3 WCARDNAME        1 00000.000    12  with spaces
         1081  +     4 EQUAL            0 00000.000    13  
         1082  +     5 LITERAL          0 00000.000    28  another value
         1083  +     6 RBRACKET         0 00000.000    29  }}
         1084  +
         1085  +test xpath-5.47 {Element name injected with tcl variable} {
         1086  +    set doc [dom parse -json {{"a":{"":"the value"},"a":{"":"another value"}}}]
         1087  +    set nodeName ""
         1088  +    set node [$doc selectNodes {a[%nodeName='another value']}]
         1089  +    set result [list]
         1090  +    lappend result [$node nodeName]
         1091  +    lappend result [$doc selectNodes {string(a[%nodeName='another value'])}]
         1092  +    $doc delete
         1093  +    set result
         1094  +} {a {another value}}
         1095  +
         1096  +test xpath-5.48 {Element name injected with tcl variable} {
         1097  +    set doc [dom parse -json {{"a":{"a\u0001b":"the value"},"a":{"a\u0001b":"another value"}}}]
         1098  +    set nodeName "a\u0001b"
         1099  +    set node [$doc selectNodes {a[%nodeName='another value']}]
         1100  +    set result [list]
         1101  +    lappend result [$node nodeName]
         1102  +    lappend result [$doc selectNodes {string(a[%nodeName='another value'])}]
         1103  +    $doc delete
         1104  +    set result
         1105  +} {a {another value}}
         1106  +
         1107  +test xpath-5.49 {Element name injected with tcl variable} {
         1108  +    set doc [dom parse -json {{"a":{"a\u0000b":"the value"},"a":{"a\u0000b":"another value"}}}]
         1109  +    set nodeName "a\u0000b"
         1110  +    set node [$doc selectNodes {a[%nodeName='another value']}]
         1111  +    set result [list]
         1112  +    lappend result [$node nodeName]
         1113  +    lappend result [$doc selectNodes {string(a[%nodeName='another value'])}]
         1114  +    $doc delete
         1115  +    set result
         1116  +} {a {another value}}
         1117  +
         1118  +test xpath-5.50 {Element name injected with tcl variable} {
         1119  +    set doc [dom parse -json {{"a":"1","*":"2","c":"3"}}]
         1120  +    set nodeName "*"
         1121  +    set result [llength [$doc selectNodes %nodeName]]
         1122  +    $doc delete
         1123  +    set result
         1124  +} {1}
         1125  +
         1126  +test xpath-5.51 {Element name injected with tcl variable} {
         1127  +    set doc [dom parse -json {{"member name with spaces":"the value"}}]
         1128  +    set nodeName "member name with spaces"
         1129  +    set node [$doc selectNodes %nodeName]
         1130  +    set result [list]
         1131  +    lappend result [$node nodeName]
         1132  +    lappend result [$doc selectNodes string(%nodeName)]
         1133  +    set node [$doc selectNodes child::%nodeName]
         1134  +    lappend result [$node nodeName]
         1135  +    $doc delete
         1136  +    set result
         1137  +} {{member name with spaces} {the value} {member name with spaces}}
         1138  +
         1139  +test xpath-5.52 {Element name injected with tcl variable} {
         1140  +    set doc [dom parse -json {{"a:b":"value"}}]
         1141  +    set nodeName "a:b"
         1142  +    set result [$doc selectNodes string(%nodeName)]
         1143  +    $doc delete
         1144  +    set result
         1145  +} {value}
         1146  +
         1147  +test xpath-5.53 {Element name injected with tcl variable} {
         1148  +    set doc [dom parse -json {{"a:b":"value"}}]
         1149  +    set nodeName "a:b"
         1150  +    set result [$doc selectNodes string(child::%nodeName)]
         1151  +    $doc delete
         1152  +    set result
         1153  +} {value}
         1154  +
         1155  +test xpath-5.54 {Element name injected with tcl variable} {
         1156  +    set doc [dom parse -json {{"a:b":"value"}}]
         1157  +    set nodeName "a:b"
         1158  +    set result [$doc selectNodes string(descendant-or-self::%nodeName)]
         1159  +    $doc delete
         1160  +    set result
         1161  +} {value}
         1162  +
         1163  +test xpath-5.55 {Element name injected with tcl variable} {
         1164  +    set doc [dom parse <a><b/></a>]
         1165  +    set nodeName "a/b"
         1166  +    set result [llength [$doc selectNodes %nodeName]]
         1167  +    lappend result [llength [$doc selectNodes a/b]]
         1168  +    $doc delete
         1169  +    set result
         1170  +} {0 1}
         1171  +
         1172  +test xpath-5.56 {Element name injected with tcl variable} {
         1173  +    set doc [dom parse -json {{"a":{"a/b":"a/b"},"a":{"a":{"b":"b"}}}}]
         1174  +    set nodeName0 "a"
         1175  +    set nodeName1 "a/b"
         1176  +    set result [list]
         1177  +    lappend result [$doc selectNodes string(%nodeName0/%nodeName1)]
         1178  +    lappend result [$doc selectNodes string(a/a/b)]
         1179  +    $doc delete
         1180  +    set result
         1181  +} {a/b b}
   722   1182   
   723   1183   set doc [dom parse {
   724   1184   <root>
   725   1185     <asub>asub2</asub>
   726   1186     <asub>asub3</asub>
   727   1187     <asub>asub4</asub>
   728   1188     <bsub>bsub1</bsub>
................................................................................
   798   1258       dom parse {<root/>} doc
   799   1259       set result [$doc selectNodes {count(parent::*)}]
   800   1260       lappend result [$doc selectNodes {count(parent::node())}]
   801   1261       lappend result [$doc selectNodes {count(..)}]
   802   1262       $doc delete
   803   1263       set result
   804   1264   } {0 0 0}
         1265  +
         1266  +test xpath-7.7 {Document order in complexer // expressions} -setup {
         1267  +    set doc [dom parse {
         1268  +    <doc>
         1269  +    <a>
         1270  +        <b>1</b>
         1271  +        <a>
         1272  +            <b>11</b>
         1273  +        </a>
         1274  +        <b>2</b>
         1275  +    </a>
         1276  +    <a>
         1277  +        <a>
         1278  +            <b>22</b>
         1279  +        </a>
         1280  +        <b>3</b>
         1281  +        <b>4</b>
         1282  +        <a>
         1283  +            <b>33</b>
         1284  +        </a>
         1285  +    </a>
         1286  +</doc>}]} -body {
         1287  +    set result [list]
         1288  +    foreach node [$doc selectNodes //a/b] {
         1289  +        lappend result [$node selectNodes string()]
         1290  +    }
         1291  +    join $result " - "
         1292  +} -cleanup {
         1293  +    $doc delete
         1294  +} -result {1 - 11 - 2 - 22 - 3 - 4 - 33}
         1295  +
         1296  +test xpath-7.8 {Attribute node as context node of a lang() call} -setup {
         1297  +    set doc [dom parse <doc/>]
         1298  +} -body {
         1299  +    $doc selectNodes {/namespace::node()[lang('en')]}
         1300  +} -cleanup {
         1301  +    $doc delete
         1302  +} -result ""
         1303  +
         1304  +test xpath-7.9 {Attribute node as context node of an id() call} -setup {
         1305  +    set doc [dom parse {<doc foo="bar"/>}]
         1306  +} -body {
         1307  +    $doc selectNodes {doc/@foo[id(.)]}
         1308  +} -cleanup {
         1309  +    $doc delete
         1310  +} -result ""
   805   1311   
   806   1312   # cleanup
   807   1313   ::tcltest::cleanupTests
   808   1314   return
   809   1315   

Changes to tests/xslt.test.

    12     12   #    xslt-3.*: xslt vars, scope, parameters
    13     13   #    xslt-4.*: xslt transformations on modified/created from the scratch docs
    14     14   #    xslt-5.*: External documents: document(), xsl:import, xsl:include
    15     15   #    xslt-6.*: xsl:output
    16     16   #    xslt-7.*: tests related to the created result doc
    17     17   #    xslt-8.*: Additional xslt rec compliance tests (details not covered by
    18     18   #              by the external xslt compliance test suite).
           19  +#    xslt-9.*: xslt transformations that are using scripted xpath functions
    19     20   #
    20         -# Copyright (c) 2002 - 2005 Rolf Ade.
           21  +# Copyright (c) 2002 - 2005, 2013 Rolf Ade.
    21     22   #
    22     23   # RCS: @(#) $Id$
    23     24   
    24     25   source [file join [file dir [info script]] loadtdom.tcl]
    25     26   
    26     27   test xslt-1.1 {unicode chars outside of US-ASCII in var name} {need_i18n} {
    27     28        set xml [dom parse {<root/>}]
    28         -     set xslt [dom parse [tDOM::xmlReadFile [file join [pwd] [file dir [info script]] data/xslt_1.xsl]]]
           29  +     set xslt [dom parse [tdom::xmlReadFile [file join [pwd] [file dir [info script]] data/xslt_1.xsl]]]
    29     30        set xmlroot [$xml documentElement]
    30     31        $xmlroot xslt $xslt resultDoc
    31     32        set resultroot [$resultDoc documentElement]
    32     33        set result [$resultroot asXML]
    33     34        $xml delete
    34     35        $xslt delete
    35     36        $resultDoc delete
................................................................................
   543    544       set result [$resultDoc asXML -indent none]
   544    545       $resultDoc delete
   545    546       $xml delete
   546    547       $xslt delete
   547    548       set result
   548    549   } {<out>the parameter value</out>}
   549    550   
          551  +proc xslt-2.21-xsltmsgcmd {msg terminate} {
          552  +    global result
          553  +    if {$msg eq "3"} {
          554  +        return -code break
          555  +    }
          556  +    append result $msg
          557  +}
          558  +
          559  +test xslt-2.21 {xslt -xsltmessagecmd return code break} {
          560  +    set result ""
          561  +    set xml [dom parse {<doc><e/><e/><e/><e/></doc>}]
          562  +    set xslt [dom parse {<xsl:stylesheet 
          563  +        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          564  +        version="1.0">
          565  +        <xsl:template match="e">
          566  +          <xsl:message><xsl:value-of select="position()"/></xsl:message>
          567  +        </xsl:template>
          568  +        </xsl:stylesheet>}]
          569  +    catch {$xml xslt -xsltmessagecmd xslt-2.21-xsltmsgcmd $xslt resultDoc} errMsg
          570  +    append result $resultDoc $errMsg
          571  +    $xml delete
          572  +    $xslt delete
          573  +    set result
          574  +} {12}
          575  +
          576  +test xslt-2.22 {xslt -xsltmessagecmd return code break} {
          577  +    set result ""
          578  +    set xml [dom parse {<doc><e/><e/><e/><e/></doc>}]
          579  +    set xslt [dom parse {<xsl:stylesheet 
          580  +        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          581  +        version="1.0">
          582  +        <xsl:template match="e">
          583  +          <xsl:message><xsl:value-of select="position()"/></xsl:message>
          584  +        </xsl:template>
          585  +        </xsl:stylesheet>}]
          586  +    set resultDoc "untouched"
          587  +    catch {$xml xslt -ignoreUndeclaredParameters -xsltmessagecmd xslt-2.21-xsltmsgcmd $xslt resultDoc} errMsg
          588  +    append result $resultDoc
          589  +    $xml delete
          590  +    $xslt delete
          591  +    set result
          592  +} {12}
          593  +
          594  +test xslt-2.23 {xslt outputVar} {
          595  +    set result ""
          596  +    set xml [dom parse {<doc/>}]
          597  +    set xslt [dom parse {<xsl:stylesheet 
          598  +        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          599  +        version="1.0">
          600  +        <xsl:template match="/">
          601  +        <resultDoc/>
          602  +        </xsl:template>
          603  +        </xsl:stylesheet>}]
          604  +    set resultDoc "untouched"
          605  +    catch {$xml xslt -foo $xslt resultDoc} errMsg
          606  +    append result $resultDoc
          607  +    $xml delete
          608  +    $xslt delete
          609  +    set result
          610  +} {untouched}
          611  +
          612  +test xslt-2.24 {xslt outputVar} {
          613  +    set xml [dom parse {<doc/>}]
          614  +    set xslt [dom parse {<xsl:stylesheet 
          615  +        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          616  +        version="1.0">
          617  +        <xsl:template match="/">
          618  +        <resultDoc/>
          619  +        </xsl:template>
          620  +        </xsl:stylesheet>}]
          621  +    set result [catch {$xml xslt -foo $xslt }]
          622  +    $xml delete
          623  +    $xslt delete
          624  +    set result
          625  +} {1}
          626  +
          627  +test xslt-2.25 {xslt outputVar} {
          628  +    set xml [dom parse {<doc/>}]
          629  +    set xslt [dom parse {<xsl:stylesheet 
          630  +        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          631  +        version="1.0">
          632  +        <xsl:template match="/">
          633  +        <xsl:message>Here</xsl:message>
          634  +        <resultDoc/>
          635  +        </xsl:template>
          636  +        </xsl:stylesheet>}]
          637  +    $xml xslt $xslt resultDoc
          638  +    $xml delete
          639  +    $xslt delete
          640  +    set result [$resultDoc asXML -indent none]
          641  +    $resultDoc delete
          642  +    set result
          643  +} {<resultDoc/>}
          644  +
          645  +test xslt-2.26 {xslt -maxApplyDepth option} {
          646  +    set xml [dom parse {<e><e><e><e></e></e></e></e>}]
          647  +    set xslt [dom parse {<xsl:stylesheet 
          648  +        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          649  +        version="1.0">
          650  +        <xsl:template match="e">
          651  +        <xsl:text>e</xsl:text>
          652  +        <xsl:apply-templates select="e"/>
          653  +        </xsl:template>
          654  +        </xsl:stylesheet>}]
          655  +    catch {$xml xslt -maxApplyDepth 3 $xslt} errMsg
          656  +    $xml delete
          657  +    $xslt delete
          658  +    set errMsg
          659  +} "Maximum nested apply templates reached (potential infinite template recursion?)."
          660  +
   550    661   test xslt-3.1 {xslt variable scope} {
   551    662       set xml [dom parse {<root/>}]
   552    663       set xslt [dom parse {<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   553    664     <xsl:template match="/">
   554    665       <xsl:variable name="main" select="'main'"/>
   555    666       <xsl:call-template name="first"/>
   556    667     </xsl:template>
................................................................................
  1038   1149       catch {$xmldoc xslt $xsltdoc resultDoc} errMsg
  1039   1150       $xmldoc delete
  1040   1151       $xsltdoc delete
  1041   1152       set errMsg
  1042   1153   } {The 'current' function is not allowed in Pattern. for '*[current() != 'notthis']' 
  1043   1154   
  1044   1155   Parsed symbols:
  1045         -     0 WCARDNAME        0    0.000     0  *
  1046         -     1 LBRACKET         0    0.000     1  
  1047         -     2 FUNCTION         0    0.000     8  current
  1048         -     3 LPAR             0    0.000     9  
  1049         -     4 RPAR             0    0.000    10  
  1050         -     5 NOTEQ            0    0.000    13  
  1051         -     6 LITERAL          0    0.000    23  notthis
  1052         -     7 RBRACKET         0    0.000    24  }
         1156  +     0 WCARDNAME        0 00000.000     0  *
         1157  +     1 LBRACKET         0 00000.000     1  
         1158  +     2 FUNCTION         0 00000.000     8  current
         1159  +     3 LPAR             0 00000.000     9  
         1160  +     4 RPAR             0 00000.000    10  
         1161  +     5 NOTEQ            0 00000.000    13  
         1162  +     6 LITERAL          0 00000.000    23  notthis
         1163  +     7 RBRACKET         0 00000.000    24  }
  1053   1164   
  1054   1165   set xslt-8.2.xml {<?xml version="1.0"?>
  1055   1166   <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">
  1056   1167   	<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
  1057   1168   	</DocumentProperties>
  1058   1169   	<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
  1059   1170   	</OfficeDocumentSettings>
................................................................................
  1143   1254   
  1144   1255       set xsltDoc [dom parse $xslt]
  1145   1256       set result [catch {$xmlDoc xslt $xsltDoc} errMsg]
  1146   1257       $xmlDoc delete
  1147   1258       $xsltDoc delete
  1148   1259       set result
  1149   1260   } {1}
  1150         -    
         1261  +
         1262  +test xslt-8.5 {Minimal xslt 1.0 stylesheet} {
         1263  +    set xmlDoc {<doc><child/></doc>}
         1264  +    set xsltDoc {<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"/>}
         1265  +    dom parse -keepEmpties $xmlDoc xmldoc
         1266  +    dom parse -keepEmpties $xsltDoc xsltdoc
         1267  +    $xmldoc xslt $xsltdoc resultDoc
         1268  +    set result [$resultDoc asXML -indent none]
         1269  +    $xmldoc delete
         1270  +    $xsltdoc delete
         1271  +    $resultDoc delete
         1272  +    set result
         1273  +} {}
         1274  +
         1275  +test xslt-8.6 {Almost minimal xslt 1.0 stylesheet} {
         1276  +    set xmlDoc {<doc><child/></doc>}
         1277  +    set xsltDoc {<xsl:stylesheet 
         1278  +        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
         1279  +        <xsl:template match="/"/>
         1280  +        </xsl:stylesheet>}
         1281  +    dom parse -keepEmpties $xmlDoc xmldoc
         1282  +    dom parse -keepEmpties $xsltDoc xsltdoc
         1283  +    $xmldoc xslt $xsltdoc resultDoc
         1284  +    set result [$resultDoc asXML -indent none]
         1285  +    $xmldoc delete
         1286  +    $xsltdoc delete
         1287  +    $resultDoc delete
         1288  +    set result
         1289  +} {}
         1290  +
         1291  +test xslt-8.7 {Minimal xslt 1.0 stylesheet returns text content of doc by default} {
         1292  +    set xmlDoc {<doc><child>text</child></doc>}
         1293  +    set xsltDoc {<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"/>}
         1294  +    dom parse -keepEmpties $xmlDoc xmldoc
         1295  +    dom parse -keepEmpties $xsltDoc xsltdoc
         1296  +    $xmldoc xslt $xsltdoc resultDoc
         1297  +    set result [$resultDoc asXML -indent none]
         1298  +    $xmldoc delete
         1299  +    $xsltdoc delete
         1300  +    $resultDoc delete
         1301  +    set result
         1302  +} {text}
         1303  +
         1304  +test xslt-8.8 {Almost minimal xslt 1.0 stylesheet} {
         1305  +    set xmlDoc {<doc><child>text</child></doc>}
         1306  +    set xsltDoc {<xsl:stylesheet 
         1307  +        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
         1308  +        <xsl:template match="/"/>
         1309  +        </xsl:stylesheet>}
         1310  +    dom parse -keepEmpties $xmlDoc xmldoc
         1311  +    dom parse -keepEmpties $xsltDoc xsltdoc
         1312  +    $xmldoc xslt $xsltdoc resultDoc
         1313  +    set result [$resultDoc asXML -indent none]
         1314  +    $xmldoc delete
         1315  +    $xsltdoc delete
         1316  +    $resultDoc delete
         1317  +    set result
         1318  +} {}
         1319  +
         1320  +test xslt-8.9 {format-number} {knownBug} {
         1321  +    set xmlDoc [dom parse <doc/>]
         1322  +    set xsltDoc [dom parse {<xsl:stylesheet
         1323  +        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
         1324  +        <xsl:template match="/">
         1325  +        <out><xsl:value-of select="format-number(1.0, '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')"/></out>
         1326  +        </xsl:template>
         1327  +        </xsl:stylesheet>}]
         1328  +    $xmlDoc xslt $xsltDoc resultDoc
         1329  +    set result [$resultDoc asXML -indent none]
         1330  +    $xmlDoc delete
         1331  +    $xsltDoc delete
         1332  +    $resultDoc delete
         1333  +    set result <out>001</out>
         1334  +} {<out>001</out>}
         1335  +
         1336  +proc ::dom::xpathFunc::xslt-9.1 {ctxNode pos nodeListType nodeList args} {
         1337  +    if {[llength $ctxNode] != 2} {
         1338  +        error "::dom::xpathFunc::xslt-9.1: expected parent node / attribute \
         1339  +               name list as first argument."
         1340  +    }
         1341  +    return {string "bar"}
         1342  +}
         1343  +
         1344  +test xslt-9.1 {xslt using scripted xpath function} -setup {
         1345  +    set xml {<a><b start="foo"><c/></b></a>}
         1346  +    set xsl {<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
         1347  +        version="1.0">
         1348  +  <xsl:template match="@* | node()">
         1349  +    <xsl:copy>
         1350  +      <xsl:apply-templates select="@* | node()"/>
         1351  +    </xsl:copy>
         1352  +  </xsl:template>         
         1353  +  <xsl:template match="@start">
         1354  +    <xsl:attribute name="start">
         1355  +      <xsl:value-of select="xslt-9.1(.)"/>
         1356  +    </xsl:attribute>
         1357  +  </xsl:template>
         1358  +</xsl:transform>}
         1359  +    set xsltDoc [dom parse -keepEmpties $xsl]
         1360  +    set xmlDoc [dom parse $xml]
         1361  +} -body {
         1362  +    $xmlDoc xslt $xsltDoc resultDoc
         1363  +    $resultDoc asXML -indent none
         1364  +} -cleanup {
         1365  +    $xsltDoc delete
         1366  +    $xmlDoc delete
         1367  +    $resultDoc delete
         1368  +} -result {<a><b start="bar"><c/></b></a>}
         1369  +
  1151   1370   # Below is code, which replaces the dom cmd with a version, which parses
  1152   1371   # the xml into a dom tree, then transformations this dom tree with the
  1153   1372   # xslt identity transformation and returns the result tree of that
  1154   1373   # transformation. This is used to test, that the result tree of an xslt
  1155   1374   # transformation could be used as any 'ordinary' tree created with
  1156         -# [dom parse]. It is here, because I didn't want to hold it seperated.
         1375  +# [dom parse]. It is here, because I didn't want to hold it separated.
  1157   1376   # It is commented out, because some of the tests in the sourced test files
  1158   1377   # need line/column or baseURI information, to work correctly, and this
  1159   1378   # information is not preserved by an xslt identity transformation and
  1160   1379   # I was up to now too lazy, to trick around this few tests with some
  1161   1380   # test constraints.
  1162   1381   # 
  1163   1382   # set identityTransformation [dom parse {<xsl:stylesheet version="1.0"

Changes to unix/CONFIG.

     1      1   #!/bin/sh
     2      2   #
     3      3   # This is a small collection of example settings you can use to
     4      4   # compile tdom on different platforms. Just uncomment the line(s)
     5      5   # you need and run this script with "sh CONFIG".
     6      6   #
     7         -# With the exception of the --enable-tdomalloc option it's best, to
     8         -# leave the tDOM specfic configuration options alone (that is: use the
     9         -# defaults, do nothing).
            7  +# For typical use it's best, to leave the tDOM specific configuration
            8  +# options alone (that is: use the defaults, do nothing).
    10      9   # 
    11     10   # --enable-tdomalloc
    12     11   # Default: off
    13     12   # With this option on, a special memory allocator is used, which is
    14     13   # optimized for low memory allocation overhead. This allocator works
    15     14   # only on 32-bit plattforms. If you build for a 64-bit OS, you _must_
    16     15   # disable this (and it's disabled by default).
................................................................................
    43     42   # 
    44     43   # --with-aolserver
    45     44   # If building tDOM as module for AOLserver, this points to the 
    46     45   # directory with the AOLserver source distribution. See below
    47     46   # for examples.
    48     47   # 
    49     48   # --with-tdom
    50         -# Useful (and avaliable) only for building extensions to tDOM (as
           49  +# Useful (and available) only for building extensions to tDOM (as
    51     50   # tnc). Use it to point to the tdomConfig.sh file.
    52     51   #
    53     52   # 
    54     53   #
    55     54   # Comment-out next line if building with GCC compiler.
    56     55   # CC=gcc; export CC
    57     56   #
    58         -#
    59         -# Tcl 8.0.5 on Unix. Uses public Tcl library
    60         -# -------------------------------------------
    61         -# ../configure-tcl8.0.5
    62         -#
    63     57   #
    64     58   # Tcl 8.1+ on Unix. Uses public Tcl library
    65     59   # -------------------------------------------
    66     60   # ../configure
    67     61   #
    68         -#
    69         -# For 64-bit Unix you've to use --disable-tdomalloc
    70         -# -------------------------------------------------
    71         -# ../configure --disable-tdomalloc
    72         -#
    73     62   #
    74     63   # AOLserver 3.X. It delivers its own patched Tcl lib.
    75     64   # Also, this one builds tdom as AOLserver module.
    76     65   # Please do not use "make install" after doing "make".
    77     66   # You have to manually adjust AOLserver config file
    78     67   # to load tdom module. See README.AOL for more info.
    79     68   # Also, you need to modify the "aolsrc" to point to

Added unix/speed-check.sh.

            1  +#!/bin/bash
            2  +#
            3  +# This script is used for performance monitoring of tDOM.
            4  +#
            5  +# Needs valgrind (cachegrind), so best use on linux.
            6  +#
            7  +if test "$1" = ""
            8  +then
            9  +  echo "Usage: $0 OUTPUTFILE [OPTIONS]"
           10  +  exit
           11  +fi
           12  +NAME=$1
           13  +CACHEGRIND_OPTS=""
           14  +TESTSCRIPT="../tests/all.tcl"
           15  +TESTRUN_OPTS=""
           16  +shift
           17  +while test "$1" != ""; do
           18  +    case $1 in
           19  +        --testscript)
           20  +            shift
           21  +            TESTSCRIPT=$1
           22  +            ;;
           23  +        --options)  
           24  +            shift
           25  +            TESTRUN_OPTS=$1
           26  +            ;;                        
           27  +    esac
           28  +    shift
           29  +done
           30  +        
           31  +echo "NAME           = $NAME" | tee summary-$NAME.txt
           32  +echo 'puts [string range [dom featureinfo versionhash] 0 12]' \
           33  +    | ./tcldomsh >> summary-$NAME.txt
           34  +echo "TESTSCRIPT     = $TESTSCRIPT" | tee -a summary-$NAME.txt
           35  +echo "TESTRUN_OPTS   = $TESTRUN_OPTS" | tee -a summary-$NAME.txt
           36  +rm -f cachegrind.out.* 
           37  +valgrind --tool=cachegrind $CACHEGRIND_OPTS ./tcldomsh $TESTSCRIPT \
           38  +         $TESTRUN_OPTS 2>&1 | tee -a summary-$NAME.txt

Changes to unix/tclAppInit.c.

    28     28   |
    29     29   |   written by Rolf Ade
    30     30   |   August, 2007
    31     31   |
    32     32   \---------------------------------------------------------------------------*/
    33     33   
    34     34   #include "tcl.h"
           35  +
           36  +#ifndef MODULE_SCOPE
           37  +#   define MODULE_SCOPE extern
           38  +#endif
           39  +MODULE_SCOPE int Tcl_AppInit(Tcl_Interp *);
           40  +MODULE_SCOPE int main(int, char **);
    35     41    
    36         -extern int Tdom_Init _ANSI_ARGS_((Tcl_Interp *interp));
    37         -extern int Tdom_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
           42  +extern int Tdom_Init (Tcl_Interp *interp);
           43  +extern int Tdom_SafeInit (Tcl_Interp *interp);
    38     44   
    39     45   /*----------------------------------------------------------------------------
    40     46   |   main
    41     47   |
    42     48   \---------------------------------------------------------------------------*/
    43     49   int
    44     50   main(
................................................................................
    54     60   |   Tcl_AppInit
    55     61   |
    56     62   \---------------------------------------------------------------------------*/
    57     63   int
    58     64   Tcl_AppInit(interp)
    59     65       Tcl_Interp *interp;
    60     66   {
    61         -    if (Tcl_Init(interp) == TCL_ERROR) {
           67  +    if ((Tcl_Init)(interp) == TCL_ERROR) {
    62     68           return TCL_ERROR;
    63     69       }
    64     70       if (Tdom_Init(interp) == TCL_ERROR) {
    65     71           return TCL_ERROR;
    66     72       }
    67     73       Tcl_StaticPackage(interp, "tdom", Tdom_Init, Tdom_SafeInit);
    68     74       Tcl_SetVar(interp, "tcl_rcFileName", "~/.tcldomshrc", TCL_GLOBAL_ONLY);
    69     75       return TCL_OK;
    70     76   }

Added win/README.

            1  +This file contains instructions for building tdom on Windows platforms.
            2  +
            3  +Windows builds may be done with either the MingW-W64 tool chain
            4  +comprising of gcc and friends, or with the Microsoft Visual C++ and
            5  +nmake tools. Each is described below.
            6  +
            7  +IMPORTANT NOTE:
            8  +Building with either tool chain requires that the Tcl libraries that
            9  +are linked have also been built with the same tool chain. The resulting
           10  +binaries however can be loaded into a Tcl shell compiled with any
           11  +tool chain provided the requisite C runtimes are present on the system.
           12  +
           13  +Building With The Mingw-W64 Tool Chain
           14  +======================================
           15  +
           16  +Building with the MingW follows a similar process to the autoconf/TEA
           17  +based Unix builds.
           18  +
           19  +1. Start a shell using mingw32.exe or mingw64.exe for 32- and 64-bit
           20  +fields respectively. Do NOT use msys2.exe directly.
           21  +
           22  +2. Assuming you want to include HTML5 support using the Gumbo libraries,
           23  +build the Gumbo libraries by running these commands in the top level
           24  +directory where you extracted the Gumbo distribution. Note these
           25  +shell commands must be run in the mingw32.exe or mingw64.exe shells
           26  +as appropriate.
           27  +
           28  +    ./autogen.sh
           29  +    ./configure
           30  +    make
           31  +    make install
           32  +
           33  +This will install the Gumbo libraries in the mingw32/mingw64 system
           34  +directories as appropriate.
           35  +
           36  +3. Change to a build directory and run the configure at the top level
           37  +tdom directory. For example, if doing a 64-bit build in the win/build64
           38  +directory within a mingw64.exe shell,
           39  +
           40  +    mkdir win/build
           41  +    cd win/build
           42  +    ../../configure --enable-threads --enable-html5 --enable-64bit --prefix=/c/tcl/mingw/85/x64 --with-tcl=/c/tcl/mingw/85/x64/lib
           43  +    make
           44  +    make install
           45  +
           46  +In the above sequence, we are building against Tcl 8.5 installed under
           47  +c:\tcl\mingw\85\x64 on the system. The Gumbo libraries built in the
           48  +previous step are automatically picked up from the mingw64.exe directories.
           49  +Note that tdom on Windows binds against the static Gumbo library so
           50  +there is no additional DLL to distribute.
           51  +
           52  +The 32-bit build is similar except omitting the --enable-64bit option
           53  +(and of course pointing configure to a 32-bit installation of Tcl.
           54  +
           55  +4. Build the tnc and tdomhtml extensions in similar fashion to the above
           56  +except that the --enable-html5 option should be left out in both cases,
           57  +and an additional option --with-tdom=path/to/tdom/build needs to be
           58  +specified for the tnc configure step.
           59  +
           60  +IMPORTANT NOTE:
           61  +Because the MinGW-built binaries link to the msvcrt 6.0 runtimes that
           62  +is present on all Windows systems, the built tdom is usable on all
           63  +Windows systems with a Tcl built with any tool chain without needing
           64  +additional runtime libraries to be installed.
           65  +
           66  +
           67  +
           68  +
           69  +Building with Visual Studio 2017 Community Edition (free)
           70  +=========================================================
           71  +
           72  +1. Build the Gumbo libraries if HTML5 support is desired.
           73  +
           74  +1a. Check out the git repository from
           75  +https://github.com/apnadkarni/gumbo-parser.  Do NOT use the original
           76  +Gumbo repository as that does not contain a complete Visual Studio
           77  +project file required for tdom.
           78  +
           79  +1b. Switch to the tdom-libs branch.
           80  +Open the visualc/gumbo.sln solution file in Visual Studio. Click the
           81  +Batch Build... item under the Build menu. In the dialog box, select
           82  +the Win32|Release|x86 and x64|Release|x64 project configurations and
           83  +then click the Build or Rebuild button. This will build the 32-bit
           84  +and 64-bit gumbo.lib libraries under visualc/Win32/Release and
           85  +visualc/x64/Release respectively.
           86  +
           87  +2. Next start a Visual Studio build command shell for 64-bit builds,
           88  +usually from
           89  +    Windows Start menu->Visual Studio 2017 Folder->x64 Native Command shell
           90  +
           91  +3. Change to the tdom\win directory and type the command
           92  +
           93  +     nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64 GUMBODIR=C:\src\gumbo
           94  +    nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64 GUMBODIR=C:\src\gumbo install
           95  +
           96  +Here INSTALLDIR is the path to your Tcl installation and GUMBODIR is
           97  +the path to the top level of the Gumbo sources. If GUMBODIR is not
           98  +specified, tdom will build without HTML5 support.
           99  +
          100  +The 32-bit builds are similar except that
          101  +
          102  +- the commands need to be run from the Visual Studio x86 Native Tools
          103  +command shell, and
          104  +- the INSTALLDIR needs to point to a 32-bit Tcl installation
          105  +- (Note GUMBODIR need not change)
          106  +
          107  +4a. To build the tnc and tdomhtml extensions,
          108  +
          109  +    cd extensions/tnc/win
          110  +    nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64
          111  +    nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64 install
          112  +
          113  +    cd extensions/tdomhtml/win
          114  +    nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64 install
          115  +
          116  +Note no build step necessary for tdomhtml as it is pure Tcl.
          117  +
          118  +Similar steps for 32-bit builds with appropriate changes.
          119  +
          120  +IMPORTANT NOTE:
          121  +The Visual Studio 2017 runtimes are not guaranteed to be installed on
          122  +all Windows systems. Thus the built tdom package should only be used
          123  +with a Tcl that is also built with Visual Studio 2017.
          124  +
          125  +
          126  +
          127  +# Building with Visual C++ 6 (32-bit) or Windows 2003 SDK (for 64-bit)
          128  +======================================================================
          129  +
          130  +Steps similar to above except that HTML5 support is not available due
          131  +to Gumbo needing C99 support. The GUMBODIR option should be left out
          132  +on the nmake build commands.
          133  +
          134  +IMPORTANT NOTE:
          135  +Because the VC++ 6 and 2003 SDK link to the msvcrt 6.0 runtimes that
          136  +is present on all Windows systems, the built tdom is usable on all
          137  +Windows systems with a Tcl built with any tool chain without needing
          138  +additional runtime libraries to be installed.
          139  +
          140  +
          141  +

Changes to win/makefile.vc.

     1         -# makefile.vc --                                               -*- Makefile -*-
            1  +#------------------------------------------------------------- -*- makefile -*-
            2  +#
            3  +# Makefile for tdom
     2      4   #
     3         -# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
            5  +# For basic build instructions see the README in this directory.
     4      6   #
     5         -# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
     6         -# make it suitable as a general package makefile. Look for the word EDIT
     7         -# which marks sections that may need modification. As a minumum you will
     8         -# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
     9         -# relevant to your package.
    10         -#
            7  +# For other build options (debug, static etc.),
            8  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
            9  +# detailed documentation.
           10  +# 
    11     11   # See the file "license.terms" for information on usage and redistribution
    12     12   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    13         -# 
    14         -# Copyright (c) 1995-1996 Sun Microsystems, Inc.
    15         -# Copyright (c) 1998-2000 Ajuba Solutions.
    16         -# Copyright (c) 2001 ActiveState Corporation.
    17         -# Copyright (c) 2001-2002 David Gravereaux.
    18         -# Copyright (c) 2003-2006 Pat Thoyts
    19         -#
    20         -#-------------------------------------------------------------------------
    21         -# RCS: @(#)$Id$
    22         -#-------------------------------------------------------------------------
    23         -
    24         -# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
    25         -# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define
    26         -# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another.
    27         -!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir)
    28         -MSG = ^
    29         -You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
    30         -Platform SDK first to setup the environment.  Jump to this line to read^
    31         -the build instructions.
    32         -!error $(MSG)
    33         -!endif
    34         -
    35         -#------------------------------------------------------------------------------
    36         -# HOW TO USE this makefile:
    37         -#
    38         -# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
    39         -#     used  as a check to see if vcvars32.bat had been run prior to running
    40         -#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
    41         -#     been set globally and the PATH adjusted.  Either way is valid.
    42         -#
    43         -#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
    44         -#     directory to setup the proper environment, if needed, for your current
    45         -#     setup.  This is a needed bootstrap requirement and allows the swapping of
    46         -#     different environments to be easier.
    47         -#
    48         -# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
    49         -#     vcvars32.bat according to the instructions for it.  This can also turn on
    50         -#     the 64-bit compiler, if your SDK has it.
    51         -#
    52         -# 3)  Targets are:
    53         -#	all       -- Builds everything.
    54         -#       <project> -- Builds the project (eg: nmake sample)
    55         -#	test      -- Builds and runs the test suite.
    56         -#	install   -- Installs the built binaries and libraries to $(INSTALLDIR)
    57         -#		     in an appropriate subdirectory.
    58         -#	clean/realclean/distclean -- varying levels of cleaning.
    59         -#
    60         -# 4)  Macros usable on the commandline:
    61         -#	INSTALLDIR=<path>
    62         -#		Sets where to install Tcl from the built binaries.
    63         -#		C:\Progra~1\Tcl is assumed when not specified.
    64         -#
    65         -#	OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
    66         -#		Sets special options for the core.  The default is for none.
    67         -#		Any combination of the above may be used (comma separated).
    68         -#		'none' will over-ride everything to nothing.
    69         -#
    70         -#		static  =  Builds a static library of the core instead of a
    71         -#			   dll.  The shell will be static (and large), as well.
    72         -#		msvcrt  =  Effects the static option only to switch it from
    73         -#			   using libcmt(d) as the C runtime [by default] to
    74         -#			   msvcrt(d). This is useful for static embedding
    75         -#			   support.
    76         -#		staticpkg = Effects the static option only to switch
    77         -#			   tclshXX.exe to have the dde and reg extension linked
    78         -#			   inside it.
    79         -#		nothreads = Turns off multithreading support (not recommended)
    80         -#		thrdalloc = Use the thread allocator (shared global free pool).
    81         -#		symbols =  Adds symbols for step debugging.
    82         -#		profile =  Adds profiling hooks.  Map file is assumed.
    83         -#		loimpact =  Adds a flag for how NT treats the heap to keep memory
    84         -#			   in use, low.  This is said to impact alloc performance.
    85         -#
    86         -#	STATS=memdbg,compdbg,none
    87         -#		Sets optional memory and bytecode compiler debugging code added
    88         -#		to the core.  The default is for none.  Any combination of the
    89         -#		above may be used (comma separated).  'none' will over-ride
    90         -#		everything to nothing.
    91         -#
    92         -#		memdbg   = Enables the debugging memory allocator.
    93         -#		compdbg  = Enables byte compilation logging.
    94         -#
    95         -#	MACHINE=(IX86|IA64|ALPHA|AMD64)
    96         -#		Set the machine type used for the compiler, linker, and
    97         -#		resource compiler.  This hook is needed to tell the tools
    98         -#		when alternate platforms are requested.  IX86 is the default
    99         -#		when not specified. If the CPU environment variable has been
   100         -#		set (ie: recent Platform SDK) then MACHINE is set from CPU.
   101         -#
   102         -#	TMP_DIR=<path>
   103         -#	OUT_DIR=<path>
   104         -#		Hooks to allow the intermediate and output directories to be
   105         -#		changed.  $(OUT_DIR) is assumed to be 
   106         -#		$(BINROOT)\(Release|Debug) based on if symbols are requested.
   107         -#		$(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
   108         -#
   109         -#	TESTPAT=<file>
   110         -#		Reads the tests requested to be run from this file.
   111         -#
   112         -#	CFG_ENCODING=encoding
   113         -#		name of encoding for configuration information. Defaults
   114         -#		to cp1252
   115         -#
   116         -# 5)  Examples:
   117         -#
   118         -#	Basic syntax of calling nmake looks like this:
   119         -#	nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
   120         -#
   121         -#                        Standard (no frills)
   122         -#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
   123         -#       Setting environment for using Microsoft Visual C++ tools.
   124         -#       c:\tcl_src\win\>nmake -f makefile.vc all
   125         -#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
   126         -#
   127         -#                         Building for Win64
   128         -#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
   129         -#       Setting environment for using Microsoft Visual C++ tools.
   130         -#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
   131         -#       Targeting Windows pre64 RETAIL
   132         -#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
   133     13   #
   134     14   #------------------------------------------------------------------------------
   135         -#==============================================================================
   136         -###############################################################################
   137         -#------------------------------------------------------------------------------
   138         -
   139         -!if !exist("makefile.vc")
   140         -MSG = ^
   141         -You must run this makefile only from the directory it is in.^
   142         -Please `cd` to its location first.
   143         -!error $(MSG)
   144         -!endif
   145         -
   146         -#-------------------------------------------------------------------------
   147         -# Project specific information (EDIT)
   148         -#
   149         -# You should edit this with the name and version of your project. This
   150         -# information is used to generate the name of the package library and
   151         -# it's install location.
   152         -#
   153         -# For example, the sample extension is  going to build sample04.dll and
   154         -# would install it into $(INSTALLDIR)\lib\sample04
   155         -#
   156         -# You need to specify the object files that need to be linked into your
   157         -# binary here.
   158         -#
   159         -#-------------------------------------------------------------------------
   160     15   
   161     16   PROJECT = tdom
   162         -!include "rules.vc"
           17  +PRJ_RCFILE = tdom.rc
           18  +!if [echo VERSIONHASH = \> nmakehlp.out] \
           19  +   || [type ..\manifest.uuid >> nmakehlp.out]
           20  +!error *** Could not retrieve VERSIONHASH.
           21  +!endif
           22  +!include nmakehlp.out
   163     23   
   164         -DOTVERSION      = 0.8.3
   165         -VERSION         = $(DOTVERSION:.=)
   166         -STUBPREFIX      = $(PROJECT)stub
           24  +!include "rules-ext.vc"
   167     25   
   168         -DLLOBJS = \
           26  +EXPATDIR = ..\expat
           27  +PRJ_OBJS = \
   169     28   	$(TMP_DIR)\xmlrole.obj     \
   170     29   	$(TMP_DIR)\xmltok.obj      \
   171     30   	$(TMP_DIR)\xmlparse.obj    \
   172     31   	$(TMP_DIR)\xmlsimple.obj   \
   173         -	$(TMP_DIR)\utf8conv.obj    \
   174     32   	$(TMP_DIR)\dom.obj         \
   175     33   	$(TMP_DIR)\domalloc.obj    \
   176     34   	$(TMP_DIR)\domhtml.obj     \
           35  +	$(TMP_DIR)\domhtml5.obj    \
   177     36   	$(TMP_DIR)\domxslt.obj     \
   178     37   	$(TMP_DIR)\nodecmd.obj     \
   179     38   	$(TMP_DIR)\domxpath.obj    \
   180     39   	$(TMP_DIR)\domlock.obj     \
           40  +	$(TMP_DIR)\domjson.obj     \
   181     41   	$(TMP_DIR)\tclexpat.obj    \
   182     42   	$(TMP_DIR)\tcldom.obj      \
           43  +	$(TMP_DIR)\tclpull.obj     \
   183     44   	$(TMP_DIR)\tdomStubInit.obj\
   184     45   	$(TMP_DIR)\tdomStubLib.obj \
   185     46   	$(TMP_DIR)\tdominit.obj    \
   186         -!if !$(STATIC_BUILD)
   187         -	$(TMP_DIR)\tdom.res
   188         -!endif
           47  +	$(TMP_DIR)\loadlibrary.obj
           48  +
           49  +PRJ_STUBOBJS = $(TMP_DIR)\tdomStubLib.obj
           50  +
           51  +PRJ_DEFINES = \
           52  +	-D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE \
           53  +	-DHAVE_MEMMOVE -DXML_DTD=1 -DXML_NS=1 -DTDOM_NO_UNKNOWN_CMD=1 \
           54  +	-DXMLIMPORT=__declspec(dllexport)
           55  +
           56  +# TBD - some of the code, like expat checks for Windows using the
           57  +# WIN32 macro. This should really be changed to check _WIN32. For now,
           58  +# define WIN32 ourselves
           59  +PRJ_DEFINES = $(PRJ_DEFINES) -DWIN32
   189     60   
   190         -PRJSTUBOBJS = \
   191         -	$(TMP_DIR)\tdomStubLib.obj
           61  +PRJ_INCLUDES	= -I"$(EXPATDIR)" -I"$(TMP_DIR)"
   192     62   
   193         -#-------------------------------------------------------------------------
   194         -# Target names and paths ( shouldn't need changing )
   195         -#-------------------------------------------------------------------------
           63  +!if "$(GUMBODIR)" != ""
   196     64   
   197         -BINROOT		= .
   198         -ROOT            = ..
   199         -
   200         -PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
   201         -PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
   202         -PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)
   203         -
   204         -PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
   205         -PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)
           65  +PRJ_DEFINES     = $(PRJ_DEFINES) -DTDOM_HAVE_GUMBO=1
           66  +PRJ_INCLUDES = $(PRJ_INCLUDES) -I"$(GUMBODIR)\src"
   206     67   
   207         -### Make sure we use backslash only.
   208         -PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
   209         -LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
   210         -BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
   211         -DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
   212         -SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
   213         -INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include
   214         -
   215         -### The following paths CANNOT have spaces in them.
   216         -GENERICDIR	= $(ROOT)\generic
   217         -WINDIR		= $(ROOT)\win
   218         -LIBDIR          = $(ROOT)\lib
   219         -DOCDIR		= $(ROOT)\doc
   220         -TOOLSDIR	= $(ROOT)\tools
   221         -COMPATDIR	= $(ROOT)\compat
   222         -EXPATDIR        = $(ROOT)\expat
   223         -
   224         -#---------------------------------------------------------------------
   225         -# Compile flags
   226         -#---------------------------------------------------------------------
   227         -
   228         -!if !$(DEBUG)
   229         -!if $(OPTIMIZING)
   230         -### This cranks the optimization level to maximize speed
   231         -cdebug	= $(OPTIMIZATIONS)
           68  +!if "$(MACHINE)" == "AMD64"
           69  +baselibs = $(baselibs) "$(GUMBODIR)\visualc\x64\Release\gumbo.lib"
   232     70   !else
   233         -cdebug	=
   234         -!endif
   235         -!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
   236         -### Warnings are too many, can't support warnings into errors.
   237         -cdebug	= -Zi -Od $(DEBUGFLAGS)
   238         -!else
   239         -cdebug	= -Zi -WX $(DEBUGFLAGS)
           71  +baselibs = $(baselibs) "$(GUMBODIR)\visualc\Win32\Release\gumbo.lib"
   240     72   !endif
   241     73   
   242         -### Declarations common to all compiler options
   243         -cwarn = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
   244         -cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
           74  +!endif # GUMBODIR
           75  +
           76  +!include "$(_RULESDIR)\targets.vc"
           77  +
           78  +$(TMP_DIR)\tcldom.obj: $(TMP_DIR)\versionhash.h
           79  +$(TMP_DIR)\versionhash.h: $(ROOT)\manifest.uuid
           80  +	echo #define FOSSIL_HASH "$(VERSIONHASH)" > $(TMP_DIR)\versionhash.h
   245     81   
   246         -# Warning level
   247         -!if $(FULLWARNINGS)
   248         -cflags = $(cflags) -W4
   249         -!else
   250         -cflags = $(cflags) -W3
   251         -!endif
           82  +install:    default-install-docs-html default-install-stubs
   252     83   
   253         -!if $(MSVCRT)
   254         -!if $(DEBUG) && !$(UNCHECKED)
   255         -crt = -MDd
   256         -!else
   257         -crt = -MD
   258         -!endif
   259         -!else
   260         -!if $(DEBUG) && !$(UNCHECKED)
   261         -crt = -MTd
   262         -!else
   263         -crt = -MT
   264         -!endif
   265         -!endif
   266         -
   267         -!if !$(STATIC_BUILD)
   268         -cflags = $(cflags) -DUSE_TCL_STUBS
   269         -!if defined(TKSTUBLIB)
   270         -cflags = $(cflags) -DUSE_TK_STUBS
   271         -!endif
   272         -!endif
   273         -
   274         -DEFS            =-DHAVE_MEMMOVE -DXML_DTD -DXML_NS -DTDOM_NO_UNKNOWN_CMD
   275         -DEFS_EXPAT	=-DXMLIMPORT=__declspec(dllexport)
   276         -INCLUDES	= -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(EXPATDIR)" $(TCL_INCLUDES) 
   277         -BASE_CFLAGS	= $(cflags) $(cdebug) $(crt) $(INCLUDES)
   278         -CON_CFLAGS	= $(cflags) $(cdebug) $(crt) -DCONSOLE
   279         -TCL_CFLAGS      = -DPACKAGE_NAME="\"$(PROJECT)\"" \
   280         -		  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
   281         -		  $(BASE_CFLAGS) $(OPTDEFINES) $(DEFS) $(DEFS_EXPAT)
   282         -
   283         -#---------------------------------------------------------------------
   284         -# Link flags
   285         -#---------------------------------------------------------------------
   286         -
   287         -!if $(DEBUG)
   288         -ldebug	= -debug:full -debugtype:cv
   289         -!if $(MSVCRT)
   290         -ldebug = $(ldebug) -nodefaultlib:msvcrt
   291         -!endif
   292         -!else
   293         -ldebug	= -release -opt:ref -opt:icf,3
   294         -!endif
   295         -
   296         -### Declarations common to all linker options
   297         -lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
   298         -
   299         -!if $(FULLWARNINGS)
   300         -lflags = $(lflags) -warn:3
   301         -!endif
   302         -
   303         -!if $(PROFILE)
   304         -lflags	= $(lflags) -profile
   305         -!endif
   306         -
   307         -!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
   308         -### Align sections for PE size savings.
   309         -lflags	= $(lflags) -opt:nowin98
   310         -!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
   311         -### Align sections for speed in loading by choosing the virtual page size.
   312         -lflags	= $(lflags) -align:4096
   313         -!endif
   314         -
   315         -!if $(LOIMPACT)
   316         -lflags	= $(lflags) -ws:aggressive
   317         -!endif
   318         -
   319         -dlllflags = $(lflags) -dll
   320         -conlflags = $(lflags) -subsystem:console
   321         -guilflags = $(lflags) -subsystem:windows
   322         -!if !$(STATIC_BUILD)
   323         -baselibs  = $(TCLSTUBLIB)
   324         -!if defined(TKSTUBLIB)
   325         -baselibs  = $(baselibs) $(TKSTUBLIB)
   326         -!endif
   327         -!endif
   328         -
   329         -# Avoid 'unresolved external symbol __security_cookie' errors.
   330         -# c.f. http://support.microsoft.com/?id=894573
   331         -!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
   332         -baselibs   = $(baselibs) bufferoverflowU.lib
   333         -!endif
   334         -
   335         -#---------------------------------------------------------------------
   336         -# TclTest flags
   337         -#---------------------------------------------------------------------
   338         -
   339         -!IF "$(TESTPAT)" != ""
   340         -TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
   341         -!ENDIF
   342         -
   343         -#---------------------------------------------------------------------
   344         -# Project specific targets (EDIT)
   345         -#---------------------------------------------------------------------
   346         -
   347         -all:	    setup $(PROJECT)
   348         -$(PROJECT): setup $(PRJLIB) $(PRJSTUBLIB)
   349         -install:    install-binaries install-libraries install-docs
   350         -
   351         -# Tests need to ensure we load the right dll file we
   352         -# have to handle the output differently on Win9x.
   353         -#
   354         -!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
   355         -test: setup $(PROJECT)
   356         -        set TCL_LIBRARY=$(ROOT)/library
   357         -        $(TCLSH) <<
   358         -load $(PRJLIB:\=/)
   359         -source [file join $(LIBDIR:\=/) tdom.tcl]
   360         -cd "$(ROOT)/tests"
   361         -set argv "$(TESTFLAGS)"
   362         -source all.tcl
   363         -<<
   364         -!else
   365         -test: setup $(PROJECT)
   366         -        echo Please wait while the test results are collected
   367         -        set TCL_LIBRARY=$(ROOT)/library
   368         -        $(TCLSH) << >tests.log
   369         -load $(PRJLIB:\=/)
   370         -source [file join $(LIBDIR:\=/) tdom.tcl]
   371         -cd "$(ROOT)/tests"
   372         -set argv "$(TESTFLAGS)"
   373         -source all.tcl
   374         -<<
   375         -        type tests.log | more
   376         -!endif
   377         -
   378         -setup:
   379         -	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
   380         -	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
   381         -
   382         -# See <tcl>/win/coffbase.txt for extension base addresses.
   383         -$(PRJLIB): $(DLLOBJS)
   384         -!if $(STATIC_BUILD)
   385         -	$(lib32) -nologo -out:$@ @<<
   386         -$**
   387         -<<
   388         -!else
   389         -	$(link32) $(dlllflags) -base:0x109E0000 -out:$@ $(baselibs) @<<
   390         -$**
   391         -<<
   392         -	$(_VC_MANIFEST_EMBED_DLL)
   393         -	-@del $*.exp
   394         -!endif
   395         -
   396         -$(PRJSTUBLIB): $(PRJSTUBOBJS)
   397         -	$(lib32) -nologo -out:$@ $(PRJSTUBOBJS)
   398         -
   399         -#---------------------------------------------------------------------
   400         -# Implicit rules
   401         -#---------------------------------------------------------------------
   402         -
   403         -{$(WINDIR)}.c{$(TMP_DIR)}.obj::
   404         -    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
           84  +{$(EXPATDIR)}.c{$(TMP_DIR)}.obj::
           85  +    $(CCPKGCMD) @<<
   405     86   $<
   406     87   <<
   407     88   
   408         -{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
   409         -    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
   410         -$<
           89  +pkgindex:
           90  +        @type << >"$(OUT_DIR)\pkgIndex.tcl"
           91  +    package ifneeded $(PROJECT) $(DOTVERSION) "[list load [file join $$dir $(PRJLIBNAME)] tdom]; [list source [file join $$dir tdom.tcl]]"
   411     92   <<
   412     93   
   413         -{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
   414         -    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
   415         -$<
   416         -<<
   417         -
   418         -{$(EXPATDIR)}.c{$(TMP_DIR)}.obj::
   419         -    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
   420         -$<
   421         -<<
   422         -
   423         -{$(WINDIR)}.rc{$(TMP_DIR)}.res:
   424         -	$(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
   425         -                -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
   426         -                -DDOTVERSION=\"$(DOTVERSION)\" \
   427         -                -DVERSION=\"$(VERSION)$(SUFX)\" \
   428         -!if $(DEBUG)
   429         -	-d DEBUG \
   430         -!endif
   431         -!if $(TCL_THREADS)
   432         -	-d TCL_THREADS \
   433         -!endif
   434         -!if $(STATIC_BUILD)
   435         -	-d STATIC_BUILD \
   436         -!endif
   437         -	$<
   438         -
   439         -.SUFFIXES:
   440         -.SUFFIXES:.c .rc
   441         -
   442         -#-------------------------------------------------------------------------
   443         -# Explicit dependency rules
   444         -#
   445         -#-------------------------------------------------------------------------
   446         -
   447         -$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
   448         -	nmakehlp -s << $** > $@
   449         -@PACKAGE_VERSION@    $(DOTVERSION)
   450         -@PACKAGE_NAME@       $(PROJECT)
   451         -@PKG_LIB_FILE@       $(PRJLIBNAME)
   452         -<<
   453         -
   454         -#---------------------------------------------------------------------
   455         -# Installation. (EDIT)
   456         -#
   457         -# You may need to modify this section to reflect the final distribution
   458         -# of your files and possibly to generate documentation.
   459         -#
   460         -#---------------------------------------------------------------------
   461         -
   462         -install-binaries:
   463         -	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
   464         -	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
   465         -	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
   466         -	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
   467         -
   468         -install-libraries:
   469         -        @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
   470         -        @if exist $(LIBDIR)\NUL $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)" >NUL
   471         -        @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
   472         -        @type << >"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
   473         -if {[info exists ::tcl_platform(debug)]} {
   474         -    package ifneeded $(PROJECT) $(DOTVERSION) "[list load [file join $$dir $(PROJECT)$(VERSION)g.$(EXT)] tdom]; [list source [file join $$dir tdom.tcl]]"
   475         -} else {
   476         -    package ifneeded $(PROJECT) $(DOTVERSION) "[list load [file join $$dir $(PROJECT)$(VERSION).$(EXT)] tdom]; [list source [file join $$dir tdom.tcl]]"
   477         -}
   478         -<<
   479         -
   480         -install-docs:
   481         -#	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
   482         -#	@if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"
   483         -
   484         -#---------------------------------------------------------------------
   485         -# Clean up
   486         -#---------------------------------------------------------------------
   487         -
   488         -clean:
   489         -	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
   490         -	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
   491         -	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
   492         -	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
   493         -	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
   494         -
   495         -realclean: clean
   496         -	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
   497         -
   498         -distclean: realclean
   499         -	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
   500         -	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj

Deleted win/makefile805.vc.

     1         -#----------------------------------------------------------------------------
     2         -#   This is derivated from the tcl8.3 win makefile and surely not
     3         -#   perfect. It works for me. 
     4         -#   rolf ade, 2001 (rolf@pointsman.de)
     5         -#   
     6         -#   Changes for 8.0.5 by Sumit Pokhariyal (sumitp@pune.tcs.co.in)
     7         -#
     8         -#   Project directories
     9         -#
    10         -#   ROOT   = top of source tree
    11         -#
    12         -#   TOOLS32 = location of VC++ 32-bit development tools.
    13         -#
    14         -#   INSTALLDIR = location of the Tcl installation
    15         -#
    16         -#----------------------------------------------------------------------------
    17         -
    18         -!if "$(MSVCDIR)" == ""
    19         -MSG = ^
    20         -You'll need to run vcvars32.bat from Developer Studio, first, to setup^
    21         -the environment.
    22         -!error $(MSG)
    23         -!endif
    24         -# emacs: '
    25         -
    26         -# Set this to the appropriate value of /MACHINE: for your platform
    27         -MACHINE                = IX86
    28         -ROOT           = ..
    29         -INSTALLDIR     = c:\Progra~1\Tcl
    30         -
    31         -TOOLS32        = $(MSVCDIR)
    32         -TOOLS32_rc     = $(MSVCDIR)\..\common\MSDev98
    33         -
    34         -# Uncomment the following line to compile with thread support
    35         -#THREADDEFINES = -DTCL_THREADS=1
    36         -
    37         -# Set NODEBUG to 0 to compile with symbols
    38         -NODEBUG = 1
    39         -
    40         -# The following defines can be used to control the amount of debugging
    41         -# code that is added to the compilation.
    42         -#
    43         -#      -DTCL_MEM_DEBUG         Enables the debugging memory allocator.
    44         -#      -DTCL_COMPILE_DEBUG     Enables byte compilation logging.
    45         -#      -DTCL_COMPILE_STATS     Enables byte compilation statistics gathering.
    46         -#      -DUSE_TCLALLOC=0        Disables the Tcl memory allocator in favor
    47         -#                              of the native malloc implementation.  This is
    48         -#
    49         -# DEBUGDEFINES = -DTCL_MEM_DEBUG -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
    50         -# DEBUGDEFINES = -DUSE_TCLALLOC=0
    51         -
    52         -
    53         -#-------------------------------------------------------------------------
    54         -#
    55         -#   Do not modify below this line
    56         -#
    57         -#-------------------------------------------------------------------------
    58         -
    59         -NAMEPREFIX = libtdom
    60         -DOTVERSION = 0.8.3
    61         -VERSION = 083
    62         -
    63         -BINROOT         = .
    64         -!IF "$(NODEBUG)" == "1"
    65         -TMPDIRNAME      =
    66         -DBGX            =
    67         -!ELSE
    68         -TMPDIRNAME      = Debug
    69         -DBGX            = d
    70         -!ENDIF
    71         -TMPDIR          = $(BINROOT)
    72         -OUTDIRNAME      = $(TMPDIRNAME)
    73         -OUTDIR          = $(TMPDIR)
    74         -TOP_DIR         = $(BINROOT)\..
    75         -
    76         -TDOMLIB         = $(OUTDIR)\$(NAMEPREFIX)$(VERSION)$(DBGX).lib
    77         -TDOMDLLNAME     = $(NAMEPREFIX)$(VERSION)$(DBGX).dll
    78         -TDOMDLL         = $(OUTDIR)\$(TDOMDLLNAME)
    79         -
    80         -MKDIR           = .\mkd.bat
    81         -RM              = del
    82         -
    83         -LIB_INSTALL_DIR        = $(INSTALLDIR)\lib
    84         -BIN_INSTALL_DIR        = $(INSTALLDIR)\bin
    85         -SCRIPT_INSTALL_DIR     = $(INSTALLDIR)\lib\tcl$(DOTVERSION)
    86         -INCLUDE_INSTALL_DIR    = $(INSTALLDIR)\include
    87         -
    88         -
    89         -TDOMOBJS = $(TMPDIR)\xmlrole.obj    \
    90         -           $(TMPDIR)\xmltok.obj     \
    91         -           $(TMPDIR)\xmlparse.obj   \
    92         -           $(TMPDIR)\xmlsimple.obj  \
    93         -           $(TMPDIR)\utf8conv.obj   \
    94         -           $(TMPDIR)\dom.obj        \
    95         -           $(TMPDIR)\domalloc.obj   \
    96         -	   $(TMPDIR)\domhtml.obj    \
    97         -	   $(TMPDIR)\domxslt.obj    \
    98         -	   $(TMPDIR)\nodecmd.obj    \
    99         -           $(TMPDIR)\domxpath.obj   \
   100         -           $(TMPDIR)\domlock.obj   \
   101         -           $(TMPDIR)\tclexpat.obj   \
   102         -           $(TMPDIR)\tcldom.obj     \
   103         -           $(TMPDIR)\tdominit.obj
   104         -
   105         -
   106         -cc32           = "$(TOOLS32)\bin\cl.exe"
   107         -link32         = "$(TOOLS32)\bin\link.exe"
   108         -rc32           = "$(TOOLS32_rc)\bin\rc.exe"
   109         -include32      = -I"$(TOOLS32)\include"
   110         -libpath32      = /LIBPATH:"$(TOOLS32)\lib"
   111         -tcllibpath     = /LIBPATH:"$(INSTALLDIR)\lib"
   112         -lib32          = "$(TOOLS32)\bin\lib.exe"
   113         -
   114         -WINDIR         = $(ROOT)\win
   115         -GENERICDIR     = $(ROOT)\generic
   116         -EXPATDIR       = $(ROOT)\expat
   117         -TCLINCDIR      = $(INSTALLDIR)\Include
   118         -
   119         -TCL_INCLUDES   = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(EXPATDIR)" -I"$(TCLINCDIR)"
   120         -TCL_DEFINES    = $(DEBUGDEFINES) $(THREADDEFINES)
   121         -
   122         -#-------------------------------------------------------------------------
   123         -#
   124         -#   Compile flags
   125         -#
   126         -#-------------------------------------------------------------------------
   127         -
   128         -!IF "$(NODEBUG)" == "1"
   129         -# This cranks the optimization level to maximize speed
   130         -cdebug = -O2 -Gs -GD
   131         -!ELSE
   132         -!IF "$(MACHINE)" == "IA64"
   133         -cdebug = -Od -Zi
   134         -!ELSE
   135         -cdebug = -Z7 -Od
   136         -!ENDIF
   137         -!ENDIF
   138         -
   139         -# declarations common to all compiler options
   140         -cflags = -c -W3 -nologo -Fp$(TMPDIR)\ -YX -DHAVE_MEMMOVE -DXML_DTD -DXML_NS -DTDOM_NO_UNKNOWN_CMD -DVERSION="\"$(DOTVERSION)\""
   141         -cvarsdll = -MD$(DBGX)
   142         -
   143         -TCL_CFLAGS     = $(cdebug) $(cflags) $(cvarsdll) $(include32) \
   144         -                       $(TCL_INCLUDES) $(TCL_DEFINES)
   145         -CON_CFLAGS     = $(cdebug) $(cflags) $(include32) -DCONSOLE
   146         -
   147         -#-------------------------------------------------------------------------
   148         -#
   149         -#   Link flags
   150         -#
   151         -#-------------------------------------------------------------------------
   152         -
   153         -!IF "$(NODEBUG)" == "1"
   154         -ldebug = /RELEASE
   155         -!ELSE
   156         -ldebug = -debug:full -debugtype:cv
   157         -!ENDIF
   158         -
   159         -# declarations common to all linker options
   160         -lflags = /NODEFAULTLIB /NOLOGO /MACHINE:$(MACHINE) $(libpath32) $(tcllibpath)
   161         -
   162         -# declarations for use on Intel i386, i486, and Pentium systems
   163         -DLLENTRY = @12
   164         -dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll
   165         -
   166         -
   167         -conlflags = $(lflags) -subsystem:console -entry:mainCRTStartup
   168         -guilflags = $(lflags) -subsystem:windows -entry:WinMainCRTStartup
   169         -
   170         -libc = libc$(DBGX).lib oldnames.lib
   171         -libcdll = msvcrt$(DBGX).lib oldnames.lib
   172         -
   173         -baselibs   = kernel32.lib $(optlibs) advapi32.lib user32.lib tcl80$(DBGX).lib
   174         -#baselibs    = kernel32.lib $(optlibs) advapi32.lib user32.lib tcl83.lib
   175         -winlibs     = $(baselibs) gdi32.lib comdlg32.lib winspool.lib
   176         -
   177         -
   178         -guilibs     = $(libc) $(winlibs)
   179         -conlibs     = $(libc) $(baselibs)
   180         -guilibsdll  = $(libcdll) $(winlibs)
   181         -conlibsdll  = $(libcdll) $(baselibs)
   182         -
   183         -#-------------------------------------------------------------------------
   184         -#
   185         -#   Project specific targets
   186         -#
   187         -#-------------------------------------------------------------------------
   188         -
   189         -all:       dlls 
   190         -dlls:      $(TDOMDLL)
   191         -
   192         -install:   all
   193         -	@echo installing tDOM
   194         -	@$(MKDIR) "$(INSTALLDIR)\lib\tDOM"
   195         -	@xcopy /y $(TDOMDLL) "$(INSTALLDIR)\lib\tDOM"
   196         -	@xcopy /y pkgIndex.tcl "$(INSTALLDIR)\lib\tDOM"
   197         -	@xcopy /y ..\lib\tdom.tcl "$(INSTALLDIR)\lib\tDOM"
   198         -	@xcopy /y ..\lib\domhtml.tcl "$(INSTALLDIR)\lib\tDOM"
   199         -
   200         -$(TDOMLIB): $(TDOMDLL)
   201         -
   202         -$(TDOMDLL): $(TDOMOBJS)
   203         -       $(link32) $(ldebug) $(dlllflags) \
   204         -               -out:$@ $(guilibsdll) @<<
   205         -$(TDOMOBJS)
   206         -<<
   207         -
   208         -
   209         -	$(cc32) $(cdebug) $(cflags) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $?
   210         -
   211         -
   212         -#---------------------------------------------------------------------
   213         -# Dedependency rules
   214         -#---------------------------------------------------------------------
   215         -
   216         -
   217         -#-------------------------------------------------------------------------
   218         -#   Implicit rules
   219         -#-------------------------------------------------------------------------
   220         -
   221         -{$(EXPATDIR)}.c{$(TMPDIR)}.obj:
   222         -    $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<
   223         -
   224         -{$(GENERICDIR)}.c{$(TMPDIR)}.obj:
   225         -    $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<
   226         -
   227         -clean:
   228         -       -@$(RM) $(OUTDIR)\*.exp 2>nul
   229         -       -@$(RM) $(OUTDIR)\*.lib 2>nul
   230         -       -@$(RM) $(OUTDIR)\*.dll 2>nul
   231         -       -@$(RM) $(TMPDIR)\*.pch 2>nul
   232         -       -@$(RM) $(TMPDIR)\*.obj 2>nul
   233         -       -@$(RM) $(TMPDIR)\*.ilk 2>nul
   234         -       -@$(RM) $(TMPDIR)\*.pdb 2>nul

Changes to win/nmakehlp.c.

     5      5    *	This is used to fix limitations within nmake and the environment.
     6      6    *
     7      7    * Copyright (c) 2002 by David Gravereaux.
     8      8    * Copyright (c) 2006 by Pat Thoyts
     9      9    *
    10     10    * See the file "license.terms" for information on usage and redistribution of
    11     11    * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    12         - *
    13         - * ----------------------------------------------------------------------------
    14         - * RCS: @(#) $Id$
    15     12    * ----------------------------------------------------------------------------
    16     13    */
    17     14   
    18     15   #define _CRT_SECURE_NO_DEPRECATE
    19     16   #include <windows.h>
           17  +#define NO_SHLWAPI_GDI
           18  +#define NO_SHLWAPI_STREAM
           19  +#define NO_SHLWAPI_REG
           20  +#include <shlwapi.h>
    20     21   #pragma comment (lib, "user32.lib")
    21     22   #pragma comment (lib, "kernel32.lib")
           23  +#pragma comment (lib, "shlwapi.lib")
    22     24   #include <stdio.h>
    23     25   #include <math.h>
           26  +
           27  +/*
           28  + * This library is required for x64 builds with _some_ versions of MSVC
           29  + */
    24     30   #if defined(_M_IA64) || defined(_M_AMD64)
           31  +#if _MSC_VER >= 1400 && _MSC_VER < 1500
    25     32   #pragma comment(lib, "bufferoverflowU")
           33  +#endif
    26     34   #endif
    27     35   
    28     36   /* ISO hack for dumb VC++ */
    29     37   #ifdef _MSC_VER
    30     38   #define   snprintf	_snprintf
    31     39   #endif
    32     40   
    33     41   
    34         -
    35     42   /* protos */
    36     43   
    37         -int		CheckForCompilerFeature(const char *option);
    38         -int		CheckForLinkerFeature(const char *option);
    39         -int		IsIn(const char *string, const char *substring);
    40         -int		GrepForDefine(const char *file, const char *string);
    41         -int		SubstituteFile(const char *substs, const char *filename);
    42         -const char *    GetVersionFromFile(const char *filename, const char *match);
    43         -DWORD WINAPI	ReadFromPipe(LPVOID args);
           44  +static int CheckForCompilerFeature(const char *option);
           45  +static int CheckForLinkerFeature(const char **options, int count);
           46  +static int IsIn(const char *string, const char *substring);
           47  +static int SubstituteFile(const char *substs, const char *filename);
           48  +static int QualifyPath(const char *path);
           49  +static int LocateDependency(const char *keyfile);
           50  +static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
           51  +static DWORD WINAPI ReadFromPipe(LPVOID args);
    44     52   
    45     53   /* globals */
    46     54   
    47     55   #define CHUNK	25
    48     56   #define STATICBUFFERSIZE    1000
    49     57   typedef struct {
    50     58       HANDLE pipe;
................................................................................
    62     70   main(
    63     71       int argc,
    64     72       char *argv[])
    65     73   {
    66     74       char msg[300];
    67     75       DWORD dwWritten;
    68     76       int chars;
           77  +    char *s;
    69     78   
    70     79       /*
    71     80        * Make sure children (cl.exe and link.exe) are kept quiet.
    72     81        */
    73     82   
    74     83       SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
    75     84   
................................................................................
    90     99   			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
    91    100   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
    92    101   			&dwWritten, NULL);
    93    102   		return 2;
    94    103   	    }
    95    104   	    return CheckForCompilerFeature(argv[2]);
    96    105   	case 'l':
    97         -	    if (argc != 3) {
          106  +	    if (argc < 3) {
    98    107   		chars = snprintf(msg, sizeof(msg) - 1,
    99         -	       		"usage: %s -l <linker option>\n"
          108  +	       		"usage: %s -l <linker option> ?<mandatory option> ...?\n"
   100    109   			"Tests for whether link.exe supports an option\n"
   101    110   			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
   102    111   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   103    112   			&dwWritten, NULL);
   104    113   		return 2;
   105    114   	    }
   106         -	    return CheckForLinkerFeature(argv[2]);
          115  +	    return CheckForLinkerFeature(&argv[2], argc-2);
   107    116   	case 'f':
   108    117   	    if (argc == 2) {
   109    118   		chars = snprintf(msg, sizeof(msg) - 1,
   110    119   			"usage: %s -f <string> <substring>\n"
   111    120   			"Find a substring within another\n"
   112    121   			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
   113    122   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
................................................................................
   118    127   		 * If the string is blank, there is no match.
   119    128   		 */
   120    129   
   121    130   		return 0;
   122    131   	    } else {
   123    132   		return IsIn(argv[2], argv[3]);
   124    133   	    }
   125         -	case 'g':
   126         -	    if (argc == 2) {
   127         -		chars = snprintf(msg, sizeof(msg) - 1,
   128         -			"usage: %s -g <file> <string>\n"
   129         -			"grep for a #define\n"
   130         -			"exitcodes: integer of the found string (no decimals)\n",
   131         -			argv[0]);
   132         -		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   133         -			&dwWritten, NULL);
   134         -		return 2;
   135         -	    }
   136         -	    return GrepForDefine(argv[2], argv[3]);
   137    134   	case 's':
   138    135   	    if (argc == 2) {
   139    136   		chars = snprintf(msg, sizeof(msg) - 1,
   140    137   			"usage: %s -s <substitutions file> <file>\n"
   141    138   			"Perform a set of string map type substutitions on a file\n"
   142    139   			"exitcodes: 0\n",
   143    140   			argv[0]);
................................................................................
   153    150   		    "Extract a version from a file:\n"
   154    151   		    "eg: pkgIndex.tcl \"package ifneeded http\"",
   155    152   		    argv[0]);
   156    153   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   157    154   		    &dwWritten, NULL);
   158    155   		return 0;
   159    156   	    }
   160         -	    printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
   161         -	    return 0;
          157  +	    s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
          158  +	    if (s && *s) {
          159  +		printf("%s\n", s);
          160  +		return 0;
          161  +	    } else
          162  +		return 1; /* Version not found. Return non-0 exit code */
          163  +
          164  +	case 'Q':
          165  +	    if (argc != 3) {
          166  +		chars = snprintf(msg, sizeof(msg) - 1,
          167  +		    "usage: %s -Q path\n"
          168  +		    "Emit the fully qualified path\n"
          169  +		    "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
          170  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          171  +		    &dwWritten, NULL);
          172  +		return 2;
          173  +	    }
          174  +	    return QualifyPath(argv[2]);
          175  +
          176  +	case 'L':
          177  +	    if (argc != 3) {
          178  +		chars = snprintf(msg, sizeof(msg) - 1,
          179  +		    "usage: %s -L keypath\n"
          180  +		    "Emit the fully qualified path of directory containing keypath\n"
          181  +		    "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
          182  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          183  +		    &dwWritten, NULL);
          184  +		return 2;
          185  +	    }
          186  +	    return LocateDependency(argv[2]);
   162    187   	}
   163    188       }
   164    189       chars = snprintf(msg, sizeof(msg) - 1,
   165         -	    "usage: %s -c|-l|-f|-g|-V ...\n"
          190  +	    "usage: %s -c|-f|-l|-Q|-s|-V ...\n"
   166    191   	    "This is a little helper app to equalize shell differences between WinNT and\n"
   167    192   	    "Win9x and get nmake.exe to accomplish its job.\n",
   168    193   	    argv[0]);
   169    194       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
   170    195       return 2;
   171    196   }
   172    197   
   173         -int
          198  +static int
   174    199   CheckForCompilerFeature(
   175    200       const char *option)
   176    201   {
   177    202       STARTUPINFO si;
   178    203       PROCESS_INFORMATION pi;
   179    204       SECURITY_ATTRIBUTES sa;
   180    205       DWORD threadID;
................................................................................
   251    276   	DWORD err = GetLastError();
   252    277   	int chars = snprintf(msg, sizeof(msg) - 1,
   253    278   		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
   254    279   
   255    280   	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
   256    281   		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
   257    282   		(300-chars), 0);
   258         -	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
          283  +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
   259    284   	return 2;
   260    285       }
   261    286   
   262    287       /*
   263    288        * Close our references to the write handles that have now been inherited.
   264    289        */
   265    290   
................................................................................
   295    320        * Look for the commandline warning code in both streams.
   296    321        *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
   297    322        */
   298    323   
   299    324       return !(strstr(Out.buffer, "D4002") != NULL
   300    325                || strstr(Err.buffer, "D4002") != NULL
   301    326                || strstr(Out.buffer, "D9002") != NULL
   302         -             || strstr(Err.buffer, "D9002") != NULL);
          327  +             || strstr(Err.buffer, "D9002") != NULL
          328  +             || strstr(Out.buffer, "D2021") != NULL
          329  +             || strstr(Err.buffer, "D2021") != NULL);
   303    330   }
   304    331   
   305         -int
          332  +static int
   306    333   CheckForLinkerFeature(
   307         -    const char *option)
          334  +    const char **options,
          335  +    int count)
   308    336   {
   309    337       STARTUPINFO si;
   310    338       PROCESS_INFORMATION pi;
   311    339       SECURITY_ATTRIBUTES sa;
   312    340       DWORD threadID;
   313    341       char msg[300];
   314    342       BOOL ok;
   315    343       HANDLE hProcess, h, pipeThreads[2];
   316         -    char cmdline[100];
          344  +    int i;
          345  +    char cmdline[255];
   317    346   
   318    347       hProcess = GetCurrentProcess();
   319    348   
   320    349       ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
   321    350       ZeroMemory(&si, sizeof(STARTUPINFO));
   322    351       si.cb = sizeof(STARTUPINFO);
   323    352       si.dwFlags   = STARTF_USESTDHANDLES;
................................................................................
   355    384   
   356    385       lstrcpy(cmdline, "link.exe -nologo ");
   357    386   
   358    387       /*
   359    388        * Append our option for testing.
   360    389        */
   361    390   
   362         -    lstrcat(cmdline, option);
          391  +    for (i = 0; i < count; i++) {
          392  +	lstrcat(cmdline, " \"");
          393  +	lstrcat(cmdline, options[i]);
          394  +	lstrcat(cmdline, "\"");
          395  +    }
   363    396   
   364    397       ok = CreateProcess(
   365    398   	    NULL,	    /* Module name. */
   366    399   	    cmdline,	    /* Command line. */
   367    400   	    NULL,	    /* Process handle not inheritable. */
   368    401   	    NULL,	    /* Thread handle not inheritable. */
   369    402   	    TRUE,	    /* yes, inherit handles. */
................................................................................
   377    410   	DWORD err = GetLastError();
   378    411   	int chars = snprintf(msg, sizeof(msg) - 1,
   379    412   		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
   380    413   
   381    414   	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
   382    415   		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
   383    416   		(300-chars), 0);
   384         -	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
          417  +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
   385    418   	return 2;
   386    419       }
   387    420   
   388    421       /*
   389    422        * Close our references to the write handles that have now been inherited.
   390    423        */
   391    424   
................................................................................
   420    453       /*
   421    454        * Look for the commandline warning code in the stderr stream.
   422    455        */
   423    456   
   424    457       return !(strstr(Out.buffer, "LNK1117") != NULL ||
   425    458   	    strstr(Err.buffer, "LNK1117") != NULL ||
   426    459   	    strstr(Out.buffer, "LNK4044") != NULL ||
   427         -	    strstr(Err.buffer, "LNK4044") != NULL);
          460  +	    strstr(Err.buffer, "LNK4044") != NULL ||
          461  +	    strstr(Out.buffer, "LNK4224") != NULL ||
          462  +	    strstr(Err.buffer, "LNK4224") != NULL);
   428    463   }
   429    464   
   430         -DWORD WINAPI
          465  +static DWORD WINAPI
   431    466   ReadFromPipe(
   432    467       LPVOID args)
   433    468   {
   434    469       pipeinfo *pi = (pipeinfo *) args;
   435    470       char *lastBuf = pi->buffer;
   436    471       DWORD dwRead;
   437    472       BOOL ok;
................................................................................
   448    483       }
   449    484       lastBuf += dwRead;
   450    485       goto again;
   451    486   
   452    487       return 0;  /* makes the compiler happy */
   453    488   }
   454    489   
   455         -int
          490  +static int
   456    491   IsIn(
   457    492       const char *string,
   458    493       const char *substring)
   459    494   {
   460    495       return (strstr(string, substring) != NULL);
   461    496   }
   462         -
   463         -/*
   464         - * Find a specified #define by name.
   465         - *
   466         - * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
   467         - */
   468         -
   469         -int
   470         -GrepForDefine(
   471         -    const char *file,
   472         -    const char *string)
   473         -{
   474         -    char s1[51], s2[51], s3[51];
   475         -    FILE *f = fopen(file, "rt");
   476         -
   477         -    if (f == NULL) {
   478         -	return 0;
   479         -    }
   480         -
   481         -    do {
   482         -	int r = fscanf(f, "%50s", s1);
   483         -
   484         -	if (r == 1 && !strcmp(s1, "#define")) {
   485         -	    /*
   486         -	     * Get next two words.
   487         -	     */
   488         -
   489         -	    r = fscanf(f, "%50s %50s", s2, s3);
   490         -	    if (r != 2) {
   491         -		continue;
   492         -	    }
   493         -
   494         -	    /*
   495         -	     * Is the first word what we're looking for?
   496         -	     */
   497         -
   498         -	    if (!strcmp(s2, string)) {
   499         -		double d1;
   500         -
   501         -		fclose(f);
   502         -
   503         -		/*
   504         -		 * Add 1 past first double quote char. "8.5"
   505         -		 */
   506         -
   507         -		d1 = atof(s3 + 1);		  /*    8.5  */
   508         -		while (floor(d1) != d1) {
   509         -		    d1 *= 10.0;
   510         -		}
   511         -		return ((int) d1);		  /*    85   */
   512         -	    }
   513         -	}
   514         -    } while (!feof(f));
   515         -
   516         -    fclose(f);
   517         -    return 0;
   518         -}
   519    497   
   520    498   /*
   521    499    * GetVersionFromFile --
   522    500    * 	Looks for a match string in a file and then returns the version
   523    501    * 	following the match where a version is anything acceptable to
   524    502    * 	package provide or package ifneeded.
   525    503    */
   526    504   
   527         -const char *
          505  +static const char *
   528    506   GetVersionFromFile(
   529    507       const char *filename,
   530         -    const char *match)
          508  +    const char *match,
          509  +    int numdots)
   531    510   {
   532    511       size_t cbBuffer = 100;
   533    512       static char szBuffer[100];
   534    513       char *szResult = NULL;
   535    514       FILE *fp = fopen(filename, "rt");
   536    515   
   537    516       if (fp != NULL) {
................................................................................
   541    520   
   542    521   	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
   543    522   	    LPSTR p, q;
   544    523   
   545    524   	    p = strstr(szBuffer, match);
   546    525   	    if (p != NULL) {
   547    526   		/*
   548         -		 * Skip to first digit.
          527  +		 * Skip to first digit after the match.
   549    528   		 */
   550    529   
          530  +		p += strlen(match);
   551    531   		while (*p && !isdigit(*p)) {
   552    532   		    ++p;
   553    533   		}
   554    534   
   555    535   		/*
   556    536   		 * Find ending whitespace.
   557    537   		 */
   558    538   
   559    539   		q = p;
   560         -		while (*q && (isalnum(*q) || *q == '.')) {
          540  +		while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q)
          541  +			    && (!strchr("ab", q[-1])) || --numdots))) {
   561    542   		    ++q;
   562    543   		}
   563    544   
   564    545   		memcpy(szBuffer, p, q - p);
   565    546   		szBuffer[q-p] = 0;
   566    547   		szResult = szBuffer;
   567    548   		break;
................................................................................
   626    607    *	Usage is something like:
   627    608    *	  nmakehlp -S << $** > $@
   628    609    *        @PACKAGE_NAME@ $(PACKAGE_NAME)
   629    610    *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
   630    611    *        <<
   631    612    */
   632    613   
   633         -int
          614  +static int
   634    615   SubstituteFile(
   635    616       const char *substitutions,
   636    617       const char *filename)
   637    618   {
   638    619       size_t cbBuffer = 1024;
   639    620       static char szBuffer[1024], szCopy[1024];
   640    621       char *szResult = NULL;
................................................................................
   647    628   	/*
   648    629   	 * Build a list of substutitions from the first filename
   649    630   	 */
   650    631   
   651    632   	sp = fopen(substitutions, "rt");
   652    633   	if (sp != NULL) {
   653    634   	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
   654         -		char *ks, *ke, *vs, *ve;
   655         -		ks = szBuffer;
          635  +		unsigned char *ks, *ke, *vs, *ve;
          636  +		ks = (unsigned char*)szBuffer;
   656    637   		while (ks && *ks && isspace(*ks)) ++ks;
   657    638   		ke = ks;
   658    639   		while (ke && *ke && !isspace(*ke)) ++ke;
   659    640   		vs = ke;
   660    641   		while (vs && *vs && isspace(*vs)) ++vs;
   661    642   		ve = vs;
   662    643   		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
   663    644   		*ke = 0, *ve = 0;
   664         -		list_insert(&substPtr, ks, vs);
          645  +		list_insert(&substPtr, (char*)ks, (char*)vs);
   665    646   	    }
   666    647   	    fclose(sp);
   667    648   	}
   668    649   
   669    650   	/* debug: dump the list */
   670    651   #ifdef _DEBUG
   671    652   	{
................................................................................
   672    653   	    int n = 0;
   673    654   	    list_item_t *p = NULL;
   674    655   	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
   675    656   		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
   676    657   	    }
   677    658   	}
   678    659   #endif
   679         -	
          660  +
   680    661   	/*
   681    662   	 * Run the substitutions over each line of the input
   682    663   	 */
   683         -	
          664  +
   684    665   	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
   685    666   	    list_item_t *p = NULL;
   686    667   	    for (p = substPtr; p != NULL; p = p->nextPtr) {
   687    668   		char *m = strstr(szBuffer, p->key);
   688    669   		if (m) {
   689    670   		    char *cp, *op, *sp;
   690    671   		    cp = szCopy;
................................................................................
   696    677   		    while (*op) *cp++ = *op++;
   697    678   		    *cp = 0;
   698    679   		    memcpy(szBuffer, szCopy, sizeof(szCopy));
   699    680   		}
   700    681   	    }
   701    682   	    printf(szBuffer);
   702    683   	}
   703         -	
          684  +
   704    685   	list_free(&substPtr);
   705    686       }
   706    687       fclose(fp);
   707    688       return 0;
   708    689   }
          690  +
          691  +/*
          692  + * QualifyPath --
          693  + *
          694  + *	This composes the current working directory with a provided path
          695  + *	and returns the fully qualified and normalized path.
          696  + *	Mostly needed to setup paths for testing.
          697  + */
          698  +
          699  +static int
          700  +QualifyPath(
          701  +    const char *szPath)
          702  +{
          703  +    char szCwd[MAX_PATH + 1];
          704  +    char szTmp[MAX_PATH + 1];
          705  +    char *p;
          706  +    GetCurrentDirectory(MAX_PATH, szCwd);
          707  +    while ((p = strchr(szPath, '/')) && *p)
          708  +	*p = '\\';
          709  +    PathCombine(szTmp, szCwd, szPath);
          710  +    PathCanonicalize(szCwd, szTmp);
          711  +    printf("%s\n", szCwd);
          712  +    return 0;
          713  +}
          714  +
          715  +/*
          716  + * Implements LocateDependency for a single directory. See that command
          717  + * for an explanation.
          718  + * Returns 0 if found after printing the directory.
          719  + * Returns 1 if not found but no errors.
          720  + * Returns 2 on any kind of error
          721  + * Basically, these are used as exit codes for the process.
          722  + */
          723  +static int LocateDependencyHelper(const char *dir, const char *keypath)
          724  +{
          725  +    HANDLE hSearch;
          726  +    char path[MAX_PATH+1];
          727  +    int dirlen, keylen, ret;
          728  +    WIN32_FIND_DATA finfo;
          729  +
          730  +    if (dir == NULL || keypath == NULL)
          731  +	return 2; /* Have no real error reporting mechanism into nmake */
          732  +    dirlen = strlen(dir);
          733  +    if ((dirlen + 3) > sizeof(path))
          734  +	return 2;
          735  +    strncpy(path, dir, dirlen);
          736  +    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
          737  +    keylen = strlen(keypath);
          738  +
          739  +#if 0 /* This function is not available in Visual C++ 6 */
          740  +    /*
          741  +     * Use numerics 0 -> FindExInfoStandard,
          742  +     * 1 -> FindExSearchLimitToDirectories, 
          743  +     * as these are not defined in Visual C++ 6
          744  +     */
          745  +    hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
          746  +#else
          747  +    hSearch = FindFirstFile(path, &finfo);
          748  +#endif
          749  +    if (hSearch == INVALID_HANDLE_VALUE)
          750  +	return 1; /* Not found */
          751  +
          752  +    /* Loop through all subdirs checking if the keypath is under there */
          753  +    ret = 1; /* Assume not found */
          754  +    do {
          755  +	int sublen;
          756  +	/*
          757  +	 * We need to check it is a directory despite the 
          758  +	 * FindExSearchLimitToDirectories in the above call. See SDK docs
          759  +	 */
          760  +	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
          761  +	    continue;
          762  +	sublen = strlen(finfo.cFileName);
          763  +	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
          764  +	    continue;		/* Path does not fit, assume not matched */
          765  +	strncpy(path+dirlen+1, finfo.cFileName, sublen);
          766  +	path[dirlen+1+sublen] = '\\';
          767  +	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
          768  +	if (PathFileExists(path)) {
          769  +	    /* Found a match, print to stdout */
          770  +	    path[dirlen+1+sublen] = '\0';
          771  +	    QualifyPath(path);
          772  +	    ret = 0;
          773  +	    break;
          774  +	}
          775  +    } while (FindNextFile(hSearch, &finfo));
          776  +    FindClose(hSearch);
          777  +    return ret;
          778  +}
          779  +
          780  +/*
          781  + * LocateDependency --
          782  + *
          783  + *	Locates a dependency for a package.
          784  + *        keypath - a relative path within the package directory
          785  + *          that is used to confirm it is the correct directory.
          786  + *	The search path for the package directory is currently only
          787  + *      the parent and grandparent of the current working directory.
          788  + *      If found, the command prints 
          789  + *         name_DIRPATH=<full path of located directory>
          790  + *      and returns 0. If not found, does not print anything and returns 1.
          791  + */
          792  +static int LocateDependency(const char *keypath)
          793  +{
          794  +    int i, ret;
          795  +    static char *paths[] = {"..", "..\\..", "..\\..\\.."};
          796  +    
          797  +    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
          798  +	ret = LocateDependencyHelper(paths[i], keypath);
          799  +	if (ret == 0)
          800  +	    return ret;
          801  +    }
          802  +    return ret;
          803  +}
          804  +
   709    805   
   710    806   /*
   711    807    * Local variables:
   712    808    *   mode: c
   713    809    *   c-basic-offset: 4
   714    810    *   fill-column: 78
   715    811    *   indent-tabs-mode: t
   716    812    *   tab-width: 8
   717    813    * End:
   718    814    */

Changes to win/pkgIndex.tcl.

     1      1   # tDOM Tcl package index file
     2      2   
     3         -package ifneeded tdom 0.8.3 \
     4         -    "[list load   [file join $dir tdom083[info sharedlibextension] ] tdom];\
            3  +package ifneeded tdom 0.9.1 \
            4  +    "[list load   [file join $dir tdom091[info sharedlibextension] ] tdom];\
     5      5        [list source [file join $dir tdom.tcl]]"

Added win/rules-ext.vc.

            1  +# This file should only be included in makefiles for Tcl extensions,
            2  +# NOT in the makefile for Tcl itself.
            3  +
            4  +!ifndef _RULES_EXT_VC
            5  +
            6  +# We need to run from the directory the parent makefile is located in.
            7  +# nmake does not tell us what makefile was used to invoke it so parent
            8  +# makefile has to set the MAKEFILEVC macro or we just make a guess and
            9  +# warn if we think that is not the case.
           10  +!if "$(MAKEFILEVC)" == ""
           11  +
           12  +!if exist("$(PROJECT).vc")
           13  +MAKEFILEVC = $(PROJECT).vc
           14  +!elseif exist("makefile.vc")
           15  +MAKEFILEVC = makefile.vc
           16  +!endif
           17  +!endif # "$(MAKEFILEVC)" == ""
           18  +
           19  +!if !exist("$(MAKEFILEVC)")
           20  +MSG = ^
           21  +You must run nmake from the directory containing the project makefile.^
           22  +If you are doing that and getting this message, set the MAKEFILEVC^
           23  +macro to the name of the project makefile.
           24  +!message WARNING: $(MSG)
           25  +!endif
           26  +
           27  +!if "$(PROJECT)" == "tcl"
           28  +!error The rules-ext.vc file is not intended for Tcl itself.
           29  +!endif
           30  +
           31  +# We extract version numbers using the nmakehlp program. For now use
           32  +# the local copy of nmakehlp. Once we locate Tcl, we will use that
           33  +# one if it is newer.
           34  +!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
           35  +!endif
           36  +
           37  +# First locate the Tcl directory that we are working with.
           38  +!ifdef TCLDIR
           39  +
           40  +_RULESDIR = $(TCLDIR:/=\)
           41  +
           42  +!else
           43  +
           44  +# If an installation path is specified, that is also the Tcl directory.
           45  +# Also Tk never builds against an installed Tcl, it needs Tcl sources
           46  +!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
           47  +_RULESDIR=$(INSTALLDIR:/=\)
           48  +!else
           49  +# Locate Tcl sources
           50  +!if [echo _RULESDIR = \> nmakehlp.out] \
           51  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
           52  +_RULESDIR = ..\..\tcl
           53  +!else
           54  +!include nmakehlp.out
           55  +!endif
           56  +
           57  +!endif # defined(INSTALLDIR)....
           58  +
           59  +!endif # ifndef TCLDIR
           60  +
           61  +# Now look for the targets.vc file under the Tcl root. Note we check this
           62  +# file and not rules.vc because the latter also exists on older systems.
           63  +!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
           64  +_RULESDIR = $(_RULESDIR)\lib\nmake
           65  +!elseif exist("$(_RULESDIR)\win\targets.vc")   # Building against Tcl sources
           66  +_RULESDIR = $(_RULESDIR)\win
           67  +!else
           68  +# If we have not located Tcl's targets file, most likely we are compiling
           69  +# against an older version of Tcl and so must use our own support files.
           70  +_RULESDIR = .
           71  +!endif
           72  +
           73  +!if "$(_RULESDIR)" != "."
           74  +# Potentially using Tcl's support files. If this extension has its own
           75  +# nmake support files, need to compare the versions and pick newer.
           76  +
           77  +!if exist("rules.vc") # The extension has its own copy
           78  +
           79  +!if [echo TCL_RULES_MAJOR = \> versions.vc] \
           80  +   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
           81  +!endif
           82  +!if [echo TCL_RULES_MINOR = \>> versions.vc] \
           83  +   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
           84  +!endif
           85  +
           86  +!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
           87  +   && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
           88  +!endif
           89  +!if [echo OUR_RULES_MINOR = \>> versions.vc] \
           90  +   && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
           91  +!endif
           92  +!include versions.vc
           93  +# We have a newer version of the support files, use them
           94  +!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
           95  +_RULESDIR = .
           96  +!endif
           97  +
           98  +!endif # if exist("rules.vc")
           99  +
          100  +!endif # if $(_RULESDIR) != "."
          101  +
          102  +# Let rules.vc know what copy of nmakehlp.c to use.
          103  +NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
          104  +
          105  +# Get rid of our internal defines before calling rules.vc
          106  +!undef TCL_RULES_MAJOR
          107  +!undef TCL_RULES_MINOR
          108  +!undef OUR_RULES_MAJOR
          109  +!undef OUR_RULES_MINOR
          110  +
          111  +!if exist("$(_RULESDIR)\rules.vc")
          112  +!message *** Using $(_RULESDIR)\rules.vc
          113  +!include "$(_RULESDIR)\rules.vc"
          114  +!else
          115  +!error *** Could not locate rules.vc in $(_RULESDIR)
          116  +!endif
          117  +
          118  +!endif # _RULES_EXT_VC

Changes to win/rules.vc.

     1         -#------------------------------------------------------------------------------
            1  +#------------------------------------------------------------- -*- makefile -*-
     2      2   # rules.vc --
     3      3   #
     4         -#	Microsoft Visual C++ makefile include for decoding the commandline
     5         -#	macros.  This file does not need editing to build Tcl.
            4  +# Part of the nmake based build system for Tcl and its extensions.
            5  +# This file does all the hard work in terms of parsing build options,
            6  +# compiler switches, defining common targets and macros. The Tcl makefile
            7  +# directly includes this. Extensions include it via "rules-ext.vc".
     6      8   #
     7         -#	This version is modified from the Tcl source version to support
     8         -#	building extensions using nmake.
            9  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
           10  +# detailed documentation.
     9     11   #
    10     12   # See the file "license.terms" for information on usage and redistribution
    11     13   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    12         -# 
    13         -# Copyright (c) 2001-2002 David Gravereaux.
    14         -# Copyright (c) 2003-2005 Patrick Thoyts
    15     14   #
    16         -#------------------------------------------------------------------------------
    17         -# RCS: @(#) $Id$
           15  +# Copyright (c) 2001-2003 David Gravereaux.
           16  +# Copyright (c) 2003-2008 Patrick Thoyts
           17  +# Copyright (c) 2017      Ashok P. Nadkarni
    18     18   #------------------------------------------------------------------------------
    19     19   
    20     20   !ifndef _RULES_VC
    21     21   _RULES_VC = 1
    22     22   
    23         -cc32		= $(CC)   # built-in default.
    24         -link32		= link
    25         -lib32		= lib
    26         -rc32		= $(RC)   # built-in default.
    27         -
    28         -!ifndef INSTALLDIR
    29         -### Assume the normal default.
    30         -_INSTALLDIR	= C:\Program Files\Tcl
    31         -!else
    32         -### Fix the path separators.
    33         -_INSTALLDIR	= $(INSTALLDIR:/=\)
    34         -!endif
    35         -
    36         -!ifndef MACHINE
    37         -!if "$(CPU)" == "" || "$(CPU)" == "i386"
    38         -MACHINE         = IX86
    39         -!else
    40         -MACHINE         = $(CPU)
    41         -!endif
    42         -!endif
    43         -
    44         -!ifndef CFG_ENCODING
    45         -CFG_ENCODING	= \"cp1252\"
    46         -!endif
           23  +# The following macros define the version of the rules.vc nmake build system
           24  +# For modifications that are not backward-compatible, you *must* change
           25  +# the major version.
           26  +RULES_VERSION_MAJOR = 1
           27  +RULES_VERSION_MINOR = 1
           28  +
           29  +# The PROJECT macro must be defined by parent makefile.
           30  +!if "$(PROJECT)" == ""
           31  +!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
           32  +!endif
           33  +
           34  +!if "$(PRJ_PACKAGE_TCLNAME)" == ""
           35  +PRJ_PACKAGE_TCLNAME = $(PROJECT)
           36  +!endif
           37  +
           38  +# Also special case Tcl and Tk to save some typing later
           39  +DOING_TCL = 0
           40  +DOING_TK  = 0
           41  +!if "$(PROJECT)" == "tcl"
           42  +DOING_TCL = 1
           43  +!elseif "$(PROJECT)" == "tk"
           44  +DOING_TK = 1
           45  +!endif
           46  +
           47  +!ifndef NEED_TK
           48  +# Backwards compatibility
           49  +!ifdef PROJECT_REQUIRES_TK
           50  +NEED_TK = $(PROJECT_REQUIRES_TK)
           51  +!else
           52  +NEED_TK = 0
           53  +!endif
           54  +!endif
           55  +
           56  +!ifndef NEED_TCL_SOURCE
           57  +NEED_TCL_SOURCE = 0
           58  +!endif
           59  +
           60  +!ifdef NEED_TK_SOURCE
           61  +!if $(NEED_TK_SOURCE)
           62  +NEED_TK = 1
           63  +!endif
           64  +!else
           65  +NEED_TK_SOURCE = 0
           66  +!endif
           67  +
           68  +################################################################
           69  +# Nmake is a pretty weak environment in syntax and capabilities
           70  +# so this file is necessarily verbose. It's broken down into
           71  +# the following parts.
           72  +#
           73  +# 0. Sanity check that compiler environment is set up and initialize
           74  +#    any built-in settings from the parent makefile
           75  +# 1. First define the external tools used for compiling, copying etc.
           76  +#    as this is independent of everything else.
           77  +# 2. Figure out our build structure in terms of the directory, whether
           78  +#    we are building Tcl or an extension, etc.
           79  +# 3. Determine the compiler and linker versions
           80  +# 4. Build the nmakehlp helper application
           81  +# 5. Determine the supported compiler options and features
           82  +# 6. Parse the OPTS macro value for user-specified build configuration
           83  +# 7. Parse the STATS macro value for statistics instrumentation
           84  +# 8. Parse the CHECKS macro for additional compilation checks
           85  +# 9. Extract Tcl, and possibly Tk, version numbers from the headers
           86  +# 10. Based on this selected configuration, construct the output
           87  +#     directory and file paths
           88  +# 11. Construct the paths where the package is to be installed
           89  +# 12. Set up the actual options passed to compiler and linker based
           90  +#     on the information gathered above.
           91  +# 13. Define some standard build targets and implicit rules. These may
           92  +#     be optionally disabled by the parent makefile.
           93  +# 14. (For extensions only.) Compare the configuration of the target
           94  +#     Tcl and the extensions and warn against discrepancies.
           95  +#
           96  +# One final note about the macro names used. They are as they are
           97  +# for historical reasons. We would like legacy extensions to
           98  +# continue to work with this make include file so be wary of
           99  +# changing them for consistency or clarity.
          100  +
          101  +# 0. Sanity check compiler environment
          102  +
          103  +# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
          104  +# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
          105  +
          106  +!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
          107  +MSG = ^
          108  +Visual C++ compiler environment not initialized.
          109  +!error $(MSG)
          110  +!endif
          111  +
          112  +# We need to run from the directory the parent makefile is located in.
          113  +# nmake does not tell us what makefile was used to invoke it so parent
          114  +# makefile has to set the MAKEFILEVC macro or we just make a guess and
          115  +# warn if we think that is not the case.
          116  +!if "$(MAKEFILEVC)" == ""
          117  +
          118  +!if exist("$(PROJECT).vc")
          119  +MAKEFILEVC = $(PROJECT).vc
          120  +!elseif exist("makefile.vc")
          121  +MAKEFILEVC = makefile.vc
          122  +!endif
          123  +!endif # "$(MAKEFILEVC)" == ""
          124  +
          125  +!if !exist("$(MAKEFILEVC)")
          126  +MSG = ^
          127  +You must run nmake from the directory containing the project makefile.^
          128  +If you are doing that and getting this message, set the MAKEFILEVC^
          129  +macro to the name of the project makefile.
          130  +!message WARNING: $(MSG)
          131  +!endif
          132  +
          133  +
          134  +################################################################
          135  +# 1. Define external programs being used
    47    136   
    48    137   #----------------------------------------------------------
    49    138   # Set the proper copy method to avoid overwrite questions
    50    139   # to the user when copying files and selecting the right
    51    140   # "delete all" method.
    52    141   #----------------------------------------------------------
    53    142   
    54         -!if "$(OS)" == "Windows_NT"
    55    143   RMDIR	= rmdir /S /Q
    56         -ERRNULL  = 2>NUL
    57         -!if ![ver | find "4.0" > nul]
    58         -CPY	= echo y | xcopy /i >NUL
    59         -COPY	= copy >NUL
    60         -!else
    61    144   CPY	= xcopy /i /y >NUL
          145  +CPYDIR  = xcopy /e /i /y >NUL
    62    146   COPY	= copy /y >NUL
    63         -!endif
    64         -!else # "$(OS)" != "Windows_NT"
    65         -CPY	= xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
    66         -COPY	= copy >_JUNK.OUT # On Win98 NUL does not work here.
    67         -RMDIR	= deltree /Y
    68         -NULL    = \NUL # Used in testing directory existence
    69         -ERRNULL = >NUL # Win9x shell cannot redirect stderr
    70         -!endif
    71    147   MKDIR   = mkdir
    72    148   
    73         -!message ===============================================================================
    74         -
    75         -#----------------------------------------------------------
    76         -# build the helper app we need to overcome nmake's limiting
    77         -# environment.
    78         -#----------------------------------------------------------
    79         -
    80         -!if !exist(nmakehlp.exe)
    81         -!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
    82         -!endif
    83         -!endif
    84         -
    85         -#----------------------------------------------------------
    86         -# Test for compiler features
    87         -#----------------------------------------------------------
    88         -
    89         -### test for optimizations
    90         -!if [nmakehlp -c -Ot]
    91         -!message *** Compiler has 'Optimizations'
    92         -OPTIMIZING	= 1
    93         -!else
    94         -!message *** Compiler doesn't have 'Optimizations'
    95         -OPTIMIZING	= 0
    96         -!endif
    97         -
    98         -OPTIMIZATIONS  =
    99         -
   100         -!if [nmakehlp -c -Ot]
   101         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
   102         -!endif
   103         -
   104         -!if [nmakehlp -c -Oi]
   105         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
   106         -!endif
   107         -
          149  +######################################################################
          150  +# 2. Figure out our build environment in terms of what we're building.
          151  +#
          152  +# (a) Tcl itself
          153  +# (b) Tk
          154  +# (c) a Tcl extension using libraries/includes from an *installed* Tcl
          155  +# (d) a Tcl extension using libraries/includes from Tcl source directory
          156  +#
          157  +# This last is needed because some extensions still need
          158  +# some Tcl interfaces that are not publicly exposed.
          159  +#
          160  +# The fragment will set the following macros:
          161  +# ROOT - root of this module sources
          162  +# COMPATDIR - source directory that holds compatibility sources
          163  +# DOCDIR - source directory containing documentation files
          164  +# GENERICDIR - platform-independent source directory
          165  +# WINDIR - Windows-specific source directory
          166  +# TESTDIR - directory containing test files
          167  +# TOOLSDIR - directory containing build tools
          168  +# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
          169  +#    when building Tcl itself.
          170  +# _INSTALLDIR - native form of the installation path. For Tcl
          171  +#    this will be the root of the Tcl installation. For extensions
          172  +#    this will be the lib directory under the root.
          173  +# TCLINSTALL  - set to 1 if _TCLDIR refers to
          174  +#    headers and libraries from an installed Tcl, and 0 if built against
          175  +#    Tcl sources. Not set when building Tcl itself. Yes, not very well
          176  +#    named.
          177  +# _TCL_H - native path to the tcl.h file
          178  +#
          179  +# If Tk is involved, also sets the following
          180  +# _TKDIR - native form Tk installation OR Tk source. Not set if building
          181  +#    Tk itself.
          182  +# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
          183  +# _TK_H - native path to the tk.h file
          184  +
          185  +# Root directory for sources and assumed subdirectories
          186  +ROOT = $(MAKEDIR)\..
          187  +# The following paths CANNOT have spaces in them as they appear on the
          188  +# left side of implicit rules.
          189  +!ifndef COMPATDIR
          190  +COMPATDIR	= $(ROOT)\compat
          191  +!endif
          192  +!ifndef DOCDIR
          193  +DOCDIR		= $(ROOT)\doc
          194  +!endif
          195  +!ifndef GENERICDIR
          196  +GENERICDIR	= $(ROOT)\generic
          197  +!endif
          198  +!ifndef TOOLSDIR
          199  +TOOLSDIR	= $(ROOT)\tools
          200  +!endif
          201  +!ifndef TESTDIR
          202  +TESTDIR	= $(ROOT)\tests
          203  +!endif
          204  +!ifndef LIBDIR
          205  +!if exist("$(ROOT)\library")
          206  +LIBDIR          = $(ROOT)\library
          207  +!else
          208  +LIBDIR          = $(ROOT)\lib
          209  +!endif
          210  +!endif
          211  +!ifndef DEMODIR
          212  +!if exist("$(LIBDIR)\demos")
          213  +DEMODIR		= $(LIBDIR)\demos
          214  +!else
          215  +DEMODIR		= $(ROOT)\demos
          216  +!endif
          217  +!endif # ifndef DEMODIR
          218  +# Do NOT enclose WINDIR in a !ifndef because Windows always defines
          219  +# WINDIR env var to point to c:\windows!
          220  +# TBD - This is a potentially dangerous conflict, rename WINDIR to
          221  +# something else
          222  +WINDIR		= $(ROOT)\win
          223  +
          224  +!ifndef RCDIR
          225  +!if exist("$(WINDIR)\rc")
          226  +RCDIR           = $(WINDIR)\rc
          227  +!else
          228  +RCDIR           = $(WINDIR)
          229  +!endif
          230  +!endif
          231  +RCDIR = $(RCDIR:/=\)
          232  +
          233  +# The target directory where the built packages and binaries will be installed.
          234  +# INSTALLDIR is the (optional) path specified by the user.
          235  +# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
          236  +!ifdef INSTALLDIR
          237  +### Fix the path separators.
          238  +_INSTALLDIR	= $(INSTALLDIR:/=\)
          239  +!else
          240  +### Assume the normal default.
          241  +_INSTALLDIR	= $(HOMEDRIVE)\Tcl
          242  +!endif
          243  +
          244  +!if $(DOING_TCL)
          245  +
          246  +# BEGIN Case 2(a) - Building Tcl itself
          247  +
          248  +# Only need to define _TCL_H
          249  +_TCL_H = ..\generic\tcl.h
          250  +
          251  +# END Case 2(a) - Building Tcl itself
          252  +
          253  +!elseif $(DOING_TK)
          254  +
          255  +# BEGIN Case 2(b) - Building Tk
          256  +
          257  +TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
          258  +!if "$(TCLDIR)" == ""
          259  +!if [echo TCLDIR = \> nmakehlp.out] \
          260  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
          261  +!error *** Could not locate Tcl source directory.
          262  +!endif
          263  +!include nmakehlp.out
          264  +!endif # TCLDIR == ""
          265  +
          266  +_TCLDIR	= $(TCLDIR:/=\)
          267  +_TCL_H  = $(_TCLDIR)\generic\tcl.h
          268  +!if !exist("$(_TCL_H)")
          269  +!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
          270  +!endif
          271  +
          272  +_TK_H = ..\generic\tk.h
          273  +
          274  +# END Case 2(b) - Building Tk
          275  +
          276  +!else
          277  +
          278  +# BEGIN Case 2(c) or (d) - Building an extension other than Tk
          279  +
          280  +# If command line has specified Tcl location through TCLDIR, use it
          281  +# else default to the INSTALLDIR setting
          282  +!if "$(TCLDIR)" != ""
          283  +
          284  +_TCLDIR	= $(TCLDIR:/=\)
          285  +!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
          286  +TCLINSTALL	= 1
          287  +_TCL_H          = $(_TCLDIR)\include\tcl.h
          288  +!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
          289  +TCLINSTALL	= 0
          290  +_TCL_H          = $(_TCLDIR)\generic\tcl.h
          291  +!endif
          292  +
          293  +!else  #  # Case 2(c) for extensions with TCLDIR undefined
          294  +
          295  +# Need to locate Tcl depending on whether it needs Tcl source or not.
          296  +# If we don't, check the INSTALLDIR for an installed Tcl first
          297  +
          298  +!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
          299  +
          300  +TCLINSTALL	= 1
          301  +TCLDIR          = $(_INSTALLDIR)\..
          302  +# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
          303  +# later so the \.. accounts for the /lib
          304  +_TCLDIR		= $(_INSTALLDIR)\..
          305  +_TCL_H          = $(_TCLDIR)\include\tcl.h
          306  +
          307  +!else # exist(...) && ! $(NEED_TCL_SOURCE)
          308  +
          309  +!if [echo _TCLDIR = \> nmakehlp.out] \
          310  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
          311  +!error *** Could not locate Tcl source directory.
          312  +!endif
          313  +!include nmakehlp.out
          314  +TCLINSTALL      = 0
          315  +TCLDIR         = $(_TCLDIR)
          316  +_TCL_H          = $(_TCLDIR)\generic\tcl.h
          317  +
          318  +!endif # exist(...) && ! $(NEED_TCL_SOURCE)
          319  +
          320  +!endif # TCLDIR
          321  +
          322  +!ifndef _TCL_H
          323  +MSG =^
          324  +Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
          325  +!error $(MSG)
          326  +!endif
          327  +
          328  +# Now do the same to locate Tk headers and libs if project requires Tk
          329  +!if $(NEED_TK)
          330  +
          331  +!if "$(TKDIR)" != ""
          332  +
          333  +_TKDIR = $(TKDIR:/=\)
          334  +!if exist("$(_TKDIR)\include\tk.h")
          335  +TKINSTALL      = 1
          336  +_TK_H          = $(_TKDIR)\include\tk.h
          337  +!elseif exist("$(_TKDIR)\generic\tk.h")
          338  +TKINSTALL      = 0
          339  +_TK_H          = $(_TKDIR)\generic\tk.h
          340  +!endif
          341  +
          342  +!else # TKDIR not defined
          343  +
          344  +# Need to locate Tcl depending on whether it needs Tcl source or not.
          345  +# If we don't, check the INSTALLDIR for an installed Tcl first
          346  +
          347  +!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          348  +
          349  +TKINSTALL      = 1
          350  +# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
          351  +# later so the \.. accounts for the /lib
          352  +_TKDIR         = $(_INSTALLDIR)\..
          353  +_TK_H          = $(_TKDIR)\include\tk.h
          354  +TKDIR          = $(_TKDIR)
          355  +
          356  +!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          357  +
          358  +!if [echo _TKDIR = \> nmakehlp.out] \
          359  +   || [nmakehlp -L generic\tk.h >> nmakehlp.out]
          360  +!error *** Could not locate Tk source directory.
          361  +!endif
          362  +!include nmakehlp.out
          363  +TKINSTALL      = 0
          364  +TKDIR          = $(_TKDIR)
          365  +_TK_H          = $(_TKDIR)\generic\tk.h
          366  +
          367  +!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          368  +
          369  +!endif # TKDIR
          370  +
          371  +!ifndef _TK_H
          372  +MSG =^
          373  +Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
          374  +!error $(MSG)
          375  +!endif
          376  +
          377  +!endif # NEED_TK
          378  +
          379  +!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
          380  +MSG = ^
          381  +*** Warning: This extension requires the source distribution of Tcl.^
          382  +*** Please set the TCLDIR macro to point to the Tcl sources.
          383  +!error $(MSG)
          384  +!endif
          385  +
          386  +!if $(NEED_TK_SOURCE)
          387  +!if $(TKINSTALL)
          388  +MSG = ^
          389  +*** Warning: This extension requires the source distribution of Tk.^
          390  +*** Please set the TKDIR macro to point to the Tk sources.
          391  +!error $(MSG)
          392  +!endif
          393  +!endif
          394  +
          395  +
          396  +# If INSTALLDIR set to Tcl installation root dir then reset to the
          397  +# lib dir for installing extensions 
          398  +!if exist("$(_INSTALLDIR)\include\tcl.h")
          399  +_INSTALLDIR=$(_INSTALLDIR)\lib
          400  +!endif
          401  +
          402  +# END Case 2(c) or (d) - Building an extension
          403  +!endif # if $(DOING_TCL)
          404  +
          405  +################################################################
          406  +# 3. Determine compiler version and architecture
          407  +# In this section, we figure out the compiler version and the
          408  +# architecture for which we are building. This sets the
          409  +# following macros:
          410  +# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
          411  +#     This is also printed by the compiler in dotted form 19.10 etc.
          412  +# VCVER - the "marketing version", for example Visual C++ 6 for internal
          413  +#     compiler version 1200. This is kept only for legacy reasons as it
          414  +#     does not make sense for recent Microsoft compilers. Only used for
          415  +#     output directory names.
          416  +# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
          417  +# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
          418  +# MACHINE - same as $(ARCH) - legacy
          419  +# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
          420  +# CFG_ENCODING - set to an character encoding.
          421  +#   TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
          422  +#   see where it is used
          423  +
          424  +cc32		= $(CC)   # built-in default.
          425  +link32		= link
          426  +lib32		= lib
          427  +rc32		= $(RC)   # built-in default.
          428  +
          429  +#----------------------------------------------------------------
          430  +# Figure out the compiler architecture and version by writing
          431  +# the C macros to a file, preprocessing them with the C
          432  +# preprocessor and reading back the created file
          433  +
          434  +_HASH=^#
          435  +_VC_MANIFEST_EMBED_EXE=
          436  +_VC_MANIFEST_EMBED_DLL=
          437  +VCVER=0
          438  +!if ![echo VCVERSION=_MSC_VER > vercl.x] \
          439  +    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
          440  +    && ![echo ARCH=IX86 >> vercl.x] \
          441  +    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
          442  +    && ![echo ARCH=AMD64 >> vercl.x] \
          443  +    && ![echo $(_HASH)endif >> vercl.x] \
          444  +    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
          445  +!include vercl.i
          446  +!if $(VCVERSION) < 1900
          447  +!if ![echo VCVER= ^\> vercl.vc] \
          448  +    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
          449  +!include vercl.vc
          450  +!endif
          451  +!else
          452  +# The simple calculation above does not apply to new Visual Studio releases
          453  +# Keep the compiler version in its native form.
          454  +VCVER = $(VCVERSION)
          455  +!endif
          456  +!endif
          457  +
          458  +!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
          459  +!endif
          460  +
          461  +#----------------------------------------------------------------
          462  +# The MACHINE macro is used by legacy makefiles so set it as well
          463  +!ifdef MACHINE
          464  +!if "$(MACHINE)" == "x86"
          465  +!undef MACHINE
          466  +MACHINE = IX86
          467  +!elseif "$(MACHINE)" == "x64"
          468  +!undef MACHINE
          469  +MACHINE = AMD64
          470  +!endif
          471  +!if "$(MACHINE)" != "$(ARCH)"
          472  +!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
          473  +!endif
          474  +!else
          475  +MACHINE=$(ARCH)
          476  +!endif
          477  +
          478  +#------------------------------------------------------------
          479  +# Figure out the *host* architecture by reading the registry
          480  +
          481  +!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
          482  +NATIVE_ARCH=IX86
          483  +!else
          484  +NATIVE_ARCH=AMD64
          485  +!endif
          486  +
          487  +# Since MSVC8 we must deal with manifest resources.
          488  +!if $(VCVERSION) >= 1400
          489  +_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
          490  +_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
          491  +!endif
          492  +
          493  +!ifndef CFG_ENCODING
          494  +CFG_ENCODING	= \"cp1252\"
          495  +!endif
          496  +
          497  +################################################################
          498  +# 4. Build the nmakehlp program
          499  +# This is a helper app we need to overcome nmake's limiting
          500  +# environment. We will call out to it to get various bits of
          501  +# information about supported compiler options etc.
          502  +#
          503  +# Tcl itself will always use the nmakehlp.c program which is
          504  +# in its own source. This is the "master" copy and kept updated.
          505  +#
          506  +# Extensions built against an installed Tcl will use the installed
          507  +# copy of Tcl's nmakehlp.c if there is one and their own version
          508  +# otherwise. In the latter case, they would also be using their own
          509  +# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
          510  +# or rules.vc.
          511  +#
          512  +# Extensions built against Tcl sources will use the one from the Tcl source.
          513  +#
          514  +# When building an extension using a sufficiently new version of Tcl,
          515  +# rules-ext.vc will define NMAKEHLPC appropriately to point to the
          516  +# copy of nmakehlp.c to be used.
          517  +
          518  +!ifndef NMAKEHLPC
          519  +# Default to the one in the current directory (the extension's own nmakehlp.c)
          520  +NMAKEHLPC = nmakehlp.c
          521  +
          522  +!if !$(DOING_TCL)
          523  +!if $(TCLINSTALL)
          524  +!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
          525  +NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
          526  +!endif
          527  +!else # ! $(TCLINSTALL)
          528  +!if exist("$(_TCLDIR)\win\nmakehlp.c")
          529  +NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
          530  +!endif
          531  +!endif # $(TCLINSTALL)
          532  +!endif # !$(DOING_TCL)
          533  +
          534  +!endif # NMAKEHLPC
          535  +
          536  +# We always build nmakehlp even if it exists since we do not know
          537  +# what source it was built from.
          538  +!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
          539  +!endif
          540  +
          541  +################################################################
          542  +# 5. Test for compiler features
          543  +# Visual C++ compiler options have changed over the years. Check
          544  +# which options are supported by the compiler in use.
          545  +#
          546  +# The following macros are set:
          547  +# OPTIMIZATIONS - the compiler flags to be used for optimized builds
          548  +# DEBUGFLAGS - the compiler flags to be used for debug builds
          549  +# LINKERFLAGS - Flags passed to the linker 
          550  +#
          551  +# Note that these are the compiler settings *available*, not those
          552  +# that will be *used*. The latter depends on the OPTS macro settings
          553  +# which we have not yet parsed.
          554  +#
          555  +# Also note that some of the flags in OPTIMIZATIONS are not really
          556  +# related to optimization. They are placed there only for legacy reasons
          557  +# as some extensions expect them to be included in that macro.
          558  +
          559  +# -Op improves float consistency. Note only needed for older compilers
          560  +# Newer compilers do not need or support this option.
   108    561   !if [nmakehlp -c -Op]
   109         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
          562  +FPOPTS  = -Op
   110    563   !endif
   111    564   
          565  +# Strict floating point semantics - present in newer compilers in lieu of -Op
   112    566   !if [nmakehlp -c -fp:strict]
   113         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
   114         -!endif
   115         -
   116         -!if [nmakehlp -c -Gs]
   117         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
   118         -!endif
   119         -
   120         -!if [nmakehlp -c -GS]
   121         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
   122         -!endif
   123         -
   124         -!if [nmakehlp -c -GL]
   125         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
   126         -!endif
   127         -
   128         -DEBUGFLAGS     =
   129         -
   130         -!if [nmakehlp -c -RTC1]
   131         -DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
   132         -!elseif [nmakehlp -c -GZ]
   133         -DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
   134         -!endif
   135         -
   136         -COMPILERFLAGS  =-W3
   137         -
   138         -# In v13 -GL and -YX are incompatible.
   139         -!if [nmakehlp -c -YX]
   140         -!if ![nmakehlp -c -GL]
   141         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
   142         -!endif
          567  +FPOPTS  = $(FPOPTS) -fp:strict
   143    568   !endif
   144    569   
   145    570   !if "$(MACHINE)" == "IX86"
   146    571   ### test for pentium errata
   147    572   !if [nmakehlp -c -QI0f]
   148    573   !message *** Compiler has 'Pentium 0x0f fix'
   149         -COMPILERFLAGS  = $(COMPILERFLAGSS) -QI0f
   150         -!else
   151         -!message *** Compiler doesn't have 'Pentium 0x0f fix'
   152         -!endif
   153         -!endif
   154         -
   155         -!if "$(MACHINE)" == "IA64"
   156         -### test for Itanium errata
   157         -!if [nmakehlp -c -QIA64_Bx]
   158         -!message *** Compiler has 'B-stepping errata workarounds'
   159         -COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
   160         -!else
   161         -!message *** Compiler does not have 'B-stepping errata workarounds'
   162         -!endif
   163         -!endif
   164         -
   165         -!if "$(MACHINE)" == "IX86"
   166         -### test for -align:4096, when align:512 will do.
   167         -!if [nmakehlp -l -opt:nowin98]
   168         -!message *** Linker has 'Win98 alignment problem'
   169         -ALIGN98_HACK	= 1
   170         -!else
   171         -!message *** Linker doesn't have 'Win98 alignment problem'
   172         -ALIGN98_HACK	= 0
   173         -!endif
   174         -!else
   175         -ALIGN98_HACK	= 0
          574  +FPOPTS  = $(FPOPTS) -QI0f
          575  +!else
          576  +!message *** Compiler does not have 'Pentium 0x0f fix'
          577  +!endif
          578  +!endif
          579  +
          580  +### test for optimizations
          581  +# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
          582  +# documentation. Note we do NOT want /Gs as that inserts a _chkstk
          583  +# stack probe at *every* function entry, not just those with more than
          584  +# a page of stack allocation resulting in a performance hit.  However,
          585  +# /O2 documentation is misleading as its stack probes are simply the
          586  +# default page size locals allocation probes and not what is implied
          587  +# by an explicit /Gs option.
          588  +
          589  +OPTIMIZATIONS = $(FPOPTS)
          590  +
          591  +!if [nmakehlp -c -O2]
          592  +OPTIMIZING = 1
          593  +OPTIMIZATIONS   = $(OPTIMIZATIONS) -O2
          594  +!else
          595  +# Legacy, really. All modern compilers support this
          596  +!message *** Compiler does not have 'Optimizations'
          597  +OPTIMIZING = 0
          598  +!endif
          599  +
          600  +# Checks for buffer overflows in local arrays
          601  +!if [nmakehlp -c -GS]
          602  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
          603  +!endif
          604  +
          605  +# Link time optimization. Note that this option (potentially) makes
          606  +# generated libraries only usable by the specific VC++ version that
          607  +# created it. Requires /LTCG linker option
          608  +!if [nmakehlp -c -GL]
          609  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
          610  +CC_GL_OPT_ENABLED = 1
          611  +!else
          612  +# In newer compilers -GL and -YX are incompatible.
          613  +!if [nmakehlp -c -YX]
          614  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
          615  +!endif
          616  +!endif # [nmakehlp -c -GL]
          617  +
          618  +DEBUGFLAGS     = $(FPOPTS)
          619  +
          620  +# Run time error checks. Not available or valid in a release, non-debug build
          621  +# RTC is for modern compilers, -GZ is legacy
          622  +!if [nmakehlp -c -RTC1]
          623  +DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
          624  +!elseif [nmakehlp -c -GZ]
          625  +DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
          626  +!endif
          627  +
          628  +#----------------------------------------------------------------
          629  +# Linker flags
          630  +
          631  +# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
          632  +# if the linker supports a specific option. Without these flags link will
          633  +# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
          634  +# They are not passed through to the actual application / extension
          635  +# link rules.
          636  +!ifndef LINKER_TESTFLAGS
          637  +LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
   176    638   !endif
   177    639   
   178    640   LINKERFLAGS     =
   179    641   
   180         -!if [nmakehlp -l -ltcg]
   181         -LINKERFLAGS     =-ltcg
   182         -!endif
   183         -
   184         -#----------------------------------------------------------
   185         -# MSVC8 (ships with Visual Studio 2005) generates a manifest
   186         -# file that we should link into the binaries. This is how.
   187         -#----------------------------------------------------------
   188         -
   189         -_VC_MANIFEST_EMBED_EXE=
   190         -_VC_MANIFEST_EMBED_DLL=
   191         -VCVER=0
   192         -!if ![echo VCVERSION=_MSC_VER > vercl.x] \
   193         -    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
   194         -!include vercl.i
   195         -!if $(VCVERSION) >= 1400
   196         -VCVER=8
   197         -_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
   198         -_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
   199         -!elseif $(VCVERSION) >= 1300
   200         -VCVER=7
   201         -!elseif $(VCVERSION) >= 1200
   202         -VCVER=6
   203         -!endif
   204         -!endif
   205         -
   206         -#----------------------------------------------------------
   207         -# Decode the options requested.
   208         -#----------------------------------------------------------
   209         -
   210         -!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
          642  +# If compiler has enabled link time optimization, linker must too with -ltcg
          643  +!ifdef CC_GL_OPT_ENABLED
          644  +!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
          645  +LINKERFLAGS     = $(LINKERFLAGS) -ltcg
          646  +!endif
          647  +!endif
          648  +
          649  +########################################################################
          650  +# 6. Parse the OPTS macro to work out the requested build configuration.
          651  +# Based on this, we will construct the actual switches to be passed to the
          652  +# compiler and linker using the macros defined in the previous section.
          653  +# The following macros are defined by this section based on OPTS
          654  +# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
          655  +#                1 -> build as a static library and shell
          656  +# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
          657  +# DEBUG - 1 -> debug build, 0 -> release builds
          658  +# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
          659  +# PROFILE - 1 -> generate profiling info, 0 -> no profiling
          660  +# PGO     - 1 -> profile based optimization, 0 -> no
          661  +# MSVCRT  - 1 -> link to dynamic C runtime even when building static Tcl build
          662  +#           0 -> link to static C runtime for static Tcl build.
          663  +#           Does not impact shared Tcl builds (STATIC_BUILD == 0)
          664  +# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
          665  +#           in the Tcl shell. 0 -> keep them as shared libraries
          666  +#           Does not impact shared Tcl builds.
          667  +# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
          668  +#           0 -> Use the non-thread allocator.
          669  +# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
          670  +#           C runtime, 0 -> use the debug C runtime.
          671  +# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
          672  +# CONFIG_CHECK - 1 -> check current build configuration against Tcl
          673  +#           configuration (ignored for Tcl itself)
          674  +# Further, LINKERFLAGS are modified based on above.
          675  +
          676  +# Default values for all the above
   211    677   STATIC_BUILD	= 0
   212    678   TCL_THREADS	= 1
   213    679   DEBUG		= 0
          680  +SYMBOLS		= 0
   214    681   PROFILE		= 0
   215         -MSVCRT		= 0
   216         -LOIMPACT	= 0
          682  +PGO		= 0
          683  +MSVCRT		= 1
   217    684   TCL_USE_STATIC_PACKAGES	= 0
   218    685   USE_THREAD_ALLOC = 1
   219         -USE_THREAD_STORAGE = 1
   220         -UNCHECKED       = 0
          686  +UNCHECKED	= 0
          687  +CONFIG_CHECK    = 1
          688  +!if $(DOING_TCL)
          689  +USE_STUBS       = 0
   221    690   !else
          691  +USE_STUBS       = 1
          692  +!endif
          693  +
          694  +# If OPTS is not empty AND does not contain "none" which turns off all OPTS
          695  +# set the above macros based on OPTS content
          696  +!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
          697  +
          698  +# OPTS are specified, parse them
          699  +
   222    700   !if [nmakehlp -f $(OPTS) "static"]
   223    701   !message *** Doing static
   224    702   STATIC_BUILD	= 1
          703  +!endif
          704  +
          705  +!if [nmakehlp -f $(OPTS) "nostubs"]
          706  +!message *** Not using stubs
          707  +USE_STUBS	= 0
          708  +!endif
          709  +
          710  +!if [nmakehlp -f $(OPTS) "nomsvcrt"]
          711  +!message *** Doing nomsvcrt
          712  +MSVCRT		= 0
   225    713   !else
   226         -STATIC_BUILD	= 0
   227         -!endif
   228    714   !if [nmakehlp -f $(OPTS) "msvcrt"]
   229    715   !message *** Doing msvcrt
   230    716   MSVCRT		= 1
   231    717   !else
          718  +!if !$(STATIC_BUILD)
          719  +MSVCRT		= 1
          720  +!else
   232    721   MSVCRT		= 0
   233    722   !endif
   234         -!if [nmakehlp -f $(OPTS) "staticpkg"]
          723  +!endif
          724  +!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
          725  +
          726  +!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
   235    727   !message *** Doing staticpkg
   236    728   TCL_USE_STATIC_PACKAGES	= 1
   237    729   !else
   238    730   TCL_USE_STATIC_PACKAGES	= 0
   239    731   !endif
          732  +
   240    733   !if [nmakehlp -f $(OPTS) "nothreads"]
   241         -!message *** Compile explicitly for non-threaded tcl
          734  +!message *** Compile explicitly for non-threaded Tcl
   242    735   TCL_THREADS	= 0
          736  +USE_THREAD_ALLOC= 0
   243    737   !else
   244         -TCL_THREADS     = 1
          738  +TCL_THREADS	= 1
          739  +USE_THREAD_ALLOC= 1
   245    740   !endif
          741  +
   246    742   !if [nmakehlp -f $(OPTS) "symbols"]
   247    743   !message *** Doing symbols
   248    744   DEBUG		= 1
   249    745   !else
   250    746   DEBUG		= 0
   251    747   !endif
          748  +
          749  +!if [nmakehlp -f $(OPTS) "pdbs"]
          750  +!message *** Doing pdbs
          751  +SYMBOLS		= 1
          752  +!else
          753  +SYMBOLS		= 0
          754  +!endif
          755  +
   252    756   !if [nmakehlp -f $(OPTS) "profile"]
   253    757   !message *** Doing profile
   254    758   PROFILE		= 1
   255    759   !else
   256    760   PROFILE		= 0
   257    761   !endif
          762  +
          763  +!if [nmakehlp -f $(OPTS) "pgi"]
          764  +!message *** Doing profile guided optimization instrumentation
          765  +PGO		= 1
          766  +!elseif [nmakehlp -f $(OPTS) "pgo"]
          767  +!message *** Doing profile guided optimization
          768  +PGO		= 2
          769  +!else
          770  +PGO		= 0
          771  +!endif
          772  +
   258    773   !if [nmakehlp -f $(OPTS) "loimpact"]
   259         -!message *** Doing loimpact
   260         -LOIMPACT	= 1
   261         -!else
   262         -LOIMPACT	= 0
          774  +!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
   263    775   !endif
          776  +
          777  +# TBD - should get rid of this option
   264    778   !if [nmakehlp -f $(OPTS) "thrdalloc"]
   265    779   !message *** Doing thrdalloc
   266    780   USE_THREAD_ALLOC = 1
   267         -!else
          781  +!endif
          782  +
          783  +!if [nmakehlp -f $(OPTS) "tclalloc"]
   268    784   USE_THREAD_ALLOC = 0
   269    785   !endif
   270         -!if [nmakehlp -f $(OPTS) "thrdstorage"]
   271         -!message *** Doing thrdstorage
   272         -USE_THREAD_STORAGE = 1
   273         -!else
   274         -USE_THREAD_STORAGE = 0
   275         -!endif
          786  +
   276    787   !if [nmakehlp -f $(OPTS) "unchecked"]
   277    788   !message *** Doing unchecked
   278    789   UNCHECKED = 1
   279    790   !else
   280    791   UNCHECKED = 0
   281    792   !endif
   282         -!endif
   283         -
   284         -
   285         -!if !$(STATIC_BUILD)
   286         -# Make sure we don't build overly fat DLLs.
   287         -MSVCRT		= 1
   288         -# We shouldn't statically put the extensions inside the shell when dynamic.
   289         -TCL_USE_STATIC_PACKAGES = 0
   290         -!endif
   291         -
   292         -
   293         -#----------------------------------------------------------
          793  +
          794  +!if [nmakehlp -f $(OPTS) "noconfigcheck"]
          795  +CONFIG_CHECK = 1
          796  +!else
          797  +CONFIG_CHECK = 0
          798  +!endif
          799  +
          800  +!endif # "$(OPTS)" != ""  && ... parsing of OPTS
          801  +
          802  +# Set linker flags based on above
          803  +
          804  +!if $(PGO) > 1
          805  +!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
          806  +LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
          807  +!else
          808  +MSG=^
          809  +This compiler does not support profile guided optimization.
          810  +!error $(MSG)
          811  +!endif
          812  +!elseif $(PGO) > 0
          813  +!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
          814  +LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
          815  +!else
          816  +MSG=^
          817  +This compiler does not support profile guided optimization.
          818  +!error $(MSG)
          819  +!endif
          820  +!endif
          821  +
          822  +################################################################
          823  +# 7. Parse the STATS macro to configure code instrumentation
          824  +# The following macros are set by this section:
          825  +# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
          826  +#                 0 -> disables
          827  +# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
          828  +#                     0 -> disables
          829  +
          830  +# Default both are off
          831  +TCL_MEM_DEBUG	    = 0
          832  +TCL_COMPILE_DEBUG   = 0
          833  +
          834  +!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
          835  +
          836  +!if [nmakehlp -f $(STATS) "memdbg"]
          837  +!message *** Doing memdbg
          838  +TCL_MEM_DEBUG	    = 1
          839  +!else
          840  +TCL_MEM_DEBUG	    = 0
          841  +!endif
          842  +
          843  +!if [nmakehlp -f $(STATS) "compdbg"]
          844  +!message *** Doing compdbg
          845  +TCL_COMPILE_DEBUG   = 1
          846  +!else
          847  +TCL_COMPILE_DEBUG   = 0
          848  +!endif
          849  +
          850  +!endif
          851  +
          852  +####################################################################
          853  +# 8. Parse the CHECKS macro to configure additional compiler checks
          854  +# The following macros are set by this section:
          855  +# WARNINGS - compiler switches that control the warnings level
          856  +# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
          857  +#                     0 -> enable deprecated functions
          858  +
          859  +# Defaults - Permit deprecated functions and warning level 3
          860  +TCL_NO_DEPRECATED	    = 0
          861  +WARNINGS		    = -W3
          862  +
          863  +!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
          864  +
          865  +!if [nmakehlp -f $(CHECKS) "nodep"]
          866  +!message *** Doing nodep check
          867  +TCL_NO_DEPRECATED	    = 1
          868  +!endif
          869  +
          870  +!if [nmakehlp -f $(CHECKS) "fullwarn"]
          871  +!message *** Doing full warnings check
          872  +WARNINGS		    = -W4
          873  +!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
          874  +LINKERFLAGS		    = $(LINKERFLAGS) -warn:3
          875  +!endif
          876  +!endif
          877  +
          878  +!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
          879  +!message *** Doing 64bit portability warnings
          880  +WARNINGS		    = $(WARNINGS) -Wp64
          881  +!endif
          882  +
          883  +!endif
          884  +
          885  +################################################################
          886  +# 9. Extract various version numbers
          887  +# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
          888  +# respectively. For extensions, versions are extracted from the
          889  +# configure.in or configure.ac from the TEA configuration if it
          890  +# exists, and unset otherwise.
          891  +# Sets the following macros:
          892  +# TCL_MAJOR_VERSION
          893  +# TCL_MINOR_VERSION
          894  +# TCL_PATCH_LEVEL
          895  +# TCL_VERSION
          896  +# TK_MAJOR_VERSION
          897  +# TK_MINOR_VERSION
          898  +# TK_PATCH_LEVEL
          899  +# TK_VERSION
          900  +# DOTVERSION - set as (for example) 2.5
          901  +# VERSION - set as (for example 25)
          902  +#--------------------------------------------------------------
          903  +
          904  +!if [echo REM = This file is generated from rules.vc > versions.vc]
          905  +!endif
          906  +!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
          907  +   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
          908  +!endif
          909  +!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
          910  +   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
          911  +!endif
          912  +!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
          913  +   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
          914  +!endif
          915  +
          916  +!if defined(_TK_H)
          917  +!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
          918  +   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
          919  +!endif
          920  +!if [echo TK_MINOR_VERSION = \>> versions.vc] \
          921  +   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
          922  +!endif
          923  +!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
          924  +   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
          925  +!endif
          926  +!endif # _TK_H
          927  +
          928  +!include versions.vc
          929  +
          930  +TCL_VERSION	= $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
          931  +TCL_DOTVERSION	= $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
          932  +!if defined(_TK_H)
          933  +TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
          934  +TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
          935  +!endif
          936  +
          937  +# Set DOTVERSION and VERSION
          938  +!if $(DOING_TCL)
          939  +
          940  +DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
          941  +VERSION = $(TCL_VERSION)
          942  +
          943  +!elseif $(DOING_TK)
          944  +
          945  +DOTVERSION = $(TK_DOTVERSION)
          946  +VERSION = $(TK_VERSION)
          947  +
          948  +!else # Doing a non-Tk extension
          949  +
          950  +# If parent makefile has not defined DOTVERSION, try to get it from TEA
          951  +# first from a configure.in file, and then from configure.ac
          952  +!ifndef DOTVERSION
          953  +!if [echo DOTVERSION = \> versions.vc] \
          954  +   || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
          955  +!if [echo DOTVERSION = \> versions.vc] \
          956  +   || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
          957  +!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
          958  +!endif
          959  +!endif
          960  +!include versions.vc
          961  +!endif # DOTVERSION
          962  +VERSION         = $(DOTVERSION:.=)
          963  +
          964  +!endif # $(DOING_TCL) ... etc.
          965  +
          966  +################################################################
          967  +# 10. Construct output directory and file paths
   294    968   # Figure-out how to name our intermediate and output directories.
   295         -# We wouldn't want different builds to use the same .obj files
   296         -# by accident.
   297         -#----------------------------------------------------------
   298         -
   299         -#----------------------------------------
   300         -# Naming convention:
          969  +# In order to avoid inadvertent mixing of object files built using
          970  +# different compilers, build configurations etc.,
          971  +#
          972  +# Naming convention (suffixes):
   301    973   #   t = full thread support.
   302         -#   s = static library (as opposed to an
   303         -#	import library)
   304         -#   g = linked to the debug enabled C
   305         -#	run-time.
   306         -#   x = special static build when it
   307         -#	links to the dynamic C run-time.
   308         -#----------------------------------------
   309         -SUFX	    = sgx
          974  +#   s = static library (as opposed to an import library)
          975  +#   g = linked to the debug enabled C run-time.
          976  +#   x = special static build when it links to the dynamic C run-time.
          977  +#
          978  +# The following macros are set in this section:
          979  +# SUFX - the suffix to use for binaries based on above naming convention
          980  +# BUILDDIRTOP - the toplevel default output directory
          981  +#      is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
          982  +# TMP_DIR - directory where object files are created
          983  +# OUT_DIR - directory where output executables are created
          984  +# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
          985  +# parent makefile (or command line). The default values are
          986  +# based on BUILDDIRTOP.
          987  +# STUBPREFIX - name of the stubs library for this project
          988  +# PRJIMPLIB - output path of the generated project import library
          989  +# PRJLIBNAME - name of generated project library
          990  +# PRJLIB     - output path of generated project library
          991  +# PRJSTUBLIBNAME - name of the generated project stubs library
          992  +# PRJSTUBLIB - output path of the generated project stubs library
          993  +# RESFILE - output resource file (only if not static build)
          994  +
          995  +SUFX	    = tsgx
   310    996   
   311    997   !if $(DEBUG)
   312    998   BUILDDIRTOP = Debug
   313    999   !else
   314   1000   BUILDDIRTOP = Release
   315   1001   !endif
   316   1002   
................................................................................
   327   1013   
   328   1014   TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
   329   1015   
   330   1016   !if !$(STATIC_BUILD)
   331   1017   TMP_DIRFULL = $(TMP_DIRFULL:Static=)
   332   1018   SUFX	    = $(SUFX:s=)
   333   1019   EXT	    = dll
   334         -!if $(MSVCRT)
   335   1020   TMP_DIRFULL = $(TMP_DIRFULL:X=)
   336   1021   SUFX	    = $(SUFX:x=)
   337         -!endif
   338   1022   !else
   339   1023   TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
   340   1024   EXT	    = lib
   341   1025   !if !$(MSVCRT)
   342   1026   TMP_DIRFULL = $(TMP_DIRFULL:X=)
   343   1027   SUFX	    = $(SUFX:x=)
   344   1028   !endif
................................................................................
   356   1040   !endif
   357   1041   !else
   358   1042   !ifndef OUT_DIR
   359   1043   OUT_DIR	    = $(TMP_DIR)
   360   1044   !endif
   361   1045   !endif
   362   1046   
   363         -
   364         -#----------------------------------------------------------
   365         -# Decode the statistics requested.
   366         -#----------------------------------------------------------
   367         -
   368         -!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]
   369         -TCL_MEM_DEBUG	    = 0
   370         -TCL_COMPILE_DEBUG   = 0
   371         -!else
   372         -!if [nmakehlp -f $(STATS) "memdbg"]
   373         -!message *** Doing memdbg
   374         -TCL_MEM_DEBUG	    = 1
   375         -!else
   376         -TCL_MEM_DEBUG	    = 0
   377         -!endif
   378         -!if [nmakehlp -f $(STATS) "compdbg"]
   379         -!message *** Doing compdbg
   380         -TCL_COMPILE_DEBUG   = 1
         1047  +# Relative paths -> absolute
         1048  +!if [echo OUT_DIR = \> nmakehlp.out] \
         1049  +   || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
         1050  +!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
         1051  +!endif
         1052  +!if [echo TMP_DIR = \>> nmakehlp.out] \
         1053  +   || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
         1054  +!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
         1055  +!endif
         1056  +!include nmakehlp.out
         1057  +
         1058  +# The name of the stubs library for the project being built
         1059  +STUBPREFIX      = $(PROJECT)stub
         1060  +
         1061  +# Set up paths to various Tcl executables and libraries needed by extensions
         1062  +!if $(DOING_TCL)
         1063  +
         1064  +TCLSHNAME       = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
         1065  +TCLSH		= $(OUT_DIR)\$(TCLSHNAME)
         1066  +TCLIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
         1067  +TCLLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
         1068  +TCLLIB		= $(OUT_DIR)\$(TCLLIBNAME)
         1069  +
         1070  +TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
         1071  +TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
         1072  +TCL_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"
         1073  +
         1074  +!else # ! $(DOING_TCL)
         1075  +
         1076  +!if $(TCLINSTALL) # Building against an installed Tcl
         1077  +
         1078  +# When building extensions, we need to locate tclsh. Depending on version
         1079  +# of Tcl we are building against, this may or may not have a "t" suffix.
         1080  +# Try various possibilities in turn.
         1081  +TCLSH		= $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
         1082  +!if !exist("$(TCLSH)") && $(TCL_THREADS)
         1083  +TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
         1084  +!endif
         1085  +!if !exist("$(TCLSH)")
         1086  +TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
         1087  +!endif
         1088  +
         1089  +TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
         1090  +TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
         1091  +# When building extensions, may be linking against Tcl that does not add
         1092  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1093  +!if !exist("$(TCLIMPLIB)")
         1094  +TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
         1095  +!endif
         1096  +TCL_LIBRARY	= $(_TCLDIR)\lib
         1097  +TCLREGLIB	= $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
         1098  +TCLDDELIB	= $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
         1099  +TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
         1100  +TCL_INCLUDES    = -I"$(_TCLDIR)\include"
         1101  +
         1102  +!else # Building against Tcl sources
         1103  +
         1104  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
         1105  +!if !exist($(TCLSH)) && $(TCL_THREADS)
         1106  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
         1107  +!endif
         1108  +!if !exist($(TCLSH))
         1109  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
         1110  +!endif
         1111  +TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
         1112  +TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
         1113  +# When building extensions, may be linking against Tcl that does not add
         1114  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1115  +!if !exist("$(TCLIMPLIB)")
         1116  +TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
         1117  +!endif
         1118  +TCL_LIBRARY	= $(_TCLDIR)\library
         1119  +TCLREGLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
         1120  +TCLDDELIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
         1121  +TCLTOOLSDIR	= $(_TCLDIR)\tools
         1122  +TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
         1123  +
         1124  +!endif # TCLINSTALL
         1125  +
         1126  +tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
         1127  +
         1128  +!endif # $(DOING_TCL)
         1129  +
         1130  +# We need a tclsh that will run on the host machine as part of the build.
         1131  +# IX86 runs on all architectures.
         1132  +!ifndef TCLSH_NATIVE
         1133  +!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
         1134  +TCLSH_NATIVE	= $(TCLSH)
   381   1135   !else
   382         -TCL_COMPILE_DEBUG   = 0
   383         -!endif
   384         -!endif
   385         -
   386         -
   387         -#----------------------------------------------------------
   388         -# Decode the checks requested.
   389         -#----------------------------------------------------------
   390         -
   391         -!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
   392         -TCL_NO_DEPRECATED	    = 0
   393         -FULLWARNINGS		    = 0
         1136  +!error You must explicitly set TCLSH_NATIVE for cross-compilation
         1137  +!endif
         1138  +!endif
         1139  +
         1140  +# Do the same for Tk and Tk extensions that require the Tk libraries
         1141  +!if $(DOING_TK) || $(NEED_TK)
         1142  +WISHNAMEPREFIX = wish
         1143  +WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
         1144  +TKLIBNAME	= $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
         1145  +TKSTUBLIBNAME	= tkstub$(TK_VERSION).lib
         1146  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib
         1147  +
         1148  +!if $(DOING_TK)
         1149  +WISH 		= $(OUT_DIR)\$(WISHNAME)
         1150  +TKSTUBLIB	= $(OUT_DIR)\$(TKSTUBLIBNAME)
         1151  +TKIMPLIB	= $(OUT_DIR)\$(TKIMPLIBNAME)
         1152  +TKLIB		= $(OUT_DIR)\$(TKLIBNAME)
         1153  +TK_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"
         1154  +
         1155  +!else # effectively NEED_TK
         1156  +
         1157  +!if $(TKINSTALL) # Building against installed Tk
         1158  +WISH		= $(_TKDIR)\bin\$(WISHNAME)
         1159  +TKSTUBLIB	= $(_TKDIR)\lib\$(TKSTUBLIBNAME)
         1160  +TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
         1161  +# When building extensions, may be linking against Tk that does not add
         1162  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1163  +!if !exist("$(TKIMPLIB)")
         1164  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
         1165  +TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
         1166  +!endif
         1167  +TK_INCLUDES     = -I"$(_TKDIR)\include"
         1168  +!else # Building against Tk sources
         1169  +WISH		= $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
         1170  +TKSTUBLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
         1171  +TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
         1172  +# When building extensions, may be linking against Tk that does not add
         1173  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1174  +!if !exist("$(TKIMPLIB)")
         1175  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
         1176  +TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
         1177  +!endif
         1178  +TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
         1179  +!endif # TKINSTALL
         1180  +tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
         1181  +
         1182  +!endif # $(DOING_TK)
         1183  +!endif # $(DOING_TK) || $(NEED_TK)
         1184  +
         1185  +# Various output paths
         1186  +PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
         1187  +PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
         1188  +PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)
         1189  +
         1190  +PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
         1191  +PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)
         1192  +
         1193  +# If extension parent makefile has not defined a resource definition file,
         1194  +# we will generate one from standard template.
         1195  +!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
         1196  +!ifdef RCFILE
         1197  +RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
   394   1198   !else
   395         -!if [nmakehlp -f $(CHECKS) "nodep"]
   396         -!message *** Doing nodep check
   397         -TCL_NO_DEPRECATED	    = 1
   398         -!else
   399         -TCL_NO_DEPRECATED	    = 0
   400         -!endif
   401         -!if [nmakehlp -f $(CHECKS) "fullwarn"]
   402         -!message *** Doing full warnings check
   403         -FULLWARNINGS		    = 1
   404         -!else
   405         -FULLWARNINGS		    = 0
   406         -!endif
   407         -!endif
   408         -
   409         -
   410         -#----------------------------------------------------------
   411         -# Set our defines now armed with our options.
   412         -#----------------------------------------------------------
   413         -
   414         -OPTDEFINES	= -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING)
         1199  +RESFILE = $(TMP_DIR)\$(PROJECT).res
         1200  +!endif
         1201  +!endif
         1202  +
         1203  +###################################################################
         1204  +# 11. Construct the paths for the installation directories
         1205  +# The following macros get defined in this section:
         1206  +# LIB_INSTALL_DIR - where libraries should be installed
         1207  +# BIN_INSTALL_DIR - where the executables should be installed
         1208  +# DOC_INSTALL_DIR - where documentation should be installed
         1209  +# SCRIPT_INSTALL_DIR - where scripts should be installed
         1210  +# INCLUDE_INSTALL_DIR - where C include files should be installed
         1211  +# DEMO_INSTALL_DIR - where demos should be installed
         1212  +# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)
         1213  +
         1214  +!if $(DOING_TCL) || $(DOING_TK)
         1215  +LIB_INSTALL_DIR		= $(_INSTALLDIR)\lib
         1216  +BIN_INSTALL_DIR		= $(_INSTALLDIR)\bin
         1217  +DOC_INSTALL_DIR		= $(_INSTALLDIR)\doc
         1218  +!if $(DOING_TCL)
         1219  +SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
         1220  +!else # DOING_TK
         1221  +SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
         1222  +!endif
         1223  +DEMO_INSTALL_DIR	= $(SCRIPT_INSTALL_DIR)\demos
         1224  +INCLUDE_INSTALL_DIR	= $(_INSTALLDIR)\include
         1225  +
         1226  +!else # extension other than Tk
         1227  +
         1228  +PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
         1229  +LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
         1230  +BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
         1231  +DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
         1232  +SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
         1233  +DEMO_INSTALL_DIR	= $(PRJ_INSTALL_DIR)\demos
         1234  +INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include
         1235  +
         1236  +!endif
         1237  +
         1238  +###################################################################
         1239  +# 12. Set up actual options to be passed to the compiler and linker
         1240  +# Now we have all the information we need, set up the actual flags and
         1241  +# options that we will pass to the compiler and linker. The main
         1242  +# makefile should use these in combination with whatever other flags
         1243  +# and switches are specific to it.
         1244  +# The following macros are defined, names are for historical compatibility:
         1245  +# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
         1246  +# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
         1247  +# crt - Compiler switch that selects the appropriate C runtime
         1248  +# cdebug - Compiler switches related to debug AND optimizations
         1249  +# cwarn - Compiler switches that set warning levels
         1250  +# cflags - complete compiler switches (subsumes cdebug and cwarn)
         1251  +# ldebug - Linker switches controlling debug information and optimization
         1252  +# lflags - complete linker switches (subsumes ldebug) except subsystem type
         1253  +# dlllflags - complete linker switches to build DLLs (subsumes lflags)
         1254  +# conlflags - complete linker switches for console program (subsumes lflags)
         1255  +# guilflags - complete linker switches for GUI program (subsumes lflags)
         1256  +# baselibs - minimum Windows libraries required. Parent makefile can
         1257  +#    define PRJ_LIBS before including rules.rc if additional libs are needed
         1258  +
         1259  +OPTDEFINES	= -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
   415   1260   
   416   1261   !if $(TCL_MEM_DEBUG)
   417   1262   OPTDEFINES	= $(OPTDEFINES) -DTCL_MEM_DEBUG
   418   1263   !endif
   419   1264   !if $(TCL_COMPILE_DEBUG)
   420   1265   OPTDEFINES	= $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
   421   1266   !endif
   422   1267   !if $(TCL_THREADS)
   423   1268   OPTDEFINES	= $(OPTDEFINES) -DTCL_THREADS=1
   424   1269   !if $(USE_THREAD_ALLOC)
   425   1270   OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
   426   1271   !endif
   427         -!if $(USE_THREAD_STORAGE)
   428         -OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_STORAGE=1
   429         -!endif
   430   1272   !endif
   431   1273   !if $(STATIC_BUILD)
   432   1274   OPTDEFINES	= $(OPTDEFINES) -DSTATIC_BUILD
   433   1275   !endif
   434   1276   !if $(TCL_NO_DEPRECATED)
   435   1277   OPTDEFINES	= $(OPTDEFINES) -DTCL_NO_DEPRECATED
   436   1278   !endif
   437   1279   
   438         -!if $(DEBUG)
   439         -OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DEBUG
   440         -!elseif $(OPTIMIZING)
         1280  +!if $(USE_STUBS)
         1281  +# Note we do not define USE_TCL_STUBS even when building Tk since some
         1282  +# test targets in Tk do not use stubs
         1283  +!if ! $(DOING_TCL)
         1284  +USE_STUBS_DEFS  = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
         1285  +!if $(NEED_TK)
         1286  +USE_STUBS_DEFS  = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
         1287  +!endif
         1288  +!endif
         1289  +!endif # USE_STUBS
         1290  +
         1291  +!if !$(DEBUG)
         1292  +OPTDEFINES	= $(OPTDEFINES) -DNDEBUG
         1293  +!if $(OPTIMIZING)
   441   1294   OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
         1295  +!endif
   442   1296   !endif
   443   1297   !if $(PROFILE)
   444   1298   OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_PROFILED
   445   1299   !endif
   446         -!if "$(MACHINE)" == "IA64"
         1300  +!if "$(MACHINE)" == "AMD64"
   447   1301   OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DO64BIT
   448   1302   !endif
   449         -
   450         -
   451         -#----------------------------------------------------------
   452         -# Get common info used when building extensions.
   453         -#----------------------------------------------------------
   454         -
   455         -!if "$(PROJECT)" != "tcl"
   456         -
   457         -# If INSTALLDIR set to tcl root dir then reset to the lib dir.
   458         -!if exist("$(_INSTALLDIR)\include\tcl.h")
   459         -_INSTALLDIR=$(_INSTALLDIR)\lib
         1303  +!if $(VCVERSION) < 1300
         1304  +OPTDEFINES	= $(OPTDEFINES) -DNO_STRTOI64
         1305  +!endif
         1306  +
         1307  +# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
         1308  +COMPILERFLAGS  = /D_ATL_XP_TARGETING
         1309  +
         1310  +# Following is primarily for the benefit of extensions. Tcl 8.5 builds
         1311  +# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
         1312  +# an extension, it is advisable (but not mandated) to use the same Windows
         1313  +# API as the Tcl build. This is accordingly defaulted below. A particular
         1314  +# extension can override this by pre-defining USE_WIDECHAR_API.
         1315  +!ifndef USE_WIDECHAR_API
         1316  +!if $(TCL_VERSION) > 85
         1317  +USE_WIDECHAR_API = 1
         1318  +!else
         1319  +USE_WIDECHAR_API = 0
         1320  +!endif
         1321  +!endif
         1322  +
         1323  +!if $(USE_WIDECHAR_API)
         1324  +COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE 
         1325  +!endif
         1326  +
         1327  +# Like the TEA system only set this non empty for non-Tk extensions
         1328  +# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
         1329  +# so we pass both
         1330  +!if !$(DOING_TCL) && !$(DOING_TK)
         1331  +PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
         1332  +               -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
         1333  +               -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
         1334  +               -DMODULE_SCOPE=extern 
         1335  +!endif
         1336  +
         1337  +# crt picks the C run time based on selected OPTS
         1338  +!if $(MSVCRT)
         1339  +!if $(DEBUG) && !$(UNCHECKED)
         1340  +crt = -MDd
         1341  +!else
         1342  +crt = -MD
         1343  +!endif
         1344  +!else
         1345  +!if $(DEBUG) && !$(UNCHECKED)
         1346  +crt = -MTd
         1347  +!else
         1348  +crt = -MT
         1349  +!endif
         1350  +!endif
         1351  +
         1352  +# cdebug includes compiler options for debugging as well as optimization.
         1353  +!if $(DEBUG)
         1354  +
         1355  +# In debugging mode, optimizations need to be disabled
         1356  +cdebug = -Zi -Od $(DEBUGFLAGS)
         1357  +
         1358  +!else
         1359  +
         1360  +cdebug = $(OPTIMIZATIONS)
         1361  +!if $(SYMBOLS)
         1362  +cdebug = $(cdebug) -Zi
         1363  +!endif
         1364  +
         1365  +!endif # $(DEBUG)
         1366  +
         1367  +# cwarn includes default warning levels.
         1368  +cwarn = $(WARNINGS)
         1369  +
         1370  +!if "$(MACHINE)" == "AMD64"
         1371  +# Disable pointer<->int warnings related to cast between different sizes
         1372  +# There are a gadzillion of these due to use of ClientData and
         1373  +# clutter up compiler
         1374  +# output increasing chance of a real warning getting lost. So disable them.
         1375  +# Eventually some day, Tcl will be 64-bit clean.
         1376  +cwarn = $(cwarn) -wd4311 -wd4312
         1377  +!endif
         1378  +
         1379  +### Common compiler options that are architecture specific
         1380  +!if "$(MACHINE)" == "ARM"
         1381  +carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
         1382  +!else
         1383  +carch =
         1384  +!endif
         1385  +
         1386  +!if $(DEBUG)
         1387  +# Turn warnings into errors
         1388  +cwarn = $(cwarn) -WX
         1389  +!endif
         1390  +
         1391  +INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
         1392  +!if !$(DOING_TCL) && !$(DOING_TK)
         1393  +INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
         1394  +!endif
         1395  +
         1396  +# These flags are defined roughly in the order of the pre-reform
         1397  +# rules.vc/makefile.vc to help visually compare that the pre- and
         1398  +# post-reform build logs
         1399  +
         1400  +# cflags contains generic flags used for building practically all object files
         1401  +cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
         1402  +
         1403  +# appcflags contains $(cflags) and flags for building the application
         1404  +# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
         1405  +# flags used for building shared object files The two differ in the
         1406  +# BUILD_$(PROJECT) macro which should be defined only for the shared
         1407  +# library *implementation* and not for its caller interface
         1408  +
         1409  +appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
         1410  +appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
         1411  +pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
         1412  +pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
         1413  +
         1414  +# stubscflags contains $(cflags) plus flags used for building a stubs
         1415  +# library for the package.  Note: -DSTATIC_BUILD is defined in
         1416  +# $(OPTDEFINES) only if the OPTS configuration indicates a static
         1417  +# library. However the stubs library is ALWAYS static hence included
         1418  +# here irrespective of the OPTS setting.
         1419  +#
         1420  +# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
         1421  +# without stating why. Tcl itself compiled stubs libs with this flag.
         1422  +# so we do not remove it from cflags. -GL may prevent extensions
         1423  +# compiled with one VC version to fail to link against stubs library
         1424  +# compiled with another VC version. Check for this and fix accordingly.
         1425  +stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
         1426  +
         1427  +# Link flags 
         1428  +
         1429  +!if $(DEBUG)
         1430  +ldebug	= -debug -debugtype:cv
         1431  +!else
         1432  +ldebug	= -release -opt:ref -opt:icf,3
         1433  +!if $(SYMBOLS)
         1434  +ldebug	= $(ldebug) -debug -debugtype:cv
         1435  +!endif
         1436  +!endif
         1437  +
         1438  +# Note: Profiling is currently only possible with the Visual Studio Enterprise
         1439  +!if $(PROFILE)
         1440  +ldebug= $(ldebug) -profile
         1441  +!endif
         1442  +
         1443  +### Declarations common to all linker versions 
         1444  +lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
         1445  +
         1446  +!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
         1447  +lflags	= $(lflags) -nodefaultlib:libucrt.lib
         1448  +!endif
         1449  +
         1450  +# Old linkers (Visual C++ 6 in particular) will link for fast loading
         1451  +# on Win98. Since we do not support Win98 any more, we specify nowin98
         1452  +# as recommended for NT and later. However, this is only required by
         1453  +# IX86 on older compilers and only needed if we are not doing a static build.
         1454  +
         1455  +!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
         1456  +!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
         1457  +# Align sections for PE size savings.
         1458  +lflags	= $(lflags) -opt:nowin98
         1459  +!endif
         1460  +!endif
         1461  +
         1462  +dlllflags = $(lflags) -dll
         1463  +conlflags = $(lflags) -subsystem:console
         1464  +guilflags = $(lflags) -subsystem:windows
         1465  +
         1466  +# Libraries that are required for every image.
         1467  +# Extensions should define any additional libraries with $(PRJ_LIBS)
         1468  +winlibs   = kernel32.lib advapi32.lib
         1469  +
         1470  +!if $(NEED_TK)
         1471  +winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
         1472  +!endif
         1473  +
         1474  +# Avoid 'unresolved external symbol __security_cookie' errors.
         1475  +# c.f. http://support.microsoft.com/?id=894573
         1476  +!if "$(MACHINE)" == "AMD64"
         1477  +!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
         1478  +winlibs   = $(winlibs) bufferoverflowU.lib
         1479  +!endif
         1480  +!endif
         1481  +
         1482  +baselibs = $(winlibs) $(PRJ_LIBS)
         1483  +
         1484  +!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
         1485  +baselibs   = $(baselibs) ucrt.lib
         1486  +!endif
         1487  +
         1488  +################################################################
         1489  +# 13. Define standard commands, common make targets and implicit rules
         1490  +
         1491  +CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
         1492  +CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
         1493  +CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
         1494  +
         1495  +LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
         1496  +DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1497  +
         1498  +CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1499  +GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1500  +RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
         1501  +	    $(TCL_INCLUDES) \
         1502  +	    -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
         1503  +	    -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
         1504  +	    -DDOTVERSION=\"$(DOTVERSION)\" \
         1505  +	    -DVERSION=\"$(VERSION)\" \
         1506  +	    -DSUFX=\"$(SUFX)\" \
         1507  +            -DPROJECT=\"$(PROJECT)\" \
         1508  +            -DPRJLIBNAME=\"$(PRJLIBNAME)\" 
         1509  +
         1510  +!ifndef DEFAULT_BUILD_TARGET
         1511  +DEFAULT_BUILD_TARGET = $(PROJECT)
   460   1512   !endif
   461   1513   
   462         -!if !defined(TCLDIR)
   463         -!if exist("$(_INSTALLDIR)\..\include\tcl.h")
   464         -TCLINSTALL	= 1
   465         -_TCLDIR		= $(_INSTALLDIR)\..
   466         -_TCL_H          = $(_INSTALLDIR)\..\include\tcl.h
   467         -TCLDIR          = $(_INSTALLDIR)\..
   468         -!else
   469         -MSG=^
   470         -Failed to find tcl.h.  Set the TCLDIR macro.
   471         -!error $(MSG)
   472         -!endif
   473         -!else
   474         -_TCLDIR	= $(TCLDIR:/=\)
   475         -!if exist("$(_TCLDIR)\include\tcl.h")
   476         -TCLINSTALL	= 1
   477         -_TCL_H          = $(_TCLDIR)\include\tcl.h
   478         -!elseif exist("$(_TCLDIR)\generic\tcl.h")
   479         -TCLINSTALL	= 0
   480         -_TCL_H          = $(_TCLDIR)\generic\tcl.h
   481         -!else
   482         -MSG =^
   483         -Failed to find tcl.h.  The TCLDIR macro does not appear correct.
   484         -!error $(MSG)
   485         -!endif
         1514  +default-target: $(DEFAULT_BUILD_TARGET)
         1515  +
         1516  +default-pkgindex:
         1517  +	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
         1518  +	    [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
         1519  +
         1520  +default-pkgindex-tea:
         1521  +	@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
         1522  +@PACKAGE_VERSION@    $(DOTVERSION)
         1523  +@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
         1524  +@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
         1525  +@PKG_LIB_FILE@       $(PRJLIBNAME)
         1526  +<<
         1527  +
         1528  +
         1529  +default-install: default-install-binaries default-install-libraries
         1530  +
         1531  +default-install-binaries: $(PRJLIB)
         1532  +	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
         1533  +	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
         1534  +	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
         1535  +
         1536  +default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
         1537  +	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
         1538  +	@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
         1539  +	@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
         1540  +	@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
         1541  +
         1542  +default-install-stubs:
         1543  +	@echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
         1544  +	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
         1545  +	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
         1546  +
         1547  +default-install-docs-html:
         1548  +	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
         1549  +	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
         1550  +	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
         1551  +
         1552  +default-install-docs-n:
         1553  +	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
         1554  +	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
         1555  +	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
         1556  +
         1557  +default-install-demos:
         1558  +	@echo Installing demos to '$(DEMO_INSTALL_DIR)'
         1559  +	@if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
         1560  +	@if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
         1561  +
         1562  +default-clean:
         1563  +	@echo Cleaning $(TMP_DIR)\* ...
         1564  +	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
         1565  +	@echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
         1566  +	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
         1567  +	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
         1568  +	@if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
         1569  +	@echo Cleaning $(WINDIR)\nmhlp-out.txt ...
         1570  +	@if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
         1571  +	@echo Cleaning $(WINDIR)\_junk.pch ...
         1572  +	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
         1573  +	@echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
         1574  +	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
         1575  +	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
         1576  +	@echo Cleaning $(WINDIR)\versions.vc, version.vc ...
         1577  +	@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
         1578  +	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
         1579  +
         1580  +default-hose: default-clean
         1581  +	@echo Hosing $(OUT_DIR)\* ...
         1582  +	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
         1583  +
         1584  +# Only for backward compatibility
         1585  +default-distclean: default-hose
         1586  +
         1587  +default-setup:
         1588  +	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
         1589  +	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
         1590  +
         1591  +!if "$(TESTPAT)" != ""
         1592  +TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
   486   1593   !endif
   487   1594   
   488         -!if [echo REM = This file is generated from rules.vc > version.vc]
   489         -!endif
   490         -!if exist("$(_TCL_H)")
   491         -!if [echo TCL_DOTVERSION = \>> version.vc] \
   492         -   && [nmakehlp -V "$(_TCL_H)" TCL_VERSION >> version.vc]
   493         -!endif
   494         -!endif
   495         -!include version.vc
   496         -TCL_VERSION	= $(TCL_DOTVERSION:.=)
         1595  +default-test: default-setup $(PROJECT)
         1596  +	@set TCLLIBPATH=$(OUT_DIR:\=/)
         1597  +	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
         1598  +	cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
   497   1599   
   498         -!if $(TCLINSTALL)
   499         -TCLSH		= "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
   500         -!if !exist($(TCLSH)) && $(TCL_THREADS)
   501         -TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
   502         -!endif
   503         -TCLSTUBLIB	= "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
   504         -TCLIMPLIB	= "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
   505         -TCL_LIBRARY	= $(_TCLDIR)\lib
   506         -TCL_INCLUDES    = -I"$(_TCLDIR)\include"
         1600  +default-shell: default-setup $(PROJECT)
         1601  +	@set TCLLIBPATH=$(OUT_DIR:\=/)
         1602  +	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
         1603  +	$(DEBUGGER) $(TCLSH)
         1604  +
         1605  +# Generation of Windows version resource 
         1606  +!ifdef RCFILE
         1607  +
         1608  +# Note: don't use $** in below rule because there may be other dependencies
         1609  +# and only the "master" rc must be passed to the resource compiler
         1610  +$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
         1611  +	$(RESCMD) $(RCDIR)\$(PROJECT).rc
         1612  +
   507   1613   !else
   508         -TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
   509         -!if !exist($(TCLSH)) && $(TCL_THREADS)
   510         -TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
         1614  +
         1615  +# If parent makefile has not defined a resource definition file,
         1616  +# we will generate one from standard template.
         1617  +$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
         1618  +
         1619  +$(TMP_DIR)\$(PROJECT).rc:
         1620  +	@$(COPY) << $(TMP_DIR)\$(PROJECT).rc
         1621  +#include <winver.h>
         1622  +
         1623  +VS_VERSION_INFO VERSIONINFO
         1624  + FILEVERSION	COMMAVERSION
         1625  + PRODUCTVERSION	COMMAVERSION
         1626  + FILEFLAGSMASK	0x3fL
         1627  +#ifdef DEBUG
         1628  + FILEFLAGS	VS_FF_DEBUG
         1629  +#else
         1630  + FILEFLAGS	0x0L
         1631  +#endif
         1632  + FILEOS		VOS_NT_WINDOWS32
         1633  + FILETYPE	VFT_DLL
         1634  + FILESUBTYPE	0x0L
         1635  +BEGIN
         1636  +    BLOCK "StringFileInfo"
         1637  +    BEGIN
         1638  +        BLOCK "040904b0"
         1639  +        BEGIN
         1640  +            VALUE "FileDescription",  "Tcl extension " PROJECT
         1641  +            VALUE "OriginalFilename", PRJLIBNAME
         1642  +            VALUE "FileVersion",      DOTVERSION
         1643  +            VALUE "ProductName",      "Package " PROJECT " for Tcl"
         1644  +            VALUE "ProductVersion",   DOTVERSION 
         1645  +        END
         1646  +    END
         1647  +    BLOCK "VarFileInfo"
         1648  +    BEGIN
         1649  +        VALUE "Translation", 0x409, 1200
         1650  +    END
         1651  +END
         1652  +
         1653  +<<
         1654  +
         1655  +!endif # ifdef RCFILE
         1656  +
         1657  +!ifndef DISABLE_IMPLICIT_RULES
         1658  +DISABLE_IMPLICIT_RULES = 0
   511   1659   !endif
   512         -TCLSTUBLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
   513         -TCLIMPLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
   514         -TCL_LIBRARY	= $(_TCLDIR)\library
   515         -TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
         1660  +
         1661  +!if !$(DISABLE_IMPLICIT_RULES)
         1662  +# Implicit rule definitions - only for building library objects. For stubs and
         1663  +# main application, the master makefile should define explicit rules.
         1664  +
         1665  +{$(ROOT)}.c{$(TMP_DIR)}.obj::
         1666  +	$(CCPKGCMD) @<<
         1667  +$<
         1668  +<<
         1669  +
         1670  +{$(WINDIR)}.c{$(TMP_DIR)}.obj::
         1671  +	$(CCPKGCMD) @<<
         1672  +$<
         1673  +<<
         1674  +
         1675  +{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
         1676  +	$(CCPKGCMD) @<<
         1677  +$<
         1678  +<<
         1679  +
         1680  +{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
         1681  +	$(CCPKGCMD) @<<
         1682  +$<
         1683  +<<
         1684  +
         1685  +{$(RCDIR)}.rc{$(TMP_DIR)}.res:
         1686  +	$(RESCMD) $<
         1687  +
         1688  +{$(WINDIR)}.rc{$(TMP_DIR)}.res:
         1689  +	$(RESCMD) $<
         1690  +
         1691  +{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
         1692  +	$(RESCMD) $<
         1693  +
         1694  +.SUFFIXES:
         1695  +.SUFFIXES:.c .rc
         1696  +
   516   1697   !endif
         1698  +
         1699  +################################################################
         1700  +# 14. Sanity check selected options against Tcl build options
         1701  +# When building an extension, certain configuration options should
         1702  +# match the ones used when Tcl was built. Here we check and
         1703  +# warn on a mismatch.
         1704  +!if ! $(DOING_TCL)
   517   1705   
         1706  +!if $(TCLINSTALL) # Building against an installed Tcl
         1707  +!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
         1708  +TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
         1709  +!endif
         1710  +!else # ! $(TCLINSTALL) - building against Tcl source
         1711  +!if exist("$(OUT_DIR)\tcl.nmake")
         1712  +TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
   518   1713   !endif
         1714  +!endif # TCLINSTALL
   519   1715   
   520         -#----------------------------------------------------------
   521         -# Optionally check for Tk info for building extensions.
   522         -#----------------------------------------------------------
   523         -
   524         -!ifdef PROJECT_REQUIRES_TK
   525         -!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
         1716  +!if $(CONFIG_CHECK)
         1717  +!ifdef TCLNMAKECONFIG
         1718  +!include $(TCLNMAKECONFIG)
   526   1719   
   527         -!if !defined(TKDIR)
   528         -!if exist("$(_INSTALLDIR)\..\include\tk.h")
   529         -TKINSTALL      = 1
   530         -_TKDIR         = $(_INSTALLDIR)\..
   531         -_TK_H          = $(_TKDIR)\include\tk.h
   532         -TKDIR          = $(_TKDIR)
   533         -!elseif exist("$(_TCLDIR)\include\tk.h")
   534         -TKINSTALL      = 1
   535         -_TKDIR         = $(_TCLDIR)
   536         -_TK_H          = $(_TKDIR)\include\tk.h
   537         -TKDIR          = $(_TKDIR)
         1720  +!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
         1721  +!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
         1722  +!endif
         1723  +!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
         1724  +!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
   538   1725   !endif
   539         -!else
   540         -_TKDIR = $(TKDIR:/=\)
   541         -!if exist("$(_TKDIR)\include\tk.h")
   542         -TKINSTALL      = 1
   543         -_TK_H          = $(_TKDIR)\include\tk.h
   544         -!elseif exist("$(_TKDIR)\generic\tk.h")
   545         -TKINSTALL      = 0
   546         -_TK_H          = $(_TKDIR)\generic\tk.h
   547         -!else
   548         -MSG =^
   549         -Failed to find tk.h. The TKDIR macro does not appear correct.
   550         -!error $(MSG)
         1726  +!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
         1727  +!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
   551   1728   !endif
   552   1729   !endif
   553   1730   
   554         -!if defined(TKDIR)
   555         -TK_DOTVERSION = 8.4
   556         -!if exist("$(_TK_H)")
   557         -!if [echo TK_DOTVERSION = \>> version.vc] \
   558         -   && [nmakehlp -V "$(_TK_H)" TK_VERSION >> version.vc]
   559         -!endif
   560         -!endif
   561         -!include version.vc
   562         -TK_VERSION = $(TK_DOTVERSION:.=)
         1731  +!endif # TCLNMAKECONFIG
   563   1732   
   564         -!if $(TKINSTALL)
   565         -WISH		= "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
   566         -TKSTUBLIB	= "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
   567         -TKIMPLIB	= "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
   568         -TK_INCLUDES     = -I"$(_TKDIR)\include"
   569         -!else
   570         -WISH		= "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
   571         -TKSTUBLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
   572         -TKIMPLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
   573         -TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
   574         -!endif
         1733  +!endif # ! $(DOING_TCL)
   575   1734   
   576         -!endif
   577         -!endif
   578         -!endif
   579   1735   
   580   1736   #----------------------------------------------------------
   581   1737   # Display stats being used.
   582   1738   #----------------------------------------------------------
   583   1739   
         1740  +!if !$(DOING_TCL)
         1741  +!message *** Building against Tcl at '$(_TCLDIR)'
         1742  +!endif
         1743  +!if !$(DOING_TK) && $(NEED_TK)
         1744  +!message *** Building against Tk at '$(_TKDIR)'
         1745  +!endif
   584   1746   !message *** Intermediate directory will be '$(TMP_DIR)'
   585   1747   !message *** Output directory will be '$(OUT_DIR)'
         1748  +!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
   586   1749   !message *** Suffix for binaries will be '$(SUFX)'
   587         -!message *** Optional defines are '$(OPTDEFINES)'
   588         -!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
   589         -!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS)'
   590         -!message *** Link options '$(LINKERFLAGS)'
         1750  +!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
   591   1751   
   592         -!endif
         1752  +!endif # ifdef _RULES_VC

Added win/targets.vc.

            1  +#------------------------------------------------------------- -*- makefile -*-
            2  +# targets.vc --
            3  +#
            4  +# Part of the nmake based build system for Tcl and its extensions.
            5  +# This file defines some standard targets for the convenience of extensions
            6  +# and can be optionally included by the extension makefile.
            7  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
            8  +
            9  +$(PROJECT): setup pkgindex $(PRJLIB)
           10  +
           11  +!ifdef PRJ_STUBOBJS
           12  +$(PROJECT): $(PRJSTUBLIB)
           13  +$(PRJSTUBLIB): $(PRJ_STUBOBJS)
           14  +	$(LIBCMD) $**
           15  +
           16  +$(PRJ_STUBOBJS):
           17  +	$(CCSTUBSCMD) %s
           18  +!endif # PRJ_STUBOBJS
           19  +
           20  +!ifdef PRJ_MANIFEST
           21  +$(PROJECT): $(PRJLIB).manifest
           22  +$(PRJLIB).manifest: $(PRJ_MANIFEST)
           23  +	@nmakehlp -s << $** >$@
           24  +@MACHINE@	  $(MACHINE:IX86=X86)
           25  +<<
           26  +!endif
           27  +
           28  +!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
           29  +$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
           30  +!if $(STATIC_BUILD)
           31  +       $(LIBCMD) $**
           32  +!else
           33  +       $(DLLCMD) $**
           34  +       $(_VC_MANIFEST_EMBED_DLL)
           35  +!endif
           36  +       -@del $*.exp
           37  +!endif
           38  +
           39  +!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
           40  +$(PRJ_OBJS): $(PRJ_HEADERS)
           41  +!endif
           42  +
           43  +# If parent makefile has defined stub objects, add their installation
           44  +# to the default install
           45  +!if "$(PRJ_STUBOBJS)" != ""
           46  +default-install: default-install-stubs
           47  +!endif
           48  +
           49  +# Unlike the other default targets, these cannot be in rules.vc because
           50  +# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
           51  +# that the parent makefile will not define until after including rules-ext.vc
           52  +!if "$(PRJ_HEADERS_PUBLIC)" != ""
           53  +default-install: default-install-headers
           54  +default-install-headers:
           55  +	@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
           56  +	@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
           57  +!endif
           58  +
           59  +!if "$(DISABLE_STANDARD_TARGETS)" == ""
           60  +DISABLE_STANDARD_TARGETS = 0
           61  +!endif
           62  +
           63  +!if "$(DISABLE_TARGET_setup)" == ""
           64  +DISABLE_TARGET_setup = 0
           65  +!endif
           66  +!if "$(DISABLE_TARGET_install)" == ""
           67  +DISABLE_TARGET_install = 0
           68  +!endif
           69  +!if "$(DISABLE_TARGET_clean)" == ""
           70  +DISABLE_TARGET_clean = 0
           71  +!endif
           72  +!if "$(DISABLE_TARGET_test)" == ""
           73  +DISABLE_TARGET_test = 0
           74  +!endif
           75  +!if "$(DISABLE_TARGET_shell)" == ""
           76  +DISABLE_TARGET_shell = 0
           77  +!endif
           78  +
           79  +!if !$(DISABLE_STANDARD_TARGETS)
           80  +!if !$(DISABLE_TARGET_setup)
           81  +setup: default-setup
           82  +!endif
           83  +!if !$(DISABLE_TARGET_install)
           84  +install: default-install
           85  +!endif
           86  +!if !$(DISABLE_TARGET_clean)
           87  +clean: default-clean
           88  +realclean: hose
           89  +hose: default-hose
           90  +distclean: realclean default-distclean
           91  +!endif
           92  +!if !$(DISABLE_TARGET_test)
           93  +test: default-test
           94  +!endif
           95  +!if !$(DISABLE_TARGET_shell)
           96  +shell: default-shell
           97  +!endif
           98  +!endif # DISABLE_STANDARD_TARGETS

Changes to win/tdom.rc.

     9      9    PRODUCTVERSION	COMMAVERSION
    10     10    FILEFLAGSMASK	0x3fL
    11     11   #ifdef DEBUG
    12     12    FILEFLAGS	VS_FF_DEBUG
    13     13   #else
    14     14    FILEFLAGS	0x0L
    15     15   #endif
    16         - FILEOS		VOS__WINDOWS32
           16  + FILEOS		VOS_NT_WINDOWS32
    17     17    FILETYPE	VFT_DLL
    18     18    FILESUBTYPE	0x0L
    19     19   BEGIN
    20     20       BLOCK "StringFileInfo"
    21     21       BEGIN
    22     22           BLOCK "040904b0"
    23     23           BEGIN
    24     24               VALUE "FileDescription",  "tdom " DOTVERSION " for Windows\0"
    25         -            VALUE "OriginalFilename", "tdom" VERSION ".dll\0"
    26         -            VALUE "FileVersion",      DOTVERSION "\0"
           25  +            VALUE "OriginalFilename", PRJLIBNAME
           26  +            VALUE "FileVersion",      DOTVERSION
    27     27               VALUE "LegalCopyright",   "Copyright \251 1998-2007 Jochen Loewer, Rolf Ade, et al.\0"
    28         -            VALUE "ProductName",      "tdom " DOTVERSION " for Windows\0"
    29         -            VALUE "ProductVersion",   DOTVERSION "\0"
           28  +            VALUE "ProductName",      "Package" PROJECT " for Tcl"
           29  +            VALUE "ProductVersion",   DOTVERSION
    30     30           END
    31     31       END
    32     32       BLOCK "VarFileInfo"
    33     33       BEGIN
    34     34           VALUE "Translation", 0x409, 1200
    35     35       END
    36     36   END

Changes to xe/README.

     7      7   
     8      8    1)  cp xe-input ~/.xe-input
     9      9        xe
    10     10   
    11     11    2)  xe xe-input
    12     12   
    13     13   
    14         -Latter should be more appropiate for Wn32 users.
           14  +Latter should be more appropriate for Wn32 users.
    15     15