ReactOS 0.4.16-dev-329-g9223134
functions.c File Reference
#include "precomp.h"
#include <libxml/xpointer.h>
Include dependency graph for functions.c:

Go to the source code of this file.

Macros

#define DOCBOOK_XSL_HACK
 

Functions

: the function name

xsltXPathFunctionLookup: @vctxt: a void * but the XSLT transformation context actually

@ns_uri: the function namespace URI

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

Returns the callback function or NULL if not found

xmlXPathFunction xsltXPathFunctionLookup (void *vctxt, const xmlChar *name, const xmlChar *ns_uri)
 
static void xsltDocumentFunctionLoadDocument (xmlXPathParserContextPtr ctxt, xmlChar *URI)
 
void xsltDocumentFunction (xmlXPathParserContextPtr ctxt, int nargs)
 
void xsltKeyFunction (xmlXPathParserContextPtr ctxt, int nargs)
 
void xsltUnparsedEntityURIFunction (xmlXPathParserContextPtr ctxt, int nargs)
 
void xsltFormatNumberFunction (xmlXPathParserContextPtr ctxt, int nargs)
 
void xsltGenerateIdFunction (xmlXPathParserContextPtr ctxt, int nargs)
 
void xsltSystemPropertyFunction (xmlXPathParserContextPtr ctxt, int nargs)
 
void xsltElementAvailableFunction (xmlXPathParserContextPtr ctxt, int nargs)
 
void xsltFunctionAvailableFunction (xmlXPathParserContextPtr ctxt, int nargs)
 
static void xsltCurrentFunction (xmlXPathParserContextPtr ctxt, int nargs)
 
void xsltRegisterAllFunctions (xmlXPathContextPtr ctxt)
 

Macro Definition Documentation

◆ DOCBOOK_XSL_HACK

#define DOCBOOK_XSL_HACK

Definition at line 26 of file functions.c.

Function Documentation

◆ xsltCurrentFunction()

static void xsltCurrentFunction ( xmlXPathParserContextPtr  ctxt,
int  nargs 
)
static

xsltCurrentFunction: @ctxt: the XPath Parser context @nargs: the number of arguments

Implement the current() XSLT function node-set current()

Definition at line 927 of file functions.c.

927 {
929
930 if (nargs != 0) {
932 "current() : function uses no argument\n");
933 ctxt->error = XPATH_INVALID_ARITY;
934 return;
935 }
936 tctxt = xsltXPathGetTransformContext(ctxt);
937 if (tctxt == NULL) {
939 "current() : internal error tctxt == NULL\n");
940 valuePush(ctxt, xmlXPathNewNodeSet(NULL));
941 } else {
942 valuePush(ctxt, xmlXPathNewNodeSet(tctxt->node)); /* current */
943 }
944}
xsltTransformContextPtr xsltXPathGetTransformContext(xmlXPathParserContextPtr ctxt)
Definition: extensions.c:1367
#define NULL
Definition: types.h:112
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678

Referenced by xsltRegisterAllFunctions().

◆ xsltDocumentFunction()

void xsltDocumentFunction ( xmlXPathParserContextPtr  ctxt,
int  nargs 
)

xsltDocumentFunction: @ctxt: the XPath Parser context @nargs: the number of arguments

Implement the document() XSLT function node-set document(object, node-set?)

Definition at line 193 of file functions.c.

