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 - modules - elldata.c (source / functions) Coverage Total Hit
Test: PARI/GP v2.18.1 lcov report (development 31042-0fbe168e69) Lines: 94.7 % 151 143
Test Date: 2026-07-23 17:04:59 Functions: 100.0 % 16 16
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Copyright (C) 2005  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; either version 2 of the License, or (at your option) any later
       8              : version. It is distributed in the hope that it will be useful, but WITHOUT
       9              : ANY WARRANTY WHATSOEVER.
      10              : 
      11              : Check the License for details. You should have received a copy of it, along
      12              : with the package; see the file 'COPYING'. If not, write to the Free Software
      13              : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      14              : 
      15              : /********************************************************************/
      16              : /**                                                                **/
      17              : /**  INTERFACE TO JOHN CREMONA ELLIPTIC CURVES DATABASE            **/
      18              : /**                                                                **/
      19              : /********************************************************************/
      20              : #include "pari.h"
      21              : #include "paripriv.h"
      22              : 
      23              : static long
      24          126 : strtoclass(const char *s)
      25              : {
      26          126 :   long c=0;
      27          378 :   while (*s && *s<='9') s++;
      28          126 :   if (!*s) return -1;
      29          252 :   while ('a'<=*s && *s<='z') c = 26*c + *(s++)-'a';
      30          126 :   return c;
      31              : }
      32              : 
      33              : /*Take a curve name like "100a2" and set
      34              :  * f to the conductor, (100)
      35              :  * c to the isogeny class (in base 26), ("a" or 0)
      36              :  * i to the curve index (2).
      37              :  * return 0 if parse error. */
      38              : static int
      39       529732 : ellparsename(const char *s, long *f, long *c, long *i)
      40              : {
      41              :   long j;
      42       529732 :   *f=-1; *c=-1; *i=-1;
      43       529732 :   if (*s<'0' || *s>'9') return 0;
      44       529725 :   *f=0;
      45      2526041 :   for (j=0;j<10 && '0'<=*s && *s<='9';j++)
      46      1996316 :     *f=10**f+*(s++)-'0';
      47       529725 :   if (j==10) {*f=-1; return 0;}
      48       529725 :   if (*s<'a' || *s>'z') return !*s;
      49       529718 :   *c=0;
      50      1086393 :   for (j=0; j<7 && 'a'<=*s && *s<='z';j++)
      51       556675 :     *c=26**c+*(s++)-'a';
      52       529718 :   if (j==7) {*c=-1; return 0;}
      53       529718 :   if (*s<'0' || *s>'9') return !*s;
      54       529704 :   *i=0;
      55      1059408 :   for (j=0; j<10 && '0'<=*s && *s<='9';j++)
      56       529704 :     *i=10**i+*(s++)-'0';
      57       529704 :   if (j==10) {*i=-1; return 0;}
      58       529704 :   return !*s;
      59              : }
      60              : 
      61              : /* Take an integer and convert it to base 26 */
      62              : static GEN
      63           14 : ellrecode(long x)
      64              : {
      65              :   GEN str;
      66              :   char *s;
      67           14 :   long d = 0, n = x;
      68           14 :   do { d++; n /= 26; } while (n);
      69           14 :   str = cgetg(nchar2nlong(d+1)+1, t_STR);
      70           14 :   s = GSTR(str); s[d] = 0;
      71           14 :   n = x;
      72           14 :   do { s[--d] = n%26 + 'a'; n /= 26; } while (n);
      73           14 :   return str;
      74              : }
      75              : 
      76              : GEN
      77       524405 : ellconvertname(GEN n)
      78              : {
      79       524405 :   switch(typ(n))
      80              :   {
      81       524391 :   case t_STR:
      82              :     {
      83              :       long f,i,c;
      84       524391 :       if (!ellparsename(GSTR(n),&f,&c,&i)) pari_err_TYPE("ellconvertname", n);
      85       524391 :       if (f<0 || c<0 || i<0)
      86            0 :         pari_err_TYPE("ellconvertname [incomplete name]", n);
      87       524391 :       return mkvec3s(f,c,i);
      88              :     }
      89           14 :   case t_VEC:
      90           14 :     if (lg(n)==4)
      91              :     {
      92           14 :       pari_sp av = avma;
      93           14 :       GEN f=gel(n,1), c=gel(n,2), s=gel(n,3);
      94           14 :       if (typ(f)!=t_INT || typ(c)!=t_INT || typ(s)!=t_INT)
      95            0 :         pari_err_TYPE("ellconvertname",n);
      96           14 :       return gc_GEN(av, shallowconcat1(mkvec3(f, ellrecode(itos(c)), s)));
      97              :     }
      98              :     /*fall through*/
      99              :   }
     100            0 :   pari_err_TYPE("ellconvertname",n);
     101              :   return NULL; /*LCOV_EXCL_LINE*/
     102              : }
     103              : 
     104              : THREAD GEN ellcondfile_cache;
     105              : THREAD long ellcondfile_cache_cond;
     106              : 
     107              : void
     108       378548 : pari_init_ellcondfile(void)
     109              : {
     110       378548 :   ellcondfile_cache = NULL;
     111       378548 :   ellcondfile_cache_cond = -1;
     112       378548 : }
     113              : 
     114              : static GEN
     115         1295 : ellcondfile(long n)
     116              : {
     117         1295 :   if (ellcondfile_cache_cond >= 0 && n == ellcondfile_cache_cond)
     118          728 :     return gcopy(ellcondfile_cache);
     119              :   else
     120              :   {
     121          567 :     pari_sp av = avma;
     122              :     pariFILE *F;
     123              :     GEN V;
     124          567 :     char *s = stack_sprintf("%s/elldata/ell%ld", pari_datadir, n);
     125          567 :     F = pari_fopengz(s);
     126          567 :     if (!F) pari_err_FILE("elldata file",s);
     127          567 :     set_avma(av);
     128          567 :     V = gp_read_stream(F->file);
     129          567 :     if (!V || typ(V)!=t_VEC ) pari_err_FILE("elldata file [read]",s);
     130          567 :     ellcondfile_cache_cond = -1; /* disable cache until update */
     131          567 :     if (ellcondfile_cache) gunclone(ellcondfile_cache);
     132          567 :     ellcondfile_cache = gclone(V);
     133          567 :     ellcondfile_cache_cond = n; /* re-enable cache */
     134          567 :     pari_fclose(F); return V;
     135              :   }
     136              : }
     137              : 
     138              : /* return the vector of all curves of conductor f */
     139              : static int
     140         9457 : cmpi1(GEN x, GEN v) { return cmpii(x, gel(v,1)); }
     141              : static GEN
     142         1092 : ellcondlist(long f)
     143              : {
     144         1092 :   pari_sp av = avma;
     145         1092 :   GEN V = ellcondfile(f/1000);
     146         1092 :   long i = tablesearch(V, utoipos(f), &cmpi1);
     147         1092 :   if (i)
     148              :   {
     149         1092 :     GEN v = gel(V,i);
     150         1092 :     return vecslice(v,2, lg(v)-1);
     151              :   }
     152            0 :   retgc_const(av, cgetg(1, t_VEC));
     153              : }
     154              : 
     155              : static GEN
     156         1036 : ellsearchbyname(GEN V, char *name)
     157              : {
     158              :   GEN x;
     159              :   long j;
     160         5068 :   for (j=1; j<lg(V); j++)
     161              :   {
     162         5068 :     GEN v = gel(V,j);
     163         5068 :     if (!strcmp(GSTR(gel(v,1)), name)) return v;
     164              :   }
     165            0 :   x = strtoGENstr(name);
     166            0 :   pari_err_DOMAIN("ellsearchbyname", "name", "=", x,x);
     167              :   return NULL;/*LCOV_EXCL_LINE*/
     168              : }
     169              : 
     170              : static GEN
     171           21 : ellsearchbyclass(GEN V, long c)
     172              : {
     173              :   long i,j,n;
     174              :   GEN res;
     175           84 :   for (n=0,j=1; j<lg(V); j++)
     176           63 :     if (strtoclass(GSTR(gmael(V,j,1)))==c) n++;
     177           21 :   res = cgetg(n+1,t_VEC);
     178           84 :   for (i=1,j=1; j<lg(V); j++)
     179           63 :     if (strtoclass(GSTR(gmael(V,j,1)))==c) res[i++] = V[j];
     180           21 :   return res;
     181              : }
     182              : 
     183              : GEN
     184           84 : ellsearch(GEN A)
     185              : {
     186           84 :   pari_sp av = avma;
     187              :   long f, c, i;
     188              :   GEN V;
     189           84 :   if      (typ(A)==t_INT) { f = itos(A); c = i = -1; }
     190           77 :   else if  (typ(A)==t_VEC)
     191              :   {
     192           35 :     long l = lg(A)-1;
     193           35 :     if (l<1 || l>3)
     194            7 :       pari_err_TYPE("ellsearch",A);
     195           28 :     f = gtos(gel(A,1));
     196           28 :     c = l>=2 ? gtos(gel(A,2)): -1;
     197           28 :     i = l>=3 ? gtos(gel(A,3)): -1;
     198           28 :     if (l>=3) A = ellconvertname(A);
     199              :   }
     200           42 :   else if (typ(A)==t_STR) {
     201           35 :     if (!ellparsename(GSTR(A),&f,&c,&i))
     202            7 :       pari_err_TYPE("ellsearch",A);
     203              :   } else {
     204            7 :     pari_err_TYPE("ellsearch",A);
     205              :     return NULL;/*LCOV_EXCL_LINE*/
     206              :   }
     207           63 :   if (f <= 0) pari_err_DOMAIN("ellsearch", "conductor", "<=", gen_0,stoi(f));
     208           56 :   V = ellcondlist(f);
     209           56 :   if (c >= 0)
     210           35 :     V = (i < 0)? ellsearchbyclass(V,c): ellsearchbyname(V, GSTR(A));
     211           56 :   return gc_GEN(av, V);
     212              : }
     213              : 
     214              : GEN
     215         1022 : ellsearchcurve(GEN name)
     216              : {
     217         1022 :   pari_sp ltop=avma;
     218              :   long f, c, i;
     219         1022 :   if (!ellparsename(GSTR(name),&f,&c,&i)) pari_err_TYPE("ellsearch",name);
     220         1022 :   if (f<0 || c<0 || i<0) pari_err_TYPE("ellsearch [incomplete name]", name);
     221         1022 :   return gc_GEN(ltop, ellsearchbyname(ellcondlist(f), GSTR(name)));
     222              : }
     223              : 
     224              : GEN
     225           21 : ellidentify(GEN E)
     226              : {
     227           21 :   pari_sp ltop=avma;
     228              :   long j;
     229              :   GEN V, M, G, N;
     230           21 :   checkell_Q(E);
     231           14 :   G = ellglobalred(E); N = gel(G,1);
     232           14 :   V = ellcondlist(itos(N));
     233           14 :   M = ellchangecurve(vecslice(E,1,5),gel(G,2));
     234           14 :   for (j=1; j<lg(V); j++)
     235           14 :     if (ZV_equal(gmael(V,j,2), M))
     236           14 :       return gc_GEN(ltop, mkvec2(gel(V,j),gel(G,2)));
     237            0 :   pari_err_BUG("ellidentify [missing curve]");
     238              :   return NULL;/*LCOV_EXCL_LINE*/
     239              : }
     240              : 
     241              : GEN
     242            7 : elldatagenerators(GEN E)
     243              : {
     244            7 :   pari_sp ltop=avma;
     245            7 :   GEN V=ellidentify(E);
     246            7 :   GEN gens=gmael(V,1,3);
     247            7 :   GEN W=ellchangepointinv(gens,gel(V,2));
     248            7 :   return gc_upto(ltop,W);
     249              : }
     250              : 
     251              : void
     252           56 : forell(void *E, long call(void*, GEN), long a, long b, long flag)
     253              : {
     254           56 :   long ca=a/1000, cb=b/1000;
     255              :   long i, j, k;
     256              : 
     257           56 :   if (ca < 0) ca = 0;
     258          259 :   for(i=ca; i<=cb; i++)
     259              :   {
     260          203 :     pari_sp ltop=avma;
     261          203 :     GEN V = ellcondfile(i);
     262       106099 :     for (j=1; j<lg(V); j++)
     263              :     {
     264       105945 :       GEN ells = gel(V,j);
     265       105945 :       long cond= itos(gel(ells,1));
     266              : 
     267       105945 :       if (i==ca && cond<a) continue;
     268       105945 :       if (i==cb && cond>b) break;
     269      1091664 :       for(k=2; k<lg(ells); k++)
     270              :       {
     271       985768 :         GEN e = gel(ells,k);
     272       985768 :         if (flag) {
     273         4284 :           GEN n = gel(e,1); /* Cremona label */
     274              :           long f, c, x;
     275         4284 :           if (!ellparsename(GSTR(n),&f,&c,&x))
     276            0 :             pari_err_TYPE("ellconvertname", n);
     277         4284 :           if (x != 1) continue;
     278              :         }
     279       982786 :         if (call(E, e)) return;
     280              :       }
     281              :     }
     282          203 :     set_avma(ltop);
     283              :   }
     284              : }
     285              : 
     286              : void
     287           56 : forell0(long a, long b, GEN code, long flag)
     288           56 : { EXPRVOID_WRAP(code, forell(EXPR_ARGVOID, a, b, flag)) }
        

Generated by: LCOV version 2.0-1