ReactOS 0.4.16-dev-257-g6aa11ac
variables.c File Reference
#include "precomp.h"
Include dependency graph for variables.c:

Go to the source code of this file.

Macros

#define XSLT_VAR_GLOBAL   (1<<0)
 
#define XSLT_VAR_IN_SELECT   (1<<1)
 
#define XSLT_TCTXT_VARIABLE(c)   ((xsltStackElemPtr) (c)->contextVariable)
 

Functions

xmlDocPtr xsltCreateRVT (xsltTransformContextPtr ctxt)
 
int xsltRegisterTmpRVT (xsltTransformContextPtr ctxt, xmlDocPtr RVT)
 
int xsltRegisterLocalRVT (xsltTransformContextPtr ctxt, xmlDocPtr RVT)
 
int xsltExtensionInstructionResultFinalize (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED)
 
int xsltExtensionInstructionResultRegister (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, xmlXPathObjectPtr obj ATTRIBUTE_UNUSED)
 
int xsltFlagRVTs (xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val)
 
void xsltReleaseRVT (xsltTransformContextPtr ctxt, xmlDocPtr RVT)
 
int xsltRegisterPersistRVT (xsltTransformContextPtr ctxt, xmlDocPtr RVT)
 
void xsltFreeRVTs (xsltTransformContextPtr ctxt)
 
static xsltStackElemPtr xsltNewStackElem (xsltTransformContextPtr ctxt)
 
static xsltStackElemPtr xsltCopyStackElem (xsltStackElemPtr elem)
 
static void xsltFreeStackElem (xsltStackElemPtr elem)
 
static void xsltFreeStackElemEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
 
void xsltFreeStackElemList (xsltStackElemPtr elem)
 
: the local part of the name

xsltStackLookup: @ctxt: an XSLT transformation context

@nameURI: the URI part of the name

Locate an element in the stack based on its name.

static xsltStackElemPtr xsltStackLookup (xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI)
 
: the variable name

xsltXPathVariableLookup: @ctxt: a void * but the the XSLT transformation context actually

@ns_uri: the variable namespace URI

This is the entry point when a varibale is needed by the XPath interpretor.

Returns the value or NULL if not found

static int xsltCheckStackElem (xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI)
 
static int xsltAddStackElem (xsltTransformContextPtr ctxt, xsltStackElemPtr elem)
 
int xsltAddStackElemList (xsltTransformContextPtr ctxt, xsltStackElemPtr elems)
 
static xmlXPathObjectPtr xsltEvalVariable (xsltTransformContextPtr ctxt, xsltStackElemPtr variable, xsltStylePreCompPtr castedComp)
 
static xmlXPathObjectPtr xsltEvalGlobalVariable (xsltStackElemPtr elem, xsltTransformContextPtr ctxt)
 
static void xsltEvalGlobalVariableWrapper (void *payload, void *data, const xmlChar *name ATTRIBUTE_UNUSED)
 
int xsltEvalGlobalVariables (xsltTransformContextPtr ctxt)
 
static int xsltRegisterGlobalVariable (xsltStylesheetPtr style, const xmlChar *name, const xmlChar *ns_uri, const xmlChar *sel, xmlNodePtr tree, xsltStylePreCompPtr comp, const xmlChar *value)
 
static xmlXPathObjectPtr xsltGlobalVariableLookup (xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *ns_uri)
 
xmlXPathObjectPtr xsltVariableLookup (xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *ns_uri)
 
xsltStackElemPtr xsltParseStylesheetCallerParam (xsltTransformContextPtr ctxt, xmlNodePtr inst)
 
void xsltParseGlobalVariable (xsltStylesheetPtr style, xmlNodePtr cur)
 
void xsltParseGlobalParam (xsltStylesheetPtr style, xmlNodePtr cur)
 
void xsltParseStylesheetVariable (xsltTransformContextPtr ctxt, xmlNodePtr inst)
 
void xsltParseStylesheetParam (xsltTransformContextPtr ctxt, xmlNodePtr cur)
 
void xsltFreeGlobalVariables (xsltTransformContextPtr ctxt)
 
xmlXPathObjectPtr xsltXPathVariableLookup (void *ctxt, const xmlChar *name, const xmlChar *ns_uri)
 
: a null terminated parameter name

xsltProcessUserParamInternal

@ctxt: the XSLT transformation context

@value: a null terminated value (may be an XPath expression) @eval: 0 to treat the value literally, else evaluate as XPath expression

If @eval is 0 then @value is treated literally and is stored in the global parameter/variable table without any change.

Uf @eval is 1 then @value is treated as an XPath expression and is evaluated. In this case, if you want to pass a string which will be interpreted literally then it must be enclosed in single or double quotes. If the string contains single quotes (double quotes) then it cannot be enclosed single quotes (double quotes). If the string which you want to be treated literally contains both single and double quotes (e.g. Meet at Joe's for "Twelfth Night" at 7 o'clock) then there is no suitable quoting character. You cannot use ' or " inside the string because the replacement of character entities with their equivalents is done at a different stage of processing. The solution is to call xsltQuoteUserParams or xsltQuoteOneUserParam.

This needs to be done on parsed stylesheets before starting to apply transformations. Normally this will be called (directly or indirectly) only from xsltEvalUserParams, xsltEvalOneUserParam, xsltQuoteUserParams, or xsltQuoteOneUserParam.

Returns 0 in case of success, -1 in case of error

static int xsltProcessUserParamInternal (xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *value, int eval)
 
int xsltEvalUserParams (xsltTransformContextPtr ctxt, const char **params)
 
int xsltQuoteUserParams (xsltTransformContextPtr ctxt, const char **params)
 
: a null terminated string giving the name of the parameter

xsltQuoteOneUserParam: @ctxt: the XSLT transformation context

@value: a null terminated string giving the parameter value

This is normally called from xsltQuoteUserParams to process a single parameter from a list of parameters. The @value is stored in the context's global variable/parameter hash table.

Returns 0 in case of success, -1 in case of error.

int xsltEvalOneUserParam (xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *value)
 
int xsltQuoteOneUserParam (xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *value)
 
static xsltStackElemPtr xsltBuildVariable (xsltTransformContextPtr ctxt, xsltStylePreCompPtr castedComp, xmlNodePtr tree)
 
static int xsltRegisterVariable (xsltTransformContextPtr ctxt, xsltStylePreCompPtr castedComp, xmlNodePtr tree, int isParam)
 

Variables

static const xmlCharxsltComputingGlobalVarMarker
 

Macro Definition Documentation

◆ XSLT_TCTXT_VARIABLE

#define XSLT_TCTXT_VARIABLE (   c)    ((xsltStackElemPtr) (c)->contextVariable)

Definition at line 27 of file variables.c.

◆ XSLT_VAR_GLOBAL

#define XSLT_VAR_GLOBAL   (1<<0)

Definition at line 25 of file variables.c.

◆ XSLT_VAR_IN_SELECT

#define XSLT_VAR_IN_SELECT   (1<<1)

Definition at line 26 of file variables.c.

Function Documentation

◆ xsltAddStackElem()

static int xsltAddStackElem ( xsltTransformContextPtr  ctxt,
xsltStackElemPtr  elem 
)
static

xsltAddStackElem: @ctxt: xn XSLT transformation context @elem: a stack element

Push an element (or list) onto the stack. In case of a list, each member will be pushed into a seperate slot; i.e. there's always 1 stack entry for 1 stack element.

Returns 0 in case of success, -1 in case of failure.

Definition at line 731 of file variables.c.

732{
733 if ((ctxt == NULL) || (elem == NULL))
734 return(-1);
735
736 do {
737 if (ctxt->varsMax == 0) {
738 ctxt->varsMax = 10;
739 ctxt->varsTab =
741 sizeof(ctxt->varsTab[0]));
742 if (ctxt->varsTab == NULL) {
743 xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
744 return (-1);
745 }
746 }
747 if (ctxt->varsNr >= ctxt->varsMax) {
748 ctxt->varsMax *= 2;
749 ctxt->varsTab =
751 ctxt->varsMax *
752 sizeof(ctxt->varsTab[0]));
753 if (ctxt->varsTab == NULL) {
754 xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
755 return (-1);
756 }
757 }
758 ctxt->varsTab[ctxt->varsNr++] = elem;
759 ctxt->vars = elem;
760
761 elem = elem->next;
762 } while (elem != NULL);
763
764 return(0);
765}
#define NULL
Definition: types.h:112
static size_t elem
Definition: string.c:68
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR void * xmlGenericErrorContext
Definition: globals.h:353
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:250
XMLPUBVAR xmlGenericErrorFunc xmlGenericError
Definition: globals.h:337
xsltStackElemPtr vars
xsltStackElemPtr * varsTab

Referenced by xsltAddStackElemList(), and xsltRegisterVariable().

◆ xsltAddStackElemList()

int xsltAddStackElemList ( xsltTransformContextPtr  ctxt,
xsltStackElemPtr  elems 
)

xsltAddStackElemList: @ctxt: xn XSLT transformation context @elems: a stack element list

Push an element list onto the stack.

Returns 0 in case of success, -1 in case of failure.

Definition at line 777 of file variables.c.

778{
779 return(xsltAddStackElem(ctxt, elems));
780}
static int xsltAddStackElem(xsltTransformContextPtr ctxt, xsltStackElemPtr elem)
Definition: variables.c:731

◆ xsltBuildVariable()

static xsltStackElemPtr xsltBuildVariable ( xsltTransformContextPtr  ctxt,
xsltStylePreCompPtr  castedComp,
xmlNodePtr  tree 
)
static

xsltBuildVariable: @ctxt: the XSLT transformation context @comp: the precompiled form @tree: the tree if select is NULL

Computes a new variable value.

Returns the xsltStackElemPtr or NULL in case of error

Definition at line 1766 of file variables.c.

1769{
1770#ifdef XSLT_REFACTORED
1771 xsltStyleBasicItemVariablePtr comp =
1772 (xsltStyleBasicItemVariablePtr) castedComp;
1773#else
1774 xsltStylePreCompPtr comp = castedComp;
1775#endif
1777
1778#ifdef WITH_XSLT_DEBUG_VARIABLE
1780 "Building variable %s", comp->name));
1781 if (comp->select != NULL)
1783 " select %s", comp->select));
1785#endif
1786
1787 elem = xsltNewStackElem(ctxt);
1788 if (elem == NULL)
1789 return(NULL);
1790 elem->comp = (xsltStylePreCompPtr) comp;
1791 elem->name = comp->name;
1792 elem->select = comp->select;
1793 elem->nameURI = comp->ns;
1794 elem->tree = tree;
1795 elem->value = xsltEvalVariable(ctxt, elem,
1796 (xsltStylePreCompPtr) comp);
1797 elem->computed = 1;
1798 return(elem);
1799}
struct _tree tree
static xmlXPathObjectPtr xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable, xsltStylePreCompPtr castedComp)
Definition: variables.c:799
static xsltStackElemPtr xsltNewStackElem(xsltTransformContextPtr ctxt)
Definition: variables.c:480
xsltStylePreComp * xsltStylePreCompPtr
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
void * xsltGenericDebugContext
Definition: xsltutils.c:549
@ XSLT_TRACE_VARIABLES
Definition: xsltutils.h:117
#define XSLT_TRACE(ctxt, code, call)
Definition: xsltutils.h:125