194{
195 xmlXPathObjectPtr obj, obj2 = NULL;
196 xmlChar *base = NULL, *URI;
197
198
199 if ((nargs < 1) || (nargs > 2)) {
201 "document() : invalid number of args %d\n",
202 nargs);
203 ctxt->error = XPATH_INVALID_ARITY;
204 return;
205 }
206 if (ctxt->value == NULL) {
208 "document() : invalid arg value\n");
209 ctxt->error = XPATH_INVALID_TYPE;
210 return;
211 }
212
213 if (nargs == 2) {
214 if (ctxt->value->type != XPATH_NODESET) {
216 "document() : invalid arg expecting a nodeset\n");
217 ctxt->error = XPATH_INVALID_TYPE;
218 return;
219 }
220
221 obj2 = valuePop(ctxt);
222 }
223
224 if (ctxt->value->type == XPATH_NODESET) {
225 int i;
226 xmlXPathObjectPtr newobj, ret;
227
228 obj = valuePop(ctxt);
229 ret = xmlXPathNewNodeSet(NULL);
230
231 if ((obj != NULL) && obj->nodesetval) {
232 for (i = 0; i < obj->nodesetval->nodeNr; i++) {
233 valuePush(ctxt,
234 xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i]));
235 xmlXPathStringFunction(ctxt, 1);
236 if (nargs == 2) {
237 valuePush(ctxt, xmlXPathObjectCopy(obj2));
238 } else {
239 valuePush(ctxt,
240 xmlXPathNewNodeSet(obj->nodesetval->
241 nodeTab[i]));
242 }
243 xsltDocumentFunction(ctxt, 2);
244 newobj = valuePop(ctxt);
245 ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
246 newobj->nodesetval);
247 xmlXPathFreeObject(newobj);
248 }
249 }
250
251 if (obj != NULL)
252 xmlXPathFreeObject(obj);
253 if (obj2 != NULL)
254 xmlXPathFreeObject(obj2);
255 valuePush(ctxt, ret);
256 return;
257 }
258 /*
259 * Make sure it's converted to a string
260 */
261 xmlXPathStringFunction(ctxt, 1);
262 if (ctxt->value->type != XPATH_STRING) {
264 "document() : invalid arg expecting a string\n");
265 ctxt->error = XPATH_INVALID_TYPE;
266 if (obj2 != NULL)
267 xmlXPathFreeObject(obj2);
268 return;
269 }
270 obj = valuePop(ctxt);
271 if (obj->stringval == NULL) {
272 valuePush(ctxt, xmlXPathNewNodeSet(NULL));
273 } else {
275 tctxt = xsltXPathGetTransformContext(ctxt);
276 if ((obj2 != NULL) && (obj2->nodesetval != NULL) &&
277 (obj2->nodesetval->nodeNr > 0) &&
278 IS_XSLT_REAL_NODE(obj2->nodesetval->nodeTab[0])) {
280
281 target = obj2->nodesetval->nodeTab[0];
282 if ((target->type == XML_ATTRIBUTE_NODE) ||
283 (target->type == XML_PI_NODE)) {
284 target = ((xmlAttrPtr) target)->parent;
285 }
287 } else {
288 if ((tctxt != NULL) && (tctxt->inst != NULL)) {
289 base = xmlNodeGetBase(tctxt->inst->doc, tctxt->inst);
290 } else if ((tctxt != NULL) && (tctxt->style != NULL) &&
291 (tctxt->style->doc != NULL)) {
292 base = xmlNodeGetBase(tctxt->style->doc,
293 (xmlNodePtr) tctxt->style->doc);
294 }
295 }
296 URI = xmlBuildURI(obj->stringval, base);
297 if (base != NULL)
298 xmlFree(base);
299 if (URI == NULL) {
300 if ((tctxt != NULL) && (tctxt->style != NULL) &&
301 (tctxt->style->doc != NULL) &&
302 (xmlStrEqual(URI, tctxt->style->doc->URL))) {
303 /* This selects the stylesheet's doc itself. */
304 valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) tctxt->style->doc));
305 } else {
306 valuePush(ctxt, xmlXPathNewNodeSet(NULL));
307 }
308 } else {
310 xmlFree(URI);
311 }
312 }
313 xmlXPathFreeObject(obj);
314 if (obj2 != NULL)
315 xmlXPathFreeObject(obj2);
316}
void xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:193
static void xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar *URI)
Definition: functions.c:78
GLenum target
Definition: glext.h:7315
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
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
@ XML_ATTRIBUTE_NODE
Definition: tree.h:161
@ XML_PI_NODE
Definition: tree.h:166
xmlAttr * xmlAttrPtr
Definition: tree.h:433
XMLPUBFUN xmlChar *XMLCALL xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur)
const xmlChar * URL
Definition: tree.h:577
Definition: tree.h:489
struct _xmlDoc * doc
Definition: tree.h:498
xsltStylesheetPtr style
XMLPUBFUN xmlChar *XMLCALL xmlBuildURI(const xmlChar *URI, const xmlChar *base)
Definition: uri.c:1892
int ret
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
unsigned char xmlChar
Definition: xmlstring.h:28
#define IS_XSLT_REAL_NODE(n)
Definition: xsltutils.h:68

Referenced by xsltDocumentFunction(), and xsltRegisterAllFunctions().

◆ xsltDocumentFunctionLoadDocument()

static void xsltDocumentFunctionLoadDocument ( xmlXPathParserContextPtr  ctxt,
xmlChar URI 
)
static

Definition at line 78 of file functions.c.

