Code coverage tests

This page documents the degree to which the PARI/GP source code is tested by our public test suite, distributed with the source distribution in directory src/test/. This is measured by the gcov utility; we then process gcov output using the lcov frond-end.

We test a few variants depending on Configure flags on the pari.math.u-bordeaux.fr machine (x86_64 architecture), and agregate them in the final report:

The target is to exceed 90% coverage for all mathematical modules (given that branches depending on DEBUGLEVEL or DEBUGMEM are not covered). This script is run to produce the results below.

LCOV - code coverage report
Current view: top level - language - anal.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.12.1 lcov report (development 25819-e703fe1174) Lines: 634 691 91.8 %
Date: 2020-09-18 06:10:04 Functions: 95 101 94.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2000  The PARI group.
       2             : 
       3             : This file is part of the PARI/GP package.
       4             : 
       5             : PARI/GP is free software; you can redistribute it and/or modify it under the
       6             : terms of the GNU General Public License as published by the Free Software
       7             : Foundation. It is distributed in the hope that it will be useful, but WITHOUT
       8             : ANY WARRANTY WHATSOEVER.
       9             : 
      10             : Check the License for details. You should have received a copy of it, along
      11             : with the package; see the file 'COPYING'. If not, write to the Free Software
      12             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      13             : 
      14             : #include "pari.h"
      15             : #include "paripriv.h"
      16             : #include "anal.h"
      17             : #include "parse.h"
      18             : 
      19             : /***************************************************************************
      20             :  **                                                                       **
      21             :  **                           Mnemonic codes parser                       **
      22             :  **                                                                       **
      23             :  ***************************************************************************/
      24             : 
      25             : /* TEMPLATE is assumed to be ";"-separated list of items.  Each item
      26             :  * may have one of the following forms: id=value id==value id|value id&~value.
      27             :  * Each id consists of alphanum characters, dashes and underscores.
      28             :  * IDs are case-sensitive.
      29             : 
      30             :  * ARG consists of several IDs separated by punctuation (and optional
      31             :  * whitespace).  Each modifies the return value in a "natural" way: an
      32             :  * ID from id=value should be the first in the sequence and sets RETVAL to
      33             :  * VALUE (and cannot be negated), ID from id|value bit-ORs RETVAL with
      34             :  * VALUE (and bit-ANDs RETVAL with ~VALUE if negated), ID from
      35             :  * id&~value behaves as if it were noid|value, ID from
      36             :  * id==value behaves the same as id=value, but should come alone.
      37             : 
      38             :  * For items of the form id|value and id&~value negated forms are
      39             :  * allowed: either when arg looks like no[-_]id, or when id looks like
      40             :  * this, and arg is not-negated. */
      41             : 
      42             : static int
      43         380 : IS_ID(char c) { return isalnum((int)c) || c == '_'; }
      44             : long
      45          28 : eval_mnemonic(GEN str, const char *tmplate)
      46             : {
      47             :   const char *arg, *etmplate;
      48          28 :   ulong retval = 0;
      49             : 
      50          28 :   if (typ(str)==t_INT) return itos(str);
      51          28 :   if (typ(str)!=t_STR) pari_err_TYPE("eval_mnemonic",str);
      52             : 
      53          28 :   arg = GSTR(str);
      54          28 :   etmplate = strchr(tmplate, '\n');
      55          28 :   if (!etmplate) etmplate = tmplate + strlen(tmplate);
      56             : 
      57             :   while (1)
      58          36 :   {
      59             :     long numarg;
      60          64 :     const char *e, *id, *negated = NULL;
      61          64 :     int negate = 0; /* Arg has 'no' prefix removed */
      62             :     ulong l;
      63             :     char *buf;
      64             :     static char b[80];
      65             : 
      66          64 :     while (isspace((int)*arg)) arg++;
      67          64 :     if (!*arg) break;
      68         364 :     e = arg; while (IS_ID(*e)) e++;
      69             :     /* Now the ID is whatever is between arg and e. */
      70          36 :     l = e - arg;
      71          36 :     if (l >= sizeof(b)) pari_err(e_MISC,"id too long in a mnemonic");
      72          36 :     if (!l) pari_err(e_MISC,"mnemonic does not start with an id");
      73          36 :     strncpy(b, arg, l); b[l] = 0;
      74          36 :     arg = e; e = buf = b;
      75          36 :     while ('0' <= *e && *e <= '9') e++;
      76          36 :     if (*e == 0) pari_err(e_MISC,"numeric id in a mnemonic");
      77          36 : FIND:
      78          36 :     id = tmplate;
      79          36 :     while ((id = strstr(id, buf)) && id < etmplate)
      80             :     {
      81          36 :       const char *s = id;
      82          36 :       id += l; if (s[l] != '|') continue; /* False positive */
      83          36 :       if (s == tmplate || !IS_ID(s[-1])) break; /* Found as is */
      84             :       /* If we found "no_ID", negate */
      85           0 :       if (!negate && s >= tmplate+3 && (s == tmplate+3 || !IS_ID(s[-4]))
      86           0 :           && s[-3] == 'n' && s[-2] == 'o' && s[-1] == '_')
      87           0 :          { negated = id; break; }
      88             :     }
      89          36 :     if (!id && !negated && !negate && l > 3
      90           0 :             && buf[0] == 'n' && buf[1] == 'o' && buf[2] == '_')
      91             :     { /* Try to find the flag without the prefix "no_". */
      92           0 :       buf += 3; l -= 3; negate = 1;
      93           0 :       if (buf[0]) goto FIND;
      94             :     }
      95             :     /* Negated and AS_IS forms, prefer AS_IS otherwise use negated form */
      96          36 :     if (!id)
      97             :     {
      98           0 :       if (!negated) pari_err(e_MISC,"Unrecognized id '%s' in mnemonic", b);
      99           0 :       id = negated; negate = 1;
     100             :     }
     101          36 :     if (*id++ != '|') pari_err(e_MISC,"Missing | in mnemonic template");
     102          36 :     e = id;
     103          88 :     while (*e >= '0' && *e <= '9') e++;
     104          36 :     while (isspace((int)*e)) e++;
     105          36 :     if (*e && *e != ';' && *e != ',')
     106           0 :       pari_err(e_MISC, "Non-numeric argument in mnemonic template");
     107          36 :     numarg = atol(id);
     108          36 :     if (negate) retval &= ~numarg; else retval |= numarg;
     109          36 :     while (isspace((int)*arg)) arg++;
     110          36 :     if (*arg && !ispunct((int)*arg++)) /* skip punctuation */
     111           0 :       pari_err(e_MISC,"Junk after id in mnemonic");
     112             :   }
     113          28 :   return retval;
     114             : }
     115             : 
     116             : /********************************************************************/
     117             : /**                                                                **/
     118             : /**                   HASH TABLE MANIPULATIONS                     **/
     119             : /**                                                                **/
     120             : /********************************************************************/
     121             : static void
     122     2199611 : insertep(entree *ep, entree **table, ulong hash)
     123             : {
     124     2199611 :   ep->hash = hash;
     125     2199611 :   hash %= functions_tblsz;
     126     2199611 :   ep->next = table[hash];
     127     2199611 :   table[hash] = ep;
     128     2199611 : }
     129             : 
     130             : static entree *
     131       29815 : initep(const char *name, long len)
     132             : {
     133       29815 :   const long add = 4*sizeof(long);
     134       29815 :   entree *ep = (entree *) pari_calloc(sizeof(entree) + add + len+1);
     135       29815 :   entree *ep1 = initial_value(ep);
     136       29815 :   char *u = (char *) ep1 + add;
     137       29815 :   ep->name    = u; memcpy(u, name,len); u[len]=0;
     138       29815 :   ep->valence = EpNEW;
     139       29815 :   ep->value   = NULL;
     140       29815 :   ep->menu    = 0;
     141       29815 :   ep->code    = NULL;
     142       29815 :   ep->help    = NULL;
     143       29815 :   ep->pvalue  = NULL;
     144       29815 :   ep->arity   = 0;
     145       29815 :   return ep;
     146             : }
     147             : 
     148             : /* Look for s of length len in T; if 'insert', insert if missing */
     149             : static entree *
     150    10028281 : findentry(const char *s, long len, entree **T, int insert)
     151             : {
     152    10028281 :   ulong hash = hash_str_len(s, len);
     153             :   entree *ep;
     154    80390227 :   for (ep = T[hash % functions_tblsz]; ep; ep = ep->next)
     155    80360466 :     if (ep->hash == hash)
     156             :     {
     157     9998541 :       const char *t = ep->name;
     158     9998541 :       if (!strncmp(t, s, len) && !t[len]) return ep;
     159             :     }
     160             :   /* not found */
     161       29761 :   if (insert) { ep = initep(s,len); insertep(ep, T, hash); }
     162       29761 :   return ep;
     163             : }
     164             : entree *
     165        1399 : pari_is_default(const char *s)
     166        1399 : { return findentry(s, strlen(s), defaults_hash, 0); }
     167             : entree *
     168     3669022 : is_entry(const char *s)
     169     3669022 : { return findentry(s, strlen(s), functions_hash, 0); }
     170             : entree *
     171     6357860 : fetch_entry_raw(const char *s, long len)
     172     6357860 : { return findentry(s, len, functions_hash, 1); }
     173             : entree *
     174      391393 : fetch_entry(const char *s) { return fetch_entry_raw(s, strlen(s)); }
     175             : 
     176             : /*******************************************************************/
     177             : /*                                                                 */
     178             : /*                  SYNTACTICAL ANALYZER FOR GP                    */
     179             : /*                                                                 */
     180             : /*******************************************************************/
     181             : static GEN
     182        4478 : readseq_i(char *t)
     183             : {
     184        4478 :   if (gp_meta(t,0)) return gnil;
     185        4478 :   return closure_evalres(pari_compile_str(t));
     186             : }
     187             : GEN
     188        4478 : readseq(char *t)
     189        4478 : { pari_sp av = avma; return gerepileupto(av, readseq_i(t)); }
     190             : 
     191             : /* filtered readseq = remove blanks and comments */
     192             : GEN
     193           0 : gp_read_str(const char *s)
     194           0 : { pari_sp av = avma; return gerepileupto(av, readseq_i(gp_filter(s))); }
     195             : 
     196             : GEN
     197       10789 : compile_str(const char *s) { return pari_compile_str(gp_filter(s)); }
     198             : 
     199             : GEN
     200           0 : gp_read_str_bitprec(const char *s, long bitprec)
     201             : {
     202             :   GEN x;
     203           0 :   push_localbitprec(bitprec);
     204           0 :   x = gp_read_str(s);
     205           0 :   pop_localprec();
     206           0 :   return x;
     207             : }
     208             : 
     209             : GEN
     210           0 : gp_read_str_prec(const char *s, long prec)
     211           0 : { return gp_read_str_bitprec(s, prec2nbits(prec)); }
     212             : 
     213             : /* valid return type */
     214             : static int
     215     2147950 : isreturn(char c)
     216     2147950 : { return c == 'l' || c == 'v' || c == 'i' || c == 'm' || c == 'u'; }
     217             : 
     218             : /* if is known that 2 commas follow s; base-10 signed integer followed
     219             :  * by comma? */
     220             : static int
     221      427544 : is_long(const char *s)
     222             : {
     223      427544 :   while (isspace(*s)) s++;
     224      427544 :   if (*s == '+' || *s == '-') s++;
     225      855084 :   while (isdigit(*s)) s++;
     226      427544 :   return *s == ',';
     227             : }
     228             : /* if is known that 2 commas follow s; base-10 unsigned integer followed
     229             :  * by comma? */
     230             : static int
     231        1702 : is_ulong(const char *s)
     232             : {
     233        1702 :   while (isspace(*s)) s++;
     234        1702 :   if (*s == '+') s++;
     235        3396 :   while (isdigit(*s)) s++;
     236        1702 :   return *s == ',';
     237             : }
     238             : static long
     239     2147950 : check_proto(const char *code)
     240             : {
     241     2147950 :   long arity = 0;
     242     2147950 :   const char *s = code;
     243     2147950 :   if (isreturn(*s)) s++;
     244     7162168 :   while (*s && *s != '\n') switch (*s++)
     245             :   {
     246     3626754 :     case '&':
     247             :     case 'C':
     248             :     case 'G':
     249             :     case 'I':
     250             :     case 'J':
     251             :     case 'U':
     252             :     case 'L':
     253             :     case 'M':
     254             :     case 'P':
     255             :     case 'W':
     256             :     case 'f':
     257             :     case 'n':
     258             :     case 'p':
     259             :     case 'b':
     260             :     case 'r':
     261     3626754 :       arity++; break;
     262      126750 :     case 'E':
     263             :     case 's':
     264      126750 :       if (*s == '*') s++;
     265      126750 :       arity++; break;
     266     1095106 :     case 'D':
     267     1095106 :       switch(*s)
     268             :       {
     269      625300 :         case 'G': case '&': case 'n': case 'I': case 'E':
     270      625300 :         case 'P': case 's': case 'r': s++; arity++; break;
     271       16900 :         case 'V': s++; break;
     272           0 :         case 0:
     273           0 :           pari_err(e_SYNTAX,"function has incomplete prototype", s,code);
     274           0 :           break;
     275      452906 :         default:
     276             :         {
     277             :           const char *p;
     278             :           long i;
     279     2289892 :           for(i = 0, p = s; *p && i < 2; p++) i += *p==','; /* skip 2 commas */
     280      452906 :           if (i < 2) pari_err(e_SYNTAX,"missing comma",s,code);
     281      452906 :           arity++;
     282      452906 :           switch(p[-2])
     283             :           {
     284      427544 :             case 'L':
     285      427544 :               if (!is_long(s)) pari_err(e_SYNTAX,"not a long",s,code);
     286      427540 :               break;
     287        1702 :             case 'U':
     288        1702 :               if (!is_ulong(s)) pari_err(e_SYNTAX,"not an ulong",s,code);
     289        1694 :               break;
     290       23660 :             case 'G': case 'r': case 's': case 'M':
     291       23660 :               break;
     292           0 :             default: pari_err(e_SYNTAX,"incorrect type",s-2,code);
     293             :           }
     294      452894 :           s = p;
     295             :         }
     296             :       }
     297     1095094 :       break;
     298      165620 :     case 'V':
     299             :     case '=':
     300      165620 :     case ',': break;
     301           0 :     case '\n': break; /* Before the mnemonic */
     302           0 :     default:
     303           0 :       if (isreturn(s[-1]))
     304           0 :         pari_err(e_SYNTAX, "this code has to come first", s-1, code);
     305           0 :       pari_err(e_SYNTAX, "unknown parser code", s-1, code);
     306             :   }
     307     2147938 :   if (arity > 20) pari_err_IMPL("functions with more than 20 parameters");
     308     2147938 :   return arity;
     309             : }
     310             : static void
     311           8 : check_name(const char *name)
     312             : {
     313           8 :   const char *s = name;
     314           8 :   if (isalpha((int)*s))
     315          40 :     while (is_keyword_char(*++s)) /* empty */;
     316           8 :   if (*s) pari_err(e_SYNTAX,"not a valid identifier", s, name);
     317           8 : }
     318             : 
     319             : entree *
     320          20 : install(void *f, const char *name, const char *code)
     321             : {
     322          20 :   long arity = check_proto(code);
     323             :   entree *ep;
     324             : 
     325           8 :   check_name(name);
     326           8 :   ep = fetch_entry(name);
     327           8 :   if (ep->valence != EpNEW)
     328             :   {
     329           0 :     if (ep->valence != EpINSTALL)
     330           0 :       pari_err(e_MISC,"[install] identifier '%s' already in use", name);
     331           0 :     pari_warn(warner, "[install] updating '%s' prototype; module not reloaded", name);
     332           0 :     if (ep->code) pari_free((void*)ep->code);
     333             :   }
     334             :   else
     335             :   {
     336           8 :     ep->value = f;
     337           8 :     ep->valence = EpINSTALL;
     338             :   }
     339           8 :   ep->code = pari_strdup(code);
     340           8 :   ep->arity = arity; return ep;
     341             : }
     342             : 
     343             : static void
     344          18 : killep(entree *ep)
     345             : {
     346          18 :   GEN p = (GEN)initial_value(ep);
     347          18 :   freeep(ep);
     348          18 :   *p = 0; /* otherwise pari_var_create won't regenerate it */
     349          18 :   ep->valence = EpNEW;
     350          18 :   ep->value   = NULL;
     351          18 :   ep->pvalue  = NULL;
     352          18 : }
     353             : /* Kill ep, i.e free all memory it references, and reset to initial value */
     354             : void
     355          18 : kill0(const char *e)
     356             : {
     357          18 :   entree *ep = is_entry(e);
     358          18 :   if (!ep || EpSTATIC(ep)) pari_err(e_MISC,"can't kill that");
     359          18 :   killep(ep);
     360          18 : }
     361             : 
     362             : void
     363          50 : addhelp(const char *e, char *s)
     364             : {
     365          50 :   entree *ep = fetch_entry(e);
     366          50 :   void *f = (void *) ep->help;
     367          50 :   ep->help = pari_strdup(s);
     368          50 :   if (f && !EpSTATIC(ep)) pari_free(f);
     369          50 : }
     370             : 
     371             : /*******************************************************************/
     372             : /*                                                                 */
     373             : /*                              PARSER                             */
     374             : /*                                                                 */
     375             : /*******************************************************************/
     376             : 
     377             : #ifdef LONG_IS_64BIT
     378             : static const long MAX_DIGITS  = 19;
     379             : #else
     380             : static const long MAX_DIGITS  = 9;
     381             : #endif
     382             : 
     383             : static const long MAX_XDIGITS = BITS_IN_LONG>>2;
     384             : static const long MAX_BDIGITS = BITS_IN_LONG;
     385             : 
     386             : static int
     387    35967442 : ishex(const char **s)
     388             : {
     389    35967442 :   if (**s == '0' && ((*s)[1] == 'x' || (*s)[1] == 'X' ))
     390             :   {
     391         127 :     *s += 2;
     392         127 :     return 1;
     393             :   }
     394             :   else
     395    35967315 :     return 0;
     396             : }
     397             : 
     398             : static int
     399    35967491 : isbin(const char **s)
     400             : {
     401    35967491 :   if (**s == '0' && ((*s)[1] == 'b' || (*s)[1] == 'B' ))
     402             :   {
     403          49 :     *s += 2;
     404          49 :     return 1;
     405             :   }
     406             :   else
     407    35967442 :     return 0;
     408             : }
     409             : 
     410             : static ulong
     411          38 : bin_number_len(const char *s, long n)
     412             : {
     413          38 :   ulong m = 0;
     414             :   long i;
     415        1494 :   for (i = 0; i < n; i++,s++)
     416        1456 :     m = 2*m + (*s - '0');
     417          38 :   return m;
     418             : }
     419             : 
     420             : static int
     421        1484 : pari_isbdigit(int c)
     422             : {
     423        1484 :   return c=='0' || c=='1';
     424             : }
     425             : 
     426             : static ulong
     427         126 : hex_number_len(const char *s, long n)
     428             : {
     429         126 :   ulong m = 0;
     430             :   long i;
     431        1479 :   for(i = 0; i < n; i++, s++)
     432             :   {
     433             :     ulong c;
     434        1353 :     if( *s >= '0' && *s <= '9')
     435         695 :       c = *s - '0';
     436         658 :     else if( *s >= 'A' && *s <= 'F')
     437          84 :       c = *s - 'A' + 10;
     438             :     else
     439         574 :       c = *s - 'a' + 10;
     440        1353 :     m = 16*m + c;
     441             :   }
     442         126 :   return m;
     443             : }
     444             : 
     445             : static GEN
     446         106 : strtobin_len(const char *s, long n, long B, ulong num(const char *s, long n))
     447             : {
     448         106 :   long i, l = (n+B-1)/B;
     449             :   GEN N, Np;
     450         106 :   N = cgetipos(l+2);
     451         106 :   Np = int_LSW(N);
     452         164 :   for (i=1; i<l; i++, Np = int_nextW(Np))
     453          58 :     uel(Np, 0) = num(s+n-i*B, B);
     454         106 :   uel(Np, 0) = num(s, n-(i-1)*B);
     455         106 :   return int_normalize(N, 0);
     456             : }
     457             : 
     458             : static GEN
     459         106 : binary_read(const char **ps, long B, int is(int), ulong num(const char *s, long n))
     460             : {
     461         106 :   const char *s = *ps;
     462        2915 :   while (is((int)**ps)) (*ps)++;
     463         106 :   return strtobin_len(s, *ps-s, B, num);
     464             : }
     465             : 
     466             : static GEN
     467          28 : bin_read(const char **ps)
     468             : {
     469          28 :   return binary_read(ps, MAX_BDIGITS, pari_isbdigit, bin_number_len);
     470             : }
     471             : 
     472             : static GEN
     473          78 : hex_read(const char **ps)
     474             : {
     475          78 :   return binary_read(ps, MAX_XDIGITS, isxdigit, hex_number_len);
     476             : }
     477             : 
     478             : static ulong
     479     2657893 : dec_number_len(const char *s, long B)
     480             : {
     481     2657893 :   ulong m = 0;
     482             :   long n;
     483    40615198 :   for (n = 0; n < B; n++,s++)
     484    37957305 :     m = 10*m + (*s - '0');
     485     2657893 :   return m;
     486             : }
     487             : 
     488             : static GEN
     489      680111 : dec_strtoi_len(const char *s, long n)
     490             : {
     491      680111 :   const long B = MAX_DIGITS;
     492      680111 :   long i, l = (n+B-1)/B;
     493      680111 :   GEN V = cgetg(l+1, t_VECSMALL);
     494     2657893 :   for (i=1; i<l; i++)
     495     1977782 :     uel(V,i) = dec_number_len(s+n-i*B, B);
     496      680111 :   uel(V, i) = dec_number_len(s, n-(i-1)*B);
     497      680111 :   return fromdigitsu(V, powuu(10, B));
     498             : }
     499             : 
     500             : static GEN
     501      680111 : dec_read_more(const char **ps)
     502             : {
     503      680111 :   pari_sp av = avma;
     504      680111 :   const char *s = *ps;
     505    38637416 :   while (isdigit((int)**ps)) (*ps)++;
     506      680111 :   return gerepileuptoint(av, dec_strtoi_len(s, *ps-s));
     507             : }
     508             : 
     509             : static ulong
     510     7974053 : number(int *n, const char **s)
     511             : {
     512     7974053 :   ulong m = 0;
     513    35815469 :   for (*n = 0; *n < MAX_DIGITS && isdigit((int)**s); (*n)++,(*s)++)
     514    27841416 :     m = 10*m + (**s - '0');
     515     7974053 :   return m;
     516             : }
     517             : 
     518             : static GEN
     519     7898495 : dec_read(const char **s)
     520             : {
     521             :   int nb;
     522     7898495 :   ulong y  = number(&nb, s);
     523     7898495 :   if (nb < MAX_DIGITS)
     524     7218384 :     return utoi(y);
     525      680111 :   *s -= MAX_DIGITS;
     526      680111 :   return dec_read_more(s);
     527             : }
     528             : 
     529             : static GEN
     530        2769 : real_read_more(GEN y, const char **ps)
     531             : {
     532        2769 :   pari_sp av = avma;
     533        2769 :   const char *s = *ps;
     534        2769 :   GEN z = dec_read(ps);
     535        2769 :   long e = *ps-s;
     536        2769 :   return gerepileuptoint(av, addmulii(z, powuu(10, e), y));
     537             : }
     538             : 
     539             : static long
     540       75558 : exponent(const char **pts)
     541             : {
     542       75558 :   const char *s = *pts;
     543             :   long n;
     544             :   int nb;
     545       75558 :   switch(*++s)
     546             :   {
     547       75418 :     case '-': s++; n = -(long)number(&nb, &s); break;
     548           0 :     case '+': s++; /* Fall through */
     549         140 :     default: n = (long)number(&nb, &s);
     550             :   }
     551       75558 :   *pts = s; return n;
     552             : }
     553             : 
     554             : static GEN
     555         175 : real_0_digits(long n) {
     556         175 :   long b = (n > 0)? (long)(n/LOG10_2): (long)-((-n)/LOG10_2 + 1);
     557         175 :   return real_0_bit(b);
     558             : }
     559             : 
     560             : static GEN
     561       84636 : real_read(pari_sp av, const char **s, GEN y, long prec)
     562             : {
     563       84636 :   long l, n = 0;
     564       84636 :   switch(**s)
     565             :   {
     566           0 :     default: return y; /* integer */
     567       10296 :     case '.':
     568             :     {
     569       10296 :       const char *old = ++*s;
     570       10296 :       if (isalpha((int)**s) || **s=='.')
     571             :       {
     572        1211 :         if (**s == 'E' || **s == 'e') {
     573        1211 :           n = exponent(s);
     574        1211 :           if (!signe(y)) { set_avma(av); return real_0_digits(n); }
     575        1183 :           break;
     576             :         }
     577           0 :         --*s; return y; /* member */
     578             :       }
     579        9085 :       if (isdigit((int)**s)) y = real_read_more(y, s);
     580        9085 :       n = old - *s;
     581        9085 :       if (**s != 'E' && **s != 'e')
     582             :       {
     583        9078 :         if (!signe(y)) { set_avma(av); return real_0(prec); }
     584        8105 :         break;
     585             :       }
     586             :     }
     587             :     /* Fall through */
     588             :     case 'E': case 'e':
     589       74347 :       n += exponent(s);
     590       74347 :       if (!signe(y)) { set_avma(av); return real_0_digits(n); }
     591             :   }
     592       83488 :   l = nbits2prec(bit_accuracy(lgefint(y)));
     593       83488 :   if (l < prec) l = prec; else prec = l;
     594       83488 :   if (!n) return itor(y, prec);
     595       77438 :   incrprec(l);
     596       77438 :   y = itor(y, l);
     597       77438 :   if (n > 0)
     598          63 :     y = mulrr(y, rpowuu(10UL, (ulong)n, l));
     599             :   else
     600       77375 :     y = divrr(y, rpowuu(10UL, (ulong)-n, l));
     601       77438 :   return gerepileuptoleaf(av, rtor(y, prec));
     602             : }
     603             : 
     604             : static GEN
     605     7811196 : int_read(const char **s)
     606             : {
     607             :   GEN y;
     608     7811196 :   if (isbin(s))
     609          28 :     y = bin_read(s);
     610     7811168 :   else if (ishex(s))
     611          78 :     y = hex_read(s);
     612             :   else
     613     7811090 :     y = dec_read(s);
     614     7811196 :   return y;
     615             : }
     616             : 
     617             : GEN
     618     7811196 : strtoi(const char *s) { return int_read(&s); }
     619             : 
     620             : GEN
     621       84636 : strtor(const char *s, long prec)
     622             : {
     623       84636 :   pari_sp av = avma;
     624       84636 :   GEN y = dec_read(&s);
     625       84636 :   y = real_read(av, &s, y, prec);
     626       84636 :   if (typ(y) == t_REAL) return y;
     627           0 :   return gerepileuptoleaf(av, itor(y, prec));
     628             : }
     629             : 
     630             : static void
     631     7819002 : skipdigits(char **lex) {
     632    61465131 :   while (isdigit((int)**lex)) ++*lex;
     633     7819002 : }
     634             : 
     635             : static int
     636     7814432 : skipexponent(char **lex)
     637             : {
     638     7814432 :   char *old=*lex;
     639     7814432 :   if ((**lex=='e' || **lex=='E'))
     640             :   {
     641        1022 :     ++*lex;
     642        1022 :     if ( **lex=='+' || **lex=='-' ) ++*lex;
     643        1022 :     if (!isdigit((int)**lex))
     644             :     {
     645         469 :       *lex=old;
     646         469 :       return KINTEGER;
     647             :     }
     648         553 :     skipdigits(lex);
     649         553 :     return KREAL;
     650             :   }
     651     7813410 :   return KINTEGER;
     652             : }
     653             : 
     654             : static int
     655     7815520 : skipconstante(char **lex)
     656             : {
     657     7815520 :   skipdigits(lex);
     658     7815520 :   if (**lex=='.')
     659             :   {
     660       15518 :     char *old = ++*lex;
     661       15518 :     if (**lex == '.') { --*lex; return KINTEGER; }
     662       14430 :     if (isalpha((int)**lex))
     663             :     {
     664       11501 :       skipexponent(lex);
     665       11501 :       if (*lex == old)
     666             :       {
     667       11466 :         --*lex; /* member */
     668       11466 :         return KINTEGER;
     669             :       }
     670          35 :       return KREAL;
     671             :     }
     672        2929 :     skipdigits(lex);
     673        2929 :     skipexponent(lex);
     674        2929 :     return KREAL;
     675             :   }
     676     7800002 :   return skipexponent(lex);
     677             : }
     678             : 
     679             : static void
     680     1144945 : skipstring(char **lex)
     681             : {
     682     8122673 :   while (**lex)
     683             :   {
     684     8123223 :     while (**lex == '\\') *lex+=2;
     685     8122673 :     if (**lex == '"')
     686             :     {
     687     1144945 :       if ((*lex)[1] != '"') break;
     688           0 :       *lex += 2; continue;
     689             :     }
     690     6977728 :     (*lex)++;
     691             :   }
     692     1144945 : }
     693             : 
     694             : int
     695    29866304 : pari_lex(union token_value *yylval, struct node_loc *yylloc, char **lex)
     696             : {
     697             :   (void) yylval;
     698    29866304 :   yylloc->start=*lex;
     699    29866304 :   if (!**lex)
     700             :   {
     701      105510 :     yylloc->end=*lex;
     702      105510 :     return 0;
     703             :   }
     704    29760794 :   if (isalpha((int)**lex))
     705             :   {
     706     1969579 :     while (is_keyword_char(**lex)) ++*lex;
     707      446965 :     yylloc->end=*lex;
     708      446965 :     return KENTRY;
     709             :   }
     710    29313829 :   if (**lex=='"')
     711             :   {
     712     1144945 :     ++*lex;
     713     1144945 :     skipstring(lex);
     714     1144945 :     if (!**lex)
     715           0 :       compile_err("run-away string",*lex-1);
     716     1144945 :     ++*lex;
     717     1144945 :     yylloc->end=*lex;
     718     1144945 :     return KSTRING;
     719             :   }
     720    28168884 :   if (**lex == '.')
     721             :   {
     722             :     int token;
     723       12589 :     if ((*lex)[1]== '.')
     724             :     {
     725        1109 :       *lex+=2; yylloc->end = *lex; return KDOTDOT;
     726             :     }
     727       11480 :     token=skipconstante(lex);
     728       11480 :     if (token==KREAL)
     729             :     {
     730          14 :       yylloc->end = *lex;
     731          14 :       return token;
     732             :     }
     733       11466 :     ++*lex;
     734       11466 :     yylloc->end=*lex;
     735       11466 :     return '.';
     736             :   }
     737    28156295 :   if (isbin((const char**)lex))
     738             :   {
     739        1029 :     while (**lex=='0' || **lex=='1') ++*lex;
     740          21 :     return KINTEGER;
     741             :   }
     742    28156274 :   if (ishex((const char**)lex))
     743             :   {
     744         868 :     while (isxdigit((int)**lex)) ++*lex;
     745          49 :     return KINTEGER;
     746             :   }
     747    28156225 :   if (isdigit((int)**lex))
     748             :   {
     749     7804040 :     int token=skipconstante(lex);
     750     7804040 :     yylloc->end = *lex;
     751     7804040 :     return token;
     752             :   }
     753    20352185 :   if ((*lex)[1]=='=')
     754       22596 :     switch (**lex)
     755             :     {
     756        8647 :     case '=':
     757        8647 :       if ((*lex)[2]=='=')
     758         357 :       { *lex+=3; yylloc->end = *lex; return KID; }
     759             :       else
     760        8290 :       { *lex+=2; yylloc->end = *lex; return KEQ; }
     761          76 :     case '>':
     762          76 :       *lex+=2; yylloc->end = *lex; return KGE;
     763         174 :     case '<':
     764         174 :       *lex+=2; yylloc->end = *lex; return KLE;
     765         160 :     case '*':
     766         160 :       *lex+=2; yylloc->end = *lex; return KME;
     767          35 :     case '/':
     768          35 :       *lex+=2; yylloc->end = *lex; return KDE;
     769           7 :     case '%':
     770           7 :       if ((*lex)[2]=='=') break;
     771           7 :       *lex+=2; yylloc->end = *lex; return KMODE;
     772        1862 :     case '!':
     773        1862 :       if ((*lex)[2]=='=') break;
     774        1862 :       *lex+=2; yylloc->end = *lex; return KNE;
     775           7 :     case '\\':
     776           7 :       *lex+=2; yylloc->end = *lex; return KEUCE;
     777         176 :     case '+':
     778         176 :       *lex+=2; yylloc->end = *lex; return KPE;
     779          49 :     case '-':
     780          49 :       *lex+=2; yylloc->end = *lex; return KSE;
     781             :     }
     782    20340992 :   if (**lex==')' && (*lex)[1]=='-' && (*lex)[2]=='>')
     783             :   {
     784        4079 :     *lex+=3; yylloc->end = *lex; return KPARROW;
     785             :   }
     786    20336913 :   if (**lex=='-' && (*lex)[1]=='>')
     787             :   {
     788        1107 :     *lex+=2; yylloc->end = *lex; return KARROW;
     789             :   }
     790    20335806 :   if (**lex=='<' && (*lex)[1]=='>')
     791             :   {
     792           0 :     *lex+=2; yylloc->end = *lex; return KNE;
     793             :   }
     794    20335806 :   if (**lex=='\\' && (*lex)[1]=='/')
     795          35 :     switch((*lex)[2])
     796             :     {
     797           7 :     case '=':
     798           7 :       *lex+=3; yylloc->end = *lex; return KDRE;
     799          28 :     default:
     800          28 :       *lex+=2; yylloc->end = *lex; return KDR;
     801             :     }
     802    20335771 :   if ((*lex)[1]==**lex)
     803     2190980 :     switch (**lex)
     804             :     {
     805         704 :     case '&':
     806         704 :       *lex+=2; yylloc->end = *lex; return KAND;
     807         315 :     case '|':
     808         315 :       *lex+=2; yylloc->end = *lex; return KOR;
     809         141 :     case '+':
     810         141 :       *lex+=2; yylloc->end = *lex; return KPP;
     811          14 :     case '-':
     812          14 :       *lex+=2; yylloc->end = *lex; return KSS;
     813          28 :     case '>':
     814          28 :       if ((*lex)[2]=='=') { *lex+=3; yylloc->end = *lex; return KSRE;}
     815          21 :       *lex+=2; yylloc->end = *lex; return KSR;
     816         112 :     case '<':
     817         112 :       if ((*lex)[2]=='=')
     818           7 :       { *lex+=3; yylloc->end = *lex; return KSLE; }
     819         105 :       *lex+=2; yylloc->end = *lex; return KSL;
     820             :     }
     821    20334457 :   yylloc->end = *lex+1;
     822    20334457 :   return (unsigned char) *(*lex)++;
     823             : }
     824             : 
     825             : /********************************************************************/
     826             : /*                                                                  */
     827             : /*                Formal variables management                       */
     828             : /*                                                                  */
     829             : /********************************************************************/
     830             : static THREAD long max_priority, min_priority;
     831             : static THREAD long max_avail; /* max variable not yet used */
     832             : static THREAD long nvar; /* first GP free variable */
     833             : static hashtable *h_polvar;
     834             : 
     835             : void
     836      285215 : varstate_save(struct pari_varstate *s)
     837             : {
     838      285215 :   s->nvar = nvar;
     839      285215 :   s->max_avail = max_avail;
     840      285215 :   s->max_priority = max_priority;
     841      285215 :   s->min_priority = min_priority;
     842      285215 : }
     843             : 
     844             : static void
     845        8636 : varentries_set(long v, entree *ep)
     846             : {
     847        8636 :   hash_insert(h_polvar, (void*)ep->name, (void*)v);
     848        8636 :   varentries[v] = ep;
     849        8636 : }
     850             : static int
     851        2926 : _given_value(void *E, hashentry *e) { return e->val == E; }
     852             : 
     853             : static void
     854       13025 : varentries_unset(long v)
     855             : {
     856       13025 :   entree *ep = varentries[v];
     857       13025 :   if (ep)
     858             :   {
     859        2926 :     hashentry *e = hash_remove_select(h_polvar, (void*)ep->name, (void*)v,
     860             :         _given_value);
     861        2926 :     if (!e) pari_err_BUG("varentries_unset [unknown var]");
     862        2926 :     varentries[v] = NULL;
     863        2926 :     pari_free(e);
     864        2926 :     if (v <= nvar && ep == is_entry(ep->name))
     865        2919 :     { /* known to the GP interpreter; entree in functions_hash is permanent */
     866        2919 :       GEN p = (GEN)initial_value(ep);
     867        2919 :       if (ep->value == p) { ep->value = NULL; ep->valence = EpNEW; }
     868        2919 :       *p = 0;
     869             :     }
     870             :     else /* from name_var() or a direct pari_var_create() */
     871           7 :       pari_free(ep);
     872             :  }
     873       13025 : }
     874             : static void
     875         104 : varentries_reset(long v, entree *ep)
     876             : {
     877         104 :   varentries_unset(v);
     878         104 :   varentries_set(v, ep);
     879         104 : }
     880             : 
     881             : static void
     882      184733 : var_restore(struct pari_varstate *s)
     883             : {
     884      184733 :   nvar = s->nvar;
     885      184733 :   max_avail = s->max_avail;
     886      184733 :   max_priority = s->max_priority;
     887      184733 :   min_priority = s->min_priority;
     888      184733 : }
     889             : 
     890             : void
     891        9974 : varstate_restore(struct pari_varstate *s)
     892             : {
     893             :   long i;
     894       22874 :   for (i = nvar; i >= s->nvar; i--)
     895             :   {
     896       12900 :     varentries_unset(i);
     897       12900 :     varpriority[i] = -i;
     898             :   }
     899        9995 :   for (i = max_avail+1; i <= s->max_avail; i++)
     900             :   {
     901          21 :     varentries_unset(i);
     902          21 :     varpriority[i] = -i;
     903             :   }
     904        9974 :   var_restore(s);
     905        9974 : }
     906             : 
     907             : void
     908      174813 : pari_set_varstate(long *vp, struct pari_varstate *vs)
     909             : {
     910      174813 :   var_restore(vs);
     911      174747 :   varpriority = (long*)newblock(MAXVARN+2) + 1;
     912      174053 :   memcpy(varpriority-1,vp-1,(MAXVARN+2)*sizeof(long));
     913      174053 : }
     914             : 
     915             : /* must come before destruction of functions_hash */
     916             : void
     917        1680 : pari_var_close(void)
     918             : {
     919        1680 :   GEN h = hash_values(h_polvar);
     920        1680 :   long i, l = lg(h);
     921        7370 :   for (i = 1; i < l; i++)
     922             :   {
     923        5690 :     long v = h[i];
     924        5690 :     entree *ep = varentries[v];
     925        5690 :     if (ep && ep != is_entry(ep->name)) pari_free(ep);
     926             :   }
     927        1680 :   free((void*)varentries);
     928        1680 :   free((void*)(varpriority-1));
     929        1680 :   hash_destroy(h_polvar);
     930        1680 : }
     931             : 
     932             : void
     933        1690 : pari_var_init(void)
     934             : {
     935             :   long i;
     936        1690 :   varentries = (entree**) pari_calloc((MAXVARN+1)*sizeof(entree*));
     937        1690 :   varpriority = (long*)pari_malloc((MAXVARN+2)*sizeof(long)) + 1;
     938        1690 :   varpriority[-1] = 1-LONG_MAX;
     939        1690 :   h_polvar = hash_create_str(100, 0);
     940        1690 :   nvar = 0; max_avail = MAXVARN;
     941        1690 :   max_priority = min_priority = 0;
     942        1690 :   (void)fetch_user_var("x");
     943        1690 :   (void)fetch_user_var("y");
     944             :   /* initialize so that people can use pol_x(i) directly */
     945    99350886 :   for (i = 2; i <= (long)MAXVARN; i++) varpriority[i] = -i;
     946             :   /* reserve varnum 1..9 for static temps with predictable priority wrt x */
     947        1690 :   nvar = 10;
     948        1690 :   min_priority = -MAXVARN;
     949        1690 : }
     950           8 : long pari_var_next(void) { return nvar; }
     951           0 : long pari_var_next_temp(void) { return max_avail; }
     952             : long
     953       34955 : pari_var_create(entree *ep)
     954             : {
     955       34955 :   GEN p = (GEN)initial_value(ep);
     956             :   long v;
     957       34955 :   if (*p) return varn(p);
     958        8532 :   if (nvar == max_avail) pari_err(e_MISC,"no more variables available");
     959        8532 :   v = nvar++;
     960             :   /* set p = pol_x(v) */
     961        8532 :   p[0] = evaltyp(t_POL) | _evallg(4);
     962        8532 :   p[1] = evalsigne(1) | evalvarn(v);
     963        8532 :   gel(p,2) = gen_0;
     964        8532 :   gel(p,3) = gen_1;
     965        8532 :   varentries_set(v, ep);
     966        8532 :   varpriority[v]= min_priority--;
     967        8532 :   return v;
     968             : }
     969             : 
     970             : long
     971       88799 : delete_var(void)
     972             : { /* user wants to delete one of his/her/its variables */
     973       88799 :   if (max_avail == MAXVARN) return 0; /* nothing to delete */
     974       88610 :   max_avail++;
     975       88610 :   if      (varpriority[max_avail] == min_priority) min_priority++;
     976       88610 :   else if (varpriority[max_avail] == max_priority) max_priority--;
     977       88610 :   return max_avail+1;
     978             : }
     979             : long
     980       52369 : fetch_var(void)
     981             : {
     982       52369 :   if (nvar == max_avail) pari_err(e_MISC,"no more variables available");
     983       52369 :   varpriority[max_avail] = min_priority--;
     984       52369 :   return max_avail--;
     985             : }
     986             : long
     987       39733 : fetch_var_higher(void)
     988             : {
     989       39733 :   if (nvar == max_avail) pari_err(e_MISC,"no more variables available");
     990       39733 :   varpriority[max_avail] = ++max_priority;
     991       39733 :   return max_avail--;
     992             : }
     993             : 
     994             : static int
     995          49 : _higher(void *E, hashentry *e)
     996          49 : { long v = (long)e->val; return (varncmp(v, (long)E) < 0); }
     997             : static int
     998          42 : _lower(void *E, hashentry *e)
     999          42 : { long v = (long)e->val; return (varncmp(v, (long)E) > 0); }
    1000             : 
    1001             : static GEN
    1002         104 : var_register(long v, const char *s)
    1003             : {
    1004         104 :   varentries_reset(v, initep(s, strlen(s)));
    1005         104 :   return pol_x(v);
    1006             : }
    1007             : GEN
    1008          91 : varhigher(const char *s, long w)
    1009             : {
    1010             :   long v;
    1011          91 :   if (w >= 0)
    1012             :   {
    1013          49 :     hashentry *e = hash_select(h_polvar, (void*)s, (void*)w, _higher);
    1014          49 :     if (e) return pol_x((long)e->val);
    1015             :   }
    1016             :   /* no luck: need to create */
    1017          77 :   if (nvar == max_avail) pari_err(e_MISC,"no more variables available");
    1018          77 :   v = nvar++;
    1019          77 :   varpriority[v]= ++max_priority;
    1020          77 :   return var_register(v, s);
    1021             : }
    1022             : GEN
    1023          34 : varlower(const char *s, long w)
    1024             : {
    1025             :   long v;
    1026          34 :   if (w >= 0)
    1027             :   {
    1028          21 :     hashentry *e = hash_select(h_polvar, (void*)s, (void*)w, _lower);
    1029          21 :     if (e) return pol_x((long)e->val);
    1030             :   }
    1031             :   /* no luck: need to create */
    1032          27 :   v = fetch_var();
    1033          27 :   return var_register(v, s);
    1034             : }
    1035             : 
    1036             : long
    1037      391279 : fetch_user_var(const char *s)
    1038             : {
    1039      391279 :   entree *ep = fetch_entry(s);
    1040             :   long v;
    1041      391279 :   switch (EpVALENCE(ep))
    1042             :   {
    1043      387717 :     case EpVAR: return varn((GEN)initial_value(ep));
    1044        3562 :     case EpNEW: break;
    1045           0 :     default: pari_err(e_MISC, "%s already exists with incompatible valence", s);
    1046             :   }
    1047        3562 :   v = pari_var_create(ep);
    1048        3562 :   ep->valence = EpVAR;
    1049        3562 :   ep->value = initial_value(ep);
    1050        3562 :   return v;
    1051             : }
    1052             : 
    1053             : GEN
    1054           7 : fetch_var_value(long v, GEN t)
    1055             : {
    1056           7 :   entree *ep = varentries[v];
    1057           7 :   if (!ep) return NULL;
    1058           7 :   if (t)
    1059             :   {
    1060           7 :     long vn = localvars_find(t,ep);
    1061           7 :     if (vn) return get_lex(vn);
    1062             :   }
    1063           7 :   return (GEN)ep->value;
    1064             : }
    1065             : 
    1066             : void
    1067           0 : name_var(long n, const char *s)
    1068             : {
    1069             :   entree *ep;
    1070             :   char *u;
    1071             : 
    1072           0 :   if (n < pari_var_next())
    1073           0 :     pari_err(e_MISC, "renaming a GP variable is forbidden");
    1074           0 :   if (n > (long)MAXVARN)
    1075           0 :     pari_err_OVERFLOW("variable number");
    1076             : 
    1077           0 :   ep = (entree*)pari_malloc(sizeof(entree) + strlen(s) + 1);
    1078           0 :   u = (char *)initial_value(ep);
    1079           0 :   ep->valence = EpVAR;
    1080           0 :   ep->name = u; strcpy(u,s);
    1081           0 :   ep->value = gen_0; /* in case geval is called */
    1082           0 :   varentries_reset(n, ep);
    1083           0 : }
    1084             : 
    1085             : static int
    1086        5136 : cmp_by_var(void *E,GEN x, GEN y)
    1087        5136 : { (void)E; return varncmp((long)x,(long)y); }
    1088             : GEN
    1089        1127 : vars_sort_inplace(GEN z)
    1090        1127 : { gen_sort_inplace(z,NULL,cmp_by_var,NULL); return z; }
    1091             : GEN
    1092         161 : vars_to_RgXV(GEN h)
    1093             : {
    1094         161 :   long i, l = lg(h);
    1095         161 :   GEN z = cgetg(l, t_VEC);
    1096        2065 :   for (i = 1; i < l; i++) gel(z,i) = pol_x(h[i]);
    1097         161 :   return z;
    1098             : }
    1099             : GEN
    1100        1169 : gpolvar(GEN x)
    1101             : {
    1102             :   long v;
    1103        1169 :   if (!x) {
    1104         140 :     GEN h = hash_values(h_polvar);
    1105         140 :     return vars_to_RgXV(vars_sort_inplace(h));
    1106             :   }
    1107        1029 :   if (typ(x)==t_PADIC) return gcopy( gel(x,2) );
    1108        1022 :   v = gvar(x);
    1109        1022 :   if (v==NO_VARIABLE) return gen_0;
    1110         966 :   return pol_x(v);
    1111             : }
    1112             : 
    1113             : static void
    1114     2169900 : fill_hashtable_single(entree **table, entree *ep)
    1115             : {
    1116     2169900 :   EpSETSTATIC(ep);
    1117     2169900 :   insertep(ep, table, hash_str(ep->name));
    1118     2169900 :   if (ep->code) ep->arity = check_proto(ep->code);
    1119     2169900 :   ep->pvalue = NULL;
    1120     2169900 : }
    1121             : 
    1122             : void
    1123        5060 : pari_fill_hashtable(entree **table, entree *ep)
    1124             : {
    1125     2174960 :   for ( ; ep->name; ep++) fill_hashtable_single(table, ep);
    1126        5060 : }
    1127             : 
    1128             : void
    1129           0 : pari_add_function(entree *ep)
    1130             : {
    1131           0 :   fill_hashtable_single(functions_hash, ep);
    1132           0 : }
    1133             : 
    1134             : /********************************************************************/
    1135             : /**                                                                **/
    1136             : /**                        SIMPLE GP FUNCTIONS                     **/
    1137             : /**                                                                **/
    1138             : /********************************************************************/
    1139             : 
    1140             : GEN
    1141          28 : arity0(GEN C)
    1142             : {
    1143          28 :   if (typ(C)!=t_CLOSURE) pari_err_TYPE("arity", C);
    1144          28 :   return utoi(closure_arity(C));
    1145             : }
    1146             : 
    1147             : #define ALIAS(ep) (entree *) ((GEN)ep->value)[1]
    1148             : 
    1149             : entree *
    1150     5994853 : do_alias(entree *ep)
    1151             : {
    1152     5994909 :   while (ep->valence == EpALIAS) ep = ALIAS(ep);
    1153     5994853 :   return ep;
    1154             : }
    1155             : 
    1156             : void
    1157          28 : alias0(const char *s, const char *old)
    1158             : {
    1159             :   entree *ep, *e;
    1160             :   GEN x;
    1161             : 
    1162          28 :   ep = fetch_entry(old);
    1163          28 :   e  = fetch_entry(s);
    1164          28 :   if (EpVALENCE(e) != EpALIAS && EpVALENCE(e) != EpNEW)
    1165           0 :     pari_err(e_MISC,"can't replace an existing symbol by an alias");
    1166          28 :   freeep(e);
    1167          28 :   x = cgetg_block(2, t_VECSMALL); gel(x,1) = (GEN)ep;
    1168          28 :   e->value=x; e->valence=EpALIAS;
    1169          28 : }
    1170             : 
    1171             : GEN
    1172    12855844 : ifpari(GEN g, GEN a/*closure*/, GEN b/*closure*/)
    1173             : {
    1174    12855844 :   if (gequal0(g)) /* false */
    1175     9966605 :     return b? closure_evalgen(b): gnil;
    1176             :   else /* true */
    1177     2889239 :     return a? closure_evalgen(a): gnil;
    1178             : }
    1179             : 
    1180             : void
    1181    40451635 : ifpari_void(GEN g, GEN a/*closure*/, GEN b/*closure*/)
    1182             : {
    1183    40451635 :   if (gequal0(g)) /* false */
    1184    39766029 :   { if (b) closure_evalvoid(b); }
    1185             :   else /* true */
    1186      685606 :   { if (a) closure_evalvoid(a); }
    1187    40451614 : }
    1188             : 
    1189             : GEN
    1190       31325 : ifpari_multi(GEN g, GEN a/*closure*/)
    1191             : {
    1192       31325 :   long i, nb = lg(a)-1;
    1193       31325 :   if (!gequal0(g)) /* false */
    1194        6713 :     return closure_evalgen(gel(a,1));
    1195       42098 :   for(i=2;i<nb;i+=2)
    1196             :   {
    1197       24724 :     GEN g = closure_evalgen(gel(a,i));
    1198       24724 :     if (!g) return g;
    1199       24717 :     if (!gequal0(g))
    1200        7231 :       return closure_evalgen(gel(a,i+1));
    1201             :   }
    1202       17374 :   return i<=nb? closure_evalgen(gel(a,i)): gnil;
    1203             : }
    1204             : 
    1205             : GEN
    1206     2000611 : andpari(GEN a, GEN b/*closure*/)
    1207             : {
    1208             :   GEN g;
    1209     2000611 :   if (gequal0(a))
    1210     1612534 :     return gen_0;
    1211      388077 :   g=closure_evalgen(b);
    1212      388077 :   if (!g) return g;
    1213      388077 :   return gequal0(g)?gen_0:gen_1;
    1214             : }
    1215             : 
    1216             : GEN
    1217    16081891 : orpari(GEN a, GEN b/*closure*/)
    1218             : {
    1219             :   GEN g;
    1220    16081891 :   if (!gequal0(a))
    1221      125531 :     return gen_1;
    1222    15956360 :   g=closure_evalgen(b);
    1223    15956360 :   if (!g) return g;
    1224    15956360 :   return gequal0(g)?gen_0:gen_1;
    1225             : }
    1226             : 
    1227       80040 : GEN gmule(GEN *x, GEN y) { *x = gmul(*x,y); return *x; }
    1228          56 : GEN gdive(GEN *x, GEN y) { *x = gdiv(*x,y); return *x; }
    1229           7 : GEN gdivente(GEN *x, GEN y) { *x = gdivent(*x,y); return *x; }
    1230           7 : GEN gdivrounde(GEN *x, GEN y) { *x = gdivround(*x,y); return *x; }
    1231           7 : GEN gmode(GEN *x, GEN y) { *x = gmod(*x,y); return *x; }
    1232           7 : GEN gshiftle(GEN *x, long n) { *x = gshift(*x,n); return *x; }
    1233           7 : GEN gshiftre(GEN *x, long n) { *x = gshift(*x,-n); return *x; }
    1234      434693 : GEN gadde(GEN *x, GEN y) { *x = gadd(*x,y); return *x; }
    1235    25675563 : GEN gadd1e(GEN *x) { *x = typ(*x)==t_INT?addiu(*x,1):gaddgs(*x,1); return *x; }
    1236    15455356 : GEN gsube(GEN *x, GEN y) { *x = gsub(*x,y); return *x; }
    1237          14 : GEN gsub1e(GEN *x) { *x = typ(*x)==t_INT?subiu(*x,1):gsubgs(*x,1); return *x; }
    1238             : 
    1239        1392 : GEN gshift_right(GEN x, long n) { return gshift(x,-n); }

Generated by: LCOV version 1.13