Referenced by xsltParseStylesheetCallerParam(), and xsltRegisterVariable().

◆ xsltCheckStackElem()

static int xsltCheckStackElem ( xsltTransformContextPtr  ctxt,
const xmlChar name,
const xmlChar nameURI 
)
static

Definition at line 696 of file variables.c.

697 {
699
700 if ((ctxt == NULL) || (name == NULL))
701 return(-1);
702
703 cur = xsltStackLookup(ctxt, name, nameURI);
704 if (cur == NULL)
705 return(0);
706 if (cur->comp != NULL) {
707 if (cur->comp->type == XSLT_FUNC_WITHPARAM)
708 return(3);
709 else if (cur->comp->type == XSLT_FUNC_PARAM)
710 return(2);
711 }
712
713 return(1);
714}
FxCollectionEntry * cur
Definition: name.c:39
static xsltStackElemPtr xsltStackLookup(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI)
Definition: variables.c:627
@ XSLT_FUNC_WITHPARAM
@ XSLT_FUNC_PARAM

Referenced by xsltRegisterVariable().

◆ xsltCopyStackElem()

static xsltStackElemPtr xsltCopyStackElem ( xsltStackElemPtr  elem)
static

xsltCopyStackElem: @elem: an XSLT stack element

Makes a copy of the stack element

Returns the copy of NULL

Definition at line 516 of file variables.c.

516 {
518
520 if (cur == NULL) {
522 "xsltCopyStackElem : malloc failed\n");
523 return(NULL);
524 }
525 memset(cur, 0, sizeof(xsltStackElem));
526 cur->context = elem->context;
527 cur->name = elem->name;
528 cur->nameURI = elem->nameURI;
529 cur->select = elem->select;
530 cur->tree = elem->tree;
531 cur->comp = elem->comp;
532 return(cur);
533}
#define memset(x, y, z)
Definition: compat.h:39
xsltStackElem * xsltStackElemPtr
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678

Referenced by xsltEvalGlobalVariables().

◆ xsltCreateRVT()

xmlDocPtr xsltCreateRVT ( xsltTransformContextPtr  ctxt)

xsltCreateRVT: @ctxt: an XSLT transformation context

Creates a Result Value Tree (the XSLT 1.0 term for this is "Result Tree Fragment")

Returns the result value tree or NULL in case of API or internal errors.

Definition at line 44 of file variables.c.

45{
47
48 /*
49 * Question: Why is this function public?
50 * Answer: It is called by the EXSLT module.
51 */
52 if (ctxt == NULL)
53 return(NULL);
54
55 /*
56 * Reuse a RTF from the cache if available.
57 */
58 if (ctxt->cache->RVT) {
59 container = ctxt->cache->RVT;
60 ctxt->cache->RVT = (xmlDocPtr) container->next;
61 /* clear the internal pointers */
62 container->next = NULL;
63 container->prev = NULL;
64 if (ctxt->cache->nbRVT > 0)
65 ctxt->cache->nbRVT--;
66#ifdef XSLT_DEBUG_PROFILE_CACHE
67 ctxt->cache->dbgReusedRVTs++;
68#endif
69 return(container);
70 }
71
73 if (container == NULL)
74 return(NULL);
75 container->dict = ctxt->dict;
78 container->doc = container;
79 container->parent = NULL;
80 return(container);
81}
if(dx< 0)
Definition: linetemp.h:194
XMLPUBFUN int XMLCALL xmlDictReference(xmlDictPtr dict)
Definition: dict.c:647
XMLPUBFUN xmlDocPtr XMLCALL xmlNewDoc(const xmlChar *version)
xmlDoc * xmlDocPtr
Definition: tree.h:550
Definition: tree.h:551
xsltTransformCachePtr cache
#define XSLT_MARK_RES_TREE_FRAG(n)
Definition: xsltInternals.h:48

Referenced by xsltEvalGlobalVariable(), and xsltEvalVariable().

◆ xsltEvalGlobalVariable()

static xmlXPathObjectPtr xsltEvalGlobalVariable ( xsltStackElemPtr  elem,
xsltTransformContextPtr  ctxt 
)
static

xsltEvalGlobalVariable: @elem: the variable or parameter @ctxt: the XSLT transformation context

Evaluates a the value of a global xsl:variable or xsl:param declaration.

Returns the XPath Object value or NULL in case of error

Definition at line 1032 of file variables.c.

1033{
1034 xmlXPathObjectPtr result = NULL;
1035 xmlNodePtr oldInst;
1036 const xmlChar* oldVarName;
1037
1038#ifdef XSLT_REFACTORED
1039 xsltStyleBasicItemVariablePtr comp;
1040#else
1042#endif
1043
1044 if ((ctxt == NULL) || (elem == NULL))
1045 return(NULL);
1046 if (elem->computed)
1047 return(elem->value);
1048
1049
1050#ifdef WITH_XSLT_DEBUG_VARIABLE
1052 "Evaluating global variable %s\n", elem->name));
1053#endif
1054
1055#ifdef WITH_DEBUGGER
1056 if ((ctxt->debugStatus != XSLT_DEBUG_NONE) &&
1057 elem->comp && elem->comp->inst)
1058 xslHandleDebugger(elem->comp->inst, NULL, NULL, ctxt);
1059#endif
1060
1061 oldInst = ctxt->inst;
1062#ifdef XSLT_REFACTORED
1063 comp = (xsltStyleBasicItemVariablePtr) elem->comp;
1064#else
1065 comp = elem->comp;
1066#endif
1067 oldVarName = elem->name;
1069 /*
1070 * OPTIMIZE TODO: We should consider instantiating global vars/params
1071 * on-demand. The vars/params don't need to be evaluated if never
1072 * called; and in the case of global params, if values for such params
1073 * are provided by the user.
1074 */
1075 if (elem->select != NULL) {
1076 xmlXPathCompExprPtr xpExpr = NULL;
1077 xmlDocPtr oldXPDoc;
1078 xmlNodePtr oldXPContextNode;
1079 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
1080 xmlNsPtr *oldXPNamespaces;
1081 xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
1082
1083 if ((comp != NULL) && (comp->comp != NULL)) {
1084 xpExpr = comp->comp;
1085 } else {
1086 xpExpr = xmlXPathCtxtCompile(ctxt->xpathCtxt, elem->select);
1087 }
1088 if (xpExpr == NULL)
1089 goto error;
1090
1091
1092 if (comp != NULL)
1093 ctxt->inst = comp->inst;
1094 else
1095 ctxt->inst = NULL;
1096 /*
1097 * SPEC XSLT 1.0:
1098 * "At top-level, the expression or template specifying the
1099 * variable value is evaluated with the same context as that used
1100 * to process the root node of the source document: the current
1101 * node is the root node of the source document and the current
1102 * node list is a list containing just the root node of the source
1103 * document."
1104 */
1105 /*
1106 * Save context states.
1107 */
1108 oldXPDoc = xpctxt->doc;
1109 oldXPContextNode = xpctxt->node;
1110 oldXPProximityPosition = xpctxt->proximityPosition;
1111 oldXPContextSize = xpctxt->contextSize;
1112 oldXPNamespaces = xpctxt->namespaces;
1113 oldXPNsNr = xpctxt->nsNr;
1114
1115 xpctxt->node = ctxt->initialContextNode;
1116 xpctxt->doc = ctxt->initialContextDoc;
1117 xpctxt->contextSize = 1;
1118 xpctxt->proximityPosition = 1;
1119
1120 if (comp != NULL) {
1121
1122#ifdef XSLT_REFACTORED
1123 if (comp->inScopeNs != NULL) {
1124 xpctxt->namespaces = comp->inScopeNs->list;
1125 xpctxt->nsNr = comp->inScopeNs->xpathNumber;
1126 } else {
1127 xpctxt->namespaces = NULL;
1128 xpctxt->nsNr = 0;
1129 }
1130#else
1131 xpctxt->namespaces = comp->nsList;
1132 xpctxt->nsNr = comp->nsNr;
1133#endif
1134 } else {
1135 xpctxt->namespaces = NULL;
1136 xpctxt->nsNr = 0;
1137 }
1138
1139 result = xmlXPathCompiledEval(xpExpr, xpctxt);
1140
1141 /*
1142 * Restore Context states.
1143 */
1144 xpctxt->doc = oldXPDoc;
1145 xpctxt->node = oldXPContextNode;
1146 xpctxt->contextSize = oldXPContextSize;
1147 xpctxt->proximityPosition = oldXPProximityPosition;
1148 xpctxt->namespaces = oldXPNamespaces;
1149 xpctxt->nsNr = oldXPNsNr;
1150
1151 if ((comp == NULL) || (comp->comp == NULL))
1152 xmlXPathFreeCompExpr(xpExpr);
1153 if (result == NULL) {
1154 if (comp == NULL)
1156 "Evaluating global variable %s failed\n", elem->name);
1157 else
1158 xsltTransformError(ctxt, NULL, comp->inst,
1159 "Evaluating global variable %s failed\n", elem->name);
1160 ctxt->state = XSLT_STATE_STOPPED;
1161 goto error;
1162 }
1163
1164 /*
1165 * Mark all RVTs that are referenced from result as part
1166 * of this variable so they won't be freed too early.
1167 */
1169
1170#ifdef WITH_XSLT_DEBUG_VARIABLE
1171#ifdef LIBXML_DEBUG_ENABLED
1174 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
1175 result, 0);
1176#endif
1177#endif
1178 } else {
1179 if (elem->tree == NULL) {
1180 result = xmlXPathNewCString("");
1181 } else {
1183 xmlNodePtr oldInsert;
1184 xmlDocPtr oldOutput, oldXPDoc;
1185 /*
1186 * Generate a result tree fragment.
1187 */
1188 container = xsltCreateRVT(ctxt);
1189 if (container == NULL)
1190 goto error;
1191 /*
1192 * Let the lifetime of the tree fragment be handled by
1193 * the Libxslt's garbage collector.
1194 */
1196
1197 oldOutput = ctxt->output;
1198 oldInsert = ctxt->insert;
1199
1200 oldXPDoc = ctxt->xpathCtxt->doc;
1201
1202 ctxt->output = container;
1203 ctxt->insert = (xmlNodePtr) container;
1204
1205 ctxt->xpathCtxt->doc = ctxt->initialContextDoc;
1206 /*
1207 * Process the sequence constructor.
1208 */
1209 xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, NULL, NULL);
1210
1211 ctxt->xpathCtxt->doc = oldXPDoc;
1212
1213 ctxt->insert = oldInsert;
1214 ctxt->output = oldOutput;
1215
1216 result = xmlXPathNewValueTree((xmlNodePtr) container);
1217 if (result == NULL) {
1218 result = xmlXPathNewCString("");
1219 } else {
1220 result->boolval = 0; /* Freeing is not handled there anymore */
1221 }
1222#ifdef WITH_XSLT_DEBUG_VARIABLE
1223#ifdef LIBXML_DEBUG_ENABLED
1226 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
1227 result, 0);
1228#endif
1229#endif
1230 }
1231 }
1232
1233error:
1234 elem->name = oldVarName;
1235 ctxt->inst = oldInst;
1236 if (result != NULL) {
1237 elem->value = result;
1238 elem->computed = 1;
1239 }
1240 return(result);
1241}
void xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr list, xsltTemplatePtr templ ATTRIBUTE_UNUSED, xsltStackElemPtr params)
Definition: transform.c:3273
GLuint64EXT * result
Definition: glext.h:11304
#define stdout
Definition: stdio.h:99
#define stderr
Definition: stdio.h:100
#define error(str)
Definition: mkdosfs.c:1605
xmlNode * xmlNodePtr
Definition: tree.h:488
struct _xmlDoc * doc
Definition: tree.h:560
Definition: tree.h:489
struct _xmlDoc * doc
Definition: tree.h:498
Definition: tree.h:389
xsltTransformState state
xmlNodePtr initialContextNode
xmlXPathContextPtr xpathCtxt
XSLTPUBFUN void XSLTCALL xslHandleDebugger(xmlNodePtr cur, xmlNodePtr node, xsltTemplatePtr templ, xsltTransformContextPtr ctxt)
xmlDocPtr xsltCreateRVT(xsltTransformContextPtr ctxt)
Definition: variables.c:44
int xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
Definition: variables.c:394
static const xmlChar * xsltComputingGlobalVarMarker
Definition: variables.c:22
int xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val)
Definition: variables.c:237
#define XSLT_RVT_GLOBAL
Definition: variables.h:62
unsigned char xmlChar
Definition: xmlstring.h:28
@ XSLT_STATE_STOPPED
@ XSLT_DEBUG_NONE
Definition: xsltutils.h:273

