File Coverage

Calculator.xs
Criterion Covered Total %
statement 123 138 89.1
branch 46 76 60.5
condition n/a
subroutine n/a
pod n/a
total 169 214 78.9


line stmt bran cond sub pod time code
1             /*
2             * THIS FILE IS AUTO-GENERATED BY ExtUtils::XSOne
3             * DO NOT EDIT DIRECTLY - edit files in lib/Acme/ExtUtils/XSOne/Test/ instead
4             *
5             * Generated from:
6             * _header.xs
7             * Calculator/Basic.xs
8             * Calculator/Memory.xs
9             * Calculator/Scientific.xs
10             * Calculator/Trig.xs
11             * _footer.xs
12             */
13              
14             /* ========== COMBINED C PREAMBLE ========== */
15              
16             #include "EXTERN.h"
17             #include "perl.h"
18             #include "XSUB.h"
19             #include
20             #include
21              
22             #define PERL_NO_GET_CONTEXT
23             #define MAX_MEMORY_SLOTS 10
24             #define MAX_HISTORY 100
25              
26             /* C code from: _header.xs */
27             #line 1 "lib/Acme/ExtUtils/XSOne/Test/_header.xs"
28             /*
29             * Acme::ExtUtils::XSOne::Test::Calculator - A demonstration of ExtUtils::XSOne
30             *
31             * This header file contains shared state and helper functions
32             * accessible from all Calculator submodules.
33             */
34              
35              
36              
37             /* ========== Shared State ========== */
38              
39             /* Memory for storing calculation results */
40             static double memory_slots[MAX_MEMORY_SLOTS];
41             static int memory_initialized = 0;
42              
43             /* Calculation history */
44             typedef struct {
45             char operation; /* +, -, *, /, ^, r (root), etc. */
46             double operand1;
47             double operand2;
48             double result;
49             } HistoryEntry;
50              
51             static HistoryEntry history[MAX_HISTORY];
52             static int history_count = 0;
53              
54             /* Last result (ANS functionality) */
55             static double last_result = 0.0;
56              
57             /* ========== Helper Functions ========== */
58              
59             static void init_memory(void) {
60             if (!memory_initialized) {
61             for (int i = 0; i < MAX_MEMORY_SLOTS; i++) {
62             memory_slots[i] = 0.0;
63             }
64             memory_initialized = 1;
65             }
66             }
67              
68             static void add_to_history(char op, double a, double b, double result) {
69             if (history_count < MAX_HISTORY) {
70             history[history_count].operation = op;
71             history[history_count].operand1 = a;
72             history[history_count].operand2 = b;
73             history[history_count].result = result;
74             history_count++;
75             }
76             last_result = result;
77             }
78              
79             static double get_last_result(void) {
80             return last_result;
81             }
82              
83             static int store_memory(int slot, double value) {
84             init_memory();
85             if (slot < 0 || slot >= MAX_MEMORY_SLOTS) {
86             return 0;
87             }
88             memory_slots[slot] = value;
89             return 1;
90             }
91              
92             static double recall_memory(int slot) {
93             init_memory();
94             if (slot < 0 || slot >= MAX_MEMORY_SLOTS) {
95             return 0.0;
96             }
97             return memory_slots[slot];
98             }
99              
100             static void clear_all_memory(void) {
101             for (int i = 0; i < MAX_MEMORY_SLOTS; i++) {
102             memory_slots[i] = 0.0;
103             }
104             history_count = 0;
105             last_result = 0.0;
106             }
107              
108             /* ========== Generic Import Helper ========== */
109              
110             /*
111             * export_sub - Export a subroutine from source package to caller's namespace
112             * src_pkg: source package name (e.g., "Acme::ExtUtils::XSOne::Test::Calculator::Basic")
113             * name: function name (e.g., "add")
114             * caller: caller's package name
115             */
116             static void export_sub(pTHX_ const char *src_pkg, const char *name, const char *caller) {
117             GV *src_gv;
118             GV *dst_gv;
119             CV *cv;
120             SV *src_name;
121             SV *dst_name;
122              
123             /* Build fully qualified source name */
124             src_name = newSVpvf("%s::%s", src_pkg, name);
125              
126             /* Get the source CV */
127             src_gv = gv_fetchpv(SvPV_nolen(src_name), 0, SVt_PVCV);
128             SvREFCNT_dec(src_name);
129              
130             if (!src_gv || !GvCV(src_gv)) {
131             croak("\"%s\" is not defined in package %s", name, src_pkg);
132             }
133             cv = GvCV(src_gv);
134              
135             /* Build fully qualified destination name */
136             dst_name = newSVpvf("%s::%s", caller, name);
137              
138             /* Install in caller's namespace */
139             dst_gv = gv_fetchpv(SvPV_nolen(dst_name), GV_ADD, SVt_PVCV);
140             SvREFCNT_dec(dst_name);
141              
142             if (dst_gv) {
143             SvREFCNT_inc((SV*)cv);
144             GvCV_set(dst_gv, cv);
145             }
146             }
147              
148             /*
149             * do_import - Generic import handler
150             * pkg: the package being imported from
151             * exports: array of exportable function names
152             * export_count: number of exports
153             * items: number of arguments to import()
154             * ax: argument stack offset
155             *
156             * Call from import() like:
157             * static const char *basic_exports[] = {"add", "subtract", ...};
158             * do_import(aTHX_ "...::Basic", basic_exports, 10, items, ax);
159             */
160             static void do_import(pTHX_ const char *pkg, const char **exports, int export_count, I32 items, I32 ax) {
161             const char *caller;
162             int i, j;
163              
164             /* Get caller's package name */
165             caller = CopSTASHPV(PL_curcop);
166             if (!caller || !*caller) {
167             caller = "main";
168             }
169              
170             /* Process import list (skip first arg which is the package name) */
171             for (i = 1; i < items; i++) {
172             SV *arg = ST(i);
173             const char *name;
174             STRLEN name_len;
175             int found = 0;
176              
177             name = SvPV(arg, name_len);
178              
179             /* Find the export */
180             for (j = 0; j < export_count; j++) {
181             if (strcmp(name, exports[j]) == 0) {
182             export_sub(aTHX_ pkg, name, caller);
183             found = 1;
184             break;
185             }
186             }
187              
188             if (!found) {
189             croak("\"%s\" is not exported by the %s module", name, pkg);
190             }
191             }
192             }
193             /* C code from: Calculator/Basic.xs */
194             #line 1 "lib/Acme/ExtUtils/XSOne/Test/Calculator/Basic.xs"
195             /*
196             * Acme::ExtUtils::XSOne::Test::Calculator::Basic - Basic arithmetic operations
197             */
198              
199              
200             /* C helper functions for Basic package */
201             static double basic_safe_divide(double a, double b, int *error) {
202             if (b == 0.0) {
203             *error = 1;
204             return 0.0;
205             }
206             *error = 0;
207             return a / b;
208             }
209              
210             static double basic_clamp(double value, double min_val, double max_val) {
211             if (value < min_val) return min_val;
212             if (value > max_val) return max_val;
213             return value;
214             }
215              
216             static double basic_percent(double value, double percent) {
217             return value * percent / 100.0;
218             }
219             /* C code from: Calculator/Memory.xs */
220             #line 1 "lib/Acme/ExtUtils/XSOne/Test/Calculator/Memory.xs"
221             /*
222             * Acme::ExtUtils::XSOne::Test::Calculator::Memory - Memory and history functions
223             *
224             * This module accesses the shared state defined in _header.xs
225             */
226              
227             /* Memory package helpers - need access to memory_slots */
228             static int mem_is_valid_slot(int slot) {
229             return (slot >= 0 && slot < MAX_MEMORY_SLOTS);
230             }
231              
232             static int mem_get_used_slots(void) {
233             int count = 0;
234             for (int i = 0; i < MAX_MEMORY_SLOTS; i++) {
235             if (memory_slots[i] != 0.0) count++;
236             }
237             return count;
238             }
239              
240             static double mem_sum_all(void) {
241             double sum = 0.0;
242             for (int i = 0; i < MAX_MEMORY_SLOTS; i++) {
243             sum += memory_slots[i];
244             }
245             return sum;
246             }
247              
248             static void mem_add_to_slot(int slot, double value) {
249             if (mem_is_valid_slot(slot)) {
250             memory_slots[slot] += value;
251             }
252             }
253             /* C code from: Calculator/Scientific.xs */
254             #line 1 "lib/Acme/ExtUtils/XSOne/Test/Calculator/Scientific.xs"
255             /*
256             * Acme::ExtUtils::XSOne::Test::Calculator::Scientific - Scientific/advanced operations
257             */
258              
259              
260             /* C helper functions for Scientific package */
261             static double sci_safe_log(double a, int *error) {
262             if (a <= 0.0) {
263             *error = 1;
264             return 0.0;
265             }
266             *error = 0;
267             return log(a);
268             }
269              
270             static double sci_safe_sqrt(double a, int *error) {
271             if (a < 0.0) {
272             *error = 1;
273             return 0.0;
274             }
275             *error = 0;
276             return sqrt(a);
277             }
278              
279             static double sci_ipow(double base, int exp) {
280             /* Integer power - faster than pow() for integer exponents */
281             if (exp == 0) return 1.0;
282             int neg = 0;
283             if (exp < 0) {
284             neg = 1;
285             exp = -exp;
286             }
287             double result = 1.0;
288             while (exp > 0) {
289             if (exp & 1) result *= base;
290             base *= base;
291             exp >>= 1;
292             }
293             return neg ? 1.0 / result : result;
294             }
295              
296             static double sci_combination(int n, int r) {
297             if (r > n || r < 0) return 0.0;
298             if (r == 0 || r == n) return 1.0;
299             double result = 1.0;
300             for (int i = 0; i < r; i++) {
301             result = result * (n - i) / (i + 1);
302             }
303             return result;
304             }
305             /* C code from: Calculator/Trig.xs */
306             #line 1 "lib/Acme/ExtUtils/XSOne/Test/Calculator/Trig.xs"
307             /*
308             * Acme::ExtUtils::XSOne::Test::Calculator::Trig - Trigonometric functions
309             */
310              
311              
312             /* C helper functions for Trig package */
313             static double trig_normalize_angle(double radians) {
314             /* Normalize angle to [-PI, PI] */
315             while (radians > M_PI) radians -= 2.0 * M_PI;
316             while (radians < -M_PI) radians += 2.0 * M_PI;
317             return radians;
318             }
319              
320             static int trig_is_valid_asin_arg(double x) {
321             return (x >= -1.0 && x <= 1.0);
322             }
323              
324             static double trig_sec(double x) {
325             return 1.0 / cos(x);
326             }
327              
328             static double trig_csc(double x) {
329             return 1.0 / sin(x);
330             }
331              
332             static double trig_cot(double x) {
333             return cos(x) / sin(x);
334             }
335             /* C code from: _footer.xs */
336             #line 1 "lib/Acme/ExtUtils/XSOne/Test/_footer.xs"
337             /*
338             * Acme::ExtUtils::XSOne::Test::Calculator - Main module and BOOT section
339             */
340             /* ========== END COMBINED C PREAMBLE ========== */
341              
342             MODULE = Acme::ExtUtils::XSOne::Test::Calculator PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator::Basic
343              
344             PROTOTYPES: DISABLE
345              
346             double
347             add(a, b)
348             double a
349             double b
350             CODE:
351 10           RETVAL = a + b;
352 10           add_to_history('+', a, b, RETVAL);
353             OUTPUT:
354             RETVAL
355              
356             double
357             subtract(a, b)
358             double a
359             double b
360             CODE:
361 4           RETVAL = a - b;
362 4           add_to_history('-', a, b, RETVAL);
363             OUTPUT:
364             RETVAL
365              
366             double
367             multiply(a, b)
368             double a
369             double b
370             CODE:
371 6           RETVAL = a * b;
372 6           add_to_history('*', a, b, RETVAL);
373             OUTPUT:
374             RETVAL
375              
376             double
377             divide(a, b)
378             double a
379             double b
380             CODE:
381 6 100         if (b == 0.0) {
382 2           croak("Division by zero");
383             }
384 4           RETVAL = a / b;
385 4           add_to_history('/', a, b, RETVAL);
386             OUTPUT:
387             RETVAL
388              
389             double
390             modulo(a, b)
391             double a
392             double b
393             CODE:
394 4 100         if (b == 0.0) {
395 2           croak("Modulo by zero");
396             }
397 2           RETVAL = fmod(a, b);
398 2           add_to_history('%', a, b, RETVAL);
399             OUTPUT:
400             RETVAL
401              
402             double
403             negate(a)
404             double a
405             CODE:
406 4           RETVAL = -a;
407 4           add_to_history('n', a, 0, RETVAL);
408             OUTPUT:
409             RETVAL
410              
411             double
412             absolute(a)
413             double a
414             CODE:
415 4           RETVAL = fabs(a);
416 4           add_to_history('a', a, 0, RETVAL);
417             OUTPUT:
418             RETVAL
419              
420             double
421             safe_divide(a, b)
422             double a
423             double b
424             CODE:
425             int error;
426 4           RETVAL = basic_safe_divide(a, b, &error);
427 4 100         if (error) {
428 2           RETVAL = 0.0; /* Return 0 instead of croak */
429             }
430 4           add_to_history('/', a, b, RETVAL);
431             OUTPUT:
432             RETVAL
433              
434             double
435             clamp(value, min_val, max_val)
436             double value
437             double min_val
438             double max_val
439             CODE:
440 6           RETVAL = basic_clamp(value, min_val, max_val);
441             OUTPUT:
442             RETVAL
443              
444             double
445             percent(value, pct)
446             double value
447             double pct
448             CODE:
449 6           RETVAL = basic_percent(value, pct);
450 6           add_to_history('%', value, pct, RETVAL);
451             OUTPUT:
452             RETVAL
453              
454             void
455             import(...)
456             CODE:
457             {
458             static const char *basic_exports[] = {
459             "add", "subtract", "multiply", "divide", "modulo",
460             "negate", "absolute", "safe_divide", "clamp", "percent"
461             };
462 2           do_import(aTHX_ "Acme::ExtUtils::XSOne::Test::Calculator::Basic",
463             basic_exports, 10, items, ax);
464             }
465              
466              
467             MODULE = Acme::ExtUtils::XSOne::Test::Calculator PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator::Memory
468              
469             PROTOTYPES: DISABLE
470              
471             int
472             store(slot, value)
473             int slot
474             double value
475             CODE:
476 8           RETVAL = store_memory(slot, value);
477 8 50         if (!RETVAL) {
478 0           warn("Invalid memory slot %d (valid: 0-%d)", slot, MAX_MEMORY_SLOTS - 1);
479             }
480             OUTPUT:
481             RETVAL
482              
483             double
484             recall(slot)
485             int slot
486             CODE:
487 10 50         if (slot < 0 || slot >= MAX_MEMORY_SLOTS) {
    50          
488 0           warn("Invalid memory slot %d (valid: 0-%d)", slot, MAX_MEMORY_SLOTS - 1);
489 0           RETVAL = 0.0;
490             } else {
491 10           RETVAL = recall_memory(slot);
492             }
493             OUTPUT:
494             RETVAL
495              
496             void
497             clear()
498             CODE:
499 10           clear_all_memory();
500              
501             double
502             ans()
503             CODE:
504 8           RETVAL = get_last_result();
505             OUTPUT:
506             RETVAL
507              
508             int
509             history_count()
510             CODE:
511 4 50         RETVAL = history_count;
512             OUTPUT:
513             RETVAL
514              
515             void
516             get_history_entry(index)
517             int index
518             PPCODE:
519 4 50         if (index < 0 || index >= history_count) {
    50          
520 0           croak("Invalid history index %d (valid: 0-%d)", index, history_count - 1);
521             }
522 4 50         EXTEND(SP, 4);
523 4           PUSHs(sv_2mortal(newSVpvf("%c", history[index].operation)));
524 4           PUSHs(sv_2mortal(newSVnv(history[index].operand1)));
525 4           PUSHs(sv_2mortal(newSVnv(history[index].operand2)));
526 4           PUSHs(sv_2mortal(newSVnv(history[index].result)));
527              
528             int
529             max_memory_slots()
530             CODE:
531 2 50         RETVAL = MAX_MEMORY_SLOTS;
532             OUTPUT:
533             RETVAL
534              
535             int
536             max_history_entries()
537             CODE:
538 2 50         RETVAL = MAX_HISTORY;
539             OUTPUT:
540             RETVAL
541              
542             int
543             is_valid_slot(slot)
544             int slot
545             CODE:
546 6           RETVAL = mem_is_valid_slot(slot);
547             OUTPUT:
548             RETVAL
549              
550             int
551             used_slots()
552             CODE:
553 2           RETVAL = mem_get_used_slots();
554             OUTPUT:
555             RETVAL
556              
557             double
558             sum_all_slots()
559             CODE:
560 2           RETVAL = mem_sum_all();
561             OUTPUT:
562             RETVAL
563              
564             void
565             add_to(slot, value)
566             int slot
567             double value
568             CODE:
569 4           mem_add_to_slot(slot, value);
570              
571             void
572             import(...)
573             CODE:
574             {
575             static const char *memory_exports[] = {
576             "store", "recall", "clear", "ans",
577             "history_count", "get_history_entry",
578             "max_memory_slots", "max_history_entries",
579             "is_valid_slot", "used_slots", "sum_all_slots", "add_to"
580             };
581 1           do_import(aTHX_ "Acme::ExtUtils::XSOne::Test::Calculator::Memory",
582             memory_exports, 12, items, ax);
583             }
584              
585              
586             MODULE = Acme::ExtUtils::XSOne::Test::Calculator PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator::Scientific
587              
588             PROTOTYPES: DISABLE
589              
590             double
591             power(base, exp)
592             double base
593             double exp
594             CODE:
595 6           RETVAL = pow(base, exp);
596 6           add_to_history('^', base, exp, RETVAL);
597             OUTPUT:
598             RETVAL
599              
600             double
601             sqrt_val(a)
602             double a
603             CODE:
604 8 100         if (a < 0.0) {
605 2           croak("Cannot take square root of negative number");
606             }
607 6           RETVAL = sqrt(a);
608 6           add_to_history('r', a, 0.5, RETVAL);
609             OUTPUT:
610             RETVAL
611              
612             double
613             cbrt_val(a)
614             double a
615             CODE:
616 4           RETVAL = cbrt(a);
617 4           add_to_history('r', a, 1.0/3.0, RETVAL);
618             OUTPUT:
619             RETVAL
620              
621             double
622             nth_root(a, n)
623             double a
624             double n
625             CODE:
626 2 50         if (n == 0.0) {
627 0           croak("Cannot take 0th root");
628             }
629 2 50         if (a < 0.0 && fmod(n, 2.0) == 0.0) {
    0          
630 0           croak("Cannot take even root of negative number");
631             }
632 2           RETVAL = pow(a, 1.0/n);
633 2           add_to_history('r', a, n, RETVAL);
634             OUTPUT:
635             RETVAL
636              
637             double
638             log_natural(a)
639             double a
640             CODE:
641 4 100         if (a <= 0.0) {
642 2           croak("Cannot take log of non-positive number");
643             }
644 2           RETVAL = log(a);
645 2           add_to_history('l', a, M_E, RETVAL);
646             OUTPUT:
647             RETVAL
648              
649             double
650             log10_val(a)
651             double a
652             CODE:
653 2 50         if (a <= 0.0) {
654 0           croak("Cannot take log of non-positive number");
655             }
656 2           RETVAL = log10(a);
657 2           add_to_history('L', a, 10, RETVAL);
658             OUTPUT:
659             RETVAL
660              
661             double
662             log_base(a, base)
663             double a
664             double base
665             CODE:
666 2 50         if (a <= 0.0 || base <= 0.0 || base == 1.0) {
    50          
    50          
667 0           croak("Invalid logarithm arguments");
668             }
669 2           RETVAL = log(a) / log(base);
670 2           add_to_history('L', a, base, RETVAL);
671             OUTPUT:
672             RETVAL
673              
674             double
675             exp_val(a)
676             double a
677             CODE:
678 2           RETVAL = exp(a);
679 2           add_to_history('e', a, 0, RETVAL);
680             OUTPUT:
681             RETVAL
682              
683             double
684             factorial(n)
685             int n
686             CODE:
687 4 100         if (n < 0) {
688 2           croak("Cannot take factorial of negative number");
689             }
690 2 50         if (n > 170) {
691 0           croak("Factorial overflow (max 170)");
692             }
693 2           RETVAL = 1.0;
694 10 100         for (int i = 2; i <= n; i++) {
695 8           RETVAL *= i;
696             }
697 2           add_to_history('!', (double)n, 0, RETVAL);
698             OUTPUT:
699             RETVAL
700              
701             double
702             ipow(base, exp)
703             double base
704             int exp
705             CODE:
706 4           RETVAL = sci_ipow(base, exp);
707 4           add_to_history('^', base, (double)exp, RETVAL);
708             OUTPUT:
709             RETVAL
710              
711             double
712             safe_sqrt(a)
713             double a
714             CODE:
715             int error;
716 4           RETVAL = sci_safe_sqrt(a, &error);
717 4 100         if (!error) {
718 2           add_to_history('r', a, 0.5, RETVAL);
719             }
720             OUTPUT:
721             RETVAL
722              
723             double
724             safe_log(a)
725             double a
726             CODE:
727             int error;
728 4           RETVAL = sci_safe_log(a, &error);
729 4 100         if (!error) {
730 2           add_to_history('l', a, M_E, RETVAL);
731             }
732             OUTPUT:
733             RETVAL
734              
735             double
736             combination(n, r)
737             int n
738             int r
739             CODE:
740 2           RETVAL = sci_combination(n, r);
741 2           add_to_history('C', (double)n, (double)r, RETVAL);
742             OUTPUT:
743             RETVAL
744              
745             double
746             permutation(n, r)
747             int n
748             int r
749             CODE:
750 2 50         if (r > n || r < 0 || n < 0) {
    50          
    50          
751 0           RETVAL = 0.0;
752             } else {
753 2           RETVAL = sci_combination(n, r);
754 4 100         for (int i = 2; i <= r; i++) {
755 2           RETVAL *= i;
756             }
757             }
758 2           add_to_history('P', (double)n, (double)r, RETVAL);
759             OUTPUT:
760             RETVAL
761              
762             void
763             import(...)
764             CODE:
765             {
766             static const char *scientific_exports[] = {
767             "power", "sqrt_val", "cbrt_val", "nth_root",
768             "log_natural", "log10_val", "log_base", "exp_val",
769             "factorial", "ipow", "safe_sqrt", "safe_log",
770             "combination", "permutation"
771             };
772 1           do_import(aTHX_ "Acme::ExtUtils::XSOne::Test::Calculator::Scientific",
773             scientific_exports, 14, items, ax);
774             }
775              
776              
777             MODULE = Acme::ExtUtils::XSOne::Test::Calculator PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator::Trig
778              
779             PROTOTYPES: DISABLE
780              
781             double
782             sin_val(a)
783             double a
784             CODE:
785 8           RETVAL = sin(a);
786 8           add_to_history('s', a, 0, RETVAL);
787             OUTPUT:
788             RETVAL
789              
790             double
791             cos_val(a)
792             double a
793             CODE:
794 4           RETVAL = cos(a);
795 4           add_to_history('c', a, 0, RETVAL);
796             OUTPUT:
797             RETVAL
798              
799             double
800             tan_val(a)
801             double a
802             CODE:
803 2           RETVAL = tan(a);
804 2           add_to_history('t', a, 0, RETVAL);
805             OUTPUT:
806             RETVAL
807              
808             double
809             asin_val(a)
810             double a
811             CODE:
812 2 50         if (a < -1.0 || a > 1.0) {
    50          
813 0           croak("asin argument must be in [-1, 1]");
814             }
815 2           RETVAL = asin(a);
816 2           add_to_history('S', a, 0, RETVAL);
817             OUTPUT:
818             RETVAL
819              
820             double
821             acos_val(a)
822             double a
823             CODE:
824 2 50         if (a < -1.0 || a > 1.0) {
    50          
825 0           croak("acos argument must be in [-1, 1]");
826             }
827 2           RETVAL = acos(a);
828 2           add_to_history('C', a, 0, RETVAL);
829             OUTPUT:
830             RETVAL
831              
832             double
833             atan_val(a)
834             double a
835             CODE:
836 2           RETVAL = atan(a);
837 2           add_to_history('T', a, 0, RETVAL);
838             OUTPUT:
839             RETVAL
840              
841             double
842             atan2_val(y, x)
843             double y
844             double x
845             CODE:
846 0           RETVAL = atan2(y, x);
847 0           add_to_history('A', y, x, RETVAL);
848             OUTPUT:
849             RETVAL
850              
851             double
852             deg_to_rad(degrees)
853             double degrees
854             CODE:
855 2 50         RETVAL = degrees * M_PI / 180.0;
856             OUTPUT:
857             RETVAL
858              
859             double
860             rad_to_deg(radians)
861             double radians
862             CODE:
863 0 0         RETVAL = radians * 180.0 / M_PI;
864             OUTPUT:
865             RETVAL
866              
867             double
868             hypot_val(a, b)
869             double a
870             double b
871             CODE:
872 2           RETVAL = hypot(a, b);
873 2           add_to_history('h', a, b, RETVAL);
874             OUTPUT:
875             RETVAL
876              
877             double
878             normalize_angle(radians)
879             double radians
880             CODE:
881 4           RETVAL = trig_normalize_angle(radians);
882             OUTPUT:
883             RETVAL
884              
885             double
886             sec_val(a)
887             double a
888             CODE:
889 2           RETVAL = trig_sec(a);
890 2           add_to_history('E', a, 0, RETVAL);
891             OUTPUT:
892             RETVAL
893              
894             double
895             csc_val(a)
896             double a
897             CODE:
898 2           RETVAL = trig_csc(a);
899 2           add_to_history('O', a, 0, RETVAL);
900             OUTPUT:
901             RETVAL
902              
903             double
904             cot_val(a)
905             double a
906             CODE:
907 2           RETVAL = trig_cot(a);
908 2           add_to_history('G', a, 0, RETVAL);
909             OUTPUT:
910             RETVAL
911              
912             int
913             is_valid_asin_arg(x)
914             double x
915             CODE:
916 4           RETVAL = trig_is_valid_asin_arg(x);
917             OUTPUT:
918             RETVAL
919              
920             void
921             import(...)
922             CODE:
923             {
924             static const char *trig_exports[] = {
925             "sin_val", "cos_val", "tan_val",
926             "asin_val", "acos_val", "atan_val", "atan2_val",
927             "deg_to_rad", "rad_to_deg", "hypot_val",
928             "normalize_angle", "sec_val", "csc_val", "cot_val",
929             "is_valid_asin_arg"
930             };
931 1           do_import(aTHX_ "Acme::ExtUtils::XSOne::Test::Calculator::Trig",
932             trig_exports, 15, items, ax);
933             }
934              
935              
936             MODULE = Acme::ExtUtils::XSOne::Test::Calculator PACKAGE = Acme::ExtUtils::XSOne::Test::Calculator
937              
938             PROTOTYPES: DISABLE
939              
940             double
941             pi()
942             CODE:
943 6 50         RETVAL = M_PI;
944             OUTPUT:
945             RETVAL
946              
947             double
948             e()
949             CODE:
950 2 50         RETVAL = M_E;
951             OUTPUT:
952             RETVAL
953              
954             const char *
955             version()
956             CODE:
957 2           RETVAL = "0.01";
958             OUTPUT:
959             RETVAL
960              
961             BOOT:
962             /* Initialize memory on module load */
963 3           init_memory();
964