79{
82 xmlChar *fragment;
83 xsltDocumentPtr idoc; /* document info */
84 xmlDocPtr doc;
85 xmlXPathContextPtr xptrctxt = NULL;
86 xmlXPathObjectPtr resObj = NULL;
87
88 tctxt = xsltXPathGetTransformContext(ctxt);
89 if (tctxt == NULL) {
91 "document() : internal error tctxt == NULL\n");
92 valuePush(ctxt, xmlXPathNewNodeSet(NULL));
93 return;
94 }
95
96 uri = xmlParseURI((const char *) URI);
97 if (uri == NULL) {
99 "document() : failed to parse URI\n");
100 valuePush(ctxt, xmlXPathNewNodeSet(NULL));
101 return;
102 }
103
104 /*
105 * check for and remove fragment identifier
106 */
107 fragment = (xmlChar *)uri->fragment;
108 if (fragment != NULL) {
109 xmlChar *newURI;
110 uri->fragment = NULL;
111 newURI = xmlSaveUri(uri);
112 idoc = xsltLoadDocument(tctxt, newURI);
113 xmlFree(newURI);
114 } else
115 idoc = xsltLoadDocument(tctxt, URI);
117
118 if (idoc == NULL) {
119 if ((URI == NULL) ||
120 (URI[0] == '#') ||
121 ((tctxt->style->doc != NULL) &&
122 (xmlStrEqual(tctxt->style->doc->URL, URI))))
123 {
124 /*
125 * This selects the stylesheet's doc itself.
126 */
127 doc = tctxt->style->doc;
128 } else {
129 valuePush(ctxt, xmlXPathNewNodeSet(NULL));
130
131 if (fragment != NULL)
132 xmlFree(fragment);
133
134 return;
135 }
136 } else
137 doc = idoc->doc;
138
139 if (fragment == NULL) {
140 valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) doc));
141 return;
142 }
143
144 /* use XPointer of HTML location for fragment ID */
145#ifdef LIBXML_XPTR_ENABLED
146 xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
147 if (xptrctxt == NULL) {
149 "document() : internal error xptrctxt == NULL\n");
150 goto out_fragment;
151 }
152
153#if LIBXML_VERSION >= 20911 || \
154 defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
155 xptrctxt->opLimit = ctxt->context->opLimit;
156 xptrctxt->opCount = ctxt->context->opCount;
157 xptrctxt->depth = ctxt->context->depth;
158
159 resObj = xmlXPtrEval(fragment, xptrctxt);
160
161 ctxt->context->opCount = xptrctxt->opCount;
162#else
163 resObj = xmlXPtrEval(fragment, xptrctxt);
164#endif
165
166 xmlXPathFreeContext(xptrctxt);
167#endif /* LIBXML_XPTR_ENABLED */
168
169 if ((resObj != NULL) && (resObj->type != XPATH_NODESET)) {
171 "document() : XPointer does not select a node set: #%s\n",
172 fragment);
173 xmlXPathFreeObject(resObj);
174 resObj = NULL;
175 }
176
177out_fragment:
178 if (resObj == NULL)
179 resObj = xmlXPathNewNodeSet(NULL);
180 valuePush(ctxt, resObj);
181 xmlFree(fragment);
182}
xsltDocumentPtr xsltLoadDocument(xsltTransformContextPtr ctxt, const xmlChar *URI)
Definition: documents.c:268
if(dx< 0)
Definition: linetemp.h:194
const char * uri
Definition: sec_mgr.c:1588
Definition: tree.h:551
Definition: uri.h:33
xmlDocPtr doc
XMLPUBFUN xmlURIPtr XMLCALL xmlParseURI(const char *str)
Definition: uri.c:940
XMLPUBFUN xmlChar *XMLCALL xmlSaveUri(xmlURIPtr uri)
Definition: uri.c:1066
XMLPUBFUN void XMLCALL xmlFreeURI(xmlURIPtr uri)
Definition: uri.c:1387

Referenced by xsltDocumentFunction().

◆ xsltElementAvailableFunction()

void xsltElementAvailableFunction ( xmlXPathParserContextPtr  ctxt,
int  nargs 
)

xsltElementAvailableFunction: @ctxt: the XPath Parser context @nargs: the number of arguments

Implement the element-available() XSLT function boolean element-available(string)

Definition at line 807 of file functions.c.

807 {
808 xmlXPathObjectPtr obj;
809 xmlChar *prefix, *name;
810 const xmlChar *nsURI = NULL;
812
813 if (nargs != 1) {
815 "element-available() : expects one string arg\n");
816 ctxt->error = XPATH_INVALID_ARITY;
817 return;
818 }
819 xmlXPathStringFunction(ctxt, 1);
820 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
822 "element-available() : invalid arg expecting a string\n");
823 ctxt->error = XPATH_INVALID_TYPE;
824 return;
825 }
826 obj = valuePop(ctxt);
827 tctxt = xsltXPathGetTransformContext(ctxt);
828 if ((tctxt == NULL) || (tctxt->inst == NULL)) {
830 "element-available() : internal error tctxt == NULL\n");
831 xmlXPathFreeObject(obj);
832 valuePush(ctxt, xmlXPathNewBoolean(0));
833 return;
834 }
835
836
837 name = xmlSplitQName2(obj->stringval, &prefix);
838 if (name == NULL) {
839 xmlNsPtr ns;
840
841 name = xmlStrdup(obj->stringval);
842 ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, NULL);
843 if (ns != NULL) nsURI = ns->href;
844 } else {
845 nsURI = xmlXPathNsLookup(ctxt->context, prefix);
846 if (nsURI == NULL) {
848 "element-available() : prefix %s is not bound\n", prefix);
849 }
850 }
851
852 if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) {
853 valuePush(ctxt, xmlXPathNewBoolean(1));
854 } else {
855 valuePush(ctxt, xmlXPathNewBoolean(0));
856 }
857
858 xmlXPathFreeObject(obj);
859 if (name != NULL)
860 xmlFree(name);
861 if (prefix != NULL)
862 xmlFree(prefix);
863}
xsltTransformFunction xsltExtElementLookup(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *URI)
Definition: extensions.c:1668
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
XMLPUBFUN xmlChar *XMLCALL xmlSplitQName2(const xmlChar *name, xmlChar **prefix)
Definition: tree.h:389
Definition: name.c:39
Definition: mxnamespace.c:45
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:67