Referenced by xsltEvalGlobalVariableWrapper(), and xsltGlobalVariableLookup().

◆ xsltEvalGlobalVariables()

int xsltEvalGlobalVariables ( xsltTransformContextPtr  ctxt)

xsltEvalGlobalVariables: @ctxt: the XSLT transformation context

Evaluates all global variables and parameters of a stylesheet. For internal use only. This is called at start of a transformation.

Returns 0 in case of success, -1 in case of error

Definition at line 1260 of file variables.c.

1260 {
1263
1264 if ((ctxt == NULL) || (ctxt->document == NULL))
1265 return(-1);
1266
1267#ifdef WITH_XSLT_DEBUG_VARIABLE
1269 "Registering global variables\n"));
1270#endif
1271 /*
1272 * Walk the list from the stylesheets and populate the hash table
1273 */
1274 style = ctxt->style;
1275 while (style != NULL) {
1276 elem = style->variables;
1277
1278#ifdef WITH_XSLT_DEBUG_VARIABLE
1279 if ((style->doc != NULL) && (style->doc->URL != NULL)) {
1281 "Registering global variables from %s\n",
1282 style->doc->URL));
1283 }
1284#endif
1285
1286 while (elem != NULL) {
1287 xsltStackElemPtr def;
1288
1289 /*
1290 * Global variables are stored in the variables pool.
1291 */
1292 def = (xsltStackElemPtr)
1294 elem->name, elem->nameURI);
1295 if (def == NULL) {
1296
1297 def = xsltCopyStackElem(elem);
1299 elem->name, elem->nameURI, def);
1300 } else if ((elem->comp != NULL) &&
1301 (elem->comp->type == XSLT_FUNC_VARIABLE)) {
1302 /*
1303 * Redefinition of variables from a different stylesheet
1304 * should not generate a message.
1305 */
1306 if ((elem->comp->inst != NULL) &&
1307 (def->comp != NULL) && (def->comp->inst != NULL) &&
1308 (elem->comp->inst->doc == def->comp->inst->doc))
1309 {
1310 xsltTransformError(ctxt, style, elem->comp->inst,
1311 "Global variable %s already defined\n", elem->name);
1312 if (style != NULL) style->errors++;
1313 }
1314 }
1315 elem = elem->next;
1316 }
1317
1319 }
1320
1321 /*
1322 * This part does the actual evaluation
1323 */
1325
1326 return(0);
1327}
Arabic default style
Definition: afstyles.h:94
xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur)
Definition: imports.c:251
XMLPUBFUN int XMLCALL xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, void *userdata)
Definition: hash.c:406
XMLPUBFUN void *XMLCALL xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2)
Definition: hash.c:476
XMLPUBFUN void XMLCALL xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data)
Definition: hash.c:859
xsltStylePreCompPtr comp
xsltDocumentPtr document
xmlHashTablePtr globalVars
xsltStylesheetPtr style
static xsltStackElemPtr xsltCopyStackElem(xsltStackElemPtr elem)
Definition: variables.c:516
static void xsltEvalGlobalVariableWrapper(void *payload, void *data, const xmlChar *name ATTRIBUTE_UNUSED)
Definition: variables.c:1244
@ XSLT_FUNC_VARIABLE

Referenced by xsltApplyStylesheetInternal().

◆ xsltEvalGlobalVariableWrapper()

static void xsltEvalGlobalVariableWrapper ( void payload,
void data,
const xmlChar *name  ATTRIBUTE_UNUSED 
)
static

Definition at line 1244 of file variables.c.

1245 {
1248}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static xmlXPathObjectPtr xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt)
Definition: variables.c:1032

Referenced by xsltEvalGlobalVariables().

◆ xsltEvalOneUserParam()

int xsltEvalOneUserParam ( xsltTransformContextPtr  ctxt,
const xmlChar name,
const xmlChar value 
)

Definition at line 1727 of file variables.c.

1729 {
1731 1 /* xpath eval ? */);
1732}
Definition: pdh_main.c:94
static int xsltProcessUserParamInternal(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *value, int eval)
Definition: variables.c:1438

Referenced by xsltEvalUserParams().

◆ xsltEvalUserParams()

int xsltEvalUserParams ( xsltTransformContextPtr  ctxt,
const char **  params 
)

xsltEvalUserParams:

@ctxt: the XSLT transformation context @params: a NULL terminated array of parameters name/value tuples

Evaluate the global variables of a stylesheet. This needs to be done on parsed stylesheets before starting to apply transformations. Each of the parameters is evaluated as an XPath expression and stored in the global variables/parameter hash table. If you want your parameter used literally, use xsltQuoteUserParams.

Returns 0 in case of success, -1 in case of error

Definition at line 1662 of file variables.c.

1662 {
1663 int indx = 0;
1664 const xmlChar *name;
1665 const xmlChar *value;
1666
1667 if (params == NULL)
1668 return(0);
1669 while (params[indx] != NULL) {
1670 name = (const xmlChar *) params[indx++];
1671 value = (const xmlChar *) params[indx++];
1672 if (xsltEvalOneUserParam(ctxt, name, value) != 0)
1673 return(-1);
1674 }
1675 return 0;
1676}
GLenum const GLfloat * params
Definition: glext.h:5645
int xsltEvalOneUserParam(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *value)
Definition: variables.c:1727

Referenced by xsltApplyStylesheetInternal().

◆ xsltEvalVariable()

static xmlXPathObjectPtr xsltEvalVariable ( xsltTransformContextPtr  ctxt,
xsltStackElemPtr  variable,
xsltStylePreCompPtr  castedComp 
)
static

xsltEvalVariable: @ctxt: the XSLT transformation context @variable: the variable or parameter item @comp: the compiled XSLT instruction

Evaluate a variable value.

Returns the XPath Object value or NULL in case of error

Definition at line 799 of file variables.c.

