ReactOS  0.4.14-dev-552-g2fad488
functions.c
Go to the documentation of this file.
1 /*
2  * functions.c: Implementation of the XSLT extra functions
3  *
4  * Reference:
5  * http://www.w3.org/TR/1999/REC-xslt-19991116
6  *
7  * See Copyright for the status of this software.
8  *
9  * daniel@veillard.com
10  * Bjorn Reese <breese@users.sourceforge.net> for number formatting
11  */
12 
13 #include "precomp.h"
14 
15 #include <libxml/xpointer.h>
16 
17 #ifdef WITH_XSLT_DEBUG
18 #define WITH_XSLT_DEBUG_FUNCTION
19 #endif
20 
21 /*
22  * Some versions of DocBook XSL use the vendor string to detect
23  * supporting chunking, this is a workaround to be considered
24  * in the list of decent XSLT processors <grin/>
25  */
26 #define DOCBOOK_XSL_HACK
27 
39 xmlXPathFunction
41  const xmlChar *name, const xmlChar *ns_uri) {
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 }
69 
70 
71 /************************************************************************
72  * *
73  * Module interfaces *
74  * *
75  ************************************************************************/
76 
77 static void
78 xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI)
79 {
81  xmlURIPtr uri;
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);
116  xmlFreeURI(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) {
148  xsltTransformError(tctxt, NULL, NULL,
149  "document() : internal error xptrctxt == NULL\n");
150  goto out_fragment;
151  }
152 
153  resObj = xmlXPtrEval(fragment, xptrctxt);
154  xmlXPathFreeContext(xptrctxt);
155 #endif
156 
157  if (resObj == NULL)
158  goto out_fragment;
159 
160  switch (resObj->type) {
161  case XPATH_NODESET:
162  break;
163  case XPATH_UNDEFINED:
164  case XPATH_BOOLEAN:
165  case XPATH_NUMBER:
166  case XPATH_STRING:
167  case XPATH_POINT:
168  case XPATH_USERS:
169  case XPATH_XSLT_TREE:
170  case XPATH_RANGE:
171  case XPATH_LOCATIONSET:
172  xsltTransformError(tctxt, NULL, NULL,
173  "document() : XPointer does not select a node set: #%s\n",
174  fragment);
175  goto out_object;
176  }
177 
178  valuePush(ctxt, resObj);
179  xmlFree(fragment);
180  return;
181 
182 out_object:
183  xmlXPathFreeObject(resObj);
184 
185 out_fragment:
186  valuePush(ctxt, xmlXPathNewNodeSet(NULL));
187  xmlFree(fragment);
188 }
189 
198 void
199 xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
200 {
201  xmlXPathObjectPtr obj, obj2 = NULL;
202  xmlChar *base = NULL, *URI;
203 
204 
205  if ((nargs < 1) || (nargs > 2)) {
207  "document() : invalid number of args %d\n",
208  nargs);
209  ctxt->error = XPATH_INVALID_ARITY;
210  return;
211  }
212  if (ctxt->value == NULL) {
214  "document() : invalid arg value\n");
215  ctxt->error = XPATH_INVALID_TYPE;
216  return;
217  }
218 
219  if (nargs == 2) {
220  if (ctxt->value->type != XPATH_NODESET) {
222  "document() : invalid arg expecting a nodeset\n");
223  ctxt->error = XPATH_INVALID_TYPE;
224  return;
225  }
226 
227  obj2 = valuePop(ctxt);
228  }
229 
230  if (ctxt->value->type == XPATH_NODESET) {
231  int i;
232  xmlXPathObjectPtr newobj, ret;
233 
234  obj = valuePop(ctxt);
235  ret = xmlXPathNewNodeSet(NULL);
236 
237  if ((obj != NULL) && obj->nodesetval) {
238  for (i = 0; i < obj->nodesetval->nodeNr; i++) {
239  valuePush(ctxt,
240  xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i]));
241  xmlXPathStringFunction(ctxt, 1);
242  if (nargs == 2) {
243  valuePush(ctxt, xmlXPathObjectCopy(obj2));
244  } else {
245  valuePush(ctxt,
246  xmlXPathNewNodeSet(obj->nodesetval->
247  nodeTab[i]));
248  }
249  xsltDocumentFunction(ctxt, 2);
250  newobj = valuePop(ctxt);
251  ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
252  newobj->nodesetval);
253  xmlXPathFreeObject(newobj);
254  }
255  }
256 
257  if (obj != NULL)
258  xmlXPathFreeObject(obj);
259  if (obj2 != NULL)
260  xmlXPathFreeObject(obj2);
261  valuePush(ctxt, ret);
262  return;
263  }
264  /*
265  * Make sure it's converted to a string
266  */
267  xmlXPathStringFunction(ctxt, 1);
268  if (ctxt->value->type != XPATH_STRING) {
270  "document() : invalid arg expecting a string\n");
271  ctxt->error = XPATH_INVALID_TYPE;
272  if (obj2 != NULL)
273  xmlXPathFreeObject(obj2);
274  return;
275  }
276  obj = valuePop(ctxt);
277  if (obj->stringval == NULL) {
278  valuePush(ctxt, xmlXPathNewNodeSet(NULL));
279  } else {
281  tctxt = xsltXPathGetTransformContext(ctxt);
282  if ((obj2 != NULL) && (obj2->nodesetval != NULL) &&
283  (obj2->nodesetval->nodeNr > 0) &&
284  IS_XSLT_REAL_NODE(obj2->nodesetval->nodeTab[0])) {
286 
287  target = obj2->nodesetval->nodeTab[0];
288  if ((target->type == XML_ATTRIBUTE_NODE) ||
289  (target->type == XML_PI_NODE)) {
290  target = ((xmlAttrPtr) target)->parent;
291  }
292  base = xmlNodeGetBase(target->doc, target);
293  } else {
294  if ((tctxt != NULL) && (tctxt->inst != NULL)) {
295  base = xmlNodeGetBase(tctxt->inst->doc, tctxt->inst);
296  } else if ((tctxt != NULL) && (tctxt->style != NULL) &&
297  (tctxt->style->doc != NULL)) {
298  base = xmlNodeGetBase(tctxt->style->doc,
299  (xmlNodePtr) tctxt->style->doc);
300  }
301  }
302  URI = xmlBuildURI(obj->stringval, base);
303  if (base != NULL)
304  xmlFree(base);
305  if (URI == NULL) {
306  if ((tctxt != NULL) && (tctxt->style != NULL) &&
307  (tctxt->style->doc != NULL) &&
308  (xmlStrEqual(URI, tctxt->style->doc->URL))) {
309  /* This selects the stylesheet's doc itself. */
310  valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) tctxt->style->doc));
311  } else {
312  valuePush(ctxt, xmlXPathNewNodeSet(NULL));
313  }
314  } else {
316  xmlFree(URI);
317  }
318  }
319  xmlXPathFreeObject(obj);
320  if (obj2 != NULL)
321  xmlXPathFreeObject(obj2);
322 }
323 
332 void
333 xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){
334  xmlXPathObjectPtr obj1, obj2;
335 
336  if (nargs != 2) {
338  "key() : expects two arguments\n");
339  ctxt->error = XPATH_INVALID_ARITY;
340  return;
341  }
342 
343  /*
344  * Get the key's value.
345  */
346  obj2 = valuePop(ctxt);
347  xmlXPathStringFunction(ctxt, 1);
348  if ((obj2 == NULL) ||
349  (ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
351  "key() : invalid arg expecting a string\n");
352  ctxt->error = XPATH_INVALID_TYPE;
353  xmlXPathFreeObject(obj2);
354 
355  return;
356  }
357  /*
358  * Get the key's name.
359  */
360  obj1 = valuePop(ctxt);
361 
362  if ((obj2->type == XPATH_NODESET) || (obj2->type == XPATH_XSLT_TREE)) {
363  int i;
364  xmlXPathObjectPtr newobj, ret;
365 
366  ret = xmlXPathNewNodeSet(NULL);
367 
368  if (obj2->nodesetval != NULL) {
369  for (i = 0; i < obj2->nodesetval->nodeNr; i++) {
370  valuePush(ctxt, xmlXPathObjectCopy(obj1));
371  valuePush(ctxt,
372  xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i]));
373  xmlXPathStringFunction(ctxt, 1);
374  xsltKeyFunction(ctxt, 2);
375  newobj = valuePop(ctxt);
376  ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
377  newobj->nodesetval);
378  xmlXPathFreeObject(newobj);
379  }
380  }
381  valuePush(ctxt, ret);
382  } else {
383  xmlNodeSetPtr nodelist = NULL;
384  xmlChar *key = NULL, *value;
385  const xmlChar *keyURI;
387  xmlChar *qname, *prefix;
388  xmlXPathContextPtr xpctxt = ctxt->context;
389  xmlNodePtr tmpNode = NULL;
390  xsltDocumentPtr oldDocInfo;
391 
392  tctxt = xsltXPathGetTransformContext(ctxt);
393 
394  oldDocInfo = tctxt->document;
395 
396  if (xpctxt->node == NULL) {
397  xsltTransformError(tctxt, NULL, tctxt->inst,
398  "Internal error in xsltKeyFunction(): "
399  "The context node is not set on the XPath context.\n");
400  tctxt->state = XSLT_STATE_STOPPED;
401  goto error;
402  }
403  /*
404  * Get the associated namespace URI if qualified name
405  */
406  qname = obj1->stringval;
407  key = xmlSplitQName2(qname, &prefix);
408  if (key == NULL) {
409  key = xmlStrdup(obj1->stringval);
410  keyURI = NULL;
411  if (prefix != NULL)
412  xmlFree(prefix);
413  } else {
414  if (prefix != NULL) {
415  keyURI = xmlXPathNsLookup(xpctxt, prefix);
416  if (keyURI == NULL) {
417  xsltTransformError(tctxt, NULL, tctxt->inst,
418  "key() : prefix %s is not bound\n", prefix);
419  /*
420  * TODO: Shouldn't we stop here?
421  */
422  }
423  xmlFree(prefix);
424  } else {
425  keyURI = NULL;
426  }
427  }
428 
429  /*
430  * Force conversion of first arg to string
431  */
432  valuePush(ctxt, obj2);
433  xmlXPathStringFunction(ctxt, 1);
434  if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
435  xsltTransformError(tctxt, NULL, tctxt->inst,
436  "key() : invalid arg expecting a string\n");
437  ctxt->error = XPATH_INVALID_TYPE;
438  goto error;
439  }
440  obj2 = valuePop(ctxt);
441  value = obj2->stringval;
442 
443  /*
444  * We need to ensure that ctxt->document is available for
445  * xsltGetKey().
446  * First find the relevant doc, which is the context node's
447  * owner doc; using context->doc is not safe, since
448  * the doc could have been acquired via the document() function,
449  * or the doc might be a Result Tree Fragment.
450  * FUTURE INFO: In XSLT 2.0 the key() function takes an additional
451  * argument indicating the doc to use.
452  */
453  if (xpctxt->node->type == XML_NAMESPACE_DECL) {
454  /*
455  * REVISIT: This is a libxml hack! Check xpath.c for details.
456  * The XPath module sets the owner element of a ns-node on
457  * the ns->next field.
458  */
459  if ((((xmlNsPtr) xpctxt->node)->next != NULL) &&
460  (((xmlNsPtr) xpctxt->node)->next->type == XML_ELEMENT_NODE))
461  {
462  tmpNode = (xmlNodePtr) ((xmlNsPtr) xpctxt->node)->next;
463  }
464  } else
465  tmpNode = xpctxt->node;
466 
467  if ((tmpNode == NULL) || (tmpNode->doc == NULL)) {
468  xsltTransformError(tctxt, NULL, tctxt->inst,
469  "Internal error in xsltKeyFunction(): "
470  "Couldn't get the doc of the XPath context node.\n");
471  goto error;
472  }
473 
474  if ((tctxt->document == NULL) ||
475  (tctxt->document->doc != tmpNode->doc))
476  {
477  if (tmpNode->doc->name && (tmpNode->doc->name[0] == ' ')) {
478  /*
479  * This is a Result Tree Fragment.
480  */
481  if (tmpNode->doc->_private == NULL) {
482  tmpNode->doc->_private = xsltNewDocument(tctxt, tmpNode->doc);
483  if (tmpNode->doc->_private == NULL)
484  goto error;
485  }
486  tctxt->document = (xsltDocumentPtr) tmpNode->doc->_private;
487  } else {
488  /*
489  * May be the initial source doc or a doc acquired via the
490  * document() function.
491  */
492  tctxt->document = xsltFindDocument(tctxt, tmpNode->doc);
493  }
494  if (tctxt->document == NULL) {
495  xsltTransformError(tctxt, NULL, tctxt->inst,
496  "Internal error in xsltKeyFunction(): "
497  "Could not get the document info of a context doc.\n");
498  tctxt->state = XSLT_STATE_STOPPED;
499  goto error;
500  }
501  }
502  /*
503  * Get/compute the key value.
504  */
505  nodelist = xsltGetKey(tctxt, key, keyURI, value);
506 
507 error:
508  tctxt->document = oldDocInfo;
509  valuePush(ctxt, xmlXPathWrapNodeSet(
510  xmlXPathNodeSetMerge(NULL, nodelist)));
511  if (key != NULL)
512  xmlFree(key);
513  }
514 
515  if (obj1 != NULL)
516  xmlXPathFreeObject(obj1);
517  if (obj2 != NULL)
518  xmlXPathFreeObject(obj2);
519 }
520 
529 void
530 xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){
531  xmlXPathObjectPtr obj;
532  xmlChar *str;
533 
534  if ((nargs != 1) || (ctxt->value == NULL)) {
536  "unparsed-entity-uri() : expects one string arg\n");
537  ctxt->error = XPATH_INVALID_ARITY;
538  return;
539  }
540  obj = valuePop(ctxt);
541  if (obj->type != XPATH_STRING) {
542  obj = xmlXPathConvertString(obj);
543  }
544 
545  str = obj->stringval;
546  if (str == NULL) {
547  valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
548  } else {
550 
551  entity = xmlGetDocEntity(ctxt->context->doc, str);
552  if (entity == NULL) {
553  valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
554  } else {
555  if (entity->URI != NULL)
556  valuePush(ctxt, xmlXPathNewString(entity->URI));
557  else
558  valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
559  }
560  }
561  xmlXPathFreeObject(obj);
562 }
563 
572 void
573 xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs)
574 {
575  xmlXPathObjectPtr numberObj = NULL;
576  xmlXPathObjectPtr formatObj = NULL;
577  xmlXPathObjectPtr decimalObj = NULL;
578  xsltStylesheetPtr sheet;
579  xsltDecimalFormatPtr formatValues = NULL;
580  xmlChar *result;
581  const xmlChar *ncname;
582  const xmlChar *prefix = NULL;
583  const xmlChar *nsUri = NULL;
585 
586  tctxt = xsltXPathGetTransformContext(ctxt);
587  if ((tctxt == NULL) || (tctxt->inst == NULL))
588  return;
589  sheet = tctxt->style;
590  if (sheet == NULL)
591  return;
592  formatValues = sheet->decimalFormat;
593 
594  switch (nargs) {
595  case 3:
596  CAST_TO_STRING;
597  decimalObj = valuePop(ctxt);
598  ncname = xsltSplitQName(sheet->dict, decimalObj->stringval, &prefix);
599  if (prefix != NULL) {
600  xmlNsPtr ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, prefix);
601  if (ns == NULL) {
602  xsltTransformError(tctxt, NULL, NULL,
603  "format-number : No namespace found for QName '%s:%s'\n",
604  prefix, ncname);
605  sheet->errors++;
606  ncname = NULL;
607  }
608  else {
609  nsUri = ns->href;
610  }
611  }
612  if (ncname != NULL) {
613  formatValues = xsltDecimalFormatGetByQName(sheet, nsUri, ncname);
614  }
615  if (formatValues == NULL) {
616  xsltTransformError(tctxt, NULL, NULL,
617  "format-number() : undeclared decimal format '%s'\n",
618  decimalObj->stringval);
619  }
620  /* Intentional fall-through */
621  case 2:
622  CAST_TO_STRING;
623  formatObj = valuePop(ctxt);
624  CAST_TO_NUMBER;
625  numberObj = valuePop(ctxt);
626  break;
627  default:
628  XP_ERROR(XPATH_INVALID_ARITY);
629  }
630 
631  if (formatValues != NULL) {
632  if (xsltFormatNumberConversion(formatValues,
633  formatObj->stringval,
634  numberObj->floatval,
635  &result) == XPATH_EXPRESSION_OK) {
636  valuePush(ctxt, xmlXPathNewString(result));
637  xmlFree(result);
638  }
639  }
640 
641  xmlXPathFreeObject(numberObj);
642  xmlXPathFreeObject(formatObj);
643  xmlXPathFreeObject(decimalObj);
644 }
645 
654 void
655 xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
656  static char base_address;
657  xmlNodePtr cur = NULL;
658  xmlXPathObjectPtr obj = NULL;
659  long val;
660  xmlChar str[30];
661 
662  if (nargs == 0) {
663  cur = ctxt->context->node;
664  } else if (nargs == 1) {
665  xmlNodeSetPtr nodelist;
666  int i, ret;
667 
668  if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
669  ctxt->error = XPATH_INVALID_TYPE;
671  "generate-id() : invalid arg expecting a node-set\n");
672  return;
673  }
674  obj = valuePop(ctxt);
675  nodelist = obj->nodesetval;
676  if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
677  xmlXPathFreeObject(obj);
678  valuePush(ctxt, xmlXPathNewCString(""));
679  return;
680  }
681  cur = nodelist->nodeTab[0];
682  for (i = 1;i < nodelist->nodeNr;i++) {
683  ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
684  if (ret == -1)
685  cur = nodelist->nodeTab[i];
686  }
687  } else {
689  "generate-id() : invalid number of args %d\n", nargs);
690  ctxt->error = XPATH_INVALID_ARITY;
691  return;
692  }
693 
694  if (obj)
695  xmlXPathFreeObject(obj);
696 
697  val = (long)((char *)cur - (char *)&base_address);
698  if (val >= 0) {
699  snprintf((char *)str, sizeof(str), "idp%ld", val);
700  } else {
701  snprintf((char *)str, sizeof(str), "idm%ld", -val);
702  }
703  valuePush(ctxt, xmlXPathNewString(str));
704 }
705 
714 void
715 xsltSystemPropertyFunction(xmlXPathParserContextPtr ctxt, int nargs){
716  xmlXPathObjectPtr obj;
717  xmlChar *prefix, *name;
718  const xmlChar *nsURI = NULL;
719 
720  if (nargs != 1) {
722  "system-property() : expects one string arg\n");
723  ctxt->error = XPATH_INVALID_ARITY;
724  return;
725  }
726  if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
728  "system-property() : invalid arg expecting a string\n");
729  ctxt->error = XPATH_INVALID_TYPE;
730  return;
731  }
732  obj = valuePop(ctxt);
733  if (obj->stringval == NULL) {
734  valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
735  } else {
736  name = xmlSplitQName2(obj->stringval, &prefix);
737  if (name == NULL) {
738  name = xmlStrdup(obj->stringval);
739  } else {
740  nsURI = xmlXPathNsLookup(ctxt->context, prefix);
741  if (nsURI == NULL) {
743  "system-property() : prefix %s is not bound\n", prefix);
744  }
745  }
746 
747  if (xmlStrEqual(nsURI, XSLT_NAMESPACE)) {
748 #ifdef DOCBOOK_XSL_HACK
749  if (xmlStrEqual(name, (const xmlChar *)"vendor")) {
750  xsltStylesheetPtr sheet;
752 
753  tctxt = xsltXPathGetTransformContext(ctxt);
754  if ((tctxt != NULL) && (tctxt->inst != NULL) &&
755  (xmlStrEqual(tctxt->inst->name, BAD_CAST "variable")) &&
756  (tctxt->inst->parent != NULL) &&
757  (xmlStrEqual(tctxt->inst->parent->name,
758  BAD_CAST "template")))
759  sheet = tctxt->style;
760  else
761  sheet = NULL;
762  if ((sheet != NULL) && (sheet->doc != NULL) &&
763  (sheet->doc->URL != NULL) &&
764  (xmlStrstr(sheet->doc->URL,
765  (const xmlChar *)"chunk") != NULL)) {
766  valuePush(ctxt, xmlXPathNewString(
767  (const xmlChar *)"libxslt (SAXON 6.2 compatible)"));
768 
769  } else {
770  valuePush(ctxt, xmlXPathNewString(
771  (const xmlChar *)XSLT_DEFAULT_VENDOR));
772  }
773  } else
774 #else
775  if (xmlStrEqual(name, (const xmlChar *)"vendor")) {
776  valuePush(ctxt, xmlXPathNewString(
777  (const xmlChar *)XSLT_DEFAULT_VENDOR));
778  } else
779 #endif
780  if (xmlStrEqual(name, (const xmlChar *)"version")) {
781  valuePush(ctxt, xmlXPathNewString(
782  (const xmlChar *)XSLT_DEFAULT_VERSION));
783  } else if (xmlStrEqual(name, (const xmlChar *)"vendor-url")) {
784  valuePush(ctxt, xmlXPathNewString(
785  (const xmlChar *)XSLT_DEFAULT_URL));
786  } else {
787  valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
788  }
789  } else {
790  valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
791  }
792  if (name != NULL)
793  xmlFree(name);
794  if (prefix != NULL)
795  xmlFree(prefix);
796  }
797  xmlXPathFreeObject(obj);
798 }
799 
808 void
809 xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){
810  xmlXPathObjectPtr obj;
811  xmlChar *prefix, *name;
812  const xmlChar *nsURI = NULL;
814 
815  if (nargs != 1) {
817  "element-available() : expects one string arg\n");
818  ctxt->error = XPATH_INVALID_ARITY;
819  return;
820  }
821  xmlXPathStringFunction(ctxt, 1);
822  if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
824  "element-available() : invalid arg expecting a string\n");
825  ctxt->error = XPATH_INVALID_TYPE;
826  return;
827  }
828  obj = valuePop(ctxt);
829  tctxt = xsltXPathGetTransformContext(ctxt);
830  if ((tctxt == NULL) || (tctxt->inst == NULL)) {
832  "element-available() : internal error tctxt == NULL\n");
833  xmlXPathFreeObject(obj);
834  valuePush(ctxt, xmlXPathNewBoolean(0));
835  return;
836  }
837 
838 
839  name = xmlSplitQName2(obj->stringval, &prefix);
840  if (name == NULL) {
841  xmlNsPtr ns;
842 
843  name = xmlStrdup(obj->stringval);
844  ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, NULL);
845  if (ns != NULL) nsURI = ns->href;
846  } else {
847  nsURI = xmlXPathNsLookup(ctxt->context, prefix);
848  if (nsURI == NULL) {
850  "element-available() : prefix %s is not bound\n", prefix);
851  }
852  }
853 
854  if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) {
855  valuePush(ctxt, xmlXPathNewBoolean(1));
856  } else {
857  valuePush(ctxt, xmlXPathNewBoolean(0));
858  }
859 
860  xmlXPathFreeObject(obj);
861  if (name != NULL)
862  xmlFree(name);
863  if (prefix != NULL)
864  xmlFree(prefix);
865 }
866 
875 void
876 xsltFunctionAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){
877  xmlXPathObjectPtr obj;
878  xmlChar *prefix, *name;
879  const xmlChar *nsURI = NULL;
880 
881  if (nargs != 1) {
883  "function-available() : expects one string arg\n");
884  ctxt->error = XPATH_INVALID_ARITY;
885  return;
886  }
887  xmlXPathStringFunction(ctxt, 1);
888  if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
890  "function-available() : invalid arg expecting a string\n");
891  ctxt->error = XPATH_INVALID_TYPE;
892  return;
893  }
894  obj = valuePop(ctxt);
895 
896  name = xmlSplitQName2(obj->stringval, &prefix);
897  if (name == NULL) {
898  name = xmlStrdup(obj->stringval);
899  } else {
900  nsURI = xmlXPathNsLookup(ctxt->context, prefix);
901  if (nsURI == NULL) {
903  "function-available() : prefix %s is not bound\n", prefix);
904  }
905  }
906 
907  if (xmlXPathFunctionLookupNS(ctxt->context, name, nsURI) != NULL) {
908  valuePush(ctxt, xmlXPathNewBoolean(1));
909  } else {
910  valuePush(ctxt, xmlXPathNewBoolean(0));
911  }
912 
913  xmlXPathFreeObject(obj);
914  if (name != NULL)
915  xmlFree(name);
916  if (prefix != NULL)
917  xmlFree(prefix);
918 }
919 
928 static void
929 xsltCurrentFunction(xmlXPathParserContextPtr ctxt, int nargs){
931 
932  if (nargs != 0) {
934  "current() : function uses no argument\n");
935  ctxt->error = XPATH_INVALID_ARITY;
936  return;
937  }
938  tctxt = xsltXPathGetTransformContext(ctxt);
939  if (tctxt == NULL) {
941  "current() : internal error tctxt == NULL\n");
942  valuePush(ctxt, xmlXPathNewNodeSet(NULL));
943  } else {
944  valuePush(ctxt, xmlXPathNewNodeSet(tctxt->node)); /* current */
945  }
946 }
947 
948 /************************************************************************
949  * *
950  * Registration of XSLT and libxslt functions *
951  * *
952  ************************************************************************/
953 
960 void
961 xsltRegisterAllFunctions(xmlXPathContextPtr ctxt)
962 {
963  xmlXPathRegisterFunc(ctxt, (const xmlChar *) "current",
965  xmlXPathRegisterFunc(ctxt, (const xmlChar *) "document",
967  xmlXPathRegisterFunc(ctxt, (const xmlChar *) "key", xsltKeyFunction);
968  xmlXPathRegisterFunc(ctxt, (const xmlChar *) "unparsed-entity-uri",
970  xmlXPathRegisterFunc(ctxt, (const xmlChar *) "format-number",
972  xmlXPathRegisterFunc(ctxt, (const xmlChar *) "generate-id",
974  xmlXPathRegisterFunc(ctxt, (const xmlChar *) "system-property",
976  xmlXPathRegisterFunc(ctxt, (const xmlChar *) "element-available",
978  xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available",
980 }
XMLPUBFUN const xmlChar *XMLCALL xmlStrstr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:341
static void xsltCurrentFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:929
const xmlChar * URL
Definition: tree.h:577
#define error(str)
Definition: mkdosfs.c:1605
const xmlChar * name
Definition: tree.h:492
const char * uri
Definition: sec_mgr.c:1594
Definition: tree.h:389
void xsltSystemPropertyFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:715
void xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:655
#define snprintf
Definition: wintirpc.h:48
#define XSLT_DEFAULT_URL
Definition: xslt.h:39
void xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:809
#define XSLT_DEFAULT_VENDOR
Definition: xslt.h:32
XMLPUBFUN xmlURIPtr XMLCALL xmlParseURI(const char *str)
Definition: uri.c:932
#define XSLT_NAMESPACE
Definition: xslt.h:46
XMLPUBFUN xmlChar *XMLCALL xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur)
xsltDocument * xsltDocumentPtr
XMLPUBFUN void *XMLCALL xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2)
Definition: hash.c:474
xmlDocPtr doc
struct _xmlDoc * doc
Definition: tree.h:498
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
void xsltFunctionAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:876
void xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:199
void xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:333
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
Definition: actctx.c:371
xmlGenericErrorFunc xsltGenericError
Definition: xsltutils.c:502
xsltTransformState state
void xsltRegisterAllFunctions(xmlXPathContextPtr ctxt)
Definition: functions.c:961
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
XMLPUBFUN xmlChar *XMLCALL xmlBuildURI(const xmlChar *URI, const xmlChar *base)
Definition: uri.c:1882
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
xmlNode * xmlNodePtr
Definition: tree.h:488
#define BAD_CAST
Definition: xmlstring.h:35
xsltDocumentPtr document
xsltTransformFunction xsltExtElementLookup(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *URI)
Definition: extensions.c:1668
void xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:530
GLuint GLfloat * val
Definition: glext.h:7180
struct _xmlNode * parent
Definition: tree.h:495
xmlXPathFunction xsltExtModuleFunctionLookup(const xmlChar *name, const xmlChar *URI)
Definition: extensions.c:1416
xsltDecimalFormatPtr xsltDecimalFormatGetByQName(xsltStylesheetPtr style, const xmlChar *nsUri, const xmlChar *name)
Definition: xslt.c:364
void * xsltGenericDebugContext
Definition: xsltutils.c:549
xmlNodeSetPtr xsltGetKey(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI, const xmlChar *value)
Definition: keys.c:415
if(!(yy_init))
Definition: macro.lex.yy.c:714
const xmlChar * xsltSplitQName(xmlDictPtr dict, const xmlChar *name, const xmlChar **prefix)
Definition: xsltutils.c:720
#define IS_XSLT_REAL_NODE(n)
Definition: xsltutils.h:71
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
void * xsltGenericErrorContext
Definition: xsltutils.c:503
Definition: tree.h:489
xsltDecimalFormatPtr decimalFormat
XMLPUBFUN xmlEntityPtr XMLCALL xmlGetDocEntity(const xmlDoc *doc, const xmlChar *name)
int ret
xmlAttr * xmlAttrPtr
Definition: tree.h:433
Definition: mxnamespace.c:44
unsigned char xmlChar
Definition: xmlstring.h:28
GLsizei const GLfloat * value
Definition: glext.h:6069
static void xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar *URI)
Definition: functions.c:78
void xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs)
Definition: functions.c:573
Definition: uri.h:33
xsltStylesheetPtr style
static unsigned __int64 next
Definition: rand_nt.c:6
xmlXPathFunction xsltXPathFunctionLookup(void *vctxt, const xmlChar *name, const xmlChar *ns_uri)
Definition: functions.c:40
#define XML_CAST_FPTR(fptr)
Definition: hash.h:56
xsltDocumentPtr xsltLoadDocument(xsltTransformContextPtr ctxt, const xmlChar *URI)
Definition: documents.c:268
#define long
Definition: qsort.c:33
xmlXPathError xsltFormatNumberConversion(xsltDecimalFormatPtr self, xmlChar *format, double number, xmlChar **result)
Definition: numbers.c:910
#define XSLT_DEFAULT_VERSION
Definition: xslt.h:25
XMLPUBFUN void XMLCALL xmlFreeURI(xmlURIPtr uri)
Definition: uri.c:1379
Definition: tree.h:551
Definition: name.c:38
xsltTransformContextPtr xsltXPathGetTransformContext(xmlXPathParserContextPtr ctxt)
Definition: extensions.c:1367
GLenum target
Definition: glext.h:7315
xsltDocumentPtr xsltFindDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc)
Definition: documents.c:398
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
GLuint64EXT * result
Definition: glext.h:11304
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:66
xsltDocumentPtr xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc)
Definition: documents.c:127
XMLPUBFUN xmlChar *XMLCALL xmlSaveUri(xmlURIPtr uri)
Definition: uri.c:1058
Definition: path.c:42
XMLPUBFUN xmlChar *XMLCALL xmlSplitQName2(const xmlChar *name, xmlChar **prefix)
GLuint const GLchar * name
Definition: glext.h:6031