ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

preproc.c
Go to the documentation of this file.
00001 /*
00002  * preproc.c: Preprocessing of style operations
00003  *
00004  * References:
00005  *   http://www.w3.org/TR/1999/REC-xslt-19991116
00006  *
00007  *   Michael Kay "XSLT Programmer's Reference" pp 637-643
00008  *   Writing Multiple Output Files
00009  *
00010  *   XSLT-1.1 Working Draft
00011  *   http://www.w3.org/TR/xslt11#multiple-output
00012  *
00013  * See Copyright for the status of this software.
00014  *
00015  * daniel@veillard.com
00016  */
00017 
00018 #define IN_LIBXSLT
00019 #include "libxslt.h"
00020 
00021 #include <string.h>
00022 
00023 #include <libxml/xmlmemory.h>
00024 #include <libxml/parser.h>
00025 #include <libxml/tree.h>
00026 #include <libxml/valid.h>
00027 #include <libxml/hash.h>
00028 #include <libxml/uri.h>
00029 #include <libxml/encoding.h>
00030 #include <libxml/xmlerror.h>
00031 #include "xslt.h"
00032 #include "xsltutils.h"
00033 #include "xsltInternals.h"
00034 #include "transform.h"
00035 #include "templates.h"
00036 #include "variables.h"
00037 #include "numbersInternals.h"
00038 #include "preproc.h"
00039 #include "extra.h"
00040 #include "imports.h"
00041 #include "extensions.h"
00042 
00043 #ifdef WITH_XSLT_DEBUG
00044 #define WITH_XSLT_DEBUG_PREPROC
00045 #endif
00046 
00047 const xmlChar *xsltExtMarker = (const xmlChar *) "Extension Element";
00048 
00049 /************************************************************************
00050  *                                  *
00051  *          Grammar checks                  *
00052  *                                  *
00053  ************************************************************************/
00054 
00055 #ifdef XSLT_REFACTORED
00056     /*
00057     * Grammar checks are now performed in xslt.c.
00058     */
00059 #else
00060 
00070 static int
00071 xsltCheckTopLevelElement(xsltStylesheetPtr style, xmlNodePtr inst, int err) {
00072     xmlNodePtr parent;
00073     if ((style == NULL) || (inst == NULL) || (inst->ns == NULL))
00074         return(-1);
00075     
00076     parent = inst->parent;
00077     if (parent == NULL) {
00078         if (err) {
00079         xsltTransformError(NULL, style, inst,
00080             "internal problem: element has no parent\n");
00081         style->errors++;
00082     }
00083     return(0);
00084     }
00085     if ((parent->ns == NULL) || (parent->type != XML_ELEMENT_NODE) ||
00086         ((parent->ns != inst->ns) &&
00087      (!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
00088     ((!xmlStrEqual(parent->name, BAD_CAST "stylesheet")) &&
00089      (!xmlStrEqual(parent->name, BAD_CAST "transform")))) {
00090     if (err) {
00091         xsltTransformError(NULL, style, inst,
00092             "element %s only allowed as child of stylesheet\n",
00093                    inst->name);
00094         style->errors++;
00095     }
00096     return(0);
00097     }
00098     return(1);
00099 }
00100 
00108 static void
00109 xsltCheckInstructionElement(xsltStylesheetPtr style, xmlNodePtr inst) {
00110     xmlNodePtr parent;
00111     int has_ext;
00112 
00113     if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
00114         (style->literal_result))
00115         return;
00116 
00117     has_ext = (style->extInfos != NULL);
00118     
00119     parent = inst->parent;
00120     if (parent == NULL) {
00121     xsltTransformError(NULL, style, inst,
00122         "internal problem: element has no parent\n");
00123     style->errors++;
00124     return;
00125     }
00126     while ((parent != NULL) && (parent->type != XML_DOCUMENT_NODE)) {
00127         if (((parent->ns == inst->ns) ||
00128          ((parent->ns != NULL) &&
00129           (xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
00130         ((xmlStrEqual(parent->name, BAD_CAST "template")) ||
00131          (xmlStrEqual(parent->name, BAD_CAST "param")) ||
00132          (xmlStrEqual(parent->name, BAD_CAST "attribute")) ||
00133          (xmlStrEqual(parent->name, BAD_CAST "variable")))) {
00134         return;
00135     }
00136 
00137     /*
00138      * if we are within an extension element all bets are off
00139      * about the semantic there e.g. xsl:param within func:function
00140      */
00141     if ((has_ext) && (parent->ns != NULL) &&
00142         (xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
00143         return;
00144     
00145         parent = parent->parent;
00146     }
00147     xsltTransformError(NULL, style, inst,
00148         "element %s only allowed within a template, variable or param\n",
00149                    inst->name);
00150     style->errors++;
00151 }
00152 
00163 static void
00164 xsltCheckParentElement(xsltStylesheetPtr style, xmlNodePtr inst,
00165                        const xmlChar *allow1, const xmlChar *allow2) {
00166     xmlNodePtr parent;
00167 
00168     if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
00169         (style->literal_result))
00170         return;
00171 
00172     parent = inst->parent;
00173     if (parent == NULL) {
00174     xsltTransformError(NULL, style, inst,
00175         "internal problem: element has no parent\n");
00176     style->errors++;
00177     return;
00178     }
00179     if (((parent->ns == inst->ns) ||
00180      ((parent->ns != NULL) &&
00181       (xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
00182     ((xmlStrEqual(parent->name, allow1)) ||
00183      (xmlStrEqual(parent->name, allow2)))) {
00184     return;
00185     }
00186 
00187     if (style->extInfos != NULL) {
00188     while ((parent != NULL) && (parent->type != XML_DOCUMENT_NODE)) {
00189         /*
00190          * if we are within an extension element all bets are off
00191          * about the semantic there e.g. xsl:param within func:function
00192          */
00193         if ((parent->ns != NULL) &&
00194         (xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
00195         return;
00196         
00197         parent = parent->parent;
00198     }
00199     }
00200     xsltTransformError(NULL, style, inst,
00201                "element %s is not allowed within that context\n",
00202                inst->name);
00203     style->errors++;
00204 }
00205 #endif
00206 
00207 /************************************************************************
00208  *                                  *
00209  *          handling of precomputed data            *
00210  *                                  *
00211  ************************************************************************/
00212 
00223 static xsltStylePreCompPtr
00224 xsltNewStylePreComp(xsltStylesheetPtr style, xsltStyleType type) {
00225     xsltStylePreCompPtr cur;
00226 #ifdef XSLT_REFACTORED
00227     size_t size;
00228 #endif
00229 
00230     if (style == NULL)
00231         return(NULL);
00232    
00233 #ifdef XSLT_REFACTORED
00234     /*
00235     * URGENT TODO: Use specialized factory functions in order
00236     *   to avoid this ugliness.
00237     */
00238     switch (type) {
00239         case XSLT_FUNC_COPY:
00240             size = sizeof(xsltStyleItemCopy); break;
00241         case XSLT_FUNC_SORT:
00242             size = sizeof(xsltStyleItemSort); break;
00243         case XSLT_FUNC_TEXT:
00244             size = sizeof(xsltStyleItemText); break;
00245         case XSLT_FUNC_ELEMENT:
00246             size = sizeof(xsltStyleItemElement); break;
00247         case XSLT_FUNC_ATTRIBUTE:
00248             size = sizeof(xsltStyleItemAttribute); break;
00249         case XSLT_FUNC_COMMENT:
00250             size = sizeof(xsltStyleItemComment); break;
00251         case XSLT_FUNC_PI:
00252             size = sizeof(xsltStyleItemPI); break;
00253         case XSLT_FUNC_COPYOF:
00254             size = sizeof(xsltStyleItemCopyOf); break;
00255         case XSLT_FUNC_VALUEOF:
00256             size = sizeof(xsltStyleItemValueOf); break;;
00257         case XSLT_FUNC_NUMBER:
00258             size = sizeof(xsltStyleItemNumber); break;
00259         case XSLT_FUNC_APPLYIMPORTS:
00260             size = sizeof(xsltStyleItemApplyImports); break;
00261         case XSLT_FUNC_CALLTEMPLATE:
00262             size = sizeof(xsltStyleItemCallTemplate); break;
00263         case XSLT_FUNC_APPLYTEMPLATES:
00264             size = sizeof(xsltStyleItemApplyTemplates); break;
00265         case XSLT_FUNC_CHOOSE:
00266             size = sizeof(xsltStyleItemChoose); break;
00267         case XSLT_FUNC_IF:
00268             size = sizeof(xsltStyleItemIf); break;
00269         case XSLT_FUNC_FOREACH:
00270             size = sizeof(xsltStyleItemForEach); break;
00271         case XSLT_FUNC_DOCUMENT:
00272             size = sizeof(xsltStyleItemDocument); break;
00273     case XSLT_FUNC_WITHPARAM:
00274         size = sizeof(xsltStyleItemWithParam); break;
00275     case XSLT_FUNC_PARAM:
00276         size = sizeof(xsltStyleItemParam); break;
00277     case XSLT_FUNC_VARIABLE:
00278         size = sizeof(xsltStyleItemVariable); break;
00279     case XSLT_FUNC_WHEN:
00280         size = sizeof(xsltStyleItemWhen); break;
00281     case XSLT_FUNC_OTHERWISE:
00282         size = sizeof(xsltStyleItemOtherwise); break;
00283     default:    
00284         xsltTransformError(NULL, style, NULL,
00285             "xsltNewStylePreComp : invalid type %d\n", type);
00286         style->errors++;
00287         return(NULL);
00288     }
00289     /*
00290     * Create the structure.
00291     */
00292     cur = (xsltStylePreCompPtr) xmlMalloc(size);
00293     if (cur == NULL) {
00294     xsltTransformError(NULL, style, NULL,
00295         "xsltNewStylePreComp : malloc failed\n");
00296     style->errors++;
00297     return(NULL);
00298     }
00299     memset(cur, 0, size);
00300 
00301 #else /* XSLT_REFACTORED */
00302     /*
00303     * Old behaviour.
00304     */
00305     cur = (xsltStylePreCompPtr) xmlMalloc(sizeof(xsltStylePreComp));
00306     if (cur == NULL) {
00307     xsltTransformError(NULL, style, NULL,
00308         "xsltNewStylePreComp : malloc failed\n");
00309     style->errors++;
00310     return(NULL);
00311     }
00312     memset(cur, 0, sizeof(xsltStylePreComp));
00313 #endif /* XSLT_REFACTORED */
00314 
00315     /*
00316     * URGENT TODO: Better to move this to spezialized factory functions.
00317     */
00318     cur->type = type;
00319     switch (cur->type) {
00320         case XSLT_FUNC_COPY:
00321             cur->func = (xsltTransformFunction) xsltCopy;break;
00322         case XSLT_FUNC_SORT:
00323             cur->func = (xsltTransformFunction) xsltSort;break;
00324         case XSLT_FUNC_TEXT:
00325             cur->func = (xsltTransformFunction) xsltText;break;
00326         case XSLT_FUNC_ELEMENT:
00327             cur->func = (xsltTransformFunction) xsltElement;break;
00328         case XSLT_FUNC_ATTRIBUTE:
00329             cur->func = (xsltTransformFunction) xsltAttribute;break;
00330         case XSLT_FUNC_COMMENT:
00331             cur->func = (xsltTransformFunction) xsltComment;break;
00332         case XSLT_FUNC_PI:
00333             cur->func = (xsltTransformFunction) xsltProcessingInstruction;
00334         break;
00335         case XSLT_FUNC_COPYOF:
00336             cur->func = (xsltTransformFunction) xsltCopyOf;break;
00337         case XSLT_FUNC_VALUEOF:
00338             cur->func = (xsltTransformFunction) xsltValueOf;break;
00339         case XSLT_FUNC_NUMBER:
00340             cur->func = (xsltTransformFunction) xsltNumber;break;
00341         case XSLT_FUNC_APPLYIMPORTS:
00342             cur->func = (xsltTransformFunction) xsltApplyImports;break;
00343         case XSLT_FUNC_CALLTEMPLATE:
00344             cur->func = (xsltTransformFunction) xsltCallTemplate;break;
00345         case XSLT_FUNC_APPLYTEMPLATES:
00346             cur->func = (xsltTransformFunction) xsltApplyTemplates;break;
00347         case XSLT_FUNC_CHOOSE:
00348             cur->func = (xsltTransformFunction) xsltChoose;break;
00349         case XSLT_FUNC_IF:
00350             cur->func = (xsltTransformFunction) xsltIf;break;
00351         case XSLT_FUNC_FOREACH:
00352             cur->func = (xsltTransformFunction) xsltForEach;break;
00353         case XSLT_FUNC_DOCUMENT:
00354             cur->func = (xsltTransformFunction) xsltDocumentElem;break;
00355     case XSLT_FUNC_WITHPARAM:
00356     case XSLT_FUNC_PARAM:       
00357     case XSLT_FUNC_VARIABLE:        
00358     case XSLT_FUNC_WHEN:
00359         break;
00360     default:
00361     if (cur->func == NULL) {
00362         xsltTransformError(NULL, style, NULL,
00363             "xsltNewStylePreComp : no function for type %d\n", type);
00364         style->errors++;
00365     }
00366     }
00367     cur->next = style->preComps;
00368     style->preComps = (xsltElemPreCompPtr) cur;
00369 
00370     return(cur);
00371 }
00372 
00379 static void
00380 xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
00381     if (comp == NULL)
00382     return;
00383 #ifdef XSLT_REFACTORED
00384     /*
00385     * URGENT TODO: Implement destructors.
00386     */
00387     switch (comp->type) {
00388     case XSLT_FUNC_LITERAL_RESULT_ELEMENT:
00389         break;
00390     case XSLT_FUNC_COPY:
00391             break;
00392         case XSLT_FUNC_SORT: {
00393         xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp;
00394         if (item->locale != (xsltLocale)0)
00395             xsltFreeLocale(item->locale);
00396         if (item->comp != NULL)
00397             xmlXPathFreeCompExpr(item->comp);
00398         }
00399             break;
00400         case XSLT_FUNC_TEXT:
00401             break;
00402         case XSLT_FUNC_ELEMENT:
00403             break;
00404         case XSLT_FUNC_ATTRIBUTE:
00405             break;
00406         case XSLT_FUNC_COMMENT:
00407             break;
00408         case XSLT_FUNC_PI:
00409         break;
00410         case XSLT_FUNC_COPYOF: {
00411         xsltStyleItemCopyOfPtr item = (xsltStyleItemCopyOfPtr) comp;
00412         if (item->comp != NULL)
00413             xmlXPathFreeCompExpr(item->comp);
00414         }
00415             break;
00416         case XSLT_FUNC_VALUEOF: {
00417         xsltStyleItemValueOfPtr item = (xsltStyleItemValueOfPtr) comp;
00418         if (item->comp != NULL)
00419             xmlXPathFreeCompExpr(item->comp);
00420         }
00421             break;
00422         case XSLT_FUNC_NUMBER:
00423             break;
00424         case XSLT_FUNC_APPLYIMPORTS:
00425             break;
00426         case XSLT_FUNC_CALLTEMPLATE:
00427             break;
00428         case XSLT_FUNC_APPLYTEMPLATES: {
00429         xsltStyleItemApplyTemplatesPtr item =
00430             (xsltStyleItemApplyTemplatesPtr) comp;
00431         if (item->comp != NULL)
00432             xmlXPathFreeCompExpr(item->comp);
00433         }
00434             break;
00435         case XSLT_FUNC_CHOOSE:
00436             break;
00437         case XSLT_FUNC_IF: {
00438         xsltStyleItemIfPtr item = (xsltStyleItemIfPtr) comp;
00439         if (item->comp != NULL)
00440             xmlXPathFreeCompExpr(item->comp);
00441         }
00442             break;
00443         case XSLT_FUNC_FOREACH: {
00444         xsltStyleItemForEachPtr item =
00445             (xsltStyleItemForEachPtr) comp;
00446         if (item->comp != NULL)
00447             xmlXPathFreeCompExpr(item->comp);
00448         }
00449             break;
00450         case XSLT_FUNC_DOCUMENT:
00451             break;
00452     case XSLT_FUNC_WITHPARAM: {
00453         xsltStyleItemWithParamPtr item =
00454             (xsltStyleItemWithParamPtr) comp;
00455         if (item->comp != NULL)
00456             xmlXPathFreeCompExpr(item->comp);
00457         }
00458         break;
00459     case XSLT_FUNC_PARAM: {
00460         xsltStyleItemParamPtr item =
00461             (xsltStyleItemParamPtr) comp;
00462         if (item->comp != NULL)
00463             xmlXPathFreeCompExpr(item->comp);
00464         }
00465         break;
00466     case XSLT_FUNC_VARIABLE: {
00467         xsltStyleItemVariablePtr item =
00468             (xsltStyleItemVariablePtr) comp;
00469         if (item->comp != NULL)
00470             xmlXPathFreeCompExpr(item->comp);
00471         }
00472         break;
00473     case XSLT_FUNC_WHEN: {
00474         xsltStyleItemWhenPtr item =
00475             (xsltStyleItemWhenPtr) comp;
00476         if (item->comp != NULL)
00477             xmlXPathFreeCompExpr(item->comp);
00478         }
00479         break;
00480     case XSLT_FUNC_OTHERWISE:       
00481     case XSLT_FUNC_FALLBACK:
00482     case XSLT_FUNC_MESSAGE:
00483     case XSLT_FUNC_INCLUDE:
00484     case XSLT_FUNC_ATTRSET:
00485     
00486         break;
00487     default:
00488         /* TODO: Raise error. */
00489         break;
00490     }
00491 #else    
00492     if (comp->locale != (xsltLocale)0)
00493     xsltFreeLocale(comp->locale);
00494     if (comp->comp != NULL)
00495     xmlXPathFreeCompExpr(comp->comp);
00496     if (comp->nsList != NULL)
00497     xmlFree(comp->nsList);
00498 #endif
00499 
00500     xmlFree(comp);
00501 }
00502 
00503 
00504 /************************************************************************
00505  *                                  *
00506  *          XSLT-1.1 extensions                 *
00507  *                                  *
00508  ************************************************************************/
00509 
00520 xsltElemPreCompPtr
00521 xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst,
00522          xsltTransformFunction function ATTRIBUTE_UNUSED) {
00523 #ifdef XSLT_REFACTORED
00524     xsltStyleItemDocumentPtr comp;
00525 #else
00526     xsltStylePreCompPtr comp;
00527 #endif
00528     const xmlChar *filename = NULL;
00529 
00530     /*
00531     * As of 2006-03-30, this function is currently defined in Libxslt
00532     * to be used for:
00533     * (in libxslt/extra.c)
00534     * "output" in XSLT_SAXON_NAMESPACE
00535     * "write" XSLT_XALAN_NAMESPACE
00536     * "document" XSLT_XT_NAMESPACE
00537     * "document" XSLT_NAMESPACE (from the abandoned old working
00538     *                            draft of XSLT 1.1)
00539     * (in libexslt/common.c)
00540     * "document" in EXSLT_COMMON_NAMESPACE
00541     */
00542 #ifdef XSLT_REFACTORED
00543     comp = (xsltStyleItemDocumentPtr)
00544     xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
00545 #else
00546     comp = xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
00547 #endif
00548     
00549     if (comp == NULL)
00550     return (NULL);
00551     comp->inst = inst;
00552     comp->ver11 = 0;
00553 
00554     if (xmlStrEqual(inst->name, (const xmlChar *) "output")) {
00555 #ifdef WITH_XSLT_DEBUG_EXTRA
00556     xsltGenericDebug(xsltGenericDebugContext,
00557         "Found saxon:output extension\n");
00558 #endif
00559     /*
00560     * The element "output" is in the namespace XSLT_SAXON_NAMESPACE
00561     *   (http://icl.com/saxon)
00562     * The @file is in no namespace; it is an AVT.
00563     *   (http://www.computerwizards.com/saxon/doc/extensions.html#saxon:output)
00564     *
00565     * TODO: Do we need not to check the namespace here?
00566     */
00567     filename = xsltEvalStaticAttrValueTemplate(style, inst,
00568              (const xmlChar *)"file",
00569              NULL, &comp->has_filename);
00570     } else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) {
00571 #ifdef WITH_XSLT_DEBUG_EXTRA
00572     xsltGenericDebug(xsltGenericDebugContext,
00573         "Found xalan:write extension\n");
00574 #endif
00575     /* the filename need to be interpreted */
00576     /*
00577     * TODO: Is "filename need to be interpreted" meant to be a todo?
00578     *   Where will be the filename of xalan:write be processed?
00579     *
00580     * TODO: Do we need not to check the namespace here?
00581     *   The extension ns is "http://xml.apache.org/xalan/redirect".
00582     *   See http://xml.apache.org/xalan-j/extensionslib.html.
00583     */
00584     } else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
00585     if (inst->ns != NULL) {
00586         if (xmlStrEqual(inst->ns->href, XSLT_NAMESPACE)) {
00587         /*
00588         * Mark the instruction as being of
00589         * XSLT version 1.1 (abandoned).
00590         */
00591         comp->ver11 = 1;
00592 #ifdef WITH_XSLT_DEBUG_EXTRA
00593         xsltGenericDebug(xsltGenericDebugContext,
00594             "Found xslt11:document construct\n");
00595 #endif              
00596         } else {        
00597         if (xmlStrEqual(inst->ns->href,
00598             (const xmlChar *)"http://exslt.org/common")) {
00599             /* EXSLT. */
00600 #ifdef WITH_XSLT_DEBUG_EXTRA
00601             xsltGenericDebug(xsltGenericDebugContext,
00602             "Found exslt:document extension\n");
00603 #endif
00604         } else if (xmlStrEqual(inst->ns->href, XSLT_XT_NAMESPACE)) {
00605             /* James Clark's XT. */
00606 #ifdef WITH_XSLT_DEBUG_EXTRA
00607             xsltGenericDebug(xsltGenericDebugContext,
00608             "Found xt:document extension\n");
00609 #endif
00610         }
00611         }
00612     }
00613     /*
00614     * The element "document" is used in conjunction with the
00615     * following namespaces:
00616     *
00617     * 1) XSLT_NAMESPACE (http://www.w3.org/1999/XSL/Transform version 1.1)
00618     *    <!ELEMENT xsl:document %template;>
00619     *    <!ATTLIST xsl:document
00620     *       href %avt; #REQUIRED
00621     *    @href is an AVT
00622     *    IMPORTANT: xsl:document was in the abandoned XSLT 1.1 draft,
00623     *    it was removed and isn't available in XSLT 1.1 anymore.
00624     *    In XSLT 2.0 it was renamed to xsl:result-document.
00625     *
00626     *   All other attributes are identical to the attributes
00627     *   on xsl:output
00628     *
00629     * 2) EXSLT_COMMON_NAMESPACE (http://exslt.org/common)
00630     *    <exsl:document
00631     *       href = { uri-reference }
00632     *    TODO: is @href is an AVT?
00633     *
00634     * 3) XSLT_XT_NAMESPACE (http://www.jclark.com/xt)
00635     *     Example: <xt:document method="xml" href="myFile.xml">
00636     *    TODO: is @href is an AVT?
00637     *       
00638     * In all cases @href is in no namespace.
00639     */
00640     filename = xsltEvalStaticAttrValueTemplate(style, inst,
00641         (const xmlChar *)"href", NULL, &comp->has_filename);
00642     }       
00643     if (!comp->has_filename) {
00644     goto error;
00645     }
00646     comp->filename = filename;
00647 
00648 error:
00649     return ((xsltElemPreCompPtr) comp);
00650 }
00651 
00652 /************************************************************************
00653  *                                  *
00654  *      Most of the XSLT-1.0 transformations            *
00655  *                                  *
00656  ************************************************************************/
00657 
00665 static void
00666 xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
00667 #ifdef XSLT_REFACTORED
00668     xsltStyleItemSortPtr comp;
00669 #else
00670     xsltStylePreCompPtr comp;
00671 #endif
00672     if ((style == NULL) || (inst == NULL))
00673     return;
00674 
00675 #ifdef XSLT_REFACTORED
00676     comp = (xsltStyleItemSortPtr) xsltNewStylePreComp(style, XSLT_FUNC_SORT);
00677 #else
00678     comp = xsltNewStylePreComp(style, XSLT_FUNC_SORT);
00679 #endif
00680     
00681     if (comp == NULL)
00682     return;
00683     inst->psvi = comp;
00684     comp->inst = inst;
00685 
00686     comp->stype = xsltEvalStaticAttrValueTemplate(style, inst,
00687              (const xmlChar *)"data-type",
00688              NULL, &comp->has_stype);
00689     if (comp->stype != NULL) {
00690     if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
00691         comp->number = 0;
00692     else if (xmlStrEqual(comp->stype, (const xmlChar *) "number"))
00693         comp->number = 1;
00694     else {
00695         xsltTransformError(NULL, style, inst,
00696          "xsltSortComp: no support for data-type = %s\n", comp->stype);
00697         comp->number = 0; /* use default */
00698         if (style != NULL) style->warnings++;
00699     }
00700     }
00701     comp->order = xsltEvalStaticAttrValueTemplate(style, inst,
00702                   (const xmlChar *)"order",
00703                   NULL, &comp->has_order);
00704     if (comp->order != NULL) {
00705     if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
00706         comp->descending = 0;
00707     else if (xmlStrEqual(comp->order, (const xmlChar *) "descending"))
00708         comp->descending = 1;
00709     else {
00710         xsltTransformError(NULL, style, inst,
00711          "xsltSortComp: invalid value %s for order\n", comp->order);
00712         comp->descending = 0; /* use default */
00713         if (style != NULL) style->warnings++;
00714     }
00715     }
00716     comp->case_order = xsltEvalStaticAttrValueTemplate(style, inst,
00717                   (const xmlChar *)"case-order",
00718                   NULL, &comp->has_use);
00719     if (comp->case_order != NULL) {
00720     if (xmlStrEqual(comp->case_order, (const xmlChar *) "upper-first"))
00721         comp->lower_first = 0;
00722     else if (xmlStrEqual(comp->case_order, (const xmlChar *) "lower-first"))
00723         comp->lower_first = 1;
00724     else {
00725         xsltTransformError(NULL, style, inst,
00726          "xsltSortComp: invalid value %s for order\n", comp->order);
00727         comp->lower_first = 0; /* use default */
00728         if (style != NULL) style->warnings++;
00729     }
00730     }
00731 
00732     comp->lang = xsltEvalStaticAttrValueTemplate(style, inst,
00733                  (const xmlChar *)"lang",
00734                  NULL, &comp->has_lang);
00735     if (comp->lang != NULL) {
00736     comp->locale = xsltNewLocale(comp->lang);
00737     }
00738     else {
00739         comp->locale = (xsltLocale)0;
00740     }
00741 
00742     comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE);
00743     if (comp->select == NULL) {
00744     /*
00745      * The default value of the select attribute is ., which will
00746      * cause the string-value of the current node to be used as
00747      * the sort key.
00748      */
00749     comp->select = xmlDictLookup(style->dict, BAD_CAST ".", 1);
00750     }
00751     comp->comp = xsltXPathCompile(style, comp->select);
00752     if (comp->comp == NULL) {
00753     xsltTransformError(NULL, style, inst,
00754          "xsltSortComp: could not compile select expression '%s'\n",
00755                      comp->select);
00756     if (style != NULL) style->errors++;
00757     }
00758     if (inst->children != NULL) {
00759     xsltTransformError(NULL, style, inst,
00760     "xsl:sort : is not empty\n");
00761     if (style != NULL) style->errors++;
00762     }
00763 }
00764 
00772 static void
00773 xsltCopyComp(xsltStylesheetPtr style, xmlNodePtr inst) {
00774 #ifdef XSLT_REFACTORED
00775     xsltStyleItemCopyPtr comp;
00776 #else
00777     xsltStylePreCompPtr comp;
00778 #endif
00779 
00780     if ((style == NULL) || (inst == NULL))
00781     return;
00782 #ifdef XSLT_REFACTORED
00783     comp = (xsltStyleItemCopyPtr) xsltNewStylePreComp(style, XSLT_FUNC_COPY);
00784 #else
00785     comp = xsltNewStylePreComp(style, XSLT_FUNC_COPY);
00786 #endif
00787     
00788     if (comp == NULL)
00789     return;
00790     inst->psvi = comp;
00791     comp->inst = inst;
00792 
00793 
00794     comp->use = xsltGetCNsProp(style, inst, (const xmlChar *)"use-attribute-sets",
00795                     XSLT_NAMESPACE);
00796     if (comp->use == NULL)
00797     comp->has_use = 0;
00798     else
00799     comp->has_use = 1;
00800 }
00801 
00802 #ifdef XSLT_REFACTORED
00803     /* Enable if ever needed for xsl:text. */
00804 #else
00805 
00815 static void
00816 xsltTextComp(xsltStylesheetPtr style, xmlNodePtr inst) {
00817 #ifdef XSLT_REFACTORED
00818     xsltStyleItemTextPtr comp;
00819 #else
00820     xsltStylePreCompPtr comp;
00821 #endif
00822     const xmlChar *prop;
00823 
00824     if ((style == NULL) || (inst == NULL))
00825     return;
00826 
00827 #ifdef XSLT_REFACTORED
00828     comp = (xsltStyleItemTextPtr) xsltNewStylePreComp(style, XSLT_FUNC_TEXT);
00829 #else
00830     comp = xsltNewStylePreComp(style, XSLT_FUNC_TEXT);
00831 #endif    
00832     if (comp == NULL)
00833     return;
00834     inst->psvi = comp;
00835     comp->inst = inst;
00836     comp->noescape = 0;
00837 
00838     prop = xsltGetCNsProp(style, inst,
00839         (const xmlChar *)"disable-output-escaping",
00840             XSLT_NAMESPACE);
00841     if (prop != NULL) {
00842     if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
00843         comp->noescape = 1;
00844     } else if (!xmlStrEqual(prop,
00845         (const xmlChar *)"no")){
00846         xsltTransformError(NULL, style, inst,
00847         "xsl:text: disable-output-escaping allows only yes or no\n");
00848         if (style != NULL) style->warnings++;
00849     }
00850     }
00851 }
00852 #endif /* else of XSLT_REFACTORED */
00853 
00861 static void
00862 xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
00863 #ifdef XSLT_REFACTORED
00864     xsltStyleItemElementPtr comp;
00865 #else
00866     xsltStylePreCompPtr comp;
00867 #endif
00868 
00869     /*
00870     * <xsl:element
00871     *   name = { qname }
00872     *   namespace = { uri-reference }
00873     *   use-attribute-sets = qnames>
00874     *   <!-- Content: template -->
00875     * </xsl:element>
00876     */
00877     if ((style == NULL) || (inst == NULL))
00878     return;
00879 
00880 #ifdef XSLT_REFACTORED
00881     comp = (xsltStyleItemElementPtr) xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
00882 #else
00883     comp = xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
00884 #endif
00885 
00886     if (comp == NULL)
00887     return;
00888     inst->psvi = comp;
00889     comp->inst = inst;
00890 
00891     /*
00892     * Attribute "name".
00893     */
00894     /*
00895     * TODO: Precompile the AVT. See bug #344894.
00896     */
00897     comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
00898     (const xmlChar *)"name", NULL, &comp->has_name);
00899     if (! comp->has_name) {
00900     xsltTransformError(NULL, style, inst,
00901         "xsl:element: The attribute 'name' is missing.\n");
00902     style->errors++;
00903     goto error;
00904     }
00905     /*
00906     * Attribute "namespace".
00907     */
00908     /*
00909     * TODO: Precompile the AVT. See bug #344894.
00910     */
00911     comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
00912     (const xmlChar *)"namespace", NULL, &comp->has_ns);
00913     
00914     if (comp->name != NULL) {   
00915     if (xmlValidateQName(comp->name, 0)) {
00916         xsltTransformError(NULL, style, inst,
00917         "xsl:element: The value '%s' of the attribute 'name' is "
00918         "not a valid QName.\n", comp->name);
00919         style->errors++;
00920     } else {
00921         const xmlChar *prefix = NULL, *name;
00922 
00923         name = xsltSplitQName(style->dict, comp->name, &prefix);
00924         if (comp->has_ns == 0) {        
00925         xmlNsPtr ns;
00926 
00927         /*
00928         * SPEC XSLT 1.0:
00929         *  "If the namespace attribute is not present, then the QName is
00930         *  expanded into an expanded-name using the namespace declarations
00931         *  in effect for the xsl:element element, including any default
00932         *  namespace declaration.
00933         */      
00934         ns = xmlSearchNs(inst->doc, inst, prefix);
00935         if (ns != NULL) {
00936             comp->ns = xmlDictLookup(style->dict, ns->href, -1);
00937             comp->has_ns = 1;
00938 #ifdef XSLT_REFACTORED
00939             comp->nsPrefix = prefix;
00940             comp->name = name;
00941 #endif
00942         } else if (prefix != NULL) {
00943             xsltTransformError(NULL, style, inst,
00944             "xsl:element: The prefixed QName '%s' "
00945             "has no namespace binding in scope in the "
00946             "stylesheet; this is an error, since the namespace was "
00947             "not specified by the instruction itself.\n", comp->name);
00948             style->errors++;
00949         }
00950         }       
00951         if ((prefix != NULL) &&
00952         (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)))
00953         {
00954         /*
00955         * Mark is to be skipped.
00956         */
00957         comp->has_name = 0;     
00958         }
00959     }
00960     }    
00961     /*
00962     * Attribute "use-attribute-sets",
00963     */
00964     comp->use = xsltEvalStaticAttrValueTemplate(style, inst,
00965                (const xmlChar *)"use-attribute-sets",
00966                NULL, &comp->has_use);
00967 
00968 error:    
00969     return;
00970 }
00971 
00979 static void
00980 xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
00981 #ifdef XSLT_REFACTORED
00982     xsltStyleItemAttributePtr comp;
00983 #else
00984     xsltStylePreCompPtr comp;
00985 #endif
00986 
00987     /*
00988     * <xsl:attribute
00989     *   name = { qname }
00990     *   namespace = { uri-reference }>
00991     *   <!-- Content: template -->
00992     * </xsl:attribute>
00993     */
00994     if ((style == NULL) || (inst == NULL))
00995     return;
00996 
00997 #ifdef XSLT_REFACTORED
00998     comp = (xsltStyleItemAttributePtr) xsltNewStylePreComp(style,
00999     XSLT_FUNC_ATTRIBUTE);
01000 #else
01001     comp = xsltNewStylePreComp(style, XSLT_FUNC_ATTRIBUTE);
01002 #endif
01003     
01004     if (comp == NULL)
01005     return;
01006     inst->psvi = comp;
01007     comp->inst = inst;
01008 
01009     /*
01010     * Attribute "name".
01011     */
01012     /*
01013     * TODO: Precompile the AVT. See bug #344894.
01014     */
01015     comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
01016                  (const xmlChar *)"name",
01017                  NULL, &comp->has_name);
01018     if (! comp->has_name) {
01019     xsltTransformError(NULL, style, inst,
01020         "XSLT-attribute: The attribute 'name' is missing.\n");
01021     style->errors++;
01022     return;
01023     }    
01024     /*
01025     * Attribute "namespace".
01026     */
01027     /*
01028     * TODO: Precompile the AVT. See bug #344894.
01029     */
01030     comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
01031     (const xmlChar *)"namespace",
01032     NULL, &comp->has_ns);
01033 
01034     if (comp->name != NULL) {
01035     if (xmlValidateQName(comp->name, 0)) {
01036         xsltTransformError(NULL, style, inst,
01037         "xsl:attribute: The value '%s' of the attribute 'name' is "
01038         "not a valid QName.\n", comp->name);
01039         style->errors++;
01040     } else {
01041         const xmlChar *prefix = NULL, *name;
01042 
01043         name = xsltSplitQName(style->dict, comp->name, &prefix);
01044         if (prefix != NULL) {
01045         if (comp->has_ns == 0) {
01046             xmlNsPtr ns;
01047 
01048             /*
01049             * SPEC XSLT 1.0:
01050             *  "If the namespace attribute is not present, then the
01051             *  QName is expanded into an expanded-name using the
01052             *  namespace declarations in effect for the xsl:element
01053             *  element, including any default namespace declaration.
01054             */              
01055             ns = xmlSearchNs(inst->doc, inst, prefix);
01056             if (ns != NULL) {
01057             comp->ns = xmlDictLookup(style->dict, ns->href, -1);
01058             comp->has_ns = 1;
01059 #ifdef XSLT_REFACTORED
01060             comp->nsPrefix = prefix;
01061             comp->name = name;
01062 #endif
01063             } else {
01064             xsltTransformError(NULL, style, inst,
01065                 "xsl:attribute: The prefixed QName '%s' "
01066                 "has no namespace binding in scope in the "
01067                 "stylesheet; this is an error, since the "
01068                 "namespace was not specified by the instruction "
01069                 "itself.\n", comp->name);
01070             style->errors++;
01071             }
01072         }
01073         if (!xmlStrncasecmp(prefix, (xmlChar *) "xmlns", 5)) {
01074             /*
01075             * SPEC XSLT 1.0:
01076             *  "It is an error if the string that results from
01077             *  instantiating the attribute value template is not a
01078             *  QName or is the string xmlns. An XSLT processor may
01079             *  signal the error; if it does not signal the error,
01080             *  it must recover by not adding the attribute to the
01081             *  result tree."
01082             *
01083             * Reject a prefix of "xmlns". Mark to be skipped.
01084             */
01085             comp->has_name = 0;
01086             
01087 #ifdef WITH_XSLT_DEBUG_PARSING
01088             xsltGenericDebug(xsltGenericDebugContext,
01089             "xsltAttribute: xmlns prefix forbidden\n");
01090 #endif          
01091             return;
01092         }
01093         
01094         }
01095     }   
01096     }
01097 }
01098 
01106 static void
01107 xsltCommentComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01108 #ifdef XSLT_REFACTORED
01109     xsltStyleItemCommentPtr comp;
01110 #else
01111     xsltStylePreCompPtr comp;
01112 #endif
01113 
01114     if ((style == NULL) || (inst == NULL))
01115     return;
01116 
01117 #ifdef XSLT_REFACTORED
01118     comp = (xsltStyleItemCommentPtr) xsltNewStylePreComp(style, XSLT_FUNC_COMMENT);
01119 #else
01120     comp = xsltNewStylePreComp(style, XSLT_FUNC_COMMENT);
01121 #endif
01122 
01123     if (comp == NULL)
01124     return;
01125     inst->psvi = comp;
01126     comp->inst = inst;
01127 }
01128 
01136 static void
01137 xsltProcessingInstructionComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01138 #ifdef XSLT_REFACTORED
01139     xsltStyleItemPIPtr comp;
01140 #else
01141     xsltStylePreCompPtr comp;
01142 #endif
01143 
01144     if ((style == NULL) || (inst == NULL))
01145     return;
01146 
01147 #ifdef XSLT_REFACTORED
01148     comp = (xsltStyleItemPIPtr) xsltNewStylePreComp(style, XSLT_FUNC_PI);
01149 #else
01150     comp = xsltNewStylePreComp(style, XSLT_FUNC_PI);
01151 #endif
01152 
01153     if (comp == NULL)
01154     return;
01155     inst->psvi = comp;
01156     comp->inst = inst;
01157 
01158     comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
01159                  (const xmlChar *)"name",
01160                  XSLT_NAMESPACE, &comp->has_name);
01161 }
01162 
01170 static void
01171 xsltCopyOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01172 #ifdef XSLT_REFACTORED
01173     xsltStyleItemCopyOfPtr comp;
01174 #else
01175     xsltStylePreCompPtr comp;
01176 #endif
01177 
01178     if ((style == NULL) || (inst == NULL))
01179     return;
01180 
01181 #ifdef XSLT_REFACTORED
01182     comp = (xsltStyleItemCopyOfPtr) xsltNewStylePreComp(style, XSLT_FUNC_COPYOF);
01183 #else
01184     comp = xsltNewStylePreComp(style, XSLT_FUNC_COPYOF);
01185 #endif
01186 
01187     if (comp == NULL)
01188     return;
01189     inst->psvi = comp;
01190     comp->inst = inst;
01191 
01192     comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
01193                             XSLT_NAMESPACE);
01194     if (comp->select == NULL) {
01195     xsltTransformError(NULL, style, inst,
01196          "xsl:copy-of : select is missing\n");
01197     if (style != NULL) style->errors++;
01198     return;
01199     }
01200     comp->comp = xsltXPathCompile(style, comp->select);
01201     if (comp->comp == NULL) {
01202     xsltTransformError(NULL, style, inst,
01203          "xsl:copy-of : could not compile select expression '%s'\n",
01204                      comp->select);
01205     if (style != NULL) style->errors++;
01206     }
01207 }
01208 
01216 static void
01217 xsltValueOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01218 #ifdef XSLT_REFACTORED
01219     xsltStyleItemValueOfPtr comp;
01220 #else
01221     xsltStylePreCompPtr comp;
01222 #endif
01223     const xmlChar *prop;
01224 
01225     if ((style == NULL) || (inst == NULL))
01226     return;
01227 
01228 #ifdef XSLT_REFACTORED
01229     comp = (xsltStyleItemValueOfPtr) xsltNewStylePreComp(style, XSLT_FUNC_VALUEOF);
01230 #else
01231     comp = xsltNewStylePreComp(style, XSLT_FUNC_VALUEOF);
01232 #endif
01233 
01234     if (comp == NULL)
01235     return;
01236     inst->psvi = comp;
01237     comp->inst = inst;
01238 
01239     prop = xsltGetCNsProp(style, inst,
01240         (const xmlChar *)"disable-output-escaping",
01241             XSLT_NAMESPACE);
01242     if (prop != NULL) {
01243     if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
01244         comp->noescape = 1;
01245     } else if (!xmlStrEqual(prop,
01246                 (const xmlChar *)"no")){
01247         xsltTransformError(NULL, style, inst,
01248 "xsl:value-of : disable-output-escaping allows only yes or no\n");
01249         if (style != NULL) style->warnings++;
01250     }
01251     }
01252     comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
01253                             XSLT_NAMESPACE);
01254     if (comp->select == NULL) {
01255     xsltTransformError(NULL, style, inst,
01256          "xsl:value-of : select is missing\n");
01257     if (style != NULL) style->errors++;
01258     return;
01259     }
01260     comp->comp = xsltXPathCompile(style, comp->select);
01261     if (comp->comp == NULL) {
01262     xsltTransformError(NULL, style, inst,
01263          "xsl:value-of : could not compile select expression '%s'\n",
01264                      comp->select);
01265     if (style != NULL) style->errors++;
01266     }
01267 }
01268 
01269 static void
01270 xsltGetQNameProperty(xsltStylesheetPtr style, xmlNodePtr inst,
01271              const xmlChar *propName,
01272              int mandatory,
01273              int *hasProp, const xmlChar **nsName,
01274              const xmlChar** localName)
01275 {
01276     const xmlChar *prop;
01277 
01278     if (nsName)
01279     *nsName = NULL;
01280     if (localName)
01281     *localName = NULL;
01282     if (hasProp)
01283     *hasProp = 0;
01284 
01285     prop = xsltGetCNsProp(style, inst, propName, XSLT_NAMESPACE);
01286     if (prop == NULL) {
01287     if (mandatory) {
01288         xsltTransformError(NULL, style, inst,
01289         "The attribute '%s' is missing.\n", propName);
01290         style->errors++;
01291         return;
01292     }
01293     } else {
01294         const xmlChar *URI;
01295 
01296     if (xmlValidateQName(prop, 0)) {
01297         xsltTransformError(NULL, style, inst,
01298         "The value '%s' of the attribute "
01299         "'%s' is not a valid QName.\n", prop, propName);
01300         style->errors++;
01301         return;
01302     } else {
01303         /*
01304         * @prop will be in the string dict afterwards, @URI not.
01305         */
01306         URI = xsltGetQNameURI2(style, inst, &prop);
01307         if (prop == NULL) {
01308         style->errors++;
01309         } else {
01310         *localName = prop;
01311         if (hasProp)
01312             *hasProp = 1;
01313         if (URI != NULL) {
01314             /*
01315             * Fixes bug #308441: Put the ns-name in the dict
01316             * in order to pointer compare names during XPath's
01317             * variable lookup.
01318             */
01319             if (nsName)
01320             *nsName = xmlDictLookup(style->dict, URI, -1);
01321             /* comp->has_ns = 1; */
01322         }
01323         }
01324     }
01325     }
01326     return;
01327 }
01328 
01342 static void
01343 xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01344 #ifdef XSLT_REFACTORED
01345     xsltStyleItemWithParamPtr comp;
01346 #else
01347     xsltStylePreCompPtr comp;
01348 #endif
01349 
01350     if ((style == NULL) || (inst == NULL))
01351     return;
01352 
01353 #ifdef XSLT_REFACTORED
01354     comp = (xsltStyleItemWithParamPtr) xsltNewStylePreComp(style, XSLT_FUNC_WITHPARAM);
01355 #else
01356     comp = xsltNewStylePreComp(style, XSLT_FUNC_WITHPARAM);
01357 #endif
01358 
01359     if (comp == NULL)
01360     return;
01361     inst->psvi = comp;
01362     comp->inst = inst;
01363 
01364     /*
01365     * Attribute "name".
01366     */
01367     xsltGetQNameProperty(style, inst, BAD_CAST "name",
01368     1, &(comp->has_name), &(comp->ns), &(comp->name));
01369     if (comp->ns)
01370     comp->has_ns = 1;
01371     /*
01372     * Attribute "select".
01373     */
01374     comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
01375                             XSLT_NAMESPACE);
01376     if (comp->select != NULL) {
01377     comp->comp = xsltXPathCompile(style, comp->select);
01378     if (comp->comp == NULL) {
01379         xsltTransformError(NULL, style, inst,
01380          "XSLT-with-param: Failed to compile select "
01381          "expression '%s'\n", comp->select);
01382         style->errors++;
01383     }
01384     if (inst->children != NULL) {
01385         xsltTransformError(NULL, style, inst,
01386         "XSLT-with-param: The content should be empty since "
01387         "the attribute select is present.\n");
01388         style->warnings++;
01389     }
01390     }
01391 }
01392 
01400 static void
01401 xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {
01402 #ifdef XSLT_REFACTORED
01403     xsltStyleItemNumberPtr comp;
01404 #else
01405     xsltStylePreCompPtr comp;
01406 #endif
01407     const xmlChar *prop;
01408 
01409     if ((style == NULL) || (cur == NULL))
01410     return;
01411 
01412 #ifdef XSLT_REFACTORED
01413     comp = (xsltStyleItemNumberPtr) xsltNewStylePreComp(style, XSLT_FUNC_NUMBER);
01414 #else
01415     comp = xsltNewStylePreComp(style, XSLT_FUNC_NUMBER);
01416 #endif
01417 
01418     if (comp == NULL)
01419     return;
01420     cur->psvi = comp;
01421 
01422     if ((style == NULL) || (cur == NULL))
01423     return;
01424 
01425     comp->numdata.doc = cur->doc;
01426     comp->numdata.node = cur;
01427     comp->numdata.value = xsltGetCNsProp(style, cur, (const xmlChar *)"value",
01428                                     XSLT_NAMESPACE);
01429     
01430     prop = xsltEvalStaticAttrValueTemplate(style, cur,
01431              (const xmlChar *)"format",
01432              XSLT_NAMESPACE, &comp->numdata.has_format);
01433     if (comp->numdata.has_format == 0) {
01434     comp->numdata.format = xmlDictLookup(style->dict, BAD_CAST "" , 0);
01435     } else {
01436     comp->numdata.format = prop;
01437     }
01438 
01439     comp->numdata.count = xsltGetCNsProp(style, cur, (const xmlChar *)"count",
01440                     XSLT_NAMESPACE);
01441     comp->numdata.from = xsltGetCNsProp(style, cur, (const xmlChar *)"from",
01442                     XSLT_NAMESPACE);
01443     
01444     prop = xsltGetCNsProp(style, cur, (const xmlChar *)"level", XSLT_NAMESPACE);
01445     if (prop != NULL) {
01446     if (xmlStrEqual(prop, BAD_CAST("single")) ||
01447         xmlStrEqual(prop, BAD_CAST("multiple")) ||
01448         xmlStrEqual(prop, BAD_CAST("any"))) {
01449         comp->numdata.level = prop;
01450     } else {
01451         xsltTransformError(NULL, style, cur,
01452              "xsl:number : invalid value %s for level\n", prop);
01453         if (style != NULL) style->warnings++;
01454     }
01455     }
01456     
01457     prop = xsltGetCNsProp(style, cur, (const xmlChar *)"lang", XSLT_NAMESPACE);
01458     if (prop != NULL) {
01459         xsltTransformError(NULL, style, cur,
01460          "xsl:number : lang attribute not implemented\n");
01461     XSLT_TODO; /* xsl:number lang attribute */
01462     }
01463     
01464     prop = xsltGetCNsProp(style, cur, (const xmlChar *)"letter-value", XSLT_NAMESPACE);
01465     if (prop != NULL) {
01466     if (xmlStrEqual(prop, BAD_CAST("alphabetic"))) {
01467         xsltTransformError(NULL, style, cur,
01468          "xsl:number : letter-value 'alphabetic' not implemented\n");
01469         if (style != NULL) style->warnings++;
01470         XSLT_TODO; /* xsl:number letter-value attribute alphabetic */
01471     } else if (xmlStrEqual(prop, BAD_CAST("traditional"))) {
01472         xsltTransformError(NULL, style, cur,
01473          "xsl:number : letter-value 'traditional' not implemented\n");
01474         if (style != NULL) style->warnings++;
01475         XSLT_TODO; /* xsl:number letter-value attribute traditional */
01476     } else {
01477         xsltTransformError(NULL, style, cur,
01478              "xsl:number : invalid value %s for letter-value\n", prop);
01479         if (style != NULL) style->warnings++;
01480     }
01481     }
01482     
01483     prop = xsltGetCNsProp(style, cur, (const xmlChar *)"grouping-separator",
01484                     XSLT_NAMESPACE);
01485     if (prop != NULL) {
01486         comp->numdata.groupingCharacterLen = xmlStrlen(prop);
01487     comp->numdata.groupingCharacter =
01488         xsltGetUTF8Char(prop, &(comp->numdata.groupingCharacterLen));
01489     }
01490     
01491     prop = xsltGetCNsProp(style, cur, (const xmlChar *)"grouping-size", XSLT_NAMESPACE);
01492     if (prop != NULL) {
01493     sscanf((char *)prop, "%d", &comp->numdata.digitsPerGroup);
01494     } else {
01495     comp->numdata.groupingCharacter = 0;
01496     }
01497 
01498     /* Set default values */
01499     if (comp->numdata.value == NULL) {
01500     if (comp->numdata.level == NULL) {
01501         comp->numdata.level = xmlDictLookup(style->dict,
01502                                             BAD_CAST"single", 6);
01503     }
01504     }
01505     
01506 }
01507 
01515 static void
01516 xsltApplyImportsComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01517 #ifdef XSLT_REFACTORED
01518     xsltStyleItemApplyImportsPtr comp;
01519 #else
01520     xsltStylePreCompPtr comp;
01521 #endif
01522 
01523     if ((style == NULL) || (inst == NULL))
01524     return;
01525 
01526 #ifdef XSLT_REFACTORED
01527     comp = (xsltStyleItemApplyImportsPtr) xsltNewStylePreComp(style, XSLT_FUNC_APPLYIMPORTS);
01528 #else
01529     comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYIMPORTS);
01530 #endif
01531 
01532     if (comp == NULL)
01533     return;
01534     inst->psvi = comp;
01535     comp->inst = inst;
01536 }
01537 
01545 static void
01546 xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01547 #ifdef XSLT_REFACTORED
01548     xsltStyleItemCallTemplatePtr comp;
01549 #else
01550     xsltStylePreCompPtr comp;
01551 #endif
01552 
01553     if ((style == NULL) || (inst == NULL))
01554     return;
01555 
01556 #ifdef XSLT_REFACTORED
01557     comp = (xsltStyleItemCallTemplatePtr)
01558     xsltNewStylePreComp(style, XSLT_FUNC_CALLTEMPLATE);
01559 #else
01560     comp = xsltNewStylePreComp(style, XSLT_FUNC_CALLTEMPLATE);
01561 #endif
01562 
01563     if (comp == NULL)
01564     return;
01565     inst->psvi = comp;
01566     comp->inst = inst;
01567 
01568     /*
01569      * Attribute "name".
01570      */
01571     xsltGetQNameProperty(style, inst, BAD_CAST "name",
01572     1, &(comp->has_name), &(comp->ns), &(comp->name));
01573     if (comp->ns)
01574     comp->has_ns = 1;
01575 }
01576 
01584 static void
01585 xsltApplyTemplatesComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01586 #ifdef XSLT_REFACTORED
01587     xsltStyleItemApplyTemplatesPtr comp;
01588 #else
01589     xsltStylePreCompPtr comp;
01590 #endif
01591 
01592     if ((style == NULL) || (inst == NULL))
01593     return;
01594 
01595 #ifdef XSLT_REFACTORED
01596     comp = (xsltStyleItemApplyTemplatesPtr)
01597     xsltNewStylePreComp(style, XSLT_FUNC_APPLYTEMPLATES);
01598 #else
01599     comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYTEMPLATES);
01600 #endif
01601 
01602     if (comp == NULL)
01603     return;
01604     inst->psvi = comp;
01605     comp->inst = inst;
01606 
01607     /*
01608      * Attribute "mode".
01609      */
01610     xsltGetQNameProperty(style, inst, BAD_CAST "mode",
01611     0, NULL, &(comp->modeURI), &(comp->mode));
01612     /*
01613     * Attribute "select".
01614     */
01615     comp->select = xsltGetCNsProp(style, inst, BAD_CAST "select",
01616     XSLT_NAMESPACE);
01617     if (comp->select != NULL) {
01618     comp->comp = xsltXPathCompile(style, comp->select);
01619     if (comp->comp == NULL) {
01620         xsltTransformError(NULL, style, inst,
01621         "XSLT-apply-templates: could not compile select "
01622         "expression '%s'\n", comp->select);
01623          style->errors++;
01624     }
01625     }
01626     /* TODO: handle (or skip) the xsl:sort and xsl:with-param */
01627 }
01628 
01636 static void
01637 xsltChooseComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01638 #ifdef XSLT_REFACTORED
01639     xsltStyleItemChoosePtr comp;
01640 #else
01641     xsltStylePreCompPtr comp;
01642 #endif
01643 
01644     if ((style == NULL) || (inst == NULL))
01645     return;
01646 
01647 #ifdef XSLT_REFACTORED
01648     comp = (xsltStyleItemChoosePtr)
01649     xsltNewStylePreComp(style, XSLT_FUNC_CHOOSE);
01650 #else
01651     comp = xsltNewStylePreComp(style, XSLT_FUNC_CHOOSE);
01652 #endif
01653 
01654     if (comp == NULL)
01655     return;
01656     inst->psvi = comp;
01657     comp->inst = inst;
01658 }
01659 
01667 static void
01668 xsltIfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01669 #ifdef XSLT_REFACTORED
01670     xsltStyleItemIfPtr comp;
01671 #else
01672     xsltStylePreCompPtr comp;
01673 #endif
01674 
01675     if ((style == NULL) || (inst == NULL))
01676     return;
01677 
01678 #ifdef XSLT_REFACTORED
01679     comp = (xsltStyleItemIfPtr)
01680     xsltNewStylePreComp(style, XSLT_FUNC_IF);
01681 #else
01682     comp = xsltNewStylePreComp(style, XSLT_FUNC_IF);
01683 #endif
01684 
01685     if (comp == NULL)
01686     return;
01687     inst->psvi = comp;
01688     comp->inst = inst;
01689 
01690     comp->test = xsltGetCNsProp(style, inst, (const xmlChar *)"test", XSLT_NAMESPACE);
01691     if (comp->test == NULL) {
01692     xsltTransformError(NULL, style, inst,
01693          "xsl:if : test is not defined\n");
01694     if (style != NULL) style->errors++;
01695     return;
01696     }
01697     comp->comp = xsltXPathCompile(style, comp->test);
01698     if (comp->comp == NULL) {
01699     xsltTransformError(NULL, style, inst,
01700          "xsl:if : could not compile test expression '%s'\n",
01701                      comp->test);
01702     if (style != NULL) style->errors++;
01703     }
01704 }
01705 
01713 static void
01714 xsltWhenComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01715 #ifdef XSLT_REFACTORED
01716     xsltStyleItemWhenPtr comp;
01717 #else
01718     xsltStylePreCompPtr comp;
01719 #endif
01720 
01721     if ((style == NULL) || (inst == NULL))
01722     return;
01723 
01724 #ifdef XSLT_REFACTORED
01725     comp = (xsltStyleItemWhenPtr)
01726     xsltNewStylePreComp(style, XSLT_FUNC_WHEN);
01727 #else
01728     comp = xsltNewStylePreComp(style, XSLT_FUNC_WHEN);
01729 #endif
01730 
01731     if (comp == NULL)
01732     return;
01733     inst->psvi = comp;
01734     comp->inst = inst;
01735 
01736     comp->test = xsltGetCNsProp(style, inst, (const xmlChar *)"test", XSLT_NAMESPACE);
01737     if (comp->test == NULL) {
01738     xsltTransformError(NULL, style, inst,
01739          "xsl:when : test is not defined\n");
01740     if (style != NULL) style->errors++;
01741     return;
01742     }
01743     comp->comp = xsltXPathCompile(style, comp->test);
01744     if (comp->comp == NULL) {
01745     xsltTransformError(NULL, style, inst,
01746          "xsl:when : could not compile test expression '%s'\n",
01747                      comp->test);
01748     if (style != NULL) style->errors++;
01749     }
01750 }
01751 
01759 static void
01760 xsltForEachComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01761 #ifdef XSLT_REFACTORED
01762     xsltStyleItemForEachPtr comp;
01763 #else
01764     xsltStylePreCompPtr comp;
01765 #endif
01766 
01767     if ((style == NULL) || (inst == NULL))
01768     return;
01769 
01770 #ifdef XSLT_REFACTORED
01771     comp = (xsltStyleItemForEachPtr)
01772     xsltNewStylePreComp(style, XSLT_FUNC_FOREACH);
01773 #else
01774     comp = xsltNewStylePreComp(style, XSLT_FUNC_FOREACH);
01775 #endif
01776 
01777     if (comp == NULL)
01778     return;
01779     inst->psvi = comp;
01780     comp->inst = inst;
01781 
01782     comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
01783                             XSLT_NAMESPACE);
01784     if (comp->select == NULL) {
01785     xsltTransformError(NULL, style, inst,
01786         "xsl:for-each : select is missing\n");
01787     if (style != NULL) style->errors++;
01788     } else {
01789     comp->comp = xsltXPathCompile(style, comp->select);
01790     if (comp->comp == NULL) {
01791         xsltTransformError(NULL, style, inst,
01792      "xsl:for-each : could not compile select expression '%s'\n",
01793                  comp->select);
01794         if (style != NULL) style->errors++;
01795     }
01796     }
01797     /* TODO: handle and skip the xsl:sort */
01798 }
01799 
01807 static void
01808 xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01809 #ifdef XSLT_REFACTORED
01810     xsltStyleItemVariablePtr comp;
01811 #else
01812     xsltStylePreCompPtr comp;
01813 #endif
01814 
01815     if ((style == NULL) || (inst == NULL))
01816     return;
01817 
01818 #ifdef XSLT_REFACTORED
01819     comp = (xsltStyleItemVariablePtr)
01820     xsltNewStylePreComp(style, XSLT_FUNC_VARIABLE);
01821 #else
01822     comp = xsltNewStylePreComp(style, XSLT_FUNC_VARIABLE);
01823 #endif
01824 
01825     if (comp == NULL)
01826     return;
01827 
01828     inst->psvi = comp;
01829     comp->inst = inst;
01830     /*
01831      * The full template resolution can be done statically
01832      */
01833 
01834     /*
01835     * Attribute "name".
01836     */
01837     xsltGetQNameProperty(style, inst, BAD_CAST "name",
01838     1, &(comp->has_name), &(comp->ns), &(comp->name));
01839     if (comp->ns)
01840     comp->has_ns = 1;    
01841     /*
01842     * Attribute "select".
01843     */
01844     comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
01845                             XSLT_NAMESPACE);
01846     if (comp->select != NULL) {
01847     comp->comp = xsltXPathCompile(style, comp->select);
01848     if (comp->comp == NULL) {
01849         xsltTransformError(NULL, style, inst,
01850         "XSLT-variable: Failed to compile the XPath expression '%s'.\n",
01851         comp->select);
01852         style->errors++;
01853     }
01854     if (inst->children != NULL) {
01855         xsltTransformError(NULL, style, inst,
01856         "XSLT-variable: The must be no child nodes, since the "
01857         "attribute 'select' was specified.\n");
01858         style->errors++;
01859     }
01860     }
01861 }
01862 
01870 static void
01871 xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
01872 #ifdef XSLT_REFACTORED
01873     xsltStyleItemParamPtr comp;
01874 #else
01875     xsltStylePreCompPtr comp;
01876 #endif
01877 
01878     if ((style == NULL) || (inst == NULL))
01879     return;
01880 
01881 #ifdef XSLT_REFACTORED
01882     comp = (xsltStyleItemParamPtr)
01883     xsltNewStylePreComp(style, XSLT_FUNC_PARAM);
01884 #else
01885     comp = xsltNewStylePreComp(style, XSLT_FUNC_PARAM);
01886 #endif
01887 
01888     if (comp == NULL)
01889     return;
01890     inst->psvi = comp;
01891     comp->inst = inst;
01892 
01893     /*
01894      * Attribute "name".
01895      */
01896     xsltGetQNameProperty(style, inst, BAD_CAST "name",
01897     1, &(comp->has_name), &(comp->ns), &(comp->name));
01898     if (comp->ns)
01899     comp->has_ns = 1;
01900     /*
01901     * Attribute "select".
01902     */
01903     comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
01904                             XSLT_NAMESPACE);
01905     if (comp->select != NULL) {
01906     comp->comp = xsltXPathCompile(style, comp->select);
01907     if (comp->comp == NULL) {
01908         xsltTransformError(NULL, style, inst,
01909         "XSLT-param: could not compile select expression '%s'.\n",
01910         comp->select);
01911         style->errors++;
01912     }
01913     if (inst->children != NULL) {
01914         xsltTransformError(NULL, style, inst,
01915         "XSLT-param: The content should be empty since the "
01916         "attribute 'select' is present.\n");
01917         style->warnings++;
01918     }
01919     }
01920 }
01921 
01922 /************************************************************************
01923  *                                  *
01924  *          Generic interface                   *
01925  *                                  *
01926  ************************************************************************/
01927 
01934 void
01935 xsltFreeStylePreComps(xsltStylesheetPtr style) {
01936     xsltElemPreCompPtr cur, next;
01937 
01938     if (style == NULL)
01939     return;        
01940     
01941     cur = style->preComps;
01942     while (cur != NULL) {
01943     next = cur->next;       
01944     if (cur->type == XSLT_FUNC_EXTENSION)
01945         cur->free(cur);
01946     else
01947         xsltFreeStylePreComp((xsltStylePreCompPtr) cur);
01948     cur = next;
01949     }
01950 }
01951 
01952 #ifdef XSLT_REFACTORED
01953 
01963 void
01964 xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr node) {
01965     /*    
01966     * The xsltXSLTElemMarker marker was set beforehand by
01967     *  the parsing mechanism for all elements in the XSLT namespace.
01968     */
01969     if (style == NULL) {
01970     if (node != NULL)
01971         node->psvi = NULL;
01972     return;
01973     }
01974     if (node == NULL)
01975     return;
01976     if (! IS_XSLT_ELEM_FAST(node))
01977     return;
01978 
01979     node->psvi = NULL;
01980     if (XSLT_CCTXT(style)->inode->type != 0) {
01981     switch (XSLT_CCTXT(style)->inode->type) {
01982         case XSLT_FUNC_APPLYTEMPLATES:
01983         xsltApplyTemplatesComp(style, node);
01984         break;
01985         case XSLT_FUNC_WITHPARAM:              
01986         xsltWithParamComp(style, node);
01987         break;
01988         case XSLT_FUNC_VALUEOF:     
01989         xsltValueOfComp(style, node);
01990         break;
01991         case XSLT_FUNC_COPY:        
01992         xsltCopyComp(style, node);
01993         break;
01994         case XSLT_FUNC_COPYOF:
01995         xsltCopyOfComp(style, node);
01996         break;
01997         case XSLT_FUNC_IF:      
01998         xsltIfComp(style, node);
01999         break;
02000         case XSLT_FUNC_CHOOSE:      
02001         xsltChooseComp(style, node);
02002         break;
02003         case XSLT_FUNC_WHEN:        
02004         xsltWhenComp(style, node);
02005         break;
02006         case XSLT_FUNC_OTHERWISE:       
02007         /* NOP yet */
02008         return;
02009         case XSLT_FUNC_FOREACH:     
02010         xsltForEachComp(style, node);
02011         break;
02012         case XSLT_FUNC_APPLYIMPORTS:        
02013         xsltApplyImportsComp(style, node);
02014         break;
02015         case XSLT_FUNC_ATTRIBUTE:       
02016         xsltAttributeComp(style, node);
02017         break;
02018         case XSLT_FUNC_ELEMENT:     
02019         xsltElementComp(style, node);
02020         break;
02021         case XSLT_FUNC_SORT:        
02022         xsltSortComp(style, node);
02023         break;
02024         case XSLT_FUNC_COMMENT:     
02025         xsltCommentComp(style, node);
02026         break;
02027         case XSLT_FUNC_NUMBER:      
02028         xsltNumberComp(style, node);
02029         break;
02030         case XSLT_FUNC_PI:      
02031         xsltProcessingInstructionComp(style, node);
02032         break;
02033         case XSLT_FUNC_CALLTEMPLATE:        
02034         xsltCallTemplateComp(style, node);
02035         break;
02036         case XSLT_FUNC_PARAM:       
02037         xsltParamComp(style, node);
02038         break;
02039         case XSLT_FUNC_VARIABLE:        
02040         xsltVariableComp(style, node);
02041         break;
02042         case XSLT_FUNC_FALLBACK:        
02043         /* NOP yet */
02044         return;
02045         case XSLT_FUNC_DOCUMENT:        
02046         /* The extra one */
02047         node->psvi = (void *) xsltDocumentComp(style, node,
02048             (xsltTransformFunction) xsltDocumentElem);
02049         break;
02050         case XSLT_FUNC_MESSAGE:
02051         /* NOP yet */
02052         return;
02053         default:
02054         /*
02055         * NOTE that xsl:text, xsl:template, xsl:stylesheet,
02056         *  xsl:transform, xsl:import, xsl:include are not expected
02057         *  to be handed over to this function.
02058         */
02059         xsltTransformError(NULL, style, node,
02060             "Internal error: (xsltStylePreCompute) cannot handle "
02061             "the XSLT element '%s'.\n", node->name);
02062         style->errors++;
02063         return;
02064     }
02065     } else {
02066     /*
02067     * Fallback to string comparison.
02068     */  
02069     if (IS_XSLT_NAME(node, "apply-templates")) {
02070         xsltApplyTemplatesComp(style, node);
02071     } else if (IS_XSLT_NAME(node, "with-param")) {
02072         xsltWithParamComp(style, node);
02073     } else if (IS_XSLT_NAME(node, "value-of")) {
02074         xsltValueOfComp(style, node);
02075     } else if (IS_XSLT_NAME(node, "copy")) {
02076         xsltCopyComp(style, node);
02077     } else if (IS_XSLT_NAME(node, "copy-of")) {
02078         xsltCopyOfComp(style, node);
02079     } else if (IS_XSLT_NAME(node, "if")) {
02080         xsltIfComp(style, node);
02081     } else if (IS_XSLT_NAME(node, "choose")) {
02082         xsltChooseComp(style, node);
02083     } else if (IS_XSLT_NAME(node, "when")) {
02084         xsltWhenComp(style, node);  
02085     } else if (IS_XSLT_NAME(node, "otherwise")) {
02086         /* NOP yet */
02087         return;
02088     } else if (IS_XSLT_NAME(node, "for-each")) {
02089         xsltForEachComp(style, node);
02090     } else if (IS_XSLT_NAME(node, "apply-imports")) {
02091         xsltApplyImportsComp(style, node);
02092     } else if (IS_XSLT_NAME(node, "attribute")) {
02093         xsltAttributeComp(style, node);
02094     } else if (IS_XSLT_NAME(node, "element")) {
02095         xsltElementComp(style, node);
02096     } else if (IS_XSLT_NAME(node, "sort")) {
02097         xsltSortComp(style, node);
02098     } else if (IS_XSLT_NAME(node, "comment")) {
02099         xsltCommentComp(style, node);
02100     } else if (IS_XSLT_NAME(node, "number")) {
02101         xsltNumberComp(style, node);
02102     } else if (IS_XSLT_NAME(node, "processing-instruction")) {
02103         xsltProcessingInstructionComp(style, node);
02104     } else if (IS_XSLT_NAME(node, "call-template")) {
02105         xsltCallTemplateComp(style, node);
02106     } else if (IS_XSLT_NAME(node, "param")) {
02107         xsltParamComp(style, node);
02108     } else if (IS_XSLT_NAME(node, "variable")) {
02109         xsltVariableComp(style, node);
02110     } else if (IS_XSLT_NAME(node, "fallback")) {
02111         /* NOP yet */
02112         return;
02113     } else if (IS_XSLT_NAME(node, "document")) {
02114         /* The extra one */
02115         node->psvi = (void *) xsltDocumentComp(style, node,
02116         (xsltTransformFunction) xsltDocumentElem);  
02117     } else if (IS_XSLT_NAME(node, "output")) {
02118         /* Top-level */
02119         return;
02120     } else if (IS_XSLT_NAME(node, "preserve-space")) {
02121         /* Top-level */
02122         return;
02123     } else if (IS_XSLT_NAME(node, "strip-space")) {
02124         /* Top-level */
02125         return; 
02126     } else if (IS_XSLT_NAME(node, "key")) {
02127         /* Top-level */
02128         return;
02129     } else if (IS_XSLT_NAME(node, "message")) {
02130         return;
02131     } else if (IS_XSLT_NAME(node, "attribute-set")) {
02132         /* Top-level */
02133         return;
02134     } else if (IS_XSLT_NAME(node, "namespace-alias")) {
02135         /* Top-level */
02136         return;
02137     } else if (IS_XSLT_NAME(node, "decimal-format")) {
02138         /* Top-level */
02139         return;
02140     } else if (IS_XSLT_NAME(node, "include")) {
02141         /* Top-level */             
02142     } else {
02143         /*
02144         * NOTE that xsl:text, xsl:template, xsl:stylesheet,
02145         *  xsl:transform, xsl:import, xsl:include are not expected
02146         *  to be handed over to this function.
02147         */
02148         xsltTransformError(NULL, style, node,
02149         "Internal error: (xsltStylePreCompute) cannot handle "
02150         "the XSLT element '%s'.\n", node->name);
02151         style->errors++;
02152         return;
02153     }   
02154     }
02155     /*
02156     * Assign the current list of in-scope namespaces to the
02157     * item. This is needed for XPath expressions.
02158     */
02159     if (node->psvi != NULL) {
02160     ((xsltStylePreCompPtr) node->psvi)->inScopeNs =
02161         XSLT_CCTXT(style)->inode->inScopeNs;
02162     }
02163 }
02164 
02165 #else
02166 
02174 void
02175 xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
02176     /*
02177     * URGENT TODO: Normally inst->psvi Should never be reserved here,
02178     *   BUT: since if we include the same stylesheet from
02179     *   multiple imports, then the stylesheet will be parsed
02180     *   again. We simply must not try to compute the stylesheet again.
02181     * TODO: Get to the point where we don't need to query the
02182     *   namespace- and local-name of the node, but can evaluate this
02183     *   using cctxt->style->inode->category;
02184     */
02185     if (inst->psvi != NULL)
02186     return;
02187 
02188     if (IS_XSLT_ELEM(inst)) {
02189     xsltStylePreCompPtr cur;
02190 
02191     if (IS_XSLT_NAME(inst, "apply-templates")) {
02192         xsltCheckInstructionElement(style, inst);
02193         xsltApplyTemplatesComp(style, inst);
02194     } else if (IS_XSLT_NAME(inst, "with-param")) {
02195         xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
02196                                BAD_CAST "call-template");
02197         xsltWithParamComp(style, inst);
02198     } else if (IS_XSLT_NAME(inst, "value-of")) {
02199         xsltCheckInstructionElement(style, inst);
02200         xsltValueOfComp(style, inst);
02201     } else if (IS_XSLT_NAME(inst, "copy")) {
02202         xsltCheckInstructionElement(style, inst);
02203         xsltCopyComp(style, inst);
02204     } else if (IS_XSLT_NAME(inst, "copy-of")) {
02205         xsltCheckInstructionElement(style, inst);
02206         xsltCopyOfComp(style, inst);
02207     } else if (IS_XSLT_NAME(inst, "if")) {
02208         xsltCheckInstructionElement(style, inst);
02209         xsltIfComp(style, inst);
02210     } else if (IS_XSLT_NAME(inst, "when")) {
02211         xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
02212         xsltWhenComp(style, inst);
02213     } else if (IS_XSLT_NAME(inst, "choose")) {
02214         xsltCheckInstructionElement(style, inst);
02215         xsltChooseComp(style, inst);
02216     } else if (IS_XSLT_NAME(inst, "for-each")) {
02217         xsltCheckInstructionElement(style, inst);
02218         xsltForEachComp(style, inst);
02219     } else if (IS_XSLT_NAME(inst, "apply-imports")) {
02220         xsltCheckInstructionElement(style, inst);
02221         xsltApplyImportsComp(style, inst);
02222     } else if (IS_XSLT_NAME(inst, "attribute")) {
02223         xmlNodePtr parent = inst->parent;
02224 
02225         if ((parent == NULL) || (parent->ns == NULL) ||
02226         ((parent->ns != inst->ns) &&
02227          (!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
02228         (!xmlStrEqual(parent->name, BAD_CAST "attribute-set"))) {
02229         xsltCheckInstructionElement(style, inst);
02230         }
02231         xsltAttributeComp(style, inst);
02232     } else if (IS_XSLT_NAME(inst, "element")) {
02233         xsltCheckInstructionElement(style, inst);
02234         xsltElementComp(style, inst);
02235     } else if (IS_XSLT_NAME(inst, "text")) {
02236         xsltCheckInstructionElement(style, inst);
02237         xsltTextComp(style, inst);
02238     } else if (IS_XSLT_NAME(inst, "sort")) {
02239         xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
02240                                BAD_CAST "for-each");
02241         xsltSortComp(style, inst);
02242     } else if (IS_XSLT_NAME(inst, "comment")) {
02243         xsltCheckInstructionElement(style, inst);
02244         xsltCommentComp(style, inst);
02245     } else if (IS_XSLT_NAME(inst, "number")) {
02246         xsltCheckInstructionElement(style, inst);
02247         xsltNumberComp(style, inst);
02248     } else if (IS_XSLT_NAME(inst, "processing-instruction")) {
02249         xsltCheckInstructionElement(style, inst);
02250         xsltProcessingInstructionComp(style, inst);
02251     } else if (IS_XSLT_NAME(inst, "call-template")) {
02252         xsltCheckInstructionElement(style, inst);
02253         xsltCallTemplateComp(style, inst);
02254     } else if (IS_XSLT_NAME(inst, "param")) {      
02255         if (xsltCheckTopLevelElement(style, inst, 0) == 0)
02256             xsltCheckInstructionElement(style, inst);
02257         xsltParamComp(style, inst);
02258     } else if (IS_XSLT_NAME(inst, "variable")) {
02259         if (xsltCheckTopLevelElement(style, inst, 0) == 0)
02260             xsltCheckInstructionElement(style, inst);
02261         xsltVariableComp(style, inst);
02262     } else if (IS_XSLT_NAME(inst, "otherwise")) {
02263         xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
02264         xsltCheckInstructionElement(style, inst);
02265         return;
02266     } else if (IS_XSLT_NAME(inst, "template")) {
02267         xsltCheckTopLevelElement(style, inst, 1);
02268         return;
02269     } else if (IS_XSLT_NAME(inst, "output")) {
02270         xsltCheckTopLevelElement(style, inst, 1);
02271         return;
02272     } else if (IS_XSLT_NAME(inst, "preserve-space")) {
02273         xsltCheckTopLevelElement(style, inst, 1);
02274         return;
02275     } else if (IS_XSLT_NAME(inst, "strip-space")) {
02276         xsltCheckTopLevelElement(style, inst, 1);
02277         return;
02278     } else if ((IS_XSLT_NAME(inst, "stylesheet")) ||
02279                (IS_XSLT_NAME(inst, "transform"))) {
02280         xmlNodePtr parent = inst->parent;
02281 
02282         if ((parent == NULL) || (parent->type != XML_DOCUMENT_NODE)) {
02283         xsltTransformError(NULL, style, inst,
02284             "element %s only allowed only as root element\n",
02285                    inst->name);
02286         style->errors++;
02287         }
02288         return;
02289     } else if (IS_XSLT_NAME(inst, "key")) {
02290         xsltCheckTopLevelElement(style, inst, 1);
02291         return;
02292     } else if (IS_XSLT_NAME(inst, "message")) {
02293         xsltCheckInstructionElement(style, inst);
02294         return;
02295     } else if (IS_XSLT_NAME(inst, "attribute-set")) {
02296         xsltCheckTopLevelElement(style, inst, 1);
02297         return;
02298     } else if (IS_XSLT_NAME(inst, "namespace-alias")) {
02299         xsltCheckTopLevelElement(style, inst, 1);
02300         return;
02301     } else if (IS_XSLT_NAME(inst, "include")) {
02302         xsltCheckTopLevelElement(style, inst, 1);
02303         return;
02304     } else if (IS_XSLT_NAME(inst, "import")) {
02305         xsltCheckTopLevelElement(style, inst, 1);
02306         return;
02307     } else if (IS_XSLT_NAME(inst, "decimal-format")) {
02308         xsltCheckTopLevelElement(style, inst, 1);
02309         return;
02310     } else if (IS_XSLT_NAME(inst, "fallback")) {
02311         xsltCheckInstructionElement(style, inst);
02312         return;
02313     } else if (IS_XSLT_NAME(inst, "document")) {
02314         xsltCheckInstructionElement(style, inst);
02315         inst->psvi = (void *) xsltDocumentComp(style, inst,
02316                 (xsltTransformFunction) xsltDocumentElem);
02317     } else {
02318         xsltTransformError(NULL, style, inst,
02319          "xsltStylePreCompute: unknown xsl:%s\n", inst->name);
02320         if (style != NULL) style->warnings++;
02321     }
02322     
02323     cur = (xsltStylePreCompPtr) inst->psvi;
02324     /*
02325     * A ns-list is build for every XSLT item in the
02326     * node-tree. This is needed for XPath expressions.
02327     */
02328     if (cur != NULL) {
02329         int i = 0;
02330 
02331         cur->nsList = xmlGetNsList(inst->doc, inst);
02332             if (cur->nsList != NULL) {
02333         while (cur->nsList[i] != NULL)
02334             i++;
02335         }
02336         cur->nsNr = i;
02337     }
02338     } else {
02339     inst->psvi =
02340         (void *) xsltPreComputeExtModuleElement(style, inst);
02341 
02342     /*
02343      * Unknown element, maybe registered at the context
02344      * level. Mark it for later recognition.
02345      */
02346     if (inst->psvi == NULL)
02347         inst->psvi = (void *) xsltExtMarker;
02348     }
02349 }
02350 #endif /* XSLT_REFACTORED */

Generated on Sat May 26 2012 04:18:27 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.