801{
802#ifdef XSLT_REFACTORED
803 xsltStyleItemVariablePtr comp =
804 (xsltStyleItemVariablePtr) castedComp;
805#else
806 xsltStylePreCompPtr comp = castedComp;
807#endif
808 xmlXPathObjectPtr result = NULL;
809 xmlNodePtr oldInst;
810
811 if ((ctxt == NULL) || (variable == NULL))
812 return(NULL);
813
814 /*
815 * A variable or parameter are evaluated on demand; thus the
816 * context (of XSLT and XPath) need to be temporarily adjusted and
817 * restored on exit.
818 */
819 oldInst = ctxt->inst;
820
821#ifdef WITH_XSLT_DEBUG_VARIABLE
823 "Evaluating variable '%s'\n", variable->name));
824#endif
825 if (variable->select != NULL) {
826 xmlXPathCompExprPtr xpExpr = NULL;
827 xmlDocPtr oldXPDoc;
828 xmlNodePtr oldXPContextNode;
829 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
830 xmlNsPtr *oldXPNamespaces;
831 xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
832 xsltStackElemPtr oldVar = ctxt->contextVariable;
833
834 if ((comp != NULL) && (comp->comp != NULL)) {
835 xpExpr = comp->comp;
836 } else {
837 xpExpr = xmlXPathCtxtCompile(ctxt->xpathCtxt, variable->select);
838 }
839 if (xpExpr == NULL)
840 return(NULL);
841 /*
842 * Save context states.
843 */
844 oldXPDoc = xpctxt->doc;
845 oldXPContextNode = xpctxt->node;
846 oldXPProximityPosition = xpctxt->proximityPosition;
847 oldXPContextSize = xpctxt->contextSize;
848 oldXPNamespaces = xpctxt->namespaces;
849 oldXPNsNr = xpctxt->nsNr;
850
851 xpctxt->node = ctxt->node;
852 /*
853 * OPTIMIZE TODO: Lame try to set the context doc.
854 * Get rid of this somehow in xpath.c.
855 */
856 if ((ctxt->node->type != XML_NAMESPACE_DECL) &&
857 ctxt->node->doc)
858 xpctxt->doc = ctxt->node->doc;
859 /*
860 * BUG TODO: The proximity position and the context size will
861 * potentially be wrong.
862 * Example:
863 * <xsl:template select="foo">
864 * <xsl:variable name="pos" select="position()"/>
865 * <xsl:for-each select="bar">
866 * <xsl:value-of select="$pos"/>
867 * </xsl:for-each>
868 * </xsl:template>
869 * Here the proximity position and context size are changed
870 * to the context of <xsl:for-each select="bar">, but
871 * the variable needs to be evaluated in the context of
872 * <xsl:template select="foo">.
873 */
874 if (comp != NULL) {
875
876#ifdef XSLT_REFACTORED
877 if (comp->inScopeNs != NULL) {
878 xpctxt->namespaces = comp->inScopeNs->list;
879 xpctxt->nsNr = comp->inScopeNs->xpathNumber;
880 } else {
881 xpctxt->namespaces = NULL;
882 xpctxt->nsNr = 0;
883 }
884#else
885 xpctxt->namespaces = comp->nsList;
886 xpctxt->nsNr = comp->nsNr;
887#endif
888 } else {
889 xpctxt->namespaces = NULL;
890 xpctxt->nsNr = 0;
891 }
892
893 /*
894 * We need to mark that we are "selecting" a var's value;
895 * if any tree fragments are created inside the expression,
896 * then those need to be stored inside the variable; otherwise
897 * we'll eventually free still referenced fragments, before
898 * we leave the scope of the variable.
899 */
902
903 result = xmlXPathCompiledEval(xpExpr, xpctxt);
904
906 /*
907 * Restore Context states.
908 */
909 ctxt->contextVariable = oldVar;
910
911 xpctxt->doc = oldXPDoc;
912 xpctxt->node = oldXPContextNode;
913 xpctxt->contextSize = oldXPContextSize;
914 xpctxt->proximityPosition = oldXPProximityPosition;
915 xpctxt->namespaces = oldXPNamespaces;
916 xpctxt->nsNr = oldXPNsNr;
917
918 if ((comp == NULL) || (comp->comp == NULL))
919 xmlXPathFreeCompExpr(xpExpr);
920 if (result == NULL) {
922 (comp != NULL) ? comp->inst : NULL,
923 "Failed to evaluate the expression of variable '%s'.\n",
924 variable->name);
926
927#ifdef WITH_XSLT_DEBUG_VARIABLE
928#ifdef LIBXML_DEBUG_ENABLED
929 } else {
932 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
933 result, 0);
934#endif
935#endif
936 }
937 } else {
938 if (variable->tree == NULL) {
939 result = xmlXPathNewCString("");
940 } else {
941 if (variable->tree) {
943 xmlNodePtr oldInsert;
944 xmlDocPtr oldOutput;
945 const xmlChar *oldLastText;
946 int oldLastTextSize, oldLastTextUse;
947 xsltStackElemPtr oldVar = ctxt->contextVariable;
948
949 /*
950 * Generate a result tree fragment.
951 */
952 container = xsltCreateRVT(ctxt);
953 if (container == NULL)
954 goto error;
955 /*
956 * NOTE: Local Result Tree Fragments of params/variables
957 * are not registered globally anymore; the life-time
958 * is not directly dependant of the param/variable itself.
959 *
960 * OLD: xsltRegisterTmpRVT(ctxt, container);
961 */
962 /*
963 * Attach the Result Tree Fragment to the variable;
964 * when the variable is freed, it will also free
965 * the Result Tree Fragment.
966 */
967 variable->fragment = container;
969
970 oldOutput = ctxt->output;
971 oldInsert = ctxt->insert;
972 oldLastText = ctxt->lasttext;
973 oldLastTextSize = ctxt->lasttsize;
974 oldLastTextUse = ctxt->lasttuse;
975
976 ctxt->output = container;
977 ctxt->insert = (xmlNodePtr) container;
979 /*
980 * Process the sequence constructor (variable->tree).
981 * The resulting tree will be held by @container.
982 */
983 xsltApplyOneTemplate(ctxt, ctxt->node, variable->tree,
984 NULL, NULL);
985
986 ctxt->contextVariable = oldVar;
987 ctxt->insert = oldInsert;
988 ctxt->output = oldOutput;
989 ctxt->lasttext = oldLastText;
990 ctxt->lasttsize = oldLastTextSize;
991 ctxt->lasttuse = oldLastTextUse;
992
993 result = xmlXPathNewValueTree((xmlNodePtr) container);
994 }
995 if (result == NULL) {
996 result = xmlXPathNewCString("");
997 } else {
998 /*
999 * Freeing is not handled there anymore.
1000 * QUESTION TODO: What does the above comment mean?
1001 */
1002 result->boolval = 0;
1003 }
1004#ifdef WITH_XSLT_DEBUG_VARIABLE
1005#ifdef LIBXML_DEBUG_ENABLED
1006
1009 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
1010 result, 0);
1011#endif
1012#endif
1013 }
1014 }
1015
1016error:
1017 ctxt->inst = oldInst;
1018 return(result);
1019}
GLenum GLenum variable
Definition: glext.h:9031
@ XML_NAMESPACE_DECL
Definition: tree.h:177
xmlElementType type
Definition: tree.h:491
const xmlChar * lasttext
char * name
Definition: compiler.c:66
#define XSLT_VAR_IN_SELECT
Definition: variables.c:26
#define XSLT_RVT_LOCAL
Definition: variables.h:46

Referenced by xsltBuildVariable(), xsltVariableLookup(), and xsltXPathVariableLookup().

◆ xsltExtensionInstructionResultFinalize()

int xsltExtensionInstructionResultFinalize ( xsltTransformContextPtr ctxt  ATTRIBUTE_UNUSED)

xsltExtensionInstructionResultFinalize: @ctxt: an XSLT transformation context

Finalizes the data (e.g. result tree fragments) created within a value-returning process (e.g. EXSLT's function). Tree fragments marked as being returned by a function are set to normal state, which means that the fragment garbage collector will free them after the function-calling process exits.

Returns 0 in case of success and -1 in case of API or internal errors.

This function is unsupported in newer releases of libxslt.

Definition at line 187 of file variables.c.

189{
191 "xsltExtensionInstructionResultFinalize is unsupported "
192 "in this release of libxslt.\n");
193 return(-1);
194}

◆ xsltExtensionInstructionResultRegister()

int xsltExtensionInstructionResultRegister ( xsltTransformContextPtr ctxt  ATTRIBUTE_UNUSED,
xmlXPathObjectPtr obj  ATTRIBUTE_UNUSED 
)

xsltExtensionInstructionResultRegister: @ctxt: an XSLT transformation context @obj: an XPath object to be inspected for result tree fragments

Marks the result of a value-returning extension instruction in order to avoid it being garbage collected before the extension instruction exits. Note that one still has to additionally register any newly created tree fragments (via xsltCreateRVT()) with xsltRegisterLocalRVT().

Returns 0 in case of success and -1 in case of error.

It isn't necessary to call this function in newer releases of libxslt.

Definition at line 213 of file variables.c.

216{
217 return(0);
218}

◆ xsltFlagRVTs()

int xsltFlagRVTs ( xsltTransformContextPtr  ctxt,
xmlXPathObjectPtr  obj,
void val 
)

xsltFlagRVTs: @ctxt: an XSLT transformation context @obj: an XPath object to be inspected for result tree fragments @val: the flag value

Updates ownership information of RVTs in @obj according to @val.

@val = XSLT_RVT_FUNC_RESULT for the result of an extension function, so its RVTs won't be destroyed after leaving the returning scope. @val = XSLT_RVT_LOCAL for the result of an extension function to reset the state of its RVTs after it was returned to a new scope. @val = XSLT_RVT_GLOBAL for parts of global variables.

Returns 0 in case of success and -1 in case of error.

Definition at line 237 of file variables.c.

237 {
238 int i;
240 xmlDocPtr doc;
241
242 if ((ctxt == NULL) || (obj == NULL))
243 return(-1);
244
245 /*
246 * OPTIMIZE TODO: If no local variables/params and no local tree
247 * fragments were created, then we don't need to analyse the XPath
248 * objects for tree fragments.
249 */
250
251 if ((obj->type != XPATH_NODESET) && (obj->type != XPATH_XSLT_TREE))
252 return(0);
253 if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0))
254 return(0);
255
256 for (i = 0; i < obj->nodesetval->nodeNr; i++) {
257 cur = obj->nodesetval->nodeTab[i];
258 if (cur->type == XML_NAMESPACE_DECL) {
259 /*
260 * The XPath module sets the owner element of a ns-node on
261 * the ns->next field.
262 */
263 if ((((xmlNsPtr) cur)->next != NULL) &&
264 (((xmlNsPtr) cur)->next->type == XML_ELEMENT_NODE))
265 {
266 cur = (xmlNodePtr) ((xmlNsPtr) cur)->next;
267 doc = cur->doc;
268 } else {
269 xsltTransformError(ctxt, NULL, ctxt->inst,
270 "Internal error in xsltFlagRVTs(): "
271 "Cannot retrieve the doc of a namespace node.\n");
272 return(-1);
273 }
274 } else {
275 doc = cur->doc;
276 }
277 if (doc == NULL) {
278 xsltTransformError(ctxt, NULL, ctxt->inst,
279 "Internal error in xsltFlagRVTs(): "
280 "Cannot retrieve the doc of a node.\n");
281 return(-1);
282 }
283 if (doc->name && (doc->name[0] == ' ') &&
284 doc->psvi != XSLT_RVT_GLOBAL) {
285 /*
286 * This is a result tree fragment.
287 * We store ownership information in the @psvi field.
288 * TODO: How do we know if this is a doc acquired via the
289 * document() function?
290 */
291#ifdef WITH_XSLT_DEBUG_VARIABLE
293 "Flagging RVT %p: %p -> %p\n", doc, doc->psvi, val));
294#endif
295
296 if (val == XSLT_RVT_LOCAL) {
297 if (doc->psvi == XSLT_RVT_FUNC_RESULT)
298 doc->psvi = XSLT_RVT_LOCAL;
299 } else if (val == XSLT_RVT_GLOBAL) {
300 if (doc->psvi != XSLT_RVT_LOCAL) {
302 "xsltFlagRVTs: Invalid transition %p => GLOBAL\n",
303 doc->psvi);
304 doc->psvi = XSLT_RVT_GLOBAL;
305 return(-1);
306 }
307
308 /* Will be registered as persistant in xsltReleaseLocalRVTs. */
309 doc->psvi = XSLT_RVT_GLOBAL;
310 } else if (val == XSLT_RVT_FUNC_RESULT) {
311 doc->psvi = val;
312 }
313 }
314 }
315
316 return(0);
317}
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static unsigned __int64 next
Definition: rand_nt.c:6
@ XML_ELEMENT_NODE
Definition: tree.h:160
char * name
Definition: tree.h:554
void * psvi
Definition: tree.h:581
#define XSLT_RVT_FUNC_RESULT
Definition: variables.h:55

Referenced by xsltEvalGlobalVariable().

◆ xsltFreeGlobalVariables()

void xsltFreeGlobalVariables ( xsltTransformContextPtr  ctxt)

xsltFreeGlobalVariables: @ctxt: the XSLT transformation context

Free up the data associated to the global variables its value.

Definition at line 2227 of file variables.c.

2227 {
2229}
XMLPUBFUN void XMLCALL xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f)
Definition: hash.c:322
static void xsltFreeStackElemEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
Definition: variables.c:591

Referenced by xsltFreeTransformContext().

◆ xsltFreeRVTs()

void xsltFreeRVTs ( xsltTransformContextPtr  ctxt)

