1 /*
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/
6  *
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.
11  *
12  * The Original Code is the Sablotron XSLT Processor.
13  *
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.
17  *
18  * Contributor(s):
19  *
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
30  * GPL.
31  */
32 
33 #ifndef ProcHIncl
34 #define ProcHIncl
35 
36 // GP: clean
37 
38 #define PROC_ARENA_SIZE         0x10000
39 
40 enum StandardPhrase
41 {
42     PHRASE_EMPTY = 0,
43     PHRASE_XSL,
44     PHRASE_XSL_NAMESPACE,
45     PHRASE_XML_NAMESPACE,
46     PHRASE_STAR,
47     PHRASE_XMLNS,
48     PHRASE_LANG,
49     PHRASE_SABEXT_NAMESPACE,
50     PHRASE_LAST
51 };
52 
53 #include "base.h"
54 #include "arena.h"
55 #include "hash.h"
56 #include "datastr.h"
57 #include "uri.h"
58 #include "output.h"
59 #include "encoding.h"
60 #include "decimal.h"
61 #include "jsext.h"
62 #include "sxpath.h"
63 // #include "vars.h"
64 //#include "expr.h"
65 //#include "context.h"
66 
67 extern const char *theXSLTNamespace;
68 
69 class Tree;
70 class TreeConstructer;
71 class LocStep;
72 class Vertex;
73 class Daddy;
74 class Attribute;
75 class XSLElement;
76 class Expression;
77 class Context;
78 typedef PList<Expression*> ExprList;
79 
80 /*****************************************************************
81 
82     R u l e I t e m
83     an item of RuleSList describing a rule
84 
85 *****************************************************************/
86 
87 class RuleItem
88 {
89 public:
90     RuleItem(XSLElement *,double, QName &, QName *);
91     ~RuleItem();
92     XSLElement *rule;
93     Attribute *match;
94     double priority;
95     QName name,
96         *mode;
97 };
98 
99 
100 class Processor;
101 
102 /*****************************************************************
103 
104     R u l e S L i s t
105     sorted list of rules
106 
107 *****************************************************************/
108 
109 class RuleSList : public SList<RuleItem*>
110 {
111 public:
112     RuleSList();
113     ~RuleSList();
114     int compare(int first, int second, void *data);
115     XSLElement* findByName(const Tree &t, const QName &q) const;
116 };
117 
118 /*****************************************************************
119 
120 DataLinesList
121 
122 *****************************************************************/
123 
124 
125 class DataLineItem
126 {
127 public:
128     DataLineItem(Sit S_);
129     ~DataLineItem();
130     DataLine *_dataline;
131     Tree *_tree;
132     Bool _isXSL;
133     Bool _preparsedTree;
134 private:
135     Sit situation;
136 };
137 
138 class DataLinesList: public PList<DataLineItem*>
139 {
140 public:
141     int findNum(Str &absoluteURI, Bool _isXSL,
142         DLAccessMode _mode);
143     Tree* getTree(Str &absoluteURI, Bool _isXSL, DLAccessMode _mode);
144     eFlag addLine(Sit S, DataLine *d, Tree *t, Bool isXSL,
145         Bool preparsedTree = FALSE);
146 
147 };
148 
149 /*****************************************************************
150 
151     OutputDocumentList
152 
153 *****************************************************************/
154 
155 class OutputDocumentList: public PList<OutputDocument*>
156 {
157 };
158 
159 
160 /*****************************************************************
161 
162     P   r   o   c   e   s   s   o   r
163 
164 *****************************************************************/
165 
166 class VarsList;
167 class VertexList;
168 class Element;
169 class KeySet;
170 
171 class Processor /* : public SabObj */
172 {
173 public:
174     Tree *input,
175         *styleSheet;
176     Processor();
177     ~Processor();
178     eFlag open(Sit S, const char *sheetURI, const char *inputURI);
179     eFlag run(Sit S, const char* resultURI, NodeHandle doc = NULL);
180     eFlag execute(Sit S, Vertex *, Context *&,  Bool resolvingGlobals);
181     eFlag execute(Sit S, VertexList&, Context *&,  Bool resolvingGlobals);
182 
183     // finds the best matching rule imported into styleSheet
184     // and applies it to the current node of c
185     eFlag execApplyImports(Sit S, Context *c, SubtreeInfo *subtree,
186 			   Bool resolvingGlobals);
187 
188     // executes the default rule for the current node of c
189     eFlag builtinRule(Sit S, Context *c,  Bool resolvingGlobals);
190 
191     FILE *logfile;
192     unsigned long allocObjects,
193         allocBytes,
194         maxAllocObjects,
195         maxAllocBytes;
196     Expression* getVarBinding(QName &);
197     VarsList *vars;
outputter()198     OutputterObj* outputter()
199 	{
200 	    if (outputters_.number())
201 		return outputters_.last();
202 	    else return NULL;
203 	}
204     QName* getCurrentMode();
205     void pushMode(QName *);
206     void popMode();
207     eFlag readTreeFromURI(Sit S, Tree*& newTree, const Str& location,
208 			  const Str& base, Bool isXSL,
209 			  Bool ignoreErr = FALSE);
210     eFlag pushOutputterForURI(Sit S, Str& location, Str& base,
211 			      OutputDefinition *outDef = NULL);
212     eFlag createOutputterForURI(Sit S, //Str& location, Str& base,
213 				Str& absolute,
214 				OutputterObj*& result,
215 				OutputDefinition *outDef = NULL);
216     eFlag pushTreeConstructer(Sit S, TreeConstructer *&newTC, Tree *t,
217 			      SAXOutputType ot = SAXOUTPUT_COPY_TREE);
218     eFlag pushOutputter(Sit S, OutputterObj* out_);
219     eFlag popOutputter(Sit S);
220     eFlag popOutputterNoFree(Sit S);
221     eFlag popTreeConstructer(Sit S, TreeConstructer *theTC);
222     eFlag processVertexAfterParse(Sit S, Vertex *, Tree *, TreeConstructer *tc);
223 
224     eFlag setHandler(Sit S, HandlerType type, void *handler, void *userData);
225     SchemeHandler* getSchemeHandler(void **udata);
226     MessageHandler* getMessageHandler(void **udata);
227     SAXHandler* getSAXHandler(void **udata);
228     MiscHandler* getMiscHandler(void **udata);
229     EncHandler* getEncHandler(void **udata);
230 
231     void* getHandlerUserData(HandlerType type, void *handler);
232 
233     void setHardEncoding(const Str& hardEncoding_);
234     const Str& getHardEncoding() const;
235 
236     eFlag addLineNoTree(Sit S, DataLine *&d, Str &absolute, Bool isXSL);
237     eFlag addLineParse(Sit S, Tree *& newTree, Str &absolute,
238 		       Bool isXSL, Bool ignoreErr = FALSE);
239     eFlag addLineTreeOnly(Sit S, DataLine *&d, Str &absolute, Bool isXSL,
240 			  Tree *t);
241     void copyArg(Sit S, const Str& argName, int* argOrdinal, char*& newCopy);
242     eFlag getArg(Sit S, const char*, char*&, Bool);
243     eFlag useArg(Sit S, const char *name, const char *val);
244     eFlag useTree(Sit S, const char *name, Tree *t);
245     eFlag freeResultArgs(Sit S);
246     eFlag addGlobalParam(Sit S, const char *name, const char *val);
247     eFlag useGlobalParam(Sit S, const char *name, const char *val);
248     eFlag useGlobalParams(Sit S);
249     const Str& baseForVertex(Sit S, Element *v);
250     const Str& findBaseURI(Sit S, const Str& unmappedBase);
251     void addBaseURIMapping(const Str& scheme, const Str& mapping);
252     void setHardBaseURI(const char* hardBase);
253 
setInstanceData(void * idata)254     void setInstanceData(void *idata)
255 	{
256 	    instanceData = idata;
257 	};
258 
getInstanceData()259     void* getInstanceData()
260 	{
261 	    return instanceData;
262 	};
263 
rememberSituation(Situation * SP)264     void rememberSituation(Situation *SP)
265 	{
266 	    instanceSituation = SP;
267 	}
268 
rememberMasterSituation(Situation * SP)269     void rememberMasterSituation(Situation *SP)
270 	{
271 	    instanceSituation = SP;
272 	    hasMasterSituation = TRUE;
273 	}
274 
recallSituation()275     Situation* recallSituation()
276 	{
277 	    return instanceSituation;
278 	}
279 
situationIsMaster()280     Bool situationIsMaster()
281 	{
282 	    return hasMasterSituation;
283 	}
284 
285     void prepareForRun();
286     void cleanupAfterRun(Situation *Sp);
287     const QName theEmptyQName;
288     SabArena* getArena();
289     //Str getAliasedName(const EQName& name, NamespaceStack& currNamespaces,
290     //Bool expatLike);
291     void getAliasedName(EQName & name, Bool & aliased);
292     void report(Sit S, MsgType type, MsgCode code,
293 		const Str &arg1, const Str &arg2) const;
getAddedFlag()294     Bool getAddedFlag() {return addedFlag;}
295     eFlag addKey(Sit S, const EQName& ename,
296 		 Expression& match, Expression &use);
297     eFlag getKeyNodes(Sit S, const EQName& ename,
298 		      const Str& value, Context& result, SXP_Document doc) const;
299     eFlag makeKeysForDoc(Sit S, SXP_Document doc);
decimals()300     DecimalFormatList& decimals()
301 	{
302 	    return decimalsList;
303 	}
304     void initForSXP(Tree *baseTree);
305     void cleanupAfterSXP();
306     Bool supportsFunction(Str &uri, Str &name);
307 #ifdef ENABLE_JS
308     eFlag evaluateJavaScript(Sit S, Str &uri, DStr &script);
309     eFlag callJSFunction(Sit S, Context *c, Str &uri, Str &name,
310 			 ExprList &atoms, Expression &retxpr);
311 #endif
getArgList()312     StrStrList &getArgList() {return argList;};
313     Str getNextNSPrefix();
314     // resolve a global variable identified by name and possibly pointer
315     // if varElem != NULL. sets 'name' accordingly
316     eFlag resolveGlobal(Sit S, Context *c, QName &name, XSLElement *varElem = NULL);
317     // resolve all global vars before executing
318     //eFlag resolveGlobals(Sit S, Context *c);
319     eFlag stripTree(Sit S, Tree &tree);
320     eFlag stripElement(Sit S, Daddy *e);
processingExternal()321     Bool processingExternal() { return runsOnExternal; };
322     void pushInBinding(Bool val);
323     void popInBinding();
324     Bool isInBinding();
325     //eFlag pushDocumentDefinition(Sit S, OutputDefinition *def,
326     //					 OutputterObj*& out);
327     //eFlag popDocumentDefinition(Sit S);
328     eFlag getOutputDocument(Sit S, Str& href, OutputDocument*& doc,
329 			    OutputDefinition *def);
330     eFlag startDocument(Sit S, OutputDocument *doc);
331     eFlag finishDocument(Sit S, OutputDocument *doc, Bool canClose);
332     eFlag prefixIsAliasTarget(Sit S, const Str& prefix, Bool& result);
333 private:
334     int nsUnique;
335     eFlag openCommon(Sit S);
336     eFlag execApplyTemplates(Sit S, Context *c, Bool resolvingGlobals);
337     eFlag execApply(Sit S, Context *c, Bool resolvingGlobals);
338     PList<QName*> modes;
339     StrStrList argList;
340     DataLinesList datalines;
341     PList<OutputterObj*> outputters_;
342     //  handlers
343     SchemeHandler *theSchemeHandler;
344     MessageHandler *theMessageHandler;
345     SAXHandler *theSAXHandler;
346     MiscHandler *theMiscHandler;
347     EncHandler *theEncHandler;
348     void
349     *theSchemeUserData,
350         *theMessageUserData,
351         *theSAXUserData,
352         *theMiscUserData,
353         *theEncUserData;
354     void *instanceData;
355     void freeNonArgDatalines();
356     StrStrList baseURIMappings, globalParamsList;
357     Str hardEncoding;
358     SabArena theArena;
359     Situation *instanceSituation;
360     Bool hasMasterSituation;
361     Bool addedFlag;
362     KeySet *keys;
363     DecimalFormatList decimalsList;
364 #ifdef ENABLE_JS
365     JSContextList jscontexts;
366 #endif
367     Bool runsOnExternal;
368     NodeHandle inputRoot;
369     List<Bool> inBinding;
370     //PList<OutputDefinition*> documentDefinitions;
371     OutputDocumentList outputDocuments;
372     SortedStringList outputDocumentURIs;
373 };
374 
375 #endif //ifndef ProcHIncl
376