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 2187           str2gen(char *s, int prefer_str)
990             {
991 2187 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 20344978           sv2pariHow(SV* sv, int prefer_str)
1007             {
1008 20344978 100         if (SvGMAGICAL(sv)) mg_get(sv); /* MAYCHANGE in perlguts.pod - bug in perl */
1009 20344978 100         if (SvROK(sv)) {
1010 13373232           SV* tsv = SvRV(sv);
1011 13373232 100         if (SvOBJECT(tsv)) {
1012 13372776 100         if (SvSTASH(tsv) == pariStash) {
1013             is_pari:
1014             {
1015 9028192 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 6971746 100         else if (SvIOK(sv)) return PerlInt_to_i(sv);
    100          
    50          
    50          
1048 2637 100         else if (SvNOK(sv)) {
1049 377 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 377           return dbltor(n);
1061             }
1062 2260 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 2830216           moveoffstack_newer_than(SV* sv)
1435             {
1436             SV* sv1;
1437             SV* nextsv;
1438 2830216           long ret=0;
1439            
1440 8080981 100         for (sv1 = PariStack; sv1 != sv; sv1 = nextsv) {
1441 5250765           ret++;
1442 5250765 100         SV_OAVMA_switch(nextsv, sv1, GENmovedOffStack); /* Mark as moved off stack. */
1443 5250765 100         SV_myvoidp_reset_clone(sv1); /* Relocate to cloned */
    50          
1444 5250765           onStack_dec;
1445 5250765           offStack_inc;
1446             }
1447 2830216           PariStack = sv;
1448 2830216           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             /* croak("See arg specifier: '%s'", s); */
1939 1946           *OUT_cnt = 0;
1940 14389 100         while (*s) {
1941 12443 50         if (i >= ARGS_SUPPORTED - 1)
1942 0           croak("Too many args for a flexible-interface function");
1943 12443           switch (*s++)
1944             {
1945             case 'G': /* GEN */
1946 4520           argvec[i++] = sv2pari(args[j++]);
1947 4520           break;
1948              
1949             case 'M': /* long or a mneumonic string (string not supported) */
1950 2           saw_M = 1;
1951             /* Fall through */
1952             #if PARI_VERSION_EXP >= 2004002
1953             case 'P': /* series precision */
1954             #endif
1955             case 'L': /* long */
1956 134 100         argvec[i++] = (GEN) (long)SvIV(args[j]);
1957 134           j++;
1958 134           break;
1959              
1960             case 'n': /* var number */
1961 4           argvec[i++] = (GEN) numvar(sv2pari(args[j++]));
1962 4           break;
1963              
1964             case 'V': /* variable */
1965             #if PARI_VERSION_EXP < 2004002
1966 1381           ep1 = bindVariable(args[j++]);
1967 1381           argvec[i++] = (GEN)ep1;
1968 1381 50         if (EpVALENCE(ep1) != EpVAR && *(s-1) == 'V')
    0          
1969 0           croak("Did not get a variable");
1970 1381           saw_V++;
1971             #else
1972             if (*s != '=')
1973             warn("Unexpected: `V' not followed by `='"); /* appears in fordiv() etc. */
1974             if (saw_V >= MaxPariVar)
1975             croak("Too many loop variables in a signature (max=%d)", MaxPariVar);
1976             loopvars[saw_V++] = args[j++]; /* XXXX Ignore this variable (should be compiled into the closure!!!) ??? */
1977             #endif
1978 1381           break;
1979             case 'S': /* symbol */
1980             #if PARI_VERSION_EXP < 2004002
1981 0           ep1 = bindVariable(args[j++]);
1982 0           argvec[i++] = (GEN)ep1;
1983             #else
1984             croak("Variable type `S' unsupported after 2.4.2");
1985             #endif
1986 0           break;
1987             case '&': /* *GEN */
1988 2           gen_OUT[*OUT_cnt] = sv2pari(args[j]);
1989 2           argvec[i++] = (GEN)(gen_OUT + *OUT_cnt);
1990 2           sv_OUT[(*OUT_cnt)++] = args[j++];
1991 2           break;
1992             case 'E': /* Input position - subroutine */
1993             case 'I': /* Input position - subroutine, ignore value */
1994 1381 50         if (!args[j])
1995 0           croak("panic: no arg when AssignPariExpr()");
1996 1381 50         if (saw_V > 1) {
1997 0 0         if (saw_V > 2)
1998 0           croak("More than 2 running variables per PARI entry point not supported");
1999 0 0         AssignPariExpr2R(expr,args[j], 'I'==s[-1], LoopVar(0), LoopVar(1));
    0          
    0          
2000 1381 50         } else if (saw_V == 1) {
2001 1381 50         AssignPariExprR(expr,args[j], 'I'==s[-1], LoopVar(0));
    50          
    0          
2002             } else
2003 0           croak("Type E, I without a preceding variable");
2004 1381           argvec[i++] = (GEN) expr; /* XXXX Cast not needed after 2004002 */
2005 1381           j++;
2006 1381           break;
2007              
2008             case 's': /* expanded string; empty arg yields "" */
2009 0 0         if (*s == '*') {
2010 0           int ii = 0;
2011 0           GEN out = cgetg(items-j+1, t_VEC);
2012              
2013 0           s++;
2014 0           argvec[i++] = out;
2015 0 0         while (j < items)
2016 0           out[1 + ii++] = (long)sv2pariStr(args[j++]);
2017 0           goto args_done;
2018             }
2019             case 'r': /* raw */
2020 0 0         argvec[i++] = (GEN) SvPV(args[j],na);
2021 0           j++;
2022 0           break;
2023              
2024             case 'p': /* precision */
2025 1474           argvec[i++] = (GEN) prec_words;
2026 1474           break;
2027              
2028             #if PARI_VERSION_EXP >= 2008000
2029             case 'b': /* bitprecision */
2030             warn("===Passing precision=%ld; precreal=%ld", (long)prec_bits, (long)precreal);
2031             argvec[i++] = (GEN)precreal; /* prec_bits; */
2032             break;
2033             #endif
2034              
2035             case '=':
2036             case ',':
2037 1467           break;
2038              
2039             case 'D': /* Has a default value */
2040 2022           pre = s;
2041 2022 100         if (j >= items || !SvOK(args[j]))
    100          
    50          
    50          
2042             {
2043 513 100         if (j < items)
2044 20           j++;
2045              
2046 513 100         if ( *s == 'G' || *s == '&'
    100          
2047 156 50         || *s == 'r' || *s == 's'
    50          
2048 156 50         || *s == 'E' || *s == 'I' || *s == 'V') {
    50          
    50          
2049 357           argvec[i++]=DFT_GEN; s++;
2050 357           break;
2051             }
2052 156 100         if (*s == 'n') {
2053 14           argvec[i++]=DFT_VAR; s++;
2054 14           break;
2055             }
2056 142 50         if (*s == 'P') {
2057 0           argvec[i++] = (GEN) precdl; s++;
2058 0           break;
2059             }
2060 287 50         while (*s && *s++ != ',');
    100          
2061 142 50         if (!*s)
2062 0 0         if (!s[0] && s[-1] != ',')
    0          
2063 0           goto unrecognized_syntax;
2064 142           switch (*s) {
2065             case 'r': case 's':
2066 0 0         if (pre[0] == '\"' && pre[1] == '\"'
    0          
2067 0 0         && s - pre == 3) {
2068 0           argvec[i++] = (GEN) "";
2069 0           break;
2070             }
2071 0           goto unknown;
2072             case 'M': /* long or a mneumonic string
2073             (string not supported) */
2074 2           saw_M = 1;
2075             /* Fall through */
2076             case 'L': /* long */
2077 142           argvec[i++] = (GEN) MYatol(pre);
2078 142           break;
2079             case 'G':
2080 0 0         if ((*pre == '1' || *pre == '0') && pre[1]==',') {
    0          
    0          
2081 0           argvec[i++] = (*pre == '1'
2082 0 0         ? gen_1 : gen_0);
2083 0           break;
2084             }
2085             default:
2086             unknown:
2087 0           croak("Cannot process default argument %.*s of type %.1s for prototype '%s'",
2088 0           (int)(s - pre - 1), pre, s, s0);
2089             }
2090 142           s++; /* Skip ',' */
2091             }
2092             else
2093 1509 100         if (*s == 'G' || *s == '&' || *s == 'n'
    100          
    100          
2094 86 50         || *s == 'P' || *s == 'r' || *s == 's'
    50          
    50          
2095 86 50         || *s == 'E' || *s == 'I' || *s == 'V')
    50          
    50          
2096             break;
2097 316 50         while (*s && *s++ != ',');
    100          
2098 228 100         if (!s[0] && s[-1] != ',') {
    50          
2099             unrecognized_syntax:
2100 0           croak("Unexpected syntax of default argument '%s' in prototype '%s'",
2101             pre - 1, s0);
2102             }
2103 228           break;
2104              
2105             #if PARI_VERSION_EXP < 2004002
2106             case 'P': /* series precision */
2107 2           argvec[i++] = (GEN) precdl;
2108 2           break;
2109             #endif
2110              
2111             case 'f': /* Fake *long argument */
2112 0           argvec[i++] = (GEN) &fake;
2113 0           break;
2114              
2115             case 'x': /* Foreign function */
2116 0           croak("Calling Perl via PARI with an unknown interface: avoiding loop");
2117             break;
2118              
2119             case 'l': /* Return long */
2120 32           *rettype = RETTYPE_LONG; break;
2121              
2122             case 'i': /* Return int */
2123 4           *rettype = RETTYPE_INT; break;
2124              
2125             case 'v': /* Return void */
2126 16           *rettype = RETTYPE_VOID; break;
2127              
2128             case '\n': /* Mneumonic starts */
2129 4 50         if (saw_M) {
2130 4           s = ""; /* Finish processing */
2131 4           break;
2132             }
2133             /* FALL THROUGH */
2134             default:
2135 0           croak("Unsupported code '%.1s' in signature '%s' of a PARI function `%s'", s-1, s0, ep->name);
2136             }
2137 12443 50         if (j > items)
2138 0           croak("Too few args %d for PARI function `%s'", items, ep->name);
2139             }
2140 1946 50         if (j < items)
2141 0           croak("%d unused args for PARI function %s of signature `%s' (with %d args)", items - j, ep->name, ep->code, j);
2142             /* if (j>=1)
2143             dbgGEN(argvec[2],j-1); */
2144             args_done: {
2145             #if PURIFY
2146             for ( ; i
2147             #endif
2148             }
2149 1946           }
2150              
2151             static void
2152 2           fill_outvect(SV **sv_OUT, GEN *gen_OUT, long c, pari_sp oldavma)
2153             {
2154 4 100         while (c-- > 0)
2155 2           resetSVpari(sv_OUT[c], gen_OUT[c], oldavma);
2156 2           }
2157              
2158             #define _to_int(in,dummy1,dummy2) to_int(in)
2159              
2160             static GEN
2161 1           to_int(GEN in)
2162             {
2163 1           long sign = gcmp(in,gen_0);
2164              
2165 1 50         if (!sign)
2166 0           return gen_0;
2167 1           switch (typ(in)) {
2168             case t_INT:
2169             #if PARI_VERSION_EXP < 2002008
2170             case t_SMALL:
2171             #endif
2172 0           return in;
2173             case t_INTMOD:
2174 0           return lift0(in, -1); /* -1: not as polmod */
2175             default:
2176 1           return gtrunc(in);
2177             }
2178             }
2179              
2180             typedef int (*FUNC_PTR)();
2181             typedef void (*TSET_FP)(char *s);
2182              
2183             #ifdef NO_HIGHLEVEL_PARI
2184             # define NO_GRAPHICS_PARI
2185             # define have_highlevel() 0
2186             #else
2187             # define have_highlevel() 1
2188             #endif
2189              
2190             #ifdef NO_GNUPLOT_PARI
2191             # define have_graphics() -1
2192             # define set_gnuterm(a,b,c) croak("This build of Math::Pari has no Gnuplot plotting support")
2193             # define int_set_term_ftable(a) croak("This build of Math::Pari has no Gnuplot plotting support")
2194             #else
2195             # ifdef NO_GRAPHICS_PARI
2196             # define have_graphics() 0
2197             # define set_gnuterm(a,b,c) croak("This build of Math::Pari has no plotting support")
2198             # define int_set_term_ftable(a) croak("This build of Math::Pari has no plotting support")
2199             # else
2200             # define have_graphics() 1
2201             # if PARI_VERSION_EXP < 2000013
2202             # define set_gnuterm(a,b,c) \
2203             set_term_funcp((FUNC_PTR)(a),(struct termentry *)(b))
2204             # else /* !( PARI_VERSION_EXP < 2000013 ) */
2205             # define set_gnuterm(a,b,c) \
2206             set_term_funcp3((FUNC_PTR)(INT2PTR(void*, a)), INT2PTR(struct termentry *, b), INT2PTR(TSET_FP,c))
2207             extern void set_term_funcp3(FUNC_PTR change_p, void *term_p, TSET_FP tchange);
2208              
2209             # endif /* PARI_VERSION_EXP < 2000013 */
2210              
2211             # define int_set_term_ftable(a) (v_set_term_ftable(INT2PTR(void*,a)))
2212             # endif
2213             #endif
2214              
2215             extern void v_set_term_ftable(void *a);
2216              
2217             /* Cast off `const' */
2218             #define s_type_name(x) (char *)type_name(typ(x));
2219              
2220             static int reset_on_reload = 0;
2221              
2222             int
2223 0           s_reset_on_reload(int newvalue)
2224             {
2225 0           int old = reset_on_reload;
2226 0 0         if (newvalue >= 0)
2227 0           reset_on_reload = newvalue;
2228 0           return old;
2229             }
2230              
2231             static int
2232 10893           isPariFunction(entree *ep)
2233             {
2234             #if PARI_VERSION_EXP < 2004000
2235 10893           return EpVALENCE(ep) < EpUSER;
2236             /* && ep>=fonctions && ep < fonctions+NUMFUNC) */
2237             #else /* !( PARI_VERSION_EXP < 2004000) */
2238             return (EpVALENCE(ep) == 0 || (EpVALENCE(ep) != EpNEW && typ((GEN)(ep->value))==t_CLOSURE)); /* == EpVAR */
2239             #endif /* !( PARI_VERSION_EXP < 2004000) */
2240             }
2241              
2242             #if 1
2243             # define checkPariFunction(arg)
2244             #else
2245             void
2246             checkPariFunction(const char *name)
2247             {
2248             long hash;
2249             entree *ep = is_entry_intern(name, functions_hash, &hash);
2250             warn( "Ep for `%s': VALENCE=%#04x, EpVAR=%d, EpINSTALL=%d, name=<%s>, code=<%s>, isFunction=%d", name, (ep ? (int)EpVALENCE(ep) : 0xDEAD),
2251             (int)EpVAR, (int)EpINSTALL, (ep ? ep->name : ""),
2252             ((ep && ep->code) ? ep->code : ""), (ep && isPariFunction(ep)));
2253             }
2254             #endif
2255              
2256             #if PARI_VERSION_EXP < 2008000 /* Need to recheck with each new major release??? See src/desc/gen_proto, src/test/32/help */
2257             # define TAG_community 12 /* "The PARI community" */
2258             #else /* !(PARI_VERSION_EXP < 2008000) */
2259             # if PARI_VERSION_EXP < 2010000
2260             # define TAG_community 15 /* "The PARI community" */
2261             # else /* !(PARI_VERSION_EXP < 2010000) */
2262             # if PARI_VERSION_EXP < 2014000
2263             # define TAG_community 17 /* "The PARI community" */
2264             # else /* !(PARI_VERSION_EXP < 2012000) */
2265             # define TAG_community TAG_community_unknown___needs_to_be_checked_for_every_new_version__see__GPbuilddir_src_test_32_help
2266             # endif /* !(PARI_VERSION_EXP < 2012000) */
2267             # endif /* !(PARI_VERSION_EXP < 2010000) */
2268             #endif /* !(PARI_VERSION_EXP < 2008000) */
2269              
2270             # define INTERNAL_TAG_start (TAG_community+1) /* symbolic_operators */
2271             # define INTERNAL_TAG_end (TAG_community+3) /* programming/internals (in between: member_functions) */
2272              
2273             int
2274 11060           _is_internal(int tag)
2275             { /* from gp_rl.c */
2276             #if PARI_VERSION_EXP < 2004000
2277 11060           return 0;
2278             #else /* !( PARI_VERSION_EXP < 2004000) */
2279             return tag >= INTERNAL_TAG_start && tag <= INTERNAL_TAG_end;
2280             #endif /* !( PARI_VERSION_EXP < 2004000) */
2281             }
2282              
2283             char *
2284 0           added_sections()
2285             {
2286             #if PARI_VERSION_EXP < 2013000
2287             /* Suggestion on format (part of 2.10.0), only use short names: "4: functions related to COMBINATORICS\n13: L-FUNCTIONS" */
2288 0           return "";
2289             #else /* !( PARI_VERSION_EXP < 2011000) */
2290             /* Check by entering "?" at gp prompt. Compare with the list in Pari.pm */
2291             croak("Do not know which \"sections\" (of list of functions) were added to PARI at v2.11.0");
2292             #endif /* !( PARI_VERSION_EXP < 2011000) */
2293             }
2294              
2295              
2296             #if PARI_VERSION_EXP >= 2006000 /* taken from 2.5.5 */
2297             static GEN
2298             gand(GEN x, GEN y) { return gequal0(x)? gen_0: (gequal0(y)? gen_0: gen_1); }
2299              
2300             static GEN
2301             gor(GEN x, GEN y) { return gequal0(x)? (gequal0(y)? gen_0: gen_1): gen_1; }
2302             #endif /* PARI_VERSION_EXP >= 2006000 */
2303              
2304              
2305             MODULE = Math::Pari PACKAGE = Math::Pari PREFIX = Arr_
2306              
2307             PROTOTYPES: ENABLE
2308              
2309             GEN
2310             Arr_FETCH(g,n)
2311             long oldavma=avma;
2312             GEN g
2313             I32 n
2314              
2315             void
2316             Arr_STORE(g,n,elt)
2317             long oldavma=avma;
2318             GEN g
2319             I32 n
2320             GEN elt
2321             CLEANUP:
2322 4           avma=oldavma;
2323              
2324             I32
2325             Arr_FETCHSIZE(g)
2326             long oldavma=avma;
2327             GEN g
2328             CLEANUP:
2329 0           avma=oldavma;
2330              
2331             I32
2332             Arr_EXISTS(g,elt)
2333             long oldavma=avma;
2334             GEN g
2335             long elt
2336             CLEANUP:
2337 0           avma=oldavma;
2338              
2339             MODULE = Math::Pari PACKAGE = Math::Pari
2340              
2341             PROTOTYPES: ENABLE
2342              
2343             int
2344             is_gnil(in)
2345             GEN in
2346              
2347             GEN
2348             sv2pari(sv)
2349             long oldavma=avma;
2350             SV * sv
2351              
2352             GEN
2353             sv2parimat(sv)
2354             long oldavma=avma;
2355             SV * sv
2356              
2357             SV *
2358             pari2iv(in)
2359             long oldavma=avma;
2360             GEN in
2361             CLEANUP:
2362 7           avma=oldavma;
2363              
2364             SV *
2365             pari2nv(in)
2366             long oldavma=avma;
2367             GEN in
2368             CLEANUP:
2369 1           avma=oldavma;
2370              
2371             SV *
2372             pari2num_(in,...)
2373             long oldavma=avma;
2374             GEN in
2375             CODE:
2376 1482 50         if (typ(in) == t_INT) {
2377 1482           RETVAL=pari2iv(in);
2378             } else {
2379 0           RETVAL=pari2nv(in);
2380             }
2381             OUTPUT:
2382             RETVAL
2383             CLEANUP:
2384 1482           avma=oldavma;
2385              
2386             SV *
2387             pari2num(in)
2388             long oldavma=avma;
2389             GEN in
2390             CODE:
2391 0 0         if (typ(in) == t_INT) {
2392 0           RETVAL=pari2iv(in);
2393             } else {
2394 0           RETVAL=pari2nv(in);
2395             }
2396             OUTPUT:
2397             RETVAL
2398             CLEANUP:
2399 0           avma=oldavma;
2400              
2401             SV *
2402             pari2pv(in,...)
2403             long oldavma=avma;
2404             GEN in
2405             CODE:
2406 547           RETVAL=pari2pv(in);
2407             OUTPUT:
2408             RETVAL
2409             CLEANUP:
2410 547           avma=oldavma;
2411              
2412             GEN
2413             _to_int(in, dummy1, dummy2)
2414             long oldavma=avma;
2415             GEN in
2416             SV *dummy1 = NO_INIT
2417             SV *dummy2 = NO_INIT
2418             CODE:
2419             PERL_UNUSED_VAR(dummy1); /* -W */
2420             PERL_UNUSED_VAR(dummy2); /* -W */
2421 1           RETVAL = _to_int(in, dummy1, dummy2);
2422             OUTPUT:
2423             RETVAL
2424              
2425             GEN
2426             PARI(...)
2427             long oldavma=avma;
2428             CODE:
2429 10495 50         if (items==1) {
2430 10495           RETVAL=sv2pari(ST(0));
2431             } else {
2432             int i;
2433              
2434 0           RETVAL=cgetg(items+1, t_VEC);
2435 0 0         for (i=0;i
2436 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2437             }
2438             }
2439             OUTPUT:
2440             RETVAL
2441              
2442             GEN
2443             PARIcol(...)
2444             long oldavma=avma;
2445             CODE:
2446 3 50         if (items==1) {
2447 3           RETVAL=sv2pari(ST(0));
2448 3 50         if (t_VEC == typ(RETVAL))
2449 3           settyp(RETVAL, t_COL);
2450             } else {
2451             int i;
2452              
2453 0           RETVAL=cgetg(items+1, t_VEC);
2454 0 0         for (i=0;i
2455 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2456             }
2457 0           settyp(RETVAL, t_COL);
2458             }
2459             OUTPUT:
2460             RETVAL
2461              
2462             GEN
2463             PARIvecL(...)
2464             long oldavma=avma;
2465             CODE:
2466             int i;
2467              
2468 0           RETVAL=cgetg(items+1, t_VEC);
2469 0 0         for (i=0;i
2470 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2471             }
2472             OUTPUT:
2473             RETVAL
2474              
2475             GEN
2476             PARIcolL(...)
2477             long oldavma=avma;
2478             CODE:
2479             int i;
2480              
2481 4           RETVAL=cgetg(items+1, t_VEC);
2482 21 100         for (i=0;i
2483 17           RETVAL[i+1]=(long)sv2pari(ST(i));
2484             }
2485 4           settyp(RETVAL, t_COL);
2486             OUTPUT:
2487             RETVAL
2488              
2489             GEN
2490             PARImat(...)
2491             long oldavma=avma;
2492             CODE:
2493 62 50         if (items==1) {
2494 62           RETVAL=sv2parimat(ST(0));
2495             } else {
2496             int i;
2497              
2498 0           RETVAL=cgetg(items+1, t_MAT);
2499 0 0         for (i=0;i
2500 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2501 0 0         if (t_VEC == typ((GEN)(RETVAL[i+1]))) {
2502 0           settyp(RETVAL[i+1], t_COL);
2503 0 0         } else if (t_COL != typ((GEN)(RETVAL[i+1]))) {
2504 0           croak("%ld'th argument (of %ld) to PARImat() is not a vector", (long)i, (long)items);
2505             }
2506             }
2507             }
2508             OUTPUT:
2509             RETVAL
2510              
2511             GEN
2512             PARImatL(...)
2513             long oldavma=avma;
2514             CODE:
2515             int i;
2516              
2517 0           RETVAL=cgetg(items+1, t_MAT);
2518 0 0         for (i=0;i
2519 0           RETVAL[i+1]=(long)sv2pari(ST(i));
2520 0 0         if (t_VEC == typ((GEN)(RETVAL[i+1]))) {
2521 0           settyp(RETVAL[i+1], t_COL);
2522 0 0         } else if (t_COL != typ((GEN)(RETVAL[i+1]))) {
2523 0           croak("%ld'th argument (of %ld) to PARImatL() is not a vector", (long)i, (long)items);
2524             }
2525             }
2526             OUTPUT:
2527             RETVAL
2528              
2529             void
2530             installPerlFunctionCV(cv, name, numargs = 1, help = NULL)
2531             SV* cv
2532             char *name
2533             I32 numargs
2534             char *help
2535             PROTOTYPE: DISABLE
2536              
2537             # In what follows if a function returns long, we do not need anything
2538             # on the stack, thus we add a cleanup section.
2539              
2540             void
2541             interface_flexible_void(...)
2542             long oldavma=avma;
2543             CODE:
2544             {
2545 16           entree *ep = (entree *) XSANY.any_dptr;
2546 16           void (*FUNCTION_real)(VARARG)
2547 16           = (void (*)(VARARG))ep->value;
2548             GEN argvec[ARGS_SUPPORTED];
2549 16           long rettype = RETTYPE_GEN;
2550 16           long has_pointer = 0; /* XXXX ?? */
2551             long OUT_cnt;
2552             SV *sv_OUT[ARGS_SUPPORTED];
2553             GEN gen_OUT[ARGS_SUPPORTED];
2554              
2555 16           fill_argvect(ep, ep->code, &has_pointer, argvec, &rettype, &ST(0), items,
2556             sv_OUT, gen_OUT, &OUT_cnt);
2557              
2558 16 50         if (rettype != RETTYPE_VOID)
2559 0           croak("Expected VOID return type, got code '%s'", ep->code);
2560            
2561 16           (FUNCTION_real)(THE_ARGS_SUPPORTED);
2562 14 50         if (has_pointer)
2563 0           check_pointer(has_pointer,argvec);
2564 14 50         if (OUT_cnt)
2565 0           fill_outvect(sv_OUT, gen_OUT, OUT_cnt, oldavma);
2566             }
2567              
2568             GEN
2569             interface_flexible_gen(...)
2570             long oldavma=avma;
2571             CODE:
2572             {
2573 1894           entree *ep = (entree *) XSANY.any_dptr;
2574 1894           GEN (*FUNCTION_real)(VARARG)
2575 1894           = (GEN (*)(VARARG))ep->value;
2576             GEN argvec[9];
2577 1894           long rettype = RETTYPE_GEN;
2578 1894           long has_pointer = 0; /* XXXX ?? */
2579             long OUT_cnt;
2580             SV *sv_OUT[ARGS_SUPPORTED];
2581             GEN gen_OUT[ARGS_SUPPORTED];
2582              
2583 1894           fill_argvect(ep, ep->code, &has_pointer, argvec, &rettype, &ST(0), items,
2584             sv_OUT, gen_OUT, &OUT_cnt);
2585              
2586 1894 50         if (rettype != RETTYPE_GEN)
2587 0           croak("Expected GEN return type, got code '%s'", ep->code);
2588            
2589 1894           RETVAL = (FUNCTION_real)(THE_ARGS_SUPPORTED);
2590 1889 50         if (has_pointer)
2591 0           check_pointer(has_pointer,argvec);
2592 1889 100         if (OUT_cnt)
2593 2           fill_outvect(sv_OUT, gen_OUT, OUT_cnt, oldavma);
2594             }
2595             OUTPUT:
2596             RETVAL
2597              
2598             long
2599             interface_flexible_long(...)
2600             long oldavma=avma;
2601             CODE:
2602             {
2603 32           entree *ep = (entree *) XSANY.any_dptr;
2604 32           long (*FUNCTION_real)(VARARG)
2605 32           = (long (*)(VARARG))ep->value;
2606             GEN argvec[9];
2607 32           long rettype = RETTYPE_GEN;
2608 32           long has_pointer = 0; /* XXXX ?? */
2609             long OUT_cnt;
2610             SV *sv_OUT[ARGS_SUPPORTED];
2611             GEN gen_OUT[ARGS_SUPPORTED];
2612              
2613 32           fill_argvect(ep, ep->code, &has_pointer, argvec, &rettype, &ST(0), items,
2614             sv_OUT, gen_OUT, &OUT_cnt);
2615              
2616 32 50         if (rettype != RETTYPE_LONG)
2617 0           croak("Expected long return type, got code '%s'", ep->code);
2618            
2619 32           RETVAL = FUNCTION_real(THE_ARGS_SUPPORTED);
2620 32 50         if (has_pointer)
2621 0           check_pointer(has_pointer,argvec);
2622 32 50         if (OUT_cnt)
2623 0           fill_outvect(sv_OUT, gen_OUT, OUT_cnt, oldavma);
2624             }
2625             OUTPUT:
2626             RETVAL
2627              
2628             int
2629             interface_flexible_int(...)
2630             long oldavma=avma;
2631             CODE:
2632             {
2633 4           entree *ep = (entree *) XSANY.any_dptr;
2634 4           int (*FUNCTION_real)(VARARG)
2635 4           = (int (*)(VARARG))ep->value;
2636             GEN argvec[9];
2637 4           long rettype = RETTYPE_GEN;
2638 4           long has_pointer = 0; /* XXXX ?? */
2639             long OUT_cnt;
2640             SV *sv_OUT[ARGS_SUPPORTED];
2641             GEN gen_OUT[ARGS_SUPPORTED];
2642              
2643 4           fill_argvect(ep, ep->code, &has_pointer, argvec, &rettype, &ST(0), items,
2644             sv_OUT, gen_OUT, &OUT_cnt);
2645              
2646 4 50         if (rettype != RETTYPE_INT)
2647 0           croak("Expected int return type, got code '%s'", ep->code);
2648            
2649 4           RETVAL=FUNCTION_real(argvec[0], argvec[1], argvec[2], argvec[3],
2650             argvec[4], argvec[5], argvec[6], argvec[7], argvec[8]);
2651 4 50         if (has_pointer)
2652 0           check_pointer(has_pointer,argvec);
2653 4 50         if (OUT_cnt)
2654 0           fill_outvect(sv_OUT, gen_OUT, OUT_cnt, oldavma);
2655             }
2656             OUTPUT:
2657             RETVAL
2658              
2659             GEN
2660             interface0()
2661             long oldavma=avma;
2662             CODE:
2663             {
2664 56           dFUNCTION(GEN);
2665              
2666 56 50         if (!FUNCTION) {
2667 0           croak("XSUB call through interface did not provide *function");
2668             }
2669              
2670 56           RETVAL=FUNCTION(prec_words);
2671             }
2672             OUTPUT:
2673             RETVAL
2674              
2675             GEN
2676             interface9900()
2677             long oldavma=avma;
2678             CODE:
2679             { /* Code="" */
2680 764           dFUNCTION(GEN);
2681              
2682 764 50         if (!FUNCTION) {
2683 0           croak("XSUB call through interface did not provide *function");
2684             }
2685              
2686 764           RETVAL=FUNCTION();
2687             }
2688             OUTPUT:
2689             RETVAL
2690              
2691             GEN
2692             interface1(arg1)
2693             long oldavma=avma;
2694             GEN arg1
2695             CODE:
2696             { /* Code="Gp" */
2697 45787           dFUNCTION(GEN);
2698              
2699 45787 50         if (!FUNCTION) {
2700 0           croak("XSUB call through interface did not provide *function");
2701             }
2702              
2703 45787           RETVAL=FUNCTION(arg1,prec_words);
2704             }
2705             OUTPUT:
2706             RETVAL
2707              
2708             # with fake arguments for overloading
2709              
2710             GEN
2711             interface199(arg1,arg2,inv)
2712             long oldavma=avma;
2713             GEN arg1
2714             GEN arg2 = NO_INIT
2715             long inv = NO_INIT
2716             CODE:
2717             {
2718 30008           dFUNCTION(GEN);
2719              
2720 30008 50         if (!FUNCTION) {
2721 0           croak("XSUB call through interface did not provide *function");
2722             }
2723              
2724             PERL_UNUSED_VAR(arg2); /* -W */
2725             PERL_UNUSED_VAR(inv); /* -W */
2726 30008           RETVAL=FUNCTION(arg1,prec_words);
2727             }
2728             OUTPUT:
2729             RETVAL
2730              
2731             long
2732             interface10(arg1)
2733             long oldavma=avma;
2734             GEN arg1
2735             CODE:
2736             { /* Code="lG" */
2737 7           dFUNCTION(long);
2738              
2739 7 50         if (!FUNCTION) {
2740 0           croak("XSUB call through interface did not provide *function");
2741             }
2742              
2743 7           RETVAL=FUNCTION(arg1);
2744             }
2745             OUTPUT:
2746             RETVAL
2747             CLEANUP:
2748 7           avma=oldavma;
2749              
2750             # With fake arguments for overloading
2751              
2752             long
2753             interface109(arg1,arg2,inv)
2754             long oldavma=avma;
2755             GEN arg1
2756             GEN arg2 = NO_INIT
2757             long inv = NO_INIT
2758             CODE:
2759             {
2760 0           dFUNCTION(long);
2761              
2762 0 0         if (!FUNCTION) {
2763 0           croak("XSUB call through interface did not provide *function");
2764             }
2765              
2766             PERL_UNUSED_VAR(arg2); /* -W */
2767             PERL_UNUSED_VAR(inv); /* -W */
2768 0           RETVAL=FUNCTION(arg1);
2769             }
2770             OUTPUT:
2771             RETVAL
2772             CLEANUP:
2773 0           avma=oldavma;
2774              
2775             GEN
2776             interface11(arg1)
2777             long oldavma=avma;
2778             long arg1
2779             CODE:
2780             { /* Code="L" */
2781 32           dFUNCTION(GEN);
2782              
2783 32 50         if (!FUNCTION) {
2784 0           croak("XSUB call through interface did not provide *function");
2785             }
2786              
2787 32           RETVAL=FUNCTION(arg1);
2788             }
2789             OUTPUT:
2790             RETVAL
2791              
2792             long
2793             interface15(arg1)
2794             long oldavma=avma;
2795             long arg1
2796             CODE:
2797             {
2798 0           dFUNCTION(long);
2799              
2800 0 0         if (!FUNCTION) {
2801 0           croak("XSUB call through interface did not provide *function");
2802             }
2803              
2804 0           RETVAL=FUNCTION(arg1);
2805             }
2806             OUTPUT:
2807             RETVAL
2808             CLEANUP:
2809 0           avma=oldavma;
2810              
2811             GEN
2812             interface18(arg1)
2813             long oldavma=avma;
2814             GEN arg1
2815             CODE:
2816             { /* Code="G" */
2817 173           dFUNCTION(GEN);
2818              
2819 173 50         if (!FUNCTION) {
2820 0           croak("XSUB call through interface did not provide *function");
2821             }
2822              
2823 173           RETVAL=FUNCTION(arg1);
2824             }
2825             OUTPUT:
2826             RETVAL
2827              
2828             GEN
2829             interface2(arg1,arg2)
2830             long oldavma=avma;
2831             GEN arg1
2832             GEN arg2
2833             CODE:
2834             { /* Code="GG" */
2835 320           dFUNCTION(GEN);
2836              
2837 320 50         if (!FUNCTION) {
2838 0           croak("XSUB call through interface did not provide *function");
2839             }
2840              
2841 320           RETVAL=FUNCTION(arg1,arg2);
2842             }
2843             OUTPUT:
2844             RETVAL
2845              
2846             # With fake arguments for overloading
2847              
2848             GEN
2849             interface299(arg1,arg2,inv)
2850             long oldavma=avma;
2851             GEN arg1
2852             GEN arg2
2853             bool inv
2854             CODE:
2855             {
2856 8934971           dFUNCTION(GEN);
2857              
2858 8934971 50         if (!FUNCTION) {
2859 0           croak("XSUB call through interface did not provide *function");
2860             }
2861              
2862 8934971 100         RETVAL = inv? FUNCTION(arg2,arg1): FUNCTION(arg1,arg2);
2863             }
2864             OUTPUT:
2865             RETVAL
2866              
2867             long
2868             interface20(arg1,arg2)
2869             long oldavma=avma;
2870             GEN arg1
2871             GEN arg2
2872             CODE:
2873             { /* Code="lGG" */
2874 4           dFUNCTION(long);
2875              
2876 4 50         if (!FUNCTION) {
2877 0           croak("XSUB call through interface did not provide *function");
2878             }
2879              
2880 4           RETVAL=FUNCTION(arg1,arg2);
2881             }
2882             OUTPUT:
2883             RETVAL
2884             CLEANUP:
2885 4           avma=oldavma;
2886              
2887             # With fake arguments for overloading and comparison to gen_1 for speed
2888              
2889             long
2890             interface2099(arg1,arg2,inv)
2891             long oldavma=avma;
2892             GEN arg1
2893             GEN arg2
2894             bool inv
2895             CODE:
2896             {
2897 102           dFUNCTION(GEN);
2898              
2899 102 50         if (!FUNCTION) {
2900 0           croak("XSUB call through interface did not provide *function");
2901             }
2902              
2903 102 100         RETVAL = (inv? FUNCTION(arg2,arg1): FUNCTION(arg1,arg2)) == gen_1;
2904             }
2905             OUTPUT:
2906             RETVAL
2907             CLEANUP:
2908 102           avma=oldavma;
2909              
2910             # With fake arguments for overloading
2911              
2912             long
2913             interface209(arg1,arg2,inv)
2914             long oldavma=avma;
2915             GEN arg1
2916             GEN arg2
2917             bool inv
2918             CODE:
2919             {
2920 0           dFUNCTION(long);
2921              
2922 0 0         if (!FUNCTION) {
2923 0           croak("XSUB call through interface did not provide *function");
2924             }
2925              
2926 0 0         RETVAL = inv? FUNCTION(arg2,arg1): FUNCTION(arg1,arg2);
2927             }
2928             OUTPUT:
2929             RETVAL
2930             CLEANUP:
2931 0           avma=oldavma;
2932              
2933             # With fake arguments for overloading, int return
2934              
2935             int
2936             interface2091(arg1,arg2,inv)
2937             long oldavma=avma;
2938             GEN arg1
2939             GEN arg2
2940             bool inv
2941             CODE:
2942             {
2943 20           dFUNCTION(int);
2944              
2945 20 50         if (!FUNCTION) {
2946 0           croak("XSUB call through interface did not provide *function");
2947             }
2948              
2949 20 100         RETVAL = inv? FUNCTION(arg2,arg1): FUNCTION(arg1,arg2);
2950             }
2951             OUTPUT:
2952             RETVAL
2953             CLEANUP:
2954 20           avma=oldavma;
2955              
2956             GEN
2957             interface29(arg1,arg2)
2958             long oldavma=avma;
2959             GEN arg1
2960             GEN arg2
2961             CODE:
2962             { /* Code="GGp" */
2963 13           dFUNCTION(GEN);
2964              
2965 13 50         if (!FUNCTION) {
2966 0           croak("XSUB call through interface did not provide *function");
2967             }
2968              
2969 13           RETVAL=FUNCTION(arg1,arg2,prec_words);
2970             }
2971             OUTPUT:
2972             RETVAL
2973              
2974             GEN
2975             interface3(arg1,arg2,arg3)
2976             long oldavma=avma;
2977             GEN arg1
2978             GEN arg2
2979             GEN arg3
2980             CODE:
2981             { /* Code="GGG" */
2982 20           dFUNCTION(GEN);
2983              
2984 20 50         if (!FUNCTION) {
2985 0           croak("XSUB call through interface did not provide *function");
2986             }
2987              
2988 20           RETVAL=FUNCTION(arg1,arg2,arg3);
2989             }
2990             OUTPUT:
2991             RETVAL
2992              
2993             long
2994             interface30(arg1,arg2,arg3)
2995             long oldavma=avma;
2996             GEN arg1
2997             GEN arg2
2998             GEN arg3
2999             CODE:
3000             { /* Code="lGGG" */
3001 2           dFUNCTION(long);
3002              
3003 2 50         if (!FUNCTION) {
3004 0           croak("XSUB call through interface did not provide *function");
3005             }
3006              
3007 2           RETVAL=FUNCTION(arg1,arg2,arg3);
3008             }
3009             OUTPUT:
3010             RETVAL
3011             CLEANUP:
3012 2           avma=oldavma;
3013              
3014             GEN
3015             interface4(arg1,arg2,arg3,arg4)
3016             long oldavma=avma;
3017             GEN arg1
3018             GEN arg2
3019             GEN arg3
3020             GEN arg4
3021             CODE:
3022             { /* Code="GGGG" */
3023 0           dFUNCTION(GEN);
3024              
3025 0 0         if (!FUNCTION) {
3026 0           croak("XSUB call through interface did not provide *function");
3027             }
3028              
3029 0           RETVAL=FUNCTION(arg1,arg2,arg3,arg4);
3030             }
3031             OUTPUT:
3032             RETVAL
3033              
3034             GEN
3035             interface5(arg1,arg2,arg3,arg4)
3036             long oldavma=avma;
3037             GEN arg1
3038             GEN arg2
3039             GEN arg3
3040             GEN arg4
3041             CODE:
3042             {
3043 0           dFUNCTION(GEN);
3044              
3045 0 0         if (!FUNCTION) {
3046 0           croak("XSUB call through interface did not provide *function");
3047             }
3048              
3049 0           RETVAL=FUNCTION(arg1,arg2,arg3,arg4,prec_words);
3050             }
3051             OUTPUT:
3052             RETVAL
3053              
3054             GEN
3055             interface12(arg1,arg2)
3056             long oldavma=avma;
3057             GEN arg1
3058             GEN arg2
3059             CODE:
3060             { /* Code="GnP" */
3061 1           dFUNCTION(GEN);
3062              
3063 1 50         if (!FUNCTION) {
3064 0           croak("XSUB call through interface did not provide *function");
3065             }
3066              
3067 1           RETVAL=FUNCTION(arg1,numvar(arg2), precdl);
3068             }
3069             OUTPUT:
3070             RETVAL
3071              
3072             GEN
3073             interface13(arg1, arg2=0, arg3=0)
3074             long oldavma=avma;
3075             GEN arg1
3076             long arg2
3077             GEN arg3
3078             CODE:
3079             { /* Code="GD0,L,DG" */ /* Was: Code="GD0,L,D0,G," */
3080 13           dFUNCTION(GEN);
3081              
3082 13 50         if (!FUNCTION) {
3083 0           croak("XSUB call through interface did not provide *function");
3084             }
3085              
3086 13           RETVAL=FUNCTION(arg1, arg2, arg3);
3087             }
3088             OUTPUT:
3089             RETVAL
3090              
3091             GEN
3092             interface14(arg1,arg2=0)
3093             long oldavma=avma;
3094             GEN arg1
3095             GEN arg2
3096             CODE:
3097             { /* Code="GDn" */
3098 41           dFUNCTION(GEN);
3099              
3100 41 50         if (!FUNCTION) {
3101 0           croak("XSUB call through interface did not provide *function");
3102             }
3103              
3104 41 100         RETVAL=FUNCTION(arg1,arg2 ? numvar(arg2) : -1);
3105             }
3106             OUTPUT:
3107             RETVAL
3108              
3109             GEN
3110             interface21(arg1,arg2)
3111             long oldavma=avma;
3112             GEN arg1
3113             long arg2
3114             CODE:
3115             { /* Code="GL" */
3116 0           dFUNCTION(GEN);
3117              
3118 0 0         if (!FUNCTION) {
3119 0           croak("XSUB call through interface did not provide *function");
3120             }
3121              
3122 0           RETVAL=FUNCTION(arg1,arg2);
3123             }
3124             OUTPUT:
3125             RETVAL
3126              
3127             # With fake arguments for overloading
3128             # This is very hairy: we need to chose the translation of arguments
3129             # depending on the value of inv
3130              
3131             GEN
3132             interface2199(arg1,arg2,inv)
3133             long oldavma=avma;
3134             GEN arg1 = NO_INIT
3135             long arg2 = NO_INIT
3136             bool inv
3137             CODE:
3138             {
3139 2           dFUNCTION(GEN);
3140              
3141 2 50         if (!FUNCTION) {
3142 0           croak("XSUB call through interface did not provide *function");
3143             }
3144 2 100         if (inv) {
3145 1           arg1 = sv2pari(ST(1));
3146 1 50         arg2 = (long)SvIV(ST(0));
3147             } else {
3148 1           arg1 = sv2pari(ST(0));
3149 1 50         arg2 = (long)SvIV(ST(1));
3150             }
3151              
3152 2           RETVAL = FUNCTION(arg1,arg2);
3153             }
3154             OUTPUT:
3155             RETVAL
3156              
3157             GEN
3158             interface22(arg1,arg2,arg3)
3159             long oldavma=avma;
3160             GEN arg1
3161             PariVar arg2
3162             PariExpr arg3
3163             CODE:
3164             { /* Code="GVI" */
3165 1           dFUNCTION(GEN);
3166              
3167 1 50         if (!FUNCTION) {
3168 0           croak("XSUB call through interface did not provide *function");
3169             }
3170             #if PARI_VERSION_EXP >= 2004002
3171             RETVAL = FUNCTION(arg1, arg3); /* XXXX Omit `V' instead of merging it into I/E */
3172             #else
3173 1           RETVAL = FUNCTION(arg1, arg2, arg3);
3174             #endif
3175             }
3176             OUTPUT:
3177             RETVAL
3178              
3179             GEN
3180             interface23(arg1,arg2)
3181             long oldavma=avma;
3182             GEN arg1
3183             long arg2
3184             CODE:
3185             { /* Code="GL" */
3186 10           dFUNCTION(GEN);
3187              
3188 10 50         if (!FUNCTION) {
3189 0           croak("XSUB call through interface did not provide *function");
3190             }
3191              
3192 10           RETVAL=FUNCTION(arg1,arg2);
3193             }
3194             OUTPUT:
3195             RETVAL
3196              
3197             GEN
3198             interface24(arg1,arg2)
3199             long oldavma=avma;
3200             long arg1
3201             GEN arg2
3202             CODE:
3203             { /* Code="LG" */
3204 1           dFUNCTION(GEN);
3205              
3206 1 50         if (!FUNCTION) {
3207 0           croak("XSUB call through interface did not provide *function");
3208             }
3209              
3210 1           RETVAL=FUNCTION(arg1,arg2);
3211             }
3212             OUTPUT:
3213             RETVAL
3214              
3215             GEN
3216             interface25(arg1,arg2,arg3=0)
3217             long oldavma=avma;
3218             GEN arg1
3219             GEN arg2
3220             long arg3
3221             CODE:
3222             { /* Code="GGD0,L," */
3223 75           dFUNCTION(GEN);
3224              
3225 75 50         if (!FUNCTION) {
3226 0           croak("XSUB call through interface did not provide *function");
3227             }
3228              
3229 75           RETVAL=FUNCTION(arg1,arg2,arg3);
3230             }
3231             OUTPUT:
3232             RETVAL
3233              
3234             GEN
3235             interface26(arg1,arg2,arg3)
3236             long oldavma=avma;
3237             GEN arg1
3238             GEN arg2
3239             GEN arg3
3240             CODE:
3241             { /* Code="GnG" */
3242 2           dFUNCTION(GEN);
3243              
3244 2 50         if (!FUNCTION) {
3245 0           croak("XSUB call through interface did not provide *function");
3246             }
3247              
3248 2           RETVAL=FUNCTION(arg1, numvar(arg2), arg3);
3249             }
3250             OUTPUT:
3251             RETVAL
3252              
3253             GEN
3254             interface27(arg1,arg2,arg3)
3255             long oldavma=avma;
3256             PariVar arg1
3257             GEN arg2
3258             PariExpr arg3
3259             CODE:
3260             { /* Code="V=GIp" */
3261 2           dFUNCTION(GEN);
3262              
3263 2 50         if (!FUNCTION) {
3264 0           croak("XSUB call through interface did not provide *function");
3265             }
3266             #if PARI_VERSION_EXP >= 2004002
3267             RETVAL=FUNCTION(arg2, arg3, prec_words); /* XXXX Omit `V' instead of merging it into I/E */
3268             #else
3269 2           RETVAL=FUNCTION(arg1, arg2, arg3, prec_words);
3270             #endif
3271             }
3272             OUTPUT:
3273             RETVAL
3274              
3275             GEN
3276             interface28(arg1,arg2=0,arg3=0)
3277             long oldavma=avma;
3278             GEN arg1
3279             PariVar arg2
3280             PariExpr arg3
3281             CODE:
3282             { /* Code="GDVDI" */
3283 74           dFUNCTION(GEN);
3284              
3285 74 50         if (!FUNCTION) {
3286 0           croak("XSUB call through interface did not provide *function");
3287             }
3288             #if PARI_VERSION_EXP >= 2004002
3289             RETVAL = FUNCTION(arg1, arg3); /* XXXX Omit `V' instead of merging it into I/E */
3290             #else
3291 74           RETVAL = FUNCTION(arg1, arg2, arg3);
3292             #endif
3293             }
3294             OUTPUT:
3295             RETVAL
3296              
3297             GEN
3298             interface28_old(arg1,arg2)
3299             long oldavma=avma;
3300             GEN arg1
3301             GEN arg2
3302             CODE:
3303             {
3304             long junk;
3305 0           dFUNCTION(GEN);
3306              
3307 0 0         if (!FUNCTION) {
3308 0           croak("XSUB call through interface did not provide *function");
3309             }
3310              
3311 0           RETVAL=FUNCTION(arg1, arg2, &junk);
3312             }
3313             OUTPUT:
3314             RETVAL
3315              
3316             long
3317             interface29_old(arg1,arg2)
3318             long oldavma=avma;
3319             GEN arg1
3320             long arg2
3321             CODE:
3322             {
3323 0           dFUNCTION(long);
3324              
3325 0 0         if (!FUNCTION) {
3326 0           croak("XSUB call through interface did not provide *function");
3327             }
3328              
3329 0           RETVAL=FUNCTION(arg1,arg2);
3330             }
3331             OUTPUT:
3332             RETVAL
3333             CLEANUP:
3334 0           avma=oldavma;
3335              
3336             GEN
3337             interface31(arg1,arg2=0,arg3=0,arg4=0)
3338             long oldavma=avma;
3339             GEN arg1
3340             GEN arg2
3341             GEN arg3
3342             GEN arg4
3343             CODE:
3344             { /* Code="GDGDGD&" */
3345 1           dFUNCTION(GEN);
3346              
3347 1 50         if (!FUNCTION) {
3348 0           croak("XSUB call through interface did not provide *function");
3349             }
3350              
3351 1 50         RETVAL=FUNCTION(arg1, arg2, arg3, arg4 ? &arg4 : NULL);
3352             }
3353             OUTPUT:
3354             RETVAL
3355              
3356             GEN
3357             interface32(arg1,arg2,arg3)
3358             long oldavma=avma;
3359             GEN arg1
3360             GEN arg2
3361             long arg3
3362             CODE:
3363             { /* Code="GGL" */
3364 1           dFUNCTION(GEN);
3365              
3366 1 50         if (!FUNCTION) {
3367 0           croak("XSUB call through interface did not provide *function");
3368             }
3369              
3370 1           RETVAL=FUNCTION(arg1,arg2,arg3);
3371             }
3372             OUTPUT:
3373             RETVAL
3374              
3375             GEN
3376             interface33(arg1,arg2,arg3,arg4=0)
3377             long oldavma=avma;
3378             GEN arg1
3379             GEN arg2
3380             GEN arg3
3381             long arg4
3382             CODE:
3383             { /* Code="GGGD0,L,p" */
3384 5           dFUNCTION(GEN);
3385              
3386 5 50         if (!FUNCTION) {
3387 0           croak("XSUB call through interface did not provide *function");
3388             }
3389              
3390 5           RETVAL=FUNCTION(arg1,arg2,arg3,arg4,prec_words);
3391             }
3392             OUTPUT:
3393             RETVAL
3394              
3395             void
3396             interface34(arg1,arg2,arg3)
3397             long arg1
3398             long arg2
3399             long arg3
3400             CODE:
3401             { /* Code="vLLL" */
3402 0           dFUNCTION(GEN);
3403              
3404 0 0         if (!FUNCTION) {
3405 0           croak("XSUB call through interface did not provide *function");
3406             }
3407              
3408 0           FUNCTION(arg1, arg2, arg3);
3409             }
3410              
3411             void
3412             interface35(arg1,arg2,arg3)
3413             long oldavma=avma;
3414             long arg1
3415             GEN arg2
3416             GEN arg3
3417             CODE:
3418             { /* Code="vLGG" */
3419 26           dFUNCTION(GEN);
3420              
3421 26 50         if (!FUNCTION) {
3422 0           croak("XSUB call through interface did not provide *function");
3423             }
3424              
3425 26           FUNCTION(arg1,arg2,arg3);
3426             }
3427             CLEANUP:
3428 26           avma=oldavma;
3429              
3430             GEN
3431             interface37(arg1,arg2,arg3,arg4)
3432             long oldavma=avma;
3433             PariVar arg1
3434             GEN arg2
3435             GEN arg3
3436             PariExpr arg4
3437             CODE:
3438             { /* Code="V=GGIp" */
3439 2           dFUNCTION(GEN);
3440              
3441 2 50         if (!FUNCTION) {
3442 0           croak("XSUB call through interface did not provide *function");
3443             }
3444             #if PARI_VERSION_EXP >= 2004002
3445             RETVAL=FUNCTION(arg2, arg3, arg4, prec_words); /* XXXX Omit `V' instead of merging it into I/E */
3446             #else
3447 2           RETVAL=FUNCTION(arg1, arg2, arg3, arg4, prec_words);
3448             #endif
3449             }
3450             OUTPUT:
3451             RETVAL
3452              
3453             GEN
3454             interface47(arg1,arg2,arg3,arg4,arg0=0)
3455             long oldavma=avma;
3456             GEN arg0
3457             PariVar arg1
3458             GEN arg2
3459             GEN arg3
3460             PariExpr arg4
3461             CODE:
3462             { /* Code="V=GGIDG" */
3463 137           dFUNCTION(GEN);
3464              
3465 137 50         if (!FUNCTION) {
3466 0           croak("XSUB call through interface did not provide *function");
3467             }
3468             #if PARI_VERSION_EXP >= 2004002
3469             RETVAL=FUNCTION(arg2, arg3, arg4, arg0); /* XXXX Omit `V' instead of merging it into I/E */
3470             #else
3471 137           RETVAL=FUNCTION(arg1, arg2, arg3, arg4, arg0);
3472             #endif
3473             }
3474             OUTPUT:
3475             RETVAL
3476              
3477             GEN
3478             interface48(arg1,arg2,arg3,arg4,arg0=0)
3479             long oldavma=avma;
3480             GEN arg0
3481             PariVar arg1
3482             GEN arg2
3483             GEN arg3
3484             PariExpr arg4
3485             CODE:
3486             { /* Code="V=GGIDG" */
3487 0           dFUNCTION(GEN);
3488              
3489 0 0         if (!FUNCTION) {
3490 0           croak("XSUB call through interface did not provide *function");
3491             }
3492             #if PARI_VERSION_EXP >= 2004002
3493             RETVAL=FUNCTION(arg2, arg3, arg4, arg0); /* XXXX Omit `V' instead of merging it into I/E */
3494             #else
3495 0           RETVAL=FUNCTION(arg1, arg2, arg3, arg4, arg0);
3496             #endif
3497             }
3498             OUTPUT:
3499             RETVAL
3500              
3501             GEN
3502             interface49(arg0,arg00,arg1=0,arg2=0,arg3=0)
3503             long oldavma=avma;
3504             GEN arg0
3505             GEN arg00
3506             PariVar arg1
3507             PariVar arg2
3508             PariExpr2 arg3
3509             CODE:
3510             { /* Code="GGDVDVDI" */
3511 34           dFUNCTION(GEN);
3512 34 50         # arg1 and arg2 may finish to be the same entree*, like after $x=$y=PARIvar 'x'
    0          
3513 0 0         if (arg1 == arg2 && arg1) {
3514 0           if (ST(2) == ST(3))
3515             croak("Same iterator for a double loop");
3516             # ST(3) is localized now
3517             #if PARI_VERSION_EXP >= 2004000
3518 0           croak("Panic (unreachable (?) in a double loop construct)");
3519 0           #else
3520 0           sv_unref(ST(3));
3521             arg2 = findVariable(ST(3),1);
3522             sv_setref_pv(ST(3), "Math::Pari::Ep", (void*)arg2);
3523 34 50         #endif
3524 0           }
3525             if (!FUNCTION) {
3526             croak("XSUB call through interface did not provide *function");
3527             }
3528             #if PARI_VERSION_EXP >= 2004002
3529 34           RETVAL=FUNCTION(arg0, arg00, arg3); /* XXXX Omit two `V's instead of merging them into I/E */
3530             #else
3531             RETVAL=FUNCTION(arg0, arg00, arg1, arg2, arg3);
3532             #endif
3533             }
3534             OUTPUT:
3535             RETVAL
3536              
3537             void
3538             interface83(arg1,arg2,arg3,arg4)
3539             long oldavma=avma;
3540             PariVar arg1
3541             GEN arg2
3542             GEN arg3
3543             PariExprV arg4
3544             CODE:
3545             { /* Code="vV=GGI" */
3546 3           dFUNCTION(void);
3547              
3548 3 50         if (!FUNCTION) {
3549 0           croak("XSUB call through interface did not provide *function");
3550             }
3551             #if PARI_VERSION_EXP >= 2004002
3552             FUNCTION(arg2, arg3, arg4); /* XXXX Omit `V' instead of merging it into I/E */
3553             #else
3554 3           FUNCTION(arg1, arg2, arg3, arg4);
3555             #endif
3556             }
3557             CLEANUP:
3558 3           avma=oldavma;
3559              
3560             void
3561             interface84(arg1,arg2,arg3)
3562             long oldavma=avma;
3563             GEN arg1
3564             PariVar arg2
3565             PariExprV arg3
3566             CODE:
3567             { /* Code="vGVI" */
3568 11           dFUNCTION(void);
3569              
3570 11 50         if (!FUNCTION) {
3571 0           croak("XSUB call through interface did not provide *function");
3572             }
3573             #if PARI_VERSION_EXP >= 2004002
3574             FUNCTION(arg1, arg3); /* XXXX Omit `V' instead of merging it into I/E */
3575             #else
3576 11           FUNCTION(arg1, arg2, arg3);
3577             #endif
3578             }
3579             CLEANUP:
3580 11           avma=oldavma;
3581              
3582             # These interfaces were automatically generated:
3583              
3584             long
3585             interface16(arg1)
3586             long oldavma=avma;
3587             char * arg1
3588             CODE:
3589             { /* Code="ls" */
3590 0           dFUNCTION(long);
3591              
3592 0 0         if (!FUNCTION) {
3593 0           croak("XSUB call through interface did not provide *function");
3594             }
3595              
3596 0           RETVAL=FUNCTION(arg1);
3597             }
3598             OUTPUT:
3599             RETVAL
3600             CLEANUP:
3601 0           avma=oldavma;
3602              
3603             void
3604             interface19(arg1, arg2)
3605             long arg1
3606             long arg2
3607             CODE:
3608             { /* Code="vLL" */
3609 2           dFUNCTION(GEN);
3610              
3611 2 50         if (!FUNCTION) {
3612 0           croak("XSUB call through interface did not provide *function");
3613             }
3614              
3615 2           FUNCTION(arg1, arg2);
3616             }
3617              
3618             GEN
3619             interface44(arg1, arg2, arg3, arg4)
3620             long oldavma=avma;
3621             long arg1
3622             long arg2
3623             long arg3
3624             long arg4
3625             CODE:
3626             {
3627 0           dFUNCTION(GEN);
3628              
3629 0 0         if (!FUNCTION) {
3630 0           croak("XSUB call through interface did not provide *function");
3631             }
3632              
3633 0           RETVAL=FUNCTION(arg1, arg2, arg3, arg4);
3634             }
3635             OUTPUT:
3636             RETVAL
3637              
3638             GEN
3639             interface45(arg1, arg2, arg3=0)
3640             long oldavma=avma;
3641             long arg1
3642             GEN arg2
3643             long arg3
3644             CODE:
3645             { /* Code="LGD0,L," */
3646 0           dFUNCTION(GEN);
3647              
3648 0 0         if (!FUNCTION) {
3649 0           croak("XSUB call through interface did not provide *function");
3650             }
3651              
3652 0           RETVAL=FUNCTION(arg1, arg2, arg3);
3653             }
3654             OUTPUT:
3655             RETVAL
3656              
3657             void
3658             interface59(arg1, arg2, arg3, arg4, arg5)
3659             long oldavma=avma;
3660             long arg1
3661             GEN arg2
3662             GEN arg3
3663             GEN arg4
3664             GEN arg5
3665             CODE:
3666             { /* Code="vLGGGG" */
3667 2           dFUNCTION(GEN);
3668              
3669 2 50         if (!FUNCTION) {
3670 0           croak("XSUB call through interface did not provide *function");
3671             }
3672              
3673 2           FUNCTION(arg1, arg2, arg3, arg4, arg5);
3674             }
3675             CLEANUP:
3676 2           avma=oldavma;
3677              
3678             GEN
3679             interface73(arg1, arg2, arg3, arg4, arg5, arg6=0, arg7=0)
3680             long oldavma=avma;
3681             long arg1
3682             PariVar arg2
3683             GEN arg3
3684             GEN arg4
3685             PariExprV arg5
3686             long arg6
3687             long arg7
3688             CODE:
3689             { /* Code="LV=GGIpD0,L,D0,L," */
3690 0           dFUNCTION(GEN);
3691              
3692 0 0         if (!FUNCTION) {
3693 0           croak("XSUB call through interface did not provide *function");
3694             }
3695             #if PARI_VERSION_EXP >= 2004002
3696             RETVAL=FUNCTION(arg1, arg3, arg4, arg5, prec_words, arg6, arg7); /* XXXX Omit `V' instead of merging it into I/E */
3697             #else
3698 0           RETVAL=FUNCTION(arg1, arg2, arg3, arg4, arg5, prec_words, arg6, arg7);
3699             #endif
3700             }
3701             OUTPUT:
3702             RETVAL
3703              
3704             void
3705             interface86(arg1, arg2, arg3, arg4, arg5)
3706             long oldavma=avma;
3707             PariVar arg1
3708             GEN arg2
3709             GEN arg3
3710             GEN arg4
3711             PariExprV arg5
3712             CODE:
3713             { /* Code="vV=GGGI" */
3714 1           dFUNCTION(GEN);
3715              
3716 1 50         if (!FUNCTION) {
3717 0           croak("XSUB call through interface did not provide *function");
3718             }
3719             #if PARI_VERSION_EXP >= 2004002
3720             FUNCTION(arg2, arg3, arg4, arg5); /* XXXX Omit `V' instead of merging it into I/E */
3721             #else
3722 1           FUNCTION(arg1, arg2, arg3, arg4, arg5);
3723             #endif
3724             }
3725             CLEANUP:
3726 1           avma=oldavma;
3727              
3728             void
3729             interface87(arg1, arg2, arg3, arg4=0)
3730             long oldavma=avma;
3731             PariVar arg1
3732             GEN arg2
3733             PariExprV arg3
3734             long arg4
3735             CODE:
3736             { /* Code="vV=GID0,L," */
3737 1           dFUNCTION(GEN);
3738              
3739 1 50         if (!FUNCTION) {
3740 0           croak("XSUB call through interface did not provide *function");
3741             }
3742             #if PARI_VERSION_EXP >= 2004002
3743             FUNCTION(arg2, arg3, arg4); /* XXXX Omit `V' instead of merging it into I/E */
3744             #else
3745 1           FUNCTION(arg1, arg2, arg3, arg4);
3746             #endif
3747             }
3748             CLEANUP:
3749 1           avma=oldavma;
3750              
3751             bool
3752             _2bool(arg1,arg2,inv)
3753             long oldavma=avma;
3754             GEN arg1
3755             GEN arg2 = NO_INIT
3756             long inv = NO_INIT
3757             CODE:
3758             PERL_UNUSED_VAR(arg2); /* -W */
3759             PERL_UNUSED_VAR(inv); /* -W */
3760 65           RETVAL=!gcmp0(arg1);
3761             OUTPUT:
3762             RETVAL
3763             CLEANUP:
3764 65           avma=oldavma;
3765              
3766             bool
3767             pari2bool(arg1)
3768             long oldavma=avma;
3769             GEN arg1
3770             CODE:
3771 0           RETVAL=!gcmp0(arg1);
3772             OUTPUT:
3773             RETVAL
3774             CLEANUP:
3775 0           avma=oldavma;
3776              
3777             CV *
3778             loadPari(name, v = 99)
3779             char * name
3780             int v
3781             CODE:
3782             {
3783 11007           char *olds = name;
3784 11007           entree *ep=NULL;
3785 11007           long hash, valence = -1; /* Avoid uninit warning */
3786 11007           void (*func)(void*)=NULL;
3787 11007           void (*unsupported)(void*) = (void (*)(void*)) not_here;
3788              
3789 11007 100         if (*name=='g') {
3790 329           switch (name[1]) {
3791             case 'a':
3792 221 100         if (strEQ(name,"gadd")) {
3793 1           valence=2;
3794 1           func=(void (*)(void*)) gadd;
3795 220 50         } else if (strEQ(name,"gand")) {
3796 0           valence=2;
3797 0           func=(void (*)(void*)) gand;
3798             }
3799 221           break;
3800             case 'c':
3801 20 50         if (strEQ(name,"gcmp0")) {
3802 0           valence=10;
3803 0           func=(void (*)(void*)) gcmp0;
3804 20 50         } else if (strEQ(name,"gcmp1")) {
3805 0           valence=10;
3806 0           func=(void (*)(void*)) gcmp1;
3807 20 50         } else if (strEQ(name,"gcmp_1")) {
3808 0           valence=10;
3809 0           func=(void (*)(void*)) gcmp_1;
3810 20 50         } else if (strEQ(name,"gcmp")) {
3811 0           valence=20;
3812 0           func=(void (*)(void*)) gcmp;
3813             }
3814 20           break;
3815             case 'd':
3816 4 50         if (strEQ(name,"gdiv")) {
3817 0           valence=2;
3818 0           func=(void (*)(void*)) gdiv;
3819 4 100         } else if (strEQ(name,"gdivent")) {
3820 3           valence=2;
3821 3           func=(void (*)(void*)) gdivent;
3822 1 50         } else if (strEQ(name,"gdivround")) {
3823 1           valence=2;
3824 1           func=(void (*)(void*)) gdivround;
3825             }
3826 4           break;
3827             case 'e':
3828 81 100         if (strEQ(name,"geq")) {
3829 1           valence=2;
3830 1           func=(void (*)(void*)) geq;
3831 80 50         } else if (strEQ(name,"gegal") || strEQ(name,"gequal")) { /* old name */
    50          
3832 0           valence=20;
3833 0           func=(void (*)(void*)) gequal;
3834             }
3835 81           break;
3836             case 'g':
3837 0 0         if (strEQ(name,"gge")) {
3838 0           valence=2;
3839 0           func=(void (*)(void*)) gge;
3840 0 0         } else if (strEQ(name,"ggt")) {
3841 0           valence=2;
3842 0           func=(void (*)(void*)) ggt;
3843             }
3844 0           break;
3845             case 'l':
3846 0 0         if (strEQ(name,"gle")) {
3847 0           valence=2;
3848 0           func=(void (*)(void*)) gle;
3849 0 0         } else if (strEQ(name,"glt")) {
3850 0           valence=2;
3851 0           func=(void (*)(void*)) glt;
3852             }
3853 0           break;
3854             case 'm':
3855 0 0         if (strEQ(name,"gmul")) {
3856 0           valence=2;
3857 0           func=(void (*)(void*)) gmul;
3858 0 0         } else if (strEQ(name,"gmod")) {
3859 0           valence=2;
3860 0           func=(void (*)(void*)) gmod;
3861             }
3862 0           break;
3863             case 'n':
3864 1 50         if (strEQ(name,"gneg")) {
3865 0           valence=1;
3866 0           func=(void (*)(void*)) gneg;
3867 1 50         } else if (strEQ(name,"gne")) {
3868 1           valence=2;
3869 1           func=(void (*)(void*)) gne;
3870             }
3871 1           break;
3872             case 'o':
3873 0 0         if (strEQ(name,"gor")) {
3874 0           valence=2;
3875 0           func=(void (*)(void*)) gor;
3876             }
3877 0           break;
3878             case 'p':
3879 1 50         if (strEQ(name,"gpui") || strEQ(name,"gpow")) {
    0          
3880 1           valence=2;
3881 1           func=(void (*)(void*)) my_gpui;
3882             }
3883 1           break;
3884             case 's':
3885 1 50         if (strEQ(name,"gsub")) {
3886 1           valence=2;
3887 1           func=(void (*)(void*)) gsub;
3888             }
3889 329           break;
3890             }
3891 10678 100         } else if (*name=='_') {
3892 103 100         if (name[1] == 'g') {
3893 100           switch (name[2]) {
3894             case 'a':
3895 11 50         if (strEQ(name,"_gadd")) {
3896 11           valence=299;
3897 11           func=(void (*)(void*)) gadd;
3898 0 0         } else if (strEQ(name,"_gand")) {
3899 0           valence=2099;
3900 0           func=(void (*)(void*)) gand;
3901             }
3902 11           break;
3903             #if PARI_VERSION_EXP >= 2000018
3904             case 'b':
3905 5 100         if (strEQ(name,"_gbitand")) {
3906 1           valence=299;
3907 1           func=(void (*)(void*)) gbitand;
3908 4 100         } else if (strEQ(name,"_gbitor")) {
3909 1           valence=299;
3910 1           func=(void (*)(void*)) gbitor;
3911 3 100         } else if (strEQ(name,"_gbitxor")) {
3912 1           valence=299;
3913 1           func=(void (*)(void*)) gbitxor;
3914 2 100         } else if (strEQ(name,"_gbitneg")) {
3915 1           valence=199;
3916 1           func=(void (*)(void*)) _gbitneg;
3917             #if PARI_VERSION_EXP >= 2002001
3918 1 50         } else if (strEQ(name,"_gbitshiftl")) {
3919 1           valence=2199;
3920 1           func=(void (*)(void*)) _gbitshiftl;
3921             #endif
3922             #if PARI_VERSION_EXP >= 2002001 && PARI_VERSION_EXP <= 2002007
3923             } else if (strEQ(name,"_gbitshiftr")) {
3924             valence=2199;
3925             func=(void (*)(void*)) _gbitshiftr;
3926             #endif
3927             }
3928 5           break;
3929             #endif
3930             case 'c':
3931 0 0         if (strEQ(name,"_gcmp")) {
3932 0           valence=209;
3933 0           func=(void (*)(void*)) gcmp;
3934 0 0         } else if (strEQ(name,"_gcmp0")) {
3935 0           valence=109;
3936 0           func=(void (*)(void*)) gcmp0;
3937             }
3938 0           break;
3939             case 'd':
3940 14 50         if (strEQ(name,"_gdiv")) {
3941 14           valence=299;
3942 14           func=(void (*)(void*)) gdiv;
3943             }
3944 14           break;
3945             case 'e':
3946 20 50         if (strEQ(name,"_geq")) {
3947 20           valence=2099;
3948 20           func=(void (*)(void*)) geq;
3949             }
3950 20           break;
3951             case 'g':
3952 1 50         if (strEQ(name,"_gge")) {
3953 1           valence=2099;
3954 1           func=(void (*)(void*)) gge;
3955 0 0         } else if (strEQ(name,"_ggt")) {
3956 0           valence=2099;
3957 0           func=(void (*)(void*)) ggt;
3958             }
3959 1           break;
3960             case 'l':
3961 2 100         if (strEQ(name,"_gle")) {
3962 1           valence=2099;
3963 1           func=(void (*)(void*)) gle;
3964 1 50         } else if (strEQ(name,"_glt")) {
3965 1           valence=2099;
3966 1           func=(void (*)(void*)) glt;
3967             }
3968 2           break;
3969             case 'm':
3970 17 100         if (strEQ(name,"_gmul")) {
3971 14           valence=299;
3972 14           func=(void (*)(void*)) gmul;
3973 3 50         } else if (strEQ(name,"_gmod")) {
3974 3           valence=299;
3975 3           func=(void (*)(void*)) gmod;
3976             }
3977 17           break;
3978             case 'n':
3979 8 100         if (strEQ(name,"_gneg")) {
3980 7           valence=199;
3981 7           func=(void (*)(void*)) gneg;
3982 1 50         } else if (strEQ(name,"_gne")) {
3983 1           valence=2099;
3984 1           func=(void (*)(void*)) gne;
3985             }
3986 8           break;
3987             case 'o':
3988 0 0         if (strEQ(name,"_gor")) {
3989 0           valence=2099;
3990 0           func=(void (*)(void*)) gor;
3991             }
3992 0           break;
3993             case 'p':
3994 11 50         if (strEQ(name,"_gpui")) {
3995 11           valence=299;
3996 11           func=(void (*)(void*)) my_gpui;
3997             }
3998 11           break;
3999             case 's':
4000 11 50         if (strEQ(name,"_gsub")) {
4001 11           valence=299;
4002 11           func=(void (*)(void*)) gsub;
4003             }
4004 100           break;
4005             }
4006             } else {
4007 3           switch (name[1]) {
4008             case 'a':
4009 1 50         if (strEQ(name,"_abs")) {
4010 1           valence=199;
4011 1           func=(void (*)(void*)) gabs;
4012             }
4013 1           break;
4014             case 'c':
4015 0 0         if (strEQ(name,"_cos")) {
4016 0           valence=199;
4017 0           func=(void (*)(void*)) gcos;
4018             }
4019 0           break;
4020             case 'e':
4021 1 50         if (strEQ(name,"_exp")) {
4022 1           valence=199;
4023 1           func=(void (*)(void*)) gexp;
4024             }
4025 1           break;
4026             case 'l':
4027 1 50         if (strEQ(name,"_lex")) {
4028 1           valence=2091;
4029 1           func=(void (*)(void*)) lexcmp;
4030 0 0         } else if (strEQ(name,"_log")) {
4031 0           valence=199;
4032 0           func=(void (*)(void*)) glog;
4033             }
4034 1           break;
4035             case 's':
4036 0 0         if (strEQ(name,"_sin")) {
4037 0           valence=199;
4038 0           func=(void (*)(void*)) gsin;
4039 0 0         } else if (strEQ(name,"_sqrt")) {
4040 0           valence=199;
4041 0           func=(void (*)(void*)) gsqrt;
4042             }
4043 0           break;
4044             }
4045             }
4046             }
4047 11007 100         if (!func) {
4048 10895           SAVEINT(doing_PARI_autoload);
4049 10895           doing_PARI_autoload = 1;
4050             checkPariFunction(name);
4051             #ifdef MAY_USE_FETCH_ENTRY
4052             ep = is_entry(name);
4053             #else
4054 10895           ep = is_entry_intern(name, functions_hash, &hash);
4055             #endif
4056 10895           doing_PARI_autoload = 0;
4057 10895 100         if (!ep)
4058 2           croak("`%s' is not a Pari function name",name);
4059              
4060 10893 50         if (ep && isPariFunction(ep)) {
    50          
4061             /* Builtin */
4062 10893           IV table_valence = 99;
4063              
4064 10893 50         if (ep->code /* This is in func_codes.h: */
    100          
4065 10852 100         && (*(ep->code) ? (PERL_constant_ISIV == func_ord_by_type (aTHX_ ep->code,
4066 10852           strlen(ep->code), &table_valence)) /* Essentially, PERL_constant_ISIV means: recognized */
4067 41           : (table_valence = 9900)))
4068 7051           valence = table_valence;
4069             else
4070 3842           valence = 99;
4071             #ifdef CHECK_VALENCE
4072             if (ep->code && valence != EpVALENCE(ep)
4073             && EpVALENCE(ep) != 99
4074             && !(valence == 23 && EpVALENCE(ep) == 21)
4075             && !(valence == 48 && EpVALENCE(ep) == 47)
4076             && !(valence == 96 && EpVALENCE(ep) == 91)
4077             && !(valence == 99 && EpVALENCE(ep) == 0)
4078             && !(valence == 9900 && EpVALENCE(ep) == 0))
4079             warn("funcname=`%s', code=`%s', val=%d, calc_val=%d\n",
4080             name, ep->code, (int)EpVALENCE(ep), (int)valence);
4081             #endif
4082 10893           func=(void (*)(void*)) ep->value;
4083 10893 50         if (!func) {
4084 10893           func = unsupported;
4085             }
4086             }
4087             }
4088 11005 50         if (func == unsupported) {
4089 0           croak("Do not know how to work with Pari control structure `%s'",
4090             olds);
4091 11005 50         } else if (func) {
4092 11005           char* file = __FILE__, *proto = NULL;
4093 11005           char subname[276]="Math::Pari::";
4094 11005           char buf[64], *pbuf = buf;
4095             const char *s, *s1;
4096             CV *protocv;
4097 11005           int flexible = 0;
4098            
4099 11005           sprintf(buf, "%ld", valence);
4100             /* warn("See valence = %d", valence); */
4101 11005           switch (valence) {
4102             case 0:
4103 41 50         if (!ep->code) {
4104 0           croak("Unsupported Pari function %s, interface 0 code NULL", olds);
4105 41 50         } else if (ep->code[0] == 'p' && ep->code[1] == 0) {
    50          
4106 41           DO_INTERFACE(0);
4107 0 0         } else if (ep->code[0] == 0) {
4108 0           DO_INTERFACE(9900);
4109             } else {
4110 0           goto flexible;
4111             }
4112 41           break;
4113 720           CASE_INTERFACE(1);
4114 140           CASE_INTERFACE(10);
4115 10           CASE_INTERFACE(199);
4116 0           CASE_INTERFACE(109);
4117 180           CASE_INTERFACE(11);
4118 0           CASE_INTERFACE(15);
4119 1709           CASE_INTERFACE(2);
4120 80           CASE_INTERFACE(20);
4121 67           CASE_INTERFACE(299);
4122 0           CASE_INTERFACE(209);
4123 24           CASE_INTERFACE(2099);
4124 1           CASE_INTERFACE(2091);
4125 1           CASE_INTERFACE(2199);
4126 560           CASE_INTERFACE(3);
4127 40           CASE_INTERFACE(30);
4128 80           CASE_INTERFACE(4);
4129 0           CASE_INTERFACE(5);
4130 0           CASE_INTERFACE(21);
4131 140           CASE_INTERFACE(23);
4132 20           CASE_INTERFACE(24);
4133 321           CASE_INTERFACE(25);
4134 380           CASE_INTERFACE(29);
4135 40           CASE_INTERFACE(32);
4136 40           CASE_INTERFACE(33);
4137 140           CASE_INTERFACE(35);
4138 20           CASE_INTERFACE(12);
4139 60           CASE_INTERFACE(13);
4140 223           CASE_INTERFACE(14);
4141 20           CASE_INTERFACE(26);
4142 60           CASE_INTERFACE(28);
4143 20           CASE_INTERFACE(31);
4144 0           CASE_INTERFACE(34);
4145 20           CASE_INTERFACE(22);
4146 20           CASE_INTERFACE(27);
4147 40           CASE_INTERFACE(37);
4148 61           CASE_INTERFACE(47);
4149 0           CASE_INTERFACE(48);
4150 20           CASE_INTERFACE(49);
4151 40           CASE_INTERFACE(83);
4152 21           CASE_INTERFACE(84);
4153 1483           CASE_INTERFACE(18);
4154             /* These interfaces were automatically generated: */
4155 20           CASE_INTERFACE(16);
4156 60           CASE_INTERFACE(19);
4157 0           CASE_INTERFACE(44);
4158 20           CASE_INTERFACE(45);
4159 20           CASE_INTERFACE(59);
4160 20           CASE_INTERFACE(73);
4161 20           CASE_INTERFACE(86);
4162 20           CASE_INTERFACE(87);
4163 41           CASE_INTERFACE(9900);
4164              
4165             default:
4166 3942 50         if (!ep)
4167 0           croak("Unsupported interface %ld for \"direct-link\" Pari function %s",
4168             valence, olds);
4169 3942 50         if (!ep->code)
4170 0           croak("Unsupported interface %ld and no code for a Pari function %s",
4171             valence, olds);
4172             flexible:
4173 3942           s1 = s = ep->code;
4174 3942 50         if (*s1 == 'x')
4175 0           s1++;
4176 3942 100         if (*s1 == 'v') {
4177 480           pbuf = "_flexible_void";
4178 480           DO_INTERFACE(_flexible_void);
4179             }
4180 3462 100         else if (*s1 == 'l') {
4181 260           pbuf = "_flexible_long";
4182 260           DO_INTERFACE(_flexible_long);
4183             }
4184 3202 100         else if (*s1 == 'i') {
4185 40           pbuf = "_flexible_int";
4186 40           DO_INTERFACE(_flexible_int);
4187             }
4188             else {
4189 3162           pbuf = "_flexible_gen";
4190 3162           DO_INTERFACE(_flexible_gen);
4191             }
4192            
4193 3942           flexible = 1;
4194             }
4195 11005           strcpy(subname+12,"interface");
4196 11005           strcpy(subname+12+9,pbuf);
4197 11005           protocv = perl_get_cv(subname, FALSE);
4198 11005 50         if (protocv) {
4199 11005 50         proto = SvPV((SV*)protocv,na);
4200             }
4201            
4202 11005           strcpy(subname+12,olds);
4203 11005           RETVAL = newXS(subname,math_pari_subaddr,file);
4204 11005 50         if (proto)
4205 11005           sv_setpv((SV*)RETVAL, proto);
4206 11005 100         XSINTERFACE_FUNC_SET(RETVAL, flexible ? (void*)ep : (void*)func);
4207             } else {
4208 0 0         croak( "Cannot load a Pari macro `%s': macros are unsupported; VALENCE=%#04x, code=<%s>, isFunction=%d, EpVAR=%d",
    0          
4209 0           olds, (ep ? (int)EpVALENCE(ep) : 0x666), (ep->code ? ep->code : ""), isPariFunction(ep), (int)EpVAR);
4210             }
4211             }
4212             OUTPUT:
4213             RETVAL
4214              
4215             # Tag is menu entry, or -1 for all.
4216              
4217             void
4218             _listPari(tag)
4219             int tag
4220             PPCODE:
4221             {
4222             long valence;
4223 32           entree *ep, *table = functions_basic;
4224 32           int i=-1;
4225              
4226 96 100         while (++i <= 1) {
4227 64 100         if (i==1)
4228             #if defined(NO_HIGHLEVEL_PARI) || PARI_VERSION_EXP >= 2009000 /* Probably disappered earlier */
4229             break;
4230             #else
4231 32           table = functions_highlevel;
4232             #endif
4233            
4234 17760 100         for(ep = table; ep->name; ep++) {
4235 17696           valence = EpVALENCE(ep);
4236 17696 100         if ((tag == -1 && !_is_internal(ep->menu)) || ep->menu == tag) {
    50          
    100          
4237 11613 100         switch (valence) {
4238             default:
4239             case 0:
4240 6216 100         if (ep->code == 0)
4241 105           break;
4242             /* FALL THROUGH */
4243             case 1:
4244             case 10:
4245             case 199:
4246             case 109:
4247             case 11:
4248             case 15:
4249             case 2:
4250             case 20:
4251             case 299:
4252             case 209:
4253             case 2099:
4254             case 2199:
4255             case 3:
4256             case 30:
4257             case 4:
4258             case 5:
4259             case 21:
4260             case 23:
4261             case 24:
4262             case 25:
4263             case 29:
4264             case 32:
4265             case 33:
4266             case 35:
4267             case 12:
4268             case 13:
4269             case 14:
4270             case 26:
4271             case 28:
4272             case 31:
4273             case 34:
4274             case 22:
4275             case 27:
4276             case 37:
4277             case 47:
4278             case 48:
4279             case 49:
4280             case 83:
4281             case 84:
4282             case 18:
4283             /* These interfaces were automatically generated: */
4284             case 16:
4285             case 19:
4286             case 44:
4287             case 45:
4288             case 59:
4289             case 73:
4290             case 86:
4291             case 87:
4292 11508 100         XPUSHs(sv_2mortal(newSVpv(ep->name, 0)));
4293             }
4294             }
4295             }
4296             }
4297             }
4298              
4299             BOOT:
4300             {
4301             static int reboot;
4302 26           SV *mem = perl_get_sv("Math::Pari::initmem", FALSE);
4303 26           SV *pri = perl_get_sv("Math::Pari::initprimes", FALSE);
4304             pari_sp av;
4305 26 50         if (!mem || !SvOK(mem)) {
    50          
    0          
    0          
4306 0           croak("$Math::Pari::initmem not defined!");
4307             }
4308 26 50         if (!pri || !SvOK(pri)) {
    50          
    0          
    0          
4309 0           croak("$Math::Pari::initprimes not defined!");
4310             }
4311 26 50         if (reboot) {
4312 0           detach_stack();
4313             #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 */
4314 0           pari_close_opts(INIT_DFTm);
4315             #else /* PARI_VERSION_EXP < 2002012 */
4316             if (reset_on_reload)
4317             freeall();
4318             else
4319             allocatemoremem(1008);
4320             #endif
4321             }
4322             #if PARI_VERSION_EXP >= 2002012
4323             /* pari_init_defaults(); */ /* Not needed with INIT_DFTm */
4324             #else
4325             INIT_JMP_off;
4326             INIT_SIG_off;
4327             /* These guys are new in 2.0. */
4328             init_defaults(1);
4329             #endif
4330             /* Different order of init required */
4331             #if PARI_VERSION_EXP < 2003000
4332             if (!(reboot++)) {
4333             # ifndef NO_HIGHLEVEL_PARI
4334             # if PARI_VERSION_EXP >= 2002012
4335             pari_add_module(functions_highlevel);
4336             # else /* !( PARI_VERSION_EXP >= 2002012 ) */
4337             pari_addfunctions(&pari_modules,
4338             functions_highlevel, helpmessages_highlevel);
4339             # endif /* !( PARI_VERSION_EXP >= 2002012 ) */
4340             init_graph();
4341             # endif
4342             }
4343             #endif /* PARI_VERSION_EXP < 2003000 */
4344 26 50         primelimit = SvIV(pri);
4345 26 50         parisize = SvIV(mem);
4346             #if PARI_VERSION_EXP >= 2002012
4347 26           pari_init_opts(parisize, primelimit, INIT_DFTm);
4348             /* Default: take four million bytes of
4349             * memory for the stack, calculate
4350             * primes up to 500000. */
4351             #else
4352             init(parisize, primelimit); /* Default: take four million bytes of
4353             * memory for the stack, calculate
4354             * primes up to 500000. */
4355             #endif
4356             /* Different order of init required */
4357             #if PARI_VERSION_EXP >= 2003000
4358 26 50         if (!(reboot++)) {
4359             # ifndef NO_HIGHLEVEL_PARI
4360             # if PARI_VERSION_EXP >= 2002012
4361             # if PARI_VERSION_EXP < 2009000 /* Probably disappered earlier */
4362 26           pari_add_module(functions_highlevel);
4363             # endif /* PARI_VERSION_EXP < 2009000 */
4364             # else /* !( PARI_VERSION_EXP >= 2002012 ) */
4365             pari_addfunctions(&pari_modules,
4366             functions_highlevel, helpmessages_highlevel);
4367             # endif /* !( PARI_VERSION_EXP >= 2002012 ) */
4368             #if PARI_VERSION_EXP >= 2011000
4369             pari_set_plot_engine(gp_get_plot);
4370             #else
4371 26           init_graph();
4372             #endif
4373             # endif
4374             }
4375             #endif /* PARI_VERSION_EXP >= 2003000 */
4376 26           PariStack = (SV *) GENfirstOnStack;
4377 26 50         if (!worksv)
4378 26           worksv = NEWSV(910,0);
4379 26 50         if (workErrsv)
4380 0           sv_setpvn(workErrsv, "", 0); /* Just in case, on restart */
4381             else
4382 26           workErrsv = newSVpvn("",0);
4383 26           pariErr = &perlErr;
4384             #if PARI_VERSION_EXP >= 2003000
4385 26           pari_set_last_newline(1); /* Bug in PARI: at the start, we do not need extra newlines */
4386             #endif
4387             #if PARI_VERSION_EXP >= 2004000 /* Undocumented when it appeared; present in 2.5.0 */
4388             cb_pari_err_recover = _svErrdie; /* XXXX Not enough for our needs! */
4389             cb_pari_handle_exception = math_pari_handle_exception;
4390             # ifdef CB_EXCEPTION_FLAGS
4391             cb_exception_resets_avma = 1;
4392             cb_exception_flushes_err = 1;
4393             # endif
4394             av = avma;
4395             /* Init the rest ourselves */
4396             #if PARI_VERSION_EXP >= 2009000
4397             if (!GP_DATA->colormap) /* init_defaults() leaves them NULL */
4398             sd_graphcolormap("[\"white\",\"black\",\"gray\",\"violetred\",\"red\",\"green\",\"blue\",\"gainsboro\",\"purple\"]",0);
4399             if (!GP_DATA->graphcolors)
4400             sd_graphcolors("[4,5]",0);
4401             avma = av;
4402             #else /* !(PARI_VERSION_EXP >= 2009000) */
4403             if (!pari_colormap) /* init_defaults() leaves them NULL */
4404             pari_colormap = gclone(readseq("[\"white\",\"black\",\"gray\",\"violetred\",\"red\",\"green\",\"blue\",\"gainsboro\",\"purple\"]"));
4405             if (!pari_graphcolors)
4406             pari_graphcolors = gclone(readseq("[4,5]"));
4407             avma = av;
4408             #endif /* !(PARI_VERSION_EXP >= 2009000) */
4409             #endif
4410             #if PARI_VERSION_EXP < 2005000 /* Undocumented when it disappeared; missing in 2.5.0 */
4411 26           foreignHandler = (void*)&callPerlFunction;
4412 26           foreignExprSwitch = (char)SVt_PVCV;
4413 26           foreignExprHandler = &exprHandler_Perl;
4414             #endif
4415 26           foreignAutoload = &autoloadPerlFunction;
4416 26           foreignFuncFree = &freePerlFunction;
4417 26           pariStash = gv_stashpv("Math::Pari", TRUE);
4418 26           pariEpStash = gv_stashpv("Math::Pari::Ep", TRUE);
4419 26           perlavma = sentinel = avma;
4420             fmt_nbPset(def_fmt_nb);
4421 26           global_top = myPARI_top;
4422             #if PARI_VERSION_EXP >= 2004002 /* Undocumented when it appeared; present in 2.5.0 */
4423             if (! code_return_1) {
4424             code_return_1 = gclone(compile_str("x->1"));
4425             code2_return_1 = gclone(compile_str("(x,y)->1"));
4426             avma = sentinel;
4427             }
4428             #endif
4429             }
4430              
4431             void
4432             memUsage()
4433             PPCODE:
4434             #ifdef DEBUG_PARI
4435 18 50         EXTEND(sp, 4); /* Got cv + 0, - but on newer Perls, this does not count. Return 4. */
4436 18           PUSHs(sv_2mortal(newSViv(SVnumtotal)));
4437 18           PUSHs(sv_2mortal(newSViv(SVnum)));
4438 18           PUSHs(sv_2mortal(newSViv(onStack)));
4439 18           PUSHs(sv_2mortal(newSViv(offStack)));
4440             #endif
4441            
4442              
4443             void
4444             dumpStack()
4445             PPCODE:
4446 19           long i = 0, ssize, oursize = 0;
4447             SV *ret, *sv1, *nextsv;
4448 19           const char *pref = "";
4449              
4450 19 50         switch(GIMME_V) {
4451             case G_VOID:
4452 19           pref = "# ";
4453             case G_SCALAR:
4454 19           ssize = getstack();
4455 19           ret = newSVpvf("%sstack size is %ld bytes (%ld x %ld longs)\n",
4456             pref, ssize, (long)sizeof(long), ssize/sizeof(long));
4457 121 100         for (sv1 = PariStack; sv1 != (SV *) GENfirstOnStack; sv1 = nextsv) {
4458 102 100         GEN x = (GEN) SV_myvoidp_get(sv1);
    50          
4459 102           SV* tmp = pari_print(x);
4460 102 50         sv_catpvf(ret,"%s %2ld: %s\n", pref, i, SvPV_nolen(tmp));
4461 102           SvREFCNT_dec(tmp);
4462 102           i++;
4463 102           oursize += gsizeword(x);
4464 102 100         nextsv = SV_Stack_find_next(sv1);
4465             }
4466 19           sv_catpvf(ret,"%sour data takes %ld words out of %ld words on stack\n", pref, oursize, ssize/sizeof(long));
4467 19 50         if(GIMME_V == G_VOID) {
    50          
4468 19 50         PerlIO_puts(PerlIO_stdout(), SvPV_nolen(ret));
4469 19           SvREFCNT_dec(ret);
4470 19           XSRETURN(0);
4471             } else {
4472 0           ST(0) = sv_2mortal(ret);
4473 0           XSRETURN(1);
4474             }
4475             case G_ARRAY:
4476 0 0         for (sv1 = PariStack; sv1 != (SV *) GENfirstOnStack; sv1 = nextsv) {
4477 0 0         GEN x = (GEN) SV_myvoidp_get(sv1);
    0          
4478 0 0         XPUSHs(sv_2mortal(pari_print(x)));
4479 0 0         nextsv = SV_Stack_find_next(sv1);
4480             }
4481             }
4482              
4483             void
4484             __dumpStack()
4485             PPCODE:
4486 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. */
4487 0           long ssize, i = 0;
4488             SV* ret;
4489              
4490 0 0         switch(GIMME_V) {
4491             case G_VOID:
4492             case G_SCALAR:
4493 0           ssize = getstack();
4494 0           ret = newSVpvf("stack size is %ld bytes (%ld x %ld longs)\n",
4495             ssize,(long)sizeof(long),ssize/sizeof(long));
4496 0 0         for(; x < (GEN)myPARI_top; x += gsizeword(x), i++) {
4497 0           SV* tmp = pari_print(x);
4498 0 0         sv_catpvf(ret," %2ld: %s\n",i,SvPV_nolen(tmp));
4499 0           SvREFCNT_dec(tmp);
4500             }
4501 0 0         if(GIMME_V == G_VOID) {
    0          
4502 0 0         PerlIO_puts(PerlIO_stdout(), SvPV_nolen(ret));
4503 0           SvREFCNT_dec(ret);
4504 0           XSRETURN(0);
4505             } else {
4506 0           ST(0) = sv_2mortal(ret);
4507 0           XSRETURN(1);
4508             }
4509             case G_ARRAY:
4510 0 0         for(; x < (GEN)myPARI_top; x += gsizeword(x), i++)
4511 0 0         XPUSHs(sv_2mortal(pari_print(x)));
4512             }
4513              
4514             void
4515             dumpHeap()
4516             PPCODE:
4517             heap_dumper_t hd;
4518 0 0         int context = GIMME_V, m;
4519              
4520 0           SV* ret = Nullsv; /* Avoid unit warning */
4521              
4522 0           switch(context) {
4523             case G_VOID:
4524 0           case G_SCALAR: ret = newSVpvn("",0); break;
4525 0           case G_ARRAY: ret = (SV*)newAV(); break;
4526             }
4527              
4528 0           hd.words = hd.items = 0;
4529 0           hd.acc = ret;
4530 0           hd.context = context;
4531              
4532 0           heap_dumper(&hd);
4533              
4534 0           switch(context) {
4535             case G_VOID:
4536             case G_SCALAR: {
4537 0           SV* tmp = newSVpvf("heap had %ld bytes (%ld items)\n",
4538 0           (hd.words + BL_HEAD * hd.items) * sizeof(long),
4539             hd.items);
4540 0           sv_catsv(tmp,ret);
4541 0           SvREFCNT_dec(ret);
4542 0 0         if(GIMME_V == G_VOID) {
    0          
4543 0 0         PerlIO_puts(PerlIO_stdout(), SvPV_nolen(tmp));
4544 0           SvREFCNT_dec(tmp);
4545 0           XSRETURN(0);
4546             } else {
4547 0           ST(0) = sv_2mortal(tmp);
4548 0           XSRETURN(1);
4549             }
4550             }
4551             case G_ARRAY:
4552 0 0         for(m = 0; m <= av_len((AV*)ret); m++)
4553 0 0         XPUSHs(sv_2mortal(SvREFCNT_inc(*av_fetch((AV*)ret,m,0))));
4554 0           SvREFCNT_dec(ret);
4555             }
4556              
4557             MODULE = Math::Pari PACKAGE = Math::Pari
4558              
4559             void
4560             DESTROY(rv)
4561             SV * rv
4562             CODE:
4563             {
4564             /* PariStack keeps the latest SV that keeps a GEN on stack. */
4565 9028372           SV* sv = SvRV(rv);
4566             char* ostack; /* The value of PariStack when the
4567             * variable was created, thus the
4568             * previous SV that keeps a GEN from
4569             * stack, or some atoms. */
4570             long oldavma; /* The value of avma on the entry
4571             * to function having the SV as
4572             * argument. */
4573             long howmany;
4574 9028372 100         SV_OAVMA_PARISTACK_get(sv, oldavma, ostack);
4575 9028372           oldavma += myPARI_bot;
4576             #if 1
4577 9028372 100         if (SvMAGICAL(sv) && SvTYPE(sv) == SVt_PVAV) {
    50          
4578 2295           MAGIC *mg = mg_find(sv, 'P');
4579             SV *obj;
4580              
4581             /* Be extra paranoid: is refcount is artificially low? */
4582 2295 50         if (mg && (obj = mg->mg_obj) && SvROK(obj) && SvRV(obj) == sv) {
    50          
    100          
    50          
4583 2265           mg->mg_flags &= ~MGf_REFCOUNTED;
4584 2265           SvREFCNT_inc(sv);
4585 2265           SvREFCNT_dec(obj);
4586             }
4587             /* We manipulated SvCUR(), which for AV overwrites AvFILLp();
4588             make sure that array looks like an empty one */
4589 2295           AvFILLp((AV*)sv) = -1;
4590             }
4591             #endif
4592 9028372 100         SV_PARISTACK_set(sv, GENheap); /* To avoid extra free() in moveoff.... */
4593 9028372 100         if (ostack == GENheap) /* Leave it alone? XXXX */
4594             /* break */ ;
4595 8023165 100         else if (ostack == GENmovedOffStack) {/* Know that it _was temporary. */
4596 5250765 100         killbloc((GEN)SV_myvoidp_get(sv));
    50          
4597             } else {
4598             /* Still on stack */
4599 2772400 50         if (ostack != (char*)PariStack) { /* But not the newest one. */
4600 2772400           howmany = moveoffstack_newer_than(sv);
4601 2772400 50         RUN_IF_DEBUG_PARI( warn("%li items moved off stack, onStack=%ld, offStack=%ld", howmany, (long)onStack, (long)offStack) );
4602             }
4603             /* Now fall through: */
4604             /* case (IV)GENfirstOnStack: */
4605             /* Now sv is the newest one on stack. */
4606 2772400           onStack_dec;
4607 2772400           perlavma = oldavma;
4608 2772400 50         if (oldavma > sentinel) {
4609 0           avma = sentinel; /* Mark the space on stack as free. */
4610             } else {
4611 2772400           avma = oldavma; /* Mark the space on stack as free. */
4612             }
4613 2772400           PariStack = (SV*)ostack; /* The same on the Perl/PARI side. */
4614             }
4615 9028372           SVnum_dec;
4616             }
4617              
4618             SV *
4619             pari_print(in)
4620             GEN in
4621              
4622             SV *
4623             pari_pprint(in)
4624             GEN in
4625              
4626             SV *
4627             pari_texprint(in)
4628             GEN in
4629              
4630             I32
4631             typ(in)
4632             GEN in
4633              
4634             SV *
4635             PARIvar(in)
4636             char *in
4637              
4638             GEN
4639             ifact(arg1)
4640             long oldavma=avma;
4641             long arg1
4642              
4643             void
4644             changevalue(name, val)
4645             PariName name
4646             GEN val
4647              
4648             void
4649             set_gnuterm(a,b,c=0)
4650             IV a
4651             IV b
4652             IV c
4653              
4654             long
4655             setprecision(digits=0)
4656             long digits
4657              
4658             long
4659             setseriesprecision(digits=0)
4660             long digits
4661              
4662             IV
4663             setprimelimit(n = 0)
4664             IV n
4665              
4666             void
4667             int_set_term_ftable(a)
4668             IV a
4669              
4670             long
4671             pari_version_exp()
4672              
4673             long
4674             have_highlevel()
4675              
4676             long
4677             have_graphics()
4678              
4679             int
4680             PARI_DEBUG()
4681              
4682             int
4683             PARI_DEBUG_set(val)
4684             int val
4685              
4686             long
4687             lgef(x)
4688             GEN x
4689              
4690             long
4691             lgefint(x)
4692             GEN x
4693              
4694             long
4695             lg(x)
4696             GEN x
4697              
4698             unsigned long
4699             longword(x,n)
4700             GEN x
4701             long n
4702              
4703             char *
4704             added_sections()
4705              
4706             void
4707             __detach_stack()
4708             CODE:
4709 0           detach_stack();
4710              
4711             MODULE = Math::Pari PACKAGE = Math::Pari PREFIX = s_
4712              
4713             char *
4714             s_type_name(x)
4715             GEN x
4716              
4717             int
4718             s_reset_on_reload(newvalue = -1)
4719             int newvalue
4720              
4721             #ifdef WITH_CRASHYOURSELF
4722              
4723             void
4724             crash_yourself()
4725             CODE:
4726             char *s = (char *) make_PariAV;
4727             *s = s[0];
4728              
4729             #endif /* defined(WITH_CRASHYOURSELF) */
4730              
4731             # Cannot do this: it is xsubpp which needs the typemap entry for UV,
4732             # and it needs to convert *all* the branches.
4733             #/* #if defined(PERL_VERSION) && (PERL_VERSION >= 6)*//* 5.6.0 has UV in the typemap */
4734              
4735             #if 0
4736             #UV
4737             #allocatemem(newsize = 0)
4738             #UV newsize
4739              
4740             #else /* !( HAVE_UVs ) */
4741              
4742             unsigned long
4743             s_allocatemem(newsize = 0)
4744             unsigned long newsize
4745              
4746             #endif /* !( HAVE_UVs ) */