xsltFreeRVTs: @ctxt: an XSLT transformation context

Frees all registered result value trees (Result Tree Fragments) of the transformation. Internal function; should not be called by user-code.

Definition at line 416 of file variables.c.

417{
419
420 if (ctxt == NULL)
421 return;
422 /*
423 * Local fragments.
424 */
425 cur = ctxt->localRVT;
426 while (cur != NULL) {
427 next = (xmlDocPtr) cur->next;
428 if (cur->_private != NULL) {
429 xsltFreeDocumentKeys(cur->_private);
430 xmlFree(cur->_private);
431 }
433 cur = next;
434 }
435 ctxt->localRVT = NULL;
436 /*
437 * User-created per-template fragments.
438 */
439 cur = ctxt->tmpRVT;
440 while (cur != NULL) {
441 next = (xmlDocPtr) cur->next;
442 if (cur->_private != NULL) {
443 xsltFreeDocumentKeys(cur->_private);
444 xmlFree(cur->_private);
445 }
447 cur = next;
448 }
449 ctxt->tmpRVT = NULL;
450 /*
451 * Global fragments.
452 */
453 cur = ctxt->persistRVT;
454 while (cur != NULL) {
455 next = (xmlDocPtr) cur->next;
456 if (cur->_private != NULL) {
457 xsltFreeDocumentKeys(cur->_private);
458 xmlFree(cur->_private);
459 }
461 cur = next;
462 }
463 ctxt->persistRVT = NULL;
464}
void xsltFreeDocumentKeys(xsltDocumentPtr idoc)
Definition: keys.c:925
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBFUN void XMLCALL xmlFreeDoc(xmlDocPtr cur)

Referenced by xsltApplyStylesheetInternal(), and xsltFreeTransformContext().

◆ xsltFreeStackElem()

static void xsltFreeStackElem ( xsltStackElemPtr  elem)
static

xsltFreeStackElem: @elem: an XSLT stack element

Free up the memory allocated by @elem

Definition at line 542 of file variables.c.

542 {
543 if (elem == NULL)
544 return;
545 if (elem->value != NULL)
546 xmlXPathFreeObject(elem->value);
547 /*
548 * Release the list of temporary Result Tree Fragments.
549 */
550 if (elem->context) {
552
553 while (elem->fragment != NULL) {
554 cur = elem->fragment;
555 elem->fragment = (xmlDocPtr) cur->next;
556
557 if (cur->psvi == XSLT_RVT_LOCAL) {
558 xsltReleaseRVT(elem->context, cur);
559 } else if (cur->psvi == XSLT_RVT_FUNC_RESULT) {
560 xsltRegisterLocalRVT(elem->context, cur);
562 } else {
564 "xsltFreeStackElem: Unexpected RVT flag %p\n",
565 cur->psvi);
566 }
567 }
568 }
569 /*
570 * Cache or free the variable structure.
571 */
572 if (elem->context && (elem->context->cache->nbStackItems < 50)) {
573 /*
574 * Store the item in the cache.
575 */
576 xsltTransformContextPtr ctxt = elem->context;
577 memset(elem, 0, sizeof(xsltStackElem));
578 elem->context = ctxt;
579 elem->next = ctxt->cache->stackItems;
580 ctxt->cache->stackItems = elem;
581 ctxt->cache->nbStackItems++;
582#ifdef XSLT_DEBUG_PROFILE_CACHE
583 ctxt->cache->dbgCachedVars++;
584#endif
585 return;
586 }
587 xmlFree(elem);
588}
xsltStackElemPtr stackItems
int xsltRegisterLocalRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
Definition: variables.c:138
void xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
Definition: variables.c:328

Referenced by xsltFreeStackElemEntry(), xsltFreeStackElemList(), and xsltProcessUserParamInternal().

◆ xsltFreeStackElemEntry()

static void xsltFreeStackElemEntry ( void payload,
const xmlChar *name  ATTRIBUTE_UNUSED 
)
static

Definition at line 591 of file variables.c.

591 {
593}
static void xsltFreeStackElem(xsltStackElemPtr elem)
Definition: variables.c:542

Referenced by xsltFreeGlobalVariables().

◆ xsltFreeStackElemList()

void xsltFreeStackElemList ( xsltStackElemPtr  elem)

xsltFreeStackElemList: @elem: an XSLT stack element

Free up the memory allocated by @elem

Definition at line 603 of file variables.c.

603 {
605
606 while (elem != NULL) {
607 next = elem->next;
609 elem = next;
610 }
611}

Referenced by xsltApplyStylesheetInternal(), xsltApplyTemplates(), xsltCallTemplate(), xsltFreeStylesheet(), xsltLocalVariablePop(), and xsltTemplateParamsCleanup().

◆ xsltGlobalVariableLookup()

static xmlXPathObjectPtr xsltGlobalVariableLookup ( xsltTransformContextPtr  ctxt,
const xmlChar name,
const xmlChar ns_uri 
)
static

Definition at line 1873 of file variables.c.

1874 {
1876 xmlXPathObjectPtr ret = NULL;
1877
1878 /*
1879 * Lookup the global variables in XPath global variable hash table
1880 */
1881 if ((ctxt->xpathCtxt == NULL) || (ctxt->globalVars == NULL))
1882 return(NULL);
1884 xmlHashLookup2(ctxt->globalVars, name, ns_uri);
1885 if (elem == NULL) {
1886#ifdef WITH_XSLT_DEBUG_VARIABLE
1888 "global variable not found %s\n", name));
1889#endif
1890 return(NULL);
1891 }
1892 /*
1893 * URGENT TODO: Move the detection of recursive definitions
1894 * to compile-time.
1895 */
1896 if (elem->computed == 0) {
1897 if (elem->name == xsltComputingGlobalVarMarker) {
1898 xsltTransformError(ctxt, NULL, elem->comp->inst,
1899 "Recursive definition of %s\n", name);
1900 return(NULL);
1901 }
1903 } else
1904 ret = elem->value;
1905 return(xmlXPathObjectCopy(ret));
1906}
int ret

Referenced by xsltVariableLookup(), and xsltXPathVariableLookup().

◆ xsltNewStackElem()

static xsltStackElemPtr xsltNewStackElem ( xsltTransformContextPtr  ctxt)
static

xsltNewStackElem:

Create a new XSLT ParserContext

Returns the newly allocated xsltParserStackElem or NULL in case of error

Definition at line 480 of file variables.c.

481{
483 /*
484 * Reuse a stack item from the cache if available.
485 */
486 if (ctxt && ctxt->cache->stackItems) {
487 ret = ctxt->cache->stackItems;
488 ctxt->cache->stackItems = ret->next;
489 ret->next = NULL;
490 ctxt->cache->nbStackItems--;
491#ifdef XSLT_DEBUG_PROFILE_CACHE
492 ctxt->cache->dbgReusedVars++;
493#endif
494 return(ret);
495 }
497 if (ret == NULL) {
499 "xsltNewStackElem : malloc failed\n");
500 return(NULL);
501 }
502 memset(ret, 0, sizeof(xsltStackElem));
503 ret->context = ctxt;
504 return(ret);
505}

Referenced by xsltBuildVariable(), xsltProcessUserParamInternal(), and xsltRegisterGlobalVariable().

◆ xsltParseGlobalParam()

void xsltParseGlobalParam ( xsltStylesheetPtr  style,
xmlNodePtr  cur 
)

xsltParseGlobalParam: @style: the XSLT stylesheet @cur: the "param" element

parse an XSLT transformation param declaration and record its value.

Definition at line 2087 of file variables.c.

2087 {
2088#ifdef XSLT_REFACTORED
2089 xsltStyleItemParamPtr comp;
2090#else
2092#endif
2093
2094 if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE))
2095 return;
2096
2097#ifdef XSLT_REFACTORED
2098 /*
2099 * Note that xsltStylePreCompute() will be called from
2100 * xslt.c only.
2101 */
2102 comp = (xsltStyleItemParamPtr) cur->psvi;
2103#else
2105 comp = (xsltStylePreCompPtr) cur->psvi;
2106#endif
2107 if (comp == NULL) {
2109 "xsl:param : compilation failed\n");
2110 return;
2111 }
2112
2113 if (comp->name == NULL) {
2115 "xsl:param : missing name attribute\n");
2116 return;
2117 }
2118
2119 /*
2120 * Parse the content (a sequence constructor) of xsl:param.
2121 */
2122 if (cur->children != NULL) {
2123#ifdef XSLT_REFACTORED
2124 xsltParseSequenceConstructor(XSLT_CCTXT(style), cur->children);
2125#else
2127#endif
2128 }
2129
2130#ifdef WITH_XSLT_DEBUG_VARIABLE
2132 "Registering global param %s\n", comp->name);
2133#endif
2134
2135 xsltRegisterGlobalVariable(style, comp->name, comp->ns,
2136 comp->select, cur->children, (xsltStylePreCompPtr) comp,
2137 NULL);
2138}
void xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst)
Definition: preproc.c:2177
static int xsltRegisterGlobalVariable(xsltStylesheetPtr style, const xmlChar *name, const xmlChar *ns_uri, const xmlChar *sel, xmlNodePtr tree, xsltStylePreCompPtr comp, const xmlChar *value)
Definition: variables.c:1345
void xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ)
Definition: xslt.c:4878

Referenced by xsltParseStylesheetTop().

◆ xsltParseGlobalVariable()

void xsltParseGlobalVariable ( xsltStylesheetPtr  style,
xmlNodePtr  cur 
)

xsltParseGlobalVariable: @style: the XSLT stylesheet @cur: the "variable" element

Parses a global XSLT 'variable' declaration at compilation time and registers it

Definition at line 2024 of file variables.c.

2025{
2026#ifdef XSLT_REFACTORED
2027 xsltStyleItemVariablePtr comp;
2028#else
2030#endif
2031
2032 if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE))
2033 return;
2034
2035#ifdef XSLT_REFACTORED
2036 /*
2037 * Note that xsltStylePreCompute() will be called from
2038 * xslt.c only.
2039 */
2040 comp = (xsltStyleItemVariablePtr) cur->psvi;
2041#else
2043 comp = (xsltStylePreCompPtr) cur->psvi;
2044#endif
2045 if (comp == NULL) {
2047 "xsl:variable : compilation failed\n");
2048 return;
2049 }
2050
2051 if (comp->name == NULL) {
2053 "xsl:variable : missing name attribute\n");
2054 return;
2055 }
2056
2057 /*
2058 * Parse the content (a sequence constructor) of xsl:variable.
2059 */
2060 if (cur->children != NULL) {
2061#ifdef XSLT_REFACTORED
2062 xsltParseSequenceConstructor(XSLT_CCTXT(style), cur->children);
2063#else
2065#endif
2066 }
2067#ifdef WITH_XSLT_DEBUG_VARIABLE
2069 "Registering global variable %s\n", comp->name);
2070#endif
2071
2072 xsltRegisterGlobalVariable(style, comp->name, comp->ns,
2073 comp->select, cur->children, (xsltStylePreCompPtr) comp,
2074 NULL);
2075}