Referenced by xsltRegisterAllFunctions().

◆ xsltFormatNumberFunction()

void xsltFormatNumberFunction ( xmlXPathParserContextPtr  ctxt,
int  nargs 
)

xsltFormatNumberFunction: @ctxt: the XPath Parser context @nargs: the number of arguments

Implement the format-number() XSLT function string format-number(number, string, string?)

Definition at line 567 of file functions.c.

568{
569 xmlXPathObjectPtr numberObj = NULL;
570 xmlXPathObjectPtr formatObj = NULL;
571 xmlXPathObjectPtr decimalObj = NULL;
572 xsltStylesheetPtr sheet;
573 xsltDecimalFormatPtr formatValues = NULL;
575 const xmlChar *ncname;
576 const xmlChar *prefix = NULL;
577 const xmlChar *nsUri = NULL;
579
580 tctxt = xsltXPathGetTransformContext(ctxt);
581 if ((tctxt == NULL) || (tctxt->inst == NULL))
582 return;
583 sheet = tctxt->style;
584 if (sheet == NULL)
585 return;
586 formatValues = sheet->decimalFormat;
587
588 switch (nargs) {
589 case 3:
590 if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING))
591 xmlXPathStringFunction(ctxt, 1);
592 decimalObj = valuePop(ctxt);
593 ncname = xsltSplitQName(sheet->dict, decimalObj->stringval, &prefix);
594 if (prefix != NULL) {
595 xmlNsPtr ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, prefix);
596 if (ns == NULL) {
598 "format-number : No namespace found for QName '%s:%s'\n",
599 prefix, ncname);
600 sheet->errors++;
601 ncname = NULL;
602 }
603 else {
604 nsUri = ns->href;
605 }
606 }
607 if (ncname != NULL) {
608 formatValues = xsltDecimalFormatGetByQName(sheet, nsUri, ncname);
609 }
610 if (formatValues == NULL) {
612 "format-number() : undeclared decimal format '%s'\n",
613 decimalObj->stringval);
614 }
615 /* Intentional fall-through */
616 case 2:
617 if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING))
618 xmlXPathStringFunction(ctxt, 1);
619 formatObj = valuePop(ctxt);
620 if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_NUMBER))
621 xmlXPathNumberFunction(ctxt, 1);
622 numberObj = valuePop(ctxt);
623 break;
624 default:
625 xmlXPathErr(ctxt, XPATH_INVALID_ARITY);
626 return;
627 }
628
629 if (formatValues != NULL) {
630 if (xsltFormatNumberConversion(formatValues,
631 formatObj->stringval,
632 numberObj->floatval,
633 &result) == XPATH_EXPRESSION_OK) {
634 valuePush(ctxt, xmlXPathNewString(result));
636 }
637 }
638
639 xmlXPathFreeObject(numberObj);
640 xmlXPathFreeObject(formatObj);
641 xmlXPathFreeObject(decimalObj);
642}
xmlXPathError xsltFormatNumberConversion(xsltDecimalFormatPtr self, xmlChar *format, double number, xmlChar **result)
Definition: numbers.c:941
GLuint64EXT * result
Definition: glext.h:11304
xsltDecimalFormatPtr decimalFormat
xsltDecimalFormatPtr xsltDecimalFormatGetByQName(xsltStylesheetPtr style, const xmlChar *nsUri, const xmlChar *name)
Definition: xslt.c:364
const xmlChar * xsltSplitQName(xmlDictPtr dict, const xmlChar *name, const xmlChar **prefix)
Definition: xsltutils.c:720

Referenced by xsltRegisterAllFunctions().

◆ xsltFunctionAvailableFunction()

void xsltFunctionAvailableFunction ( xmlXPathParserContextPtr  ctxt,
int  nargs 
)

xsltFunctionAvailableFunction: @ctxt: the XPath Parser context @nargs: the number of arguments

Implement the function-available() XSLT function boolean function-available(string)

