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

Generated by: LCOV version 1.11