Referenced by xsltParseStylesheetTop().

◆ xsltParseStylesheetCallerParam()

xsltStackElemPtr xsltParseStylesheetCallerParam ( xsltTransformContextPtr  ctxt,
xmlNodePtr  inst 
)

xsltParseStylesheetCallerParam: @ctxt: the XSLT transformation context @inst: the xsl:with-param instruction element

Processes an xsl:with-param instruction at transformation time. The value is computed, but not recorded. NOTE that this is also called with an xsl:param element from exsltFuncFunctionFunction().

Returns the new xsltStackElemPtr or NULL

Definition at line 1962 of file variables.c.

1963{
1964#ifdef XSLT_REFACTORED
1965 xsltStyleBasicItemVariablePtr comp;
1966#else
1968#endif
1969 xmlNodePtr tree = NULL; /* The first child node of the instruction or
1970 the instruction itself. */
1972
1973 if ((ctxt == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1974 return(NULL);
1975
1976#ifdef XSLT_REFACTORED
1977 comp = (xsltStyleBasicItemVariablePtr) inst->psvi;
1978#else
1979 comp = (xsltStylePreCompPtr) inst->psvi;
1980#endif
1981
1982 if (comp == NULL) {
1983 xsltTransformError(ctxt, NULL, inst,
1984 "Internal error in xsltParseStylesheetCallerParam(): "
1985 "The XSLT 'with-param' instruction was not compiled.\n");
1986 return(NULL);
1987 }
1988 if (comp->name == NULL) {
1989 xsltTransformError(ctxt, NULL, inst,
1990 "Internal error in xsltParseStylesheetCallerParam(): "
1991 "XSLT 'with-param': The attribute 'name' was not compiled.\n");
1992 return(NULL);
1993 }
1994
1995#ifdef WITH_XSLT_DEBUG_VARIABLE
1997 "Handling xsl:with-param %s\n", comp->name));
1998#endif
1999
2000 if (comp->select == NULL) {
2001 tree = inst->children;
2002 } else {
2003#ifdef WITH_XSLT_DEBUG_VARIABLE
2005 " select %s\n", comp->select));
2006#endif
2007 tree = inst;
2008 }
2009
2011
2012 return(param);
2013}
GLfloat param
Definition: glext.h:5796
struct _xmlNode * children
Definition: tree.h:493
void * psvi
Definition: tree.h:505
static xsltStackElemPtr xsltBuildVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr castedComp, xmlNodePtr tree)
Definition: variables.c:1766

Referenced by xsltApplyTemplates(), and xsltCallTemplate().

◆ xsltParseStylesheetParam()

void xsltParseStylesheetParam ( xsltTransformContextPtr  ctxt,
xmlNodePtr  cur 
)

xsltParseStylesheetParam: @ctxt: the XSLT transformation context @cur: the XSLT 'param' element

Registers a local XSLT 'param' declaration at transformation time and evaluates its value.

Definition at line 2191 of file variables.c.

2192{
2193#ifdef XSLT_REFACTORED
2194 xsltStyleItemParamPtr comp;
2195#else
2197#endif
2198
2199 if ((cur == NULL) || (ctxt == NULL) || (cur->type != XML_ELEMENT_NODE))
2200 return;
2201
2202 comp = cur->psvi;
2203 if ((comp == NULL) || (comp->name == NULL)) {
2205 "Internal error in xsltParseStylesheetParam(): "
2206 "The XSLT 'param' declaration was not compiled correctly.\n");
2207 return;
2208 }
2209
2210#ifdef WITH_XSLT_DEBUG_VARIABLE
2212 "Registering param %s\n", comp->name));
2213#endif
2214
2215 xsltRegisterVariable(ctxt, (xsltStylePreCompPtr) comp, cur->children, 1);
2216}
static int xsltRegisterVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr castedComp, xmlNodePtr tree, int isParam)
Definition: variables.c:1813

Referenced by xsltApplyXSLTTemplate().

◆ xsltParseStylesheetVariable()

void xsltParseStylesheetVariable ( xsltTransformContextPtr  ctxt,
xmlNodePtr  inst 
)

xsltParseStylesheetVariable: @ctxt: the XSLT transformation context @inst: the xsl:variable instruction element

Registers a local XSLT 'variable' instruction at transformation time and evaluates its value.

Definition at line 2149 of file variables.c.

2150{
2151#ifdef XSLT_REFACTORED
2152 xsltStyleItemVariablePtr comp;
2153#else
2155#endif
2156
2157 if ((inst == NULL) || (ctxt == NULL) || (inst->type != XML_ELEMENT_NODE))
2158 return;
2159
2160 comp = inst->psvi;
2161 if (comp == NULL) {
2162 xsltTransformError(ctxt, NULL, inst,
2163 "Internal error in xsltParseStylesheetVariable(): "
2164 "The XSLT 'variable' instruction was not compiled.\n");
2165 return;
2166 }
2167 if (comp->name == NULL) {
2168 xsltTransformError(ctxt, NULL, inst,
2169 "Internal error in xsltParseStylesheetVariable(): "
2170 "The attribute 'name' was not compiled.\n");
2171 return;
2172 }
2173
2174#ifdef WITH_XSLT_DEBUG_VARIABLE
2176 "Registering variable '%s'\n", comp->name));
2177#endif
2178
2179 xsltRegisterVariable(ctxt, (xsltStylePreCompPtr) comp, inst->children, 0);
2180}

Referenced by xsltApplySequenceConstructor().

◆ xsltProcessUserParamInternal()

static int xsltProcessUserParamInternal ( xsltTransformContextPtr  ctxt,
const xmlChar name,
const xmlChar value,
int  eval 
)
static

Definition at line 1438 of file variables.c.

1441 {
1442
1444 const xmlChar *prefix;
1445 const xmlChar *href;
1446 xmlXPathCompExprPtr xpExpr;
1447 xmlXPathObjectPtr result;
1448
1450 int res;
1451 void *res_ptr;
1452
1453 if (ctxt == NULL)
1454 return(-1);
1455 if (name == NULL)
1456 return(0);
1457 if (value == NULL)
1458 return(0);
1459
1460 style = ctxt->style;
1461
1462#ifdef WITH_XSLT_DEBUG_VARIABLE
1464 "Evaluating user parameter %s=%s\n", name, value));
1465#endif
1466
1467 /*
1468 * Name lookup
1469 */
1470 href = NULL;
1471
1472 if (name[0] == '{') {
1473 int len = 0;
1474
1475 while ((name[len] != 0) && (name[len] != '}')) len++;
1476 if (name[len] == 0) {
1478 "user param : malformed parameter name : %s\n", name);
1479 } else {
1480 href = xmlDictLookup(ctxt->dict, &name[1], len-1);
1481 name = xmlDictLookup(ctxt->dict, &name[len + 1], -1);
1482 }
1483 }
1484 else {
1485 name = xsltSplitQName(ctxt->dict, name, &prefix);
1486 if (prefix != NULL) {
1487 xmlNsPtr ns;
1488
1490 prefix);
1491 if (ns == NULL) {
1493 "user param : no namespace bound to prefix %s\n", prefix);
1494 href = NULL;
1495 } else {
1496 href = ns->href;
1497 }
1498 }
1499 }
1500
1501 if (name == NULL)
1502 return (-1);
1503
1504 res_ptr = xmlHashLookup2(ctxt->globalVars, name, href);
1505 if (res_ptr != 0) {
1507 "Global parameter %s already defined\n", name);
1508 }
1509 if (ctxt->globalVars == NULL)
1510 ctxt->globalVars = xmlHashCreate(20);
1511
1512 /*
1513 * do not overwrite variables with parameters from the command line
1514 */
1515 while (style != NULL) {
1516 elem = ctxt->style->variables;
1517 while (elem != NULL) {
1518 if ((elem->comp != NULL) &&
1519 (elem->comp->type == XSLT_FUNC_VARIABLE) &&
1520 (xmlStrEqual(elem->name, name)) &&
1521 (xmlStrEqual(elem->nameURI, href))) {
1522 return(0);
1523 }
1524 elem = elem->next;
1525 }
1527 }
1528 style = ctxt->style;
1529 elem = NULL;
1530
1531 /*
1532 * Do the evaluation if @eval is non-zero.
1533 */
1534
1535 result = NULL;
1536 if (eval != 0) {
1537 xpExpr = xmlXPathCtxtCompile(ctxt->xpathCtxt, value);
1538 if (xpExpr != NULL) {
1539 xmlDocPtr oldXPDoc;
1540 xmlNodePtr oldXPContextNode;
1541 int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
1542 xmlNsPtr *oldXPNamespaces;
1543 xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
1544
1545 /*
1546 * Save context states.
1547 */
1548 oldXPDoc = xpctxt->doc;
1549 oldXPContextNode = xpctxt->node;
1550 oldXPProximityPosition = xpctxt->proximityPosition;
1551 oldXPContextSize = xpctxt->contextSize;
1552 oldXPNamespaces = xpctxt->namespaces;
1553 oldXPNsNr = xpctxt->nsNr;
1554
1555 /*
1556 * SPEC XSLT 1.0:
1557 * "At top-level, the expression or template specifying the
1558 * variable value is evaluated with the same context as that used
1559 * to process the root node of the source document: the current
1560 * node is the root node of the source document and the current
1561 * node list is a list containing just the root node of the source
1562 * document."
1563 */
1564 xpctxt->doc = ctxt->initialContextDoc;
1565 xpctxt->node = ctxt->initialContextNode;
1566 xpctxt->contextSize = 1;
1567 xpctxt->proximityPosition = 1;
1568 /*
1569 * There is really no in scope namespace for parameters on the
1570 * command line.
1571 */
1572 xpctxt->namespaces = NULL;
1573 xpctxt->nsNr = 0;
1574
1575 result = xmlXPathCompiledEval(xpExpr, xpctxt);
1576
1577 /*
1578 * Restore Context states.
1579 */
1580 xpctxt->doc = oldXPDoc;
1581 xpctxt->node = oldXPContextNode;
1582 xpctxt->contextSize = oldXPContextSize;
1583 xpctxt->proximityPosition = oldXPProximityPosition;
1584 xpctxt->namespaces = oldXPNamespaces;
1585 xpctxt->nsNr = oldXPNsNr;
1586
1587 xmlXPathFreeCompExpr(xpExpr);
1588 }
1589 if (result == NULL) {
1591 "Evaluating user parameter %s failed\n", name);
1592 ctxt->state = XSLT_STATE_STOPPED;
1593 return(-1);
1594 }
1595 }
1596
1597 /*
1598 * If @eval is 0 then @value is to be taken literally and result is NULL
1599 *
1600 * If @eval is not 0, then @value is an XPath expression and has been
1601 * successfully evaluated and result contains the resulting value and
1602 * is not NULL.
1603 *
1604 * Now create an xsltStackElemPtr for insertion into the context's
1605 * global variable/parameter hash table.
1606 */
1607
1608#ifdef WITH_XSLT_DEBUG_VARIABLE
1609#ifdef LIBXML_DEBUG_ENABLED
1612 xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
1613 result, 0);
1614#endif
1615#endif
1616
1618 if (elem != NULL) {
1619 elem->name = name;
1620 elem->select = xmlDictLookup(ctxt->dict, value, -1);
1621 if (href != NULL)
1622 elem->nameURI = xmlDictLookup(ctxt->dict, href, -1);
1623 elem->tree = NULL;
1624 elem->computed = 1;
1625 if (eval == 0) {
1626 elem->value = xmlXPathNewString(value);
1627 }
1628 else {
1629 elem->value = result;
1630 }
1631 }
1632
1633 /*
1634 * Global parameters are stored in the XPath context variables pool.
1635 */
1636
1637 res = xmlHashAddEntry2(ctxt->globalVars, name, href, elem);
1638 if (res != 0) {
1641 "Global parameter %s already defined\n", name);
1642 }
1643 return(0);
1644}
GLuint res
Definition: glext.h:9613
GLenum GLsizei len
Definition: glext.h:6722
XMLPUBFUN const xmlChar *XMLCALL xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:867
XMLPUBFUN xmlHashTablePtr XMLCALL xmlHashCreate(int size)
Definition: hash.c:176
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement(const xmlDoc *doc)
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
xsltStackElemPtr variables
Definition: mxnamespace.c:45
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
const xmlChar * xsltSplitQName(xmlDictPtr dict, const xmlChar *name, const xmlChar **prefix)
Definition: xsltutils.c:720