Definition at line 874 of file functions.c.

874 {
875 xmlXPathObjectPtr obj;
876 xmlChar *prefix, *name;
877 const xmlChar *nsURI = NULL;
878
879 if (nargs != 1) {
881 "function-available() : expects one string arg\n");
882 ctxt->error = XPATH_INVALID_ARITY;
883 return;
884 }
885 xmlXPathStringFunction(ctxt, 1);
886 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
888 "function-available() : invalid arg expecting a string\n");
889 ctxt->error = XPATH_INVALID_TYPE;
890 return;
891 }
892 obj = valuePop(ctxt);
893
894 name = xmlSplitQName2(obj->stringval, &prefix);
895 if (name == NULL) {
896 name = xmlStrdup(obj->stringval);
897 } else {
898 nsURI = xmlXPathNsLookup(ctxt->context, prefix);
899 if (nsURI == NULL) {
901 "function-available() : prefix %s is not bound\n", prefix);
902 }
903 }
904
905 if (xmlXPathFunctionLookupNS(ctxt->context, name, nsURI) != NULL) {
906 valuePush(ctxt, xmlXPathNewBoolean(1));
907 } else {
908 valuePush(ctxt, xmlXPathNewBoolean(0));
909 }
910
911 xmlXPathFreeObject(obj);
912 if (name != NULL)
913 xmlFree(name);
914 if (prefix != NULL)
915 xmlFree(prefix);
916}

Referenced by xsltRegisterAllFunctions().

◆ xsltGenerateIdFunction()

void xsltGenerateIdFunction ( xmlXPathParserContextPtr  ctxt,
int  nargs 
)

xsltGenerateIdFunction: @ctxt: the XPath Parser context @nargs: the number of arguments

Implement the generate-id() XSLT function string generate-id(node-set?)

Definition at line 653 of file functions.c.

653 {
654 static char base_address;
656 xmlXPathObjectPtr obj = NULL;
657 long val;
658 xmlChar str[30];
659
660 if (nargs == 0) {
661 cur = ctxt->context->node;
662 } else if (nargs == 1) {
663 xmlNodeSetPtr nodelist;
664 int i, ret;
665
666 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
667 ctxt->error = XPATH_INVALID_TYPE;
669 "generate-id() : invalid arg expecting a node-set\n");
670 return;
671 }
672 obj = valuePop(ctxt);
673 nodelist = obj->nodesetval;
674 if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
675 xmlXPathFreeObject(obj);
676 valuePush(ctxt, xmlXPathNewCString(""));
677 return;
678 }
679 cur = nodelist->nodeTab[0];
680 for (i = 1;i < nodelist->nodeNr;i++) {
681 ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
682 if (ret == -1)
683 cur = nodelist->nodeTab[i];
684 }
685 } else {
687 "generate-id() : invalid number of args %d\n", nargs);
688 ctxt->error = XPATH_INVALID_ARITY;
689 return;
690 }
691
692 if (obj)
693 xmlXPathFreeObject(obj);
694
695 val = (long)((char *)cur - (char *)&base_address);
696 if (val >= 0) {
697 snprintf((char *)str, sizeof(str), "idp%ld", val);
698 } else {
699 snprintf((char *)str, sizeof(str), "idm%ld", -val);
700 }
701 valuePush(ctxt, xmlXPathNewString(str));
702}
FxCollectionEntry * cur
GLuint GLfloat * val
Definition: glext.h:7180
#define long
Definition: qsort.c:33
const WCHAR * str
#define snprintf
Definition: wintirpc.h:48

Referenced by xsltRegisterAllFunctions().

◆ xsltKeyFunction()

void xsltKeyFunction ( xmlXPathParserContextPtr  ctxt,
int  nargs 
)

xsltKeyFunction: @ctxt: the XPath Parser context @nargs: the number of arguments

Implement the key() XSLT function node-set key(string, object)

Definition at line 327 of file functions.c.

