VirtualBox

source: vbox/trunk/src/libs/libxslt-1.1.22/libexslt/math.c@ 28321

Last change on this file since 28321 was 7299, checked in by vboxsync, 17 years ago

Added vboxconfig.h for linux builds.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 24.0 KB
Line 
1#define IN_LIBEXSLT
2#include "libexslt/libexslt.h"
3
4#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__)
5#include <win32config.h>
6#elif defined(VBOX)
7#include "vboxconfig.h"
8#else
9#include "config.h"
10#endif
11
12#include <libxml/tree.h>
13#include <libxml/xpath.h>
14#include <libxml/xpathInternals.h>
15
16#include <libxslt/xsltconfig.h>
17#include <libxslt/xsltutils.h>
18#include <libxslt/xsltInternals.h>
19#include <libxslt/extensions.h>
20
21#ifdef HAVE_MATH_H
22#include <math.h>
23#endif
24
25#ifdef HAVE_STDLIB_H
26#include <stdlib.h>
27#endif
28
29#include "exslt.h"
30
31/**
32 * exsltMathMin:
33 * @ns: a node-set
34 *
35 * Implements the EXSLT - Math min() function:
36 * number math:min (node-set)
37 *
38 * Returns the minimum value of the nodes passed as the argument, or
39 * xmlXPathNAN if @ns is NULL or empty or if one of the nodes
40 * turns into NaN.
41 */
42static double
43exsltMathMin (xmlNodeSetPtr ns) {
44 double ret, cur;
45 int i;
46
47 if ((ns == NULL) || (ns->nodeNr == 0))
48 return(xmlXPathNAN);
49 ret = xmlXPathCastNodeToNumber(ns->nodeTab[0]);
50 if (xmlXPathIsNaN(ret))
51 return(xmlXPathNAN);
52 for (i = 1; i < ns->nodeNr; i++) {
53 cur = xmlXPathCastNodeToNumber(ns->nodeTab[i]);
54 if (xmlXPathIsNaN(cur))
55 return(xmlXPathNAN);
56 if (cur < ret)
57 ret = cur;
58 }
59 return(ret);
60}
61
62/**
63 * exsltMathMinFunction:
64 * @ctxt: an XPath parser context
65 * @nargs: the number of arguments
66 *
67 * Wraps #exsltMathMin for use by the XPath processor.
68 */
69static void
70exsltMathMinFunction (xmlXPathParserContextPtr ctxt, int nargs) {
71 xmlNodeSetPtr ns;
72 double ret;
73 void *user = NULL;
74
75 if (nargs != 1) {
76 xsltGenericError(xsltGenericErrorContext,
77 "math:min: invalid number of arguments\n");
78 ctxt->error = XPATH_INVALID_ARITY;
79 return;
80 }
81 /* We need to delay the freeing of value->user */
82 if ((ctxt->value != NULL) && (ctxt->value->boolval != 0)) {
83 user = ctxt->value->user;
84 ctxt->value->boolval = 0;
85 ctxt->value->user = NULL;
86 }
87 ns = xmlXPathPopNodeSet(ctxt);
88 if (xmlXPathCheckError(ctxt))
89 return;
90
91 ret = exsltMathMin(ns);
92
93 xmlXPathFreeNodeSet(ns);
94 if (user != NULL)
95 xmlFreeNodeList((xmlNodePtr)user);
96
97 xmlXPathReturnNumber(ctxt, ret);
98}
99
100/**
101 * exsltMathMax:
102 * @ns: a node-set
103 *
104 * Implements the EXSLT - Math max() function:
105 * number math:max (node-set)
106 *
107 * Returns the maximum value of the nodes passed as arguments, or
108 * xmlXPathNAN if @ns is NULL or empty or if one of the nodes
109 * turns into NaN.
110 */
111static double
112exsltMathMax (xmlNodeSetPtr ns) {
113 double ret, cur;
114 int i;
115
116 if ((ns == NULL) || (ns->nodeNr == 0))
117 return(xmlXPathNAN);
118 ret = xmlXPathCastNodeToNumber(ns->nodeTab[0]);
119 if (xmlXPathIsNaN(ret))
120 return(xmlXPathNAN);
121 for (i = 1; i < ns->nodeNr; i++) {
122 cur = xmlXPathCastNodeToNumber(ns->nodeTab[i]);
123 if (xmlXPathIsNaN(cur))
124 return(xmlXPathNAN);
125 if (cur > ret)
126 ret = cur;
127 }
128 return(ret);
129}
130
131/**
132 * exsltMathMaxFunction:
133 * @ctxt: an XPath parser context
134 * @nargs: the number of arguments
135 *
136 * Wraps #exsltMathMax for use by the XPath processor.
137 */
138static void
139exsltMathMaxFunction (xmlXPathParserContextPtr ctxt, int nargs) {
140 xmlNodeSetPtr ns;
141 double ret;
142 void *user = NULL;
143
144 if (nargs != 1) {
145 xmlXPathSetArityError(ctxt);
146 return;
147 }
148
149 /* We need to delay the freeing of value->user */
150 if ((ctxt->value != NULL) && (ctxt->value->boolval != 0)) {
151 user = ctxt->value->user;
152 ctxt->value->boolval = 0;
153 ctxt->value->user = 0;
154 }
155 ns = xmlXPathPopNodeSet(ctxt);
156 if (xmlXPathCheckError(ctxt))
157 return;
158
159 ret = exsltMathMax(ns);
160
161 xmlXPathFreeNodeSet(ns);
162
163 if (user != NULL)
164 xmlFreeNodeList((xmlNodePtr)user);
165 xmlXPathReturnNumber(ctxt, ret);
166}
167
168/**
169 * exsltMathHighest:
170 * @ns: a node-set
171 *
172 * Implements the EXSLT - Math highest() function:
173 * node-set math:highest (node-set)
174 *
175 * Returns the nodes in the node-set whose value is the maximum value
176 * for the node-set.
177 */
178static xmlNodeSetPtr
179exsltMathHighest (xmlNodeSetPtr ns) {
180 xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL);
181 double max, cur;
182 int i;
183
184 if ((ns == NULL) || (ns->nodeNr == 0))
185 return(ret);
186
187 max = xmlXPathCastNodeToNumber(ns->nodeTab[0]);
188 if (xmlXPathIsNaN(max))
189 return(ret);
190 else
191 xmlXPathNodeSetAddUnique(ret, ns->nodeTab[0]);
192
193 for (i = 1; i < ns->nodeNr; i++) {
194 cur = xmlXPathCastNodeToNumber(ns->nodeTab[i]);
195 if (xmlXPathIsNaN(cur)) {
196 xmlXPathEmptyNodeSet(ret);
197 return(ret);
198 }
199 if (cur < max)
200 continue;
201 if (cur > max) {
202 max = cur;
203 xmlXPathEmptyNodeSet(ret);
204 xmlXPathNodeSetAddUnique(ret, ns->nodeTab[i]);
205 continue;
206 }
207 xmlXPathNodeSetAddUnique(ret, ns->nodeTab[i]);
208 }
209 return(ret);
210}
211
212/**
213 * exsltMathHighestFunction:
214 * @ctxt: an XPath parser context
215 * @nargs: the number of arguments
216 *
217 * Wraps #exsltMathHighest for use by the XPath processor
218 */
219static void
220exsltMathHighestFunction (xmlXPathParserContextPtr ctxt, int nargs) {
221 xmlNodeSetPtr ns, ret;
222 void *user = NULL;
223
224 if (nargs != 1) {
225 xmlXPathSetArityError(ctxt);
226 return;
227 }
228
229 /* We need to delay the freeing of value->user */
230 if ((ctxt->value != NULL) && ctxt->value->boolval != 0) {
231 user = ctxt->value->user;
232 ctxt->value->boolval = 0;
233 ctxt->value->user = NULL;
234 }
235 ns = xmlXPathPopNodeSet(ctxt);
236 if (xmlXPathCheckError(ctxt))
237 return;
238
239 ret = exsltMathHighest(ns);
240
241 xmlXPathFreeNodeSet(ns);
242 if (user != NULL)
243 xmlFreeNodeList((xmlNodePtr)user);
244
245 xmlXPathReturnNodeSet(ctxt, ret);
246}
247
248/**
249 * exsltMathLowest:
250 * @ns: a node-set
251 *
252 * Implements the EXSLT - Math lowest() function
253 * node-set math:lowest (node-set)
254 *
255 * Returns the nodes in the node-set whose value is the minimum value
256 * for the node-set.
257 */
258static xmlNodeSetPtr
259exsltMathLowest (xmlNodeSetPtr ns) {
260 xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL);
261 double min, cur;
262 int i;
263
264 if ((ns == NULL) || (ns->nodeNr == 0))
265 return(ret);
266
267 min = xmlXPathCastNodeToNumber(ns->nodeTab[0]);
268 if (xmlXPathIsNaN(min))
269 return(ret);
270 else
271 xmlXPathNodeSetAddUnique(ret, ns->nodeTab[0]);
272
273 for (i = 1; i < ns->nodeNr; i++) {
274 cur = xmlXPathCastNodeToNumber(ns->nodeTab[i]);
275 if (xmlXPathIsNaN(cur)) {
276 xmlXPathEmptyNodeSet(ret);
277 return(ret);
278 }
279 if (cur > min)
280 continue;
281 if (cur < min) {
282 min = cur;
283 xmlXPathEmptyNodeSet(ret);
284 xmlXPathNodeSetAddUnique(ret, ns->nodeTab[i]);
285 continue;
286 }
287 xmlXPathNodeSetAddUnique(ret, ns->nodeTab[i]);
288 }
289 return(ret);
290}
291
292/**
293 * exsltMathLowestFunction:
294 * @ctxt: an XPath parser context
295 * @nargs: the number of arguments
296 *
297 * Wraps #exsltMathLowest for use by the XPath processor
298 */
299static void
300exsltMathLowestFunction (xmlXPathParserContextPtr ctxt, int nargs) {
301 xmlNodeSetPtr ns, ret;
302 void *user = NULL;
303
304
305 if (nargs != 1) {
306 xmlXPathSetArityError(ctxt);
307 return;
308 }
309
310 /* We need to delay the freeing of value->user */
311 if ((ctxt->value != NULL) && (ctxt->value->boolval != 0)) {
312 user = ctxt->value->user;
313 ctxt->value->boolval = 0;
314 ctxt->value->user = NULL;
315 }
316 ns = xmlXPathPopNodeSet(ctxt);
317 if (xmlXPathCheckError(ctxt))
318 return;
319
320 ret = exsltMathLowest(ns);
321
322 xmlXPathFreeNodeSet(ns);
323 if (user != NULL)
324 xmlFreeNodeList((xmlNodePtr)user);
325
326 xmlXPathReturnNodeSet(ctxt, ret);
327}
328
329/* math other functions */
330
331/* constant values */
332#define EXSLT_PI (const xmlChar *) \
333 "3.1415926535897932384626433832795028841971693993751"
334#define EXSLT_E (const xmlChar *) \
335 "2.71828182845904523536028747135266249775724709369996"
336#define EXSLT_SQRRT2 (const xmlChar *) \
337 "1.41421356237309504880168872420969807856967187537694"
338#define EXSLT_LN2 (const xmlChar *) \
339 "0.69314718055994530941723212145817656807550013436025"
340#define EXSLT_LN10 (const xmlChar *) \
341 "2.30258509299404568402"
342#define EXSLT_LOG2E (const xmlChar *) \
343 "1.4426950408889634074"
344#define EXSLT_SQRT1_2 (const xmlChar *) \
345 "0.70710678118654752440"
346
347/**
348 * exsltMathConstant
349 * @name: string
350 * @precision: number
351 *
352 * Implements the EXSLT - Math constant function:
353 * number math:constant(string, number)
354 *
355 * Returns a number value of the given constant with the given precision or
356 * xmlXPathNAN if name is unknown.
357 * The constants are PI, E, SQRRT2, LN2, LN10, LOG2E, and SQRT1_2
358 */
359static double
360exsltMathConstant (xmlChar *name, double precision) {
361 xmlChar *str;
362 double ret;
363
364 if ((name == NULL) || (xmlXPathIsNaN(precision)) || (precision < 1.0)) {
365 return xmlXPathNAN;
366 }
367
368 if (xmlStrEqual(name, BAD_CAST "PI")) {
369 int len = xmlStrlen(EXSLT_PI);
370
371 if (precision <= len)
372 len = (int)precision;
373
374 str = xmlStrsub(EXSLT_PI, 0, len);
375
376 } else if (xmlStrEqual(name, BAD_CAST "E")) {
377 int len = xmlStrlen(EXSLT_E);
378
379 if (precision <= len)
380 len = (int)precision;
381
382 str = xmlStrsub(EXSLT_E, 0, len);
383
384 } else if (xmlStrEqual(name, BAD_CAST "SQRRT2")) {
385 int len = xmlStrlen(EXSLT_SQRRT2);
386
387 if (precision <= len)
388 len = (int)precision;
389
390 str = xmlStrsub(EXSLT_SQRRT2, 0, len);
391
392 } else if (xmlStrEqual(name, BAD_CAST "LN2")) {
393 int len = xmlStrlen(EXSLT_LN2);
394
395 if (precision <= len)
396 len = (int)precision;
397
398 str = xmlStrsub(EXSLT_LN2, 0, len);
399
400 } else if (xmlStrEqual(name, BAD_CAST "LN10")) {
401 int len = xmlStrlen(EXSLT_LN10);
402
403 if (precision <= len)
404 len = (int)precision;
405
406 str = xmlStrsub(EXSLT_LN10, 0, len);
407
408 } else if (xmlStrEqual(name, BAD_CAST "LOG2E")) {
409 int len = xmlStrlen(EXSLT_LOG2E);
410
411 if (precision <= len)
412 len = (int)precision;
413
414 str = xmlStrsub(EXSLT_LOG2E, 0, len);
415
416 } else if (xmlStrEqual(name, BAD_CAST "SQRT1_2")) {
417 int len = xmlStrlen(EXSLT_SQRT1_2);
418
419 if (precision <= len)
420 len = (int)precision;
421
422 str = xmlStrsub(EXSLT_SQRT1_2, 0, len);
423
424 } else {
425 str = NULL;
426 }
427 if (str == NULL)
428 return xmlXPathNAN;
429 ret = xmlXPathCastStringToNumber(str);
430 xmlFree(str);
431 return ret;
432}
433
434/**
435 * exsltMathConstantFunction:
436 * @ctxt: an XPath parser context
437 * @nargs: the number of arguments
438 *
439 * Wraps #exsltMathConstant for use by the XPath processor.
440 */
441static void
442exsltMathConstantFunction (xmlXPathParserContextPtr ctxt, int nargs) {
443 double ret;
444 xmlChar *name;
445
446 if (nargs != 2) {
447 xmlXPathSetArityError(ctxt);
448 return;
449 }
450 ret = xmlXPathPopNumber(ctxt);
451 if (xmlXPathCheckError(ctxt))
452 return;
453
454 name = xmlXPathPopString(ctxt);
455 if (xmlXPathCheckError(ctxt))
456 return;
457
458 ret = exsltMathConstant(name, ret);
459 if (name != NULL)
460 xmlFree(name);
461
462 xmlXPathReturnNumber(ctxt, ret);
463}
464
465#if defined(HAVE_STDLIB_H) && defined(RAND_MAX)
466
467/**
468 * exsltMathRandom:
469 *
470 * Implements the EXSLT - Math random() function:
471 * number math:random ()
472 *
473 * Returns a random number between 0 and 1 inclusive.
474 */
475static double
476exsltMathRandom (void) {
477 double ret;
478 int num;
479
480 num = rand();
481 ret = (double)num / (double)RAND_MAX;
482 return(ret);
483}
484
485/**
486 * exsltMathRandomFunction:
487 * @ctxt: an XPath parser context
488 * @nargs: the number of arguments
489 *
490 * Wraps #exsltMathRandom for use by the XPath processor.
491 */
492static void
493exsltMathRandomFunction (xmlXPathParserContextPtr ctxt, int nargs) {
494 double ret;
495
496 if (nargs != 0) {
497 xmlXPathSetArityError(ctxt);
498 return;
499 }
500
501 ret = exsltMathRandom();
502
503 xmlXPathReturnNumber(ctxt, ret);
504}
505
506#endif /* defined(HAVE_STDLIB_H) && defined(RAND_MAX) */
507
508#if HAVE_MATH_H
509
510/**
511 * exsltMathAbs:
512 * @num: a double
513 *
514 * Implements the EXSLT - Math abs() function:
515 * number math:abs (number)
516 *
517 * Returns the absolute value of the argument, or xmlXPathNAN if @num is Nan.
518 */
519static double
520exsltMathAbs (double num) {
521 double ret;
522
523 if (xmlXPathIsNaN(num))
524 return(xmlXPathNAN);
525 ret = fabs(num);
526 return(ret);
527}
528
529/**
530 * exsltMathAbsFunction:
531 * @ctxt: an XPath parser context
532 * @nargs: the number of arguments
533 *
534 * Wraps #exsltMathAbs for use by the XPath processor.
535 */
536static void
537exsltMathAbsFunction (xmlXPathParserContextPtr ctxt, int nargs) {
538 double ret;
539
540 if (nargs != 1) {
541 xmlXPathSetArityError(ctxt);
542 return;
543 }
544 ret = xmlXPathPopNumber(ctxt);
545 if (xmlXPathCheckError(ctxt))
546 return;
547
548 ret = exsltMathAbs(ret);
549
550 xmlXPathReturnNumber(ctxt, ret);
551}
552
553/**
554 * exsltMathSqrt:
555 * @num: a double
556 *
557 * Implements the EXSLT - Math sqrt() function:
558 * number math:sqrt (number)
559 *
560 * Returns the square root of the argument, or xmlXPathNAN if @num is Nan.
561 */
562static double
563exsltMathSqrt (double num) {
564 double ret;
565
566 if (xmlXPathIsNaN(num))
567 return(xmlXPathNAN);
568 ret = sqrt(num);
569 return(ret);
570}
571
572/**
573 * exsltMathSqrtFunction:
574 * @ctxt: an XPath parser context
575 * @nargs: the number of arguments
576 *
577 * Wraps #exsltMathSqrt for use by the XPath processor.
578 */
579static void
580exsltMathSqrtFunction (xmlXPathParserContextPtr ctxt, int nargs) {
581 double ret;
582
583 if (nargs != 1) {
584 xmlXPathSetArityError(ctxt);
585 return;
586 }
587 ret = xmlXPathPopNumber(ctxt);
588 if (xmlXPathCheckError(ctxt))
589 return;
590
591 ret = exsltMathSqrt(ret);
592
593 xmlXPathReturnNumber(ctxt, ret);
594}
595
596/**
597 * exsltMathPower:
598 * @base: a double
599 * @power: a double
600 *
601 * Implements the EXSLT - Math power() function:
602 * number math:power (number, number)
603 *
604 * Returns the power base and power arguments, or xmlXPathNAN
605 * if either @base or @power is Nan.
606 */
607static double
608exsltMathPower (double base, double power) {
609 double ret;
610
611 if ((xmlXPathIsNaN(base) || xmlXPathIsNaN(power)))
612 return(xmlXPathNAN);
613 ret = pow(base, power);
614 return(ret);
615}
616
617/**
618 * exsltMathPower:
619 * @ctxt: an XPath parser context
620 * @nargs: the number of arguments
621 *
622 * Wraps #exsltMathPower for use by the XPath processor.
623 */
624static void
625exsltMathPowerFunction (xmlXPathParserContextPtr ctxt, int nargs) {
626 double ret, base;
627
628 if (nargs != 2) {
629 xmlXPathSetArityError(ctxt);
630 return;
631 }
632 ret = xmlXPathPopNumber(ctxt);
633 if (xmlXPathCheckError(ctxt))
634 return;
635
636 /* power */
637 base = xmlXPathPopNumber(ctxt);
638 if (xmlXPathCheckError(ctxt))
639 return;
640
641 ret = exsltMathPower(base, ret);
642
643 xmlXPathReturnNumber(ctxt, ret);
644}
645
646/**
647 * exsltMathLog:
648 * @num: a double
649 *
650 * Implements the EXSLT - Math log() function:
651 * number math:log (number)
652 *
653 * Returns the natural log of the argument, or xmlXPathNAN if @num is Nan.
654 */
655static double
656exsltMathLog (double num) {
657 double ret;
658
659 if (xmlXPathIsNaN(num))
660 return(xmlXPathNAN);
661 ret = log(num);
662 return(ret);
663}
664
665/**
666 * exsltMathLogFunction:
667 * @ctxt: an XPath parser context
668 * @nargs: the number of arguments
669 *
670 * Wraps #exsltMathLog for use by the XPath processor.
671 */
672static void
673exsltMathLogFunction (xmlXPathParserContextPtr ctxt, int nargs) {
674 double ret;
675
676 if (nargs != 1) {
677 xmlXPathSetArityError(ctxt);
678 return;
679 }
680 ret = xmlXPathPopNumber(ctxt);
681 if (xmlXPathCheckError(ctxt))
682 return;
683
684 ret = exsltMathLog(ret);
685
686 xmlXPathReturnNumber(ctxt, ret);
687}
688
689/**
690 * exsltMathSin:
691 * @num: a double
692 *
693 * Implements the EXSLT - Math sin() function:
694 * number math:sin (number)
695 *
696 * Returns the sine of the argument, or xmlXPathNAN if @num is Nan.
697 */
698static double
699exsltMathSin (double num) {
700 double ret;
701
702 if (xmlXPathIsNaN(num))
703 return(xmlXPathNAN);
704 ret = sin(num);
705 return(ret);
706}
707
708/**
709 * exsltMathSinFunction:
710 * @ctxt: an XPath parser context
711 * @nargs: the number of arguments
712 *
713 * Wraps #exsltMathSin for use by the XPath processor.
714 */
715static void
716exsltMathSinFunction (xmlXPathParserContextPtr ctxt, int nargs) {
717 double ret;
718
719 if (nargs != 1) {
720 xmlXPathSetArityError(ctxt);
721 return;
722 }
723 ret = xmlXPathPopNumber(ctxt);
724 if (xmlXPathCheckError(ctxt))
725 return;
726
727 ret = exsltMathSin(ret);
728
729 xmlXPathReturnNumber(ctxt, ret);
730}
731
732/**
733 * exsltMathCos:
734 * @num: a double
735 *
736 * Implements the EXSLT - Math cos() function:
737 * number math:cos (number)
738 *
739 * Returns the cosine of the argument, or xmlXPathNAN if @num is Nan.
740 */
741static double
742exsltMathCos (double num) {
743 double ret;
744
745 if (xmlXPathIsNaN(num))
746 return(xmlXPathNAN);
747 ret = cos(num);
748 return(ret);
749}
750
751/**
752 * exsltMathCosFunction:
753 * @ctxt: an XPath parser context
754 * @nargs: the number of arguments
755 *
756 * Wraps #exsltMathCos for use by the XPath processor.
757 */
758static void
759exsltMathCosFunction (xmlXPathParserContextPtr ctxt, int nargs) {
760 double ret;
761
762 if (nargs != 1) {
763 xmlXPathSetArityError(ctxt);
764 return;
765 }
766 ret = xmlXPathPopNumber(ctxt);
767 if (xmlXPathCheckError(ctxt))
768 return;
769
770 ret = exsltMathCos(ret);
771
772 xmlXPathReturnNumber(ctxt, ret);
773}
774
775/**
776 * exsltMathTan:
777 * @num: a double
778 *
779 * Implements the EXSLT - Math tan() function:
780 * number math:tan (number)
781 *
782 * Returns the tangent of the argument, or xmlXPathNAN if @num is Nan.
783 */
784static double
785exsltMathTan (double num) {
786 double ret;
787
788 if (xmlXPathIsNaN(num))
789 return(xmlXPathNAN);
790 ret = tan(num);
791 return(ret);
792}
793
794/**
795 * exsltMathTanFunction:
796 * @ctxt: an XPath parser context
797 * @nargs: the number of arguments
798 *
799 * Wraps #exsltMathTan for use by the XPath processor.
800 */
801static void
802exsltMathTanFunction (xmlXPathParserContextPtr ctxt, int nargs) {
803 double ret;
804
805 if (nargs != 1) {
806 xmlXPathSetArityError(ctxt);
807 return;
808 }
809 ret = xmlXPathPopNumber(ctxt);
810 if (xmlXPathCheckError(ctxt))
811 return;
812
813 ret = exsltMathTan(ret);
814
815 xmlXPathReturnNumber(ctxt, ret);
816}
817
818/**
819 * exsltMathAsin:
820 * @num: a double
821 *
822 * Implements the EXSLT - Math asin() function:
823 * number math:asin (number)
824 *
825 * Returns the arc sine of the argument, or xmlXPathNAN if @num is Nan.
826 */
827static double
828exsltMathAsin (double num) {
829 double ret;
830
831 if (xmlXPathIsNaN(num))
832 return(xmlXPathNAN);
833 ret = asin(num);
834 return(ret);
835}
836
837/**
838 * exsltMathAsinFunction:
839 * @ctxt: an XPath parser context
840 * @nargs: the number of arguments
841 *
842 * Wraps #exsltMathAsin for use by the XPath processor.
843 */
844static void
845exsltMathAsinFunction (xmlXPathParserContextPtr ctxt, int nargs) {
846 double ret;
847
848 if (nargs != 1) {
849 xmlXPathSetArityError(ctxt);
850 return;
851 }
852 ret = xmlXPathPopNumber(ctxt);
853 if (xmlXPathCheckError(ctxt))
854 return;
855
856 ret = exsltMathAsin(ret);
857
858 xmlXPathReturnNumber(ctxt, ret);
859}
860
861/**
862 * exsltMathAcos:
863 * @num: a double
864 *
865 * Implements the EXSLT - Math acos() function:
866 * number math:acos (number)
867 *
868 * Returns the arc cosine of the argument, or xmlXPathNAN if @num is Nan.
869 */
870static double
871exsltMathAcos (double num) {
872 double ret;
873
874 if (xmlXPathIsNaN(num))
875 return(xmlXPathNAN);
876 ret = acos(num);
877 return(ret);
878}
879
880/**
881 * exsltMathAcosFunction:
882 * @ctxt: an XPath parser context
883 * @nargs: the number of arguments
884 *
885 * Wraps #exsltMathAcos for use by the XPath processor.
886 */
887static void
888exsltMathAcosFunction (xmlXPathParserContextPtr ctxt, int nargs) {
889 double ret;
890
891 if (nargs != 1) {
892 xmlXPathSetArityError(ctxt);
893 return;
894 }
895 ret = xmlXPathPopNumber(ctxt);
896 if (xmlXPathCheckError(ctxt))
897 return;
898
899 ret = exsltMathAcos(ret);
900
901 xmlXPathReturnNumber(ctxt, ret);
902}
903
904/**
905 * exsltMathAtan:
906 * @num: a double
907 *
908 * Implements the EXSLT - Math atan() function:
909 * number math:atan (number)
910 *
911 * Returns the arc tangent of the argument, or xmlXPathNAN if @num is Nan.
912 */
913static double
914exsltMathAtan (double num) {
915 double ret;
916
917 if (xmlXPathIsNaN(num))
918 return(xmlXPathNAN);
919 ret = atan(num);
920 return(ret);
921}
922
923/**
924 * exsltMathAtanFunction:
925 * @ctxt: an XPath parser context
926 * @nargs: the number of arguments
927 *
928 * Wraps #exsltMathAtan for use by the XPath processor.
929 */
930static void
931exsltMathAtanFunction (xmlXPathParserContextPtr ctxt, int nargs) {
932 double ret;
933
934 if (nargs != 1) {
935 xmlXPathSetArityError(ctxt);
936 return;
937 }
938 ret = xmlXPathPopNumber(ctxt);
939 if (xmlXPathCheckError(ctxt))
940 return;
941
942 ret = exsltMathAtan(ret);
943
944 xmlXPathReturnNumber(ctxt, ret);
945}
946
947/**
948 * exsltMathAtan2:
949 * @y: a double
950 * @x: a double
951 *
952 * Implements the EXSLT - Math atan2() function:
953 * number math:atan2 (number, number)
954 *
955 * Returns the arc tangent function of the y/x arguments, or xmlXPathNAN
956 * if either @y or @x is Nan.
957 */
958static double
959exsltMathAtan2 (double y, double x) {
960 double ret;
961
962 if ((xmlXPathIsNaN(y) || xmlXPathIsNaN(x)))
963 return(xmlXPathNAN);
964 ret = atan2(y, x);
965 return(ret);
966}
967
968/**
969 * exsltMathAtan2Function:
970 * @ctxt: an XPath parser context
971 * @nargs: the number of arguments
972 *
973 * Wraps #exsltMathAtan2 for use by the XPath processor.
974 */
975static void
976exsltMathAtan2Function (xmlXPathParserContextPtr ctxt, int nargs) {
977 double ret, y;
978
979 if (nargs != 2) {
980 xmlXPathSetArityError(ctxt);
981 return;
982 }
983 y = xmlXPathPopNumber(ctxt);
984 if (xmlXPathCheckError(ctxt))
985 return;
986
987 /* x */
988 ret = xmlXPathPopNumber(ctxt);
989 if (xmlXPathCheckError(ctxt))
990 return;
991
992 ret = exsltMathAtan2(y, ret);
993
994 xmlXPathReturnNumber(ctxt, ret);
995}
996
997/**
998 * exsltMathExp:
999 * @num: a double
1000 *
1001 * Implements the EXSLT - Math exp() function:
1002 * number math:exp (number)
1003 *
1004 * Returns the exponential function of the argument, or xmlXPathNAN if
1005 * @num is Nan.
1006 */
1007static double
1008exsltMathExp (double num) {
1009 double ret;
1010
1011 if (xmlXPathIsNaN(num))
1012 return(xmlXPathNAN);
1013 ret = exp(num);
1014 return(ret);
1015}
1016
1017/**
1018 * exsltMathExpFunction:
1019 * @ctxt: an XPath parser context
1020 * @nargs: the number of arguments
1021 *
1022 * Wraps #exsltMathExp for use by the XPath processor.
1023 */
1024static void
1025exsltMathExpFunction (xmlXPathParserContextPtr ctxt, int nargs) {
1026 double ret;
1027
1028 if (nargs != 1) {
1029 xmlXPathSetArityError(ctxt);
1030 return;
1031 }
1032 ret = xmlXPathPopNumber(ctxt);
1033 if (xmlXPathCheckError(ctxt))
1034 return;
1035
1036 ret = exsltMathExp(ret);
1037
1038 xmlXPathReturnNumber(ctxt, ret);
1039}
1040
1041#endif /* HAVE_MATH_H */
1042
1043/**
1044 * exsltMathRegister:
1045 *
1046 * Registers the EXSLT - Math module
1047 */
1048
1049void
1050exsltMathRegister (void) {
1051 xsltRegisterExtModuleFunction ((const xmlChar *) "min",
1052 EXSLT_MATH_NAMESPACE,
1053 exsltMathMinFunction);
1054 xsltRegisterExtModuleFunction ((const xmlChar *) "max",
1055 EXSLT_MATH_NAMESPACE,
1056 exsltMathMaxFunction);
1057 xsltRegisterExtModuleFunction ((const xmlChar *) "highest",
1058 EXSLT_MATH_NAMESPACE,
1059 exsltMathHighestFunction);
1060 xsltRegisterExtModuleFunction ((const xmlChar *) "lowest",
1061 EXSLT_MATH_NAMESPACE,
1062 exsltMathLowestFunction);
1063 /* register other math functions */
1064 xsltRegisterExtModuleFunction ((const xmlChar *) "constant",
1065 EXSLT_MATH_NAMESPACE,
1066 exsltMathConstantFunction);
1067#ifdef HAVE_STDLIB_H
1068 xsltRegisterExtModuleFunction ((const xmlChar *) "random",
1069 EXSLT_MATH_NAMESPACE,
1070 exsltMathRandomFunction);
1071#endif
1072#if HAVE_MATH_H
1073 xsltRegisterExtModuleFunction ((const xmlChar *) "abs",
1074 EXSLT_MATH_NAMESPACE,
1075 exsltMathAbsFunction);
1076 xsltRegisterExtModuleFunction ((const xmlChar *) "sqrt",
1077 EXSLT_MATH_NAMESPACE,
1078 exsltMathSqrtFunction);
1079 xsltRegisterExtModuleFunction ((const xmlChar *) "power",
1080 EXSLT_MATH_NAMESPACE,
1081 exsltMathPowerFunction);
1082 xsltRegisterExtModuleFunction ((const xmlChar *) "log",
1083 EXSLT_MATH_NAMESPACE,
1084 exsltMathLogFunction);
1085 xsltRegisterExtModuleFunction ((const xmlChar *) "sin",
1086 EXSLT_MATH_NAMESPACE,
1087 exsltMathSinFunction);
1088 xsltRegisterExtModuleFunction ((const xmlChar *) "cos",
1089 EXSLT_MATH_NAMESPACE,
1090 exsltMathCosFunction);
1091 xsltRegisterExtModuleFunction ((const xmlChar *) "tan",
1092 EXSLT_MATH_NAMESPACE,
1093 exsltMathTanFunction);
1094 xsltRegisterExtModuleFunction ((const xmlChar *) "asin",
1095 EXSLT_MATH_NAMESPACE,
1096 exsltMathAsinFunction);
1097 xsltRegisterExtModuleFunction ((const xmlChar *) "acos",
1098 EXSLT_MATH_NAMESPACE,
1099 exsltMathAcosFunction);
1100 xsltRegisterExtModuleFunction ((const xmlChar *) "atan",
1101 EXSLT_MATH_NAMESPACE,
1102 exsltMathAtanFunction);
1103 xsltRegisterExtModuleFunction ((const xmlChar *) "atan2",
1104 EXSLT_MATH_NAMESPACE,
1105 exsltMathAtan2Function);
1106 xsltRegisterExtModuleFunction ((const xmlChar *) "exp",
1107 EXSLT_MATH_NAMESPACE,
1108 exsltMathExpFunction);
1109#endif
1110}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette