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) Hit Total Coverage
Test: PARI/GP v2.18.0 lcov report (development 29792-e7296d7d08) Lines: 111 124 89.5 %
Date: 2024-12-05 09:09:40 Functions: 14 15 93.3 %
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       41431 : stack_strdup(const char *s)
      27             : {
      28       41431 :   long n = strlen(s)+1;
      29       41431 :   char *t = stack_malloc(n);
      30       41431 :   memcpy(t,s,n); return t;
      31             : }
      32             : char *
      33        1211 : stack_strcat(const char *s, const char *t)
      34             : {
      35        1211 :   long ls = strlen(s), lt = strlen(t);
      36        1211 :   long n = ls + lt + 1;
      37        1211 :   char *u = stack_malloc(n);
      38        1211 :   memcpy(u,     s, ls);
      39        1211 :   memcpy(u + ls,t, lt+1); return u;
      40             : }
      41             : 
      42             : char *
      43       38076 : pari_strdup(const char *s)
      44             : {
      45       38076 :   long n = strlen(s)+1;
      46       38076 :   char *t = (char*)pari_malloc(n);
      47       38076 :   memcpy(t,s,n); return t;
      48             : }
      49             : char *
      50        5767 : pari_strndup(const char *s, long n)
      51             : {
      52        5767 :   char *t = (char*)pari_malloc(n+1);
      53        5767 :   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      958255 : strntoGENstr(const char *s, long n0)
      59             : {
      60      958255 :   long n = nchar2nlong(n0+1); /* +1 for trailing 0 */
      61      958255 :   GEN x = cgetg(n+1, t_STR);
      62      958255 :   char *t = GSTR(x);
      63      958255 :   x[n] = 0; /* avoid uninitialized memory */
      64      958255 :   strncpy(t, s, n0); t[n0] = 0; return x;
      65             : }
      66             : 
      67             : /* strntoGENstr would trigger gcc-8 stringop-truncation warning */
      68             : GEN
      69     8130257 : strtoGENstr(const char *s)
      70             : {
      71     8130257 :   long n0 = strlen(s) + 1, n = nchar2nlong(n0);
      72     8130243 :   GEN x = cgetg(n+1, t_STR);
      73     8130214 :   char *t = GSTR(x);
      74     8130214 :   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       45886 : type_name(long t)
      87             : {
      88             :   const char *s;
      89       45886 :   switch(t)
      90             :   {
      91       11025 :     case t_INT    : s="t_INT";     break;
      92        4312 :     case t_REAL   : s="t_REAL";    break;
      93        2576 :     case t_INTMOD : s="t_INTMOD";  break;
      94         595 :     case t_FRAC   : s="t_FRAC";    break;
      95        2583 :     case t_FFELT  : s="t_FFELT";   break;
      96        1771 :     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        3364 :     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        8306 :     case t_VEC    : s="t_VEC";     break;
     105        3724 :     case t_COL    : s="t_COL";     break;
     106        2310 :     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          50 :     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       45886 :   return s;
     116             : }
     117             : 
     118             : GEN
     119       31804 : type0(GEN x)
     120             : {
     121       31804 :   const char *s = type_name(typ(x));
     122       31804 :   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       33957 :   for (i = i0 = 0; i < ls; i++)
     178       35189 :     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 gerepileuptoleaf(av, strtoGENstr(s));
     202             :   }
     203          28 :   if (!p) p = strtoGENstr("");
     204          28 :   w = cgetg(2*l - 2, t_VEC);
     205          28 :   gel(w, 1) = gel(v, 1);
     206        1225 :   for (i = 2; i < l; i++)
     207             :   {
     208        1197 :     gel(w, 2*i-2) = p;
     209        1197 :     gel(w, 2*i-1) = gel(v, i);
     210             :   }
     211          28 :   return gerepileuptoleaf(av, shallowconcat1(w));
     212             : }
     213             : 
     214             : GEN
     215           0 : pari_base64(const char *s)
     216             : {
     217             :   static const char *base64 =
     218             :     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     219           0 :   long i, j, ls = strlen(s), lt = ((ls+2)/3)*4;
     220           0 :   long n = nchar2nlong(lt+1);
     221           0 :   GEN g = cgetg(1+n, t_STR);
     222           0 :   char *t = GSTR(g);
     223           0 :   g[n] = 0L;
     224           0 :   for(i=j=0; i < ls; i+=3, j+=4)
     225             :   {
     226           0 :     char s0 = s[i], s1 = i+1<ls ? s[i+1]: 0, s2 = i+2<ls ? s[i+2]: 0;
     227           0 :     t[j] = base64[(s0 & 0xfc) >> 2];
     228           0 :     t[j+1] = base64[((s0 & 0x3) << 4) + ((s1 & 0xf0) >> 4)];
     229           0 :     t[j+2] = i+1<ls ? base64[((s1 & 0xf) << 2) + ((s2 & 0xc0) >> 6)]: '=';
     230           0 :     t[j+3] = i+2<ls ? base64[s2 & 0x3f]: '=';
     231             :   }
     232           0 :   return g;
     233             : }

Generated by: LCOV version 1.16