~ubuntu-branches/ubuntu/trusty/libxslt/trusty

« back to all changes in this revision

Viewing changes to libexslt/functions.c

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2006-10-27 18:30:38 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20061027183038-gjgawhlr2k4csrr6
Tags: 1.1.18-1
* New upstream release:
  + Fixes xsl:variable with node sets. Closes: #381597.
  + Honors disable-output-escaping in xhtml 1.0 style element.
    Closes: #395210.
  + Supports XInclude processing on XSL stylesheets. Closes: #395210.
  + Correctly handles xsl:param names with namespaces. Closes: #389023.
* debian/control:
  + Bumped Standards-Version to 3.7.2.2. No changes required.
  + Build depend on libxml2 >= 2.6.27, and adapt other dependencies
    accordingly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
    xmlHashTablePtr funcs;      /* pointer to the stylesheet module data */
36
36
    xmlXPathObjectPtr result;   /* returned by func:result */
37
37
    int error;                  /* did an error occur? */
 
38
    xmlDocPtr RVT;   /* result tree fragment */
38
39
};
39
40
 
40
41
typedef struct _exsltFuncResultPreComp exsltFuncResultPreComp;
56
57
                                       int nargs);
57
58
static exsltFuncFunctionData *exsltFuncNewFunctionData(void);
58
59
 
 
60
/*static const xmlChar *exsltResultDataID = (const xmlChar *) "EXSLT Result";*/
 
61
 
59
62
/**
60
63
 * exsltFuncRegisterFunc:
61
64
 * @func:  the #exsltFuncFunctionData for the function
274
277
    xmlXPathObjectPtr obj, oldResult, ret;
275
278
    exsltFuncData *data;
276
279
    exsltFuncFunctionData *func;
277
 
    xmlNodePtr paramNode, oldInsert, fake, content = NULL;
 
280
    xmlNodePtr paramNode, oldInsert, fake;
278
281
    int oldBase;
279
282
    xsltStackElemPtr params = NULL, param;
280
283
    xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
304
307
    }
305
308
    if (func->content != NULL) {
306
309
        paramNode = func->content->prev;
307
 
        content = func->content;
308
310
    }
309
311
    else
310
312
        paramNode = NULL;
314
316
                         "param == NULL\n");
315
317
        return;
316
318
    }
317
 
 
318
 
    /* set params */
 
319
    /*
 
320
    * Process xsl:param instructions which were not set by the
 
321
    * invoking function call.
 
322
    */
319
323
    for (i = func->nargs; (i > nargs) && (paramNode != NULL); i--) {
 
324
        /*
 
325
        * Those are the xsl:param instructions, which were not
 
326
        * set by the calling function.  
 
327
        */
 
328
        param = xsltParseStylesheetCallerParam (tctxt, paramNode);
 
329
        param->next = params;
 
330
        params = param;
320
331
        paramNode = paramNode->prev;
321
 
        if (content != NULL)
322
 
            content = content->prev;
323
332
    }
 
333
    /*
 
334
    * Process xsl:param instructions which are set by the
 
335
    * invoking function call.
 
336
    */
324
337
    while ((i-- > 0) && (paramNode != NULL)) {
325
338
        obj = valuePop(ctxt);
326
 
        /* FIXME: this is a bit hackish */
 
339
        /*
 
340
        * TODO: Using xsltParseStylesheetCallerParam() is actually
 
341
        * not correct, since we are processing an xsl:param; but
 
342
        * using xsltParseStylesheetParam() won't work, as it puts
 
343
        * the param on the varible stack and does not give access to
 
344
        * the created xsltStackElemPtr.
 
345
        * It's also not correct, as xsltParseStylesheetCallerParam()
 
346
        * will report error messages indicating an "xsl:with-param" and
 
347
        * not the actual "xsl:param".
 
348
        */
327
349
        param = xsltParseStylesheetCallerParam (tctxt, paramNode);
328
350
        param->computed = 1;
329
351
        if (param->value != NULL)
333
355
        params = param;
334
356
        paramNode = paramNode->prev;
335
357
    }
336
 
 
 
358
    
337
359
    /*
338
360
     * actual processing
339
361
     */
348
370
    oldBase = tctxt->varsBase;
349
371
    tctxt->varsBase = tctxt->varsNr;
350
372
    xsltApplyOneTemplate (tctxt, xmlXPathGetContextNode(ctxt),
351
 
                          content, NULL, params);
 
373
                          func->content, NULL, params);
352
374
    tctxt->insert = oldInsert;
353
375
    tctxt->varsBase = oldBase;  /* restore original scope */
354
376
    if (params != NULL)
