File Coverage

Pari.xs
Criterion Covered Total %
statement 954 1431 66.6
branch 489 1014 48.2
condition n/a
subroutine n/a
pod n/a
total 1443 2445 59.0


line stmt bran cond sub pod time code
1             #ifdef _WIN32 /* including windows.h later leads to macro name collisions */
2             # define WIN32_LEAN_AND_MEAN
3             # include
4             #endif
5              
6             #define strtoi PARI_strtoi /* NetBSD declares a function strtoi() conflicting with PARI one */
7              
8             #ifdef USE_STANDALONE_PARILIB
9             # include
10             # include
11             #else
12             # include
13             # if PARI_VERSION_EXP < 2011000 /* Probably much earlier too... */
14             # include
15             # endif
16             # if 1 || PARI_VERSION_EXP < 2011000 /* Misses foreign*, varentries, fetch_entry... */
17             # include
18             # endif
19              
20             #ifdef HAVE_PARIPRIV
21             # if 1 || PARI_VERSION_EXP < 2011000 /* Misses EpNEW, EpVAR, precreal */
22             # include
23             # endif
24             #endif
25              
26             # if 1 || PARI_VERSION_EXP < 2011000 /* misses gp_get_plot */ /* Probably much earlier too... */
27             # include /* init_opts */
28             # endif
29             #endif /* !defined USE_STANDALONE_PARILIB */
30              
31             /* On some systems /usr/include/sys/dl.h attempts to declare
32             ladd which pari.h already defined with a different meaning.
33              
34             It is not clear whether this is a correct fix...
35             */
36             #undef ladd
37             #undef strtoi /* See above */
38              
39             #define PERL_POLLUTE /* We use older varnames */
40              
41             #ifdef __cplusplus
42             extern "C" {
43             #endif
44              
45             #if defined(_WIN64) && defined(long)
46             # undef long
47             # define NEED_TO_REDEFINE_LONG
48             #endif
49              
50             #include "EXTERN.h"
51             #include "perl.h"
52             #include "XSUB.h"
53             #include "func_codes.h"
54              
55             #ifdef NEED_TO_REDEFINE_LONG
56             # ifdef SSize_t /* XXX Defect in Perl??? Not in 5.18.0, but in 5.28.1. */
57             typedef SSize_t mySSize_t;
58             # undef SSize_t /* long long; would be expanded to long long long long */
59             # define SSize_t mySSize_t
60             # endif
61             # define long long long /* see parigen.h */
62             # define MYatol atoll
63             #else
64             # define MYatol atol
65             #endif
66              
67             #ifdef __cplusplus
68             }
69             #endif
70              
71             #ifndef PTRV
72             # define PTRV IV
73             #endif
74              
75             #ifndef TWOPOTBYTES_IN_LONG /* Miss starting from 2.4.2; taken from 2.3.5 */
76             #ifdef LONG_IS_64BIT
77             # define TWOPOTBYTES_IN_LONG 3
78             #else
79             # define TWOPOTBYTES_IN_LONG 2
80             #endif
81             #define BYTES_IN_LONG (1<
82             #endif
83              
84             #if !defined(na) && defined(PERL_VERSION) && (PERL_VERSION > 7) /* Added in 6 (???), Removed in 13 */
85             # define na PL_na
86             # define sv_no PL_sv_no
87             # define sv_yes PL_sv_yes
88             #endif
89              
90             #if PARI_VERSION_EXP < 2002012
91             void init_defaults(int force); /* Probably, will never be fixed in 2.1.* */
92             #endif
93              
94             #if PARI_VERSION_EXP >= 2004000 /* Unclear when exactly they disappeared. Miss in 3.5.0 */
95             extern entree functions_basic[];
96             extern entree functions_highlevel[];
97             #endif
98              
99             #if PARI_VERSION_EXP < 2009000
100             # define myPARI_top (top)
101             # define myPARI_bot (bot)
102             #else
103             # define myPARI_top (pari_mainstack->top)
104             # define myPARI_bot (pari_mainstack->bot)
105             # define lgef lg
106             #endif
107              
108             #if PARI_VERSION_EXP < 2002009
109             #define gen_0 gzero
110             #define gen_1 gun
111             #endif
112              
113             #if PARI_VERSION_EXP < 2002011
114             # define readseq lisexpr
115             #endif
116              
117             #if PARI_VERSION_EXP < 2002010
118             # define gequal gegal
119             #endif
120              
121             #if PARI_VERSION_EXP < 2000009
122             # define gpow gpui
123             #endif
124              
125             #if PARI_VERSION_EXP < 2002013
126             # define myforcecopy forcecopy
127             #else
128             # define myforcecopy gcopy
129             #endif
130              
131             /* This should not be defined at this moment, but in 5.001n is. */
132             #ifdef coeff
133             # undef coeff
134             #endif
135              
136             #ifdef warner
137             # undef warner
138             #endif
139              
140             /* $Id: Pari.xs,v 1.7 1995/01/23 18:50:58 ilya Exp ilya $ */
141             /* dFUNCTION should be the last declaration! */
142              
143             #ifdef __cplusplus
144             #define VARARG ...
145             #else
146             #define VARARG
147             #endif
148              
149             #define dFUNCTION(retv) retv (*FUNCTION)(VARARG) = \
150             (retv (*)(VARARG)) XSANY.any_dptr
151              
152             #if DEBUG_PARI
153             static int pari_debug = 0;
154             # define RUN_IF_DEBUG_PARI(a) \
155             do { if (pari_debug) {a;} } while (0)
156             # define PARI_DEBUG_set(d) ((pari_debug = (d)), 1)
157             # define PARI_DEBUG() (pari_debug)
158             #else
159             # define RUN_IF_DEBUG_PARI(a)
160             # define PARI_DEBUG_set(d) (0)
161             # define PARI_DEBUG(d) (0)
162             #endif
163              
164             #define DO_INTERFACE(inter) math_pari_subaddr = CAT2(XS_Math__Pari_interface, inter)
165             #define CASE_INTERFACE(inter) case inter: \
166             DO_INTERFACE(inter); break
167              
168             #ifndef XSINTERFACE_FUNC_SET /* Not in 5.004_04 */
169             # define XSINTERFACE_FUNC_SET(cv,f) \
170             CvXSUBANY(cv).any_dptr = (void (*) (void*))(f)
171             #endif
172              
173             #ifndef SvPV_nolen
174             STRLEN n___a;
175             # define SvPV_nolen(sv) SvPV((sv),n___a)
176             #endif
177              
178             #ifndef PERL_UNUSED_VAR
179             # define PERL_UNUSED_VAR(var) if (0) var = var
180             #endif
181              
182             /* Here is the rationals for managing SVs which keep GENs:
183             * SVs may reference GENs on stack, or
184             * or GEN on stack which we later moved to heap (so nobody else knows where they are!), or
185             * GEN which was originally on heap.
186             We assume that we do not need to free stuff
187             that was originally on heap. However, we need to free the stuff we
188             moved from the stack ourself.
189            
190             Here is how we do it: The variables that were initially off stack
191             have SvPVX == GENheap.
192            
193             The variables that were moved from the stack have SvPVX ==
194             GENmovedOffStack.
195              
196             If the variable is on stack, and it is the oldest one which is on
197             stack, then SvPVX == GENfirstOnStack.
198              
199             Otherwise SvPVX is the next older SV that refers to a GEN on stack.
200              
201             In the last two cases SvCUR is the offset on stack of the stack
202             frame on the entry into the function for which SV is the argument.
203             */
204              
205             #ifndef USE_SLOW_NARGS_ACCESS
206             # define USE_SLOW_NARGS_ACCESS (defined(PERL_VERSION) && (PERL_VERSION > 9))
207             #endif
208              
209             #if USE_SLOW_NARGS_ACCESS
210             # define PARI_MAGIC_TYPE ((char)0xDE)
211             # define PARI_MAGIC_PRIVATE 0x2020
212              
213             /* Can't return IV, since may not fit in mg_ptr;
214             However, we use it to store numargs, and result of gclone() */
215             static void**
216 4349031           PARI_SV_to_voidpp(SV *const sv)
217             {
218             MAGIC *mg;
219 8696589 50         for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
220 8696589 100         if (mg->mg_type == PARI_MAGIC_TYPE
221 4349031 50         && mg->mg_private == PARI_MAGIC_PRIVATE)
222 4349031           return (void **) &mg->mg_ptr;
223             }
224 0           croak("panic: PARI narg value not attached");
225             return NULL;
226             }
227             # define PARI_SV_to_intp(sv) ((int*)PARI_SV_to_voidpp(sv))
228              
229             static void
230 2303           SV_myvoidp_set(SV *sv, void *p)
231             {
232             MAGIC *mg;
233              
234 2303           mg = sv_magicext((SV*)sv, NULL, PARI_MAGIC_TYPE, NULL, p, 0);
235 2303           mg->mg_private = PARI_MAGIC_PRIVATE;
236 2303           }
237              
238             # define SV_myvoidp_reset_clone(sv) \
239             STMT_START { \
240             if(SvTYPE(sv) == SVt_PVAV) { \
241             void **p = PARI_SV_to_voidpp(sv); \
242             *p = (void*) gclone((GEN)*p); \
243             } else { \
244             SV_myvoidp_reset_clone_IVX(sv); \
245             } } STMT_END
246              
247             /* Should be applied to SV* and AV* only */
248             # define SV_myvoidp_get(sv) \
249             ((SvTYPE(sv) == SVt_PVAV) ? *PARI_SV_to_voidpp(sv) : INT2PTR(void*,SvIV(sv)))
250             # define CV_myint_get(sv) INT2PTR(PTRV, *PARI_SV_to_voidpp(sv)) /* INT2PTR is two-way; PTR2INT missing in newer Perls */
251             # define CV_myint_set(sv,i) SV_myvoidp_set((sv), INT2PTR(void*,(PTRV)i))
252             #else /* !USE_SLOW_NARGS_ACCESS */
253             # define CV_myint_get(sv) SvIVX(sv) /* IVOK is not set! */
254             # define CV_myint_set(sv, i) (SvIVX(sv) = (i))
255             # define SV_myvoidp_get(sv) INT2PTR(void*, SvIVX(sv))
256             # define SV_myvoidp_set(sv, p) (SvIVX(sv) = PTR2IV(p))
257             # define SV_myvoidp_reset_clone SV_myvoidp_reset_clone_IVX
258             #endif
259              
260             #define SV_myvoidp_reset_clone_IVX(sv) (SvIVX(sv) = PTR2IV(gclone(INT2PTR(GEN, SvIV(sv)))))
261             #define CV_NUMARGS_get CV_myint_get
262             #define CV_NUMARGS_set CV_myint_set
263              
264             #ifndef USE_SLOW_ARRAY_ACCESS
265             # define USE_SLOW_ARRAY_ACCESS (defined(PERL_VERSION) && (PERL_VERSION > 9))
266             #endif
267              
268             #if USE_SLOW_ARRAY_ACCESS
269             /* 5.9.x and later assert that you're not using SvPVX() and SvCUR() on arrays,
270             so need a little more code to cheat round this. */
271             # define NEED_SLOW_ARRAY_ACCESS(sv) (SvTYPE(sv) == SVt_PVAV)
272             # define AV_SET_LEVEL(sv, val) (AvARRAY(sv) = (SV **)(val))
273             # define AV_GET_LEVEL(sv) ((char*)AvARRAY(sv))
274             #else
275             # define NEED_SLOW_ARRAY_ACCESS(sv) 0
276             # define AV_SET_LEVEL(sv, val) croak("Panic AV LEVEL") /* This will never be called */
277             # define AV_GET_LEVEL(sv) (croak("Panic AV LEVEL"),Nullch) /* This will never be called */
278             #endif
279              
280             /* XXXX May need a flavor when we know it is an AV??? */
281             #define SV_PARISTACK_set(sv, stack) \
282             (NEED_SLOW_ARRAY_ACCESS(sv) ? ( \
283             AV_SET_LEVEL(sv, stack), (void)0 \
284             ) : ( \
285             SvPVX(sv) = stack, (void)0 \
286             ))
287              
288             #define SV_OAVMA_PARISTACK_set(sv, level, stack) \
289             (NEED_SLOW_ARRAY_ACCESS(sv) ? ( \
290             AvFILLp(sv) = (level), \
291             AV_SET_LEVEL(sv, (stack)), (void)0 \
292             ) : ( \
293             SvCUR(sv) = (level), \
294             SvPVX(sv) = (char*)(stack), (void)0 \
295             ))
296              
297             #define SV_OAVMA_PARISTACK_get(sv, level, stack) \
298             (NEED_SLOW_ARRAY_ACCESS(sv) ? ( \
299             (level) = AvFILLp(sv), \
300             (stack) = AV_GET_LEVEL(sv), (void)0 \
301             ) : ( \
302             (level) = SvCUR(sv), \
303             (stack) = SvPVX(sv), (void)0 \
304             ))
305              
306             #define SV_OAVMA_switch(next, sv, newval) \
307             ( NEED_SLOW_ARRAY_ACCESS(sv) ? ( \
308             (next) = (SV *)AvARRAY(sv), \
309             AV_SET_LEVEL(sv, newval), (void)0 \
310             ) : ( \
311             next = (SV *) SvPVX(sv), \
312             SvPVX(sv) = newval, (void)0 \
313             ))
314              
315             #define SV_Stack_find_next(sv) \
316             ( NEED_SLOW_ARRAY_ACCESS(sv) ? ( \
317             (SV *)AvARRAY(sv) \
318             ) : ( \
319             (SV *) SvPVX(sv) \
320             ))
321              
322             #define GENmovedOffStack ((char*) 1) /* Just an atom. */
323             #define GENfirstOnStack ((char*) 2) /* Just an atom. */
324             #define GENheap NULL
325             #define ifact mpfact
326              
327             #if PARI_VERSION_EXP >= 2004002
328             typedef SV * PariVar; /* For loop variables. */
329             #else
330             typedef entree * PariVar; /* For loop variables. */
331             #endif
332              
333             typedef entree * PariName; /* For changevalue. */
334             #if PARI_VERSION_EXP >= 2004002
335             typedef GEN PariExpr, PariExpr2, PariExprV;
336             #else
337             typedef char * PariExpr, *PariExpr2, *PariExprV;
338             #endif
339             typedef GEN * GEN_Ptr;
340              
341             #if PARI_VERSION_EXP >= 2004002 /* Undocumented when it appeared; present in 2.5.0 */
342             # define AssignPariExprR(var,arg,is_void,sv) \
343             ((SvROK(arg) && (SvTYPE(SvRV(arg)) == SVt_PVCV)) ? \
344             (var = make_trampolinecv(SvRV(arg),is_void,sv)) \
345             : (warn("Argument-types E,I of string type not supported yet, substituting x->1"), var = code_return_1))
346             # define AssignPariExpr2R(var,arg,is_void,sv1,sv2) (warn("Argument-types E,I not supported yet, substituting (x,y)->1"), var = code2_return_1)
347             #else /* PARI_VERSION_EXP < 2004002 */ /* Undocumented when it appeared; present in 2.5.0 */
348             # define AssignPariExprR(var,arg,is_void,sv) \
349             ((SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVCV) ? \
350             (var = ((char*)&(SvRV(arg)->sv_flags)) + LSB_in_U32) \
351             : (var = (char *)SvPV(arg,na)))
352             # define AssignPariExpr2R(var,arg,is_void,sv1,sv2) AssignPariExprR(var,arg,is_void,sv1)
353             #endif /* PARI_VERSION_EXP < 2004002 */ /* Undocumented when it appeared; present in 2.5.0 */
354              
355             #define MAYBE_NOTVOID 0 /* Used in 'typemap' - but only for Expr2 now */
356             #define AssignPariExpr2(var,arg) AssignPariExpr2R(var,arg,MAYBE_NOTVOID, 0, 0)
357             #define AssignPariExprR0(var,arg,is_void) AssignPariExprR(var,arg,is_void,0)
358              
359             XS((*math_pari_subaddr)); /* On CygWin XS() has attribute conflicting with static */
360              
361             #if defined(MYMALLOC) && defined(EMBEDMYMALLOC) && defined(UNEMBEDMYMALLOC)
362              
363             Malloc_t
364             malloc(register size_t nbytes)
365             {
366             return Perl_malloc(nbytes);
367             }
368              
369             Free_t
370             free(void *mp)
371             {
372             Perl_mfree(mp); /* What to return? */
373             }
374              
375             Malloc_t
376             realloc(void *mp, size_t nbytes)
377             {
378             return Perl_realloc(mp, nbytes);
379             }
380              
381             #endif
382              
383             /* We make a "fake" PVAV, not enough entries. */
384              
385             /* This macro resets avma *immediately* if IN is a global
386             static GEN (such as gnil, gen_1 etc). So it should be called near
387             the end of stack-manipulating scope */
388             #define setSVpari(sv, in, oldavma) \
389             setSVpari_or_do(sv, in, oldavma, avma = oldavma)
390              
391             #define setSVpari_keep_avma(sv, in, oldavma) \
392             setSVpari_or_do(sv, in, oldavma, ((void)0))
393              
394             #define setSVpari_or_do(sv, in, oldavma, action) do { \
395             sv_setref_pv(sv, "Math::Pari", (void*)in); \
396             morphSVpari(sv, in, oldavma, action); \
397             } while (0)
398              
399             #define morphSVpari(sv, in, oldavma, action) do { \
400             if (is_matvec_t(typ(in)) && SvTYPE(SvRV(sv)) != SVt_PVAV) { \
401             make_PariAV(sv); \
402             } \
403             if (isonstack(in)) { \
404             SV* g = SvRV(sv); \
405             SV_OAVMA_PARISTACK_set(g, oldavma - myPARI_bot, PariStack); \
406             PariStack = g; \
407             perlavma = avma; \
408             onStack_inc; \
409             } else { \
410             action; \
411             } \
412             SVnum_inc; \
413             } while (0)
414              
415             #if PARI_VERSION_EXP < 2002005
416             typedef long pari_sp;
417             #endif
418              
419             SV* PariStack; /* PariStack keeps the latest SV that
420             * keeps a GEN on stack. */
421             pari_sp perlavma; /* How much stack is needed
422             for GENs in Perl variables. */
423             pari_sp sentinel; /* How much stack was used
424             when Pari called Perl. */
425              
426             #ifdef DEBUG_PARI
427              
428             long SVnum;
429             long SVnumtotal;
430             long onStack;
431             long offStack;
432              
433             # define SVnum_inc (SVnum++, SVnumtotal++)
434             # define SVnum_dec (SVnum--)
435             # define onStack_inc (onStack++)
436             # define onStack_dec (onStack--)
437             # define offStack_inc (offStack++)
438             #else /* !defined DEBUG_PARI */
439             # define SVnum_inc
440             # define SVnum_dec
441             # define onStack_inc
442             # define onStack_dec
443             # define offStack_inc
444             #endif /* !defined DEBUG_PARI */
445              
446             #define pari_version_exp() PARI_VERSION_EXP
447              
448             #if !defined(ndec2prec) && PARI_VERSION_EXP < 2003000
449             # ifndef pariK1
450             # define pariK1 (0.103810253/(BYTES_IN_LONG/4)) /* log(10)/(SL*log(2)) */
451             # endif
452             # define ndec2prec(d) (long)(d*pariK1 + 3)
453             #endif
454              
455             #if PARI_VERSION_EXP >= 2008000
456             # define prec_words get_localprec()
457             # define prec_bits get_localbitprec()
458             #else /* !(PARI_VERSION_EXP >= 2008000) */
459             # if PARI_VERSION_EXP >= 2002012
460             # define prec_words precreal
461             # else
462             # define prec_words prec
463             # endif
464             #endif
465              
466             #if PARI_VERSION_EXP >= 2003005 /* XXX When did it actually start??? */
467             long dummy;
468             /* # define prec_words_set(w) (fmt_nbPset(w), precreal = prec2nbits(w)) */
469             # define prec_digits_set(w) setrealprecision(w, &dummy)
470             # define fmt_nbP getrealprecision()
471             # define fmt_nbPset(v) ((void)0)
472             #else /* !(PARI_VERSION_EXP >= 2008000) */
473             # define prec_words_set(p) (prec_words = (p))
474             # define prec_digits_set(d) prec_words_set(ndec2prec(d))
475              
476             int fmt_nb;
477             # define fmt_nbP fmt_nb
478             # define fmt_nbPset(v) fmt_nb = (v)
479              
480             # ifdef LONG_IS_64BIT
481             # define def_fmt_nb 38
482             # else
483             # define def_fmt_nb 28
484             # endif
485              
486             #endif /* !(PARI_VERSION_EXP >= 2008000) */
487              
488              
489             #ifdef USE_PERLLOCAL_PREC
490              
491             #else /* !defined(USE_PERLLOCAL_PREC) */
492             #endif /* !defined(USE_PERLLOCAL_PREC) */
493              
494             #if PARI_VERSION_EXP >= 2000018
495              
496             GEN
497 1           _gbitneg(GEN g)
498             {
499 1           return gbitneg(g,-1);
500             }
501              
502             #endif /* PARI_VERSION_EXP >= 2000018 */
503              
504             #if PARI_VERSION_EXP >= 2002001
505              
506             GEN
507 2           _gbitshiftl(GEN g, long s)
508             {
509 2           return gshift(g, s);
510             }
511              
512             #endif
513             #if PARI_VERSION_EXP >= 2002001 && PARI_VERSION_EXP <= 2002007
514              
515             GEN
516             _gbitshiftr(GEN g, long s)
517             {
518             return gshift3(g, -s, signe(g) < 0); /* Bug up to 2.2.2: 1 should be OK */
519             }
520              
521             #endif /* PARI_VERSION_EXP >= 2002001 && PARI_VERSION_EXP <= 2002007 */
522              
523             /* Upgrade to PVAV, attach a magic of type 'P' which is just a reference to
524             ourselves (non-standard refcounts, so needs special logic on DESTROY) */
525             void
526 2293           make_PariAV(SV *sv)
527             {
528 2293           AV *av = (AV*)SvRV(sv);
529 2293           char *s = SvPVX(av);
530 2293           void *p = INT2PTR(void*, SvIVX(av));
531 2293           SV *newsub = newRV_noinc((SV*)av); /* cannot use sv, it may be
532             sv_restore()d */
533              
534 2293 50         (void)SvUPGRADE((SV*)av, SVt_PVAV);
535 2293 50         SV_PARISTACK_set(av, s);
536 2293           SV_myvoidp_set((SV*)av, p);
537 2293           sv_magic((SV*)av, newsub, 'P', Nullch, 0);
538 2293           SvREFCNT_dec(newsub); /* now RC(newsub)==1 */
539             /* We avoid an reference loop, so should be careful on DESTROY */
540             #if 0
541             if ((mg = SvMAGIC((SV*)av)) && mg->mg_type == 'P' /* be extra paranoid */
542             && (mg->mg_flags & MGf_REFCOUNTED)) {
543             /* mg->mg_flags &= ~MGf_REFCOUNTED; */
544             /* SvREFCNT_dec(sv); */
545             sv_2mortal((SV*)av); /* We restore refcount on DESTROY */
546             }
547             #endif
548 2293           }
549              
550             SV*
551 0           wrongT(SV *sv, char *file, int line)
552             {
553 0 0         if (SvTYPE(sv) != SVt_PVCV && SvTYPE(sv) != SVt_PVGV) {
    0          
554 0           croak("Got the type 0x%x instead of CV=0x%x or GV=0x%x in %s, %i",
555 0           SvTYPE(sv), SVt_PVCV, SVt_PVGV, file, line);
556             } else {
557 0           croak("Something very wrong in %s, %i", file, line);
558             }
559             return NULL; /* To pacify compiler. */
560             }
561              
562             HV *pariStash; /* For quick id. */
563             HV *pariEpStash;
564              
565             #if PARI_VERSION_EXP < 2002012 /* Probably earlier too */
566             /* Copied from anal.c. */
567             static entree *
568             installep(void *f, char *name, int len, int valence, int add, entree **table)
569             {
570             entree *ep = (entree *) gpmalloc(sizeof(entree) + add + len+1);
571             const entree *ep1 = initial_value(ep);
572             char *u = (char *) ep1 + add;
573              
574             ep->name = u; strncpy(u, name,len); u[len]=0;
575             ep->args = NULL; ep->help = NULL; ep->code = NULL;
576             ep->value = f? f: (void *) ep1;
577             ep->next = *table;
578             ep->valence = valence;
579             ep->menu = 0;
580             return *table = ep;
581             }
582             #endif /* PARI_VERSION_EXP >= 2002012 */
583              
584             #if PARI_VERSION_EXP >= 2002012 /* Probably earlier too */
585             # if PARI_VERSION_EXP < 2009000 /* Probably earlier too */
586             # define my_fetch_named_var fetch_named_var
587             # else /* !(PARI_VERSION_EXP < 2009000) */
588             # define MAY_USE_FETCH_ENTRY
589             entree *
590             my_fetch_named_var(const char *s)
591             { /* A part of fetch_user_var() of 2.9.0 */
592             entree *ep = fetch_entry(s);
593             switch (EpVALENCE(ep))
594             {
595             case EpNEW:
596             pari_var_create(ep); /* fall through */
597             ep->valence = EpVAR;
598             ep->value = initial_value(ep);
599             case EpVAR:
600             return ep;
601             default: pari_err(e_MISC, "variable <<<%s>>> already exists with incompatible valence", s);
602             }
603             return 0; /* NOT REACHED */
604             }
605             # endif /* !(PARI_VERSION_EXP < 2009000) */
606             #else
607             static entree *
608             my_fetch_named_var(char *s)
609             {
610             long hash;
611             entree * ep = is_entry_intern(s, functions_hash, &hash);
612              
613             if (ep) {
614             if (EpVALENCE(ep) != EpVAR
615             #if PARI_VERSION_EXP >= 2004000
616             || typ(ep->value)==t_CLOSURE
617             #endif
618             )
619             croak("Got a function name instead of a variable");
620             } else {
621             ep = installep(NULL, s, strlen(s), EpVAR, 7*sizeof(long),
622             functions_hash + hash);
623             manage_var(0,ep);
624             }
625             return ep;
626             }
627             #endif
628              
629             #if PARI_VERSION_EXP <= 2002000 /* Global after 2.2.0 */
630             static void
631             changevalue(entree *ep, GEN val)
632             {
633             GEN y = gclone(val), x = (GEN)ep->value;
634              
635             ep->value = (void *)y;
636             if (x == (GEN) initial_value(ep) || !isclone(x))
637             {
638             y[-1] = (long)x; /* push new value */
639             return;
640             }
641             y[-1] = x[-1]; /* save initial value */
642             killbloc(x); /* destroy intermediate one */
643             }
644             #endif
645              
646             static GEN
647 4028660           my_gpui(GEN x, GEN y)
648             {
649 4028660           return gpow(x, y, prec_words);
650             }
651              
652             static long
653 9           numvar(GEN x)
654             {
655 18 50         if (typ(x) != t_POL || lgef(x) != 4 ||
656 18 50         !gcmp0((GEN)x[2]) || !gcmp1((GEN)x[3]))
657 0           croak("Corrupted data: should be variable");
658 9           return varn(x);
659             }
660              
661             static SV *
662 27           PARIvar(char *s)
663             {
664             SV *sv;
665             entree *ep;
666              
667 27           ep = my_fetch_named_var(s);
668 27           sv = NEWSV(909,0);
669 27           sv_setref_pv(sv, "Math::Pari::Ep", (void*)ep);
670 27           make_PariAV(sv);
671 27           return sv;
672             }
673              
674             #if PARI_VERSION_EXP >= 2004000
675             # define ORDVAR(n) (n) /* The big change... */
676             # define FETCH_CODE_const const /* ->code is const */
677             #else
678             # define ORDVAR(n) ordvar[n]
679             # define FETCH_CODE_const /* fetch_named_variable() cannot take const */
680             #endif /* PARI_VERSION_EXP >= 2004000 */
681              
682             static entree *
683 1684           findVariable(SV *sv, int generate)
684             { /* Used for PariVar (generate=1, before 2.4.2) and PariName (generate=0; only for changevalue()) */
685             /* There may be 4 important cases:
686             a) we got a 'word' string, which we interpret as the name of
687             the variable to use;
688             b1) It is a pari value containing a polynomial 0+1*v, we use it;
689             b2) It is other pari value, we ignore it;
690             c) it is a string containing junk, same as 'b';
691             d) It is an ep value => typo (same iterator in two loops).
692             In any case we localize the value.
693             */
694 1684           FETCH_CODE_const char *s = Nullch;
695             FETCH_CODE_const char *s1;
696             long hash;
697             entree *ep;
698             char name[50];
699              
700 1684 100         if (SvROK(sv)) {
701 1638           SV* tsv = SvRV(sv);
702 1638 50         if (SvOBJECT(tsv)) {
703 1638 100         if (SvSTASH(tsv) == pariStash) {
704             is_pari:
705             {
706 1637 100         GEN x = (GEN)SV_myvoidp_get(tsv);
    50          
707 1637 100         if (typ(x) == t_POL /* Polynomial. */
708 1632 50         && lgef(x)==4 /* 2 terms */
709 1632 50         && (gcmp0((GEN)x[2])) /* Free */
710 1632 50         && (gcmp1((GEN)x[3]))) { /* Leading */
711 1632           s = varentries[ORDVAR(varn(x))]->name;
712 1632           goto repeat;
713             }
714 5           goto ignore;
715             }
716 1 50         } else if (SvSTASH(tsv) == pariEpStash) {
717             is_pari_ep:
718             {
719             /* Itsn't good to croak: $v=PARIvar 'v'; vector(3,$v,'v'); */
720             if (generate)
721             /*croak("Same iterator in embedded PARI loop construct")*/;
722 1 50         return (entree*) SV_myvoidp_get(tsv);
    0          
723             }
724 0 0         } else if (sv_derived_from(sv, "Math::Pari")) { /* Avoid recursion */
725 0 0         if (sv_derived_from(sv, "Math::Pari::Ep"))
726 0           goto is_pari_ep;
727             else
728 0           goto is_pari;
729             }
730             }
731             }
732 46 100         if (!SvOK(sv))
    50          
    50          
733 39           goto ignore;
734 7 100         s = SvPV(sv,na);
735             repeat:
736 1684           s1 = s;
737 3687 100         while (isalnum((unsigned char)*s1))
738 2003           s1++;
739 1684 100         if (*s1 || s1 == s || !isalpha((unsigned char)*s)) {
    50          
    50          
740             static int depth;
741              
742             ignore:
743 45 50         if (!generate)
744 0           croak("Bad PARI variable name \"%s\" specified",s);
745 45           SAVEINT(depth);
746 45           sprintf(name, "intiter%i",depth++);
747 45           s = name;
748 45           goto repeat;
749             }
750              
751 1684           return my_fetch_named_var(s);
752             }
753              
754             #if PARI_VERSION_EXP >= 2004000
755             /* # define findVariable(sv,gen) (sv) */ /* Not needed */
756             # define bindVariable(sv) (sv)
757             #else /* !(PARI_VERSION_EXP >= 2004000) */
758             static PariVar
759 1681           bindVariable(SV *sv)
760             {
761             /* There may be 4 important cases:
762             a) we got a 'word' string, which we interpret as the name of
763             the variable to use;
764             b1) It is a pari value containing a polynomial 0+1*v, we use it;
765             b2) It is other pari value, we ignore it, and generate a suitable name of iteration variable;
766             c) it is a string containing junk, same as 'b2';
767             d) It is an ep value => typo (same iterator in two loops).
768             In any case we localize the value.
769             */
770 1681           long override = 0;
771             entree *ep;
772              
773 1681 100         if (!SvREADONLY(sv)) {
774 1676           save_item(sv); /* Localize it. */
775 1676           override = 1;
776             }
777 1681           ep = findVariable(sv, 1);
778 1681 100         if (override) {
779 1676           sv_setref_pv(sv, "Math::Pari::Ep", (void*)ep);
780 1676           make_PariAV(sv);
781             }
782 1681           return ep;
783             }
784             #endif /* !(PARI_VERSION_EXP >= 2004000) */
785              
786             static int
787 0           not_here(char *s)
788             {
789 0           croak("%s not implemented on this architecture", s);
790             return -1;
791             }
792              
793             unsigned long
794 3           longword(GEN x, long n)
795             {
796 3 100         if (n < 0 || n >= lg(x))
    100          
797 2           croak("The longword %ld ordinal out of bound", n);
798 1           return x[n];
799             }
800              
801             SV* worksv = 0;
802             SV* workErrsv = 0;
803              
804             /* Our output routines may be called several times during a Perl's statement */
805             #define renewWorkSv \
806             ((SvREFCNT(worksv) > 1 && /* Still in use */ \
807             (SvREFCNT_dec(worksv), /* Abandon the old copy */ \
808             worksv = NEWSV(910,0))), \
809             SvREFCNT_inc(worksv)) /* It is going to be mortalized soon */
810              
811             void
812 127748           svputc(char c)
813             {
814 127748           sv_catpvn(worksv,&c,1);
815 127748           }
816              
817             #if PARI_VERSION_EXP >= 2002005
818             # define PUTS_CONST const
819             #else
820             # define PUTS_CONST
821             #endif
822              
823             #if PARI_VERSION_EXP < 2005000 && !defined(taille) /* When did it appear??? In >= 2.5.0 the definition of taille() and taille2() are mixed up */
824             # define gsizeword taille
825             #endif
826              
827             void
828 104250           svputs(PUTS_CONST char* p)
829             {
830 104250           sv_catpv(worksv,p);
831 104250           }
832              
833             void
834 131           svErrputc(char c)
835             {
836 131           sv_catpvn(workErrsv,&c,1);
837 131           }
838              
839             void
840 71           svErrputs(PUTS_CONST char* p)
841             {
842 71           sv_catpv(workErrsv,p);
843 71           }
844              
845             void
846 0           svOutflush(void)
847             {
848             /* EMPTY */
849 0           }
850              
851             /* Support error messages of the form (calling PARI('O(det2($mat))')):
852             PARI: *** obsolete function: O(det2($mat))
853             ^----------- */
854              
855             void
856 14           svErrflush(void)
857             {
858             STRLEN l;
859 14 50         char *s = SvPV(workErrsv, l);
860              
861 14 50         if (s && l) {
    50          
862 0           char *nl = memchr(s,'\n',l);
863 0 0         char *nl1 = nl ? memchr(nl+1,'\n',l - (STRLEN)(nl-s+1)) : NULL;
864              
865             /* Avoid signed/unsigned mismatch */
866 0 0         if (nl1 && (STRLEN)(nl1 - s) < l - 1)
    0          
867 0           warn("PARI: %.*s%*s%.*s%*s%s", (int)(nl + 1 - s), s, 6, "", (int)(nl1 - nl), nl + 1, 6, "", nl1 + 1);
868 0 0         else if (nl && (STRLEN)(nl - s) < l - 1)
    0          
869 0           warn("PARI: %.*s%*s%s", (int)(nl + 1 - s), s, 6, "", nl + 1);
870             else
871 0           warn("PARI: %s", s);
872 0           sv_setpv(workErrsv,"");
873             }
874 14           }
875              
876             enum _Unknown_Exception {Unknown_Exception=-1000};
877              
878             static pari_sp global_top;
879              
880             void
881 14           _svErrdie(long e)
882             {
883 14           SV *errSv = newSVsv(workErrsv);
884             STRLEN l;
885 14 50         char *s = SvPV(errSv,l), *nl, *nl1;
886              
887             if (e == -1) { /* XXXX Need to abandon our references to stack positions! */
888             }
889 14           sv_setpvn(workErrsv,"",0);
890 14           sv_2mortal(errSv);
891 14 50         if (l && s[l-1] == '\n')
    50          
892 0           s[l-- - 1] = 0;
893 14 50         if (l && s[l-1] == '.')
    100          
894 9           s[l-- - 1] = 0;
895 14           nl = memchr(s,'\n',l);
896 14 100         nl1 = nl ? memchr(nl+1,'\n',l - (STRLEN)(nl-s+1)) : NULL;
897              
898             #if PARI_VERSION_EXP >= 2005000 /* Undocumented when it changed; needed in 2.5.0 */
899             # ifdef CB_EXCEPTION_FLAGS
900             if (!cb_exception_resets_avma)
901             # endif
902             myPARI_top = global_top;
903             #endif
904             /* Avoid signed/unsigned mismatch */
905 14 100         if (nl1 && (STRLEN)(nl1 - s) < l - 1)
    50          
906 2           croak("PARI: %.*s%*s%.*s%*s%s", (int)(nl + 1 - s), s, 6, "", (int)(nl1 - nl), nl + 1, 6, "", nl1 + 1);
907 12 100         else if (nl && (STRLEN)(nl - s) < l - 1)
    50          
908 9           croak("PARI: %.*s%*s%s", (int)(nl + 1 - s), s, 6, "", nl + 1);
909             else
910 3           croak("PARI: %s", s);
911             }
912              
913             int
914 0           math_pari_handle_exception(long e)
915             {
916             # ifdef CB_EXCEPTION_FLAGS
917             if (!cb_exception_resets_avma)
918             # endif
919 0           myPARI_top = avma; /* ??? XXXX Do not let evalstate_reset() steal our avma! */
920 0           return 0;
921             }
922              
923             #if PARI_VERSION_EXP < 2004000 /* Undocumented when it changed; not present in 2.5.0 */
924             void
925 14           svErrdie(void)
926             {
927 14           _svErrdie(Unknown_Exception);
928 0           }
929              
930             PariOUT perlOut={svputc, svputs, svOutflush, NULL};
931             PariOUT perlErr={svErrputc, svErrputs, svErrflush, svErrdie};
932             #else /* !(PARI_VERSION_EXP < 2004000) */
933             PariOUT perlOut={svputc, svputs, svOutflush};
934             PariOUT perlErr={svErrputc, svErrputs, svErrflush};
935             #endif /* !(PARI_VERSION_EXP < 2004000) */
936              
937             static GEN
938 1           my_ulongtoi(ulong uv)
939             {
940 1           pari_sp oldavma = avma;
941 1           GEN a = stoi((long)(uv>>1));
942              
943 1           a = gshift(a, 1);
944 1 50         if (uv & 0x1)
945 0           a = gadd(a, gen_1);
946 1           return gerepileupto(oldavma, a);
947             }
948              
949             #ifdef LONG_SHORTER_THAN_IV
950             GEN
951             my_UVtoi(UV uv)
952             {
953             pari_sp oldavma = avma;
954             GEN a = my_ulongtoi((ulong)(uv>>(8*sizeof(ulong))));
955             GEN b = my_ulongtoi((ulong)(uv & ((((UV)1)<<(8*sizeof(ulong))) - 1)));
956              
957             a = gshift(a, (8*sizeof(ulong)));
958             return gerepileupto(oldavma, gadd(a,b));
959             }
960             GEN
961             my_IVtoi(IV iv)
962             {
963             pari_sp oldavma = avma;
964             GEN a;
965              
966             if (iv >= 0)
967             return my_UVtoi((UV)iv);
968             oldavma = avma;
969             return gerepileupto(oldavma, gneg(my_UVtoi((UV)-iv)));
970             }
971              
972             #else
973             #define my_IVtoi stoi
974             #define my_UVtoi my_ulongtoi
975             #endif
976              
977             #ifdef SvIsUV
978             # define mySvIsUV SvIsUV
979             #else
980             # define mySvIsUV(sv) 0
981             #endif
982             #define PerlInt_to_i(sv) (mySvIsUV(sv) ? my_UVtoi(SvUV(sv)) : my_IVtoi(SvIV(sv)))
983              
984             static int warn_undef = 0; /* Cannot enable until 'I' prototype can be distinguished: it may return undef correctly */
985              
986             #define is_gnil(g) ((g) == gnil)
987              
988             static GEN
989 2183           str2gen(char *s, int prefer_str)
990             {
991 2183 50         if (!prefer_str) return readseq(s);
992             { /* as genconcat() */
993 0           long ll, l = nchar2nlong((ll = strlen(s)) + 1);
994 0           GEN x = cgetg(l + 1, t_STR);
995            
996 0           strncpy(GSTR(x), s, ll+1);
997 0           return x;
998             }
999             }
1000              
1001             #define sv2pari(sv) sv2pariHow(sv,0)
1002             #define sv2pariStr(sv) sv2pariHow(sv,1) /* When given an array, use sv2pari() on the elements */
1003             #define sv2pariStrDeep(sv) sv2pariHow(sv,2)
1004              
1005             GEN
1006 20344970           sv2pariHow(SV* sv, int prefer_str)
1007             {
1008 20344970 100         if (SvGMAGICAL(sv)) mg_get(sv); /* MAYCHANGE in perlguts.pod - bug in perl */
1009 20344970 100         if (SvROK(sv)) {
1010 13373225           SV* tsv = SvRV(sv);
1011 13373225 100         if (SvOBJECT(tsv)) {
1012 13372769 100         if (SvSTASH(tsv) == pariStash) {
1013             is_pari:
1014             {
1015 9028185 100         return (GEN) SV_myvoidp_get(tsv);
    50          
1016             }
1017 4344586 100         } else if (SvSTASH(tsv) == pariEpStash) {
1018             is_pari_ep:
1019             {
1020 4344584 50         return (GEN)(((entree*) SV_myvoidp_get(tsv))->value);
    0          
1021             }
1022 2 50         } else if (sv_derived_from(sv, "Math::Pari")) { /* Avoid recursion */
1023 2 50         if (sv_derived_from(sv, "Math::Pari::Ep"))
1024 0           goto is_pari_ep;
1025             else
1026 2           goto is_pari;
1027             }
1028             }
1029             {
1030 456           int type = SvTYPE(tsv);
1031 456 50         if (type==SVt_PVAV) {
1032 456           AV* av=(AV*) tsv;
1033 456           I32 len=av_len(av); /* Length-1 */
1034 456           GEN ret=cgetg(len+2, t_VEC);
1035             int i;
1036 1524 100         for (i=0;i<=len;i++) {
1037 1068           SV** svp=av_fetch(av,i,0);
1038 1068 50         if (!svp) croak("Internal error in sv2pari!");
1039 1068 50         ret[i+1]=(long)sv2pariHow(*svp, prefer_str > 1 ? 2 : 0);
1040             }
1041 456           return ret;
1042             } else {
1043 0 0         return readseq(SvPV(sv,na)); /* For overloading */
1044             }
1045             }
1046             }
1047 6971745 100         else if (SvIOK(sv)) return PerlInt_to_i(sv);
    100          
    50          
    50          
1048 2637 100         else if (SvNOK(sv)) {
1049 381 50         double n = (double)SvNV(sv);
1050             #if !defined(PERL_VERSION) || (PERL_VERSION < 6)
1051             /* Earlier needed more voodoo, since sv_true sv_false are NOK,
1052             but not IOK. Now we propagate them to IOK in Pari.pm;
1053             This works at least with 5.5.640 onwards. */
1054             /* With 5.00553 they are (NOK,POK,READONLY,pNOK,pPOK).
1055             This would special-case all READONLY double-headed stuff;
1056             let's hope it is not too frequent... */
1057             if (SvREADONLY(sv) && SvPOK(sv) && (n == 1 || n == 0))
1058             return stoi((long)n);
1059             #endif /* !defined(PERL_VERSION) || (PERL_VERSION < 6) */
1060 381           return dbltor(n);
1061             }
1062 2256 100         else if (SvPOK(sv)) return str2gen(SvPV(sv,na), prefer_str);
    50          
1063 73 50         else if (SvIOKp(sv)) return PerlInt_to_i(sv);
    0          
    0          
    0          
1064 73 50         else if (SvNOKp(sv)) return dbltor((double)SvNV(sv));
    0          
1065 73 50         else if (SvPOKp(sv)) return str2gen(SvPV(sv,na), prefer_str);
    0          
1066 73 50         else if (SvOK(sv)) croak("Variable in sv2pari is not of known type");
    50          
    50          
1067              
1068 73 50         if (warn_undef) warn("undefined value in sv2pari");
1069 73           return gnil; /* was: stoi(0) */ /* !SvOK(sv) */
1070             }
1071              
1072             GEN
1073 62           sv2parimat(SV* sv)
1074             {
1075 62           GEN in=sv2pari(sv);
1076 62 50         if (typ(in)==t_VEC) {
1077 62           long len=lg(in)-1;
1078             long t;
1079 62           long l=lg((GEN)(in[1]));
1080 186 100         for (;len;len--) {
1081 124           GEN elt = (GEN)(in[len]);
1082              
1083 124 50         if ((t=typ(elt)) == t_VEC) {
1084 124           settyp(elt, t_COL);
1085 0 0         } else if (t != t_COL) {
1086 0           croak("Not a vector where column of a matrix expected");
1087             }
1088 124 50         if (lg(elt)!=l) {
1089 0           croak("Columns of input matrix are of different height");
1090             }
1091             }
1092 62           settyp(in, t_MAT);
1093 0 0         } else if (typ(in) != t_MAT) {
1094 0           croak("Not a matrix where matrix expected");
1095             }
1096 62           return in;
1097             }
1098              
1099             SV*
1100 1489           pari2iv(GEN in)
1101             {
1102             #ifdef SvIsUV
1103             # define HAVE_UVs 1
1104             UV uv;
1105             #else
1106             # define HAVE_UVs 0
1107             IV uv;
1108             #endif
1109 1489           int overflow = 0;
1110              
1111 1489 50         if (typ(in) != t_INT)
1112 0           return newSViv((IV)gtolong(in));
1113 1489           switch (lgef(in)) {
1114             case 2:
1115 1443           uv = 0;
1116 1443           break;
1117             case 3:
1118 46           uv = in[2];
1119 46 50         if (sizeof(long) >= sizeof(IV) && in[2] < 0)
1120 0           overflow = 1;
1121 46           break;
1122             case 4:
1123             if ( 2 * sizeof(long) > sizeof(IV)
1124             || ((2 * sizeof(long) == sizeof(IV)) && !HAVE_UVs && in[2] < 0) )
1125 0           goto do_nv;
1126             uv = in[2];
1127             uv = (uv << TWOPOTBYTES_IN_LONG) + in[3];
1128             break;
1129             default:
1130 0           goto do_nv;
1131             }
1132 1489 50         if (overflow) {
1133             #ifdef SvIsUV
1134 0 0         if (signe(in) > 0) {
1135 0           SV *sv = newSViv((IV)uv);
1136              
1137 0           SvIsUV_on(sv);
1138 0           return sv;
1139             } else
1140             #endif
1141 0           goto do_nv;
1142             }
1143 1489 100         return newSViv(signe(in) > 0 ? (IV)uv : -(IV)uv);
1144             do_nv:
1145 0           return newSVnv(gtodouble(in)); /* XXXX to NV, not to double? */
1146             }
1147              
1148             #if PARI_VERSION_EXP >= 2002005 && PARI_VERSION_EXP <= 2002007
1149             # define _gtodouble gtodouble
1150             #else /* !(PARI_VERSION_EXP >= 2002005 && PARI_VERSION_EXP <= 2002007) */
1151              
1152             #ifndef m_evallg
1153             # define m_evallg _evallg
1154             #endif
1155              
1156             double
1157 1           _gtodouble(GEN x)
1158             {
1159             static long reel4[4]={ evaltyp(t_REAL) | m_evallg(4),0,0,0 };
1160              
1161 1 50         if (typ(x)==t_REAL) return rtodbl(x);
1162 1           gaffect(x,(GEN)reel4); return rtodbl((GEN)reel4);
1163             }
1164             #endif /* !(PARI_VERSION_EXP >= 2002005 && PARI_VERSION_EXP <= 2002007) */
1165              
1166             #if PARI_VERSION_EXP >= 2003000 /* In 2.3.5 is using argument 0, in 2.1.7 it is still 1. */
1167             # define mybrute brute
1168             #else /* !(PARI_VERSION_EXP >= 2003000) */
1169             # if PARI_VERSION_EXP >= 2002005 && PARI_VERSION_EXP <= 2002007
1170             static void
1171             _initout(pariout_t *T, char f, long sigd, long sp, long fieldw, int prettyp)
1172             {
1173             T->format = f;
1174             T->sigd = sigd;
1175             T->sp = sp;
1176             T->fieldw = fieldw;
1177             T->initial = 1;
1178             T->prettyp = prettyp;
1179             }
1180              
1181             void
1182             mybruteall(GEN g, char f, long d, long sp)
1183             {
1184             pariout_t T; _initout(&T,f,d,sp,0, f_RAW);
1185             my_gen_output(g, &T);
1186             }
1187             # else /* !((PARI_VERSION_EXP >= 2002005 && PARI_VERSION_EXP <= 2002007) || PARI_VERSION_EXP >= 2004000) */
1188             # define mybruteall bruteall
1189             # endif /* !((PARI_VERSION_EXP >= 2002005 && PARI_VERSION_EXP <= 2002007) || PARI_VERSION_EXP >= 2004000) */
1190             # define mybrute(g,f,d) mybruteall(g,f,d,0) /* 0: compact pari-readable form */
1191             #endif /* !(PARI_VERSION_EXP >= 2003000) */
1192              
1193             SV*
1194 1           pari2nv(GEN in)
1195             {
1196 1           return newSVnv(_gtodouble(in));
1197             }
1198              
1199             SV*
1200 547           pari2pv(GEN in)
1201             {
1202 547 100         renewWorkSv;
    50          
1203 547 100         if (typ(in) == t_STR) /* Puts "" around without special-casing */
1204 1           return sv_setpv(worksv, GSTR(in)), worksv;
1205             {
1206 546           PariOUT *oldOut = pariOut;
1207 546           pariOut = &perlOut;
1208 546           sv_setpvn(worksv,"",0);
1209 546           mybrute(in,'g',-1);
1210 546           pariOut = oldOut;
1211 546           return worksv;
1212             }
1213             }
1214              
1215             long
1216 26           setprecision(long digits)
1217             {
1218 26           long m = fmt_nbP;
1219              
1220 26 50         if(digits>0) {fmt_nbPset(digits); prec_digits_set(digits);}
1221 26           return m;
1222             }
1223              
1224             #if 0
1225             long
1226             setbitprecision(long bits)
1227             {
1228             long m = fmt_nbP;
1229              
1230             if(bits>0) {fmt_nbPset((long)bits*10/3); prec_bits_set(bits);}
1231             return m;
1232             }
1233             #endif
1234              
1235             #if PARI_VERSION_EXP < 2002012 || PARI_VERSION_EXP >= 2003000
1236             long
1237 1           setseriesprecision(long digits)
1238             {
1239 1           long m = precdl;
1240              
1241 1 50         if(digits>0) {precdl = digits;}
1242 1           return m;
1243             }
1244             #endif /* PARI_VERSION_EXP < 2002012 || PARI_VERSION_EXP >= 2003000 */
1245              
1246             static IV primelimit;
1247             static UV parisize;
1248              
1249             IV
1250 0           setprimelimit(IV n)
1251             {
1252             byteptr ptr;
1253 0           IV o = primelimit;
1254              
1255 0 0         if (n != 0) {
1256             #if PARI_VERSION_EXP < 2007000
1257 0           ptr = initprimes(n);
1258 0           free(diffptr);
1259 0           diffptr = ptr;
1260 0           primelimit = n;
1261             #else
1262             initprimetable(n);
1263             #endif
1264             }
1265 0           return o;
1266             }
1267              
1268             SV*
1269 802           pari_print(GEN in)
1270             {
1271 802           PariOUT *oldOut = pariOut;
1272 802           pariOut = &perlOut;
1273 802 50         renewWorkSv;
    0          
1274 802           sv_setpvn(worksv,"",0);
1275 802           brute(in, 'g', fmt_nbP);
1276 802           pariOut = oldOut;
1277 802           return worksv;
1278             }
1279              
1280             SV*
1281 0           pari_pprint(GEN in)
1282             {
1283 0           PariOUT *oldOut = pariOut;
1284 0           pariOut = &perlOut;
1285 0 0         renewWorkSv;
    0          
1286 0           sv_setpvn(worksv,"",0);
1287             #if PARI_VERSION_EXP >= 2004000
1288             brute(in, 'g', fmt_nbP); /* Make a synonim of pari_print(), as in GP/PARI */
1289             #else
1290 0           sor(in, 'g'/*fmt.format*/, fmt_nbP, 0/*fmt.field*/);
1291             #endif
1292 0           pariOut = oldOut;
1293 0           return worksv;
1294             }
1295              
1296             SV*
1297 0           pari_texprint(GEN in)
1298             {
1299 0           PariOUT *oldOut = pariOut;
1300 0           pariOut = &perlOut;
1301 0 0         renewWorkSv;
    0          
1302 0           sv_setpvn(worksv,"",0);
1303 0           texe(in, 'g', fmt_nbP);
1304 0           pariOut = oldOut;
1305 0           return worksv;
1306             }
1307              
1308             SV*
1309 1566           pari2mortalsv(GEN in, long oldavma)
1310             { /* Oldavma should keep the value of
1311             * avma when entering a function call. */
1312 1566           SV *sv = sv_newmortal();
1313              
1314 1566 50         setSVpari_keep_avma(sv, in, oldavma);
    0          
    0          
    100          
    50          
    50          
1315 1566           return sv;
1316             }
1317              
1318             typedef struct {
1319             long items, words;
1320             SV *acc;
1321             int context;
1322             } heap_dumper_t;
1323              
1324             #ifndef BL_HEAD /* in 2.5.0 it is 4 */
1325             # define BL_HEAD 3 /* from init.c */
1326             #endif
1327             static void
1328 0           heap_dump_one(heap_dumper_t *d, GEN x)
1329             {
1330             SV* tmp;
1331              
1332 0           d->items++;
1333 0 0         if(!x[0]) { /* user function */
1334 0           d->words += strlen((char *)(x+2))/sizeof(long);
1335 0           tmp = newSVpv((char*)(x+2),0);
1336 0 0         } else if (x==bernzone) {
1337 0           d->words += x[0];
1338 0           tmp = newSVpv("bernzone",8);
1339             } else { /* GEN */
1340 0           d->words += gsizeword(x);
1341 0           tmp = pari_print(x);
1342             }
1343             /* add to output */
1344 0           switch(d->context) {
1345             case G_VOID:
1346 0 0         case G_SCALAR: sv_catpvf(d->acc, " %2ld: %s\n",
1347 0           (long)(d->items - 1), SvPV_nolen(tmp));
1348 0           SvREFCNT_dec(tmp); break;
1349 0           case G_ARRAY: av_push((AV*)d->acc,tmp); break;
1350             }
1351 0           }
1352              
1353             #if PARI_VERSION_EXP >= 2002012
1354              
1355             static void
1356 0           heap_dump_one_v(GEN x, void *v)
1357             {
1358 0           heap_dumper_t *d = (heap_dumper_t *)v;
1359              
1360 0           heap_dump_one(d, x);
1361 0           }
1362              
1363             static void
1364 0           heap_dumper(heap_dumper_t *d)
1365             {
1366 0           traverseheap(&heap_dump_one_v, (void*)d);
1367 0           }
1368              
1369             #else /* !( PARI_VERSION_EXP >= 2002012 ) */
1370              
1371             static void
1372             heap_dumper(heap_dumper_t *d)
1373             {
1374             /* create a new block on the heap so we can examine the linked list */
1375             GEN tmp1 = newbloc(1); /* at least 1 to avoid warning */
1376             GEN x = (GEN)bl_prev(tmp1);
1377              
1378             killbloc(tmp1);
1379              
1380             /* code adapted from getheap() in PARI src/language/init.c */
1381             for(; x; x = (GEN)bl_prev(x))
1382             heap_dump_one(d, x);
1383             }
1384              
1385             #endif /* !( PARI_VERSION_EXP >= 2002012 ) */
1386              
1387             void
1388 2           resetSVpari(SV* sv, GEN g, pari_sp oldavma)
1389             {
1390 2 50         if (SvROK(sv)) {
1391 2           SV* tsv = SvRV(sv);
1392              
1393 2 50         if (g && SvOBJECT(tsv)) {
    50          
1394 2           IV tmp = 0;
1395              
1396 2 50         if (SvSTASH(tsv) == pariStash) {
1397             #if 0 /* To dangerous to muck with this */
1398             is_pari:
1399             #endif
1400             {
1401 2 50         tmp = SvIV(tsv);
1402             }
1403             }
1404             #if 0 /* To dangerous to muck with this */
1405             else if (SvSTASH(tsv) == pariEpStash) {
1406             is_pari_ep:
1407             {
1408             tmp = SvIV(tsv);
1409             tmp = PTR2IV((INT2PTR(entree*, tmp))->value);
1410             }
1411             }
1412             else if (sv_derived_from(sv, "Math::Pari")) { /* Avoid recursion */
1413             if (sv_derived_from(sv, "Math::Pari::Ep"))
1414             goto is_pari_ep;
1415             else
1416             goto is_pari;
1417             }
1418             #endif
1419 2 50         if (tmp == PTR2IV(g)) /* Did not change */
1420 0           return;
1421             }
1422             }
1423             /* XXXX do it the non-optimized way */
1424 2 50         setSVpari_keep_avma(sv,g,oldavma);
    0          
    0          
    50          
    50          
    50          
1425             }
1426              
1427             static const
1428             unsigned char defcode[] = "xD0,G,D0,G,D0,G,D0,G,D0,G,D0,G,";
1429             int def_numargs = 6;
1430              
1431             static int doing_PARI_autoload = 0;
1432              
1433             long
1434 2830218           moveoffstack_newer_than(SV* sv)
1435             {
1436             SV* sv1;
1437             SV* nextsv;
1438 2830218           long ret=0;
1439            
1440 8080974 100         for (sv1 = PariStack; sv1 != sv; sv1 = nextsv) {
1441 5250756           ret++;
1442 5250756 100         SV_OAVMA_switch(nextsv, sv1, GENmovedOffStack); /* Mark as moved off stack. */
1443 5250756 100         SV_myvoidp_reset_clone(sv1); /* Relocate to cloned */
    50          
1444 5250756           onStack_dec;
1445 5250756           offStack_inc;
1446             }
1447 2830218           PariStack = sv;
1448 2830218           return ret;
1449             }
1450              
1451             #if PARI_VERSION_EXP > 2004002
1452             typedef long PerlFunctionArg1;
1453             # define toEntreeP(l) ((entree *)(l))
1454             # define elt_CV pvalue
1455             #else
1456             typedef entree *PerlFunctionArg1;
1457             # define toEntreeP
1458             # define elt_CV value
1459             #endif
1460              
1461             GEN
1462 1473           callPerlFunction_va_list(int rettype, int numargs, SV *cv, va_list args)
1463             {
1464             GEN res;
1465             int i;
1466 1473           dSP;
1467             int count ;
1468 1473           pari_sp oldavma = avma;
1469 1473           SV *oPariStack = PariStack;
1470             SV *sv;
1471              
1472             /* warn("Entering Perl handler inside PARI, %d args", numargs); */
1473 1473           ENTER ;
1474 1473           SAVETMPS;
1475 1473           SAVEINT(sentinel);
1476 1473           sentinel = avma;
1477 1473 50         PUSHMARK(sp);
1478 1473 50         EXTEND(sp, numargs + 1);
    50          
1479 3039 100         for (i = 0; i < numargs; i++) {
1480             /* It should be OK to have the same oldavma here, since avma
1481             is not modified... */
1482 1566 100         PUSHs(pari2mortalsv(va_arg(args, GEN), oldavma));
1483             /* warn("pushed an argument"); */
1484             }
1485 1473           PUTBACK;
1486 1473           count = perl_call_sv(cv, rettype);
1487 1473 50         if (rettype == G_VOID && count == 1)
    0          
1488 0           count = 0;
1489              
1490 1473           SPAGAIN;
1491 1473 50         if (count != (rettype == G_SCALAR))
1492 0           croak("Perl function exported into PARI returns unexpected number %d of values (need %d)", count, (rettype == G_SCALAR));
1493              
1494 1473 50         if (rettype == G_SCALAR)
1495 1473           sv = SvREFCNT_inc(POPs); /* Preserve the guy. */
1496              
1497 1473           PUTBACK ;
1498 1473 100         FREETMPS ;
1499 1473           LEAVE ;
1500              
1501 1473 50         if (rettype == G_VOID)
1502 0           return 0;
1503             /* Now PARI data created inside this subroutine sits above
1504             oldavma, but the caller is going to unwind the stack: */
1505 1473 50         if (PariStack != oPariStack)
1506 0           moveoffstack_newer_than(oPariStack);
1507             /* Now, when everything is moved off stack, and avma is reset, we
1508             can get the answer: */
1509 1473           res = sv2pari(sv); /* XXXX When to decrement the count? */
1510             /* We need to copy it back to stack, otherwise we cannot decrement
1511             the count. The ABI is that a C function [which can be put into a
1512             GP/PARI function C-function slot] should have its result
1513             completely on stack. */
1514 1473           res = myforcecopy(res);
1515 1473           SvREFCNT_dec(sv);
1516            
1517 1473           return res;
1518             }
1519              
1520             GEN
1521 1473           callPerlFunction(PerlFunctionArg1 long_ep, ...)
1522             {
1523             GEN res;
1524 1473           entree *ep = toEntreeP(long_ep);
1525             va_list args;
1526 1473           SV *cv = (SV*) ep->elt_CV;
1527 1473           int numargs = CV_NUMARGS_get(cv);
1528              
1529 1473           va_start(args, long_ep);
1530             /* warn("calling with numargs=%d", numargs); */
1531 1473           res = callPerlFunction_va_list(G_SCALAR, numargs, cv, args);
1532             /* warn("ending call"); */
1533 1473           va_end(args);
1534             /* warn("ended call"); */
1535 1473           return res;
1536             }
1537              
1538             entree *
1539 10           installPerlFunctionCV(SV* cv, char *name, I32 numargs, char *help)
1540             {
1541             char *code, *s, *s0;
1542 10           I32 req = numargs, opt = 0;
1543             entree *ep;
1544             STRLEN len;
1545              
1546 10 100         if(SvROK(cv))
1547 1           cv = SvRV(cv);
1548              
1549 10 100         if (numargs < 0 && SvPOK(cv) && (s0 = s = SvPV(cv,len))) {
    100          
    50          
    50          
1550 7           char *end = s + len; /* CvCONST() may have a CvFILE() appended - depends on version */
1551              
1552             /* Get number of arguments. */
1553 7           req = opt = 0;
1554 16 100         while (s < end && *s == '$')
    50          
1555 9           req++, s++;
1556 7 50         if (s < end && *s == ';')
    0          
1557 0           s++;
1558 7 50         while (s < end && *s == '$')
    0          
1559 0           opt++, s++;
1560 7 50         if (s < end && *s == '@') {
    0          
1561 0           opt += 6; /* Max 6 optional arguments. */
1562 0           s++;
1563             }
1564 7 50         if (s == end) { /* Got it! */
1565 7           numargs = req + opt;
1566             } else {
1567 0           croak("Can't install Perl function with prototype `%s'", s0);
1568             }
1569             }
1570            
1571 10 100         if (numargs < 0) { /* Variable number of arguments. */
1572             /* Install something hairy with <= 6 args */
1573 2           code = (char*)defcode; /* Remove constness. */
1574 2           numargs = def_numargs;
1575 8 50         } else if (numargs >= 256) {
1576 0           croak("Import of Perl function with too many arguments");
1577             } else {
1578             /* Should not use gpmalloc(), since we call free()... */
1579 8           code = (char *)malloc(numargs*6 - req*5 + 2);
1580 8           code[0] = 'x';
1581 8           memset(code + 1, 'G', req);
1582 8           s = code + 1 + req;
1583 8 50         while (opt--) {
1584 0           strcpy(s, "D0,G,");
1585 0           s += 5;
1586             }
1587 8           *s = '\0';
1588             }
1589 10           CV_NUMARGS_set(cv, numargs);
1590 10           SAVEINT(doing_PARI_autoload);
1591 10           doing_PARI_autoload = 1;
1592 10           ep = install((void*)SvREFCNT_inc(cv), name, code);
1593             #if PARI_VERSION_EXP >= 2004002
1594             ep->pvalue = (void*)cv;
1595             ep->value = (void*)callPerlFunction;
1596             #endif
1597             /* warn("installed %#x code=<%s> numargs=%d", (int)ep->value, ep->code, (int)numargs); */
1598 10           doing_PARI_autoload = 0;
1599 10 100         if (code != (char*)defcode)
1600 8           free(code);
1601 10 50         if (help)
1602 0           ep->help = pari_strdup(help); /* Same code as in addhelp() so that the same free()ing code works */
1603 10           return ep;
1604             }
1605              
1606             void
1607 0           freePerlFunction(entree *ep)
1608             {
1609 0 0         if (!ep->code || (*ep->code != 'x')) {
    0          
1610 0           croak("Attempt to ask Perl to free PARI function not installed from Perl");
1611             }
1612 0 0         if (ep->code && (ep->code != (char *)defcode))
    0          
1613 0           free((void *)(ep->code));
1614 0           ep->code = NULL;
1615 0           SvREFCNT_dec((SV*)ep->elt_CV);
1616 0           ep->elt_CV = NULL;
1617 0           }
1618              
1619             void
1620 1           detach_stack(void)
1621             {
1622 1           moveoffstack_newer_than((SV *) GENfirstOnStack);
1623 1           }
1624              
1625             static unsigned long
1626 1           s_allocatemem(unsigned long newsize)
1627             {
1628             #ifdef CB_EXCEPTION_FLAGS
1629             int o = cb_exception_resets_avma;
1630             #endif
1631              
1632 1 50         if (newsize) {
1633 1           detach_stack();
1634             #if PARI_VERSION_EXP >= 2004000 /* ??? */
1635             # if PARI_VERSION_EXP >= 2009000 /* ??? */
1636             # ifdef CB_EXCEPTION_FLAGS__try_without
1637             cb_exception_resets_avma = 0; /* otherwise warn about stack increase would try to use old avma */
1638             # endif
1639             if (pari_mainstack->vsize)
1640             paristack_resize(newsize);
1641             else if (newsize != pari_mainstack->rsize)
1642             paristack_setsize(newsize, 0);
1643             # ifdef CB_EXCEPTION_FLAGS__try_without
1644             cb_exception_resets_avma = o;
1645             # endif
1646             # else /* !(PARI_VERSION_EXP >= 2009000) */
1647             pari_init_stack(newsize, 0);
1648             # endif /* !(PARI_VERSION_EXP >= 2009000) */
1649              
1650             parisize = myPARI_top - myPARI_bot;
1651             #else
1652 1           parisize = allocatemoremem(newsize);
1653             #endif
1654 1           perlavma = sentinel = avma;
1655             }
1656 1           global_top = myPARI_top;
1657 1           return parisize;
1658             }
1659              
1660             /* Currently with <=6 arguments only! */
1661              
1662             #if PARI_VERSION_EXP >= 2004000
1663             # define APF_CONST const
1664             #else /* !(PARI_VERSION_EXP >= 2004000) */
1665             # define APF_CONST
1666             #endif /* PARI_VERSION_EXP >= 2004000 */
1667              
1668             entree *
1669 668           autoloadPerlFunction(APF_CONST char *s, long len)
1670             {
1671             CV *cv;
1672             SV* name;
1673             HV* converted;
1674              
1675 668 100         if (doing_PARI_autoload)
1676 12           return 0;
1677 656           converted = perl_get_hv("Math::Pari::converted",TRUE);
1678 656 50         if (hv_fetch(converted, s, len, FALSE))
1679 0           return 0;
1680              
1681 656           name = sv_2mortal(newSVpv(s, len));
1682              
1683 656           cv = perl_get_cv(SvPVX(name), FALSE);
1684 656 100         if (cv == Nullcv) {
1685 647           return 0;
1686             }
1687             /* Got it! */
1688 9           return installPerlFunctionCV((SV*)cv, SvPVX(name), -1, NULL); /* -1 gives variable. */
1689             }
1690              
1691             GEN
1692 2376679           exprHandler_Perl(char *s)
1693             {
1694 2376679           SV* dummy = Nullsv; /* Avoid "without initialization" warnings from M$ */
1695 2376679           SV* cv = (SV*)(s - LSB_in_U32 -
1696             ((char*)&(dummy->sv_flags) - ((char*)dummy)));
1697             GEN res;
1698 2376679           dSP;
1699             SV *sv;
1700 2376679           SV *oPariStack = PariStack;
1701              
1702 2376679           ENTER ;
1703 2376679           SAVETMPS;
1704 2376679 50         PUSHMARK(sp);
1705 2376679           SAVEINT(sentinel);
1706 2376679           sentinel = avma;
1707 2376679           (void)perl_call_sv(cv, G_SCALAR); /* The retval is always 1 */
1708              
1709 2376679           SPAGAIN;
1710 2376679           sv = SvREFCNT_inc(POPs); /* Preserve it through FREETMPS */
1711              
1712 2376679           PUTBACK ;
1713 2376679 50         FREETMPS ;
1714 2376679           LEAVE ;
1715              
1716             /* Now PARI data created inside this subroutine sits above
1717             oldavma, but the caller is going to unwind the stack: */
1718 2376679 100         if (PariStack != oPariStack)
1719 57815           moveoffstack_newer_than(oPariStack);
1720             /* Now, when everything is moved off stack, and avma is reset, we
1721             can get the answer: */
1722 2376679           res = sv2pari(sv);
1723             /* We need to copy it back to stack, otherwise we cannot decrement
1724             the count. */
1725 2376679           res = myforcecopy(res);
1726 2376679           SvREFCNT_dec(sv);
1727            
1728 2376679           return res;
1729             }
1730              
1731             static GEN
1732 65           Arr_FETCH(GEN g, I32 n)
1733             {
1734 65           I32 l = lg(g) - 1;
1735              
1736 65 50         if (!is_matvec_t(typ(g)))
    50          
1737 0           croak("Access to elements of not-a-vector");
1738 65 50         if (n >= l || n < 0)
    50          
1739 0           croak("Array index %li out of range", (long)n);
1740             #if 0
1741             warn("fetching %ld-th element of type %d", (long)n, typ((GEN)g[n + 1]));
1742             #endif
1743 65           return (GEN)g[n + 1];
1744             }
1745              
1746             static void
1747 6           Arr_STORE(GEN g, I32 n, GEN elt)
1748             {
1749 6           I32 l = lg(g) - 1, docol = 0;
1750             GEN old;
1751              
1752 6 50         if (!is_matvec_t(typ(g)))
    50          
1753 0           croak("Access to elements of not-a-vector");
1754 6 50         if (n >= l || n < 0)
    50          
1755 0           croak("Array index %li out of range", (long)n);
1756             #if 0
1757             warn("storing %ld-th element of type %d", (long)n, typ((GEN)g[n + 1]));
1758             #endif /* 0 */
1759              
1760 6 100         if (typ(g) == t_MAT) {
1761 4           long len = lg(g);
1762 4           long l = lg((GEN)(g[1]));
1763 4 50         if (typ(elt) != t_COL) {
1764 4 100         if (typ(elt) != t_VEC)
1765 1           croak("Not a vector where column of a matrix expected");
1766 3           docol = 1;
1767             }
1768 3 100         if (lg(elt)!=l && len != 2)
    100          
1769 1           croak("Assignment of a columns into a matrix of incompatible height");
1770             }
1771            
1772 4           old = (GEN)g[n + 1];
1773             /* It is not clear whether we need to clone if the elt is offstack */
1774 4           elt = gclone(elt);
1775 4 100         if (docol)
1776 2           settyp(elt, t_COL);
1777              
1778             /* anal.c is optimizing inspection away around here... */
1779 4 50         if (isclone(old)) killbloc(old);
1780 4           g[n + 1] = (long)elt;
1781 4           }
1782              
1783             #define Arr_FETCHSIZE(g) (lg(g) - 1)
1784             #define Arr_EXISTS(g,l) ((l)>=0 && l < lg(g) - 1)
1785              
1786             #define DFT_VAR (GEN)-1
1787             #define DFT_GEN (GEN)NULL
1788              
1789             static void
1790 0           check_pointer(unsigned int ptrs, GEN argvec[])
1791             {
1792             unsigned int i;
1793 0 0         for (i=0; ptrs; i++,ptrs>>=1)
1794 0 0         if (ptrs & 1) *((GEN*)argvec[i]) = gclone(*((GEN*)argvec[i]));
1795 0           }
1796              
1797             #define RETTYPE_VOID 0
1798             #define RETTYPE_LONG 1
1799             #define RETTYPE_GEN 2
1800             #define RETTYPE_INT 3
1801              
1802             #define ARGS_SUPPORTED 9
1803             #define THE_ARGS_SUPPORTED \
1804             argvec[0], argvec[1], argvec[2], argvec[3], \
1805             argvec[4], argvec[5], argvec[6], argvec[7], argvec[8]
1806              
1807             GEN code_return_1 = 0;
1808             GEN code2_return_1 = 0;
1809              
1810             #if PARI_VERSION_EXP >= 2004000
1811             struct trampoline_data_1v {SV *var1; SV* cv;};
1812              
1813             GEN
1814             callPerlFunction_var(int rettype, int numargs, SV *cv, ...)
1815             {
1816             va_list args;
1817             GEN res;
1818              
1819             va_start(args, cv);
1820             res = callPerlFunction_va_list(rettype, numargs, cv, args);
1821             va_end(args);
1822             return res;
1823             }
1824              
1825             static GEN code_trampoline_1v_ret(GEN v)
1826             {
1827             struct trampoline_data_1v *tr = (struct trampoline_data_1v*)itos(v);
1828             GEN arg1 = get_lex(-2); /* XXX one before v, which is -1 ??? */
1829             GEN res = callPerlFunction_var(G_SCALAR, 1, tr->cv, arg1);
1830              
1831             return res;
1832             }
1833              
1834             static void code_trampoline_vL_ret(long v)
1835             {
1836             struct trampoline_data_1v *tr = (struct trampoline_data_1v*)v;
1837             GEN arg1 = get_lex(-2); /* XXX one before v, which is -1 ??? */
1838              
1839             (void)callPerlFunction_var(G_VOID, 1, tr->cv, arg1); /* works with G_SCALAR */
1840             return;
1841             }
1842              
1843             static void code_trampoline_vG_ret(GEN v)
1844             {
1845             struct trampoline_data_1v *tr = (struct trampoline_data_1v*)itos(v);
1846             GEN arg1 = get_lex(-2); /* XXX one before v, which is -1 ??? */
1847             SV *oPariStack = PariStack;
1848              
1849             (void)callPerlFunction_var(G_VOID, 1, tr->cv, arg1); /* works with G_SCALAR */
1850              
1851             /* Now PARI data created inside this subroutine sits above
1852             oldavma, but the caller is going to unwind the stack: */
1853             if (PariStack != oPariStack)
1854             moveoffstack_newer_than(oPariStack);
1855             return;
1856             }
1857              
1858             static GEN code_trampoline_G_ret(GEN v)
1859             {
1860             struct trampoline_data_1v *tr = (struct trampoline_data_1v*)itos(v);
1861             GEN arg1 = get_lex(-2), ret; /* XXX one before v, which is -1 ??? */
1862             SV *oPariStack = PariStack;
1863              
1864              
1865             ret = callPerlFunction_var(G_SCALAR, 1, tr->cv, arg1);
1866             /* Now PARI data created inside this subroutine sits above
1867             oldavma, but the caller is going to unwind the stack: */
1868             if (PariStack != oPariStack)
1869             moveoffstack_newer_than(oPariStack);
1870             return ret;
1871             }
1872              
1873             static GEN code_trampoline_G_ret_SV(GEN v)
1874             {
1875             struct trampoline_data_1v *tr = (struct trampoline_data_1v*)itos(v);
1876             GEN arg1 = get_lex(-2), ret; /* XXX one before v, which is -1 ??? */
1877             SV *oPariStack = PariStack;
1878             pari_sp oldavma = avma;
1879              
1880             setSVpari_keep_avma(tr->var1, arg1, oldavma);
1881             ret = callPerlFunction_var(G_SCALAR, 0, tr->cv);
1882             /* Now PARI data created inside this subroutine sits above
1883             oldavma, but the caller is going to unwind the stack: */
1884             if (PariStack != oPariStack)
1885             moveoffstack_newer_than(oPariStack);
1886             return ret;
1887             }
1888             #endif /* PARI_VERSION_EXP >= 2004000 */
1889              
1890             #if PARI_VERSION_EXP >= 2004002 /* Undocumented when it appeared; present in 2.5.0 */
1891             static const entree eH_vG = {"___fake_MathPari_handler_vG",0x100/*EpSTATIC*/,(void*)code_trampoline_vG_ret,2,"vG","trampoline to call Perl call in PARI \"loops\"", 0, 1};
1892             static const entree eH_G = {"___fake_MathPari_handler_G",0x100/*EpSTATIC*/,(void*)code_trampoline_G_ret,2,"G","trampoline to call Perl call in PARI \"loops\"", 0, 1};
1893              
1894             static GEN
1895             make_trampolinecv(SV *cv, int is_void, SV *sv)
1896             { /* Poor man's snmk_closure(): create a no-argument closure which calls a 1-argument function e(callee);
1897             e extracts the current loop variable, and calls a 1-argument function callee->cv with this argument. */
1898             struct trampoline_data_1v *callee;
1899             char *s = "N/A";
1900             STRLEN len;
1901              
1902             if (!SvPOK(cv) || !(s = SvPV(cv,len)) || len != 1 || s[0] != '$') {
1903             warn("Argument-types E,I with prototype `%s' not supported yet, substituting x->1", s);
1904             return code_return_1;
1905             }
1906             warn("Ignoring the variable(s) of a closure");
1907             callee = (struct trampoline_data_1v*) stack_malloc(sizeof(struct trampoline_data_1v)); /* new_chunk(words)??? */
1908             callee->cv = cv;
1909             callee->var1 = sv;
1910             GEN extraargs = mkvec(stoi((long) callee)); /* Need real mkvec()!!! XXX ??? */
1911             return snm_closure((entree*) (is_void ? &eH_vG : &eH_G), extraargs);
1912             }
1913             #endif /* PARI_VERSION_EXP < 2004002 */ /* Undocumented when it appeared; present in 2.5.0 */
1914              
1915             static void
1916 1946           fill_argvect(entree *ep, const char *s, long *has_pointer, GEN *argvec,
1917             long *rettype, SV **args, int items,
1918             SV **sv_OUT, GEN *gen_OUT, long *OUT_cnt)
1919             { /* The last 3 to support '&' code - treated after the call */
1920             entree *ep1;
1921 1946           int i = 0, j = 0, saw_M = 0, saw_V = 0;
1922             long fake;
1923 1946           const char *s0 = s, *pre;
1924             PariExpr expr;
1925             #if PARI_VERSION_EXP >= 2004002
1926             # define MaxPariVar 7
1927             PariVar loopvars[MaxPariVar];
1928             # define LoopVar(i) loopvars[i]
1929             #else
1930             # define LoopVar(i) N/A
1931             #endif
1932              
1933 1946 50         if (!ep)
1934 0           croak("XSUB call through interface did not provide *function");
1935 1946 50         if (!s)
1936 0           croak("XSUB call through interface with a NULL code");
1937              
1938 1946           *OUT_cnt = 0;
1939 14389 100         while (*s) {
1940 12443 50         if (i >= ARGS_SUPPORTED - 1)
1941 0           croak("Too many args for a flexible-interface function");
1942 12443           switch (*s++)
1943             {
1944             case 'G': /* GEN */
1945 4520           argvec[i++] = sv2pari(args[j++]);
1946 4520           break;
1947              
1948             case 'M': /* long or a mneumonic string (string not supported) */
1949 2           saw_M = 1;
1950             /* Fall through */
1951             #if PARI_VERSION_EXP >= 2004002
1952             case 'P': /* series precision */
1953             #endif
1954             case 'L': /* long */
1955 134 100         argvec[i++] = (GEN) (long)SvIV(args[j]);
1956 134           j++;
1957 134           break;
1958              
1959             case 'n': /* var number */
1960 4           argvec[i++] = (GEN) numvar(sv2pari(args[j++]));
1961 4           break;
1962              
1963             case 'V': /* variable */
1964             #if PARI_VERSION_EXP < 2004002
1965 1381           ep1 = bindVariable(args[j++]);
1966 1381           argvec[i++] = (GEN)ep1;
1967 1381 50         if (EpVALENCE(ep1) != EpVAR && *(s-1) == 'V')
    0          
1968 0           croak("Did not get a variable");
1969 1381           saw_V++;
1970             #else
1971             if (*s != '=')
1972             warn("Unexpected: `V' not followed by `='"); /* appears in fordiv() etc. */
1973             if (saw_V >= MaxPariVar)
1974             croak("Too many loop variables in a signature (max=%d)", MaxPariVar);
1975             loopvars[saw_V++] = args[j++]; /* XXXX Ignore this variable (should be compiled into the closure!!!) ??? */
1976             #endif
1977 1381           break;
1978             case 'S': /* symbol */
1979             #if PARI_VERSION_EXP < 2004002
1980 0           ep1 = bindVariable(args[j++]);
1981 0           argvec[i++] = (GEN)ep1;
1982             #else
1983             croak("Variable type `S' unsupported after 2.4.2");
1984             #endif
1985 0           break;
1986             case '&': /* *GEN */
1987 2           gen_OUT[*OUT_cnt] = sv2pari(args[j]);
1988 2           argvec[i++] = (GEN)(gen_OUT + *OUT_cnt);
1989 2           sv_OUT[(*OUT_cnt)++] = args[j++];
1990 2           break;
1991             case 'E': /* Input position - subroutine */
1992             case 'I': /* Input position - subroutine, ignore value */
1993 1381 50         if (!args[j])
1994 0           croak("panic: no arg when AssignPariExpr()");
1995 1381 50         if (saw_V > 1) {
1996 0 0         if (saw_V > 2)
1997 0           croak("More than 2 running variables per PARI entry point not supported");
1998 0 0         AssignPariExpr2R(expr,args[j], 'I'==s[-1], LoopVar(0), LoopVar(1));
    0          
    0          
1999 1381 50         } else if (saw_V == 1) {
2000 1381 50         AssignPariExprR(expr,args[j], 'I'==s[-1], LoopVar(0));
    50          
    0          
2001             } else
2002 0           croak("Type E, I without a preceding variable");
2003 1381           argvec[i++] = (GEN) expr; /* XXXX Cast not needed after 2004002 */
2004 1381           j++;
2005 1381           break;
2006              
2007             case 's': /* expanded string; empty arg yields "" */
2008 0 0         if (*s == '*') {
2009 0           int ii = 0;
2010 0           GEN out = cgetg(items-j+1, t_VEC);
2011              
2012 0           s++;
2013 0           argvec[i++] = out;
2014 0 0         while (j < items)
2015 0           out[1 + ii++] = (long)sv2pariStr(args[j++]);
2016 0           goto args_done;
2017             }
2018             case 'r': /* raw */
2019 0 0         argvec[i++] = (GEN) SvPV(args[j],na);
2020 0           j++;
2021 0           break;
2022              
2023             case 'p': /* precision */
2024 1474           argvec[i++] = (GEN) prec_words;
2025 1474           break;
2026              
2027             #if PARI_VERSION_EXP >= 2008000
2028             case 'b': /* bitprecision */
2029             warn("===Passing precision=%ld; precreal=%ld", (long)prec_bits, (long)precreal);
2030             argvec[i++] = (GEN)precreal; /* prec_bits; */
2031             break;
2032             #endif
2033              
2034             case '=':
2035             case ',':
2036 1467           break;
2037              
2038             case 'D': /* Has a default value */
2039 2022           pre = s;
2040 2022 100         if (j >= items || !SvOK(args[j]))
    100          
    50          
    50          
2041             {
2042 513 100         if (j < items)
2043 20           j++;
2044              
2045 513 100         if ( *s == 'G' || *s == '&'
    100          
2046 156 50         || *s == 'r' || *s == 's'
    50          
2047 156 50         || *s == 'E' || *s == 'I' || *s == 'V') {
    50          
    50          
2048 357           argvec[i++]=DFT_GEN; s++;
2049 357           break;
2050             }
2051 156 100         if (*s == 'n') {
2052 14           argvec[i++]=DFT_VAR; s++;
2053 14           break;
2054             }
2055 142 50         if (*s == 'P') {
2056 0           argvec[i++] = (GEN) precdl; s++;
2057 0           break;
2058             }
2059 287 50         while (*s && *s++ != ',');
    100          
2060 142 50         if (!*s)
2061 0 0         if (!s[0] && s[-1] != ',')
    0          
2062 0           goto unrecognized_syntax;
2063 142           switch (*s) {
2064             case 'r': case 's':
2065 0 0         if (pre[0] == '\"' && pre[1] == '\"'
    0          
2066 0 0         && s - pre == 3) {
2067 0           argvec[i++] = (GEN) "";
2068 0           break;
2069             }
2070 0           goto unknown;
2071             case 'M': /* long or a mneumonic string
2072             (string not supported) */
2073 2           saw_M = 1;
2074             /* Fall through */
2075             case 'L': /* long */
2076 142           argvec[i++] = (GEN) MYatol(pre);
2077 142           break;
2078             case 'G':
2079 0 0         if ((*pre == '1' || *pre == '0') && pre[1]==',') {
    0          
    0          
2080 0           argvec[i++] = (*pre == '1'
2081 0 0         ? gen_1 : gen_0);
2082 0           break;
2083             }
2084             default:
2085             unknown:
2086 0           croak("Cannot process default argument %.*s of type %.1s for prototype '%s'",
2087 0           (int)(s - pre - 1), pre, s, s0);
2088             }
2089 142           s++; /* Skip ',' */
2090             }
2091             else
2092 1509 100         if (*s == 'G' || *s == '&' || *s == 'n'
    100          
    100          
2093 86 50         || *s == 'P' || *s == 'r' || *s == 's'
    50          
    50          
2094 86 50         || *s == 'E' || *s == 'I' || *s == 'V')
    50          
    50          
2095             break;
2096 316 50         while (*s && *s++ != ',');
    100          
2097 228 100         if (!s[0] && s[-1] != ',') {
    50          
2098             unrecognized_syntax:
2099 0           croak("Unexpected syntax of default argument '%s' in prototype '%s'",
2100             pre - 1, s0);
2101             }
2102 228           break;
2103              
2104             #if PARI_VERSION_EXP < 2004002
2105             case 'P': /* series precision */
2106 2           argvec[i++] = (GEN) precdl;
2107 2           break;
2108             #endif
2109              
2110             case 'f': /* Fake *long argument */
2111 0           argvec[i++] = (GEN) &fake;
2112 0           break;
2113              
2114             case 'x': /* Foreign function */
2115 0           croak("Calling Perl via PARI with an unknown interface: avoiding loop");
2116             break;
2117              
2118             case 'l': /* Return long */
2119 32           *rettype = RETTYPE_LONG; break;
2120              
2121             case 'i': /* Return int */
2122 4           *rettype = RETTYPE_INT; break;
2123              
2124             case 'v': /* Return void */
2125 16           *rettype = RETTYPE_VOID; break;
2126              
2127             case '\n': /* Mneumonic starts */
2128 4 50         if (saw_M) {
2129 4           s = ""; /* Finish processing */
2130 4           break;
2131             }
2132             /* FALL THROUGH */
2133             default:
2134 0           croak("Unsupported code '%.1s' in signature '%s' of a PARI function `%s'", s-1, s0, ep->name);
2135             }
2136 12443 50         if (j > items)
2137 0           croak("Too few args %d for PARI function `%s'", items, ep->name);
2138             }
2139 1946 50         if (j < items)
2140 0           croak("%d unused args for PARI function %s of signature `%s' (with %d args)", items - j, ep->name, ep->code, j);
2141             args_done: {
2142             #if PURIFY
2143             for ( ; i
2144             #endif
2145             }
2146 1946           }
2147              
2148             static void
2149 2           fill_outvect(SV **sv_OUT, GEN *gen_OUT, long c, pari_sp oldavma)
2150             {
2151 4 100         while (c-- > 0)
2152 2           resetSVpari(sv_OUT[c], gen_OUT[c], oldavma);
2153 2           }
2154              
2155             #define _to_int(in,dummy1,dummy2) to_int(in)
2156              
2157             static GEN
2158 1           to_int(GEN in)
2159             {
2160 1           long sign = gcmp(in,gen_0);
2161              
2162 1 50         if (!sign)
2163 0           return gen_0;
2164 1           switch (typ(in)) {
2165             case t_INT:
2166             #if PARI_VERSION_EXP < 2002008
2167             case t_SMALL:
2168             #endif
2169 0           return in;
2170             case t_INTMOD:
2171 0           return lift0(in, -1); /* -1: not as polmod */
2172             default:
2173 1           return gtrunc(in);
2174             }
2175             }
2176              
2177             typedef int (*FUNC_PTR)();
2178             typedef void (*TSET_FP)(char *s);
2179              
2180             #ifdef NO_HIGHLEVEL_PARI
2181             # define NO_GRAPHICS_PARI
2182             # define have_highlevel() 0
2183             #else
2184             # define have_highlevel() 1
2185             #endif
2186              
2187             #ifdef NO_GNUPLOT_PARI
2188             # define have_graphics() -1
2189             # define set_gnuterm(a,b,c) croak("This build of Math::Pari has no Gnuplot plotting support")
2190             # define int_set_term_ftable(a) croak("This build of Math::Pari has no Gnuplot plotting support")
2191             #else
2192             # ifdef NO_GRAPHICS_PARI
2193             # define have_graphics() 0
2194             # define set_gnuterm(a,b,c) croak("This build of Math::Pari has no plotting support")
2195             # define int_set_term_ftable(a) croak("This build of Math::Pari has no plotting support")
2196             # else
2197             # define have_graphics() 1
2198             # if PARI_VERSION_EXP < 2000013
2199             # define set_gnuterm(a,b,c) \
2200             set_term_funcp((FUNC_PTR)(a),(struct termentry *)(b))
2201             # else /* !( PARI_VERSION_EXP < 2000013 ) */
2202             # define set_gnuterm(a,b,c) \
2203             set_term_funcp3((FUNC_PTR)(INT2PTR(void*, a)), INT2PTR(struct termentry *, b), INT2PTR(TSET_FP,c))
2204             extern void set_term_funcp3(FUNC_PTR change_p, void *term_p, TSET_FP tchange);
2205              
2206             # endif /* PARI_VERSION_EXP < 2000013 */
2207              
2208             # define int_set_term_ftable(a) (v_set_term_ftable(INT2PTR(void*,a)))
2209             # endif
2210             #endif
2211              
2212             extern void v_set_term_ftable(void *a);
2213              
2214             /* Cast off `const' */
2215             #define s_type_name(x) (char *)type_name(typ(x));
2216              
2217             static int reset_on_reload = 0;
2218              
2219             int
2220 0           s_reset_on_reload(int newvalue)
2221             {
2222 0           int old = reset_on_reload;
2223 0 0         if (newvalue >= 0)
2224 0           reset_on_reload = newvalue;
2225 0           return old;
2226             }
2227              
2228             static int
2229 10893           isPariFunction(entree *ep)
2230             {
2231             #if PARI_VERSION_EXP < 2004000
2232 10893           return EpVALENCE(ep) < EpUSER;
2233             /* && ep>=fonctions && ep < fonctions+NUMFUNC) */
2234             #else /* !( PARI_VERSION_EXP < 2004000) */
2235             return (EpVALENCE(ep) == 0 || (EpVALENCE(ep) != EpNEW && typ((GEN)(ep->value))==t_CLOSURE)); /* == EpVAR */
2236             #endif /* !( PARI_VERSION_EXP < 2004000) */
2237             }
2238              
2239             #if 1
2240             # define checkPariFunction(arg)
2241             #else
2242             void
2243             checkPariFunction(const char *name)
2244             {
2245             long hash;
2246             entree *ep = is_entry_intern(name, functions_hash, &hash);
2247             warn( "Ep for `%s': VALENCE=%#04x, EpVAR=%d, EpINSTALL=%d, name=<%s>, code=<%s>, isFunction=%d", name, (ep ? (int)EpVALENCE(ep) : 0xDEAD),
2248             (int)EpVAR, (int)EpINSTALL, (ep ? ep->name : ""),
2249             ((ep && ep->code) ? ep->code : ""), (ep && isPariFunction(ep)));
2250             }
2251             #endif
2252              
2253             #if PARI_VERSION_EXP < 2008000 /* Need to recheck with each new major release??? See src/desc/gen_proto, src/test/32/help */
2254             # define TAG_community 12 /* "The PARI community" */
2255             #else /* !(PARI_VERSION_EXP < 2008000) */
2256             # if PARI_VERSION_EXP < 2010000
2257             # define TAG_community 15 /* "The PARI community" */
2258             # else /* !(PARI_VERSION_EXP < 2010000) */
2259             # if PARI_VERSION_EXP < 2014000
2260             # define TAG_community 17 /* "The PARI community" */
2261             # else /* !(PARI_VERSION_EXP < 2012000) */
2262             # define TAG_community TAG_community_unknown___needs_to_be_checked_for_every_new_version__see__GPbuilddir_src_test_32_help
2263             # endif /* !(PARI_VERSION_EXP < 2012000) */
2264             # endif /* !(PARI_VERSION_EXP < 2010000) */
2265             #endif /* !(PARI_VERSION_EXP < 2008000) */
2266              
2267             # define INTERNAL_TAG_start (TAG_community+1) /* symbolic_operators */
2268             # define INTERNAL_TAG_end (TAG_community+3) /* programming/internals (in between: member_functions) */
2269              
2270             int
2271 11060           _is_internal(int tag)
2272             { /* from gp_rl.c */
2273             #if PARI_VERSION_EXP < 2004000
2274 11060           return 0;
2275             #else /* !( PARI_VERSION_EXP < 2004000) */
2276             return tag >= INTERNAL_TAG_start && tag <= INTERNAL_TAG_end;
2277             #endif /* !( PARI_VERSION_EXP < 2004000) */
2278             }
2279              
2280             char *
2281 0           added_sections()
2282             {
2283             #if PARI_VERSION_EXP < 2013000
2284             /* Suggestion on format (part of 2.10.0), only use short names: "4: functions related to COMBINATORICS\n13: L-FUNCTIONS" */
2285 0           return "";
2286             #else /* !( PARI_VERSION_EXP < 2011000) */
2287             /* Check by entering "?" at gp prompt. Compare with the list in Pari.pm */
2288             croak("Do not know which \"sections\" (of list of functions) were added to PARI at v2.11.0");
2289             #endif /* !( PARI_VERSION_EXP < 2011000) */
2290             }
2291              
2292              
2293             #if PARI_VERSION_EXP >= 2006000 /* taken from 2.5.5 */
2294             static GEN
2295             gand(GEN x, GEN y) { return gequal0(x)? gen_0: (gequal0(y)? gen_0: gen_1); }
2296              
2297             static GEN
2298             gor(GEN x, GEN y) { return gequal0(x)? (gequal0(y)? gen_0: gen_1): gen_1; }
2299             #endif /* PARI_VERSION_EXP >= 2006000 */
2300              
2301              
2302             MODULE = Math::Pari PACKAGE = Math::Pari PREFIX = Arr_
2303              
2304             PROTOTYPES: ENABLE
2305              
2306             GEN
2307             Arr_FETCH(g,n)
2308             long oldavma=avma;
2309             GEN g
2310             I32 n
2311              
2312             void
2313             Arr_STORE(g,n,elt)
2314             long oldavma=avma;
2315             GEN g
2316             I32 n
2317             GEN elt
2318             CLEANUP:
2319 4           avma=oldavma;
2320              
2321             I32
2322             Arr_FETCHSIZE(g)
2323             long oldavma=avma;
2324             GEN g
2325             CLEANUP:
2326 0           avma=oldavma;
2327              
2328             I32
2329             Arr_EXISTS(g,elt)
2330             long oldavma=avma;
2331             GEN g
2332             long elt
2333             CLEANUP:
2334 0           avma=oldavma;
2335              
2336             MODULE = Math::Pari PACKAGE = Math::Pari
2337              
2338             PROTOTYPES: ENABLE
2339              
2340             int
2341             is_gnil(in)
2342             GEN in
2343              
2344             GEN
2345             sv2pari(sv)
2346             long oldavma=avma;
2347             SV * sv
2348              
2349             GEN
2350             sv2parimat(sv)
2351             long oldavma=avma;
2352             SV * sv
2353              
2354             SV *
2355             pari2iv(in)
2356             long oldavma=avma;
2357             GEN in
2358             CLEANUP:
2359 7           avma=oldavma;
2360              
2361             SV *
2362             pari2nv(in)
2363             long oldavma=avma;
2364             GEN in
2365             CLEANUP:
2366 1           avma=oldavma;
2367              
2368             SV *
2369             pari2num_(in,...)
2370             long oldavma=avma;
2371             GEN in
2372             CODE:
2373 1482 50         if (typ(in) == t_INT) {
2374 1482           RETVAL=pari2iv(in);
2375             } else {
2376 0           RETVAL=pari2nv(in);
2377             }
2378             OUTPUT:
2379             RETVAL
2380             CLEANUP:
2381 1482           avma=oldavma;
2382              
2383             SV *
2384             pari2num(in)
2385             long oldavma=avma;
2386             GEN in
2387             CODE:
2388 0 0         if (typ(in) == t_INT) {
2389 0           RETVAL=pari2iv(in);
2390             } else {
2391 0           RETVAL=pari2nv(in);
2392             }
2393             OUTPUT:
2394             RETVAL
2395             CLEANUP:
2396 0           avma=oldavma;
2397              
2398             SV *
2399             pari2pv(in,...)
2400             long oldavma=avma;
2401             GEN in
2402             CODE:
2403 547           RETVAL=pari2pv(in);
2404             OUTPUT:
2405             RETVAL
2406             CLEANUP:
2407 547           avma=oldavma;
2408              
2409             GEN
2410             _to_int(in, dummy1, dummy2)
2411             long oldavma=avma;
2412             GEN in
2413             SV *dummy1 = NO_INIT
2414             SV *dummy2 = NO_INIT
2415             CODE:
2416             PERL_UNUSED_VAR(dummy1); /* -W */
2417             PERL_UNUSED_VAR(dummy2); /* -W */
2418 1           RETVAL = _to_int(in, dummy1, dummy2);
2419             OUTPUT:
2420             RETVAL
2421              
2422             GEN
2423             PARI(...)
2424             long oldavma=avma;
2425             CODE:
2426 10491 50         if (items==1) {
2427 10491           RETVAL=sv2pari(ST(0));
2428             } else {
2429             int i;
2430              
2431 0           RETVAL=cgetg(items+1, t_VEC);
2432 0 0         for (i=0;i
2433 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2434             }
2435             }
2436             OUTPUT:
2437             RETVAL
2438              
2439             GEN
2440             PARIcol(...)
2441             long oldavma=avma;
2442             CODE:
2443 3 50         if (items==1) {
2444 3           RETVAL=sv2pari(ST(0));
2445 3 50         if (t_VEC == typ(RETVAL))
2446 3           settyp(RETVAL, t_COL);
2447             } else {
2448             int i;
2449              
2450 0           RETVAL=cgetg(items+1, t_VEC);
2451 0 0         for (i=0;i
2452 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2453             }
2454 0           settyp(RETVAL, t_COL);
2455             }
2456             OUTPUT:
2457             RETVAL
2458              
2459             GEN
2460             PARIvecL(...)
2461             long oldavma=avma;
2462             CODE:
2463             int i;
2464              
2465 0           RETVAL=cgetg(items+1, t_VEC);
2466 0 0         for (i=0;i
2467 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2468             }
2469             OUTPUT:
2470             RETVAL
2471              
2472             GEN
2473             PARIcolL(...)
2474             long oldavma=avma;
2475             CODE:
2476             int i;
2477              
2478 4           RETVAL=cgetg(items+1, t_VEC);
2479 21 100         for (i=0;i
2480 17           RETVAL[i+1]=(long)sv2pari(ST(i));
2481             }
2482 4           settyp(RETVAL, t_COL);
2483             OUTPUT:
2484             RETVAL
2485              
2486             GEN
2487             PARImat(...)
2488             long oldavma=avma;
2489             CODE:
2490 62 50         if (items==1) {
2491 62           RETVAL=sv2parimat(ST(0));
2492             } else {
2493             int i;
2494              
2495 0           RETVAL=cgetg(items+1, t_MAT);
2496 0 0         for (i=0;i
2497 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2498 0 0         if (t_VEC == typ((GEN)(RETVAL[i+1]))) {
2499 0           settyp(RETVAL[i+1], t_COL);
2500 0 0         } else if (t_COL != typ((GEN)(RETVAL[i+1]))) {
2501 0           croak("%ld'th argument (of %ld) to PARImat() is not a vector", (long)i, (long)items);
2502             }
2503             }
2504             }
2505             OUTPUT:
2506             RETVAL
2507              
2508             GEN
2509             PARImatL(...)
2510             long oldavma=avma;
2511             CODE:
2512             int i;
2513              
2514 0           RETVAL=cgetg(items+1, t_MAT);
2515 0 0         for (i=0;i
2516 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2517 0 0         if (t_VEC == typ((GEN)(RETVAL[i+1]))) {
2518 0           settyp(RETVAL[i+1], t_COL);
2519 0 0         } else if (t_COL != typ((GEN)(RETVAL[i+1]))) {
2520 0           croak("%ld'th argument (of %ld) to PARImatL() is not a vector", (long)i, (long)items);
2521             }
2522             }
2523             OUTPUT:
2524             RETVAL
2525              
2526             void
2527             installPerlFunctionCV(cv, name, numargs = 1, help = NULL)
2528             SV* cv
2529             char *name
2530             I32 numargs
2531             char *help
2532             PROTOTYPE: DISABLE
2533              
2534             # In what follows if a function returns long, we do not need anything
2535             # on the stack, thus we add a cleanup section.
2536              
2537             void
2538             interface_flexible_void(...)
2539             long oldavma=avma;
2540             CODE:
2541             {
2542 16           entree *ep = (entree *) XSANY.any_dptr;
2543 16           void (*FUNCTION_real)(VARARG)
2544 16           = (void (*)(VARARG))ep->value;
2545             GEN argvec[ARGS_SUPPORTED];
2546 16           long rettype = RETTYPE_GEN;
2547 16           long has_pointer = 0; /* XXXX ?? */
2548             long OUT_cnt;
2549             SV *sv_OUT[ARGS_SUPPORTED];
2550             GEN gen_OUT[ARGS_SUPPORTED];
2551              
2552 16           fill_argvect(ep, ep->code, &has_pointer, argvec, &rettype, &ST(0), items,
2553             sv_OUT, gen_OUT, &OUT_cnt);
2554              
2555 16 50         if (rettype != RETTYPE_VOID)
2556 0           croak("Expected VOID return type, got code '%s'", ep->code);
2557            
2558 16           (FUNCTION_real)(THE_ARGS_SUPPORTED);
2559 14 50         if (has_pointer)
2560 0           check_pointer(has_pointer,argvec);
2561 14 50         if (OUT_cnt)
2562 0           fill_outvect(sv_OUT, gen_OUT, OUT_cnt, oldavma);
2563             }
2564              
2565             GEN
2566             interface_flexible_gen(...)
2567             long oldavma=avma;
2568             CODE:
2569             {
2570 1894           entree *ep = (entree *) XSANY.any_dptr;
2571 1894           GEN (*FUNCTION_real)(VARARG)
2572 1894           = (GEN (*)(VARARG))ep->value;
2573             GEN argvec[9];
2574 1894           long rettype = RETTYPE_GEN;
2575 1894           long has_pointer = 0; /* XXXX ?? */
2576             long OUT_cnt;
2577             SV *sv_OUT[ARGS_SUPPORTED];
2578             GEN gen_OUT[ARGS_SUPPORTED];
2579              
2580 1894           fill_argvect(ep, ep->code, &has_pointer, argvec, &rettype, &ST(0), items,
2581             sv_OUT, gen_OUT, &OUT_cnt);
2582              
2583 1894 50         if (rettype != RETTYPE_GEN)
2584 0           croak("Expected GEN return type, got code '%s'", ep->code);
2585            
2586 1894           RETVAL = (FUNCTION_real)(THE_ARGS_SUPPORTED);
2587 1889 50         if (has_pointer)
2588 0           check_pointer(has_pointer,argvec);
2589 1889 100         if (OUT_cnt)
2590 2           fill_outvect(sv_OUT, gen_OUT, OUT_cnt, oldavma);
2591             }
2592             OUTPUT:
2593             RETVAL
2594              
2595             long
2596             interface_flexible_long(...)
2597             long oldavma=avma;
2598             CODE:
2599             {
2600 32           entree *ep = (entree *) XSANY.any_dptr;
2601 32           long (*FUNCTION_real)(VARARG)
2602 32           = (long (*)(VARARG))ep->value;
2603             GEN argvec[9];
2604 32           long rettype = RETTYPE_GEN;
2605 32           long has_pointer = 0; /* XXXX ?? */
2606             long OUT_cnt;
2607             SV *sv_OUT[ARGS_SUPPORTED];
2608             GEN gen_OUT[ARGS_SUPPORTED];
2609              
2610 32           fill_argvect(ep, ep->code, &has_pointer, argvec, &rettype, &ST(0), items,
2611             sv_OUT, gen_OUT, &OUT_cnt);
2612              
2613 32 50         if (rettype != RETTYPE_LONG)
2614 0           croak("Expected long return type, got code '%s'", ep->code);
2615            
2616 32           RETVAL = FUNCTION_real(THE_ARGS_SUPPORTED);
2617 32 50         if (has_pointer)
2618 0           check_pointer(has_pointer,argvec);
2619 32 50         if (OUT_cnt)
2620 0           fill_outvect(sv_OUT, gen_OUT, OUT_cnt, oldavma);
2621             }
2622             OUTPUT:
2623             RETVAL
2624              
2625             int
2626             interface_flexible_int(...)
2627             long oldavma=avma;
2628             CODE:
2629             {
2630 4           entree *ep = (entree *) XSANY.any_dptr;
2631 4           int (*FUNCTION_real)(VARARG)
2632 4           = (int (*)(VARARG))ep->value;
2633             GEN argvec[9];
2634 4           long rettype = RETTYPE_GEN;
2635 4           long has_pointer = 0; /* XXXX ?? */
2636             long OUT_cnt;
2637             SV *sv_OUT[ARGS_SUPPORTED];
2638             GEN gen_OUT[ARGS_SUPPORTED];
2639              
2640 4           fill_argvect(ep, ep->code, &has_pointer, argvec, &rettype, &ST(0), items,
2641             sv_OUT, gen_OUT, &OUT_cnt);
2642              
2643 4 50         if (rettype != RETTYPE_INT)
2644 0           croak("Expected int return type, got code '%s'", ep->code);
2645            
2646 4           RETVAL=FUNCTION_real(argvec[0], argvec[1], argvec[2], argvec[3],
2647             argvec[4], argvec[5], argvec[6], argvec[7], argvec[8]);
2648 4 50         if (has_pointer)
2649 0           check_pointer(has_pointer,argvec);
2650 4 50         if (OUT_cnt)
2651 0           fill_outvect(sv_OUT, gen_OUT, OUT_cnt, oldavma);
2652             }
2653             OUTPUT:
2654             RETVAL
2655              
2656             GEN
2657             interface0()
2658             long oldavma=avma;
2659             CODE:
2660             {
2661 56           dFUNCTION(GEN);
2662              
2663 56 50         if (!FUNCTION) {
2664 0           croak("XSUB call through interface did not provide *function");
2665             }
2666              
2667 56           RETVAL=FUNCTION(prec_words);
2668             }
2669             OUTPUT:
2670             RETVAL
2671              
2672             GEN
2673             interface9900()
2674             long oldavma=avma;
2675             CODE:
2676             { /* Code="" */
2677 764           dFUNCTION(GEN);
2678              
2679 764 50         if (!FUNCTION) {
2680 0           croak("XSUB call through interface did not provide *function");
2681             }
2682              
2683 764           RETVAL=FUNCTION();
2684             }
2685             OUTPUT:
2686             RETVAL
2687              
2688             GEN
2689             interface1(arg1)
2690             long oldavma=avma;
2691             GEN arg1
2692             CODE:
2693             { /* Code="Gp" */
2694 45787           dFUNCTION(GEN);
2695              
2696 45787 50         if (!FUNCTION) {
2697 0           croak("XSUB call through interface did not provide *function");
2698             }
2699              
2700 45787           RETVAL=FUNCTION(arg1,prec_words);
2701             }
2702             OUTPUT:
2703             RETVAL
2704              
2705             # with fake arguments for overloading
2706              
2707             GEN
2708             interface199(arg1,arg2,inv)
2709             long oldavma=avma;
2710             GEN arg1
2711             GEN arg2 = NO_INIT
2712             long inv = NO_INIT
2713             CODE:
2714             {
2715 30006           dFUNCTION(GEN);
2716              
2717 30006 50         if (!FUNCTION) {
2718 0           croak("XSUB call through interface did not provide *function");
2719             }
2720              
2721             PERL_UNUSED_VAR(arg2); /* -W */
2722             PERL_UNUSED_VAR(inv); /* -W */
2723 30006           RETVAL=FUNCTION(arg1,prec_words);
2724             }
2725             OUTPUT:
2726             RETVAL
2727              
2728             long
2729             interface10(arg1)
2730             long oldavma=avma;
2731             GEN arg1
2732             CODE:
2733             { /* Code="lG" */
2734 7           dFUNCTION(long);
2735              
2736 7 50         if (!FUNCTION) {
2737 0           croak("XSUB call through interface did not provide *function");
2738             }
2739              
2740 7           RETVAL=FUNCTION(arg1);
2741             }
2742             OUTPUT:
2743             RETVAL
2744             CLEANUP:
2745 7           avma=oldavma;
2746              
2747             # With fake arguments for overloading
2748              
2749             long
2750             interface109(arg1,arg2,inv)
2751             long oldavma=avma;
2752             GEN arg1
2753             GEN arg2 = NO_INIT
2754             long inv = NO_INIT
2755             CODE:
2756             {
2757 0           dFUNCTION(long);
2758              
2759 0 0         if (!FUNCTION) {
2760 0           croak("XSUB call through interface did not provide *function");
2761             }
2762              
2763             PERL_UNUSED_VAR(arg2); /* -W */
2764             PERL_UNUSED_VAR(inv); /* -W */
2765 0           RETVAL=FUNCTION(arg1);
2766             }
2767             OUTPUT:
2768             RETVAL
2769             CLEANUP:
2770 0           avma=oldavma;
2771              
2772             GEN
2773             interface11(arg1)
2774             long oldavma=avma;
2775             long arg1
2776             CODE:
2777             { /* Code="L" */
2778 32           dFUNCTION(GEN);
2779              
2780 32 50         if (!FUNCTION) {
2781 0           croak("XSUB call through interface did not provide *function");
2782             }
2783              
2784 32           RETVAL=FUNCTION(arg1);
2785             }
2786             OUTPUT:
2787             RETVAL
2788              
2789             long
2790             interface15(arg1)
2791             long oldavma=avma;
2792             long arg1
2793             CODE:
2794             {
2795 0           dFUNCTION(long);
2796              
2797 0 0         if (!FUNCTION) {
2798 0           croak("XSUB call through interface did not provide *function");
2799             }
2800              
2801 0           RETVAL=FUNCTION(arg1);
2802             }
2803             OUTPUT:
2804             RETVAL
2805             CLEANUP:
2806 0           avma=oldavma;
2807              
2808             GEN
2809             interface18(arg1)
2810             long oldavma=avma;
2811             GEN arg1
2812             CODE:
2813             { /* Code="G" */
2814 173           dFUNCTION(GEN);
2815              
2816 173 50         if (!FUNCTION) {
2817 0           croak("XSUB call through interface did not provide *function");
2818             }
2819              
2820 173           RETVAL=FUNCTION(arg1);
2821             }
2822             OUTPUT:
2823             RETVAL
2824              
2825             GEN
2826             interface2(arg1,arg2)
2827             long oldavma=avma;
2828             GEN arg1
2829             GEN arg2
2830             CODE:
2831             { /* Code="GG" */
2832 320           dFUNCTION(GEN);
2833              
2834 320 50         if (!FUNCTION) {
2835 0           croak("XSUB call through interface did not provide *function");
2836             }
2837              
2838 320           RETVAL=FUNCTION(arg1,arg2);
2839             }
2840             OUTPUT:
2841             RETVAL
2842              
2843             # With fake arguments for overloading
2844              
2845             GEN
2846             interface299(arg1,arg2,inv)
2847             long oldavma=avma;
2848             GEN arg1
2849             GEN arg2
2850             bool inv
2851             CODE:
2852             {
2853 8934970           dFUNCTION(GEN);
2854              
2855 8934970 50         if (!FUNCTION) {
2856 0           croak("XSUB call through interface did not provide *function");
2857             }
2858              
2859 8934970 100         RETVAL = inv? FUNCTION(arg2,arg1): FUNCTION(arg1,arg2);
2860             }
2861             OUTPUT:
2862             RETVAL
2863              
2864             long
2865             interface20(arg1,arg2)
2866             long oldavma=avma;
2867             GEN arg1
2868             GEN arg2
2869             CODE:
2870             { /* Code="lGG" */
2871 4           dFUNCTION(long);
2872              
2873 4 50         if (!FUNCTION) {
2874 0           croak("XSUB call through interface did not provide *function");
2875             }
2876              
2877 4           RETVAL=FUNCTION(arg1,arg2);
2878             }
2879             OUTPUT:
2880             RETVAL
2881             CLEANUP:
2882 4           avma=oldavma;
2883              
2884             # With fake arguments for overloading and comparison to gen_1 for speed
2885              
2886             long
2887             interface2099(arg1,arg2,inv)
2888             long oldavma=avma;
2889             GEN arg1
2890             GEN arg2
2891             bool inv
2892             CODE:
2893             {
2894 102           dFUNCTION(GEN);
2895              
2896 102 50         if (!FUNCTION) {
2897 0           croak("XSUB call through interface did not provide *function");
2898             }
2899              
2900 102 100         RETVAL = (inv? FUNCTION(arg2,arg1): FUNCTION(arg1,arg2)) == gen_1;
2901             }
2902             OUTPUT:
2903             RETVAL
2904             CLEANUP:
2905 102           avma=oldavma;
2906              
2907             # With fake arguments for overloading
2908              
2909             long
2910             interface209(arg1,arg2,inv)
2911             long oldavma=avma;
2912             GEN arg1
2913             GEN arg2
2914             bool inv
2915             CODE:
2916             {
2917 0           dFUNCTION(long);
2918              
2919 0 0         if (!FUNCTION) {
2920 0           croak("XSUB call through interface did not provide *function");
2921             }
2922              
2923 0 0         RETVAL = inv? FUNCTION(arg2,arg1): FUNCTION(arg1,arg2);
2924             }
2925             OUTPUT:
2926             RETVAL
2927             CLEANUP:
2928 0           avma=oldavma;
2929              
2930             # With fake arguments for overloading, int return
2931              
2932             int
2933             interface2091(arg1,arg2,inv)
2934             long oldavma=avma;
2935             GEN arg1
2936             GEN arg2
2937             bool inv
2938             CODE:
2939             {
2940 20           dFUNCTION(int);
2941              
2942 20 50         if (!FUNCTION) {
2943 0           croak("XSUB call through interface did not provide *function");
2944             }
2945              
2946 20 100         RETVAL = inv? FUNCTION(arg2,arg1): FUNCTION(arg1,arg2);
2947             }
2948             OUTPUT:
2949             RETVAL
2950             CLEANUP:
2951 20           avma=oldavma;
2952              
2953             GEN
2954             interface29(arg1,arg2)
2955             long oldavma=avma;
2956             GEN arg1
2957             GEN arg2
2958             CODE:
2959             { /* Code="GGp" */
2960 13           dFUNCTION(GEN);
2961              
2962 13 50         if (!FUNCTION) {
2963 0           croak("XSUB call through interface did not provide *function");
2964             }
2965              
2966 13           RETVAL=FUNCTION(arg1,arg2,prec_words);
2967             }
2968             OUTPUT:
2969             RETVAL
2970              
2971             GEN
2972             interface3(arg1,arg2,arg3)
2973             long oldavma=avma;
2974             GEN arg1
2975             GEN arg2
2976             GEN arg3
2977             CODE:
2978             { /* Code="GGG" */
2979 20           dFUNCTION(GEN);
2980              
2981 20 50         if (!FUNCTION) {
2982 0           croak("XSUB call through interface did not provide *function");
2983             }
2984              
2985 20           RETVAL=FUNCTION(arg1,arg2,arg3);
2986             }
2987             OUTPUT:
2988             RETVAL
2989              
2990             long
2991             interface30(arg1,arg2,arg3)
2992             long oldavma=avma;
2993             GEN arg1
2994             GEN arg2
2995             GEN arg3
2996             CODE:
2997             { /* Code="lGGG" */
2998 2           dFUNCTION(long);
2999              
3000 2 50         if (!FUNCTION) {
3001 0           croak("XSUB call through interface did not provide *function");
3002             }
3003              
3004 2           RETVAL=FUNCTION(arg1,arg2,arg3);
3005             }
3006             OUTPUT:
3007             RETVAL
3008             CLEANUP:
3009 2           avma=oldavma;
3010              
3011             GEN
3012             interface4(arg1,arg2,arg3,arg4)
3013             long oldavma=avma;
3014             GEN arg1
3015             GEN arg2
3016             GEN arg3
3017             GEN arg4
3018             CODE:
3019             { /* Code="GGGG" */
3020 0           dFUNCTION(GEN);
3021              
3022 0 0         if (!FUNCTION) {
3023 0           croak("XSUB call through interface did not provide *function");
3024             }
3025              
3026 0           RETVAL=FUNCTION(arg1,arg2,arg3,arg4);
3027             }
3028             OUTPUT:
3029             RETVAL
3030              
3031             GEN
3032             interface5(arg1,arg2,arg3,arg4)
3033             long oldavma=avma;
3034             GEN arg1
3035             GEN arg2
3036             GEN arg3
3037             GEN arg4
3038             CODE:
3039             {
3040 0           dFUNCTION(GEN);
3041              
3042 0 0         if (!FUNCTION) {
3043 0           croak("XSUB call through interface did not provide *function");
3044             }
3045              
3046 0           RETVAL=FUNCTION(arg1,arg2,arg3,arg4,prec_words);
3047             }
3048             OUTPUT:
3049             RETVAL
3050              
3051             GEN
3052             interface12(arg1,arg2)
3053             long oldavma=avma;
3054             GEN arg1
3055             GEN arg2
3056             CODE:
3057             { /* Code="GnP" */
3058 1           dFUNCTION(GEN);
3059              
3060 1 50         if (!FUNCTION) {
3061 0           croak("XSUB call through interface did not provide *function");
3062             }
3063              
3064 1           RETVAL=FUNCTION(arg1,numvar(arg2), precdl);
3065             }
3066             OUTPUT:
3067             RETVAL
3068              
3069             GEN
3070             interface13(arg1, arg2=0, arg3=gen_0)
3071             long oldavma=avma;
3072             GEN arg1
3073             long arg2
3074             GEN arg3
3075             CODE:
3076             { /* Code="GD0,L,D0,G," */
3077 13           dFUNCTION(GEN);
3078              
3079 13 50         if (!FUNCTION) {
3080 0           croak("XSUB call through interface did not provide *function");
3081             }
3082              
3083 13           RETVAL=FUNCTION(arg1, arg2, arg3);
3084             }
3085             OUTPUT:
3086             RETVAL
3087              
3088             GEN
3089             interface14(arg1,arg2=0)
3090             long oldavma=avma;
3091             GEN arg1
3092             GEN arg2
3093             CODE:
3094             { /* Code="GDn" */
3095 41           dFUNCTION(GEN);
3096              
3097 41 50         if (!FUNCTION) {
3098 0           croak("XSUB call through interface did not provide *function");
3099             }
3100              
3101 41 100         RETVAL=FUNCTION(arg1,arg2 ? numvar(arg2) : -1);
3102             }
3103             OUTPUT:
3104             RETVAL
3105              
3106             GEN
3107             interface21(arg1,arg2)
3108             long oldavma=avma;
3109             GEN arg1
3110             long arg2
3111             CODE:
3112             { /* Code="GL" */
3113 0           dFUNCTION(GEN);
3114              
3115 0 0         if (!FUNCTION) {
3116 0           croak("XSUB call through interface did not provide *function");
3117             }
3118              
3119 0           RETVAL=FUNCTION(arg1,arg2);
3120             }
3121             OUTPUT:
3122             RETVAL
3123              
3124             # With fake arguments for overloading
3125             # This is very hairy: we need to chose the translation of arguments
3126             # depending on the value of inv
3127              
3128             GEN
3129             interface2199(arg1,arg2,inv)
3130             long oldavma=avma;
3131             GEN arg1 = NO_INIT
3132             long arg2 = NO_INIT
3133             bool inv
3134             CODE:
3135             {
3136 2           dFUNCTION(GEN);
3137              
3138 2 50         if (!FUNCTION) {
3139 0           croak("XSUB call through interface did not provide *function");
3140             }
3141 2 100         if (inv) {
3142 1           arg1 = sv2pari(ST(1));
3143 1 50         arg2 = (long)SvIV(ST(0));
3144             } else {
3145 1           arg1 = sv2pari(ST(0));
3146 1 50         arg2 = (long)SvIV(ST(1));
3147             }
3148              
3149 2           RETVAL = FUNCTION(arg1,arg2);
3150             }
3151             OUTPUT:
3152             RETVAL
3153              
3154             GEN
3155             interface22(arg1,arg2,arg3)
3156             long oldavma=avma;
3157             GEN arg1
3158             PariVar arg2
3159             PariExpr arg3
3160             CODE:
3161             { /* Code="GVI" */
3162 1           dFUNCTION(GEN);
3163              
3164 1 50         if (!FUNCTION) {
3165 0           croak("XSUB call through interface did not provide *function");
3166             }
3167             #if PARI_VERSION_EXP >= 2004002
3168             RETVAL = FUNCTION(arg1, arg3); /* XXXX Omit `V' instead of merging it into I/E */
3169             #else
3170 1           RETVAL = FUNCTION(arg1, arg2, arg3);
3171             #endif
3172             }
3173             OUTPUT:
3174             RETVAL
3175              
3176             GEN
3177             interface23(arg1,arg2)
3178             long oldavma=avma;
3179             GEN arg1
3180             long arg2
3181             CODE:
3182             { /* Code="GL" */
3183 10           dFUNCTION(GEN);
3184              
3185 10 50         if (!FUNCTION) {
3186 0           croak("XSUB call through interface did not provide *function");
3187             }
3188              
3189 10           RETVAL=FUNCTION(arg1,arg2);
3190             }
3191             OUTPUT:
3192             RETVAL
3193              
3194             GEN
3195             interface24(arg1,arg2)
3196             long oldavma=avma;
3197             long arg1
3198             GEN arg2
3199             CODE:
3200             { /* Code="LG" */
3201 1           dFUNCTION(GEN);
3202              
3203 1 50         if (!FUNCTION) {
3204 0           croak("XSUB call through interface did not provide *function");
3205             }
3206              
3207 1           RETVAL=FUNCTION(arg1,arg2);
3208             }
3209             OUTPUT:
3210             RETVAL
3211              
3212             GEN
3213             interface25(arg1,arg2,arg3=0)
3214             long oldavma=avma;
3215             GEN arg1
3216             GEN arg2
3217             long arg3
3218             CODE:
3219             { /* Code="GGD0,L," */
3220 75           dFUNCTION(GEN);
3221              
3222 75 50         if (!FUNCTION) {
3223 0           croak("XSUB call through interface did not provide *function");
3224             }
3225              
3226 75           RETVAL=FUNCTION(arg1,arg2,arg3);
3227             }
3228             OUTPUT:
3229             RETVAL
3230              
3231             GEN
3232             interface26(arg1,arg2,arg3)
3233             long oldavma=avma;
3234             GEN arg1
3235             GEN arg2
3236             GEN arg3
3237             CODE:
3238             { /* Code="GnG" */
3239 2           dFUNCTION(GEN);
3240              
3241 2 50         if (!FUNCTION) {
3242 0           croak("XSUB call through interface did not provide *function");
3243             }
3244              
3245 2           RETVAL=FUNCTION(arg1, numvar(arg2), arg3);
3246             }
3247             OUTPUT:
3248             RETVAL
3249              
3250             GEN
3251             interface27(arg1,arg2,arg3)
3252             long oldavma=avma;
3253             PariVar arg1
3254             GEN arg2
3255             PariExpr arg3
3256             CODE:
3257             { /* Code="V=GIp" */
3258 2           dFUNCTION(GEN);
3259              
3260 2 50         if (!FUNCTION) {
3261 0           croak("XSUB call through interface did not provide *function");
3262             }
3263             #if PARI_VERSION_EXP >= 2004002
3264             RETVAL=FUNCTION(arg2, arg3, prec_words); /* XXXX Omit `V' instead of merging it into I/E */
3265             #else
3266 2           RETVAL=FUNCTION(arg1, arg2, arg3, prec_words);
3267             #endif
3268             }
3269             OUTPUT:
3270             RETVAL
3271              
3272             GEN
3273             interface28(arg1,arg2=0,arg3=0)
3274             long oldavma=avma;
3275             GEN arg1
3276             PariVar arg2
3277             PariExpr arg3
3278             CODE:
3279             { /* Code="GDVDI" */
3280 74           dFUNCTION(GEN);
3281              
3282 74 50         if (!FUNCTION) {
3283 0           croak("XSUB call through interface did not provide *function");
3284             }
3285             #if PARI_VERSION_EXP >= 2004002
3286             RETVAL = FUNCTION(arg1, arg3); /* XXXX Omit `V' instead of merging it into I/E */
3287             #else
3288 74           RETVAL = FUNCTION(arg1, arg2, arg3);
3289             #endif
3290             }
3291             OUTPUT:
3292             RETVAL
3293              
3294             GEN
3295             interface28_old(arg1,arg2)
3296             long oldavma=avma;
3297             GEN arg1
3298             GEN arg2
3299             CODE:
3300             {
3301             long junk;
3302 0           dFUNCTION(GEN);
3303              
3304 0 0         if (!FUNCTION) {
3305 0           croak("XSUB call through interface did not provide *function");
3306             }
3307              
3308 0           RETVAL=FUNCTION(arg1, arg2, &junk);
3309             }
3310             OUTPUT:
3311             RETVAL
3312              
3313             long
3314             interface29_old(arg1,arg2)
3315             long oldavma=avma;
3316             GEN arg1
3317             long arg2
3318             CODE:
3319             {
3320 0           dFUNCTION(long);
3321              
3322 0 0         if (!FUNCTION) {
3323 0           croak("XSUB call through interface did not provide *function");
3324             }
3325              
3326 0           RETVAL=FUNCTION(arg1,arg2);
3327             }
3328             OUTPUT:
3329             RETVAL
3330             CLEANUP:
3331 0           avma=oldavma;
3332              
3333             GEN
3334             interface31(arg1,arg2=0,arg3=0,arg4=0)
3335             long oldavma=avma;
3336             GEN arg1
3337             GEN arg2
3338             GEN arg3
3339             GEN arg4
3340             CODE:
3341             { /* Code="GDGDGD&" */
3342 1           dFUNCTION(GEN);
3343              
3344 1 50         if (!FUNCTION) {
3345 0           croak("XSUB call through interface did not provide *function");
3346             }
3347              
3348 1 50         RETVAL=FUNCTION(arg1, arg2, arg3, arg4 ? &arg4 : NULL);
3349             }
3350             OUTPUT:
3351             RETVAL
3352              
3353             GEN
3354             interface32(arg1,arg2,arg3)
3355             long oldavma=avma;
3356             GEN arg1
3357             GEN arg2
3358             long arg3
3359             CODE:
3360             { /* Code="GGL" */
3361 1           dFUNCTION(GEN);
3362              
3363 1 50         if (!FUNCTION) {
3364 0           croak("XSUB call through interface did not provide *function");
3365             }
3366              
3367 1           RETVAL=FUNCTION(arg1,arg2,arg3);
3368             }
3369             OUTPUT:
3370             RETVAL
3371              
3372             GEN
3373             interface33(arg1,arg2,arg3,arg4=0)
3374             long oldavma=avma;
3375             GEN arg1
3376             GEN arg2
3377             GEN arg3
3378             long arg4
3379             CODE:
3380             { /* Code="GGGD0,L,p" */
3381 5           dFUNCTION(GEN);
3382              
3383 5 50         if (!FUNCTION) {
3384 0           croak("XSUB call through interface did not provide *function");
3385             }
3386              
3387 5           RETVAL=FUNCTION(arg1,arg2,arg3,arg4,prec_words);
3388             }
3389             OUTPUT:
3390             RETVAL
3391              
3392             void
3393             interface34(arg1,arg2,arg3)
3394             long arg1
3395             long arg2
3396             long arg3
3397             CODE:
3398             { /* Code="vLLL" */
3399 0           dFUNCTION(GEN);
3400              
3401 0 0         if (!FUNCTION) {
3402 0           croak("XSUB call through interface did not provide *function");
3403             }
3404              
3405 0           FUNCTION(arg1, arg2, arg3);
3406             }
3407              
3408             void
3409             interface35(arg1,arg2,arg3)
3410             long oldavma=avma;
3411             long arg1
3412             GEN arg2
3413             GEN arg3
3414             CODE:
3415             { /* Code="vLGG" */
3416 26           dFUNCTION(GEN);
3417              
3418 26 50         if (!FUNCTION) {
3419 0           croak("XSUB call through interface did not provide *function");
3420             }
3421              
3422 26           FUNCTION(arg1,arg2,arg3);
3423             }
3424             CLEANUP:
3425 26           avma=oldavma;
3426              
3427             GEN
3428             interface37(arg1,arg2,arg3,arg4)
3429             long oldavma=avma;
3430             PariVar arg1
3431             GEN arg2
3432             GEN arg3
3433             PariExpr arg4
3434             CODE:
3435             { /* Code="V=GGIp" */
3436 2           dFUNCTION(GEN);
3437              
3438 2 50         if (!FUNCTION) {
3439 0           croak("XSUB call through interface did not provide *function");
3440             }
3441             #if PARI_VERSION_EXP >= 2004002
3442             RETVAL=FUNCTION(arg2, arg3, arg4, prec_words); /* XXXX Omit `V' instead of merging it into I/E */
3443             #else
3444 2           RETVAL=FUNCTION(arg1, arg2, arg3, arg4, prec_words);
3445             #endif
3446             }
3447             OUTPUT:
3448             RETVAL
3449              
3450             GEN
3451             interface47(arg1,arg2,arg3,arg4,arg0=0)
3452             long oldavma=avma;
3453             GEN arg0
3454             PariVar arg1
3455             GEN arg2
3456             GEN arg3
3457             PariExpr arg4
3458             CODE:
3459             { /* Code="V=GGIDG" */
3460 137           dFUNCTION(GEN);
3461              
3462 137 50         if (!FUNCTION) {
3463 0           croak("XSUB call through interface did not provide *function");
3464             }
3465             #if PARI_VERSION_EXP >= 2004002
3466             RETVAL=FUNCTION(arg2, arg3, arg4, arg0); /* XXXX Omit `V' instead of merging it into I/E */
3467             #else
3468 137           RETVAL=FUNCTION(arg1, arg2, arg3, arg4, arg0);
3469             #endif
3470             }
3471             OUTPUT:
3472             RETVAL
3473              
3474             GEN
3475             interface48(arg1,arg2,arg3,arg4,arg0=0)
3476             long oldavma=avma;
3477             GEN arg0
3478             PariVar arg1
3479             GEN arg2
3480             GEN arg3
3481             PariExpr arg4
3482             CODE:
3483             { /* Code="V=GGIDG" */
3484 0           dFUNCTION(GEN);
3485              
3486 0 0         if (!FUNCTION) {
3487 0           croak("XSUB call through interface did not provide *function");
3488             }
3489             #if PARI_VERSION_EXP >= 2004002
3490             RETVAL=FUNCTION(arg2, arg3, arg4, arg0); /* XXXX Omit `V' instead of merging it into I/E */
3491             #else
3492 0           RETVAL=FUNCTION(arg1, arg2, arg3, arg4, arg0);
3493             #endif
3494             }
3495             OUTPUT:
3496             RETVAL
3497              
3498             GEN
3499             interface49(arg0,arg00,arg1=0,arg2=0,arg3=0)
3500             long oldavma=avma;
3501             GEN arg0
3502             GEN arg00
3503             PariVar arg1
3504             PariVar arg2
3505             PariExpr2 arg3
3506             CODE:
3507             { /* Code="GGDVDVDI" */
3508 34           dFUNCTION(GEN);
3509 34 50         # arg1 and arg2 may finish to be the same entree*, like after $x=$y=PARIvar 'x'
    0          
3510 0 0         if (arg1 == arg2 && arg1) {
3511 0           if (ST(2) == ST(3))
3512             croak("Same iterator for a double loop");
3513             # ST(3) is localized now
3514             #if PARI_VERSION_EXP >= 2004000
3515 0           croak("Panic (unreachable (?) in a double loop construct)");
3516 0           #else
3517 0           sv_unref(ST(3));
3518             arg2 = findVariable(ST(3),1);
3519             sv_setref_pv(ST(3), "Math::Pari::Ep", (void*)arg2);
3520 34 50         #endif
3521 0           }
3522             if (!FUNCTION) {
3523             croak("XSUB call through interface did not provide *function");
3524             }
3525             #if PARI_VERSION_EXP >= 2004002
3526 34           RETVAL=FUNCTION(arg0, arg00, arg3); /* XXXX Omit two `V's instead of merging them into I/E */
3527             #else
3528             RETVAL=FUNCTION(arg0, arg00, arg1, arg2, arg3);
3529             #endif
3530             }
3531             OUTPUT:
3532             RETVAL
3533              
3534             void
3535             interface83(arg1,arg2,arg3,arg4)
3536             long oldavma=avma;
3537             PariVar arg1
3538             GEN arg2
3539             GEN arg3
3540             PariExprV arg4
3541             CODE:
3542             { /* Code="vV=GGI" */
3543 3           dFUNCTION(void);
3544              
3545 3 50         if (!FUNCTION) {
3546 0           croak("XSUB call through interface did not provide *function");
3547             }
3548             #if PARI_VERSION_EXP >= 2004002
3549             FUNCTION(arg2, arg3, arg4); /* XXXX Omit `V' instead of merging it into I/E */
3550             #else
3551 3           FUNCTION(arg1, arg2, arg3, arg4);
3552             #endif
3553             }
3554             CLEANUP:
3555 3           avma=oldavma;
3556              
3557             void
3558             interface84(arg1,arg2,arg3)
3559             long oldavma=avma;
3560             GEN arg1
3561             PariVar arg2
3562             PariExprV arg3
3563             CODE:
3564             { /* Code="vGVI" */
3565 11           dFUNCTION(void);
3566              
3567 11 50         if (!FUNCTION) {
3568 0           croak("XSUB call through interface did not provide *function");
3569             }
3570             #if PARI_VERSION_EXP >= 2004002
3571             FUNCTION(arg1, arg3); /* XXXX Omit `V' instead of merging it into I/E */
3572             #else
3573 11           FUNCTION(arg1, arg2, arg3);
3574             #endif
3575             }
3576             CLEANUP:
3577 11           avma=oldavma;
3578              
3579             # These interfaces were automatically generated:
3580              
3581             long
3582             interface16(arg1)
3583             long oldavma=avma;
3584             char * arg1
3585             CODE:
3586             { /* Code="ls" */
3587 0           dFUNCTION(long);
3588              
3589 0 0         if (!FUNCTION) {
3590 0           croak("XSUB call through interface did not provide *function");
3591             }
3592              
3593 0           RETVAL=FUNCTION(arg1);
3594             }
3595             OUTPUT:
3596             RETVAL
3597             CLEANUP:
3598 0           avma=oldavma;
3599              
3600             void
3601             interface19(arg1, arg2)
3602             long arg1
3603             long arg2
3604             CODE:
3605             { /* Code="vLL" */
3606 2           dFUNCTION(GEN);
3607              
3608 2 50         if (!FUNCTION) {
3609 0           croak("XSUB call through interface did not provide *function");
3610             }
3611              
3612 2           FUNCTION(arg1, arg2);
3613             }
3614              
3615             GEN
3616             interface44(arg1, arg2, arg3, arg4)
3617             long oldavma=avma;
3618             long arg1
3619             long arg2
3620             long arg3
3621             long arg4
3622             CODE:
3623             {
3624 0           dFUNCTION(GEN);
3625              
3626 0 0         if (!FUNCTION) {
3627 0           croak("XSUB call through interface did not provide *function");
3628             }
3629              
3630 0           RETVAL=FUNCTION(arg1, arg2, arg3, arg4);
3631             }
3632             OUTPUT:
3633             RETVAL
3634              
3635             GEN
3636             interface45(arg1, arg2, arg3=0)
3637             long oldavma=avma;
3638             long arg1
3639             GEN arg2
3640             long arg3
3641             CODE:
3642             { /* Code="LGD0,L," */
3643 0           dFUNCTION(GEN);
3644              
3645 0 0         if (!FUNCTION) {
3646 0           croak("XSUB call through interface did not provide *function");
3647             }
3648              
3649 0           RETVAL=FUNCTION(arg1, arg2, arg3);
3650             }
3651             OUTPUT:
3652             RETVAL
3653              
3654             void
3655             interface59(arg1, arg2, arg3, arg4, arg5)
3656             long oldavma=avma;
3657             long arg1
3658             GEN arg2
3659             GEN arg3
3660             GEN arg4
3661             GEN arg5
3662             CODE:
3663             { /* Code="vLGGGG" */
3664 2           dFUNCTION(GEN);
3665              
3666 2 50         if (!FUNCTION) {
3667 0           croak("XSUB call through interface did not provide *function");
3668             }
3669              
3670 2           FUNCTION(arg1, arg2, arg3, arg4, arg5);
3671             }
3672             CLEANUP:
3673 2           avma=oldavma;
3674              
3675             GEN
3676             interface73(arg1, arg2, arg3, arg4, arg5, arg6=0, arg7=0)
3677             long oldavma=avma;
3678             long arg1
3679             PariVar arg2
3680             GEN arg3
3681             GEN arg4
3682             PariExprV arg5
3683             long arg6
3684             long arg7
3685             CODE:
3686             { /* Code="LV=GGIpD0,L,D0,L," */
3687 0           dFUNCTION(GEN);
3688              
3689 0 0         if (!FUNCTION) {
3690 0           croak("XSUB call through interface did not provide *function");
3691             }
3692             #if PARI_VERSION_EXP >= 2004002
3693             RETVAL=FUNCTION(arg1, arg3, arg4, arg5, prec_words, arg6, arg7); /* XXXX Omit `V' instead of merging it into I/E */
3694             #else
3695 0           RETVAL=FUNCTION(arg1, arg2, arg3, arg4, arg5, prec_words, arg6, arg7);
3696             #endif
3697             }
3698             OUTPUT:
3699             RETVAL
3700              
3701             void
3702             interface86(arg1, arg2, arg3, arg4, arg5)
3703             long oldavma=avma;
3704             PariVar arg1
3705             GEN arg2
3706             GEN arg3
3707             GEN arg4
3708             PariExprV arg5
3709             CODE:
3710             { /* Code="vV=GGGI" */
3711 1           dFUNCTION(GEN);
3712              
3713 1 50         if (!FUNCTION) {
3714 0           croak("XSUB call through interface did not provide *function");
3715             }
3716             #if PARI_VERSION_EXP >= 2004002
3717             FUNCTION(arg2, arg3, arg4, arg5); /* XXXX Omit `V' instead of merging it into I/E */
3718             #else
3719 1           FUNCTION(arg1, arg2, arg3, arg4, arg5);
3720             #endif
3721             }
3722             CLEANUP:
3723 1           avma=oldavma;
3724              
3725             void
3726             interface87(arg1, arg2, arg3, arg4=0)
3727             long oldavma=avma;
3728             PariVar arg1
3729             GEN arg2
3730             PariExprV arg3
3731             long arg4
3732             CODE:
3733             { /* Code="vV=GID0,L," */
3734 1           dFUNCTION(GEN);
3735              
3736 1 50         if (!FUNCTION) {
3737 0           croak("XSUB call through interface did not provide *function");
3738             }
3739             #if PARI_VERSION_EXP >= 2004002
3740             FUNCTION(arg2, arg3, arg4); /* XXXX Omit `V' instead of merging it into I/E */
3741             #else
3742 1           FUNCTION(arg1, arg2, arg3, arg4);
3743             #endif
3744             }
3745             CLEANUP:
3746 1           avma=oldavma;
3747              
3748             bool
3749             _2bool(arg1,arg2,inv)
3750             long oldavma=avma;
3751             GEN arg1
3752             GEN arg2 = NO_INIT
3753             long inv = NO_INIT
3754             CODE:
3755             PERL_UNUSED_VAR(arg2); /* -W */
3756             PERL_UNUSED_VAR(inv); /* -W */
3757 65           RETVAL=!gcmp0(arg1);
3758             OUTPUT:
3759             RETVAL
3760             CLEANUP:
3761 65           avma=oldavma;
3762              
3763             bool
3764             pari2bool(arg1)
3765             long oldavma=avma;
3766             GEN arg1
3767             CODE:
3768 0           RETVAL=!gcmp0(arg1);
3769             OUTPUT:
3770             RETVAL
3771             CLEANUP:
3772 0           avma=oldavma;
3773              
3774             CV *
3775             loadPari(name, v = 99)
3776             char * name
3777             int v
3778             CODE:
3779             {
3780 11007           char *olds = name;
3781 11007           entree *ep=NULL;
3782 11007           long hash, valence = -1; /* Avoid uninit warning */
3783 11007           void (*func)(void*)=NULL;
3784 11007           void (*unsupported)(void*) = (void (*)(void*)) not_here;
3785              
3786 11007 100         if (*name=='g') {
3787 329           switch (name[1]) {
3788             case 'a':
3789 221 100         if (strEQ(name,"gadd")) {
3790 1           valence=2;
3791 1           func=(void (*)(void*)) gadd;
3792 220 50         } else if (strEQ(name,"gand")) {
3793 0           valence=2;
3794 0           func=(void (*)(void*)) gand;
3795             }
3796 221           break;
3797             case 'c':
3798 20 50         if (strEQ(name,"gcmp0")) {
3799 0           valence=10;
3800 0           func=(void (*)(void*)) gcmp0;
3801 20 50         } else if (strEQ(name,"gcmp1")) {
3802 0           valence=10;
3803 0           func=(void (*)(void*)) gcmp1;
3804 20 50         } else if (strEQ(name,"gcmp_1")) {
3805 0           valence=10;
3806 0           func=(void (*)(void*)) gcmp_1;
3807 20 50         } else if (strEQ(name,"gcmp")) {
3808 0           valence=20;
3809 0           func=(void (*)(void*)) gcmp;
3810             }
3811 20           break;
3812             case 'd':
3813 4 50         if (strEQ(name,"gdiv")) {
3814 0           valence=2;
3815 0           func=(void (*)(void*)) gdiv;
3816 4 100         } else if (strEQ(name,"gdivent")) {
3817 3           valence=2;
3818 3           func=(void (*)(void*)) gdivent;
3819 1 50         } else if (strEQ(name,"gdivround")) {
3820 1           valence=2;
3821 1           func=(void (*)(void*)) gdivround;
3822             }
3823 4           break;
3824             case 'e':
3825 81 100         if (strEQ(name,"geq")) {
3826 1           valence=2;
3827 1           func=(void (*)(void*)) geq;
3828 80 50         } else if (strEQ(name,"gegal") || strEQ(name,"gequal")) { /* old name */
    50          
3829 0           valence=20;
3830 0           func=(void (*)(void*)) gequal;
3831             }
3832 81           break;
3833             case 'g':
3834 0 0         if (strEQ(name,"gge")) {
3835 0           valence=2;
3836 0           func=(void (*)(void*)) gge;
3837 0 0         } else if (strEQ(name,"ggt")) {
3838 0           valence=2;
3839 0           func=(void (*)(void*)) ggt;
3840             }
3841 0           break;
3842             case 'l':
3843 0 0         if (strEQ(name,"gle")) {
3844 0           valence=2;
3845 0           func=(void (*)(void*)) gle;
3846 0 0         } else if (strEQ(name,"glt")) {
3847 0           valence=2;
3848 0           func=(void (*)(void*)) glt;
3849             }
3850 0           break;
3851             case 'm':
3852 0 0         if (strEQ(name,"gmul")) {
3853 0           valence=2;
3854 0           func=(void (*)(void*)) gmul;
3855 0 0         } else if (strEQ(name,"gmod")) {
3856 0           valence=2;
3857 0           func=(void (*)(void*)) gmod;
3858             }
3859 0           break;
3860             case 'n':
3861 1 50         if (strEQ(name,"gneg")) {
3862 0           valence=1;
3863 0           func=(void (*)(void*)) gneg;
3864 1 50         } else if (strEQ(name,"gne")) {
3865 1           valence=2;
3866 1           func=(void (*)(void*)) gne;
3867             }
3868 1           break;
3869             case 'o':
3870 0 0         if (strEQ(name,"gor")) {
3871 0           valence=2;
3872 0           func=(void (*)(void*)) gor;
3873             }
3874 0           break;
3875             case 'p':
3876 1 50         if (strEQ(name,"gpui") || strEQ(name,"gpow")) {
    0          
3877 1           valence=2;
3878 1           func=(void (*)(void*)) my_gpui;
3879             }
3880 1           break;
3881             case 's':
3882 1 50         if (strEQ(name,"gsub")) {
3883 1           valence=2;
3884 1           func=(void (*)(void*)) gsub;
3885             }
3886 329           break;
3887             }
3888 10678 100         } else if (*name=='_') {
3889 103 100         if (name[1] == 'g') {
3890 100           switch (name[2]) {
3891             case 'a':
3892 11 50         if (strEQ(name,"_gadd")) {
3893 11           valence=299;
3894 11           func=(void (*)(void*)) gadd;
3895 0 0         } else if (strEQ(name,"_gand")) {
3896 0           valence=2099;
3897 0           func=(void (*)(void*)) gand;
3898             }
3899 11           break;
3900             #if PARI_VERSION_EXP >= 2000018
3901             case 'b':
3902 5 100         if (strEQ(name,"_gbitand")) {
3903 1           valence=299;
3904 1           func=(void (*)(void*)) gbitand;
3905 4 100         } else if (strEQ(name,"_gbitor")) {
3906 1           valence=299;
3907 1           func=(void (*)(void*)) gbitor;
3908 3 100         } else if (strEQ(name,"_gbitxor")) {
3909 1           valence=299;
3910 1           func=(void (*)(void*)) gbitxor;
3911 2 100         } else if (strEQ(name,"_gbitneg")) {
3912 1           valence=199;
3913 1           func=(void (*)(void*)) _gbitneg;
3914             #if PARI_VERSION_EXP >= 2002001
3915 1 50         } else if (strEQ(name,"_gbitshiftl")) {
3916 1           valence=2199;
3917 1           func=(void (*)(void*)) _gbitshiftl;
3918             #endif
3919             #if PARI_VERSION_EXP >= 2002001 && PARI_VERSION_EXP <= 2002007
3920             } else if (strEQ(name,"_gbitshiftr")) {
3921             valence=2199;
3922             func=(void (*)(void*)) _gbitshiftr;
3923             #endif
3924             }
3925 5           break;
3926             #endif
3927             case 'c':
3928 0 0         if (strEQ(name,"_gcmp")) {
3929 0           valence=209;
3930 0           func=(void (*)(void*)) gcmp;
3931 0 0         } else if (strEQ(name,"_gcmp0")) {
3932 0           valence=109;
3933 0           func=(void (*)(void*)) gcmp0;
3934             }
3935 0           break;
3936             case 'd':
3937 14 50         if (strEQ(name,"_gdiv")) {
3938 14           valence=299;
3939 14           func=(void (*)(void*)) gdiv;
3940             }
3941 14           break;
3942             case 'e':
3943 20 50         if (strEQ(name,"_geq")) {
3944 20           valence=2099;
3945 20           func=(void (*)(void*)) geq;
3946             }
3947 20           break;
3948             case 'g':
3949 1 50         if (strEQ(name,"_gge")) {
3950 1           valence=2099;
3951 1           func=(void (*)(void*)) gge;
3952 0 0         } else if (strEQ(name,"_ggt")) {
3953 0           valence=2099;
3954 0           func=(void (*)(void*)) ggt;
3955             }
3956 1           break;
3957             case 'l':
3958 2 100         if (strEQ(name,"_gle")) {
3959 1           valence=2099;
3960 1           func=(void (*)(void*)) gle;
3961 1 50         } else if (strEQ(name,"_glt")) {
3962 1           valence=2099;
3963 1           func=(void (*)(void*)) glt;
3964             }
3965 2           break;
3966             case 'm':
3967 17 100         if (strEQ(name,"_gmul")) {
3968 14           valence=299;
3969 14           func=(void (*)(void*)) gmul;
3970 3 50         } else if (strEQ(name,"_gmod")) {
3971 3           valence=299;
3972 3           func=(void (*)(void*)) gmod;
3973             }
3974 17           break;
3975             case 'n':
3976 8 100         if (strEQ(name,"_gneg")) {
3977 7           valence=199;
3978 7           func=(void (*)(void*)) gneg;
3979 1 50         } else if (strEQ(name,"_gne")) {
3980 1           valence=2099;
3981 1           func=(void (*)(void*)) gne;
3982             }
3983 8           break;
3984             case 'o':
3985 0 0         if (strEQ(name,"_gor")) {
3986 0           valence=2099;
3987 0           func=(void (*)(void*)) gor;
3988             }
3989 0           break;
3990             case 'p':
3991 11 50         if (strEQ(name,"_gpui")) {
3992 11           valence=299;
3993 11           func=(void (*)(void*)) my_gpui;
3994             }
3995 11           break;
3996             case 's':
3997 11 50         if (strEQ(name,"_gsub")) {
3998 11           valence=299;
3999 11           func=(void (*)(void*)) gsub;
4000             }
4001 100           break;
4002             }
4003             } else {
4004 3           switch (name[1]) {
4005             case 'a':
4006 1 50         if (strEQ(name,"_abs")) {
4007 1           valence=199;
4008 1           func=(void (*)(void*)) gabs;
4009             }
4010 1           break;
4011             case 'c':
4012 0 0         if (strEQ(name,"_cos")) {
4013 0           valence=199;
4014 0           func=(void (*)(void*)) gcos;
4015             }
4016 0           break;
4017             case 'e':
4018 1 50         if (strEQ(name,"_exp")) {
4019 1           valence=199;
4020 1           func=(void (*)(void*)) gexp;
4021             }
4022 1           break;
4023             case 'l':
4024 1 50         if (strEQ(name,"_lex")) {
4025 1           valence=2091;
4026 1           func=(void (*)(void*)) lexcmp;
4027 0 0         } else if (strEQ(name,"_log")) {
4028 0           valence=199;
4029 0           func=(void (*)(void*)) glog;
4030             }
4031 1           break;
4032             case 's':
4033 0 0         if (strEQ(name,"_sin")) {
4034 0           valence=199;
4035 0           func=(void (*)(void*)) gsin;
4036 0 0         } else if (strEQ(name,"_sqrt")) {
4037 0           valence=199;
4038 0           func=(void (*)(void*)) gsqrt;
4039             }
4040 0           break;
4041             }
4042             }
4043             }
4044 11007 100         if (!func) {
4045 10895           SAVEINT(doing_PARI_autoload);
4046 10895           doing_PARI_autoload = 1;
4047             checkPariFunction(name);
4048             #ifdef MAY_USE_FETCH_ENTRY
4049             ep = is_entry(name);
4050             #else
4051 10895           ep = is_entry_intern(name, functions_hash, &hash);
4052             #endif
4053 10895           doing_PARI_autoload = 0;
4054 10895 100         if (!ep)
4055 2           croak("`%s' is not a Pari function name",name);
4056              
4057 10893 50         if (ep && isPariFunction(ep)) {
    50          
4058             /* Builtin */
4059 10893           IV table_valence = 99;
4060              
4061 10893 50         if (ep->code /* This is in func_codes.h: */
    100          
4062 10852 100         && (*(ep->code) ? (PERL_constant_ISIV == func_ord_by_type (aTHX_ ep->code,
4063 10852           strlen(ep->code), &table_valence)) /* Essentially, PERL_constant_ISIV means: recognized */
4064 41           : (table_valence = 9900)))
4065 7051           valence = table_valence;
4066             else
4067 3842           valence = 99;
4068             #ifdef CHECK_VALENCE
4069             if (ep->code && valence != EpVALENCE(ep)
4070             && EpVALENCE(ep) != 99
4071             && !(valence == 23 && EpVALENCE(ep) == 21)
4072             && !(valence == 48 && EpVALENCE(ep) == 47)
4073             && !(valence == 96 && EpVALENCE(ep) == 91)
4074             && !(valence == 99 && EpVALENCE(ep) == 0)
4075             && !(valence == 9900 && EpVALENCE(ep) == 0))
4076             warn("funcname=`%s', code=`%s', val=%d, calc_val=%d\n",
4077             name, ep->code, (int)EpVALENCE(ep), (int)valence);
4078             #endif
4079 10893           func=(void (*)(void*)) ep->value;
4080 10893 50         if (!func) {
4081 10893           func = unsupported;
4082             }
4083             }
4084             }
4085 11005 50         if (func == unsupported) {
4086 0           croak("Do not know how to work with Pari control structure `%s'",
4087             olds);
4088 11005 50         } else if (func) {
4089 11005           char* file = __FILE__, *proto = NULL;
4090 11005           char subname[276]="Math::Pari::";
4091 11005           char buf[64], *pbuf = buf;
4092             const char *s, *s1;
4093             CV *protocv;
4094 11005           int flexible = 0;
4095            
4096 11005           sprintf(buf, "%ld", valence);
4097             /* warn("See valence = %d", valence); */
4098 11005           switch (valence) {
4099             case 0:
4100 41 50         if (!ep->code) {
4101 0           croak("Unsupported Pari function %s, interface 0 code NULL", olds);
4102 41 50         } else if (ep->code[0] == 'p' && ep->code[1] == 0) {
    50          
4103 41           DO_INTERFACE(0);
4104 0 0         } else if (ep->code[0] == 0) {
4105 0           DO_INTERFACE(9900);
4106             } else {
4107 0           goto flexible;
4108             }
4109 41           break;
4110 720           CASE_INTERFACE(1);
4111 140           CASE_INTERFACE(10);
4112 10           CASE_INTERFACE(199);
4113 0           CASE_INTERFACE(109);
4114 180           CASE_INTERFACE(11);
4115 0           CASE_INTERFACE(15);
4116 1709           CASE_INTERFACE(2);
4117 80           CASE_INTERFACE(20);
4118 67           CASE_INTERFACE(299);
4119 0           CASE_INTERFACE(209);
4120 24           CASE_INTERFACE(2099);
4121 1           CASE_INTERFACE(2091);
4122 1           CASE_INTERFACE(2199);
4123 560           CASE_INTERFACE(3);
4124 40           CASE_INTERFACE(30);
4125 80           CASE_INTERFACE(4);
4126 0           CASE_INTERFACE(5);
4127 0           CASE_INTERFACE(21);
4128 140           CASE_INTERFACE(23);
4129 20           CASE_INTERFACE(24);
4130 321           CASE_INTERFACE(25);
4131 380           CASE_INTERFACE(29);
4132 40           CASE_INTERFACE(32);
4133 40           CASE_INTERFACE(33);
4134 140           CASE_INTERFACE(35);
4135 20           CASE_INTERFACE(12);
4136 60           CASE_INTERFACE(13);
4137 223           CASE_INTERFACE(14);
4138 20           CASE_INTERFACE(26);
4139 60           CASE_INTERFACE(28);
4140 20           CASE_INTERFACE(31);
4141 0           CASE_INTERFACE(34);
4142 20           CASE_INTERFACE(22);
4143 20           CASE_INTERFACE(27);
4144 40           CASE_INTERFACE(37);
4145 61           CASE_INTERFACE(47);
4146 0           CASE_INTERFACE(48);
4147 20           CASE_INTERFACE(49);
4148 40           CASE_INTERFACE(83);
4149 21           CASE_INTERFACE(84);
4150 1483           CASE_INTERFACE(18);
4151             /* These interfaces were automatically generated: */
4152 20           CASE_INTERFACE(16);
4153 60           CASE_INTERFACE(19);
4154 0           CASE_INTERFACE(44);
4155 20           CASE_INTERFACE(45);
4156 20           CASE_INTERFACE(59);
4157 20           CASE_INTERFACE(73);
4158 20           CASE_INTERFACE(86);
4159 20           CASE_INTERFACE(87);
4160 41           CASE_INTERFACE(9900);
4161              
4162             default:
4163 3942 50         if (!ep)
4164 0           croak("Unsupported interface %ld for \"direct-link\" Pari function %s",
4165             valence, olds);
4166 3942 50         if (!ep->code)
4167 0           croak("Unsupported interface %ld and no code for a Pari function %s",
4168             valence, olds);
4169             flexible:
4170 3942           s1 = s = ep->code;
4171 3942 50         if (*s1 == 'x')
4172 0           s1++;
4173 3942 100         if (*s1 == 'v') {
4174 480           pbuf = "_flexible_void";
4175 480           DO_INTERFACE(_flexible_void);
4176             }
4177 3462 100         else if (*s1 == 'l') {
4178 260           pbuf = "_flexible_long";
4179 260           DO_INTERFACE(_flexible_long);
4180             }
4181 3202 100         else if (*s1 == 'i') {
4182 40           pbuf = "_flexible_int";
4183 40           DO_INTERFACE(_flexible_int);
4184             }
4185             else {
4186 3162           pbuf = "_flexible_gen";
4187 3162           DO_INTERFACE(_flexible_gen);
4188             }
4189            
4190 3942           flexible = 1;
4191             }
4192 11005           strcpy(subname+12,"interface");
4193 11005           strcpy(subname+12+9,pbuf);
4194 11005           protocv = perl_get_cv(subname, FALSE);
4195 11005 50         if (protocv) {
4196 11005 50         proto = SvPV((SV*)protocv,na);
4197             }
4198            
4199 11005           strcpy(subname+12,olds);
4200 11005           RETVAL = newXS(subname,math_pari_subaddr,file);
4201 11005 50         if (proto)
4202 11005           sv_setpv((SV*)RETVAL, proto);
4203 11005 100         XSINTERFACE_FUNC_SET(RETVAL, flexible ? (void*)ep : (void*)func);
4204             } else {
4205 0 0         croak( "Cannot load a Pari macro `%s': macros are unsupported; VALENCE=%#04x, code=<%s>, isFunction=%d, EpVAR=%d",
    0          
4206 0           olds, (ep ? (int)EpVALENCE(ep) : 0x666), (ep->code ? ep->code : ""), isPariFunction(ep), (int)EpVAR);
4207             }
4208             }
4209             OUTPUT:
4210             RETVAL
4211              
4212             # Tag is menu entry, or -1 for all.
4213              
4214             void
4215             _listPari(tag)
4216             int tag
4217             PPCODE:
4218             {
4219             long valence;
4220 32           entree *ep, *table = functions_basic;
4221 32           int i=-1;
4222              
4223 96 100         while (++i <= 1) {
4224 64 100         if (i==1)
4225             #if defined(NO_HIGHLEVEL_PARI) || PARI_VERSION_EXP >= 2009000 /* Probably disappered earlier */
4226             break;
4227             #else
4228 32           table = functions_highlevel;
4229             #endif
4230            
4231 17760 100         for(ep = table; ep->name; ep++) {
4232 17696           valence = EpVALENCE(ep);
4233 17696 100         if ((tag == -1 && !_is_internal(ep->menu)) || ep->menu == tag) {
    50          
    100          
4234 11613 100         switch (valence) {
4235             default:
4236             case 0:
4237 6216 100         if (ep->code == 0)
4238 105           break;
4239             /* FALL THROUGH */
4240             case 1:
4241             case 10:
4242             case 199:
4243             case 109:
4244             case 11:
4245             case 15:
4246             case 2:
4247             case 20:
4248             case 299:
4249             case 209:
4250             case 2099:
4251             case 2199:
4252             case 3:
4253             case 30:
4254             case 4:
4255             case 5:
4256             case 21:
4257             case 23:
4258             case 24:
4259             case 25:
4260             case 29:
4261             case 32:
4262             case 33:
4263             case 35:
4264             case 12:
4265             case 13:
4266             case 14:
4267             case 26:
4268             case 28:
4269             case 31:
4270             case 34:
4271             case 22:
4272             case 27:
4273             case 37:
4274             case 47:
4275             case 48:
4276             case 49:
4277             case 83:
4278             case 84:
4279             case 18:
4280             /* These interfaces were automatically generated: */
4281             case 16:
4282             case 19:
4283             case 44:
4284             case 45:
4285             case 59:
4286             case 73:
4287             case 86:
4288             case 87:
4289 11508 100         XPUSHs(sv_2mortal(newSVpv(ep->name, 0)));
4290             }
4291             }
4292             }
4293             }
4294             }
4295              
4296             BOOT:
4297             {
4298             static int reboot;
4299 26           SV *mem = perl_get_sv("Math::Pari::initmem", FALSE);
4300 26           SV *pri = perl_get_sv("Math::Pari::initprimes", FALSE);
4301             pari_sp av;
4302 26 50         if (!mem || !SvOK(mem)) {
    50          
    0          
    0          
4303 0           croak("$Math::Pari::initmem not defined!");
4304             }
4305 26 50         if (!pri || !SvOK(pri)) {
    50          
    0          
    0          
4306 0           croak("$Math::Pari::initprimes not defined!");
4307             }
4308 26 50         if (reboot) {
4309 0           detach_stack();
4310             #if PARI_VERSION_EXP >= 2002012 /* Present at least in 2.3.5; assume correct due to http://pari.math.u-bordeaux.fr/archives/pari-dev-0511/msg00037.html */
4311 0           pari_close_opts(INIT_DFTm);
4312             #else /* PARI_VERSION_EXP < 2002012 */
4313             if (reset_on_reload)
4314             freeall();
4315             else
4316             allocatemoremem(1008);
4317             #endif
4318             }
4319             #if PARI_VERSION_EXP >= 2002012
4320             /* pari_init_defaults(); */ /* Not needed with INIT_DFTm */
4321             #else
4322             INIT_JMP_off;
4323             INIT_SIG_off;
4324             /* These guys are new in 2.0. */
4325             init_defaults(1);
4326             #endif
4327             /* Different order of init required */
4328             #if PARI_VERSION_EXP < 2003000
4329             if (!(reboot++)) {
4330             # ifndef NO_HIGHLEVEL_PARI
4331             # if PARI_VERSION_EXP >= 2002012
4332             pari_add_module(functions_highlevel);
4333             # else /* !( PARI_VERSION_EXP >= 2002012 ) */
4334             pari_addfunctions(&pari_modules,
4335             functions_highlevel, helpmessages_highlevel);
4336             # endif /* !( PARI_VERSION_EXP >= 2002012 ) */
4337             init_graph();
4338             # endif
4339             }
4340             #endif /* PARI_VERSION_EXP < 2003000 */
4341 26 50         primelimit = SvIV(pri);
4342 26 50         parisize = SvIV(mem);
4343             #if PARI_VERSION_EXP >= 2002012
4344 26           pari_init_opts(parisize, primelimit, INIT_DFTm);
4345             /* Default: take four million bytes of
4346             * memory for the stack, calculate
4347             * primes up to 500000. */
4348             #else
4349             init(parisize, primelimit); /* Default: take four million bytes of
4350             * memory for the stack, calculate
4351             * primes up to 500000. */
4352             #endif
4353             /* Different order of init required */
4354             #if PARI_VERSION_EXP >= 2003000
4355 26 50         if (!(reboot++)) {
4356             # ifndef NO_HIGHLEVEL_PARI
4357             # if PARI_VERSION_EXP >= 2002012
4358             # if PARI_VERSION_EXP < 2009000 /* Probably disappered earlier */
4359 26           pari_add_module(functions_highlevel);
4360             # endif /* PARI_VERSION_EXP < 2009000 */
4361             # else /* !( PARI_VERSION_EXP >= 2002012 ) */
4362             pari_addfunctions(&pari_modules,
4363             functions_highlevel, helpmessages_highlevel);
4364             # endif /* !( PARI_VERSION_EXP >= 2002012 ) */
4365             #if PARI_VERSION_EXP >= 2011000
4366             pari_set_plot_engine(gp_get_plot);
4367             #else
4368 26           init_graph();
4369             #endif
4370             # endif
4371             }
4372             #endif /* PARI_VERSION_EXP >= 2003000 */
4373 26           PariStack = (SV *) GENfirstOnStack;
4374 26 50         if (!worksv)
4375 26           worksv = NEWSV(910,0);
4376 26 50         if (workErrsv)
4377 0           sv_setpvn(workErrsv, "", 0); /* Just in case, on restart */
4378             else
4379 26           workErrsv = newSVpvn("",0);
4380 26           pariErr = &perlErr;
4381             #if PARI_VERSION_EXP >= 2003000
4382 26           pari_set_last_newline(1); /* Bug in PARI: at the start, we do not need extra newlines */
4383             #endif
4384             #if PARI_VERSION_EXP >= 2004000 /* Undocumented when it appeared; present in 2.5.0 */
4385             cb_pari_err_recover = _svErrdie; /* XXXX Not enough for our needs! */
4386             cb_pari_handle_exception = math_pari_handle_exception;
4387             # ifdef CB_EXCEPTION_FLAGS
4388             cb_exception_resets_avma = 1;
4389             cb_exception_flushes_err = 1;
4390             # endif
4391             av = avma;
4392             /* Init the rest ourselves */
4393             #if PARI_VERSION_EXP >= 2009000
4394             if (!GP_DATA->colormap) /* init_defaults() leaves them NULL */
4395             sd_graphcolormap("[\"white\",\"black\",\"gray\",\"violetred\",\"red\",\"green\",\"blue\",\"gainsboro\",\"purple\"]",0);
4396             if (!GP_DATA->graphcolors)
4397             sd_graphcolors("[4,5]",0);
4398             avma = av;
4399             #else /* !(PARI_VERSION_EXP >= 2009000) */
4400             if (!pari_colormap) /* init_defaults() leaves them NULL */
4401             pari_colormap = gclone(readseq("[\"white\",\"black\",\"gray\",\"violetred\",\"red\",\"green\",\"blue\",\"gainsboro\",\"purple\"]"));
4402             if (!pari_graphcolors)
4403             pari_graphcolors = gclone(readseq("[4,5]"));
4404             avma = av;
4405             #endif /* !(PARI_VERSION_EXP >= 2009000) */
4406             #endif
4407             #if PARI_VERSION_EXP < 2005000 /* Undocumented when it disappeared; missing in 2.5.0 */
4408 26           foreignHandler = (void*)&callPerlFunction;
4409 26           foreignExprSwitch = (char)SVt_PVCV;
4410 26           foreignExprHandler = &exprHandler_Perl;
4411             #endif
4412 26           foreignAutoload = &autoloadPerlFunction;
4413 26           foreignFuncFree = &freePerlFunction;
4414 26           pariStash = gv_stashpv("Math::Pari", TRUE);
4415 26           pariEpStash = gv_stashpv("Math::Pari::Ep", TRUE);
4416 26           perlavma = sentinel = avma;
4417             fmt_nbPset(def_fmt_nb);
4418 26           global_top = myPARI_top;
4419             #if PARI_VERSION_EXP >= 2004002 /* Undocumented when it appeared; present in 2.5.0 */
4420             if (! code_return_1) {
4421             code_return_1 = gclone(compile_str("x->1"));
4422             code2_return_1 = gclone(compile_str("(x,y)->1"));
4423             avma = sentinel;
4424             }
4425             #endif
4426             }
4427              
4428             void
4429             memUsage()
4430             PPCODE:
4431             #ifdef DEBUG_PARI
4432 18 50         EXTEND(sp, 4); /* Got cv + 0, - but on newer Perls, this does not count. Return 4. */
4433 18           PUSHs(sv_2mortal(newSViv(SVnumtotal)));
4434 18           PUSHs(sv_2mortal(newSViv(SVnum)));
4435 18           PUSHs(sv_2mortal(newSViv(onStack)));
4436 18           PUSHs(sv_2mortal(newSViv(offStack)));
4437             #endif
4438            
4439              
4440             void
4441             dumpStack()
4442             PPCODE:
4443 19           long i = 0, ssize, oursize = 0;
4444             SV *ret, *sv1, *nextsv;
4445 19           const char *pref = "";
4446              
4447 19 50         switch(GIMME_V) {
4448             case G_VOID:
4449 19           pref = "# ";
4450             case G_SCALAR:
4451 19           ssize = getstack();
4452 19           ret = newSVpvf("%sstack size is %ld bytes (%ld x %ld longs)\n",
4453             pref, ssize, (long)sizeof(long), ssize/sizeof(long));
4454 121 100         for (sv1 = PariStack; sv1 != (SV *) GENfirstOnStack; sv1 = nextsv) {
4455 102 100         GEN x = (GEN) SV_myvoidp_get(sv1);
    50          
4456 102           SV* tmp = pari_print(x);
4457 102 50         sv_catpvf(ret,"%s %2ld: %s\n", pref, i, SvPV_nolen(tmp));
4458 102           SvREFCNT_dec(tmp);
4459 102           i++;
4460 102           oursize += gsizeword(x);
4461 102 100         nextsv = SV_Stack_find_next(sv1);
4462             }
4463 19           sv_catpvf(ret,"%sour data takes %ld words out of %ld words on stack\n", pref, oursize, ssize/sizeof(long));
4464 19 50         if(GIMME_V == G_VOID) {
    50          
4465 19 50         PerlIO_puts(PerlIO_stdout(), SvPV_nolen(ret));
4466 19           SvREFCNT_dec(ret);
4467 19           XSRETURN(0);
4468             } else {
4469 0           ST(0) = sv_2mortal(ret);
4470 0           XSRETURN(1);
4471             }
4472             case G_ARRAY:
4473 0 0         for (sv1 = PariStack; sv1 != (SV *) GENfirstOnStack; sv1 = nextsv) {
4474 0 0         GEN x = (GEN) SV_myvoidp_get(sv1);
    0          
4475 0 0         XPUSHs(sv_2mortal(pari_print(x)));
4476 0 0         nextsv = SV_Stack_find_next(sv1);
4477             }
4478             }
4479              
4480             void
4481             __dumpStack()
4482             PPCODE:
4483 0           GEN x = (GEN)avma; /* If this works, it is accidental only: it assumes the entry point to “the region on stack” is at its smallest address. */
4484 0           long ssize, i = 0;
4485             SV* ret;
4486              
4487 0 0         switch(GIMME_V) {
4488             case G_VOID:
4489             case G_SCALAR:
4490 0           ssize = getstack();
4491 0           ret = newSVpvf("stack size is %ld bytes (%ld x %ld longs)\n",
4492             ssize,(long)sizeof(long),ssize/sizeof(long));
4493 0 0         for(; x < (GEN)myPARI_top; x += gsizeword(x), i++) {
4494 0           SV* tmp = pari_print(x);
4495 0 0         sv_catpvf(ret," %2ld: %s\n",i,SvPV_nolen(tmp));
4496 0           SvREFCNT_dec(tmp);
4497             }
4498 0 0         if(GIMME_V == G_VOID) {
    0          
4499 0 0         PerlIO_puts(PerlIO_stdout(), SvPV_nolen(ret));
4500 0           SvREFCNT_dec(ret);
4501 0           XSRETURN(0);
4502             } else {
4503 0           ST(0) = sv_2mortal(ret);
4504 0           XSRETURN(1);
4505             }
4506             case G_ARRAY:
4507 0 0         for(; x < (GEN)myPARI_top; x += gsizeword(x), i++)
4508 0 0         XPUSHs(sv_2mortal(pari_print(x)));
4509             }
4510              
4511             void
4512             dumpHeap()
4513             PPCODE:
4514             heap_dumper_t hd;
4515 0 0         int context = GIMME_V, m;
4516              
4517 0           SV* ret = Nullsv; /* Avoid unit warning */
4518              
4519 0           switch(context) {
4520             case G_VOID:
4521 0           case G_SCALAR: ret = newSVpvn("",0); break;
4522 0           case G_ARRAY: ret = (SV*)newAV(); break;
4523             }
4524              
4525 0           hd.words = hd.items = 0;
4526 0           hd.acc = ret;
4527 0           hd.context = context;
4528              
4529 0           heap_dumper(&hd);
4530              
4531 0           switch(context) {
4532             case G_VOID:
4533             case G_SCALAR: {
4534 0           SV* tmp = newSVpvf("heap had %ld bytes (%ld items)\n",
4535 0           (hd.words + BL_HEAD * hd.items) * sizeof(long),
4536             hd.items);
4537 0           sv_catsv(tmp,ret);
4538 0           SvREFCNT_dec(ret);
4539 0 0         if(GIMME_V == G_VOID) {
    0          
4540 0 0         PerlIO_puts(PerlIO_stdout(), SvPV_nolen(tmp));
4541 0           SvREFCNT_dec(tmp);
4542 0           XSRETURN(0);
4543             } else {
4544 0           ST(0) = sv_2mortal(tmp);
4545 0           XSRETURN(1);
4546             }
4547             }
4548             case G_ARRAY:
4549 0 0         for(m = 0; m <= av_len((AV*)ret); m++)
4550 0 0         XPUSHs(sv_2mortal(SvREFCNT_inc(*av_fetch((AV*)ret,m,0))));
4551 0           SvREFCNT_dec(ret);
4552             }
4553              
4554             MODULE = Math::Pari PACKAGE = Math::Pari
4555              
4556             void
4557             DESTROY(rv)
4558             SV * rv
4559             CODE:
4560             {
4561             /* PariStack keeps the latest SV that keeps a GEN on stack. */
4562 9028365           SV* sv = SvRV(rv);
4563             char* ostack; /* The value of PariStack when the
4564             * variable was created, thus the
4565             * previous SV that keeps a GEN from
4566             * stack, or some atoms. */
4567             long oldavma; /* The value of avma on the entry
4568             * to function having the SV as
4569             * argument. */
4570             long howmany;
4571 9028365 100         SV_OAVMA_PARISTACK_get(sv, oldavma, ostack);
4572 9028365           oldavma += myPARI_bot;
4573             #if 1
4574 9028365 100         if (SvMAGICAL(sv) && SvTYPE(sv) == SVt_PVAV) {
    50          
4575 2295           MAGIC *mg = mg_find(sv, 'P');
4576             SV *obj;
4577              
4578             /* Be extra paranoid: is refcount is artificially low? */
4579 2295 50         if (mg && (obj = mg->mg_obj) && SvROK(obj) && SvRV(obj) == sv) {
    50          
    100          
    50          
4580 2258           mg->mg_flags &= ~MGf_REFCOUNTED;
4581 2258           SvREFCNT_inc(sv);
4582 2258           SvREFCNT_dec(obj);
4583             }
4584             /* We manipulated SvCUR(), which for AV overwrites AvFILLp();
4585             make sure that array looks like an empty one */
4586 2295           AvFILLp((AV*)sv) = -1;
4587             }
4588             #endif
4589 9028365 100         SV_PARISTACK_set(sv, GENheap); /* To avoid extra free() in moveoff.... */
4590 9028365 100         if (ostack == GENheap) /* Leave it alone? XXXX */
4591             /* break */ ;
4592 8023158 100         else if (ostack == GENmovedOffStack) {/* Know that it _was temporary. */
4593 5250756 100         killbloc((GEN)SV_myvoidp_get(sv));
    50          
4594             } else {
4595             /* Still on stack */
4596 2772402 50         if (ostack != (char*)PariStack) { /* But not the newest one. */
4597 2772402           howmany = moveoffstack_newer_than(sv);
4598 2772402 50         RUN_IF_DEBUG_PARI( warn("%li items moved off stack, onStack=%ld, offStack=%ld", howmany, (long)onStack, (long)offStack) );
4599             }
4600             /* Now fall through: */
4601             /* case (IV)GENfirstOnStack: */
4602             /* Now sv is the newest one on stack. */
4603 2772402           onStack_dec;
4604 2772402           perlavma = oldavma;
4605 2772402 50         if (oldavma > sentinel) {
4606 0           avma = sentinel; /* Mark the space on stack as free. */
4607             } else {
4608 2772402           avma = oldavma; /* Mark the space on stack as free. */
4609             }
4610 2772402           PariStack = (SV*)ostack; /* The same on the Perl/PARI side. */
4611             }
4612 9028365           SVnum_dec;
4613             }
4614              
4615             SV *
4616             pari_print(in)
4617             GEN in
4618              
4619             SV *
4620             pari_pprint(in)
4621             GEN in
4622              
4623             SV *
4624             pari_texprint(in)
4625             GEN in
4626              
4627             I32
4628             typ(in)
4629             GEN in
4630              
4631             SV *
4632             PARIvar(in)
4633             char *in
4634              
4635             GEN
4636             ifact(arg1)
4637             long oldavma=avma;
4638             long arg1
4639              
4640             void
4641             changevalue(name, val)
4642             PariName name
4643             GEN val
4644              
4645             void
4646             set_gnuterm(a,b,c=0)
4647             IV a
4648             IV b
4649             IV c
4650              
4651             long
4652             setprecision(digits=0)
4653             long digits
4654              
4655             long
4656             setseriesprecision(digits=0)
4657             long digits
4658              
4659             IV
4660             setprimelimit(n = 0)
4661             IV n
4662              
4663             void
4664             int_set_term_ftable(a)
4665             IV a
4666              
4667             long
4668             pari_version_exp()
4669              
4670             long
4671             have_highlevel()
4672              
4673             long
4674             have_graphics()
4675              
4676             int
4677             PARI_DEBUG()
4678              
4679             int
4680             PARI_DEBUG_set(val)
4681             int val
4682              
4683             long
4684             lgef(x)
4685             GEN x
4686              
4687             long
4688             lgefint(x)
4689             GEN x
4690              
4691             long
4692             lg(x)
4693             GEN x
4694              
4695             unsigned long
4696             longword(x,n)
4697             GEN x
4698             long n
4699              
4700             char *
4701             added_sections()
4702              
4703             void
4704             __detach_stack()
4705             CODE:
4706 0           detach_stack();
4707              
4708             MODULE = Math::Pari PACKAGE = Math::Pari PREFIX = s_
4709              
4710             char *
4711             s_type_name(x)
4712             GEN x
4713              
4714             int
4715             s_reset_on_reload(newvalue = -1)
4716             int newvalue
4717              
4718             #ifdef WITH_CRASHYOURSELF
4719              
4720             void
4721             crash_yourself()
4722             CODE:
4723             char *s = (char *) make_PariAV;
4724             *s = s[0];
4725              
4726             #endif /* defined(WITH_CRASHYOURSELF) */
4727              
4728             # Cannot do this: it is xsubpp which needs the typemap entry for UV,
4729             # and it needs to convert *all* the branches.
4730             #/* #if defined(PERL_VERSION) && (PERL_VERSION >= 6)*//* 5.6.0 has UV in the typemap */
4731              
4732             #if 0
4733             #UV
4734             #allocatemem(newsize = 0)
4735             #UV newsize
4736              
4737             #else /* !( HAVE_UVs ) */
4738              
4739             unsigned long
4740             s_allocatemem(newsize = 0)
4741             unsigned long newsize
4742              
4743             #endif /* !( HAVE_UVs ) */