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-bordeaux1.fr machine (x86_64 architecture), and agregate them in the final report:

The target is 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.8.0 lcov report (development 16937-4bd9b4e) Lines: 426 610 69.8 %
Date: 2014-10-24 Functions: 63 71 88.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 278 505 55.0 %

           Branch data     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                 :            : enum { A_ACTION_ASSIGN, A_ACTION_SET, A_ACTION_UNSET };
      43                 :            : #define IS_ID(c)        (isalnum((int)c) || ((c) == '_') || ((c) == '-'))
      44                 :            : 
      45                 :            : long
      46                 :          0 : eval_mnemonic(GEN str, const char *tmplate)
      47                 :            : {
      48                 :          0 :   pari_sp av=avma;
      49                 :          0 :   ulong retval = 0;
      50                 :          0 :   const char *etmplate = NULL;
      51                 :            :   const char *arg;
      52                 :            : 
      53         [ #  # ]:          0 :   if (typ(str)==t_INT) return itos(str);
      54         [ #  # ]:          0 :   if (typ(str)!=t_STR) pari_err_TYPE("eval_mnemonic",str);
      55                 :            : 
      56                 :          0 :   arg=GSTR(str);
      57                 :          0 :   etmplate = strchr(tmplate, '\n');
      58         [ #  # ]:          0 :   if (!etmplate)
      59                 :          0 :     etmplate = tmplate + strlen(tmplate);
      60                 :            : 
      61                 :            :   while (1)
      62                 :            :   {
      63                 :            :     long numarg;
      64                 :            :     const char *e, *id;
      65                 :            :     const char *negated;                /* action found with 'no'-ID */
      66                 :            :     int negate;                 /* Arg has 'no' prefix removed */
      67                 :          0 :     ulong l, action = 0, first = 1, singleton = 0;
      68                 :            :     char *buf, *inibuf;
      69                 :            :     static char b[80];
      70                 :            : 
      71         [ #  # ]:          0 :     while (isspace((int)*arg)) arg++;
      72         [ #  # ]:          0 :     if (!*arg)
      73                 :          0 :       break;
      74                 :          0 :     e = arg;
      75 [ #  # ][ #  # ]:          0 :     while (IS_ID(*e)) e++;
                 [ #  # ]
      76                 :            :     /* Now the ID is whatever is between arg and e. */
      77                 :          0 :     l = e - arg;
      78         [ #  # ]:          0 :     if (l >= sizeof(b))
      79                 :          0 :       pari_err(e_MISC,"id too long in a stringified flag");
      80         [ #  # ]:          0 :     if (!l)                             /* Garbage after whitespace? */
      81                 :          0 :       pari_err(e_MISC,"a stringified flag does not start with an id");
      82                 :          0 :     strncpy(b, arg, l);
      83                 :          0 :     b[l] = 0;
      84                 :          0 :     arg = e;
      85                 :          0 :     e = inibuf = buf = b;
      86 [ #  # ][ #  # ]:          0 :     while (('0' <= *e) && (*e <= '9'))
      87                 :          0 :       e++;
      88         [ #  # ]:          0 :     if (*e == 0)
      89                 :          0 :       pari_err(e_MISC,"numeric id in a stringified flag");
      90                 :          0 :     negate = 0;
      91                 :          0 :     negated = NULL;
      92                 :            : find:
      93                 :          0 :     id = tmplate;
      94 [ #  # ][ #  # ]:          0 :     while ((id = strstr(id, buf)) && id < etmplate)
      95                 :            :     {
      96 [ #  # ][ #  # ]:          0 :       if (IS_ID(id[l])) {       /* We do not allow abbreviations yet */
                 [ #  # ]
      97                 :          0 :         id += l;                /* False positive */
      98                 :          0 :         continue;
      99                 :            :       }
     100 [ #  # ][ #  # ]:          0 :       if ((id >= tmplate + 2) && (IS_ID(id[-1])))
         [ #  # ][ #  # ]
     101                 :            :       {
     102                 :          0 :         const char *s = id;
     103                 :            : 
     104 [ #  # ][ #  # ]:          0 :         if ( !negate && s >= tmplate+3
     105 [ #  # ][ #  # ]:          0 :             && ((id[-1] == '_') || (id[-1] == '-')) )
     106                 :          0 :           s--;
     107                 :            :         /* Check whether we are preceeded by "no" */
     108         [ #  # ]:          0 :         if ( negate             /* buf initially started with "no" */
     109 [ #  # ][ #  # ]:          0 :             || (s < tmplate+2) || (s[-1] != 'o') || (s[-2] != 'n')
                 [ #  # ]
     110 [ #  # ][ #  # ]:          0 :             || (s >= tmplate+3 && IS_ID(s[-3]))) {
         [ #  # ][ #  # ]
     111                 :          0 :           id += l;              /* False positive */
     112                 :          0 :           continue;
     113                 :            :         }
     114                 :            :         /* Found noID in the template! */
     115                 :          0 :         id += l;
     116                 :          0 :         negated = id;
     117                 :          0 :         continue;               /* Try to find without 'no'. */
     118                 :            :       }
     119                 :            :       /* Found as is */
     120                 :          0 :       id += l;
     121                 :          0 :       break;
     122                 :            :     }
     123 [ #  # ][ #  # ]:          0 :     if ( !id && !negated && !negate
                 [ #  # ]
     124 [ #  # ][ #  # ]:          0 :         && (l > 2) && buf[0] == 'n' && buf[1] == 'o' ) {
                 [ #  # ]
     125                 :            :       /* Try to find the flag without the prefix "no". */
     126                 :          0 :       buf += 2; l -= 2;
     127 [ #  # ][ #  # ]:          0 :       if ((buf[0] == '_') || (buf[0] == '-')) { buf++; l--; }
     128                 :          0 :       negate = 1;
     129         [ #  # ]:          0 :       if (buf[0])
     130                 :          0 :         goto find;
     131                 :            :     }
     132 [ #  # ][ #  # ]:          0 :     if (!id && negated) /* Negated and AS_IS forms, prefer AS_IS */
     133                 :            :     {
     134                 :          0 :       id = negated;     /* Otherwise, use negated form */
     135                 :          0 :       negate = 1;
     136                 :            :     }
     137         [ #  # ]:          0 :     if (!id)
     138                 :          0 :       pari_err(e_MISC,"Unrecognized id '%s' in a stringified flag", inibuf);
     139 [ #  # ][ #  # ]:          0 :     if (singleton && !first)
     140                 :          0 :       pari_err(e_MISC,"Singleton id non-single in a stringified flag");
     141         [ #  # ]:          0 :     if (id[0] == '=') {
     142         [ #  # ]:          0 :       if (negate)
     143                 :          0 :         pari_err(e_MISC,"Cannot negate id=value in a stringified flag");
     144         [ #  # ]:          0 :       if (!first)
     145                 :          0 :         pari_err(e_MISC,"Assign action should be first in a stringified flag");
     146                 :          0 :       action = A_ACTION_ASSIGN;
     147                 :          0 :       id++;
     148         [ #  # ]:          0 :       if (id[0] == '=') {
     149                 :          0 :         singleton = 1;
     150                 :          0 :         id++;
     151                 :            :       }
     152         [ #  # ]:          0 :     } else if (id[0] == '^') {
     153         [ #  # ]:          0 :       if (id[1] != '~')
     154                 :          0 :         pari_err(e_MISC, "Unrecognized action in a template");
     155                 :          0 :       id += 2;
     156         [ #  # ]:          0 :       if (negate)
     157                 :          0 :         action = A_ACTION_SET;
     158                 :            :       else
     159                 :          0 :         action = A_ACTION_UNSET;
     160         [ #  # ]:          0 :     } else if (id[0] == '|') {
     161                 :          0 :       id++;
     162         [ #  # ]:          0 :       if (negate)
     163                 :          0 :         action = A_ACTION_UNSET;
     164                 :            :       else
     165                 :          0 :         action = A_ACTION_SET;
     166                 :            :     }
     167                 :            : 
     168                 :          0 :     e = id;
     169                 :            : 
     170 [ #  # ][ #  # ]:          0 :     while ((*e >= '0' && *e <= '9')) e++;
     171         [ #  # ]:          0 :     while (isspace((int)*e))
     172                 :          0 :       e++;
     173 [ #  # ][ #  # ]:          0 :     if (*e && (*e != ';') && (*e != ','))
                 [ #  # ]
     174                 :          0 :       pari_err(e_MISC, "Non-numeric argument of an action in a template");
     175                 :          0 :     numarg = atol(id);          /* Now it is safe to get it... */
     176   [ #  #  #  # ]:          0 :     switch (action) {
     177                 :            :     case A_ACTION_SET:
     178                 :          0 :       retval |= numarg;
     179                 :          0 :       break;
     180                 :            :     case A_ACTION_UNSET:
     181                 :          0 :       retval &= ~numarg;
     182                 :          0 :       break;
     183                 :            :     case A_ACTION_ASSIGN:
     184                 :          0 :       retval = numarg;
     185                 :          0 :       break;
     186                 :            :     default:
     187                 :          0 :       pari_err(e_MISC,"error in parse_option_string");
     188                 :            :     }
     189                 :          0 :     first = 0;
     190         [ #  # ]:          0 :     while (isspace((int)*arg))
     191                 :          0 :       arg++;
     192 [ #  # ][ #  # ]:          0 :     if (*arg && !(ispunct((int)*arg) && *arg != '-'))
                 [ #  # ]
     193                 :          0 :       pari_err(e_MISC,"Junk after an id in a stringified flag");
     194                 :            :     /* Skip punctuation */
     195         [ #  # ]:          0 :     if (*arg)
     196                 :          0 :       arg++;
     197                 :          0 :   }
     198                 :          0 :   avma=av;
     199                 :          0 :   return retval;
     200                 :            : }
     201                 :            : 
     202                 :            : /*******************************************************************/
     203                 :            : /*                                                                 */
     204                 :            : /*                  SYNTACTICAL ANALYZER FOR GP                    */
     205                 :            : /*                                                                 */
     206                 :            : /*******************************************************************/
     207                 :            : GEN
     208                 :       3325 : readseq(char *t)
     209                 :            : {
     210                 :       3325 :   pari_sp av = avma;
     211                 :            :   GEN x;
     212         [ -  + ]:       3325 :   if (gp_meta(t,0)) return gnil;
     213                 :       3325 :   x = pari_compile_str(t);
     214                 :       3325 :   return gerepileupto(av, closure_evalres(x));
     215                 :            : }
     216                 :            : 
     217                 :            : /* filtered readseq = remove blanks and comments */
     218                 :            : GEN
     219                 :          0 : gp_read_str(const char *s)
     220                 :            : {
     221                 :          0 :   char *t = gp_filter(s);
     222                 :          0 :   GEN x = readseq(t);
     223                 :          0 :   pari_free(t); return x;
     224                 :            : }
     225                 :            : 
     226                 :            : GEN
     227                 :       9793 : compile_str(const char *s)
     228                 :            : {
     229                 :       9793 :   char *t = gp_filter(s);
     230                 :       9793 :   GEN x = pari_compile_str(t);
     231                 :       9786 :   pari_free(t); return x;
     232                 :            : }
     233                 :            : 
     234                 :            : static long
     235                 :    1028063 : check_proto(const char *code)
     236                 :            : {
     237                 :    1028063 :   long arity = 0;
     238                 :    1028063 :   const char *s = code, *old;
     239 [ +  + ][ +  + ]:    1028063 :   if (*s == 'l' || *s == 'v' || *s == 'i' || *s == 'm' || *s == 'u') s++;
         [ +  + ][ +  + ]
                 [ -  + ]
     240   [ +  +  +  +  :    3864839 :   while (*s && *s != '\n') switch (*s++)
                -  -  - ]
         [ +  + ][ +  + ]
     241                 :            :   {
     242                 :            :     case '&':
     243                 :            :     case 'C':
     244                 :            :     case 'G':
     245                 :            :     case 'I':
     246                 :            :     case 'J':
     247                 :            :     case 'U':
     248                 :            :     case 'L':
     249                 :            :     case 'M':
     250                 :            :     case 'P':
     251                 :            :     case 'W':
     252                 :            :     case 'f':
     253                 :            :     case 'n':
     254                 :            :     case 'p':
     255                 :            :     case 'r':
     256                 :            :     case 'x':
     257                 :    1802715 :       arity++;
     258                 :    1802715 :       break;
     259                 :            :     case 'E':
     260                 :            :     case 's':
     261         [ +  + ]:      82869 :       if (*s == '*') s++;
     262                 :      82869 :       arity++;
     263                 :      82869 :       break;
     264                 :            :     case 'D':
     265 [ +  + ][ +  + ]:     470792 :       if (*s == 'G' || *s == '&' || *s == 'n' || *s == 'I' || *s == 'E'
         [ +  + ][ +  + ]
                 [ +  + ]
     266 [ +  + ][ +  + ]:     213778 :                     || *s == 'V' || *s == 'P' || *s == 's' || *s == 'r')
         [ +  + ][ +  + ]
     267                 :            :       {
     268         [ +  + ]:     278632 :         if (*s != 'V') arity++;
     269                 :     278632 :         s++; break;
     270                 :            :       }
     271 [ +  - ][ +  + ]:     395129 :       old = s; while (*s && *s != ',') s++;
     272         [ -  + ]:     192160 :       if (*s != ',') pari_err(e_SYNTAX, "missing comma", old, code);
     273                 :     192160 :       break;
     274                 :            :     case 'V':
     275                 :            :     case '=':
     276                 :     480400 :     case ',': break;
     277                 :          0 :     case '\n': break; /* Before the mnemonic */
     278                 :            : 
     279                 :            :     case 'm':
     280                 :            :     case 'l':
     281                 :            :     case 'i':
     282                 :          0 :     case 'v': pari_err(e_SYNTAX, "this code has to come first", s-1, code);
     283                 :          0 :     default: pari_err(e_SYNTAX, "unknown parser code", s-1, code);
     284                 :            :   }
     285         [ -  + ]:    1028063 :   if (arity > 20) pari_err_IMPL("functions with more than 20 parameters");
     286                 :    1028063 :   return arity;
     287                 :            : }
     288                 :            : 
     289                 :            : static entree *
     290                 :      15050 : installep(const char *name, long len, entree **table)
     291                 :            : {
     292                 :      15050 :   const long add = 4*sizeof(long);
     293                 :      15050 :   entree *ep = (entree *) pari_calloc(sizeof(entree) + add + len+1);
     294                 :      15050 :   entree *ep1 = initial_value(ep);
     295                 :      15050 :   char *u = (char *) ep1 + add;
     296                 :      15050 :   ep->name    = u; strncpy(u, name,len); u[len]=0;
     297                 :      15050 :   ep->valence = EpNEW;
     298                 :      15050 :   ep->value   = NULL;
     299                 :      15050 :   ep->menu    = 0;
     300                 :      15050 :   ep->code    = NULL;
     301                 :      15050 :   ep->help    = NULL;
     302                 :      15050 :   ep->pvalue  = NULL;
     303                 :      15050 :   ep->arity   = 0;
     304                 :      15050 :   ep->next    = *table;
     305                 :      15050 :   return *table = ep;
     306                 :            : }
     307                 :            : 
     308                 :            : entree *
     309                 :          7 : install(void *f, const char *name, const char *code)
     310                 :            : {
     311                 :            :   long hash, arity;
     312                 :          7 :   entree *ep = is_entry_intern(name, functions_hash, &hash);
     313                 :            : 
     314                 :          7 :   arity=check_proto(code);
     315 [ -  + ][ #  # ]:          7 :   if (ep && ep->valence != EpNEW)
     316                 :            :   {
     317         [ #  # ]:          0 :     if (ep->valence != EpINSTALL)
     318                 :          0 :       pari_err(e_MISC,"[install] identifier '%s' already in use", name);
     319                 :          0 :     pari_warn(warner, "[install] updating '%s' prototype; module not reloaded", name);
     320         [ #  # ]:          0 :     if (ep->code) pari_free((void*)ep->code);
     321                 :            :   }
     322                 :            :   else
     323                 :            :   {
     324                 :          7 :     const char *s = name;
     325         [ +  - ]:          7 :     if (isalpha((int)*s))
     326         [ +  + ]:         35 :       while (is_keyword_char(*++s)) /* empty */;
     327         [ -  + ]:          7 :     if (*s) pari_err(e_SYNTAX,"not a valid identifier", s, name);
     328         [ +  - ]:          7 :     if (!ep) ep = installep(name, strlen(name), functions_hash + hash);
     329                 :          7 :     ep->value=f; ep->valence=EpINSTALL;
     330                 :            :   }
     331                 :          7 :   ep->code = pari_strdup(code);
     332                 :          7 :   ep->arity=arity;
     333                 :          7 :   return ep;
     334                 :            : }
     335                 :            : 
     336                 :            : /* Kill ep, i.e free all memory it references, and reset to initial value */
     337                 :            : void
     338                 :         21 : kill0(const char *e)
     339                 :            : {
     340                 :         21 :   entree *ep = is_entry(e);
     341 [ +  - ][ -  + ]:         21 :   if (!ep || EpSTATIC(ep)) pari_err(e_MISC,"can't kill that");
     342                 :         21 :   freeep(ep);
     343                 :         21 :   ep->valence = EpNEW;
     344                 :         21 :   ep->value   = NULL;
     345                 :         21 :   ep->pvalue  = NULL;
     346                 :         21 : }
     347                 :            : 
     348                 :            : void
     349                 :         42 : addhelp(const char *e, char *s)
     350                 :            : {
     351                 :         42 :   entree *ep = fetch_entry(e, strlen(e));
     352 [ +  + ][ -  + ]:         42 :   if (ep->help && !EpSTATIC(ep)) pari_free((void*)ep->help);
     353                 :         42 :   ep->help = pari_strdup(s);
     354                 :         42 : }
     355                 :            : 
     356                 :            : GEN
     357                 :      11221 : type0(GEN x)
     358                 :            : {
     359                 :      11221 :   const char *s = type_name(typ(x));
     360                 :      11221 :   return strtoGENstr(s);
     361                 :            : }
     362                 :            : 
     363                 :            : /*******************************************************************/
     364                 :            : /*                                                                 */
     365                 :            : /*                              PARSER                             */
     366                 :            : /*                                                                 */
     367                 :            : /*******************************************************************/
     368                 :            : 
     369                 :            : #ifdef LONG_IS_64BIT
     370                 :            : static const long MAX_DIGITS = 19;
     371                 :            : #else
     372                 :            : static const long MAX_DIGITS = 9;
     373                 :            : #endif
     374                 :            : 
     375                 :            : static ulong
     376                 :    8560003 : number(int *n, const char **s)
     377                 :            : {
     378                 :    8560003 :   ulong m = 0;
     379 [ +  + ][ +  + ]:   53551684 :   for (*n = 0; *n < MAX_DIGITS && isdigit((int)**s); (*n)++,(*s)++)
     380                 :   44991681 :     m = 10*m + (**s - '0');
     381                 :    8560003 :   return m;
     382                 :            : }
     383                 :            : 
     384                 :            : ulong
     385                 :    1531689 : u_pow10(int n)
     386                 :            : {
     387                 :    1531689 :   const ulong pw10[] = {
     388                 :            :     1UL
     389                 :            :     ,10UL
     390                 :            :     ,100UL
     391                 :            :     ,1000UL
     392                 :            :     ,10000UL
     393                 :            :     ,100000UL
     394                 :            :     ,1000000UL
     395                 :            :     ,10000000UL
     396                 :            :     ,100000000UL
     397                 :            :     ,1000000000UL
     398                 :            : #ifdef LONG_IS_64BIT
     399                 :            :     ,10000000000UL
     400                 :            :     ,100000000000UL
     401                 :            :     ,1000000000000UL
     402                 :            :     ,10000000000000UL
     403                 :            :     ,100000000000000UL
     404                 :            :     ,1000000000000000UL
     405                 :            :     ,10000000000000000UL
     406                 :            :     ,100000000000000000UL
     407                 :            :     ,1000000000000000000UL
     408                 :            :     ,10000000000000000000UL
     409                 :            : #endif
     410                 :            :   };
     411                 :    1531689 :   return pw10[n];
     412                 :            : }
     413                 :            : 
     414                 :            : static GEN
     415                 :     563972 : int_read_more(GEN y, const char **ps)
     416                 :            : {
     417                 :     563972 :   pari_sp av = avma;
     418                 :     563972 :   int i = 0, nb;
     419         [ +  + ]:    2095661 :   while (isdigit((int)**ps))
     420                 :            :   {
     421                 :    1531689 :     ulong m = number(&nb, ps);
     422 [ +  + ][ +  + ]:    1531689 :     if (avma != av && ++i > 4) { avma = av; i = 0; } /* HACK gerepile */
     423                 :    1531689 :     y = addumului(m, u_pow10(nb), y);
     424                 :            :   }
     425                 :     563972 :   return y;
     426                 :            : }
     427                 :            : 
     428                 :            : static long
     429                 :      88662 : exponent(const char **pts)
     430                 :            : {
     431                 :      88662 :   const char *s = *pts;
     432                 :            :   long n;
     433                 :            :   int nb;
     434      [ +  -  + ]:      88662 :   switch(*++s)
     435                 :            :   {
     436                 :      88571 :     case '-': s++; n = -(long)number(&nb, &s); break;
     437                 :          0 :     case '+': s++; /* Fall through */
     438                 :         91 :     default: n = (long)number(&nb, &s);
     439                 :            :   }
     440                 :      88662 :   *pts = s; return n;
     441                 :            : }
     442                 :            : 
     443                 :            : static GEN
     444                 :        161 : real_0_digits(long n) {
     445         [ +  + ]:        161 :   long b = (n > 0)? (long)(n/LOG10_2): (long)-((-n)/LOG10_2 + 1);
     446                 :        161 :   return real_0_bit(b);
     447                 :            : }
     448                 :            : 
     449                 :            : static GEN
     450                 :      93784 : real_read(pari_sp av, const char **s, GEN y, long prec)
     451                 :            : {
     452                 :      93784 :   long l, n = 0;
     453      [ -  +  + ]:      93784 :   switch(**s)
     454                 :            :   {
     455                 :          0 :     default: return y; /* integer */
     456                 :            :     case '.':
     457                 :            :     {
     458                 :       6326 :       const char *old = ++*s;
     459 [ +  + ][ -  + ]:       6326 :       if (isalpha((int)**s) || **s=='.')
     460                 :            :       {
     461 [ +  + ][ +  - ]:       1197 :         if (**s == 'E' || **s == 'e') {
     462                 :       1197 :           n = exponent(s);
     463         [ +  + ]:       1197 :           if (!signe(y)) { avma = av; return real_0_digits(n); }
     464                 :       1183 :           break;
     465                 :            :         }
     466                 :          0 :         --*s; return y; /* member */
     467                 :            :       }
     468                 :       5129 :       y = int_read_more(y, s);
     469                 :       5129 :       n = old - *s;
     470 [ +  - ][ +  + ]:       5129 :       if (**s != 'E' && **s != 'e')
     471                 :            :       {
     472         [ +  + ]:       5122 :         if (!signe(y)) { avma = av; return real_0(prec); }
     473                 :       4254 :         break;
     474                 :            :       }
     475                 :            :     }
     476                 :            :     /* Fall through */
     477                 :            :     case 'E': case 'e':
     478                 :      87465 :       n += exponent(s);
     479         [ +  + ]:      87465 :       if (!signe(y)) { avma = av; return real_0_digits(n); }
     480                 :            :   }
     481                 :      92755 :   l = nbits2prec(bit_accuracy(lgefint(y)));
     482         [ +  + ]:      92755 :   if (l < prec) l = prec; else prec = l;
     483         [ +  + ]:      92755 :   if (!n) return itor(y, prec);
     484                 :      89215 :   incrprec(l);
     485                 :      89215 :   y = itor(y, l);
     486         [ +  + ]:      89215 :   if (n > 0)
     487                 :         14 :     y = mulrr(y, rpowuu(10UL, (ulong)n, l));
     488                 :            :   else
     489                 :      89201 :     y = divrr(y, rpowuu(10UL, (ulong)-n, l));
     490                 :      93784 :   return gerepileuptoleaf(av, rtor(y, prec));
     491                 :            : }
     492                 :            : 
     493                 :            : static GEN
     494                 :    6939652 : int_read(const char **s)
     495                 :            : {
     496                 :            :   int nb;
     497                 :    6939652 :   GEN y = utoi(number(&nb, s));
     498         [ +  + ]:    6939652 :   if (nb == MAX_DIGITS) y = int_read_more(y, s);
     499                 :    6939652 :   return y;
     500                 :            : }
     501                 :            : 
     502                 :            : GEN
     503                 :    6845868 : strtoi(const char *s) { return int_read(&s); }
     504                 :            : 
     505                 :            : GEN
     506                 :      93784 : strtor(const char *s, long prec)
     507                 :            : {
     508                 :      93784 :   pari_sp av = avma;
     509                 :      93784 :   GEN y = int_read(&s);
     510                 :      93784 :   y = real_read(av, &s, y, prec);
     511         [ +  - ]:      93784 :   if (typ(y) == t_REAL) return y;
     512                 :      93784 :   return gerepileuptoleaf(av, itor(y, prec));
     513                 :            : }
     514                 :            : 
     515                 :            : static void
     516                 :    6705038 : skipdigits(char **lex) {
     517         [ +  + ]:   49120448 :   while (isdigit((int)**lex)) ++*lex;
     518                 :    6705038 : }
     519                 :            : 
     520                 :            : static int
     521                 :    6702728 : skipexponent(char **lex)
     522                 :            : {
     523                 :    6702728 :   char *old=*lex;
     524 [ +  + ][ +  + ]:    6702728 :   if ((**lex=='e' || **lex=='E'))
     525                 :            :   {
     526                 :        735 :     ++*lex;
     527 [ +  - ][ +  + ]:        735 :     if ( **lex=='+' || **lex=='-' ) ++*lex;
     528         [ +  + ]:        735 :     if (!isdigit((int)**lex))
     529                 :            :     {
     530                 :        399 :       *lex=old;
     531                 :        399 :       return KINTEGER;
     532                 :            :     }
     533                 :        336 :     skipdigits(lex);
     534                 :        336 :     return KREAL;
     535                 :            :   }
     536                 :    6702728 :   return KINTEGER;
     537                 :            : }
     538                 :            : 
     539                 :            : static int
     540                 :    6703106 : skipconstante(char **lex)
     541                 :            : {
     542                 :    6703106 :   skipdigits(lex);
     543         [ +  + ]:    6703106 :   if (**lex=='.')
     544                 :            :   {
     545                 :      11263 :     char *old = ++*lex;
     546         [ +  + ]:      11263 :     if (**lex == '.') { --*lex; return KINTEGER; }
     547         [ +  + ]:      10885 :     if (isalpha((int)**lex))
     548                 :            :     {
     549                 :       9289 :       skipexponent(lex);
     550         [ +  + ]:       9289 :       if (*lex == old)
     551                 :            :       {
     552                 :       9268 :         --*lex; /* member */
     553                 :       9268 :         return KINTEGER;
     554                 :            :       }
     555                 :         21 :       return KREAL;
     556                 :            :     }
     557                 :       1596 :     skipdigits(lex);
     558                 :       1596 :     skipexponent(lex);
     559                 :       1596 :     return KREAL;
     560                 :            :   }
     561                 :    6703106 :   return skipexponent(lex);
     562                 :            : }
     563                 :            : 
     564                 :            : static void
     565                 :    1026702 : skipstring(char **lex)
     566                 :            : {
     567         [ +  - ]:    7354844 :   while (**lex)
     568                 :            :   {
     569         [ +  + ]:    7355201 :     while (**lex == '\\') *lex+=2;
     570         [ +  + ]:    7354844 :     if (**lex == '"')
     571                 :            :     {
     572         [ +  - ]:    1026702 :       if ((*lex)[1] != '"') break;
     573                 :          0 :       *lex += 2; continue;
     574                 :            :     }
     575                 :    6328142 :     (*lex)++;
     576                 :            :   }
     577                 :    1026702 : }
     578                 :            : 
     579                 :            : int
     580                 :   25443725 : pari_lex(union token_value *yylval, struct node_loc *yylloc, char **lex)
     581                 :            : {
     582                 :            :   (void) yylval;
     583                 :   25443725 :   yylloc->start=*lex;
     584         [ +  + ]:   25443725 :   if (!**lex)
     585                 :            :   {
     586                 :      52142 :     yylloc->end=*lex;
     587                 :      52142 :     return 0;
     588                 :            :   }
     589         [ +  + ]:   25391583 :   if (isalpha((int)**lex))
     590                 :            :   {
     591         [ +  + ]:     726536 :     while (is_keyword_char(**lex)) ++*lex;
     592                 :     178628 :     yylloc->end=*lex;
     593                 :     178628 :     return KENTRY;
     594                 :            :   }
     595         [ +  + ]:   25212955 :   if (**lex=='"')
     596                 :            :   {
     597                 :    1026702 :     ++*lex;
     598                 :    1026702 :     skipstring(lex);
     599         [ -  + ]:    1026702 :     if (!**lex)
     600                 :          0 :       compile_err("run-away string",*lex-1);
     601                 :    1026702 :     ++*lex;
     602                 :    1026702 :     yylloc->end=*lex;
     603                 :    1026702 :     return KSTRING;
     604                 :            :   }
     605         [ +  + ]:   24186253 :   if (**lex == '.')
     606                 :            :   {
     607                 :            :     int token;
     608         [ +  + ]:       9660 :     if ((*lex)[1]== '.')
     609                 :            :     {
     610                 :        392 :       *lex+=2; yylloc->end = *lex; return KDOTDOT;
     611                 :            :     }
     612                 :       9268 :     token=skipconstante(lex);
     613         [ -  + ]:       9268 :     if (token==KREAL)
     614                 :            :     {
     615                 :          0 :       yylloc->end = *lex;
     616                 :          0 :       return token;
     617                 :            :     }
     618                 :       9268 :     ++*lex;
     619                 :       9268 :     yylloc->end=*lex;
     620                 :       9268 :     return '.';
     621                 :            :   }
     622         [ +  + ]:   24176593 :   if (isdigit((int)**lex))
     623                 :            :   {
     624                 :    6693838 :     int token=skipconstante(lex);
     625                 :    6693838 :     yylloc->end = *lex;
     626                 :    6693838 :     return token;
     627                 :            :   }
     628         [ +  + ]:   17482755 :   if ((*lex)[1]=='=')
     629   [ +  +  +  +  :       3997 :     switch (**lex)
          +  +  +  +  +  
                   +  + ]
     630                 :            :     {
     631                 :            :     case '=':
     632         [ +  + ]:       1078 :       if ((*lex)[2]=='=')
     633                 :        273 :       { *lex+=3; yylloc->end = *lex; return KID; }
     634                 :            :       else
     635                 :        805 :       { *lex+=2; yylloc->end = *lex; return KEQ; }
     636                 :            :     case '>':
     637                 :         56 :       *lex+=2; yylloc->end = *lex; return KGE;
     638                 :            :     case '<':
     639                 :         56 :       *lex+=2; yylloc->end = *lex; return KLE;
     640                 :            :     case '*':
     641                 :         84 :       *lex+=2; yylloc->end = *lex; return KME;
     642                 :            :     case '/':
     643                 :          7 :       *lex+=2; yylloc->end = *lex; return KDE;
     644                 :            :     case '%':
     645         [ -  + ]:          7 :       if ((*lex)[2]=='=') break;
     646                 :          7 :       *lex+=2; yylloc->end = *lex; return KMODE;
     647                 :            :     case '!':
     648         [ -  + ]:        581 :       if ((*lex)[2]=='=') break;
     649                 :        581 :       *lex+=2; yylloc->end = *lex; return KNE;
     650                 :            :     case '\\':
     651                 :          7 :       *lex+=2; yylloc->end = *lex; return KEUCE;
     652                 :            :     case '+':
     653                 :         28 :       *lex+=2; yylloc->end = *lex; return KPE;
     654                 :            :     case '-':
     655                 :         28 :       *lex+=2; yylloc->end = *lex; return KSE;
     656                 :            :     }
     657 [ +  + ][ +  + ]:   17480823 :   if (**lex==')' && (*lex)[1]=='-' && (*lex)[2]=='>')
                 [ +  + ]
     658                 :            :   {
     659                 :         42 :     *lex+=3; yylloc->end = *lex; return KPARROW;
     660                 :            :   }
     661 [ +  + ][ +  + ]:   17480781 :   if (**lex=='-' && (*lex)[1]=='>')
     662                 :            :   {
     663                 :        336 :     *lex+=2; yylloc->end = *lex; return KARROW;
     664                 :            :   }
     665 [ +  + ][ -  + ]:   17480445 :   if (**lex=='<' && (*lex)[1]=='>')
     666                 :            :   {
     667                 :          0 :     *lex+=2; yylloc->end = *lex; return KNE;
     668                 :            :   }
     669 [ +  + ][ +  + ]:   17480445 :   if (**lex=='\\' && (*lex)[1]=='/')
     670         [ +  + ]:         35 :     switch((*lex)[2])
     671                 :            :     {
     672                 :            :     case '=':
     673                 :          7 :       *lex+=3; yylloc->end = *lex; return KDRE;
     674                 :            :     default:
     675                 :         28 :       *lex+=2; yylloc->end = *lex; return KDR;
     676                 :            :     }
     677         [ +  + ]:   17480410 :   if ((*lex)[1]==**lex)
     678   [ +  +  +  -  :    1956720 :     switch (**lex)
                +  +  + ]
     679                 :            :     {
     680                 :            :     case '&':
     681                 :        119 :       *lex+=2; yylloc->end = *lex; return KAND;
     682                 :            :     case '|':
     683                 :        133 :       *lex+=2; yylloc->end = *lex; return KOR;
     684                 :            :     case '+':
     685                 :         35 :       *lex+=2; yylloc->end = *lex; return KPP;
     686                 :            :     case '-':
     687                 :          0 :       *lex+=2; yylloc->end = *lex; return KSS;
     688                 :            :     case '>':
     689         [ +  + ]:         28 :       if ((*lex)[2]=='=') { *lex+=3; yylloc->end = *lex; return KSRE;}
     690                 :         21 :       *lex+=2; yylloc->end = *lex; return KSR;
     691                 :            :     case '<':
     692         [ +  + ]:         84 :       if ((*lex)[2]=='=')
     693                 :          7 :       { *lex+=3; yylloc->end = *lex; return KSLE; }
     694                 :         77 :       *lex+=2; yylloc->end = *lex; return KSL;
     695                 :            :     }
     696                 :   17480011 :   yylloc->end = *lex+1;
     697                 :   25443725 :   return (unsigned char) *(*lex)++;
     698                 :            : }
     699                 :            : 
     700                 :            : /********************************************************************/
     701                 :            : /**                                                                **/
     702                 :            : /**                            STRINGS                             **/
     703                 :            : /**                                                                **/
     704                 :            : /********************************************************************/
     705                 :            : 
     706                 :            : /* return the first n0 chars of s as a GEN [s may not be 0-terminated] */
     707                 :            : GEN
     708                 :     111876 : strntoGENstr(const char *s, long n0)
     709                 :            : {
     710                 :     111876 :   long n = nchar2nlong(n0+1);
     711                 :     111876 :   GEN x = cgetg(n+1, t_STR);
     712                 :     111876 :   char *t = GSTR(x);
     713                 :     111876 :   strncpy(t, s, n0); t[n0] = 0; return x;
     714                 :            : }
     715                 :            : 
     716                 :            : GEN
     717                 :      53836 : strtoGENstr(const char *s) { return strntoGENstr(s, strlen(s)); }
     718                 :            : 
     719                 :            : GEN
     720                 :         56 : chartoGENstr(char c)
     721                 :            : {
     722                 :         56 :   GEN x = cgetg(2, t_STR);
     723                 :         56 :   char *t = GSTR(x);
     724                 :         56 :   t[0] = c; t[1] = 0; return x;
     725                 :            : }
     726                 :            : /********************************************************************/
     727                 :            : /**                                                                **/
     728                 :            : /**                   HASH TABLE MANIPULATIONS                     **/
     729                 :            : /**                                                                **/
     730                 :            : /********************************************************************/
     731                 :            : /* return hashing value for identifier s */
     732                 :            : static ulong
     733                 :    1075218 : hashvalue(const char *s)
     734                 :            : {
     735                 :    1075218 :   ulong n = 0, c;
     736         [ +  + ]:    9801341 :   while ( (c = (ulong)*s++) ) n = (n<<1) ^ c;
     737                 :    1075218 :   return n % functions_tblsz;
     738                 :            : }
     739                 :            : 
     740                 :            : static ulong
     741                 :    4754406 : hashvalue_raw(const char *s, long len, ulong n)
     742                 :            : {
     743                 :            :   long i;
     744         [ +  + ]:   15122133 :   for(i=0; i<len; i++) { n = (n<<1) ^ *s; s++; }
     745                 :    4754406 :   return n % functions_tblsz;
     746                 :            : }
     747                 :            : 
     748                 :            : /* Looking for entry in hashtable. ep1 is the cell's first element */
     749                 :            : static entree *
     750                 :    4774632 : findentry(const char *name, long len, entree *ep1)
     751                 :            : {
     752                 :            :   entree *ep;
     753         [ +  + ]:   27455272 :   for (ep = ep1; ep; ep = ep->next)
     754 [ +  + ][ +  + ]:   27440187 :     if (!strncmp(ep->name, name, len) && !(ep->name)[len]) return ep;
     755                 :    4774632 :   return NULL; /* not found */
     756                 :            : }
     757                 :            : 
     758                 :            : entree *
     759                 :      36511 : is_entry_intern(const char *s, entree **table, long *pthash)
     760                 :            : {
     761                 :      36511 :   long hash = hashvalue(s);
     762         [ +  + ]:      36511 :   if (pthash) *pthash = hash;
     763                 :      36511 :   return findentry(s, strlen(s), table[hash]);
     764                 :            : }
     765                 :            : 
     766                 :            : entree *
     767                 :      34296 : is_entry(const char *s)
     768                 :            : {
     769                 :      34296 :   return is_entry_intern(s,functions_hash,NULL);
     770                 :            : }
     771                 :            : 
     772                 :            : entree *
     773                 :    4735877 : fetch_entry(const char *s, long len)
     774                 :            : {
     775                 :    4735877 :   entree **funhash = functions_hash + hashvalue_raw(s, len, 0);
     776                 :    4735877 :   entree *ep = findentry(s, len, *funhash);
     777         [ +  + ]:    4735877 :   if (ep) return ep;
     778                 :    4735877 :   else return installep(s,len,funhash);
     779                 :            : }
     780                 :            : 
     781                 :            : /* Assume s point somewhere in the code text, so s[-1]='.' and s[-2]>0
     782                 :            :  * So many kludges, so little time */
     783                 :            : entree *
     784                 :      18529 : fetch_member(const char *s, long len)
     785                 :            : {
     786                 :      18529 :   entree **funhash = functions_hash+hashvalue_raw(s-1, len+1, '_');
     787                 :            :   entree *ep;
     788         [ +  + ]:     129696 :   for (ep = *funhash; ep; ep = ep->next)
     789                 :            :   {
     790 [ +  + ][ +  + ]:     129689 :     if (ep->name[0]!='_' || ep->name[1]!='.') continue;
     791 [ +  + ][ +  - ]:      24486 :     if (!strncmp(ep->name+2, s, len) && !(ep->name)[len+2]) break;
     792                 :            :   }
     793         [ +  + ]:      18529 :   if (ep) return ep;
     794                 :          7 :   ep=installep(s-2,len+2,funhash);
     795                 :          7 :   ((char*)ep->name)[0]='_';
     796                 :      18529 :   return ep;
     797                 :            : }
     798                 :            : 
     799                 :            : /********************************************************************/
     800                 :            : /*                                                                  */
     801                 :            : /*                Formal variables management                       */
     802                 :            : /*                                                                  */
     803                 :            : /********************************************************************/
     804                 :            : static long max_avail; /* max variable not yet used */
     805                 :            : static long nvar; /* first GP free variable */
     806                 :            : 
     807                 :       1201 : void pari_var_init(void) {
     808                 :       1201 :   nvar = 0; max_avail = MAXVARN;
     809                 :       1201 :   (void)fetch_var();
     810                 :       1201 :   (void)fetch_named_var("x");
     811                 :       1201 : }
     812                 :        168 : long pari_var_next(void) { return nvar; }
     813                 :         84 : long pari_var_next_temp(void) { return max_avail; }
     814                 :            : static long
     815                 :          0 : pari_var_pop(long v)
     816                 :            : {
     817         [ #  # ]:          0 :   if (v != nvar-1) pari_err(e_MISC,"can't pop user variable %ld", v);
     818                 :          0 :   return --nvar;
     819                 :            : }
     820                 :            : void
     821                 :      15957 : pari_var_create(entree *ep)
     822                 :            : {
     823                 :      15957 :   GEN p = (GEN)initial_value(ep);
     824                 :            :   long v;
     825         [ +  + ]:      28078 :   if (*p) return;
     826         [ -  + ]:      12121 :   if (nvar == max_avail) pari_err(e_MISC,"no more variables available");
     827                 :      12121 :   v = nvar++;
     828                 :            :   /* set p = pol_x(v) */
     829                 :      12121 :   p[0] = evaltyp(t_POL) | _evallg(4);
     830                 :      12121 :   p[1] = evalsigne(1) | evalvarn(v);
     831                 :      12121 :   gel(p,2) = gen_0;
     832                 :      12121 :   gel(p,3) = gen_1;
     833                 :      12121 :   varentries[v] = ep;
     834                 :            : }
     835                 :            : 
     836                 :            : long
     837                 :       3751 : delete_var(void)
     838                 :            : { /* user wants to delete one of his/her/its variables */
     839         [ +  + ]:       3751 :   if (max_avail == MAXVARN-1) return 0; /* nothing to delete */
     840                 :       3751 :   max_avail++; return max_avail+1;
     841                 :            : }
     842                 :            : long
     843                 :       3763 : fetch_var(void)
     844                 :            : {
     845         [ -  + ]:       3763 :   if (nvar == max_avail) pari_err(e_MISC,"no more variables available");
     846                 :       3763 :   return max_avail--;
     847                 :            : }
     848                 :            : 
     849                 :            : /* FIXE: obsolete, kept for backward compatibility */
     850                 :            : long
     851                 :          0 : manage_var(long n, entree *ep)
     852                 :            : {
     853   [ #  #  #  #  :          0 :   switch(n) {
                #  #  # ]
     854                 :          0 :       case manage_var_init: pari_var_init(); return 0;
     855                 :          0 :       case manage_var_next: return pari_var_next();
     856                 :          0 :       case manage_var_max_avail: return pari_var_next_temp();
     857                 :          0 :       case manage_var_pop: return pari_var_pop((long)ep);
     858                 :          0 :       case manage_var_delete: return delete_var();
     859                 :            :       case manage_var_create:
     860                 :          0 :         pari_var_create(ep);
     861                 :          0 :         return varn((GEN)initial_value(ep));
     862                 :            :   }
     863                 :          0 :   pari_err(e_MISC, "panic");
     864                 :          0 :   return -1; /* not reached */
     865                 :            : }
     866                 :            : 
     867                 :            : entree *
     868                 :       2244 : fetch_named_var(const char *s)
     869                 :            : {
     870                 :       2244 :   entree **funhash = functions_hash + hashvalue(s);
     871                 :       2244 :   entree *ep = findentry(s, strlen(s), *funhash);
     872         [ +  + ]:       2244 :   if (!ep) ep = installep(s,strlen(s),funhash);
     873      [ +  -  - ]:       1008 :   else switch (EpVALENCE(ep))
     874                 :            :   {
     875                 :       1008 :     case EpVAR: return ep;
     876                 :          0 :     case EpNEW: break;
     877                 :          0 :     default: pari_err(e_MISC, "%s already exists with incompatible valence", s);
     878                 :            :   }
     879                 :       1236 :   pari_var_create(ep);
     880                 :       1236 :   ep->valence=EpVAR;
     881                 :       1236 :   ep->value=initial_value(ep);
     882                 :       2244 :   return ep;
     883                 :            : }
     884                 :            : 
     885                 :            : long
     886                 :       1043 : fetch_user_var(const char *s)
     887                 :            : {
     888                 :       1043 :   return varn((GEN)initial_value(fetch_named_var(s)) );
     889                 :            : }
     890                 :            : 
     891                 :            : GEN
     892                 :          7 : fetch_var_value(long vx, GEN t)
     893                 :            : {
     894                 :          7 :   entree *ep = varentries[vx];
     895                 :            :   long vn;
     896         [ -  + ]:          7 :   if (!ep) return NULL;
     897         [ -  + ]:          7 :   if (!t)  return (GEN) ep->value;
     898                 :          7 :   vn=localvars_find(t,ep);
     899         [ -  + ]:          7 :   if (vn) return get_lex(vn);
     900                 :          7 :   return (GEN) ep->value;
     901                 :            : }
     902                 :            : 
     903                 :            : void
     904                 :         84 : name_var(long n, const char *s)
     905                 :            : {
     906                 :            :   entree *ep;
     907                 :            :   char *u;
     908                 :            : 
     909         [ -  + ]:         84 :   if (n < pari_var_next())
     910                 :          0 :     pari_err(e_MISC, "renaming a GP variable is forbidden");
     911         [ -  + ]:         84 :   if (n > (long)MAXVARN)
     912                 :          0 :     pari_err_OVERFLOW("variable number");
     913                 :            : 
     914                 :         84 :   ep = (entree*)pari_malloc(sizeof(entree) + strlen(s) + 1);
     915                 :         84 :   u = (char *)initial_value(ep);
     916                 :         84 :   ep->valence = EpVAR;
     917                 :         84 :   ep->name = u; strcpy(u,s);
     918                 :         84 :   ep->value = gen_0; /* in case geval is called */
     919         [ +  + ]:         84 :   if (varentries[n]) pari_free(varentries[n]);
     920                 :         84 :   varentries[n] = ep;
     921                 :         84 : }
     922                 :            : 
     923                 :            : GEN
     924                 :        427 : gpolvar(GEN x)
     925                 :            : {
     926                 :            :   long v;
     927         [ +  + ]:        427 :   if (!x) {
     928                 :         84 :     long k = 1, n = pari_var_next();
     929                 :         84 :     GEN z = cgetg(n+1, t_VEC);
     930         [ +  + ]:       1211 :     for (v = 0; v < n; v++)
     931                 :            :     {
     932                 :       1127 :       entree *ep = varentries[v];
     933 [ +  - ][ +  - ]:       1127 :       if (ep && ep->name[0] != '_') gel(z,k++) = (GEN)initial_value(ep);
     934                 :            :     }
     935         [ -  + ]:         84 :     if (k <= n) {
     936                 :          0 :       setlg(z,k);
     937                 :          0 :       stackdummy((pari_sp)(z+n), (pari_sp)(z+k));
     938                 :            :     }
     939                 :         84 :     return z;
     940                 :            :   }
     941         [ +  + ]:        343 :   if (typ(x)==t_PADIC) return gcopy( gel(x,2) );
     942                 :        336 :   v = gvar(x);
     943         [ +  + ]:        336 :   if (v==NO_VARIABLE) return gen_0;
     944                 :        427 :   return pol_x(v);
     945                 :            : }
     946                 :            : 
     947                 :            : static void
     948                 :    1036463 : fill_hashtable_single(entree **table, entree *ep)
     949                 :            : {
     950                 :    1036463 :   long n = hashvalue(ep->name);
     951                 :    1036463 :   EpSETSTATIC(ep);
     952                 :    1036463 :   ep->next = table[n]; table[n] = ep;
     953         [ +  + ]:    1036463 :   if (ep->code) ep->arity=check_proto(ep->code);
     954                 :    1036463 :   ep->pvalue = NULL;
     955                 :    1036463 : }
     956                 :            : 
     957                 :            : void
     958                 :       4804 : pari_fill_hashtable(entree **table, entree *ep)
     959                 :            : {
     960         [ +  + ]:    1041267 :   for ( ; ep->name; ep++) fill_hashtable_single(table, ep);
     961                 :       4804 : }
     962                 :            : 
     963                 :            : void
     964                 :          0 : pari_add_function(entree *ep)
     965                 :            : {
     966                 :          0 :   fill_hashtable_single(functions_hash, ep);
     967                 :          0 : }
     968                 :            : 
     969                 :            : /********************************************************************/
     970                 :            : /**                                                                **/
     971                 :            : /**                        SIMPLE GP FUNCTIONS                     **/
     972                 :            : /**                                                                **/
     973                 :            : /********************************************************************/
     974                 :            : 
     975                 :            : #define ALIAS(ep) (entree *) ((GEN)ep->value)[1]
     976                 :            : 
     977                 :            : entree *
     978                 :    4776394 : do_alias(entree *ep)
     979                 :            : {
     980         [ +  + ]:    4776450 :   while (ep->valence == EpALIAS) ep = ALIAS(ep);
     981                 :    4776394 :   return ep;
     982                 :            : }
     983                 :            : 
     984                 :            : void
     985                 :         28 : alias0(const char *s, const char *old)
     986                 :            : {
     987                 :            :   entree *ep, *e;
     988                 :            :   GEN x;
     989                 :            : 
     990                 :         28 :   ep = fetch_entry(old,strlen(old));
     991                 :         28 :   e  = fetch_entry(s,strlen(s));
     992 [ +  - ][ -  + ]:         28 :   if (EpVALENCE(e) != EpALIAS && EpVALENCE(e) != EpNEW)
     993                 :          0 :     pari_err(e_MISC,"can't replace an existing symbol by an alias");
     994                 :         28 :   freeep(e);
     995                 :         28 :   x = newblock(2); x[0] = evaltyp(t_STR)|_evallg(2); /* for getheap */
     996                 :         28 :   gel(x,1) = (GEN)ep;
     997                 :         28 :   e->value=x; e->valence=EpALIAS;
     998                 :         28 : }
     999                 :            : 
    1000                 :            : GEN
    1001                 :   12627208 : ifpari(GEN g, GEN a/*closure*/, GEN b/*closure*/)
    1002                 :            : {
    1003         [ +  + ]:   12627208 :   if (gequal0(g)) /* false */
    1004         [ +  + ]:    9844473 :     return b?closure_evalgen(b):gnil;
    1005                 :            :   else /* true */
    1006         [ +  - ]:   12627208 :     return a?closure_evalgen(a):gnil;
    1007                 :            : }
    1008                 :            : 
    1009                 :            : void
    1010                 :   16314890 : ifpari_void(GEN g, GEN a/*closure*/, GEN b/*closure*/)
    1011                 :            : {
    1012         [ +  + ]:   16314890 :   if (gequal0(g)) /* false */
    1013                 :            :   {
    1014         [ +  + ]:   15827011 :     if(b) closure_evalvoid(b);
    1015                 :            :   }
    1016                 :            :   else /* true */
    1017                 :            :   {
    1018         [ +  + ]:     487879 :     if(a) closure_evalvoid(a);
    1019                 :            :   }
    1020                 :   16314869 : }
    1021                 :            : 
    1022                 :            : GEN
    1023                 :      12271 : ifpari_multi(GEN g, GEN a/*closure*/)
    1024                 :            : {
    1025                 :      12271 :   long i, nb = lg(a)-1;
    1026         [ +  + ]:      12271 :   if (!gequal0(g)) /* false */
    1027                 :       4564 :     return closure_evalgen(gel(a,1));
    1028         [ +  + ]:      10892 :   for(i=2;i<nb;i+=2)
    1029                 :            :   {
    1030                 :       7735 :     GEN g = closure_evalgen(gel(a,i));
    1031         [ +  + ]:       7735 :     if (!g) return g;
    1032         [ +  + ]:       7728 :     if (!gequal0(g))
    1033                 :       4543 :       return closure_evalgen(gel(a,i+1));
    1034                 :            :   }
    1035         [ +  + ]:      12271 :   return i<=nb? closure_evalgen(gel(a,i)): gnil;
    1036                 :            : }
    1037                 :            : 
    1038                 :            : GEN
    1039                 :     159943 : andpari(GEN a, GEN b/*closure*/)
    1040                 :            : {
    1041                 :            :   GEN g;
    1042         [ +  + ]:     159943 :   if (gequal0(a))
    1043                 :      10171 :     return gen_0;
    1044                 :     149772 :   g=closure_evalgen(b);
    1045         [ -  + ]:     149772 :   if (!g) return g;
    1046         [ +  + ]:     159943 :   return gequal0(g)?gen_0:gen_1;
    1047                 :            : }
    1048                 :            : 
    1049                 :            : GEN
    1050                 :    2395540 : orpari(GEN a, GEN b/*closure*/)
    1051                 :            : {
    1052                 :            :   GEN g;
    1053         [ +  + ]:    2395540 :   if (!gequal0(a))
    1054                 :     118153 :     return gen_1;
    1055                 :    2277387 :   g=closure_evalgen(b);
    1056         [ -  + ]:    2277387 :   if (!g) return g;
    1057         [ +  + ]:    2395540 :   return gequal0(g)?gen_0:gen_1;
    1058                 :            : }
    1059                 :            : 
    1060                 :       5467 : GEN gmule(GEN *x, GEN y)
    1061                 :            : {
    1062                 :       5467 :   *x=gmul(*x,y);
    1063                 :       5467 :   return *x;
    1064                 :            : }
    1065                 :            : 
    1066                 :          7 : GEN gdive(GEN *x, GEN y)
    1067                 :            : {
    1068                 :          7 :   *x=gdiv(*x,y);
    1069                 :          7 :   return *x;
    1070                 :            : }
    1071                 :            : 
    1072                 :          7 : GEN gdivente(GEN *x, GEN y)
    1073                 :            : {
    1074                 :          7 :   *x=gdivent(*x,y);
    1075                 :          7 :   return *x;
    1076                 :            : }
    1077                 :            : 
    1078                 :          7 : GEN gdivrounde(GEN *x, GEN y)
    1079                 :            : {
    1080                 :          7 :   *x=gdivround(*x,y);
    1081                 :          7 :   return *x;
    1082                 :            : }
    1083                 :            : 
    1084                 :          7 : GEN gmode(GEN *x, GEN y)
    1085                 :            : {
    1086                 :          7 :   *x=gmod(*x,y);
    1087                 :          7 :   return *x;
    1088                 :            : }
    1089                 :            : 
    1090                 :          7 : GEN gshiftle(GEN *x, long n)
    1091                 :            : {
    1092                 :          7 :   *x=gshift(*x,n);
    1093                 :          7 :   return *x;
    1094                 :            : }
    1095                 :            : 
    1096                 :          7 : GEN gshiftre(GEN *x, long n)
    1097                 :            : {
    1098                 :          7 :   *x=gshift(*x,-n);
    1099                 :          7 :   return *x;
    1100                 :            : }
    1101                 :            : 
    1102                 :      29603 : GEN gadde(GEN *x, GEN y)
    1103                 :            : {
    1104                 :      29603 :   *x=gadd(*x,y);
    1105                 :      29603 :   return *x;
    1106                 :            : }
    1107                 :            : 
    1108                 :    3160241 : GEN gadd1e(GEN *x)
    1109                 :            : {
    1110         [ +  + ]:    3160241 :   *x=typ(*x)==t_INT?addis(*x,1):gaddgs(*x,1);
    1111                 :    3160241 :   return *x;
    1112                 :            : }
    1113                 :            : 
    1114                 :   15171471 : GEN gsube(GEN *x, GEN y)
    1115                 :            : {
    1116                 :   15171471 :   *x=gsub(*x,y);
    1117                 :   15171471 :   return *x;
    1118                 :            : }
    1119                 :            : 
    1120                 :          0 : GEN gsub1e(GEN *x)
    1121                 :            : {
    1122         [ #  # ]:          0 :   *x=typ(*x)==t_INT?subis(*x,1):gsubgs(*x,1);
    1123                 :          0 :   return *x;
    1124                 :            : }
    1125                 :            : 
    1126                 :       1392 : GEN gshift_right(GEN x, long n) { return gshift(x,-n); }
    1127                 :            : 
    1128                 :            : /********************************************************************/
    1129                 :            : /**                                                                **/
    1130                 :            : /**            PRINT USER FUNCTION AND MEMBER FUNCTION             **/
    1131                 :            : /**                                                                **/
    1132                 :            : /********************************************************************/
    1133                 :            : static int
    1134                 :          0 : cmp_epname(void *E, GEN e, GEN f)
    1135                 :            : {
    1136                 :            :   (void)E;
    1137                 :          0 :   return strcmp(((entree*)e)->name, ((entree*)f)->name);
    1138                 :            : }
    1139                 :            : 
    1140                 :            : void
    1141                 :          0 : print_all_user_fun(int member)
    1142                 :            : {
    1143                 :          0 :   pari_sp av = avma;
    1144                 :          0 :   long iL = 0, lL = 1024;
    1145                 :          0 :   GEN L = cgetg(lL+1, t_VECSMALL);
    1146                 :            :   entree *ep;
    1147                 :            :   int i;
    1148         [ #  # ]:          0 :   for (i = 0; i < functions_tblsz; i++)
    1149         [ #  # ]:          0 :     for (ep = functions_hash[i]; ep; ep = ep->next)
    1150                 :            :     {
    1151                 :            :       const char *f;
    1152                 :            :       int is_member;
    1153 [ #  # ][ #  # ]:          0 :       if (EpVALENCE(ep) != EpVAR || typ((GEN)ep->value)!=t_CLOSURE) continue;
    1154                 :          0 :       f = ep->name;
    1155 [ #  # ][ #  # ]:          0 :       is_member = (f[0] == '_' && f[1] == '.');
    1156         [ #  # ]:          0 :       if (member != is_member) continue;
    1157                 :            : 
    1158         [ #  # ]:          0 :       if (iL >= lL)
    1159                 :            :       {
    1160                 :          0 :         GEN oL = L;
    1161                 :            :         long j;
    1162                 :          0 :         lL *= 2; L = cgetg(lL+1, t_VECSMALL);
    1163         [ #  # ]:          0 :         for (j = 1; j <= iL; j++) gel(L,j) = gel(oL,j);
    1164                 :            :       }
    1165                 :          0 :       L[++iL] = (long)ep;
    1166                 :            :     }
    1167         [ #  # ]:          0 :   if (iL)
    1168                 :            :   {
    1169                 :          0 :     setlg(L, iL+1);
    1170                 :          0 :     L = gen_sort(L, NULL, &cmp_epname);
    1171         [ #  # ]:          0 :     for (i = 1; i <= iL; i++)
    1172                 :            :     {
    1173                 :          0 :       ep = (entree*)L[i];
    1174                 :          0 :       pari_printf("%s =\n  %Ps\n\n", ep->name, ep->value);
    1175                 :            :     }
    1176                 :            :   }
    1177                 :          0 :   avma = av;
    1178                 :          0 : }

Generated by: LCOV version 1.9