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 /****************************************
34 *                                       *
35 i n c l u d e s
36 *                                       *
37 ****************************************/
38 
39 // #include<iostream.h>
40 
41 // GP: clean
42 
43 #include <stdarg.h>
44 
45 #define SablotAsExport
46 #include "sablot.h"
47 
48 #include "base.h"
49 #include "verts.h"
50 #include "tree.h"
51 #include "expr.h"
52 #include "proc.h"
53 #include "situa.h"
54 #include "uri.h"
55 #include "parser.h"
56 #include "guard.h"
57 #include "sxpath.h"
58 #include "domprovider.h"
59 
60 //
61 //  defines
62 //
63 
64 #define P( PTR ) ((Processor *)(PTR))
65 #define EE(statement) {int code___=(statement); if (code___) return code___;}
66 #define ES(statement) {if (statement) return SIT(S).getError();}
67 // same as EE() but destroys the given processor
68 #define EE_D(CODE,PROC) {int code___=(CODE); if (code___) {SablotDestroyProcessor(PROC); return code___;}}
69 // error-checking chain
70 #define EC( VAR, STMT ) {if (!VAR) VAR = STMT;}
71 #define SIT( S ) (*(Situation*)S)
72 
73 
74 /****************************************
75 g l o b a l s
76 ****************************************/
77 #define checkErr(situation) {if (situation->isError()) \
78     {Warn(situation, W_PENDING_ERROR); return NOT_OK;}}
79 
80 
81 /****************************************
82 d e f i n i t i o n s
83 ****************************************/
84 
doStart(Sit S)85 void doStart(Sit S)
86 {
87     S.message(MT_LOG, L_START, S.timeStr(), (char*) NULL);
88 //    Log1(S, L_START, S.timeStr());
89 };
90 
doEnd(Sit S)91 void doEnd(Sit S)
92 {
93     S.message(MT_LOG, L_STOP, S.timeStr(), (char*) NULL);
94 //    Log1(S, L_STOP, S.timeStr());
95 }
96 
97 #define ErrQ(S, e) {\
98     S.message(MT_ERROR, e,(char*) NULL, (char*)NULL); \
99     doEnd(S); \
100     return e; \
101 	}
102 
103 // report function to enable the Sablot... globals to use Err and Log
report(Sit S,MsgType type,MsgCode code,const Str & arg1,const Str & arg2)104 void report(Sit S, MsgType type, MsgCode code, const Str& arg1, const Str& arg2)
105 {
106     S.message(type, code, arg1, arg2);
107 }
108 
109 
110 //
111 //
112 //      situation functions
113 //
114 //
115 
SablotCreateSituation(SablotSituation * sPtr)116 int SablotCreateSituation(SablotSituation *sPtr)
117 {
118     *sPtr = new Situation;
119     if (!*sPtr)
120         return E_MEMORY;
121     return OK;
122 }
123 
SablotDestroySituation(SablotSituation S)124 int SablotDestroySituation(SablotSituation S)
125 {
126     if (S) delete (Situation*)S;
127     S = NULL;
128     return OK;
129 }
130 
SablotSetOptions(SablotSituation S,int flags)131 int SablotSetOptions(SablotSituation S, int flags)
132 {
133     ((Situation*)S) -> setFlags(flags);
134     return OK;
135 }
136 
SablotGetOptions(SablotSituation S)137 int SablotGetOptions(SablotSituation S)
138 {
139   return ((Situation*)S) -> getFlags();
140 }
141 
SablotClearSituation(SablotSituation S)142 int SablotClearSituation(SablotSituation S)
143 {
144     ((Situation*)S) -> clear();
145     return OK;
146 }
147 
148 //
149 //    document functions
150 //
151 
SablotCreateDocument(SablotSituation S,SDOM_Document * D)152 int SablotCreateDocument(SablotSituation S, SDOM_Document *D)
153 {
154     // non-XSL tree with empty name
155     Tree *t = new Tree((char*)"", FALSE);
156     SabArena &ar = t -> getArena();
157     NmSpace *nm = new (&ar) NmSpace(*t, t -> unexpand("xml"),
158 				    t -> unexpand(theXMLNamespace),
159 				    TRUE, NSKIND_DECLARED);
160     RootNode &root = t -> getRoot();
161     root.namespaces.append(nm);
162     *D = &root;
163     return OK;
164 }
165 
SablotParse_(SablotSituation S,const char * uri,const char * buffer,SDOM_Document * D,Bool asStylesheet)166 int SablotParse_(
167     SablotSituation S,
168     const char *uri,
169     const char *buffer,
170     SDOM_Document *D,
171     Bool asStylesheet)
172 {
173     Str absolute;
174     StrStrList argList;
175     DStr base;
176     *D = NULL;
177     double time_was = getMillisecs();
178     int code = 0;
179 
180     SIT(S).clear();
181     // make absolute address
182     char *parserBase = NULL;
183     if (!buffer)
184     {
185         my_getcwd(base);
186         base = Str("file://") + base;
187         // should call Processor::findBaseURI() here (but have no Processor)
188         makeAbsoluteURI(SIT(S), uri, base, absolute);
189 	parserBase = (char*)absolute;
190     }
191     else
192       absolute = "arg:/_parsed_";
193 
194     // create the tree and dataline
195     DataLine line;
196     GP( Tree ) newTree = new Tree(absolute, /* isXSL = */ asStylesheet);
197     TreeConstructer tc(SIT(S));
198 
199     // add buffer if there is one
200     if (buffer)
201         argList.appendConstruct("/_parsed_", buffer);
202 
203     // open the line
204     EC( code, line.open(SIT(S), absolute, DLMODE_READ, &argList) );
205 
206     Log1(SIT(S), L1_PARSING, absolute);
207     EC( code, tc.parseDataLineUsingExpat(SIT(S), newTree, &line, parserBase) );
208     EC( code, line.close(SIT(S)) );
209     *D = &(newTree.keep() -> getRoot());
210     Log1(SIT(S), L1_PARSE_DONE, getMillisecsDiff(time_was));
211 
212     argList.freeall(FALSE);
213     return SIT(S).getError();
214 }
215 
216 
SablotParse(SablotSituation S,const char * uri,SDOM_Document * D)217 int SablotParse(
218     SablotSituation S,
219     const char *uri,
220     SDOM_Document *D)
221 {
222     return SablotParse_(S, uri, NULL, D, FALSE);
223 }
224 
SablotParseBuffer(SablotSituation S,const char * buffer,SDOM_Document * D)225 int SablotParseBuffer(
226     SablotSituation S,
227     const char *buffer,
228     SDOM_Document *D)
229 {
230     return SablotParse_(S, NULL, buffer, D, FALSE);
231 }
232 
SablotParseStylesheet(SablotSituation S,const char * uri,SDOM_Document * D)233 int SablotParseStylesheet(
234     SablotSituation S,
235     const char *uri,
236     SDOM_Document *D)
237 {
238     return SablotParse_(S, uri, NULL, D, TRUE);
239 }
240 
SablotParseStylesheetBuffer(SablotSituation S,const char * buffer,SDOM_Document * D)241 int SablotParseStylesheetBuffer(
242     SablotSituation S,
243     const char *buffer,
244     SDOM_Document *D)
245 {
246     return SablotParse_(S, NULL, buffer, D, TRUE);
247 }
248 
SablotLockDocument(SablotSituation S,SDOM_Document D)249 int SablotLockDocument(SablotSituation S, SDOM_Document D)
250 {
251     ((RootNode*)D) -> getOwner().makeStamps();
252     return OK;
253 }
254 
SablotDestroyDocument(SablotSituation S,SDOM_Document D)255 int SablotDestroyDocument(SablotSituation S, SDOM_Document D)
256 {
257   delete &((toRoot(toV(D))) -> getOwner());
258   return OK;
259 }
260 
261 
262 //
263 //
264 //      SablotCreateProcessor
265 //
266 //
267 
SablotCreateProcessor(void ** processorPtr)268 int SablotCreateProcessor(void **processorPtr)
269 {
270     // to debug memory leaks in MSVC, uncomment the call to checkLeak()
271     // and set _crtBreakAlloc to the # of block (proc=51)
272 
273     // create a new situation for this processor
274     void *newSit = NULL;
275     SablotCreateSituation(&newSit);
276 
277 #if defined(HAVE_MTRACE) && defined(CHECK_LEAKS)
278     mtrace();
279 #endif
280     *processorPtr = new Processor;
281     if (!*processorPtr)
282     {
283         ((Situation*)newSit) -> message(MT_ERROR, E_MEMORY, (char*) NULL, (char*) NULL);
284 	return E_MEMORY;
285         // Err( *newSit, E_MEMORY );
286     }
287     // the processor must remember its situation (this is just to
288     // avoid compatibility breakdown)
289     P( *processorPtr ) -> rememberSituation((Situation*)newSit);
290     SIT( newSit).setProcessor( P(*processorPtr) );
291 
292     // the following seems superfluous - the processor is new
293     // checkErr( P(*processorPtr)->situation );
294     doStart ( SIT( newSit ) );
295     return OK;
296 }
297 
SablotCreateProcessorForSituation(SablotSituation S,void ** processorPtr)298 int SablotCreateProcessorForSituation(SablotSituation S, void **processorPtr)
299 {
300 #if defined(HAVE_MTRACE) && defined(CHECK_LEAKS)
301     mtrace();
302 #endif
303     *processorPtr = new Processor;
304     if (!*processorPtr)
305     {
306         SIT(S).message(MT_ERROR, E_MEMORY, (char*) NULL, (char*) NULL);
307 	return E_MEMORY;
308     }
309     P( *processorPtr ) -> rememberMasterSituation((Situation*)S);
310     SIT(S).setProcessor( P(*processorPtr) ); // this will go asap
311     doStart ( SIT(S) );
312     return OK;
313 }
314 
SablotAddParam(SablotSituation S,void * processor_,const char * paramName,const char * paramValue)315 int SablotAddParam(
316     SablotSituation S,
317     void *processor_,
318     const char *paramName,
319     const char *paramValue)
320 {
321     SIT(S).clear();
322     ES( P(processor_) -> addGlobalParam(SIT(S),
323         (char*)paramName, (char*)paramValue) );
324     return OK;
325 }
326 
SablotAddArgBuffer(SablotSituation S,void * processor_,const char * argName,const char * bufferValue)327 int SablotAddArgBuffer(
328     SablotSituation S,
329     void *processor_,
330     const char *argName,
331     const char *bufferValue)
332 {
333     SIT(S).clear();
334     if (!(P(processor_) -> getAddedFlag()))
335         SablotFreeResultArgs (processor_);
336     ES( P(processor_) -> useArg(SIT(S), (char*)argName, (char*)bufferValue) );
337     return OK;
338 }
339 
SablotAddArgTree(SablotSituation S,void * processor_,const char * argName,SDOM_Document tree)340 int SablotAddArgTree(
341     SablotSituation S,
342     void *processor_,
343     const char *argName,
344     SDOM_Document tree)
345 {
346     SIT(S).clear();
347     if (!(P(processor_) -> getAddedFlag()))
348         SablotFreeResultArgs (processor_);
349     ES( P(processor_) -> useTree(SIT(S), (char*) argName,
350 				 &(toRoot(tree) -> getOwner())) );
351     return OK;
352 }
353 
SablotRunProcessorGen(SablotSituation S,void * processor_,const char * sheetURI,const char * inputURI,const char * resultURI)354 int SablotRunProcessorGen(
355     SablotSituation S,
356     void *processor_,
357     const char *sheetURI,
358     const char *inputURI,
359     const char *resultURI)
360 {
361     int code = 0;
362 
363     void *saveproc = processor_;
364     SIT(S).swapProcessor(saveproc);
365 
366     SIT(S).clear();
367     // remove the existing 'arg' buffers
368     if (!(P(processor_) -> getAddedFlag()))
369         EC( code, SablotFreeResultArgs (processor_) );
370     if (!code)
371 	P(processor_) -> prepareForRun();
372     // must first open the files, then use global params
373     // because VarsList needs stylesheet's dictionary
374     EC( code, P(processor_) -> open(SIT(S), sheetURI,inputURI) );
375     EC( code, P(processor_) -> useGlobalParams(SIT(S)) );
376     EC( code, P(processor_) -> run(SIT(S), resultURI) );
377     code = SIT(S).getError();
378     P(processor_) -> cleanupAfterRun((Situation*)S);
379     if (code)
380     {
381         // GP: if not all files could be opened, those that could are
382         // closed in cleanupAfterRun
383         // code = SIT(S).getError();
384         P(processor_) -> freeResultArgs(SIT(S));
385     };
386 
387     SIT(S).swapProcessor(saveproc);
388     return code;
389 }
390 
SablotRunProcessorExt(SablotSituation S,void * processor_,const char * sheetURI,const char * resultURI,NodeHandle doc)391 int SablotRunProcessorExt(
392     SablotSituation S,
393     void *processor_,
394     const char *sheetURI,
395     const char *resultURI,
396     NodeHandle doc)
397 {
398     int code = 0;
399     //mask external node
400     doc = SXP_MASK_LEVEL(doc, SIT(S).getSXPMaskBit());
401 
402     void *saveproc = processor_;
403     SIT(S).swapProcessor(saveproc);
404 
405     SIT(S).clear();
406     // remove the existing 'arg' buffers
407     if (!(P(processor_) -> getAddedFlag()))
408         EC( code, SablotFreeResultArgs (processor_) );
409     if (!code)
410 	P(processor_) -> prepareForRun();
411     // must first open the files, then use global params
412     // because VarsList needs stylesheet's dictionary
413     EC( code, P(processor_) -> open(SIT(S), sheetURI, NULL) );
414     EC( code, P(processor_) -> useGlobalParams(SIT(S)) );
415     EC( code, P(processor_) -> run(SIT(S), resultURI, doc) );
416     code = SIT(S).getError();
417     P(processor_) -> cleanupAfterRun((Situation*)S);
418     if (code)
419     {
420         // GP: if not all files could be opened, those that could are
421         // closed in cleanupAfterRun
422         // code = SIT(S).getError();
423         P(processor_) -> freeResultArgs(SIT(S));
424     };
425 
426     SIT(S).swapProcessor(saveproc);
427     return code;
428 }
429 
430 
431 //
432 //
433 //      SablotRunProcessor
434 //
435 //
SablotRunProcessor(void * processor_,const char * sheetURI,const char * inputURI,const char * resultURI,const char ** params,const char ** arguments)436 int SablotRunProcessor(void *processor_,
437                        const char *sheetURI,
438                        const char *inputURI,
439                        const char *resultURI,
440                        const char **params,
441                        const char **arguments)
442 {
443     Bool problem = FALSE;
444     Sit S = *(NZ(P( processor_ )) -> recallSituation());
445 
446     {
447         // remove the existing 'arg' buffers
448 	    S.clearError();
449         E( SablotFreeResultArgs (processor_));
450         P(processor_) -> prepareForRun();
451         const char **p;
452         if (arguments)
453         {
454             for (p = arguments; *p && !problem; p += 2)
455                 problem = P(processor_) -> useArg(S, p[0], p[1]);
456         }
457 	    if (!problem)
458 	    {
459 	        // must first open the files, then use global params
460 		    // because VarsList needs stylesheet's dictionary
461 	        problem = P(processor_) -> open(S, sheetURI,inputURI);
462             if (params)
463             {
464                 for (p = params; *p && !problem; p += 2)
465                     problem = P(processor_) -> useGlobalParam(S, p[0], p[1]);
466             }
467 	    }
468         if (problem || P(processor_) -> run(S, resultURI))
469         {
470             // GP: if not all files could be opened, those that could are
471             // closed in cleanupAfterRun
472             int code = S.getError();
473             P(processor_) -> cleanupAfterRun(&S);
474             P(processor_) -> freeResultArgs(S);
475 //            cdelete(proc);
476             // S.clear(); (why forget the message?)
477             return code;
478         }
479     }
480     P(processor_) -> cleanupAfterRun(&S);
481     return OK;
482 }
483 
484 
485 
486 //
487 //
488 //      SablotDestroyProcessor
489 //
490 //
491 
492 
SablotDestroyProcessor(void * processor_)493 int SablotDestroyProcessor(void *processor_)
494 {
495     int code;
496     Bool killSit = !(P( processor_ ) -> situationIsMaster());
497     Situation *SP = P(processor_) -> recallSituation();
498     code = SablotFreeResultArgs(processor_);
499     doEnd(*SP);
500     if(processor_) delete P( processor_);
501     processor_ = NULL;
502     if (killSit)
503 	cdelete(SP);
504 #if defined(WIN32) && defined(CHECK_LEAKS)
505     memStats();
506     checkLeak();
507 #endif
508     return code;
509 };
510 
511 
512 
513 //
514 //
515 //      SablotSetBase
516 //
517 //
518 
SablotSetBase(void * processor_,const char * theBase)519 int SablotSetBase(void* processor_,
520                   const char *theBase)
521 {
522     P(processor_) -> setHardBaseURI(theBase);
523     return OK;
524 }
525 
526 
527 //
528 //
529 //      SablotSetBaseForScheme
530 //
531 //
532 
SablotSetBaseForScheme(void * processor_,const char * scheme,const char * base)533 int SablotSetBaseForScheme(void* processor_,
534                   const char *scheme, const char *base)
535 {
536     P(processor_) -> addBaseURIMapping(scheme, base);
537     return OK;
538 }
539 
540 
541 
542 
543 //
544 //
545 //      SablotGetResultArg
546 //
547 //
548 
SablotGetResultArg(void * processor_,const char * argURI,char ** argValue)549 int SablotGetResultArg(void *processor_,
550                        const char *argURI,
551                        char **argValue)
552 {
553     char *newCopy; // GP: OK
554     // we even obtain the index of the output buffer but won't use it
555     int resultNdx_;
556     if (argValue)
557     {
558       Situation *s = P(processor_) -> recallSituation();
559       sabassert(s); //we always should have some situation, master or internal
560       P(processor_) -> copyArg(SIT(s), argURI, &resultNdx_, newCopy);
561       // if output does not go to a buffer, newCopy is NULL
562       *argValue = newCopy;
563     }
564     return OK;
565 }
566 
567 
568 //
569 //
570 //      SablotSetLog
571 //
572 //
573 
SablotSetLog(void * processor_,const char * logFilename,int logLevel)574 int SablotSetLog(void *processor_,
575     const char *logFilename, int logLevel)
576 {
577     P(processor_) -> recallSituation()->msgOutputFile((char *)"/__stderr",(char*) logFilename);
578     // logLevel ignored so far
579     return OK;
580 }
581 
582 
583 /*****************************************************************
584 SablotProcess
585 
586   the main function published by Sablotron. Feeds given XML
587   input to a stylesheet. Both of these as well as the location for
588   output are identified by a URI. One can also pass top-level
589   stylesheet parameters and named buffers ('args').
590 ARGS
591   sheetURI      URI of the XSLT stylesheet
592   inputURI      URI of the XML document
593   resultURI     URI of the output document
594   params        a NULL-terminated array of char*'s defining the top-level
595                 parameters to be passed, interpreted as a
596                 sequence of (name, value) pairs.
597   arguments     a NULL-terminated array of char*'s defining the named
598                 buffers to be passed, interpreted as a
599                 sequence of (name, value) pairs. Both params and arguments
600                 may be NULL.
601 RETURNS
602   .             nonzero iff error
603   resultArg     in case output goes to a named buffer, *resultArg is set to
604                 point to it (otherwise to NULL). Free it using SablotFree().
605 *****************************************************************/
606 
SablotProcess(const char * sheetURI,const char * inputURI,const char * resultURI,const char ** params,const char ** arguments,char ** resultArg)607 int SablotProcess(const char *sheetURI, const char *inputURI,
608 		  const char *resultURI,
609 		  const char **params, const char **arguments,
610 		  char **resultArg)
611 {
612     void *theproc;
613     EE( SablotCreateProcessor (&theproc) );
614     EE_D( SablotRunProcessor(theproc,
615         sheetURI, inputURI, resultURI,
616         params, arguments), theproc );
617     EE_D( SablotGetResultArg(theproc, resultURI, resultArg), theproc );
618     EE( SablotDestroyProcessor(theproc) );
619     return OK;
620 };
621 
622 
623 /*****************************************************************
624 SablotProcessFiles
625 
626   calls SablotProcess to process files identified by their
627   file names. No named buffers or params are passed. Included
628   for backward compatibility.
629 ARGUMENTS
630   styleSheetName, inputName, resultName
631             file names of the stylesheet, XML input and output,
632             respectively.
633 RETURNS
634   .         error flag
635 *****************************************************************/
636 
637 
SablotProcessFiles(const char * styleSheetName,const char * inputName,const char * resultName)638 int SablotProcessFiles(const char *styleSheetName,
639                        const char *inputName,
640                        const char *resultName)
641 {
642     return SablotProcess(
643         styleSheetName, inputName, resultName,
644         NULL, NULL, NULL);
645 };
646 
647 
648 /*****************************************************************
649 SablotProcessStrings
650 
651   calls SablotProcess to process documents in memory, passing
652   pointers to the documents. No named buffers or params are passed.
653   Included for backward compatibility.
654 ARGUMENTS
655   styleSheetStr, inputStr
656                 text of the stylesheet and the XML input
657 RETURNS
658   .             error flag
659   *resultStr    pointer to the newly allocated block containing
660                 the result
661 *****************************************************************/
SablotProcessStrings(const char * styleSheetStr,const char * inputStr,char ** resultStr)662 int SablotProcessStrings(const char *styleSheetStr,
663                          const char *inputStr,
664                          char **resultStr)
665 {
666   const char *argums[] =
667   {
668     "/_stylesheet", styleSheetStr,
669     "/_xmlinput", inputStr,
670     "/_output", NULL, //was: *resultStr,
671     NULL
672   };
673   return SablotProcess("arg:/_stylesheet",
674                        "arg:/_xmlinput",
675                        "arg:/_output",
676                        NULL, argums, resultStr);
677 };
678 
679 
680 /*****************************************************************
681 SablotProcessStringsWithBase
682 
683     Like SablotProcessStrings but lets you pass an URI that replaces
684     the stylesheet's URI in relative address resolution.
685 
686 ARGUMENTS
687   styleSheetStr, inputStr
688                 text of the stylesheet and the XML input
689   theHardBase   the "hard base URI" replacing the stylesheet's URI
690                 in all relevant situations
691 RETURNS
692   .             error flag
693   *resultStr    pointer to the newly allocated block containing
694                 the result
695 *****************************************************************/
696 
SablotProcessStringsWithBase(const char * styleSheetStr,const char * inputStr,char ** resultStr,const char * theHardBase)697 int SablotProcessStringsWithBase(const char *styleSheetStr,
698                          const char *inputStr,
699                          char **resultStr,
700                          const char *theHardBase)
701 {
702     const char *argums[] =
703     {
704         "/_stylesheet", styleSheetStr,
705         "/_xmlinput", inputStr,
706         "/_output", NULL, //was: *resultStr,
707         NULL
708     };
709     void *theproc;
710     EE( SablotCreateProcessor(&theproc));
711     EE_D( SablotSetBase(theproc, theHardBase), theproc );
712     EE_D( SablotRunProcessor(theproc,
713         "arg:/_stylesheet",
714         "arg:/_xmlinput",
715         "arg:/_output",
716         NULL, argums), theproc);
717     EE_D( SablotGetResultArg(theproc,
718         "arg:/_output", resultStr), theproc);
719     EE( SablotDestroyProcessor(theproc));
720     return OK;
721 };
722 
723 
724 /*****************************************************************
725 SablotFree
726 
727   Frees the Sablotron-allocated buffer.
728 *****************************************************************/
729 
SablotFree(char * resultStr)730 int SablotFree(char *resultStr)
731 {
732     if (resultStr)
733         delete[] resultStr;
734     return OK;
735 }
736 
737 
738 //
739 //
740 //      SablotFreeResultArgs
741 //      frees the result arg buffers after the have been obtained
742 //      via SablotGetResultArg()
743 //
744 //
745 
SablotFreeResultArgs(void * processor_)746 int SablotFreeResultArgs(void *processor_)
747 {
748     EE( P(processor_) -> freeResultArgs(*(P(processor_) -> recallSituation())) );
749     return OK;
750 }
751 
752 
753 //
754 //
755 //      SablotRegHandler
756 //
757 //
758 
SablotRegHandler(void * processor_,HandlerType type,void * handler,void * userData)759 int SablotRegHandler(void *processor_,
760                      /* HLR_MESSAGE, HLR_SCHEME, HLR_SAX, HLR_MISC */
761                      HandlerType type,
762                      void *handler,
763                      void *userData)
764 {
765     Sit S = *(P(processor_) -> recallSituation());
766     EE( P(processor_) -> setHandler(S, type, handler, userData) );
767     if (type == HLR_MESSAGE)
768         EE( S.closeFiles() );
769     return OK;
770 }
771 
772 
773 
774 //
775 //
776 //      SablotUnregHandler
777 //
778 //
779 
SablotUnregHandler(void * processor_,HandlerType type,void * handler,void * userData)780 int SablotUnregHandler(void *processor_,
781                        HandlerType type,   /* HLR_MESSAGE, HLR_SCHEME, HLR_SAX */
782                        void *handler,
783                        void *userData)
784 {
785     Sit S = *(P(processor_) -> recallSituation());
786     EE( P(processor_) -> setHandler(S, type, NULL, NULL) );
787     if (type == HLR_MESSAGE)
788         EE( S.openDefaultFiles() );
789     return OK;
790 }
791 
792 
793 //
794 //
795 //      SablotGetMsgText
796 //
797 //
798 
SablotGetMsgText(int code)799 const char* SablotGetMsgText(int code)
800 {
801     return GetMessage((MsgCode) code) -> text;
802 }
803 
804 //
805 //
806 //      SablotClearError
807 //
808 //
809 
SablotClearError(void * processor_)810 int SablotClearError(void *processor_)
811 {
812     P(processor_) -> recallSituation() -> clear();
813     return OK;
814 }
815 
816 //
817 //
818 //      SablotSetInstanceData
819 //
820 //
821 
SablotSetInstanceData(void * processor_,void * idata)822 void SablotSetInstanceData(void *processor_, void *idata)
823 {
824     P(processor_) -> setInstanceData(idata);
825 }
826 
827 //
828 //
829 //      SablotGetInstanceData
830 //
831 //
832 
SablotGetInstanceData(void * processor_)833 void* SablotGetInstanceData(void *processor_)
834 {
835     return P(processor_) -> getInstanceData();
836 }
837 
838 //
839 //
840 //      SablotSetEncoding
841 //      sets the output encoding to be used regardless of the encoding
842 //      specified by the stylesheet
843 //      To unset, call with encoding_ NULL.
844 //
845 //
846 
SablotSetEncoding(void * processor_,char * encoding_)847 void SablotSetEncoding(void *processor_, char *encoding_)
848 {
849     P(processor_) -> setHardEncoding(
850         encoding_ ? encoding_ : (const char*) "");
851 }
852