327 {
328 xmlXPathObjectPtr obj1, obj2;
329
330 if (nargs != 2) {
332 "key() : expects two arguments\n");
333 ctxt->error = XPATH_INVALID_ARITY;
334 return;
335 }
336
337 /*
338 * Get the key's value.
339 */
340 obj2 = valuePop(ctxt);
341 xmlXPathStringFunction(ctxt, 1);
342 if ((obj2 == NULL) ||
343 (ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
345 "key() : invalid arg expecting a string\n");
346 ctxt->error = XPATH_INVALID_TYPE;
347 xmlXPathFreeObject(obj2);
348
349 return;
350 }
351 /*
352 * Get the key's name.
353 */
354 obj1 = valuePop(ctxt);
355
356 if ((obj2->type == XPATH_NODESET) || (obj2->type == XPATH_XSLT_TREE)) {
357 int i;
358 xmlXPathObjectPtr newobj, ret;
359
360 ret = xmlXPathNewNodeSet(NULL);
361
362 if (obj2->nodesetval != NULL) {
363 for (i = 0; i < obj2->nodesetval->nodeNr; i++) {
364 valuePush(ctxt, xmlXPathObjectCopy(obj1));
365 valuePush(ctxt,
366 xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i]));
367 xmlXPathStringFunction(ctxt, 1);
368 xsltKeyFunction(ctxt, 2);
369 newobj = valuePop(ctxt);
370 ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
371 newobj->nodesetval);
372 xmlXPathFreeObject(newobj);
373 }
374 }
375 valuePush(ctxt, ret);
376 } else {
377 xmlNodeSetPtr nodelist = NULL;
378 xmlChar *key = NULL, *value;
379 const xmlChar *keyURI;
381 xmlChar *qname, *prefix;
382 xmlXPathContextPtr xpctxt = ctxt->context;
383 xmlNodePtr tmpNode = NULL;
384 xsltDocumentPtr oldDocInfo;
385
386 tctxt = xsltXPathGetTransformContext(ctxt);
387
388 oldDocInfo = tctxt->document;
389
390 if (xpctxt->node == NULL) {
391 xsltTransformError(tctxt, NULL, tctxt->inst,
392 "Internal error in xsltKeyFunction(): "
393 "The context node is not set on the XPath context.\n");
394 tctxt->state = XSLT_STATE_STOPPED;
395 goto error;
396 }
397 /*
398 * Get the associated namespace URI if qualified name
399 */
400 qname = obj1->stringval;
401 key = xmlSplitQName2(qname, &prefix);
402 if (key == NULL) {
403 key = xmlStrdup(obj1->stringval);
404 keyURI = NULL;
405 if (prefix != NULL)
406 xmlFree(prefix);
407 } else {
408 if (prefix != NULL) {
409 keyURI = xmlXPathNsLookup(xpctxt, prefix);
410 if (keyURI == NULL) {
411 xsltTransformError(tctxt, NULL, tctxt->inst,
412 "key() : prefix %s is not bound\n", prefix);
413 /*
414 * TODO: Shouldn't we stop here?
415 */
416 }
417 xmlFree(prefix);
418 } else {
419 keyURI = NULL;
420 }
421 }
422
423 /*
424 * Force conversion of first arg to string
425 */
426 valuePush(ctxt, obj2);
427 xmlXPathStringFunction(ctxt, 1);
428 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
429 xsltTransformError(tctxt, NULL, tctxt->inst,
430 "key() : invalid arg expecting a string\n");
431 ctxt->error = XPATH_INVALID_TYPE;
432 goto error;
433 }
434 obj2 = valuePop(ctxt);
435 value = obj2->stringval;
436
437 /*
438 * We need to ensure that ctxt->document is available for
439 * xsltGetKey().
440 * First find the relevant doc, which is the context node's
441 * owner doc; using context->doc is not safe, since
442 * the doc could have been acquired via the document() function,
443 * or the doc might be a Result Tree Fragment.
444 * FUTURE INFO: In XSLT 2.0 the key() function takes an additional
445 * argument indicating the doc to use.
446 */
447 if (xpctxt->node->type == XML_NAMESPACE_DECL) {
448 /*
449 * REVISIT: This is a libxml hack! Check xpath.c for details.
450 * The XPath module sets the owner element of a ns-node on
451 * the ns->next field.
452 */
453 if ((((xmlNsPtr) xpctxt->node)->next != NULL) &&
454 (((xmlNsPtr) xpctxt->node)->next->type == XML_ELEMENT_NODE))
455 {
456 tmpNode = (xmlNodePtr) ((xmlNsPtr) xpctxt->node)->next;
457 }
458 } else
459 tmpNode = xpctxt->node;
460
461 if ((tmpNode == NULL) || (tmpNode->doc == NULL)) {
462 xsltTransformError(tctxt, NULL, tctxt->inst,
463 "Internal error in xsltKeyFunction(): "
464 "Couldn't get the doc of the XPath context node.\n");
465 goto error;
466 }
467
468 if ((tctxt->document == NULL) ||
469 (tctxt->document->doc != tmpNode->doc))
470 {
471 if (tmpNode->doc->name && (tmpNode->doc->name[0] == ' ')) {
472 /*
473 * This is a Result Tree Fragment.
474 */
475 if (tmpNode->doc->_private == NULL) {
476 tmpNode->doc->_private = xsltNewDocument(tctxt, tmpNode->doc);
477 if (tmpNode->doc->_private == NULL)
478 goto error;
479 }
480 tctxt->document = (xsltDocumentPtr) tmpNode->doc->_private;
481 } else {
482 /*
483 * May be the initial source doc or a doc acquired via the
484 * document() function.
485 */
486 tctxt->document = xsltFindDocument(tctxt, tmpNode->doc);
487 }
488 if (tctxt->document == NULL) {
489 xsltTransformError(tctxt, NULL, tctxt->inst,
490 "Internal error in xsltKeyFunction(): "
491 "Could not get the document info of a context doc.\n");
492 tctxt->state = XSLT_STATE_STOPPED;
493 goto error;
494 }
495 }
496 /*
497 * Get/compute the key value.
498 */
499 nodelist = xsltGetKey(tctxt, key, keyURI, value);
500
501error:
502 tctxt->document = oldDocInfo;
503 valuePush(ctxt, xmlXPathWrapNodeSet(
504 xmlXPathNodeSetMerge(NULL, nodelist)));
505 if (key != NULL)
506 xmlFree(key);
507 }
508
509 if (obj1 != NULL)
510 xmlXPathFreeObject(obj1);
511 if (obj2 != NULL)
512 xmlXPathFreeObject(obj2);
513}
xsltDocumentPtr xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc)
Definition: documents.c:127
xsltDocumentPtr xsltFindDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc)
Definition: documents.c:400
void xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:327
xmlNodeSetPtr xsltGetKey(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI, const xmlChar *value)
Definition: keys.c:417
#define error(str)
Definition: mkdosfs.c:1605
static unsigned __int64 next
Definition: rand_nt.c:6
xmlNode * xmlNodePtr
Definition: tree.h:488
@ XML_NAMESPACE_DECL
Definition: tree.h:177
@ XML_ELEMENT_NODE
Definition: tree.h:160
xsltTransformState state
xsltDocumentPtr document
Definition: copy.c:22
Definition: pdh_main.c:94
@ XSLT_STATE_STOPPED
xsltDocument * xsltDocumentPtr