Referenced by xsltEvalOneUserParam(), and xsltQuoteOneUserParam().

◆ xsltQuoteOneUserParam()

int xsltQuoteOneUserParam ( xsltTransformContextPtr  ctxt,
const xmlChar name,
const xmlChar value 
)

Definition at line 1748 of file variables.c.

1750 {
1752 0 /* xpath eval ? */);
1753}

Referenced by xsltQuoteUserParams().

◆ xsltQuoteUserParams()

int xsltQuoteUserParams ( xsltTransformContextPtr  ctxt,
const char **  params 
)

xsltQuoteUserParams:

@ctxt: the XSLT transformation context @params: a NULL terminated arry of parameters names/values tuples

Similar to xsltEvalUserParams, but the values are treated literally and are * not evaluated as XPath expressions. This should be done on parsed stylesheets before starting to apply transformations.

Returns 0 in case of success, -1 in case of error.

Definition at line 1692 of file variables.c.

1692 {
1693 int indx = 0;
1694 const xmlChar *name;
1695 const xmlChar *value;
1696
1697 if (params == NULL)
1698 return(0);
1699 while (params[indx] != NULL) {
1700 name = (const xmlChar *) params[indx++];
1701 value = (const xmlChar *) params[indx++];
1702 if (xsltQuoteOneUserParam(ctxt, name, value) != 0)
1703 return(-1);
1704 }
1705 return 0;
1706}
int xsltQuoteOneUserParam(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *value)
Definition: variables.c:1748

◆ xsltRegisterGlobalVariable()

static int xsltRegisterGlobalVariable ( xsltStylesheetPtr  style,
const xmlChar name,
const xmlChar ns_uri,
const xmlChar sel,
xmlNodePtr  tree,
xsltStylePreCompPtr  comp,
const xmlChar value 
)
static

Definition at line 1345 of file variables.c.

1348 {
1350 if (style == NULL)
1351 return(-1);
1352 if (name == NULL)
1353 return(-1);
1354 if (comp == NULL)
1355 return(-1);
1356
1357#ifdef WITH_XSLT_DEBUG_VARIABLE
1358 if (comp->type == XSLT_FUNC_PARAM)
1360 "Defining global param %s\n", name);
1361 else
1363 "Defining global variable %s\n", name);
1364#endif
1365
1367 if (elem == NULL)
1368 return(-1);
1369 elem->comp = comp;
1370 elem->name = xmlDictLookup(style->dict, name, -1);
1371 elem->select = xmlDictLookup(style->dict, sel, -1);
1372 if (ns_uri)
1373 elem->nameURI = xmlDictLookup(style->dict, ns_uri, -1);
1374 elem->tree = tree;
1375 tmp = style->variables;
1376 if (tmp == NULL) {
1377 elem->next = NULL;
1378 style->variables = elem;
1379 } else {
1380 while (tmp != NULL) {
1381 if ((elem->comp->type == XSLT_FUNC_VARIABLE) &&
1382 (tmp->comp->type == XSLT_FUNC_VARIABLE) &&
1383 (xmlStrEqual(elem->name, tmp->name)) &&
1384 ((elem->nameURI == tmp->nameURI) ||
1385 (xmlStrEqual(elem->nameURI, tmp->nameURI))))
1386 {
1388 "redefinition of global variable %s\n", elem->name);
1389 style->errors++;
1390 }
1391 if (tmp->next == NULL)
1392 break;
1393 tmp = tmp->next;
1394 }
1395 elem->next = NULL;
1396 tmp->next = elem;
1397 }
1398 if (value != NULL) {
1399 elem->computed = 1;
1400 elem->value = xmlXPathNewString(value);
1401 }
1402 return(0);
1403}
struct _xsltStackElem * next
const xmlChar * nameURI
const xmlChar * name
xsltStyleType type

Referenced by xsltParseGlobalParam(), and xsltParseGlobalVariable().

◆ xsltRegisterLocalRVT()

int xsltRegisterLocalRVT ( xsltTransformContextPtr  ctxt,
xmlDocPtr  RVT 
)

xsltRegisterLocalRVT: @ctxt: an XSLT transformation context @RVT: a result value tree (Result Tree Fragment; xmlDocPtr)

Registers a result value tree (XSLT 1.0 term: Result Tree Fragment) in the RVT garbage collector. The fragment will be freed when the instruction which created the fragment exits.

Returns 0 in case of success and -1 in case of API or internal errors.

Definition at line 138 of file variables.c.

140{
141 if ((ctxt == NULL) || (RVT == NULL))
142 return(-1);
143
144 RVT->prev = NULL;
145 RVT->psvi = XSLT_RVT_LOCAL;
146
147 /*
148 * When evaluating "select" expressions of xsl:variable
149 * and xsl:param, we need to bind newly created tree fragments
150 * to the variable itself; otherwise the fragment will be
151 * freed before we leave the scope of a var.
152 */
153 if ((ctxt->contextVariable != NULL) &&
155 {
156 RVT->next = (xmlNodePtr) XSLT_TCTXT_VARIABLE(ctxt)->fragment;
157 XSLT_TCTXT_VARIABLE(ctxt)->fragment = RVT;
158 return(0);
159 }
160 /*
161 * Store the fragment in the scope of the current instruction.
162 * If not reference by a returning instruction (like EXSLT's function),
163 * then this fragment will be freed, when the instruction exits.
164 */
165 RVT->next = (xmlNodePtr) ctxt->localRVT;
166 if (ctxt->localRVT != NULL)
167 ctxt->localRVT->prev = (xmlNodePtr) RVT;
168 ctxt->localRVT = RVT;
169 return(0);
170}
GLbitfield flags
Definition: glext.h:7161
struct _xmlNode * next
Definition: tree.h:558
struct _xmlNode * prev
Definition: tree.h:559
#define XSLT_TCTXT_VARIABLE(c)
Definition: variables.c:27

Referenced by xsltFreeStackElem(), and xsltReleaseLocalRVTs().

◆ xsltRegisterPersistRVT()

int xsltRegisterPersistRVT ( xsltTransformContextPtr  ctxt,
xmlDocPtr  RVT 
)

xsltRegisterPersistRVT: @ctxt: an XSLT transformation context @RVT: a result value tree (Result Tree Fragment)

Register the result value tree (XSLT 1.0 term: Result Tree Fragment) in the fragment garbage collector. The fragment will be freed when the transformation context is freed.

Returns 0 in case of success and -1 in case of error.

Definition at line 394 of file variables.c.

395{
396 if ((ctxt == NULL) || (RVT == NULL)) return(-1);
397
398 RVT->psvi = XSLT_RVT_GLOBAL;
399 RVT->prev = NULL;
400 RVT->next = (xmlNodePtr) ctxt->persistRVT;
401 if (ctxt->persistRVT != NULL)
402 ctxt->persistRVT->prev = (xmlNodePtr) RVT;
403 ctxt->persistRVT = RVT;
404 return(0);
405}

Referenced by xsltEvalGlobalVariable(), and xsltReleaseLocalRVTs().

◆ xsltRegisterTmpRVT()

int xsltRegisterTmpRVT ( xsltTransformContextPtr  ctxt,
xmlDocPtr  RVT 
)

xsltRegisterTmpRVT: @ctxt: an XSLT transformation context @RVT: a result value tree (Result Tree Fragment)

Registers the result value tree (XSLT 1.0 term: Result Tree Fragment) in the garbage collector. The fragment will be freed at the exit of the currently instantiated xsl:template. Obsolete; this function might produce massive memory overhead, since the fragment is only freed when the current xsl:template exits. Use xsltRegisterLocalRVT() instead.

Returns 0 in case of success and -1 in case of API or internal errors.

Definition at line 99 of file variables.c.

100{
101 if ((ctxt == NULL) || (RVT == NULL))
102 return(-1);
103
104 RVT->prev = NULL;
105 RVT->psvi = XSLT_RVT_LOCAL;
106
107 /*
108 * We'll restrict the lifetime of user-created fragments
109 * insinde an xsl:variable and xsl:param to the lifetime of the
110 * var/param itself.
111 */
112 if (ctxt->contextVariable != NULL) {
113 RVT->next = (xmlNodePtr) XSLT_TCTXT_VARIABLE(ctxt)->fragment;
114 XSLT_TCTXT_VARIABLE(ctxt)->fragment = RVT;
115 return(0);
116 }
117
118 RVT->next = (xmlNodePtr) ctxt->tmpRVT;
119 if (ctxt->tmpRVT != NULL)
120 ctxt->tmpRVT->prev = (xmlNodePtr) RVT;
121 ctxt->tmpRVT = RVT;
122 return(0);
123}

◆ xsltRegisterVariable()

static int xsltRegisterVariable ( xsltTransformContextPtr  ctxt,
xsltStylePreCompPtr  castedComp,
xmlNodePtr  tree,
int  isParam 
)
static

xsltRegisterVariable: @ctxt: the XSLT transformation context @comp: the compiled XSLT-variable (or param) instruction @tree: the tree if select is NULL @isParam: indicates if this is a parameter

Computes and registers a new variable.

Returns 0 in case of success, -1 in case of error

Definition at line 1813 of file variables.c.

1816{
1817#ifdef XSLT_REFACTORED
1818 xsltStyleBasicItemVariablePtr comp =
1819 (xsltStyleBasicItemVariablePtr) castedComp;
1820#else
1821 xsltStylePreCompPtr comp = castedComp;
1822 int present;
1823#endif
1825
1826#ifdef XSLT_REFACTORED
1827 /*
1828 * REFACTORED NOTE: Redefinitions of vars/params are checked
1829 * at compilation time in the refactored code.
1830 * xsl:with-param parameters are checked in xsltApplyXSLTTemplate().
1831 */
1832#else
1833 present = xsltCheckStackElem(ctxt, comp->name, comp->ns);
1834 if (isParam == 0) {
1835 if ((present != 0) && (present != 3)) {
1836 /* TODO: report QName. */
1837 xsltTransformError(ctxt, NULL, comp->inst,
1838 "XSLT-variable: Redefinition of variable '%s'.\n", comp->name);
1839 return(0);
1840 }
1841 } else if (present != 0) {
1842 if ((present == 1) || (present == 2)) {
1843 /* TODO: report QName. */
1844 xsltTransformError(ctxt, NULL, comp->inst,
1845 "XSLT-param: Redefinition of parameter '%s'.\n", comp->name);
1846 return(0);
1847 }
1848#ifdef WITH_XSLT_DEBUG_VARIABLE
1850 "param %s defined by caller\n", comp->name));
1851#endif
1852 return(0);
1853 }
1854#endif /* else of XSLT_REFACTORED */
1855
1858 return(0);
1859}
static int xsltCheckStackElem(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI)
Definition: variables.c:696

