Code coverage tests

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

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

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

LCOV - code coverage report
Current view: top level - language - str.c (source / functions) Coverage Total Hit
Test: PARI/GP v2.18.1 lcov report (development 31041-bd73e9fcdd) Lines: 90.1 % 131 118
Test Date: 2026-07-22 22:45:42 Functions: 93.3 % 15 14
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Copyright (C) 2018  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              : #include "pari.h"
      16              : #include "paripriv.h"
      17              : 
      18              : /********************************************************************/
      19              : /**                                                                **/
      20              : /**                       CHARACTER STRINGS                        **/
      21              : /**                                                                **/
      22              : /********************************************************************/
      23              : 
      24              : /* Utillity functions */
      25              : char *
      26        42729 : stack_strdup(const char *s)
      27              : {
      28        42729 :   long n = strlen(s)+1;
      29        42729 :   char *t = stack_malloc(n);
      30        42729 :   memcpy(t,s,n); return t;
      31              : }
      32              : char *
      33         2009 : stack_strcat(const char *s, const char *t)
      34              : {
      35         2009 :   long ls = strlen(s), lt = strlen(t);
      36         2009 :   long n = ls + lt + 1;
      37         2009 :   char *u = stack_malloc(n);
      38         2009 :   memcpy(u,     s, ls);
      39         2009 :   memcpy(u + ls,t, lt+1); return u;
      40              : }
      41              : 
      42              : char *
      43        38737 : pari_strdup(const char *s)
      44              : {
      45        38737 :   long n = strlen(s)+1;
      46        38737 :   char *t = (char*)pari_malloc(n);
      47        38737 :   memcpy(t,s,n); return t;
      48              : }
      49              : char *
      50         5842 : pari_strndup(const char *s, long n)
      51              : {
      52         5842 :   char *t = (char*)pari_malloc(n+1);
      53         5842 :   memcpy(t,s,n); t[n] = 0; return t;
      54              : }
      55              : 
      56              : /* return the first n0 chars of s as a GEN [s may not be 0-terminated] */
      57              : GEN
      58       965319 : strntoGENstr(const char *s, long n0)
      59              : {
      60       965319 :   long n = nchar2nlong(n0+1); /* +1 for trailing 0 */
      61       965319 :   GEN x = cgetg(n+1, t_STR);
      62       965319 :   char *t = GSTR(x);
      63       965319 :   x[n] = 0; /* avoid uninitialized memory */
      64       965319 :   strncpy(t, s, n0); t[n0] = 0; return x;
      65              : }
      66              : 
      67              : /* strntoGENstr would trigger gcc-8 stringop-truncation warning */
      68              : GEN
      69      9300727 : strtoGENstr(const char *s)
      70              : {
      71      9300727 :   long n0 = strlen(s) + 1, n = nchar2nlong(n0);
      72      9300705 :   GEN x = cgetg(n+1, t_STR);
      73      9300669 :   char *t = GSTR(x);
      74      9300669 :   x[n] = 0; strncpy(t, s, n0); return x;
      75              : }
      76              : 
      77              : GEN
      78       340512 : chartoGENstr(char c)
      79              : {
      80       340512 :   GEN x = cgetg(2, t_STR);
      81       340512 :   char *t = GSTR(x);
      82       340512 :   t[0] = c; t[1] = 0; return x;
      83              : }
      84              : 
      85              : const char *
      86        46879 : type_name(long t)
      87              : {
      88              :   const char *s;
      89        46879 :   switch(t)
      90              :   {
      91        11424 :     case t_INT    : s="t_INT";     break;
      92         4536 :     case t_REAL   : s="t_REAL";    break;
      93         2548 :     case t_INTMOD : s="t_INTMOD";  break;
      94          595 :     case t_FRAC   : s="t_FRAC";    break;
      95         2625 :     case t_FFELT  : s="t_FFELT";   break;
      96         1897 :     case t_COMPLEX: s="t_COMPLEX"; break;
      97          896 :     case t_PADIC  : s="t_PADIC";   break;
      98         1113 :     case t_QUAD   : s="t_QUAD";    break;
      99         1358 :     case t_POLMOD : s="t_POLMOD";  break;
     100         3413 :     case t_POL    : s="t_POL";     break;
     101          679 :     case t_SER    : s="t_SER";     break;
     102           42 :     case t_RFRAC  : s="t_RFRAC";   break;
     103          147 :     case t_QFB    : s="t_QFB";     break;
     104         8411 :     case t_VEC    : s="t_VEC";     break;
     105         3752 :     case t_COL    : s="t_COL";     break;
     106         2366 :     case t_MAT    : s="t_MAT";     break;
     107           91 :     case t_LIST   : s="t_LIST";    break;
     108          469 :     case t_STR    : s="t_STR";     break;
     109          238 :     case t_VECSMALL:s="t_VECSMALL";break;
     110           42 :     case t_CLOSURE: s="t_CLOSURE"; break;
     111          216 :     case t_ERROR:   s="t_ERROR";   break;
     112           21 :     case t_INFINITY:s="t_INFINITY";break;
     113              :     default: pari_err_BUG("type"); s = NULL; /* LCOV_EXCL_LINE */
     114              :   }
     115        46879 :   return s;
     116              : }
     117              : 
     118              : GEN
     119        32678 : type0(GEN x)
     120              : {
     121        32678 :   const char *s = type_name(typ(x));
     122        32678 :   return strtoGENstr(s);
     123              : }
     124              : 
     125              : static char
     126         1960 : ltoc(long n) {
     127         1960 :   if (n <= 0 || n > 255)
     128            7 :     pari_err(e_MISC, "out of range in integer -> character conversion (%ld)", n);
     129         1953 :   return (char)n;
     130              : }
     131              : static char
     132           91 : itoc(GEN x) { return ltoc(gtos(x)); }
     133              : 
     134              : GEN
     135           28 : pari_strchr(GEN g)
     136              : {
     137           28 :   long i, l, len, t = typ(g);
     138              :   char *s;
     139              :   GEN x;
     140           28 :   if (is_vec_t(t)) {
     141            7 :     l = lg(g); len = nchar2nlong(l);
     142            7 :     x = cgetg(len+1, t_STR); s = GSTR(x);
     143           91 :     for (i=1; i<l; i++) *s++ = itoc(gel(g,i));
     144              :   }
     145           21 :   else if (t == t_VECSMALL)
     146              :   {
     147           14 :     l = lg(g); len = nchar2nlong(l);
     148           14 :     x = cgetg(len+1, t_STR); s = GSTR(x);
     149         1883 :     for (i=1; i<l; i++) *s++ = ltoc(g[i]);
     150              :   }
     151              :   else
     152            7 :     return chartoGENstr(itoc(g));
     153           21 :   *s = 0; return x;
     154              : }
     155              : 
     156              : GEN
     157           70 : strsplit(GEN x, GEN p)
     158              : {
     159              :   long i0, i, iv, ls, lt;
     160              :   char *s, *t;
     161              :   GEN v;
     162           70 :   if (typ(x) != t_STR) pari_err_TYPE("strsplit",x);
     163           63 :   s = GSTR(x); ls = strlen(s);
     164           63 :   if (!p) lt = 0;
     165              :   else
     166              :   {
     167           56 :     if (typ(p) != t_STR) pari_err_TYPE("strsplit",p);
     168           49 :     t = GSTR(p); lt = strlen(t);
     169              :   }
     170           56 :   if (!lt) /* empty separator: split by char */
     171              :   {
     172           14 :     v = cgetg(ls+1, t_VEC);
     173           56 :     for (i = 1; i <= ls; i++) gel(v,i) = chartoGENstr(s[i-1]);
     174           14 :     return v;
     175              :   }
     176           42 :   v = cgetg(ls + 2, t_VEC); iv = 1;
     177        33964 :   for (i = i0 = 0; i < ls; i++)
     178        35196 :     while (!strncmp(s + i, t, lt))
     179              :     {
     180         1274 :       gel(v, iv++) = strntoGENstr(s + i0, i - i0);
     181         1274 :       i += lt; i0 = i;
     182              :     }
     183           42 :   gel(v, iv++) = strntoGENstr(s + i0, i - i0);
     184           42 :   stackdummy((pari_sp)(v + iv), (pari_sp)(v + ls + 2));
     185           42 :   setlg(v, iv); return v;
     186              : }
     187              : 
     188              : GEN
     189           63 : strjoin(GEN v, GEN p)
     190              : {
     191           63 :   pari_sp av = avma;
     192              :   long i, l;
     193              :   GEN w;
     194           63 :   if (!is_vec_t(typ(v))) pari_err_TYPE("strjoin",v);
     195           56 :   if (p && typ(p) != t_STR) pari_err_TYPE("strjoin",p);
     196           49 :   l = lg(v);
     197           49 :   if (l == 1) return strtoGENstr("");
     198           42 :   if (l == 2)
     199              :   {
     200           14 :     char *s = GENtostr_unquoted(gel(v,1));
     201           14 :     return gc_leaf(av, strtoGENstr(s));
     202              :   }
     203           28 :   if (!p || !*GSTR(p))
     204              :   { /* no delimiter: shortcut */
     205            7 :     w = cgetg(l, t_VEC);
     206           28 :     for (i = 1; i < l; i++)
     207              :     {
     208           21 :       GEN s = gel(v,i);
     209           21 :       if (typ(s) != t_STR) s = GENtoGENstr(gel(v,i));
     210           21 :       gel(w,i) = s;
     211              :     }
     212              :   }
     213              :   else
     214              :   {
     215           21 :     w = cgetg(2*l - 2, t_VEC);
     216           21 :     gel(w, 1) = gel(v, 1);
     217         1204 :     for (i = 2; i < l; i++)
     218              :     {
     219         1183 :       GEN s = gel(v,i);
     220         1183 :       if (typ(s) != t_STR) s = GENtoGENstr(gel(v,i));
     221         1183 :       gel(w, 2*i-2) = p;
     222         1183 :       gel(w, 2*i-1) = s;
     223              :     }
     224              :   }
     225           28 :   return gc_leaf(av, shallowconcat1(w));
     226              : }
     227              : 
     228              : GEN
     229            0 : pari_base64(const char *s)
     230              : {
     231              :   static const char *base64 =
     232              :     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     233            0 :   long i, j, ls = strlen(s), lt = ((ls+2)/3)*4;
     234            0 :   long n = nchar2nlong(lt+1);
     235            0 :   GEN g = cgetg(1+n, t_STR);
     236            0 :   char *t = GSTR(g);
     237            0 :   g[n] = 0L;
     238            0 :   for(i=j=0; i < ls; i+=3, j+=4)
     239              :   {
     240            0 :     char s0 = s[i], s1 = i+1<ls ? s[i+1]: 0, s2 = i+2<ls ? s[i+2]: 0;
     241            0 :     t[j] = base64[(s0 & 0xfc) >> 2];
     242            0 :     t[j+1] = base64[((s0 & 0x3) << 4) + ((s1 & 0xf0) >> 4)];
     243            0 :     t[j+2] = i+1<ls ? base64[((s1 & 0xf) << 2) + ((s2 & 0xc0) >> 6)]: '=';
     244            0 :     t[j+3] = i+2<ls ? base64[s2 & 0x3f]: '=';
     245              :   }
     246            0 :   return g;
     247              : }
        

Generated by: LCOV version 2.0-1