Referenced by xsltKeyFunction(), and xsltRegisterAllFunctions().

◆ xsltRegisterAllFunctions()

void xsltRegisterAllFunctions ( xmlXPathContextPtr  ctxt)

xsltRegisterAllFunctions: @ctxt: the XPath context

Registers all default XSLT functions in this context

Definition at line 959 of file functions.c.

960{
961 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "current",
963 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "document",
965 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "key", xsltKeyFunction);
966 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "unparsed-entity-uri",
968 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "format-number",
970 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "generate-id",
972 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "system-property",
974 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "element-available",
976 xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available",
978}
void xsltSystemPropertyFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:713
void xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:653
void xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:567
void xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:807
void xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:524
void xsltFunctionAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:874
static void xsltCurrentFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:927

◆ xsltSystemPropertyFunction()

void xsltSystemPropertyFunction ( xmlXPathParserContextPtr  ctxt,
int  nargs 
)

xsltSystemPropertyFunction: @ctxt: the XPath Parser context @nargs: the number of arguments

Implement the system-property() XSLT function object system-property(string)

Definition at line 713 of file functions.c.

713 {
714 xmlXPathObjectPtr obj;
715 xmlChar *prefix, *name;
716 const xmlChar *nsURI = NULL;
717
718 if (nargs != 1) {
720 "system-property() : expects one string arg\n");
721 ctxt->error = XPATH_INVALID_ARITY;
722 return;
723 }
724 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
726 "system-property() : invalid arg expecting a string\n");
727 ctxt->error = XPATH_INVALID_TYPE;
728 return;
729 }
730 obj = valuePop(ctxt);
731 if (obj->stringval == NULL) {
732 valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
733 } else {
734 name = xmlSplitQName2(obj->stringval, &prefix);
735 if (name == NULL) {
736 name = xmlStrdup(obj->stringval);
737 } else {
738 nsURI = xmlXPathNsLookup(ctxt->context, prefix);
739 if (nsURI == NULL) {
741 "system-property() : prefix %s is not bound\n", prefix);
742 }
743 }
744
745 if (xmlStrEqual(nsURI, XSLT_NAMESPACE)) {
746#ifdef DOCBOOK_XSL_HACK
747 if (xmlStrEqual(name, (const xmlChar *)"vendor")) {
748 xsltStylesheetPtr sheet;
750
751 tctxt = xsltXPathGetTransformContext(ctxt);
752 if ((tctxt != NULL) && (tctxt->inst != NULL) &&
753 (xmlStrEqual(tctxt->inst->name, BAD_CAST "variable")) &&
754 (tctxt->inst->parent != NULL) &&
755 (xmlStrEqual(tctxt->inst->parent->name,
756 BAD_CAST "template")))
757 sheet = tctxt->style;
758 else
759 sheet = NULL;
760 if ((sheet != NULL) && (sheet->doc != NULL) &&
761 (sheet->doc->URL != NULL) &&
762 (xmlStrstr(sheet->doc->URL,
763 (const xmlChar *)"chunk") != NULL)) {
764 valuePush(ctxt, xmlXPathNewString(
765 (const xmlChar *)"libxslt (SAXON 6.2 compatible)"));
766
767 } else {
768 valuePush(ctxt, xmlXPathNewString(
769 (const xmlChar *)XSLT_DEFAULT_VENDOR));
770 }
771 } else
772#else
773 if (xmlStrEqual(name, (const xmlChar *)"vendor")) {
774 valuePush(ctxt, xmlXPathNewString(
775 (const xmlChar *)XSLT_DEFAULT_VENDOR));
776 } else
777#endif
778 if (xmlStrEqual(name, (const xmlChar *)"version")) {
779 valuePush(ctxt, xmlXPathNewString(
780 (const xmlChar *)XSLT_DEFAULT_VERSION));
781 } else if (xmlStrEqual(name, (const xmlChar *)"vendor-url")) {
782 valuePush(ctxt, xmlXPathNewString(
783 (const xmlChar *)XSLT_DEFAULT_URL));
784 } else {
785 valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
786 }
787 } else {
788 valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
789 }
790 if (name != NULL)
791 xmlFree(name);
792 if (prefix != NULL)
793 xmlFree(prefix);
794 }
795 xmlXPathFreeObject(obj);
796}
const xmlChar * name
Definition: tree.h:492
struct _xmlNode * parent
Definition: tree.h:495
XMLPUBFUN const xmlChar *XMLCALL xmlStrstr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:345
#define BAD_CAST
Definition: xmlstring.h:35
#define XSLT_DEFAULT_VENDOR
Definition: xslt.h:32
#define XSLT_DEFAULT_URL
Definition: xslt.h:39
#define XSLT_NAMESPACE
Definition: xslt.h:46
#define XSLT_DEFAULT_VERSION
Definition: xslt.h:25

