2 * The contents of this file are subject to the Mozilla Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/MPL/
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
12 * The Original Code is the Sablotron XSLT Processor.
14 * The Initial Developer of the Original Code is Ginger Alliance Ltd.
15 * Portions created by Ginger Alliance are Copyright (C) 2000-2002
16 * Ginger Alliance Ltd. All Rights Reserved.
20 * Alternatively, the contents of this file may be used under the
21 * terms of the GNU General Public License Version 2 or later (the
22 * "GPL"), in which case the provisions of the GPL are applicable
23 * instead of those above. If you wish to allow use of your
24 * version of this file only under the terms of the GPL and not to
25 * allow others to use your version of this file under the MPL,
26 * indicate your decision by deleting the provisions above and
27 * replace them with the notice and other provisions required by
28 * the GPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under either the MPL or the
39 // #include <strings.h>
43 #if defined(CHECK_LEAKS)
44 #pragma Msg("Building with leak checking")
47 // includes for time measurement moved to platform.cpp
49 /****************************************
50 X S L c o n s t a n t s
51 ****************************************/
53 // !!!!!!!!!!!!!!!!!!!!!
54 // the order of items in the following tables must agree with
55 // that in the corresponding enums as defined in base.h
57 const char* xslOpNames[]=
59 "apply-imports","apply-templates",
60 "attribute","attribute-set",
61 "call-template","choose",
62 "comment", "copy","copy-of",
63 "decimal-format","element",
64 "fallback","for-each",
67 "message","namespace-alias",
70 "preserve-space","processing-instruction",
72 "stylesheet","template",
74 "value-of","variable",
79 const char* xslAttNames[]=
81 "case-order", "cdata-section-elements", "count",
82 "data-type", "decimal-separator", "digit", "disable-output-escaping", "doctype-public", "doctype-system",
83 "elements", "encoding", "exclude-result-prefixes", "extension-element-prefixes",
85 "grouping-separator", "grouping-size",
87 "id", "indent", "infinity",
88 "lang", "letter-value", "level",
89 "match", "media-type", "method", "minus-sign", "mode",
90 "name", "namespace", "NaN",
91 "omit-xml-declaration", "order",
92 "pattern-separator", "percent", "per-mille", "priority",
94 "select", "standalone", "stylesheet-prefix",
96 "use", "use-attribute-sets",
102 const char* axisNames[]=
104 "ancestor","ancestor-or-self",
106 "descendant","descendant-or-self",
107 "following","following-sibling",
108 "namespace","parent",
109 "preceding","preceding-sibling",
115 const char* vertexTypeNames[] =
117 "","root","element","attribute",
118 "text","processing instruction","comment","namespace"
121 const char* exNodeTypeNames[] =
124 "processing-instruction", "comment",
128 const char* theXSLTNamespace = "http://www.w3.org/1999/XSL/Transform";
129 const char* oldXSLTNamespace = "http://www.w3.org/XSL/Transform/1.0";
130 const char* theXMLNamespace = "http://www.w3.org/XML/1998/namespace";
131 const char* theXHTMLNamespace = "http://www.w3.org/1999/xhtml";
132 const char* theXMLNSNamespace = "http://www.w3.org/2000/xmlns/";
133 const char* theSabExtNamespace = "http://www.gingerall.org/sablotron/extension";
135 const char* theWhitespace = " \t\x0a\x0d";
142 * escNewline = " ",
145 * escGreater = ">",
146 * escQuote = """,
147 * escApos = "'";
151 // to match HandlerType in shandler.h
154 const char* hlrTypeNames[] = {"message", "scheme", "streaming",
155 "miscellaneous", "encoding"};
157 /*****************************************************************
158 Global handlers that can be set via Sablot functions
159 *****************************************************************/
161 // URI scheme handler
162 SchemeHandler* theSchemeHandler = NULL;
163 // message handler (errors, warnings, log messages...)
164 MessageHandler* theMessageHandler = NULL;
165 // SAX call handler (streamed access to the result document)
166 SAXHandler* theSAXHandler = NULL;
167 void* theSAXUserData = NULL;
169 /****************************************
171 ****************************************/
173 // Finds a string in a NULL-terminated table of pointers.
175 int lookup(const char* str, const char** table)
177 const char **p = table;
181 if (!strcmp(str,*p)) return i;
187 int lookupNoCase(const char* str, const char** table)
189 const char **p = table;
193 if (strEqNoCase(str,*p)) return i;
201 /*****************************************************************
202 stdopen(), stdclose()
203 *****************************************************************/
205 Bool isstd(const char *fname)
207 if (!strcmp(fname,"stdin") || !strcmp(fname,"stderr")
208 || !strcmp(fname,"stdout"))
213 int stdclose(FILE *f)
215 if ((!f) || (f == stdin) || (f == stdout) || (f == stderr))
217 else return fclose(f);
220 FILE* stdopen(const char *fn, const char *mode)
222 if (!strcmp(fn,"stderr"))
224 else if (!strcmp(fn,"stdout"))
226 else if (!strcmp(fn,"stdin"))
230 FILE* x = fopen(fn,mode);
236 /*****************************************************************
238 *****************************************************************/
240 Bool strEqNoCase(const char* s1, const char* s2)
243 for (i = 0; s1[i]; i++)
245 if (tolower(s1[i]) != tolower(s2[i]))
248 return s2[i] ? FALSE : TRUE;
251 /*****************************************************************
253 *****************************************************************/
257 #if (defined(WIN32) && defined(CHECK_LEAKS))
258 _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
259 _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
260 _CrtMemDumpAllObjectsSince(NULL);
266 #if (defined(WIN32) && defined(CHECK_LEAKS))
267 _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
268 _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
269 _CrtMemState memsnap;
270 _CrtMemCheckpoint(&memsnap);
271 _CrtMemDumpStatistics(&memsnap);
275 /*****************************************************************
277 *****************************************************************/
280 //#pragma Msg("'new' handler in linux?")
284 static _PNH oldNewHandler = NULL;
287 int sablotNewHandler(size_t size)
289 #if defined(WIN32) || defined(__linux__) || defined(__unix)
292 //situation.error(E_MEMORY, *theEmptyString, theEmptyString);
297 void pushNewHandler()
300 assert(!oldNewHandler);
301 oldNewHandler = _set_new_handler(sablotNewHandler);
308 _set_new_handler( oldNewHandler );
309 oldNewHandler = NULL;
313 /*****************************************************************
316 float comparison: returns 0 / 1 / -1 if p1 == / > / < p2.
317 *****************************************************************/
319 int fcomp(double p1, double p2)
322 if ((d < EPS) && (d > -EPS)) return 0;
323 else return (d > 0 ? 1 : -1);
328 Str getMillisecsDiff(double originalTime)
331 // getMillisecs() is in platform.cpp
332 sprintf(buf, "%.3f", getMillisecs() - originalTime);
337 /**************** XML name checks ********************/
339 Bool isValidNCName(const char* name)
341 int len = utf8StrLength(name);
342 if (len == 0) return FALSE;
344 wchar_t *buff = new wchar_t[len + 1];
346 utf8ToUtf16(buff, name);
348 Bool result = utf8IsLetter(buff[0]) || buff[0] == 0x005F; //underscore
349 for (int i = 1; i < len && result; i++)
352 utf8IsLetter(buff[i]) ||
353 utf8IsDigit(buff[i]) ||
354 utf8IsCombiningChar(buff[i]) ||
355 utf8IsExtender(buff[i]) ||
356 buff[i] == 0x002E || //dot
357 buff[i] == 0x002D || //hyphen
358 buff[i] == 0x005F; //underscore
365 Bool isValidQName(const char* name)
370 char *colon = (char *)strchr(name, ':');
377 result = isValidNCName(name) && (local == NULL || isValidNCName(local));
379 if (colon) *colon = ':';
385 Bool getWhDelimString(char *&list, Str& firstPart)
388 if (!*list) return FALSE;
389 char *list_was = list;
390 for(; *list && !isWhite(*list); list++);
391 firstPart.nset(list_was, (int)(list - list_was));