355
 
        xsltFreeStackElemList(params);
 
377
        xsltFreeStackElemList(params);    
356
378
 
357
379
    if (data->error != 0)
358
 
        return;
 
380
        goto error;
359
381
 
360
 
    if (data->result != NULL)
 
382
    if (data->result != NULL) {
361
383
        ret = data->result;
362
 
    else
 
384
    } else
363
385
        ret = xmlXPathNewCString("");
364
386
 
365
387
    data->result = oldResult;
377
399
                         "executing a function\n",
378
400
                         ctxt->context->functionURI, ctxt->context->function);
379
401
        xmlFreeNode(fake);
380
 
        return;
 
402
        goto error;
381
403
    }
382
404
    xmlFreeNode(fake);
383
405
    valuePush(ctxt, ret);
 
406
 
 
407
error:
 
408
    /*
 
409
    * IMPORTANT: This enables previously tree fragments marked as
 
410
    * being results of a function, to be garbage-collected after
 
411
    * the calling process exits.
 
412
    */
 
413
    xsltExtensionInstructionResultFinalize(tctxt);
384
414
}
385
415
 
386
416
 
569
599
                     exsltFuncResultPreComp *comp) {
570
600
    exsltFuncData *data;
571
601
    xmlXPathObjectPtr ret;
572
 
    xmlNsPtr *oldNsList;
573
 
    int oldNsNr;
 
602
    
574
603
 
575
604
    /* It is an error if instantiating the content of the
576
605
     * func:function element results in the instantiation of more than
592
621
     * Processing
593
622
     */
594
623
    if (comp->select != NULL) {
 
624
        xmlNsPtr *oldXPNsList;
 
625
        int oldXPNsNr;
 
626
        xmlNodePtr oldXPContextNode;
595
627
        /* If the func:result element has a select attribute, then the
596
628
         * value of the attribute must be an expression and the
597
629
         * returned value is the object that results from evaluating
604
636
            data->error = 1;
605
637
            return;
606
638
        }
607
 
        oldNsList = ctxt->xpathCtxt->namespaces;
608
 
        oldNsNr = ctxt->xpathCtxt->nsNr;
 
639
        oldXPNsList = ctxt->xpathCtxt->namespaces;
 
640
        oldXPNsNr = ctxt->xpathCtxt->nsNr;
 
641
        oldXPContextNode = ctxt->xpathCtxt->node;
 
642
 
609
643
        ctxt->xpathCtxt->namespaces = comp->nsList;
610
644
        ctxt->xpathCtxt->nsNr = comp->nsNr;
 
645
 
611
646
        ret = xmlXPathCompiledEval(comp->select, ctxt->xpathCtxt);
612
 
        ctxt->xpathCtxt->nsNr = oldNsNr;
613
 
        ctxt->xpathCtxt->namespaces = oldNsList;
 
647
 
 
648
        ctxt->xpathCtxt->node = oldXPContextNode;
 
649
        ctxt->xpathCtxt->nsNr = oldXPNsNr;
 
650
        ctxt->xpathCtxt->namespaces = oldXPNsList;
 
651
 
614
652
        if (ret == NULL) {
615
653
            xsltGenericError(xsltGenericErrorContext,
616
654
                             "exsltFuncResultElem: ret == NULL\n");
617
655
            return;
618
656
        }
 
657
        /*
 
658
        * Mark it as a function result in order to avoid garbage
 
659
        * collecting of tree fragments before the function exits.
 
660
        */
 
661
        xsltExtensionInstructionResultRegister(ctxt, ret);
619
662
    } else if (inst->children != NULL) {
620
663
        /* If the func:result element does not have a select attribute
621
664
         * and has non-empty content (i.e. the func:result element has
632
675
            data->error = 1;
633
676
            return;
634
677
        }
635
 
        xsltRegisterTmpRVT(ctxt, container);
 
678
        xsltRegisterLocalRVT(ctxt, container);  
 
679
 
636
680
        oldInsert = ctxt->insert;
637
681
        ctxt->insert = (xmlNodePtr) container;
638
682
        xsltApplyOneTemplate (ctxt, ctxt->xpathCtxt->node,
646
690
            data->error = 1;
647
691
        } else {
648
692
            ret->boolval = 0; /* Freeing is not handled there anymore */
 
693
            /*
 
694
            * Mark it as a function result in order to avoid garbage
 
695
            * collecting of tree fragments before the function exits.
 
696
            */
 
697
            xsltExtensionInstructionResultRegister(ctxt, ret);
649
698
        }
650
699
    } else {
651
700
        /* If the func:result element has empty content and does not