Referenced by xsltRegisterAllFunctions().

◆ xsltUnparsedEntityURIFunction()

void xsltUnparsedEntityURIFunction ( xmlXPathParserContextPtr  ctxt,
int  nargs 
)

xsltUnparsedEntityURIFunction: @ctxt: the XPath Parser context @nargs: the number of arguments

Implement the unparsed-entity-uri() XSLT function string unparsed-entity-uri(string)

Definition at line 524 of file functions.c.

524 {
525 xmlXPathObjectPtr obj;
526 xmlChar *str;
527
528 if ((nargs != 1) || (ctxt->value == NULL)) {
530 "unparsed-entity-uri() : expects one string arg\n");
531 ctxt->error = XPATH_INVALID_ARITY;
532 return;
533 }
534 obj = valuePop(ctxt);
535 if (obj->type != XPATH_STRING) {
536 obj = xmlXPathConvertString(obj);
537 }
538
539 str = obj->stringval;
540 if (str == NULL) {
541 valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
542 } else {
544
545 entity = xmlGetDocEntity(ctxt->context->doc, str);
546 if (entity == NULL) {
547 valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
548 } else {
549 if (entity->URI != NULL)
550 valuePush(ctxt, xmlXPathNewString(entity->URI));
551 else
552 valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
553 }
554 }
555 xmlXPathFreeObject(obj);
556}
XMLPUBFUN xmlEntityPtr XMLCALL xmlGetDocEntity(const xmlDoc *doc, const xmlChar *name)
Definition: actctx.c:446
xmlGenericErrorFunc xsltGenericError
Definition: xsltutils.c:502
void * xsltGenericErrorContext
Definition: xsltutils.c:503

Referenced by xsltRegisterAllFunctions().

◆ xsltXPathFunctionLookup()

xmlXPathFunction xsltXPathFunctionLookup ( void vctxt,
const xmlChar name,
const xmlChar ns_uri 
)

Definition at line 40 of file functions.c.

41 {
42 xmlXPathContextPtr ctxt = (xmlXPathContextPtr) vctxt;
43 xmlXPathFunction ret;
44
45 if ((ctxt == NULL) || (name == NULL) || (ns_uri == NULL))
46 return (NULL);
47
48#ifdef WITH_XSLT_DEBUG_FUNCTION
50 "Lookup function {%s}%s\n", ns_uri, name);
51#endif
52
53 /* give priority to context-level functions */
54 /*
55 ret = (xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri);
56 */
57 XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri);
58
59 if (ret == NULL)
61
62#ifdef WITH_XSLT_DEBUG_FUNCTION
63 if (ret != NULL)
65 "found function %s\n", name);
66#endif
67 return(ret);
68}
xmlXPathFunction xsltExtModuleFunctionLookup(const xmlChar *name, const xmlChar *URI)
Definition: extensions.c:1416
#define XML_CAST_FPTR(fptr)
Definition: hash.h:56
XMLPUBFUN void *XMLCALL xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2)
Definition: hash.c:476
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
void * xsltGenericDebugContext
Definition: xsltutils.c:549