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 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 - default.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.8.0 lcov report (development 19217-a6dcf64) Lines: 239 493 48.5 %
Date: 2016-07-27 07:10:32 Functions: 29 59 49.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2000  The PARI group.
       2             : 
       3             : This file is part of the PARI/GP package.
       4             : 
       5             : PARI/GP is free software; you can redistribute it and/or modify it under the
       6             : terms of the GNU General Public License as published by the Free Software
       7             : Foundation. It is distributed in the hope that it will be useful, but WITHOUT
       8             : ANY WARRANTY WHATSOEVER.
       9             : 
      10             : Check the License for details. You should have received a copy of it, along
      11             : with the package; see the file 'COPYING'. If not, write to the Free Software
      12             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      13             : #include "pari.h"
      14             : #include "paripriv.h"
      15             : 
      16             : #ifdef _WIN32
      17             : #  include "../systems/mingw/mingw.h"
      18             : #endif
      19             : 
      20             : 
      21             : /* Return all chars, up to next separator
      22             :  * [as strtok but must handle verbatim character string] */
      23             : char*
      24        1383 : get_sep(const char *t)
      25             : {
      26        1383 :   char *buf = stack_malloc(strlen(t)+1);
      27        1383 :   char *s = buf;
      28        1383 :   int outer = 1;
      29             : 
      30             :   for(;;)
      31             :   {
      32        4460 :     switch(*s++ = *t++)
      33             :     {
      34             :       case '"':
      35           0 :         outer = !outer; break;
      36             :       case '\0':
      37        1376 :         return buf;
      38             :       case ';':
      39           0 :         if (outer) { s[-1] = 0; return buf; }
      40           0 :         break;
      41             :       case '\\': /* gobble next char */
      42           7 :         if (! (*s++ = *t++) ) return buf;
      43             :     }
      44        3077 :   }
      45             : }
      46             : 
      47             : static ulong
      48          56 : safe_mul(ulong x, ulong y)
      49             : {
      50             :   ulong z;
      51             :   LOCAL_HIREMAINDER;
      52          56 :   z = mulll(x, y);
      53          56 :   return hiremainder? 0: z;
      54             : }
      55             : 
      56             : /* "atoul" + optional [kmg] suffix */
      57             : static ulong
      58        1141 : my_int(char *s)
      59             : {
      60        1141 :   ulong n = 0;
      61        1141 :   char *p = s;
      62             : 
      63        4743 :   while (isdigit((int)*p)) {
      64             :     ulong m;
      65        2461 :     if (n > (~0UL / 10)) pari_err(e_SYNTAX,"integer too large",s,s);
      66        2461 :     n *= 10; m = n;
      67        2461 :     n += *p++ - '0';
      68        2461 :     if (n < m) pari_err(e_SYNTAX,"integer too large",s,s);
      69             :   }
      70        1141 :   if (n)
      71             :   {
      72        1127 :     switch(*p)
      73             :     {
      74           0 :       case 'k': case 'K': n = safe_mul(n,1000UL);       p++; break;
      75          56 :       case 'm': case 'M': n = safe_mul(n,1000000UL);    p++; break;
      76           0 :       case 'g': case 'G': n = safe_mul(n,1000000000UL); p++; break;
      77             : #ifdef LONG_IS_64BIT
      78           0 :       case 't': case 'T': n = safe_mul(n,1000000000000UL); p++; break;
      79             : #endif
      80             :     }
      81        1127 :     if (!n) pari_err(e_SYNTAX,"integer too large",s,s);
      82             :   }
      83        1141 :   if (*p) pari_err(e_SYNTAX,"I was expecting an integer here", s, s);
      84        1141 :   return n;
      85             : }
      86             : 
      87             : long
      88         158 : get_int(const char *s, long dflt)
      89             : {
      90         158 :   pari_sp av = avma;
      91         158 :   char *p = get_sep(s);
      92             :   long n;
      93         158 :   int minus = 0;
      94             : 
      95         158 :   if (*p == '-') { minus = 1; p++; }
      96         158 :   if (!isdigit((int)*p)) { avma = av; return dflt; }
      97             : 
      98         158 :   n = (long)my_int(p);
      99         158 :   if (n < 0) pari_err(e_SYNTAX,"integer too large",s,s);
     100         158 :   avma = av; return minus? -n: n;
     101             : }
     102             : 
     103             : ulong
     104         983 : get_uint(const char *s)
     105             : {
     106         983 :   pari_sp av = avma;
     107         983 :   char *p = get_sep(s);
     108             :   ulong u;
     109         983 :   if (*p == '-') pari_err(e_SYNTAX,"arguments must be positive integers",s,s);
     110         983 :   u = my_int(p); avma = av; return u;
     111             : }
     112             : 
     113             : /********************************************************************/
     114             : /*                                                                  */
     115             : /*                            DEFAULTS                              */
     116             : /*                                                                  */
     117             : /********************************************************************/
     118             : 
     119             : long
     120           0 : getrealprecision(void)
     121             : {
     122           0 :   return GP_DATA->fmt->sigd;
     123             : }
     124             : 
     125             : long
     126           0 : setrealprecision(long n, long *prec)
     127             : {
     128           0 :   GP_DATA->fmt->sigd = n;
     129           0 :   *prec = ndec2prec(n);
     130           0 :   precreal = prec2nbits(*prec);
     131           0 :   return n;
     132             : }
     133             : 
     134             : GEN
     135         158 : sd_toggle(const char *v, long flag, const char *s, int *ptn)
     136             : {
     137         158 :   int state = *ptn;
     138         158 :   if (v)
     139             :   {
     140         158 :     int n = (int)get_int(v,0);
     141         158 :     if (n == state) return gnil;
     142         158 :     if (n != !state)
     143             :     {
     144           0 :       char *t = stack_malloc(64 + strlen(s));
     145           0 :       (void)sprintf(t, "default: incorrect value for %s [0:off / 1:on]", s);
     146           0 :       pari_err(e_SYNTAX, t, v,v);
     147             :     }
     148         158 :     state = *ptn = n;
     149             :   }
     150         158 :   switch(flag)
     151             :   {
     152           0 :     case d_RETURN: return utoi(state);
     153             :     case d_ACKNOWLEDGE:
     154         109 :       if (state) pari_printf("   %s = 1 (on)\n", s);
     155           0 :       else       pari_printf("   %s = 0 (off)\n", s);
     156         109 :       break;
     157             :   }
     158         158 :   return gnil;
     159             : }
     160             : 
     161             : static void
     162         983 : sd_ulong_init(const char *v, const char *s, ulong *ptn, ulong Min, ulong Max)
     163             : {
     164         983 :   if (v)
     165             :   {
     166         983 :     ulong n = get_uint(v);
     167         983 :     if (n > Max || n < Min)
     168             :     {
     169           0 :       char *buf = stack_malloc(strlen(s) + 2 * 20 + 40);
     170           0 :       (void)sprintf(buf, "default: incorrect value for %s [%lu-%lu]",
     171             :                     s, Min, Max);
     172           0 :       pari_err(e_SYNTAX, buf, v,v);
     173             :     }
     174         983 :     *ptn = n;
     175             :   }
     176         983 : }
     177             : 
     178             : /* msg is NULL or NULL-terminated array with msg[0] != NULL. */
     179             : GEN
     180         147 : sd_ulong(const char *v, long flag, const char *s, ulong *ptn, ulong Min, ulong Max,
     181             :          const char **msg)
     182             : {
     183         147 :   ulong n = *ptn;
     184         147 :   sd_ulong_init(v, s, ptn, Min, Max);
     185         147 :   switch(flag)
     186             :   {
     187             :     case d_RETURN:
     188           0 :       return utoi(*ptn);
     189             :     case d_ACKNOWLEDGE:
     190           7 :       if (!v || *ptn != n) {
     191           7 :         if (!msg)         /* no specific message */
     192           7 :           pari_printf("   %s = %lu\n", s, *ptn);
     193           0 :         else if (!msg[1]) /* single message, always printed */
     194           0 :           pari_printf("   %s = %lu %s\n", s, *ptn, msg[0]);
     195             :         else              /* print (new)-n-th message */
     196           0 :           pari_printf("   %s = %lu %s\n", s, *ptn, msg[*ptn]);
     197             :       }
     198           7 :       break;
     199             :   }
     200         147 :   return gnil;
     201             : }
     202             : 
     203             : GEN
     204         829 : sd_realprecision(const char *v, long flag)
     205             : {
     206         829 :   pariout_t *fmt = GP_DATA->fmt;
     207         829 :   if (v)
     208             :   {
     209         829 :     ulong newnb = fmt->sigd;
     210             :     long prec;
     211         829 :     sd_ulong_init(v, "realprecision", &newnb, 1, prec2ndec(LGBITS));
     212        1215 :     if (fmt->sigd == (long)newnb) return gnil;
     213         443 :     if (fmt->sigd >= 0) fmt->sigd = newnb;
     214         443 :     prec = ndec2nbits(newnb);
     215         443 :     if (prec == precreal) return gnil;
     216         443 :     precreal = prec;
     217             :   }
     218         443 :   if (flag == d_RETURN) return stoi(nbits2ndec(precreal));
     219         443 :   if (flag == d_ACKNOWLEDGE)
     220             :   {
     221         144 :     long n = nbits2ndec(precreal);
     222         144 :     pari_printf("   realprecision = %ld significant digits", n);
     223         144 :     if (fmt->sigd < 0)
     224           0 :       pari_puts(" (all digits displayed)");
     225         144 :     else if (n != fmt->sigd)
     226          21 :       pari_printf(" (%ld digits displayed)", fmt->sigd);
     227         144 :     pari_putc('\n');
     228             :   }
     229         443 :   return gnil;
     230             : }
     231             : 
     232             : GEN
     233           7 : sd_realbitprecision(const char *v, long flag)
     234             : {
     235           7 :   pariout_t *fmt = GP_DATA->fmt;
     236           7 :   if (v)
     237             :   {
     238           7 :     ulong newnb = precreal;
     239             :     long n;
     240           7 :     sd_ulong_init(v, "realbitprecision", &newnb, 1, prec2nbits(LGBITS));
     241           7 :     if ((long)newnb == precreal) return gnil;
     242           7 :     n = nbits2ndec(newnb);
     243           7 :     if (!n) n = 1;
     244           7 :     if (fmt->sigd >= 0) fmt->sigd = n;
     245           7 :     precreal = (long) newnb;
     246             :   }
     247           7 :   if (flag == d_RETURN) return stoi(precreal);
     248           7 :   if (flag == d_ACKNOWLEDGE)
     249             :   {
     250           7 :     pari_printf("   realbitprecision = %ld significant bits", precreal);
     251           7 :     if (fmt->sigd < 0)
     252           0 :       pari_puts(" (all digits displayed)");
     253             :     else
     254           7 :       pari_printf(" (%ld decimal digits displayed)", fmt->sigd);
     255           7 :     pari_putc('\n');
     256             :   }
     257           7 :   return gnil;
     258             : }
     259             : 
     260             : GEN
     261          21 : sd_seriesprecision(const char *v, long flag)
     262             : {
     263          21 :   const char *msg[] = {"significant terms", NULL};
     264          21 :   return sd_ulong(v,flag,"seriesprecision",&precdl, 1,LGBITS,msg);
     265             : }
     266             : 
     267             : static long
     268           0 : gp_get_color(char **st)
     269             : {
     270           0 :   char *s, *v = *st;
     271             :   int trans;
     272             :   long c;
     273           0 :   if (isdigit((int)*v))
     274           0 :     { c = atol(v); trans = 1; } /* color on transparent background */
     275             :   else
     276             :   {
     277           0 :     if (*v == '[')
     278             :     {
     279             :       const char *a[3];
     280           0 :       long i = 0;
     281           0 :       for (a[0] = s = ++v; *s && *s != ']'; s++)
     282           0 :         if (*s == ',') { *s = 0; a[++i] = s+1; }
     283           0 :       if (*s != ']') pari_err(e_SYNTAX,"expected character: ']'",s, *st);
     284           0 :       *s = 0; for (i++; i<3; i++) a[i] = "";
     285             :       /*    properties    |   color    | background */
     286           0 :       c = (atoi(a[2])<<8) | atoi(a[0]) | (atoi(a[1])<<4);
     287           0 :       trans = (*(a[1]) == 0);
     288           0 :       v = s + 1;
     289             :     }
     290           0 :     else { c = c_NONE; trans = 0; }
     291             :   }
     292           0 :   if (trans) c = c | (1L<<12);
     293           0 :   while (*v && *v++ != ',') /* empty */;
     294           0 :   if (c != c_NONE) disable_color = 0;
     295           0 :   *st = v; return c;
     296             : }
     297             : 
     298             : /* 1: error, 2: history, 3: prompt, 4: input, 5: output, 6: help, 7: timer */
     299             : GEN
     300           0 : sd_colors(const char *v, long flag)
     301             : {
     302             :   long c,l;
     303           0 :   if (v && !(GP_DATA->flags & (gpd_EMACS|gpd_TEXMACS)))
     304             :   {
     305             :     char *v0, *s;
     306           0 :     disable_color=1;
     307           0 :     l = strlen(v);
     308           0 :     if (l <= 2 && strncmp(v, "no", l) == 0)
     309           0 :       v = "";
     310           0 :     if (l <= 6 && strncmp(v, "darkbg", l) == 0)
     311           0 :       v = "1, 5, 3, 7, 6, 2, 3"; /* Assume recent ReadLine. */
     312           0 :     if (l <= 7 && strncmp(v, "lightbg", l) == 0)
     313           0 :       v = "1, 6, 3, 4, 5, 2, 3"; /* Assume recent ReadLine. */
     314           0 :     if (l <= 8 && strncmp(v, "brightfg", l) == 0)      /* Good for windows consoles */
     315           0 :       v = "9, 13, 11, 15, 14, 10, 11";
     316           0 :     if (l <= 6 && strncmp(v, "boldfg", l) == 0)        /* Good for darkbg consoles */
     317           0 :       v = "[1,,1], [5,,1], [3,,1], [7,,1], [6,,1], , [2,,1]";
     318           0 :     v0 = s = gp_filter(v);
     319           0 :     for (c=c_ERR; c < c_LAST; c++)
     320           0 :       gp_colors[c] = gp_get_color(&s);
     321           0 :     pari_free(v0);
     322             :   }
     323           0 :   if (flag == d_ACKNOWLEDGE || flag == d_RETURN)
     324             :   {
     325           0 :     char s[128], *t = s;
     326             :     long col[3], n;
     327           0 :     for (*t=0,c=c_ERR; c < c_LAST; c++)
     328             :     {
     329           0 :       n = gp_colors[c];
     330           0 :       if (n == c_NONE)
     331           0 :         sprintf(t,"no");
     332             :       else
     333             :       {
     334           0 :         decode_color(n,col);
     335           0 :         if (n & (1L<<12))
     336             :         {
     337           0 :           if (col[0])
     338           0 :             sprintf(t,"[%ld,,%ld]",col[1],col[0]);
     339             :           else
     340           0 :             sprintf(t,"%ld",col[1]);
     341             :         }
     342             :         else
     343           0 :           sprintf(t,"[%ld,%ld,%ld]",col[1],col[2],col[0]);
     344             :       }
     345           0 :       t += strlen(t);
     346           0 :       if (c < c_LAST - 1) { *t++=','; *t++=' '; }
     347             :     }
     348           0 :     if (flag==d_RETURN) return strtoGENstr(s);
     349           0 :     pari_printf("   colors = \"%s\"\n",s);
     350             :   }
     351           0 :   return gnil;
     352             : }
     353             : 
     354             : GEN
     355           7 : sd_format(const char *v, long flag)
     356             : {
     357           7 :   pariout_t *fmt = GP_DATA->fmt;
     358           7 :   if (v)
     359             :   {
     360           7 :     char c = *v;
     361           7 :     if (c!='e' && c!='f' && c!='g')
     362           0 :       pari_err(e_SYNTAX,"default: inexistent format",v,v);
     363           7 :     fmt->format = c; v++;
     364             : 
     365           7 :     if (isdigit((int)*v))
     366           0 :       { while (isdigit((int)*v)) v++; } /* FIXME: skip obsolete field width */
     367           7 :     if (*v++ == '.')
     368             :     {
     369           7 :       if (*v == '-') fmt->sigd = -1;
     370             :       else
     371           7 :         if (isdigit((int)*v)) fmt->sigd=atol(v);
     372             :     }
     373             :   }
     374           7 :   if (flag == d_RETURN)
     375             :   {
     376           0 :     char *s = stack_malloc(64);
     377           0 :     (void)sprintf(s, "%c.%ld", fmt->format, fmt->sigd);
     378           0 :     return strtoGENstr(s);
     379             :   }
     380           7 :   if (flag == d_ACKNOWLEDGE)
     381           0 :     pari_printf("   format = %c.%ld\n", fmt->format, fmt->sigd);
     382           7 :   return gnil;
     383             : }
     384             : 
     385             : GEN
     386           0 : sd_compatible(const char *v, long flag)
     387             : {
     388           0 :   const char *msg[] = {
     389             :     "(no backward compatibility)",
     390             :     "(no backward compatibility)",
     391             :     "(no backward compatibility)",
     392             :     "(no backward compatibility)", NULL
     393             :   };
     394           0 :   ulong junk = 0;
     395           0 :   return sd_ulong(v,flag,"compatible",&junk, 0,3,msg);
     396             : }
     397             : 
     398             : GEN
     399           0 : sd_secure(const char *v, long flag)
     400             : {
     401           0 :   if (v && GP_DATA->secure)
     402           0 :     pari_ask_confirm("[secure mode]: About to modify the 'secure' flag");
     403           0 :   return sd_toggle(v,flag,"secure", &(GP_DATA->secure));
     404             : }
     405             : 
     406             : GEN
     407          21 : sd_debug(const char *v, long flag)
     408          21 : { return sd_ulong(v,flag,"debug",&DEBUGLEVEL, 0,20,NULL); }
     409             : 
     410             : GEN
     411           0 : sd_debugfiles(const char *v, long flag)
     412           0 : { return sd_ulong(v,flag,"debugfiles",&DEBUGFILES, 0,20,NULL); }
     413             : 
     414             : GEN
     415           0 : sd_debugmem(const char *v, long flag)
     416           0 : { return sd_ulong(v,flag,"debugmem",&DEBUGMEM, 0,20,NULL); }
     417             : 
     418             : /* set D->hist to size = s / total = t */
     419             : static void
     420        1342 : init_hist(gp_data *D, size_t s, ulong t)
     421             : {
     422        1342 :   gp_hist *H = D->hist;
     423        1342 :   H->total = t;
     424        1342 :   H->size = s;
     425        1342 :   H->v = (gp_hist_cell*)pari_calloc(s * sizeof(gp_hist_cell));
     426        1342 : }
     427             : GEN
     428          14 : sd_histsize(const char *s, long flag)
     429             : {
     430          14 :   gp_hist *H = GP_DATA->hist;
     431          14 :   ulong n = H->size;
     432          14 :   GEN r = sd_ulong(s,flag,"histsize",&n, 1,
     433             :                      (LONG_MAX / sizeof(long)) - 1,NULL);
     434          14 :   if (n != H->size)
     435             :   {
     436          14 :     const ulong total = H->total;
     437             :     long g, h, k, kmin;
     438          14 :     gp_hist_cell *v = H->v, *w; /* v = old data, w = new one */
     439          14 :     size_t sv = H->size, sw;
     440             : 
     441          14 :     init_hist(GP_DATA, n, total);
     442          14 :     if (!total) return r;
     443             : 
     444          14 :     w = H->v;
     445          14 :     sw= H->size;
     446             :     /* copy relevant history entries */
     447          14 :     g     = (total-1) % sv;
     448          14 :     h = k = (total-1) % sw;
     449          14 :     kmin = k - minss(sw, sv);
     450          28 :     for ( ; k > kmin; k--, g--, h--)
     451             :     {
     452          14 :       w[h]   = v[g];
     453          14 :       v[g].z = NULL;
     454          14 :       if (!g) g = sv;
     455          14 :       if (!h) h = sw;
     456             :     }
     457             :     /* clean up */
     458          84 :     for ( ; v[g].z; g--)
     459             :     {
     460          70 :       gunclone(v[g].z);
     461          70 :       if (!g) g = sv;
     462             :     }
     463          14 :     pari_free((void*)v);
     464             :   }
     465          14 :   return r;
     466             : }
     467             : 
     468             : static void
     469           0 : TeX_define(const char *s, const char *def) {
     470           0 :   fprintf(pari_logfile, "\\ifx\\%s\\undefined\n  \\def\\%s{%s}\\fi\n", s,s,def);
     471           0 : }
     472             : static void
     473           0 : TeX_define2(const char *s, const char *def) {
     474           0 :   fprintf(pari_logfile, "\\ifx\\%s\\undefined\n  \\def\\%s#1#2{%s}\\fi\n", s,s,def);
     475           0 : }
     476             : 
     477             : static FILE *
     478           0 : open_logfile(const char *s) {
     479           0 :   FILE *log = fopen(s, "a");
     480           0 :   if (!log) pari_err_FILE("logfile",s);
     481           0 :   setbuf(log,(char *)NULL);
     482           0 :   return log;
     483             : }
     484             : 
     485             : GEN
     486           0 : sd_log(const char *v, long flag)
     487             : {
     488           0 :   const char *msg[] = {
     489             :       "(off)",
     490             :       "(on)",
     491             :       "(on with colors)",
     492             :       "(TeX output)", NULL
     493             :   };
     494           0 :   ulong s = logstyle;
     495           0 :   GEN res = sd_ulong(v,flag,"log", &s, 0, 3, msg);
     496             : 
     497           0 :   if (!s != !logstyle) /* Compare converts to boolean */
     498             :   { /* toggled LOG */
     499           0 :     if (logstyle)
     500             :     { /* close log */
     501           0 :       if (flag == d_ACKNOWLEDGE)
     502           0 :         pari_printf("   [logfile was \"%s\"]\n", current_logfile);
     503           0 :       if (pari_logfile) /* paranoia */
     504             :       {
     505           0 :         fclose(pari_logfile);
     506           0 :         pari_logfile = NULL;
     507             :       }
     508             :     }
     509             :     else
     510           0 :       pari_logfile = open_logfile(current_logfile);
     511             :   }
     512           0 :   if (pari_logfile && s != logstyle && s == logstyle_TeX)
     513             :   {
     514           0 :     TeX_define("PARIbreak",
     515             :                "\\hskip 0pt plus \\hsize\\relax\\discretionary{}{}{}");
     516           0 :     TeX_define("PARIpromptSTART", "\\vskip\\medskipamount\\bgroup\\bf");
     517           0 :     TeX_define("PARIpromptEND", "\\egroup\\bgroup\\tt");
     518           0 :     TeX_define("PARIinputEND", "\\egroup");
     519           0 :     TeX_define2("PARIout",
     520             :                 "\\vskip\\smallskipamount$\\displaystyle{\\tt\\%#1} = #2$");
     521             :   }
     522             :   /* don't record new value until we are sure everything is fine */
     523           0 :   logstyle = s; return res;
     524             : }
     525             : 
     526             : GEN
     527           0 : sd_TeXstyle(const char *v, long flag)
     528             : {
     529           0 :   const char *msg[] = { "(bits 0x2/0x4 control output of \\left/\\PARIbreak)",
     530             :                         NULL };
     531           0 :   ulong n = GP_DATA->fmt->TeXstyle;
     532           0 :   GEN z = sd_ulong(v,flag,"TeXstyle", &n, 0, 7, msg);
     533           0 :   GP_DATA->fmt->TeXstyle = n; return z;
     534             : }
     535             : 
     536             : GEN
     537           0 : sd_nbthreads(const char *v, long flag)
     538           0 : { return sd_ulong(v,flag,"nbthreads",&pari_mt_nbthreads, 1,LONG_MAX,NULL); }
     539             : 
     540             : GEN
     541           0 : sd_output(const char *v, long flag)
     542             : {
     543           0 :   const char *msg[] = {"(raw)", "(prettymatrix)", "(prettyprint)",
     544             :                  "(external prettyprint)", NULL};
     545           0 :   ulong n = GP_DATA->fmt->prettyp;
     546           0 :   GEN z = sd_ulong(v,flag,"output", &n, 0,3,msg);
     547           0 :   GP_DATA->fmt->prettyp = n;
     548           0 :   GP_DATA->fmt->sp = (n != f_RAW);
     549           0 :   return z;
     550             : }
     551             : 
     552             : GEN
     553           0 : sd_parisizemax(const char *v, long flag)
     554             : {
     555           0 :   ulong size = pari_mainstack->vsize, n = size;
     556           0 :   GEN r = sd_ulong(v,flag,"parisizemax",&n, 0,LONG_MAX,NULL);
     557           0 :   if (n != size) {
     558           0 :     if (flag == d_INITRC)
     559           0 :       paristack_setsize(pari_mainstack->rsize, n);
     560             :     else
     561           0 :       parivstack_resize(n);
     562             :   }
     563           0 :   return r;
     564             : }
     565             : 
     566             : GEN
     567          77 : sd_parisize(const char *v, long flag)
     568             : {
     569          77 :   ulong rsize = pari_mainstack->rsize, n = rsize;
     570          77 :   GEN r = sd_ulong(v,flag,"parisize",&n, 10000,LONG_MAX,NULL);
     571          77 :   if (n != rsize) {
     572          77 :     if (flag == d_INITRC)
     573           0 :       paristack_setsize(n, pari_mainstack->vsize);
     574             :     else
     575          77 :       paristack_newrsize(n);
     576             :   }
     577           0 :   return r;
     578             : }
     579             : 
     580             : GEN
     581           0 : sd_threadsizemax(const char *v, long flag)
     582             : {
     583           0 :   ulong size = GP_DATA->threadsizemax, n = size;
     584           0 :   GEN r = sd_ulong(v,flag,"threadsizemax",&n, 0,LONG_MAX,NULL);
     585           0 :   if (n != size)
     586           0 :     GP_DATA->threadsizemax = n;
     587           0 :   return r;
     588             : }
     589             : 
     590             : GEN
     591           0 : sd_threadsize(const char *v, long flag)
     592             : {
     593           0 :   ulong size = GP_DATA->threadsize, n = size;
     594           0 :   GEN r = sd_ulong(v,flag,"threadsize",&n, 0,LONG_MAX,NULL);
     595           0 :   if (n != size)
     596           0 :     GP_DATA->threadsize = n;
     597           0 :   return r;
     598             : }
     599             : 
     600             : GEN
     601          14 : sd_primelimit(const char *v, long flag)
     602          14 : { return sd_ulong(v,flag,"primelimit",&(GP_DATA->primelimit),
     603             :                   0,2*(ulong)(LONG_MAX-1024) + 1,NULL); }
     604             : 
     605             : GEN
     606           0 : sd_simplify(const char *v, long flag)
     607           0 : { return sd_toggle(v,flag,"simplify", &(GP_DATA->simplify)); }
     608             : 
     609             : GEN
     610           0 : sd_strictmatch(const char *v, long flag)
     611           0 : { return sd_toggle(v,flag,"strictmatch", &(GP_DATA->strictmatch)); }
     612             : 
     613             : GEN
     614           7 : sd_strictargs(const char *v, long flag)
     615           7 : { return sd_toggle(v,flag,"strictargs", &(GP_DATA->strictargs)); }
     616             : 
     617             : GEN
     618           0 : sd_string(const char *v, long flag, const char *s, char **pstr)
     619             : {
     620           0 :   char *old = *pstr;
     621           0 :   if (v)
     622             :   {
     623           0 :     char *str, *ev = path_expand(v);
     624           0 :     long l = strlen(ev) + 256;
     625           0 :     str = (char *) pari_malloc(l);
     626           0 :     strftime_expand(ev,str, l-1); pari_free(ev);
     627           0 :     if (GP_DATA->secure)
     628             :     {
     629           0 :       char *msg=pari_sprintf("[secure mode]: About to change %s to '%s'",s,str);
     630           0 :       pari_ask_confirm(msg);
     631           0 :       pari_free(msg);
     632             :     }
     633           0 :     if (old) pari_free(old);
     634           0 :     *pstr = old = pari_strdup(str);
     635           0 :     pari_free(str);
     636             :   }
     637           0 :   else if (!old) old = (char*)"<undefined>";
     638           0 :   if (flag == d_RETURN) return strtoGENstr(old);
     639           0 :   if (flag == d_ACKNOWLEDGE) pari_printf("   %s = \"%s\"\n",s,old);
     640           0 :   return gnil;
     641             : }
     642             : 
     643             : GEN
     644           0 : sd_logfile(const char *v, long flag)
     645             : {
     646           0 :   GEN r = sd_string(v, flag, "logfile", &current_logfile);
     647           0 :   if (v && pari_logfile)
     648             :   {
     649           0 :     FILE *log = open_logfile(current_logfile);
     650           0 :     fclose(pari_logfile); pari_logfile = log;
     651             :   }
     652           0 :   return r;
     653             : }
     654             : 
     655             : GEN
     656           0 : sd_factor_add_primes(const char *v, long flag)
     657           0 : { return sd_toggle(v,flag,"factor_add_primes", &factor_add_primes); }
     658             : 
     659             : GEN
     660           0 : sd_factor_proven(const char *v, long flag)
     661           0 : { return sd_toggle(v,flag,"factor_proven", &factor_proven); }
     662             : 
     663             : GEN
     664          14 : sd_new_galois_format(const char *v, long flag)
     665          14 : { return sd_toggle(v,flag,"new_galois_format", &new_galois_format); }
     666             : 
     667             : GEN
     668          13 : sd_datadir(const char *v, long flag)
     669             : {
     670             :   const char *str;
     671          13 :   if (v)
     672             :   {
     673           0 :     if (pari_datadir) pari_free(pari_datadir);
     674           0 :     pari_datadir = path_expand(v);
     675             :   }
     676          13 :   str = pari_datadir? pari_datadir: "none";
     677          13 :   if (flag == d_RETURN) return strtoGENstr(str);
     678           0 :   if (flag == d_ACKNOWLEDGE)
     679           0 :     pari_printf("   datadir = \"%s\"\n", str);
     680           0 :   return gnil;
     681             : }
     682             : 
     683             : static GEN
     684           0 : sd_PATH(const char *v, long flag, const char* s, gp_path *p)
     685             : {
     686           0 :   if (v)
     687             :   {
     688           0 :     pari_free((void*)p->PATH);
     689           0 :     p->PATH = pari_strdup(v);
     690           0 :     if (flag == d_INITRC) return gnil;
     691           0 :     gp_expand_path(p);
     692             :   }
     693           0 :   if (flag == d_RETURN) return strtoGENstr(p->PATH);
     694           0 :   if (flag == d_ACKNOWLEDGE)
     695           0 :     pari_printf("   %s = \"%s\"\n", s, p->PATH);
     696           0 :   return gnil;
     697             : }
     698             : GEN
     699           0 : sd_path(const char *v, long flag)
     700           0 : { return sd_PATH(v, flag, "path", GP_DATA->path); }
     701             : GEN
     702           0 : sd_sopath(char *v, int flag)
     703           0 : { return sd_PATH(v, flag, "sopath", GP_DATA->sopath); }
     704             : 
     705             : static const char *DFT_PRETTYPRINTER = "tex2mail -TeX -noindent -ragged -by_par";
     706             : GEN
     707           0 : sd_prettyprinter(const char *v, long flag)
     708             : {
     709           0 :   gp_pp *pp = GP_DATA->pp;
     710           0 :   if (v && !(GP_DATA->flags & gpd_TEXMACS))
     711             :   {
     712           0 :     char *old = pp->cmd;
     713           0 :     int cancel = (!strcmp(v,"no"));
     714             : 
     715           0 :     if (GP_DATA->secure)
     716           0 :       pari_err(e_MISC,"[secure mode]: can't modify 'prettyprinter' default (to %s)",v);
     717           0 :     if (!strcmp(v,"yes")) v = DFT_PRETTYPRINTER;
     718           0 :     if (old && strcmp(old,v) && pp->file)
     719             :     {
     720             :       pariFILE *f;
     721           0 :       if (cancel) f = NULL;
     722             :       else
     723             :       {
     724           0 :         f = try_pipe(v, mf_OUT);
     725           0 :         if (!f)
     726             :         {
     727           0 :           pari_warn(warner,"broken prettyprinter: '%s'",v);
     728           0 :           return gnil;
     729             :         }
     730             :       }
     731           0 :       pari_fclose(pp->file);
     732           0 :       pp->file = f;
     733             :     }
     734           0 :     pp->cmd = cancel? NULL: pari_strdup(v);
     735           0 :     if (old) pari_free(old);
     736           0 :     if (flag == d_INITRC) return gnil;
     737             :   }
     738           0 :   if (flag == d_RETURN)
     739           0 :     return strtoGENstr(pp->cmd? pp->cmd: "");
     740           0 :   if (flag == d_ACKNOWLEDGE)
     741           0 :     pari_printf("   prettyprinter = \"%s\"\n",pp->cmd? pp->cmd: "");
     742           0 :   return gnil;
     743             : }
     744             : 
     745             : /* compare entrees s1 s2 according to the attached function name */
     746             : static int
     747           0 : compare_name(const void *s1, const void *s2) {
     748           0 :   entree *e1 = *(entree**)s1, *e2 = *(entree**)s2;
     749           0 :   return strcmp(e1->name, e2->name);
     750             : }
     751             : static void
     752           0 : defaults_list(pari_stack *s)
     753             : {
     754             :   entree *ep;
     755             :   long i;
     756           0 :   for (i = 0; i < functions_tblsz; i++)
     757           0 :     for (ep = defaults_hash[i]; ep; ep = ep->next) pari_stack_pushp(s, ep);
     758           0 : }
     759             : /* ep attached to function f of arity 2. Call f(v,flag) */
     760             : static GEN
     761         880 : call_f2(entree *ep, const char *v, long flag)
     762         880 : { return ((GEN (*)(const char*,long))ep->value)(v, flag); }
     763             : GEN
     764         880 : setdefault(const char *s, const char *v, long flag)
     765             : {
     766             :   entree *ep;
     767         880 :   if (!s)
     768             :   { /* list all defaults */
     769             :     pari_stack st;
     770             :     entree **L;
     771             :     long i;
     772           0 :     pari_stack_init(&st, sizeof(*L), (void**)&L);
     773           0 :     defaults_list(&st);
     774           0 :     qsort (L, st.n, sizeof(*L), compare_name);
     775           0 :     for (i = 0; i < st.n; i++) (void)call_f2(L[i], NULL, d_ACKNOWLEDGE);
     776           0 :     pari_stack_delete(&st);
     777           0 :     return gnil;
     778             :   }
     779         880 :   ep = pari_is_default(s);
     780         880 :   if (!ep)
     781             :   {
     782           0 :     pari_err(e_MISC,"unknown default: %s",s);
     783           0 :     return NULL; /* not reached */
     784             :   }
     785         880 :   return call_f2(ep, v, flag);
     786             : }
     787             : 
     788             : GEN
     789         880 : default0(const char *a, const char *b) { return setdefault(a,b, b? d_SILENT: d_RETURN); }
     790             : 
     791             : /********************************************************************/
     792             : /*                                                                  */
     793             : /*                     INITIALIZE GP_DATA                           */
     794             : /*                                                                  */
     795             : /********************************************************************/
     796             : /* initialize path */
     797             : static void
     798        2656 : init_path(gp_path *path, const char *v)
     799             : {
     800        2656 :   path->PATH = pari_strdup(v);
     801        2656 :   path->dirs = NULL;
     802        2656 : }
     803             : 
     804             : /* initialize D->fmt */
     805             : static void
     806        1328 : init_fmt(gp_data *D)
     807             : {
     808             : #ifdef LONG_IS_64BIT
     809             :   static pariout_t DFLT_OUTPUT = { 'g', 38, 1, f_PRETTYMAT, 0 };
     810             : #else
     811             :   static pariout_t DFLT_OUTPUT = { 'g', 28, 1, f_PRETTYMAT, 0 };
     812             : #endif
     813        1328 :   D->fmt = &DFLT_OUTPUT;
     814        1328 : }
     815             : 
     816             : /* initialize D->pp */
     817             : static void
     818        1328 : init_pp(gp_data *D)
     819             : {
     820        1328 :   gp_pp *p = D->pp;
     821        1328 :   p->cmd = pari_strdup(DFT_PRETTYPRINTER);
     822        1328 :   p->file = NULL;
     823        1328 : }
     824             : 
     825             : static char *
     826        1328 : init_help(void)
     827             : {
     828        1328 :   char *h = os_getenv("GPHELP");
     829             : # ifdef GPHELP
     830        1328 :   if (!h) h = (char*)GPHELP;
     831             : # endif
     832             : #ifdef _WIN32
     833             :   win32_set_pdf_viewer();
     834             : #endif
     835        1328 :   if (h) h = pari_strdup(h);
     836        1328 :   return h;
     837             : }
     838             : 
     839             : static void
     840        1328 : init_graphs(gp_data *D)
     841             : {
     842        1328 :   const char *cols[] = { "",
     843             :     "white","black","blue","violetred","red","green","grey","gainsboro"
     844             :   };
     845        1328 :   const long N = 8;
     846        1328 :   GEN c = cgetalloc(t_VECSMALL, 3), s;
     847             :   long i;
     848        1328 :   c[1] = 4;
     849        1328 :   c[2] = 5;
     850        1328 :   D->graphcolors = c;
     851        1328 :   c = (GEN)pari_malloc((N+1 + 4*N)*sizeof(long));
     852        1328 :   c[0] = evaltyp(t_VEC)|evallg(N+1);
     853       11952 :   for (i = 1, s = c+N+1; i <= N; i++, s += 4)
     854             :   {
     855       10624 :     GEN lp = s;
     856       10624 :     lp[0] = evaltyp(t_STR)|evallg(4);
     857       10624 :     strcpy(GSTR(lp), cols[i]);
     858       10624 :     gel(c,i) = lp;
     859             :   }
     860        1328 :   D->colormap = c;
     861        1328 : }
     862             : 
     863             : gp_data *
     864        1328 : default_gp_data(void)
     865             : {
     866             :   static gp_data __GPDATA, *D = &__GPDATA;
     867             :   static gp_hist __HIST;
     868             :   static gp_pp   __PP;
     869             :   static gp_path __PATH, __SOPATH;
     870             :   static pari_timer __T;
     871             : 
     872        1328 :   D->flags       = 0;
     873        1328 :   D->primelimit  = 500000;
     874             : 
     875             :   /* GP-specific */
     876        1328 :   D->breakloop   = 1;
     877        1328 :   D->echo        = 0;
     878        1328 :   D->lim_lines   = 0;
     879        1328 :   D->linewrap    = 0;
     880        1328 :   D->recover     = 1;
     881        1328 :   D->chrono      = 0;
     882             : 
     883        1328 :   D->strictargs  = 0;
     884        1328 :   D->strictmatch = 1;
     885        1328 :   D->simplify    = 1;
     886        1328 :   D->secure      = 0;
     887        1328 :   D->use_readline= 0;
     888        1328 :   D->T    = &__T;
     889        1328 :   D->hist = &__HIST;
     890        1328 :   D->pp   = &__PP;
     891        1328 :   D->path = &__PATH;
     892        1328 :   D->sopath=&__SOPATH;
     893        1328 :   init_fmt(D);
     894        1328 :   init_hist(D, 5000, 0);
     895        1328 :   init_path(D->path, pari_default_path());
     896        1328 :   init_path(D->sopath, "");
     897        1328 :   init_pp(D);
     898        1328 :   init_graphs(D);
     899        1328 :   D->prompt_comment = (char*)"comment> ";
     900        1328 :   D->prompt = pari_strdup("? ");
     901        1328 :   D->prompt_cont = pari_strdup("");
     902        1328 :   D->help = init_help();
     903        1328 :   D->readline_state = DO_ARGS_COMPLETE;
     904        1328 :   D->histfile = NULL;
     905        1328 :   return D;
     906             : }

Generated by: LCOV version 1.11