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,
 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 <head>, 93 + <tbody>, 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><channel-ID></i> 85 167 </dt> 86 168 87 169 <dd>If <i class="m">-channel <channel-ID></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><baseURI></i> 97 179 </dt> 98 180 99 - <dd>If <i class="m">-baseurl <baseURI></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 <baseURI></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><#bytes></i> 108 191 </dt> 109 192 110 - <dd>If <i class="m">-feedbackAfter <#bytes></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 <#bytes></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><script></i> 214 +</dt> 215 + 216 + <dd>If <i class="m">-feedbackcmd <script></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><script></i> 121 233 </dt> 122 234 123 235 <dd>If <i class="m">-externalentitycommand <script></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><boolean></i> 143 255 </dt> 144 256 145 257 <dd>If <boolean> 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><always|never|notstandalone></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 (&) and the left angle bracket (<) 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 <head>, 102 + <tbody>, 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><channel-ID></optarg> 94 174 <desc>If <m>-channel <channel-ID></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><baseURI></optarg> 104 - <desc>If <m>-baseurl <baseURI></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 <baseURI></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><#bytes></optarg> 113 - <desc>If <m>-feedbackAfter <#bytes></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 <#bytes></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><script></optarg> 215 + <desc>If <m>-feedbackcmd <script></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><script></optarg> 124 232 <desc>If <m>-externalentitycommand <script></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><boolean></optarg> 144 252 <desc>If <boolean> 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><always|never|notstandalone></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 (&) and the left angle bracket (<) 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 <boolean>?</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 &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 <boolean>?</b> <b class="option">-xmlDeclaration <boolean>?</b> <b class="option">-encString <string></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 &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 '>' 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 <boolean>?</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|*) ?<boolean>?</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 <xsl:param> 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 <xsl:param> 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 " 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 " 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 <boolean>?</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 &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 <boolean>?</option> <option>-xmlDeclaration <boolean>?</option> <option>-encString <string></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 &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 <boolean>?</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|*) ?<boolean>?</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 <xsl:param> 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 <xsl:param> 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><xsltCmd> 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 <index>", 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 + {<localname> <prefix> <namespace_uri>}. In the special case of 243 + an xml namespace declaration it is {<the prefix defined> 244 + <localname> ""}. 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 -&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 <boolean>?</b> <b class="option">-encString <string></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 &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 '>' 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 <xsl:param> 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 -" 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 " 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 "Document Object Model ................................................................................ 53 54 target for processing-instructions, "#text" for text node, 54 55 "#comment" for comment nodes or "#cdata" 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 "live" nodeList object of the child nodes of 87 88 the node in the sense of the DOM recommendation. This nodeList object is 88 89 "live" 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 "item 92 +of the node. The two accessors known by the nodeList object are "item 92 93 <index>", which returns the indexth item in the collection, and 93 94 "length", 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 + {<localname> <prefix> <namespace_uri>}. In the special case of 221 + an xml namespace declaration it is {<the prefix defined> 222 + <localname> ""}. 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 -&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 <boolean>?</option> <option>-encString <string></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 &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 <xsl:param> 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 <boolen> 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><boolen></optarg> 555 555 <desc>If <boolen> 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 "continue" 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 "return" 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 <tclexpat.h> 14 + <h2><a name="SECTid0x1d90950">SYNOPSIS</a></h2><pre class="syntax">#include <tclexpat.h> 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 "not standalone" 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"><parserObj> 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 - "enable", "getresult", "remove", 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, "First argument has to be a expat parser object", 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><parserObj> 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 "tdom" 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 "dom" 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 +[](https://travis-ci.org/libexpat/libexpat) 2 +[](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 — e.g. as part of 69 +a Linux distribution — 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(" "); break; 2087 2248 case 0241: AE("¡"); break; 2088 2249 case 0242: AE("¢"); break; 2089 2250 case 0243: AE("£"); break; 2090 2251 case 0244: AE("¤"); break; 2091 2252 case 0245: AE("¥"); break; ................................................................................ 2175 2336 case 0371: AE("ù"); break; 2176 2337 case 0372: AE("ú"); break; 2177 2338 case 0373: AE("û"); break; 2178 2339 case 0374: AE("ü"); break; 2179 2340 case 0375: AE("ý"); break; 2180 2341 case 0376: AE("þ"); break; 2181 2342 case 0377: AE("ÿ"); break; 2182 -#if !TclOnly8Bits 2183 2343 /* "Special" chars, according to XHTML xhtml-special.ent */ 2184 2344 case 338: AE("Œ"); break; 2185 2345 case 339: AE("œ"); break; 2186 2346 case 352: AE("Š"); break; 2187 2347 case 353: AE("š"); break; 2188 2348 case 376: AE("Ÿ"); break; 2189 2349 case 710: AE("ˆ"); break; ................................................................................ 2330 2490 case 9001: AE("⟨"); break; 2331 2491 case 9002: AE("⟩"); break; 2332 2492 case 9674: AE("◊"); break; 2333 2493 case 9824: AE("♠"); break; 2334 2494 case 9827: AE("♣"); break; 2335 2495 case 9829: AE("♥"); break; 2336 2496 case 9830: AE("♦"); 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 “ and ”. 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 "&#60;"> 54 +<!ENTITY gt ">"> 55 +<!ENTITY amp "&#38;"> 56 +<!ENTITY apos "'"> 57 +<!ENTITY quot """> 58 +<!ENTITY nbsp " "> 59 +<!ENTITY mdash "&#x2014;"> 60 +<!ENTITY ldquo "&#x201C;"> 61 +<!ENTITY rdquo "&#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>абвгдежзий</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=\"äöüß\"><!-- A comment with german umlauts: \u00E4\u00F6\u00FC\u00DF --><?\u00E4\u00F6\u00FC\u00DF A processing node with german umlauts?> 55 56 german umlauts: äöüß 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"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 & 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><p>Some <b>important</b> stuff</p></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 & 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 & 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 & 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∡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∡</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> ¡Äü</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>ÖÄÄ</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>€∋</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>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: <script> lacks "type" attribute 200 + line 11 column 17 - Warning: <table> 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>€∋</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>'xyz</html>}] 44 + set root [$doc documentElement] 45 + set result [$root text] 46 + $doc delete 47 + set result 48 +} "'xyz" 49 + 50 +test html-1.5 {Numeric character entity} { 51 + set doc [dom parse -html {<html>�</html>}] 52 + set root [$doc documentElement] 53 + set result [$root text] 54 + $doc delete 55 + set result 56 +} "�" 57 + 58 +test html-1.6 {Numeric character entity} { 59 + set doc [dom parse -html {<html>�</html>}] 60 + set root [$doc documentElement] 61 + set result [$root text] 62 + $doc delete 63 + set result 64 +} "�" 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>👮👾💔</doc>"] 42 + set result [$doc asXML -indent none -escapeNonASCII] 43 + $doc delete 44 + set result 45 +} -result "<doc>👮👾💔</doc>" 46 + 47 +test i18n-1.5 {pcdata outside BMP} -body { 48 + set doc [dom parse "<doc>👮👾💔</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>👮👾💔</doc>" 63 + 64 +test i18n-1.7 {pcdata outside BMP} -body { 65 + set doc [dom parse "<doc>👮👾💔</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>👮👾💔</doc>" 80 + 81 +test i18n-1.10 {pcdata outside unicode} -body { 82 + set doc [dom parse "<doc></doc>"] 83 + set result [$doc asXML -indent none -escapeNonASCII] 84 + $doc delete 85 + set result 86 +} -result "<doc></doc>" 87 + 88 +test i18n-1.11 {pcdata outside unicode} -body { 89 + set result [catch {dom parse "<doc>�</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 '%zz;'> 767 +<!ENTITY % zz '<!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 <PCDATA></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><foo & ><![CDATA[test of & <bad> format]]>' bar "</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><>&'"</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>AB</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