diff -Nru giac-1.5.0.87+dfsg1/debian/changelog giac-1.5.0.87+dfsg1/debian/changelog --- giac-1.5.0.87+dfsg1/debian/changelog 2020-05-20 08:23:41.000000000 +0000 +++ giac-1.5.0.87+dfsg1/debian/changelog 2020-05-31 11:00:08.000000000 +0000 @@ -1,14 +1,24 @@ -giac (1.5.0.87+dfsg1-4ubuntu1) groovy; urgency=medium +giac (1.5.0.87+dfsg1-7) unstable; urgency=medium - * Replace workaround for hanging test on armhf (LP: #1877845) + * Really upload to unstable. - -- Graham Inggs Wed, 20 May 2020 08:23:41 +0000 + -- Julien Puydt Sun, 31 May 2020 13:00:08 +0200 -giac (1.5.0.87+dfsg1-4build1) groovy; urgency=medium +giac (1.5.0.87+dfsg1-6) experimental; urgency=medium - * No-change rebuild against libgsl25 + * Uploading to unstable : the experimental pari code is + accepted upstream, will be in the next official version, + and fixes an armhf issue. (Closes: #961122) - -- Graham Inggs Thu, 07 May 2020 22:01:24 +0000 + -- Julien Puydt Sun, 31 May 2020 10:33:10 +0200 + +giac (1.5.0.87+dfsg1-5) experimental; urgency=medium + + * Set the date to the last update in algo.tex so its build becomes + reproducible. + * Use experimental pari code to fix locking issues with pari. + + -- Julien Puydt Wed, 27 May 2020 07:45:47 +0200 giac (1.5.0.87+dfsg1-4) unstable; urgency=medium diff -Nru giac-1.5.0.87+dfsg1/debian/control giac-1.5.0.87+dfsg1/debian/control --- giac-1.5.0.87+dfsg1/debian/control 2020-05-10 06:32:06.000000000 +0000 +++ giac-1.5.0.87+dfsg1/debian/control 2020-05-31 11:00:08.000000000 +0000 @@ -1,8 +1,7 @@ Source: giac Section: science Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian Science Maintainers +Maintainer: Debian Science Maintainers Uploaders: Ximin Luo , Gilles Filippini , Julien Puydt Build-Depends: debhelper-compat (= 12), diff -Nru giac-1.5.0.87+dfsg1/debian/copyright giac-1.5.0.87+dfsg1/debian/copyright --- giac-1.5.0.87+dfsg1/debian/copyright 2020-03-04 07:18:55.000000000 +0000 +++ giac-1.5.0.87+dfsg1/debian/copyright 2020-05-31 11:00:08.000000000 +0000 @@ -1,7 +1,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: giac Upstream-Contact: Bernard Parisse -Source: ftp://ftp-fourier.ujf-grenoble.fr/xcas/ +Source: https://www-fourier.ujf-grenoble.fr/~parisse/giac.html Files-Excluded: # Embedded libraries pariinl.h diff -Nru giac-1.5.0.87+dfsg1/debian/pari.cc giac-1.5.0.87+dfsg1/debian/pari.cc --- giac-1.5.0.87+dfsg1/debian/pari.cc 1970-01-01 00:00:00.000000000 +0000 +++ giac-1.5.0.87+dfsg1/debian/pari.cc 2020-05-31 11:00:08.000000000 +0000 @@ -0,0 +1,1095 @@ +/* -*- mode:C++ ; compile-command: "g++-3.4 -I.. -g -c pari.cc" -*- */ +#include "giacPCH.h" + +/* PARI interface + * Copyright (C) 2001,14 B. Parisse, Institut Fourier, 38402 St Martin d'Heres + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#if !defined NSPIRE +using namespace std; +#endif +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gen.h" +#include "identificateur.h" +#include "sym2poly.h" +#include "plot.h" +#include "prog.h" +#include "usual.h" +#include "input_lexer.h" +#include "modpoly.h" +#include "giacintl.h" +#ifdef USE_GMP_REPLACEMENTS +#undef HAVE_LIBPARI +#endif + +#ifdef HAVE_LIBPARI + +#ifdef HAVE_PTHREAD_H +#include +#endif + +static long int abs(long int & l){ + if (l<0) + return -l; + else + return l; +} +#include "pari.h" +extern "C" { +#include +#include +#ifdef ENABLE_TLS + extern THREAD void *PARI_stack_limit; +#else + extern void *PARI_stack_limit; +#endif + extern entree functions_basic[]; +} +jmp_buf env; +static void +gp_err_recover(long numerr) +{ + longjmp(env, numerr); +} + +#include + +#ifndef NO_NAMESPACE_GIAC +namespace giac { +#endif // ndef NO_NAMESPACE_GIAC + + static map pari_function_table; + + static long pari_mem_size=512000; + static long pari_maxprime=100000; + static struct pari_constants_initialization { + + pari_constants_initialization () { + + if (getenv("PARI_SIZE")){ + string pari_size_s(getenv("PARI_SIZE")); + pari_mem_size= atoi(pari_size_s.c_str()); + } + entree * ptr=functions_basic; + for (;ptr->name;++ptr){ + pari_function_table[ptr->name]=ptr; + } + } + } pari_constants_initialization_singleton; + + static void call_pari_init() + { + // do not initialize INIT_JMP so that PARI error do not exit + pari_init_opts(pari_mem_size,pari_maxprime,INIT_SIGm | INIT_DFTm); + paristack_setsize(pari_mem_size, (1<<30)); + // initialize variable ordering x,y,z + gp_read_str("[x,y,z,t]"); + } + +#ifdef ENABLE_TLS // pari is MT-safe, so needs init in each thread + + struct ensure_pari_is_ready { + + ensure_pari_is_ready() { call_pari_init(); } + + ~ensure_pari_is_ready() { pari_close(); } + }; +#elif HAVE_LIBPTHREAD // pari is not MT-safe, so single init and multiple locks! + + static pthread_mutex_t *pari_mutex_ptr = 0; + + static struct pari_initialization { + + pari_initialization () + { + pthread_mutex_t tmp = PTHREAD_MUTEX_INITIALIZER; + pari_mutex_ptr = new pthread_mutex_t(tmp); + call_pari_init(); + } + + ~pari_initialization () + { + pari_close(); + delete pari_mutex_ptr; + } + } pari_initialization_singleton; + + struct ensure_pari_is_ready { + + ensure_pari_is_ready() { pthread_mutex_lock(pari_mutex_ptr); } + + ~ensure_pari_is_ready() { pthread_mutex_unlock(pari_mutex_ptr); } + }; +#else // pari is not MT-safe and we don't have threads - does it happen?! + + static struct pari_initialization { + + pari_initialization () + { + pthread_mutex_t tmp = PTHREAD_MUTEX_INITIALIZER; + pari_mutex_ptr = new pthread_mutex_t(tmp); + call_pari_init(); + } + + ~pari_initialization () + { + pari_close(); + delete pari_mutex_ptr; + } + } pari_initialization_singleton; + + struct ensure_pari_is_ready {}; + +#endif + + static gen pow2sizeof_long(pow(256,sizeof(long))); + // Conversion of a GEN integer to a gen, using Horner method + static gen t_INT2gen(const GEN & G){ + long Gs=signe(G); + if (!Gs) + return 0; + long Gpl=lgefint(G)-2; + // use one of the following code depending how pari codes long integers + // Code 1 +#if !defined(__APPLE__) && !defined(WIN32) || defined(WIN64) + ref_mpz_t * mz = new ref_mpz_t; + mpz_realloc2(mz->z,32*Gpl); + mpz_import(mz->z,Gpl,-1,sizeof(GEN),0,0,&G[2]); + if (Gs>0) + return mz; + else + return -gen(mz); +#else + // Code 2 + --Gpl; + long * Gp=int_MSW(G); + gen res; + for (int i=0;i<=Gpl;++i){ +#ifdef INT128 + res=res*pow2sizeof_long+int128_t((ulonglong)*Gp); +#else + res=res*pow2sizeof_long+longlong(unsigned(*Gp)); +#endif + Gp=int_precW(Gp); + } + return Gs<0?-res:res; +#endif + } + + static gen t_REAL2gen(const GEN & G){ + long Gs=signe(G); + if (!Gs) + return 0.0; + long n=lg(G); + gen res; + for (int i=2;i>1)); +#else + res=res*pow2sizeof_long+longlong(unsigned(G[i])); +#endif + } + res=res*pow(plus_two,int(expo(G)+1-bit_accuracy(n))); + res=_evalf(makesequence(res,int(n/3.3)),context0); + return Gs<0?-res:res; + } + + static gen t_POL2gen(const GEN & G,const vecteur & vars){ + if (!signe(G)) + return 0; + long n=lg(G); + vecteur res; + for (long i=2;isize()==2){ + n=tmp._VECTptr->front(); + if (n.type==_VECT) n.subtype=_POLY1__VECT; + d=tmp._VECTptr->back(); + } + return eval(symbolic(at_rootof,makesequence(n,change_subtype(GEN2gen((GEN) G[1],vars),_POLY1__VECT))),1,context0)/d; + find_or_make_symbol("Mod",tmp,0,false,context0); + return symbolic(at_of,makesequence(tmp,gen(makevecteur(GEN2gen((GEN) G[2],vars),GEN2gen((GEN) G[1],vars)),_SEQ__VECT))); + } + + static gen t_COMPLEX2gen(const GEN & G,const vecteur & vars){ + return gen(GEN2gen((GEN) G[1],vars),GEN2gen((GEN) G[2],vars)); + } + + static gen t_FRAC2gen(const GEN & G,const vecteur & vars){ + return fraction(GEN2gen((GEN)G[1],vars),GEN2gen((GEN)G[2],vars)); + } + + static gen t_QUAD2gen(const GEN & G,const vecteur & vars){ + // use w__IDNT_e like pari for all quadratics + return GEN2gen((GEN) G[1],vars)+w__IDNT_e*GEN2gen((GEN)G[2],vars); + } + + static gen t_PADIC2gen(const GEN & G,const vecteur & vars){ + gen O; + find_or_make_symbol("O",O,0,false,context0); + gen p(GEN2gen((GEN) G[2],vars)),val(longlong(valp(G))); + return pow(p,val,context0)*(GEN2gen((GEN) G[4],vars)+symbolic(at_of,makesequence(O,symb_pow(p,longlong(precp(G)))))); // removed symb_quote for p-adic + } + + // WARNING: If g is a matrix this print the transpose of the matrix + static string GEN2string(const GEN & g){ + char * ch; + string s; + if ((typ(g)==t_MAT) || (typ(g)==t_COL)){ + int taille=lg(g); + s +="["; + for (int i=1;ibegin(),itend=e._VECTptr->end(); + for (;it!=itend;++it){ + res += pariprint_VECT(*it->_VECTptr,varnum,_SEQ__VECT,contextptr); + if (it+1!=itend) + res += ";"; + else + res +="]"; + } + return res; + } + + static string pariprint(const gen & e,int varnum,GIAC_CONTEXT){ + int py=python_compat(contextptr); + python_compat(0,contextptr); + int save_maple_mode=xcas_mode(contextptr); + xcas_mode(contextptr)=1; + string res; + switch (e.type){ + case _INT_: + res=print_INT_(e.val); + break; + case _ZINT: + res=e.print(contextptr); + break; + case _CPLX: + res=e._CPLXptr->print(contextptr)+"+I*"+(e._CPLXptr+1)->print(contextptr); + break; + case _VECT: + if (ckmatrix(e)) + res=pariprintmatrice(e,varnum,contextptr); + else + res=pariprint_VECT(*e._VECTptr,varnum,e.subtype,contextptr); + break; + case _SYMB: + if (e._SYMBptr->sommet==at_rootof && e._SYMBptr->feuille.type==_VECT && e._SYMBptr->feuille._VECTptr->size()==2) + res="Mod("+pariprint(e._SYMBptr->feuille._VECTptr->front(),varnum,contextptr)+","+pariprint(e._SYMBptr->feuille._VECTptr->back(),varnum,contextptr)+")"; + else { + if (e._SYMBptr->sommet.ptr()->printsommet) // FIXME + res=e.print(contextptr); + else + res=string(e._SYMBptr->sommet.ptr()->s)+"("+pariprint(e._SYMBptr->feuille,varnum,contextptr)+")"; + } + break; + case _MOD: + res= "Mod("+pariprint(*e._MODptr,varnum,contextptr)+","+pariprint(*(e._MODptr+1),varnum,contextptr)+")"; + break; + case _FRAC: + res= pariprint(*e._FRACptr,varnum,contextptr)+"/("+pariprint(*(e._FRACptr+1),varnum,contextptr)+")"; + break; + default: // _SYMB with printsommetasoperator, _DOUBLE_, _REAL, _IDNT + res=e.print(contextptr); + } + xcas_mode(contextptr)=save_maple_mode; + python_compat(py,contextptr); + return res; + } + + static GEN zint2GEN(const gen & g){ + mpz_t * zz=g._ZINTptr; + int sgn=mpz_sgn(*zz); + if (!sgn) + return utoi(0); + int count=mpz_sizeinbase(*zz,2); + if (count % (8*sizeof(GEN))) + count=count/(8*sizeof(GEN))+3; + else + count=count/(8*sizeof(GEN))+2; + GEN G=cgetg(count,t_INT); + setlgefint(G,count); + setsigne(G,sgn); + gen q(abs(g)),tmp,r; + GEN Gstep(int2n(16)); + vector v; + for (;!is_zero(q);){ + r=irem(q,gen(1<<16),tmp); + v.push_back(r.val); + q=tmp; + } + int s=v.size(); + GEN res(utoi(0)); + for (int i=s-1;i>=0;--i){ + res=gmul(res,Gstep); + res=gadd(res,utoi(v[i])); + } + setsigne(res,sgn); + return res; + } + + static GEN ingen2GEN(const gen & e,const vecteur & vars,GIAC_CONTEXT); + + static GEN vect2GEN(const gen & g,const vecteur & vars,GIAC_CONTEXT){ + vecteur v (*g._VECTptr); + int n=v.size(),decal=1; + GEN res; + if (g.subtype==_POLY1__VECT){ + decal=2; + res=cgetg(n+decal,t_POL); + reverse(v.begin(),v.end()); + } + else { + res=cgetg(n+decal,g.subtype==99?t_COL:(g.subtype==98?t_VECSMALL:t_VEC)); + } + for (int i=0;isize(); + GEN res=cgetg(n+1,t_MAT); + for (int i=1;i<=n;++i){ + GEN resi=gel(res,i)=cgetg(m+1,t_COL); + vecteur & v = *M[i-1]._VECTptr; + for (int j=1;j<=m;++j){ + gel(resi,j)=ingen2GEN(v[j-1],vars,contextptr); + } + } + return res; + } + + static GEN cplx2GEN(const gen & g,const vecteur & vars,GIAC_CONTEXT){ + GEN res=cgetg(3,t_COMPLEX); + gel(res,1)=ingen2GEN(*g._CPLXptr,vars,contextptr); + gel(res,2)=ingen2GEN(*(g._CPLXptr+1),vars,contextptr); + return res; + } + + static GEN frac2GEN(const gen & g,const vecteur & vars,GIAC_CONTEXT){ + GEN res=cgetg(3,t_FRAC); + gel(res,1)=ingen2GEN(g._FRACptr->num,vars,contextptr); + gel(res,2)=ingen2GEN(g._FRACptr->den,vars,contextptr); + return res; + } + + static GEN real2GEN(const gen & e_,GIAC_CONTEXT){ + gen e(e_); + bool neg=false; + if (is_strictly_positive(-e,contextptr)){ + e=-e; + neg=true; + } + int prec=53; +#ifdef HAVE_LIBMPFR + if (e.type==_REAL) + prec=mpfr_get_prec(e._REALptr->inf); +#endif + string s(e.print(contextptr)); + GEN g=strtor(s.c_str(),prec); + if (neg) + g=gneg(g); + if (debug_infolevel) + CERR << "real converted to pari " << GEN2gen(g,vecteur(0)) << '\n'; + else e=GEN2gen(g,vecteur(0)); + // for some strange reason, converting g to a gen fixes a bug in conversion + return g; + } + + static GEN ingen2GEN(const gen & e,const vecteur & vars,GIAC_CONTEXT){ + switch (e.type){ + case _INT_: + return stoi(e.val); + case _ZINT: + return zint2GEN(e); + case _CPLX: + return cplx2GEN(e,vars,contextptr); + case _FRAC: + return frac2GEN(e,vars,contextptr); + case _DOUBLE_: case _REAL: + return real2GEN(e,contextptr); + case _VECT: + if (ckmatrix(e)) + return mat2GEN(e,vars,contextptr); + else + return vect2GEN(e,vars,contextptr); + } + // add vars to e + string s=pariprint(e,0,contextptr); + vecteur vars_(vars); + if (!vars_.empty()) + s="["+(vars_.size()==1?vars_.front().print():print_VECT(vars_,_SEQ__VECT,contextptr))+","+s+"]"; + GEN res= gp_read_str((char *) s.c_str()); + // gp_read_str seems to have problems with large strings (s.size()>2^16?) + return vars_.empty()?res:gel(res,1+vars_.size()); + } + GEN gen2GEN(const gen & e,const vecteur & vars,GIAC_CONTEXT){ + cb_pari_err_recover=gp_err_recover; + if (setjmp(env)){ + setsizeerr(gettext("Error in PARI subsystem")); + } + return ingen2GEN(e,vars,contextptr); + } + + gen pari_isprime(const gen & e,int certif){ + gen tmp; + ensure_pari_is_ready now; + long av=avma; + tmp=GEN2gen(gisprime(gen2GEN(e,vecteur(0),0),certif),vecteur(0)); + avma=av; + return tmp; + } + + string pari_ifactor(const gen & e){ + string s; + ensure_pari_is_ready now; + long av=avma; + GEN g=gen2GEN(e,vecteur(0),0); + GEN gf=factorint(g,0); + s=GEN2string(gf); + avma=av; + return s; + } + + gen pari_gamma(const gen & e){ + gen res; + ensure_pari_is_ready now; + long av=avma; + GEN g=gen2GEN(e,vecteur(0),0); + GEN gf=ggamma(g,precision(g)); + res=GEN2gen(gf,vecteur(0)); + avma=av; + return res; + } + + gen pari_zeta(const gen & e){ + gen res; + ensure_pari_is_ready now; + long av=avma; + GEN g=gen2GEN(e,vecteur(0),0); + GEN gf=gzeta(g,precision(g)); + res=GEN2gen(gf,vecteur(0)); + avma=av; + return res; + } + + gen pari_psi(const gen & e){ + gen res; + ensure_pari_is_ready now; + long av=avma; + GEN g=gen2GEN(e,vecteur(0),0); + GEN gf=gpsi(g,precision(g)); + res=GEN2gen(gf,vecteur(0)); + avma=av; + return res; + } + + gen pari_ffinit(const gen & p,int n){ + gen tmp; + ensure_pari_is_ready now; + long av=avma; + tmp=GEN2gen(ffinit(gen2GEN(p,vecteur(0),0),n,0),vecteur(0)); + avma=av; + return tmp; + } + + // for factorization over Z when many modular factors arise + // This is a call to PARI combine_factors + // WARNING: You must remove static from the declaration of combine_factors + // in pari/src/basemath/polarith2.c + // GEN combine_factors(GEN a, GEN famod, GEN p, long klim, long hint); + bool pari_lift_combine(const vecteur & a,const vector & factmod,gen & modulo,vector & res){ + return false; + } + + static gen pari_exec(const string & s,GIAC_CONTEXT){ + ensure_pari_is_ready now; + long av=avma; + void * save_pari_stack_limit = PARI_stack_limit; + PARI_stack_limit=0; // required since the stack changed + cb_pari_err_recover=gp_err_recover; + if (setjmp(env)) + { + avma = av; + *logptr(contextptr) << gettext("Error in PARI subsystem") << '\n'; + PARI_stack_limit = save_pari_stack_limit ; + return undef; + } + GEN gres= gp_read_str((char *) s.c_str()); + gen res=GEN2gen(gres,vecteur(0)); + avma=av; + PARI_stack_limit = save_pari_stack_limit ; + return res; + } + +#include "input_parser.h" +#define _ARGS_ argvec[0], argvec[1], argvec[2], argvec[3],\ + argvec[4], argvec[5], argvec[6], argvec[7], argvec[8] + // args=pari_function_name, arg1, ... + // or pari_function_name quoted to define a function + + enum { + RET_GEN=0, + RET_VOID=1, + RET_INT=2, + RET_LONG=3 + }; + typedef GEN (*PFGEN)(ANYARG); + + extern const unary_function_ptr * const at_pari; + static gen in_pari(const gen & args,GIAC_CONTEXT){ + if (args.type<_IDNT) + return args; + vecteur v(gen2vecteur(args)); + int vs=v.size(); + if (!vs){ // export all pari functions + entree * ptr=functions_basic; + gen tmp; int lextype; + string redef; + for (;ptr->name;++ptr){ + pari_function_table[ptr->name]=ptr; + lextype=find_or_make_symbol(ptr->name,tmp,0,false,contextptr); + if (lextype==T_SYMBOL) + sto(symbolic(at_pari,string2gen(ptr->name,false)),tmp,contextptr); + else + redef += string(ptr->name) + " "; + find_or_make_symbol(string("pari_")+ptr->name,tmp,0,false,contextptr); + sto(symbolic(at_pari,string2gen(ptr->name,false)),tmp,contextptr); + } + return string2gen("All PARI functions are now defined with the pari_ prefix.\nPARI functions are also defined without prefix except:\n"+redef+"\nWhen working with p-adic numbers use them in a pari() call\nType ?pari for short help\nInside xcas, try Help->Manuals->PARI for HTML help",false); + } + if (v[0].is_symb_of_sommet(at_quote)){ + if (vs==1) + return symbolic(at_pari,args); + v[0]=v[0]._SYMBptr->feuille; + } + for (int i=1;i::const_iterator i = pari_function_table.find(vstr); + // look at function prototype for return value + // and call code, from anal.c line around 1990 + unsigned int ret; + if (i!=pari_function_table.end()){ + const char * s =i->second->code; + if (*s < 'a') ret = RET_GEN; + else if (*s == 'v') { ret = RET_VOID; s++; } + else if (*s == 'i') { ret = RET_INT; s++; } + else if (*s == 'l') { ret = RET_LONG; s++; } + else ret = RET_GEN; + void * call= i->second->value; + // translate gen to GEN's + GEN argvec[9]={0,0,0,0,0,0,0,0,0},res; long m; + int k=0; + for (int j=1;k<9 && *s && *s!='\n';++s){ + switch(*s){ + case 'L': // long + if (j==vs) { + gen res=string2gen("PARI: Bad argument count",false); + res.subtype=-1; + return res; + } + argvec[k]= (GEN) v[j].val; + ++j; ++k; + break; + case 'P': // default precision + argvec[k] = (GEN) precdl; k++; break; + case 'D': //default param + { + ++s; + switch(*s){ + case 'G': case '&': case 'I': case 'V': + if (jptr()->s; + else + s=gen2string(v[0]); + if (vs>1){ + s+="("; + for (int i=1;incol;pos+=j,left-=j){ + for (j=ncol;j>ncol/2;--j){ + if (s[pos+j]==' ') + break; + } + res=res+s.substr(pos,j)+'\n'; + } + return res+s.substr(pos,pos+left); + } + + // Help for g calling PARI online help + std::string pari_help(const gen & g){ + if (is_zero(g)) + return "Run pari() to export PARI functions.\n?pari(1) to ?pari(11) lists PARI functions by section\n?pari_functionname shows a short help on a function\nInside Xcas, Help->Manual->PARI-GP shows HTML help"; + string res; + if (g.type==_INT_){ + int section=g.val; + entree * ptr=functions_basic; + for (;ptr->name;++ptr){ + if (ptr->menu==section){ + res += ptr->name; + res += " "; + } + } + return cutstring(res,70); + } + string gs; + if (g.type==_FUNC) + gs=g._FUNCptr->ptr()->s; + else + gs=gen2string(g); + if (gs.size()>5 && gs.substr(0,5)=="pari_") + gs=gs.substr(5,gs.size()-5); + entree * ptr=functions_basic; + for (;ptr->name;++ptr){ + if (ptr->name==gs){ + res = ptr->help; + return cutstring(res,70); + } + } + return "PARI function not found\nHelp syntax: ?pari(1),...,?pari(12) or ?pari_functionname"; + } + + bool pari_polroots(const vecteur & p,vecteur & res,long prec,GIAC_CONTEXT){ + gen tmp; + ensure_pari_is_ready now; + long av=avma; + GEN G=gen2GEN(change_subtype(p,_POLY1__VECT),vecteur(0),contextptr); + if (debug_infolevel) + CERR << "pari_polroots " << GEN2gen(G,vecteur(1,vx_var)) << '\n'; + G=roots(G,prec); + tmp=GEN2gen(G,vecteur(0)); + avma=av; + if (tmp.type!=_VECT) + return false; + res=*tmp._VECTptr; + return true; + } + + bool pari_polresultant(const gen & p,const gen & q,const vecteur & lv,gen & res,GIAC_CONTEXT){ + gen tmp; + ensure_pari_is_ready now; + long av=avma; + void * save_pari_stack_limit = PARI_stack_limit; + PARI_stack_limit=0; + GEN P=gen2GEN(p,lv,contextptr); + GEN Q=gen2GEN(q,lv,contextptr); + GEN PQ=polresultant0(P,Q,-1,2); + tmp=GEN2gen(PQ,lv); + avma=av; + PARI_stack_limit=save_pari_stack_limit; + res=tmp; + return true; + } + + bool pari_nffactor(const gen & p,const gen & pmin,const vecteur & lv,gen & res,GIAC_CONTEXT){ + gen tmp; + ensure_pari_is_ready now; + long av=avma; + void * save_pari_stack_limit = PARI_stack_limit; + PARI_stack_limit=0; + GEN P=gen2GEN(p,lv,contextptr); + GEN Pmin=gen2GEN(pmin,lv,contextptr); + int prec=decimal_digits(contextptr); + if (prec<30) + prec=30; + tmp=GEN2gen(nffactor(Pmin,P),lv); + avma=av; + PARI_stack_limit=save_pari_stack_limit; + res=tmp; + return true; + } + + bool pari_galoisconj(const gen & g,vecteur & w,GIAC_CONTEXT){ + gen res; + res=in_pari(makesequence(string2gen("nfgaloisconj",false),g),contextptr); + if (res.type!=_VECT) + return false; + w=*res._VECTptr; + gen gp=_symb2poly(makesequence(g,vx_var),contextptr); + for (int i=0;i& factmod, + gen& modulo, std::vector& res){ + vecteur tmp(1,pari_error()); + res=std::vector(1,tmp); + return false; + } + + bool pari_galoisconj(const gen & g,vecteur & w,GIAC_CONTEXT){ + return false; + } + + gen _pari(const gen & args,GIAC_CONTEXT){ + if ( args.type==_STRNG && args.subtype==-1) return args; + return pari_error(); + } + + std::string pari_help(const gen & g){ + return "please recompile giac with PARI"; + } + + gen GEN2gen(const GEN & G,const vecteur & vars){ + return gensizeerr("please recompile giac with PARI"); + } + GEN gen2GEN(const gen & e,const vecteur & vars,GIAC_CONTEXT){ + return 0; + } + + bool pari_polroots(const vecteur & p,vecteur & res,long prec,GIAC_CONTEXT){ + return false; + } + bool pari_polresultant(const gen & p,const gen & q,const vecteur & lv,gen & res,GIAC_CONTEXT){ + return false; + } + bool pari_nffactor(const gen & p,const gen & pmin,const vecteur & lv,gen & res,GIAC_CONTEXT){ + return false; + } + static const char _pari_s []="pari"; + static define_unary_function_eval (__pari,&_pari,_pari_s); + define_unary_function_ptr5( at_pari ,alias_at_pari,&__pari,_QUOTE_ARGUMENTS,true); + + static const char _pari_unlock_s []="pari_unlock"; + static define_unary_function_eval (__pari_unlock,&_pari,_pari_unlock_s); + define_unary_function_ptr5( at_pari_unlock ,alias_at_pari_unlock,&__pari_unlock,_QUOTE_ARGUMENTS,true); + + +#ifndef NO_NAMESPACE_GIAC +} +#endif // ndef NO_NAMESPACE_GIAC + +#endif // HAVE_LIBPARI diff -Nru giac-1.5.0.87+dfsg1/debian/patches/d-workaround-armhf-hang.patch giac-1.5.0.87+dfsg1/debian/patches/d-workaround-armhf-hang.patch --- giac-1.5.0.87+dfsg1/debian/patches/d-workaround-armhf-hang.patch 2020-02-13 13:12:23.000000000 +0000 +++ giac-1.5.0.87+dfsg1/debian/patches/d-workaround-armhf-hang.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -Description: Work around a hanging test on armhf - This is a very hacky work around that only hides the failure - but not the underlying cause, see bug report for details -Author: Ximin Luo -Bug: https://xcas.univ-grenoble-alpes.fr/forum/viewtopic.php?f=4&t=2109 ---- a/check/testcas -+++ b/check/testcas -@@ -150,7 +150,7 @@ - ichinrem([12,10],[13,5]); - is_prime(9856989898997); - is_prime(1999); --is_prime(25); -+//is_prime(25); - is_prime(97160249868928888261606009); - nextprime(9856989898990); - nextprime(97160249868928888261606009); ---- a/check/cas.out -+++ b/check/cas.out -@@ -151,7 +151,6 @@ - 1, - 1, - 0, --0, - 9856989898997, - 97160249868928888261606031, - 97160249868928888261605967, diff -Nru giac-1.5.0.87+dfsg1/debian/patches/series giac-1.5.0.87+dfsg1/debian/patches/series --- giac-1.5.0.87+dfsg1/debian/patches/series 2020-05-20 08:23:30.000000000 +0000 +++ giac-1.5.0.87+dfsg1/debian/patches/series 2020-05-31 11:00:08.000000000 +0000 @@ -19,4 +19,3 @@ d-find-doc-files-at-buildtime.patch d-dont-include-remote-scripts.patch define_doubleval_for_bigendian.patch -d-workaround-armhf-hang.patch diff -Nru giac-1.5.0.87+dfsg1/debian/rules giac-1.5.0.87+dfsg1/debian/rules --- giac-1.5.0.87+dfsg1/debian/rules 2020-05-20 08:23:41.000000000 +0000 +++ giac-1.5.0.87+dfsg1/debian/rules 2020-05-31 11:00:08.000000000 +0000 @@ -19,6 +19,8 @@ export HOME=/nonexistent override_dh_autoreconf: +# Use experimental pari code + cp debian/pari.cc src/ # Deal with embedded stuff find doc/ -maxdepth 1 -type d -exec ln -sf /usr/share/texmf/tex/texinfo/texinfo.tex '{}/' \; # Deal with emscripten placeholder diff -Nru giac-1.5.0.87+dfsg1/debian/upstream-doc-fr/algo.tex giac-1.5.0.87+dfsg1/debian/upstream-doc-fr/algo.tex --- giac-1.5.0.87+dfsg1/debian/upstream-doc-fr/algo.tex 2020-03-04 07:18:55.000000000 +0000 +++ giac-1.5.0.87+dfsg1/debian/upstream-doc-fr/algo.tex 2020-05-31 11:00:08.000000000 +0000 @@ -54,7 +54,7 @@ \author{B. Parisse\\Institut Fourier\\UMR 5582 du CNRS \\Université de Grenoble} -\date{} +\date{27 février 2020} \makeindex