Referenced by xsltParseStylesheetParam(), and xsltParseStylesheetVariable().

◆ xsltReleaseRVT()

void xsltReleaseRVT ( xsltTransformContextPtr  ctxt,
xmlDocPtr  RVT 
)

xsltReleaseRVT: @ctxt: an XSLT transformation context @RVT: a result value tree (Result Tree Fragment)

Either frees the RVT (which is an xmlDoc) or stores it in the context's cache for later reuse.

Definition at line 328 of file variables.c.

329{
330 if (RVT == NULL)
331 return;
332
333 if (ctxt && (ctxt->cache->nbRVT < 40)) {
334 /*
335 * Store the Result Tree Fragment.
336 * Free the document info.
337 */
338 if (RVT->_private != NULL) {
340 xmlFree(RVT->_private);
341 RVT->_private = NULL;
342 }
343 /*
344 * Clear the document tree.
345 */
346 if (RVT->children != NULL) {
348 RVT->children = NULL;
349 RVT->last = NULL;
350 }
351 if (RVT->ids != NULL) {
353 RVT->ids = NULL;
354 }
355
356 /*
357 * Reset the ownership information.
358 */
359 RVT->psvi = NULL;
360
361 RVT->next = (xmlNodePtr) ctxt->cache->RVT;
362 ctxt->cache->RVT = RVT;
363
364 ctxt->cache->nbRVT++;
365
366#ifdef XSLT_DEBUG_PROFILE_CACHE
367 ctxt->cache->dbgCachedRVTs++;
368#endif
369 return;
370 }
371 /*
372 * Free it.
373 */
374 if (RVT->_private != NULL) {
376 xmlFree(RVT->_private);
377 }
378 xmlFreeDoc(RVT);
379}
XMLPUBFUN void XMLCALL xmlFreeNodeList(xmlNodePtr cur)
void * _private
Definition: tree.h:552
void * ids
Definition: tree.h:575
struct _xmlNode * last
Definition: tree.h:556
struct _xmlNode * children
Definition: tree.h:555
XMLPUBFUN void XMLCALL xmlFreeIDTable(xmlIDTablePtr table)
Definition: valid.c:2756

Referenced by xsltApplyXSLTTemplate(), xsltFreeStackElem(), and xsltReleaseLocalRVTs().

◆ xsltStackLookup()

static xsltStackElemPtr xsltStackLookup ( xsltTransformContextPtr  ctxt,
const xmlChar name,
const xmlChar nameURI 
)
static

Definition at line 627 of file variables.c.

628 {
629 int i;
631
632 if ((ctxt == NULL) || (name == NULL) || (ctxt->varsNr == 0))
633 return(NULL);
634
635 /*
636 * Do the lookup from the top of the stack, but
637 * don't use params being computed in a call-param
638 * First lookup expects the variable name and URI to
639 * come from the disctionnary and hence pointer comparison.
640 */
641 for (i = ctxt->varsNr; i > ctxt->varsBase; i--) {
642 cur = ctxt->varsTab[i-1];
643 while (cur != NULL) {
644 if ((cur->name == name) && (cur->nameURI == nameURI)) {
645#if 0
646 stack_addr++;
647#endif
648 return(cur);
649 }
650 cur = cur->next;
651 }
652 }
653
654 /*
655 * Redo the lookup with interned string compares
656 * to avoid string compares.
657 */
658 name = xmlDictLookup(ctxt->dict, name, -1);
659 if (nameURI != NULL)
660 nameURI = xmlDictLookup(ctxt->dict, nameURI, -1);
661
662 for (i = ctxt->varsNr; i > ctxt->varsBase; i--) {
663 cur = ctxt->varsTab[i-1];
664 while (cur != NULL) {
665 if ((cur->name == name) && (cur->nameURI == nameURI)) {
666#if 0
667 stack_cmp++;
668#endif
669 return(cur);
670 }
671 cur = cur->next;
672 }
673 }
674
675 return(NULL);
676}

Referenced by xsltCheckStackElem(), and xsltVariableLookup().

◆ xsltVariableLookup()

xmlXPathObjectPtr xsltVariableLookup ( xsltTransformContextPtr  ctxt,
const xmlChar name,
const xmlChar ns_uri 
)

Definition at line 1920 of file variables.c.

1921 {
1923
1924 if (ctxt == NULL)
1925 return(NULL);
1926
1927 elem = xsltStackLookup(ctxt, name, ns_uri);
1928 if (elem == NULL) {
1929 return(xsltGlobalVariableLookup(ctxt, name, ns_uri));
1930 }
1931 if (elem->computed == 0) {
1932#ifdef WITH_XSLT_DEBUG_VARIABLE
1934 "uncomputed variable %s\n", name));
1935#endif
1936 elem->value = xsltEvalVariable(ctxt, elem, NULL);
1937 elem->computed = 1;
1938 }
1939 if (elem->value != NULL)
1940 return(xmlXPathObjectCopy(elem->value));
1941#ifdef WITH_XSLT_DEBUG_VARIABLE
1943 "variable not found %s\n", name));
1944#endif
1945 return(NULL);
1946}
static xmlXPathObjectPtr xsltGlobalVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *ns_uri)
Definition: variables.c:1873

◆ xsltXPathVariableLookup()

xmlXPathObjectPtr xsltXPathVariableLookup ( void ctxt,
const xmlChar name,
const xmlChar ns_uri 
)

Definition at line 2243 of file variables.c.

2244 {
2246 xmlXPathObjectPtr valueObj = NULL;
2247
2248 if ((ctxt == NULL) || (name == NULL))
2249 return(NULL);
2250
2251#ifdef WITH_XSLT_DEBUG_VARIABLE
2253 "Lookup variable '%s'\n", name));
2254#endif
2255
2256 tctxt = (xsltTransformContextPtr) ctxt;
2257 /*
2258 * Local variables/params ---------------------------------------------
2259 *
2260 * Do the lookup from the top of the stack, but
2261 * don't use params being computed in a call-param
2262 * First lookup expects the variable name and URI to
2263 * come from the disctionnary and hence pointer comparison.
2264 */
2265 if (tctxt->varsNr != 0) {
2266 int i;
2268
2269 for (i = tctxt->varsNr; i > tctxt->varsBase; i--) {
2270 cur = tctxt->varsTab[i-1];
2271 if ((cur->name == name) && (cur->nameURI == ns_uri)) {
2272#if 0
2273 stack_addr++;
2274#endif
2275 variable = cur;
2276 goto local_variable_found;
2277 }
2278 cur = cur->next;
2279 }
2280 /*
2281 * Redo the lookup with interned strings to avoid string comparison.
2282 *
2283 * OPTIMIZE TODO: The problem here is, that if we request a
2284 * global variable, then this will be also executed.
2285 */
2286 {
2287 const xmlChar *tmpName = name, *tmpNsName = ns_uri;
2288
2289 name = xmlDictLookup(tctxt->dict, name, -1);
2290 if (ns_uri)
2291 ns_uri = xmlDictLookup(tctxt->dict, ns_uri, -1);
2292 if ((tmpName != name) || (tmpNsName != ns_uri)) {
2293 for (i = tctxt->varsNr; i > tctxt->varsBase; i--) {
2294 cur = tctxt->varsTab[i-1];
2295 if ((cur->name == name) && (cur->nameURI == ns_uri)) {
2296#if 0
2297 stack_cmp++;
2298#endif
2299 variable = cur;
2300 goto local_variable_found;
2301 }
2302 }
2303 }
2304 }
2305
2306local_variable_found:
2307
2308 if (variable) {
2309 if (variable->computed == 0) {
2310
2311#ifdef WITH_XSLT_DEBUG_VARIABLE
2313 "uncomputed variable '%s'\n", name));
2314#endif
2315 variable->value = xsltEvalVariable(tctxt, variable, NULL);
2316 variable->computed = 1;
2317 }
2318 if (variable->value != NULL) {
2319 valueObj = xmlXPathObjectCopy(variable->value);
2320 }
2321 return(valueObj);
2322 }
2323 }
2324 /*
2325 * Global variables/params --------------------------------------------
2326 */
2327 if (tctxt->globalVars) {
2328 valueObj = xsltGlobalVariableLookup(tctxt, name, ns_uri);
2329 }
2330
2331 if (valueObj == NULL) {
2332
2333#ifdef WITH_XSLT_DEBUG_VARIABLE
2335 "variable not found '%s'\n", name));
2336#endif
2337
2338 if (ns_uri) {
2339 xsltTransformError(tctxt, NULL, tctxt->inst,
2340 "Variable '{%s}%s' has not been declared.\n", ns_uri, name);
2341 } else {
2342 xsltTransformError(tctxt, NULL, tctxt->inst,
2343 "Variable '%s' has not been declared.\n", name);
2344 }
2345 } else {
2346
2347#ifdef WITH_XSLT_DEBUG_VARIABLE
2349 "found variable '%s'\n", name));
2350#endif
2351 }
2352
2353 return(valueObj);
2354}
xsltTransformContext * xsltTransformContextPtr

Variable Documentation

◆ xsltComputingGlobalVarMarker

const xmlChar* xsltComputingGlobalVarMarker
static
Initial value:
=
(const xmlChar *) " var/param being computed"

Definition at line 22 of file variables.c.

Referenced by xsltEvalGlobalVariable(), and xsltGlobalVariableLookup().