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 - gp - gp.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.16.2 lcov report (development 29419-8afb0ed749) Lines: 281 339 82.9 %
Date: 2024-07-02 09:03:41 Functions: 25 29 86.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; either version 2 of the License, or (at your option) any later
       8             : version. It is distributed in the hope that it will be useful, but WITHOUT
       9             : ANY WARRANTY WHATSOEVER.
      10             : 
      11             : Check the License for details. You should have received a copy of it, along
      12             : with the package; see the file 'COPYING'. If not, write to the Free Software
      13             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      14             : 
      15             : /*******************************************************************/
      16             : /**                                                               **/
      17             : /**                        PARI CALCULATOR                        **/
      18             : /**                                                               **/
      19             : /*******************************************************************/
      20             : #ifdef _WIN32
      21             : #  include "../systems/mingw/pwinver.h"
      22             : #  include <windows.h>
      23             : #  include "../systems/mingw/mingw.h"
      24             : #endif
      25             : #ifdef DEBUG_FLOATS
      26             : #  undef  _GNU_SOURCE
      27             : #  define _GNU_SOURCE
      28             : #  include <fenv.h>
      29             : #endif
      30             : #include "pari.h"
      31             : #include "paripriv.h"
      32             : #include "gp.h"
      33             : 
      34             : static jmp_buf *env;
      35             : static pari_stack s_env;
      36             : void (*cb_pari_end_output)(void) = NULL;
      37             : 
      38             : static void
      39           0 : gp_ask_confirm(const char *s)
      40             : {
      41           0 :   err_printf(s);
      42           0 :   err_printf(". OK ? (^C if not)\n");
      43           0 :   pari_hit_return();
      44           0 : }
      45             : 
      46             : /* numerr < 0: after changing PARI stack size
      47             :  * numerr > 0: normal error, including SIGINT */
      48             : static void
      49       12731 : gp_err_recover(long numerr)
      50             : {
      51       12731 :   longjmp(env[s_env.n-1], numerr);
      52             : }
      53             : 
      54             : /* numerr >= 0 */
      55             : static void
      56       12279 : gp_pre_recover(long numerr)
      57             : {
      58       12279 :   out_puts(pariErr, "\n"); pariErr->flush();
      59       12279 :   gp_err_recover(numerr);
      60           0 : }
      61             : 
      62             : static void
      63      134397 : reset_ctrlc(void)
      64             : {
      65             : #if defined(_WIN32) || defined(__CYGWIN32__)
      66             :   win32ctrlc = 0;
      67             : #endif
      68      134397 : }
      69             : 
      70             : static int
      71       86445 : is_silent(char *s) { return s[strlen(s) - 1] == ';'; }
      72             : 
      73             : static int stdin_isatty = 0;
      74             : static int
      75        1954 : is_interactive(void)
      76        1954 : { return pari_infile == stdin && stdin_isatty; }
      77             : 
      78             : /*******************************************************************/
      79             : /**                                                               **/
      80             : /**                        INITIALIZATION                         **/
      81             : /**                                                               **/
      82             : /*******************************************************************/
      83             : static void
      84           2 : print_shortversion(void)
      85             : {
      86           2 :   const ulong mask = (1UL<<PARI_VERSION_SHIFT) - 1;
      87           2 :   ulong n = paricfg_version_code, major, minor, patch;
      88             : 
      89           2 :   patch = n & mask; n >>= PARI_VERSION_SHIFT;
      90           2 :   minor = n & mask; n >>= PARI_VERSION_SHIFT;
      91           2 :   major = n;
      92           2 :   printf("%lu.%lu.%lu\n", major,minor,patch); exit(0);
      93             : }
      94             : 
      95             : static void
      96           2 : usage(char *s)
      97             : {
      98           2 :   printf("### Usage: %s [options] [GP files]\n", s);
      99           2 :   printf("Available options:\n");
     100           2 :   printf("  [-f,--fast]\t\tFast start: do not read .gprc\n");
     101           2 :   printf("  [-q,--quiet]\t\tQuiet mode: do not print banner and history numbers\n");
     102           2 :   printf("  [-s stacksize]\tStart with the PARI stack of given size (in bytes)\n");
     103           2 :   printf("  [--default key=val]\tExecute default(key,val) on startup\n");
     104           2 :   printf("  [--emacs]\t\tRun as if in Emacs shell\n");
     105           2 :   printf("  [--help]\t\tPrint this message\n");
     106           2 :   printf("  [--test]\t\tTest mode. No history, wrap long lines (bench only)\n");
     107           2 :   printf("  [--texmacs]\t\tRun as if using TeXmacs frontend\n");
     108           2 :   printf("  [--version]\t\tOutput version info and exit\n");
     109           2 :   printf("  [--version-short]\tOutput version number and exit\n\n");
     110           2 :   exit(0);
     111             : }
     112             : 
     113             : static void
     114           2 : gp_head(void)
     115             : {
     116             :   ulong p, f;
     117           2 :   pari_print_version();
     118           2 :   pari_putc('\n');
     119           2 :   pari_center("Copyright (C) 2000-2024 The PARI Group");
     120           2 :   pari_putc('\n');
     121           2 :   print_text("PARI/GP is free software, covered by the GNU General Public \
     122             : License, and comes WITHOUT ANY WARRANTY WHATSOEVER.");
     123           2 :   pari_puts("\nType ? for help, \\q to quit.\n");
     124           2 :   pari_printf("Type ?%d for how to get moral"
     125             :               " (and possibly technical) support.\n", pari_community());
     126           2 :   p = GP_DATA->primelimit;
     127           2 :   f = GP_DATA->factorlimit;
     128           2 :   if (pari_mainstack->vsize)
     129           0 :     pari_printf("\nparisizemax = %lu, primelimit = %lu, factorlimit = %lu",
     130           0 :                 pari_mainstack->vsize, p, f);
     131             :   else
     132           2 :     pari_printf("\nparisize = %lu, primelimit = %lu, factorlimit = %lu",
     133           2 :                 pari_mainstack->rsize, p, f);
     134           2 :   pari_putc('\n');
     135           2 : }
     136             : 
     137             : static char *
     138           0 : read_arg(long *nread, char *t, long argc, char **argv)
     139             : {
     140           0 :   long i = *nread;
     141           0 :   if (isdigit((unsigned char)*t)) return t;
     142           0 :   if (*t || i==argc) usage(argv[0]);
     143           0 :   *nread = i+1; return argv[i];
     144             : }
     145             : 
     146             : static char *
     147           0 : read_arg_equal(long *nread, char *t, long argc, char **argv)
     148             : {
     149           0 :   long i = *nread;
     150           0 :   if (*t=='=' && isdigit((unsigned char)t[1])) return t+1;
     151           0 :   if (*t || i==argc) usage(argv[0]);
     152           0 :   *nread = i+1; return argv[i];
     153             : }
     154             : 
     155             : static void
     156           4 : init_trivial_stack(void)
     157             : {
     158           4 :   const size_t s = 2048;
     159           4 :   pari_mainstack->size = s;
     160           4 :   pari_mainstack->bot = (pari_sp)pari_malloc(s);
     161           4 :   avma = pari_mainstack->top = pari_mainstack->bot + s;
     162           4 : }
     163             : 
     164             : static void
     165           4 : free_trivial_stack(void)
     166             : {
     167           4 :   free((void*)pari_mainstack->bot);
     168           4 : }
     169             : 
     170             : typedef struct { char *key, *val; } pair_t;
     171             : /* If ab of the form key=val, record pair in new stack entry
     172             :  * P[n].key must be freed by caller to avoid memory leak */
     173             : static void
     174           6 : record_default(pari_stack *s_P, char *ab)
     175             : {
     176           6 :   pair_t *P = (pair_t*)*pari_stack_base(s_P);
     177             :   char *k, *v;
     178             :   long n;
     179           6 :   ab = pari_strdup(ab);
     180           6 :   parse_key_val(ab, &k, &v);
     181           6 :   n = pari_stack_new(s_P);
     182           6 :   P[n].key = k;
     183           6 :   P[n].val = v;
     184           6 : }
     185             : static void
     186        1851 : read_opt(pari_stack *p_A, long argc, char **argv)
     187             : {
     188             :   pair_t *P;
     189             :   pari_stack s_P; /* key / value to record default() settings */
     190        1851 :   char *b = NULL, *p = NULL, *s = NULL;
     191        1851 :   ulong f = GP_DATA->flags;
     192        1851 :   long i = 1, initrc = 1;
     193             : 
     194             :   (void)&p; (void)&b; (void)&s; /* -Wall gcc-2.95 */
     195             : 
     196        1851 :   pari_stack_init(&s_P,sizeof(*P),(void**)&P);
     197        1851 :   pari_stack_alloc(&s_P, 64);
     198        1851 :   pari_outfile = stderr;
     199        5535 :   while (i < argc)
     200             :   {
     201        3692 :     char *t = argv[i];
     202             : 
     203        3692 :     if (*t++ != '-') break;
     204        3692 :     i++;
     205        3692 : START:
     206        3692 :     switch(*t++)
     207             :     {
     208           0 :       case 'p': p = read_arg(&i,t,argc,argv); break;
     209           0 :       case 's': s = read_arg(&i,t,argc,argv); break;
     210           0 :       case 'e':
     211           0 :         f |= gpd_EMACS; if (*t) goto START;
     212           0 :         break;
     213        1837 :       case 'q':
     214        1837 :         f |= gpd_QUIET; if (*t) goto START;
     215        1837 :         break;
     216           0 :       case 't':
     217           0 :         f |= gpd_TEST; if (*t) goto START;
     218           0 :         break;
     219          33 :       case 'f':
     220          33 :         initrc = 0; if (*t) goto START;
     221          33 :         break;
     222           4 :       case 'D':
     223           4 :         if (*t || i == argc) usage(argv[0]);
     224           4 :         record_default(&s_P, argv[i++]);
     225           4 :         break;
     226        1818 :       case '-':
     227        1818 :         if (strcmp(t, "version-short") == 0) { print_shortversion(); exit(0); }
     228        1816 :         if (strcmp(t, "version") == 0) {
     229           4 :           init_trivial_stack(); pari_print_version();
     230           4 :           free_trivial_stack(); exit(0);
     231             :         }
     232        1812 :         if (strcmp(t, "default") == 0) {
     233           2 :           if (i == argc) usage(argv[0]);
     234           2 :           record_default(&s_P, argv[i++]);
     235           2 :           break;
     236             :         }
     237        1810 :         if (strcmp(t, "texmacs") == 0) { f |= gpd_TEXMACS; break; }
     238        1810 :         if (strcmp(t, "emacs") == 0) { f |= gpd_EMACS; break; }
     239        1810 :         if (strcmp(t, "test") == 0) { f |= gpd_TEST; initrc = 0; break; }
     240           6 :         if (strcmp(t, "quiet") == 0) { f |= gpd_QUIET; break; }
     241           4 :         if (strcmp(t, "fast") == 0) { initrc = 0; break; }
     242           2 :         if (strncmp(t, "primelimit",10) == 0) {p = read_arg_equal(&i,t+10,argc,argv); break; }
     243           2 :         if (strncmp(t, "stacksize",9) == 0) {s = read_arg_equal(&i,t+9,argc,argv); break; }
     244             :        /* fall through */
     245             :       default:
     246           2 :         usage(argv[0]);
     247             :     }
     248             :   }
     249        1843 :   if (f & gpd_TEST) stdin_isatty = 0;
     250        1843 :   GP_DATA->flags = f;
     251             : #ifdef READLINE
     252        1843 :   GP_DATA->use_readline = stdin_isatty;
     253             : #endif
     254        1843 :   if (!is_interactive()) GP_DATA->breakloop = 0;
     255        1843 :   if (initrc) gp_initrc(p_A);
     256        1843 :   for ( ; i < argc; i++) pari_stack_pushp(p_A, pari_strdup(argv[i]));
     257             : 
     258             :   /* override the values from gprc */
     259        1843 :   if (p) (void)sd_primelimit(p, d_INITRC);
     260        1843 :   if (s) (void)sd_parisize(s, d_INITRC);
     261        1847 :   for (i = 0; i < s_P.n; i++) {
     262           6 :     setdefault(P[i].key, P[i].val, d_INITRC);
     263           4 :     free((void*)P[i].key);
     264             :   }
     265        1841 :   pari_stack_delete(&s_P);
     266        1841 :   pari_outfile = stdout;
     267        1841 : }
     268             : 
     269             : /*******************************************************************/
     270             : /**                                                               **/
     271             : /**                            TEST MODE                          **/
     272             : /**                                                               **/
     273             : /*******************************************************************/
     274             : static int
     275      250414 : test_is_interactive(void) { return 0; }
     276             : 
     277             : static void
     278       58353 : test_output(long n) { init_linewrap(76); gen_output(pari_get_hist(n)); }
     279             : void
     280        1804 : init_test(void)
     281             : {
     282        1804 :   disable_color = 1;
     283        1804 :   init_linewrap(76);
     284        1804 :   pari_errfile = stdout;
     285        1804 :   cb_pari_display_hist = test_output;
     286        1804 :   cb_pari_is_interactive = test_is_interactive;
     287        1804 : }
     288             : 
     289             : static GEN
     290        1841 : gp_main_loop(long ismain)
     291             : {
     292        1841 :   VOLATILE GEN z = gnil;
     293        1841 :   VOLATILE long t = 0, r = 0;
     294        1841 :   VOLATILE pari_sp av = avma;
     295             :   filtre_t F;
     296        1841 :   Buffer *b = filtered_buffer(&F);
     297             :   struct gp_context rec;
     298             :   long er;
     299        1841 :   if ((er = setjmp(env[s_env.n-1])))
     300             :   { /* recover: jump from error [ > 0 ] or allocatemem [ -1 ] */
     301       12701 :     if (er > 0) { /* true error */
     302       12270 :       if (!(GP_DATA->recover)) exit(1);
     303       12270 :       gp_context_restore(&rec);
     304             :       /* true error not from main instance, let caller sort it out */
     305       12270 :       if (!ismain) { kill_buffers_upto_including(b); return NULL; }
     306             :     } else { /* allocatemem */
     307         431 :       tmp_restore(rec.file.file);
     308         431 :       gp_context_save(&rec);
     309             :     }
     310       12701 :     set_avma(av = pari_mainstack->top);
     311       12701 :     parivstack_reset();
     312       12701 :     kill_buffers_upto(b);
     313       12701 :     pari_alarm(0);
     314             :   }
     315             :   for(;;)
     316             :   {
     317      136063 :     gp_context_save(&rec);
     318      136063 :     if (! gp_read_line(&F, NULL))
     319             :     {
     320        1841 :       if (popinfile()) gp_quit(0);
     321           0 :       if (ismain) continue;
     322           0 :       pop_buffer(); return z;
     323             :     }
     324      134222 :     if (ismain)
     325             :     {
     326      134222 :       reset_ctrlc();
     327      134222 :       timer_start(GP_DATA->T);
     328      134222 :       walltimer_start(GP_DATA->Tw);
     329      134222 :       pari_set_last_newline(1);
     330             :     }
     331      134222 :     if (gp_meta(b->buf,ismain)) continue;
     332      113473 :     z = pari_compile_str(b->buf);
     333      113396 :     z = closure_evalres(z);
     334      100793 :     if (!ismain) continue;
     335             : 
     336      100793 :     t = timer_delay(GP_DATA->T);
     337      100793 :     r = walltimer_delay(GP_DATA->Tw);
     338      100793 :     if (!pari_last_was_newline()) pari_putc('\n');
     339      100793 :     pari_alarm(0);
     340      100793 :     if (t && GP_DATA->chrono)
     341             :     {
     342           0 :       if (pari_mt_nbthreads==1)
     343             :       {
     344           0 :         pari_puts("time = ");
     345           0 :         pari_puts(gp_format_time(t));
     346             :       }
     347             :       else
     348             :       {
     349           0 :         pari_puts("cpu time = ");
     350           0 :         pari_puts(gp_format_time(t));
     351           0 :         pari_puts(", real time = ");
     352           0 :         pari_puts(gp_format_time(r));
     353             :       }
     354           0 :       pari_puts(".\n");
     355             :     }
     356      100793 :     if (GP_DATA->simplify) z = simplify_shallow(z);
     357      100793 :     pari_add_hist(z, t, r);
     358      100793 :     if (z != gnil && ! is_silent(b->buf) )
     359       58357 :       gp_display_hist(GP_DATA->hist->total);
     360      100793 :     set_avma(av);
     361      100793 :     parivstack_reset();
     362             :   }
     363             : }
     364             : 
     365             : /* as gp_read_file, before running the main gp instance */
     366             : static void
     367           0 : read_main(const char *s)
     368             : {
     369             :   GEN z;
     370           0 :   if (setjmp(env[s_env.n-1]))
     371           0 :     z = NULL;
     372             :   else {
     373           0 :     FILE *f = switchin(s);
     374           0 :     if (file_is_binary(f)) {
     375           0 :       z = readbin(s,f, NULL);
     376           0 :       popinfile();
     377             :     }
     378           0 :     else z = gp_main_loop(0);
     379             :   }
     380           0 :   if (!z) err_printf("... skipping file '%s'\n", s);
     381           0 :   set_avma(pari_mainstack->top);
     382           0 : }
     383             : 
     384             : static const char *
     385         126 : break_loop_prompt(long n)
     386             : {
     387         126 :   return n==0 ? "GP prompt" : n==1? "break> ": stack_sprintf("break[%ld]> ", n);
     388             : }
     389             : 
     390             : static long frame_level=0, dbg_level = 0;
     391             : 
     392             : static int
     393          63 : break_loop(int numerr)
     394             : {
     395             :   filtre_t F;
     396             :   Buffer *b;
     397          63 :   int sigint = numerr<0, go_on = sigint;
     398             :   struct gp_context rec1, rec2;
     399             :   const char *prompt, *msg;
     400          63 :   long nenv, oldframe_level = frame_level;
     401             :   pari_sp av;
     402             : 
     403          63 :   if (numerr == e_SYNTAX) return 0;
     404          63 :   if (numerr == e_STACK) { evalstate_clone(); set_avma(pari_mainstack->top); }
     405          63 :   gp_context_save(&rec1);
     406             : 
     407          63 :   b = filtered_buffer(&F);
     408          63 :   nenv=pari_stack_new(&s_env);
     409          63 :   prompt = gp_format_prompt(break_loop_prompt(nenv));
     410          63 :   iferr_env = NULL;
     411          63 :   dbg_level = 0;
     412          63 :   frame_level = closure_context(oldframe_level, dbg_level);
     413          63 :   pari_infile = newfile(stdin, "stdin", mf_IN)->file;
     414          63 :   term_color(c_ERR); pari_putc('\n');
     415          63 :   if (sigint)
     416           7 :     msg = "Break loop: <Return> to continue; 'break' to go back to %s";
     417             :   else
     418          56 :     msg = "Break loop: type 'break' to go back to %s";
     419          63 :   msg = stack_sprintf(msg, break_loop_prompt(nenv-1));
     420          63 :   print_errcontext(pariOut, msg, NULL, NULL);
     421          63 :   term_color(c_NONE);
     422          63 :   av = avma;
     423             :   for(;;)
     424          91 :   {
     425             :     GEN x;
     426             :     long er, br_status;
     427         154 :     set_avma(av);
     428         154 :     gp_context_save(&rec2);
     429         154 :     if ((er=setjmp(env[nenv])))
     430             :     {
     431          35 :       if (er < 0)
     432             :       {
     433           7 :         s_env.n = 1;
     434           7 :         frame_level = oldframe_level;
     435           7 :         longjmp(env[s_env.n-1], er);
     436             :       }
     437          28 :       gp_context_restore(&rec2);
     438          28 :       iferr_env = NULL;
     439          28 :       closure_err(dbg_level);
     440          28 :       compilestate_restore(&rec1.eval.comp);
     441          28 :       (void) closure_context(oldframe_level, dbg_level);
     442          28 :       pari_infile = newfile(stdin, "stdin", mf_IN)->file;
     443             :     }
     444         182 :     term_color(c_NONE);
     445         182 :     if (!gp_read_line(&F, prompt))
     446           0 :       br_status = br_BREAK; /* EOF */
     447             :     else
     448             :     {
     449             :       /* Empty input ? Continue if entry on sigint (exit debugger frame) */
     450         182 :       if (! *(b->buf) && sigint) break;
     451         175 :       reset_ctrlc();
     452         175 :       if (gp_meta(b->buf,0)) continue;
     453         175 :       x = pari_compile_str(b->buf);
     454         175 :       x = closure_evalbrk(x, &br_status);
     455             :     }
     456         140 :     switch (br_status)
     457             :     {
     458           0 :       case br_NEXT: case br_MULTINEXT:
     459           0 :         popinfile(); /* exit frame. Don't exit debugger if s_env.n > 2 */
     460          49 :         go_on = 0; goto BR_EXIT;
     461          49 :       case br_BREAK: case br_RETURN:
     462          49 :         killallfiles(); /* completely exit the debugger */
     463          49 :         go_on = 0; goto BR_EXIT;
     464             :     }
     465          91 :     if (x!=gnil && !is_silent(b->buf)) { term_color(c_OUTPUT); gen_output(x); }
     466             :   }
     467          56 : BR_EXIT:
     468          56 :   s_env.n=nenv;
     469          56 :   frame_level = oldframe_level;
     470          56 :   gp_context_restore(&rec1);
     471          56 :   pop_buffer(); return go_on;
     472             : }
     473             : 
     474             : #ifdef __CYGWIN32__
     475             : void
     476             : cyg_environment(int argc, char ** argv)
     477             : {
     478             :   char *ti_dirs = getenv("TERMINFO_DIRS");
     479             :   char *argv0, *p;
     480             :   char *newdir;
     481             :   long n;
     482             : 
     483             :   if (!argc || !argv) return;
     484             :   argv0 = *argv;
     485             :   if (!argv0 || !*argv0) return;
     486             :   p = strrchr(argv0, '/');
     487             :   if (!p)
     488             :     p = argv0 = "";
     489             :   else
     490             :     p++;
     491             :   n = p - argv0;
     492             :   if (ti_dirs)
     493             :   {
     494             :     n += 14 + strlen(ti_dirs) + 1 + 8 + 1;
     495             :     newdir = malloc(n);
     496             :     if (!newdir) return;
     497             :     snprintf(newdir, n-8, "TERMINFO_DIRS=%s:%s", ti_dirs, argv0);
     498             :   }
     499             :   else
     500             :   {
     501             :     n += 14 + 8 + 1;
     502             :     newdir = malloc(n);
     503             :     if (!newdir) return;
     504             :     snprintf(newdir, n-8, "TERMINFO_DIRS=%s", argv0);
     505             :   }
     506             :   strcpy(newdir+n-9,"terminfo");
     507             :   putenv(newdir);
     508             : }
     509             : #endif
     510             : 
     511             : int
     512        1851 : main(int argc, char **argv)
     513             : {
     514             :   char **A;
     515             :   pari_stack s_A;
     516             : 
     517        1851 :   GP_DATA = default_gp_data();
     518        1851 :   pari_stack_init(&s_env, sizeof(*env), (void**)&env);
     519        1851 :   (void)pari_stack_new(&s_env);
     520             : 
     521        1851 :   if (setjmp(env[s_env.n-1]))
     522             :   {
     523           2 :     puts("### Errors on startup, exiting...\n\n");
     524           2 :     exit(1);
     525             :   }
     526             : #ifdef DEBUG_FLOATS
     527             :   feenableexcept(FE_INVALID);
     528             : #endif
     529             : #ifdef __CYGWIN32__
     530             :   cyg_environment(argc, argv);
     531             : #endif
     532        1851 :   stdin_isatty = pari_stdin_isatty();
     533        1851 :   pari_init_defaults();
     534        1851 :   pari_library_path = DL_DFLT_NAME;
     535        1851 :   pari_stack_init(&s_A,sizeof(*A),(void**)&A);
     536             :   /* must be defined here in case an error is raised in pari_init_opts, e.g.
     537             :    * when parsing function prototypes */
     538        1851 :   cb_pari_err_recover = gp_err_recover;
     539        1851 :   pari_init_opts(8000000, 0, INIT_SIGm | INIT_noPRIMEm | INIT_noIMTm);
     540        1851 :   cb_pari_pre_recover = gp_pre_recover;
     541        1851 :   cb_pari_break_loop = break_loop;
     542        1851 :   cb_pari_is_interactive = is_interactive;
     543             : 
     544        1851 :   read_opt(&s_A, argc,argv);
     545        1841 :   pari_init_primes(GP_DATA->primelimit);
     546             : #ifdef SIGALRM
     547        1841 :   (void)os_signal(SIGALRM,gp_alarm_handler);
     548             : #endif
     549        1841 :   pari_add_module(functions_gp);
     550             : 
     551        1841 :   pari_set_plot_engine(gp_get_plot);
     552        1841 :   cb_pari_quit = gp_quit;
     553        1841 :   cb_pari_whatnow = whatnow;
     554        1841 :   cb_pari_sigint = gp_sigint_fun;
     555        1841 :   cb_pari_handle_exception = gp_handle_exception;
     556        1841 :   cb_pari_ask_confirm = gp_ask_confirm;
     557        1841 :   pari_init_paths();
     558        1841 :   pari_mt_init(); /* MPI: will not return on slaves (pari_MPI_rank = 0) */
     559             : #ifdef _WIN32
     560             :   if (stdin_isatty) win32_set_codepage();
     561             : #endif
     562             : #ifdef READLINE
     563        1841 :   init_readline();
     564             : #endif
     565        1841 :   if (GP_DATA->flags & gpd_EMACS) init_emacs();
     566        1841 :   if (GP_DATA->flags & gpd_TEXMACS) init_texmacs();
     567             : 
     568        1841 :   timer_start(GP_DATA->T);
     569        1841 :   walltimer_start(GP_DATA->Tw);
     570        1841 :   if (!(GP_DATA->flags & gpd_QUIET)) gp_head();
     571        1841 :   if (GP_DATA->flags & gpd_TEST) init_test();
     572        1841 :   if (s_A.n)
     573             :   {
     574           0 :     FILE *l = pari_logfile;
     575             :     long i;
     576           0 :     pari_logfile = NULL;
     577           0 :     for (i = 0; i < s_A.n; pari_free(A[i]),i++) read_main(A[i]);
     578             :     /* Reading one of the input files above can set pari_logfile.
     579             :      * Don't restore in that case. */
     580           0 :     if (!pari_logfile) pari_logfile = l;
     581             :   }
     582        1841 :   pari_stack_delete(&s_A);
     583        1841 :   (void)gp_main_loop(1);
     584           0 :   gp_quit(0);
     585             :   return 0; /* LCOV_EXCL_LINE */
     586             : }
     587             : 
     588             : void
     589           7 : pari_breakpoint(void)
     590             : {
     591           7 :   if (!pari_last_was_newline()) pari_putc('\n');
     592           7 :   closure_err(0);
     593           7 :   if (cb_pari_break_loop && cb_pari_break_loop(-1)) return;
     594           0 :   cb_pari_err_recover(e_MISC);
     595             : }
     596             : 
     597             : void
     598           7 : dbg_down(long k)
     599             : {
     600           7 :   if (k<0) k=0;
     601           7 :   dbg_level -= k;
     602           7 :   if (dbg_level<0) dbg_level=0;
     603           7 :   gp_err_recover(e_NONE);
     604           0 : }
     605             : 
     606             : GEN
     607           7 : dbg_err(void) { GEN E = pari_err_last(); return E? gcopy(E):gnil; }
     608             : 
     609             : void
     610          14 : dbg_up(long k)
     611             : {
     612          14 :   if (k<0) k=0;
     613          14 :   dbg_level += k;
     614          14 :   if (dbg_level>frame_level) dbg_level=frame_level;
     615          14 :   gp_err_recover(e_NONE);
     616           0 : }
     617             : 
     618             : void
     619        1841 : gp_quit(long code)
     620             : {
     621        1841 :   pari_kill_plot_engine();
     622        1841 :   pari_close();
     623        1841 :   kill_buffers_upto(NULL);
     624        1841 :   if (!(GP_DATA->flags & gpd_QUIET)) pari_puts("Goodbye!\n");
     625        1841 :   if (cb_pari_end_output) cb_pari_end_output();
     626        1841 :   exit(code);
     627             : }
     628             : 
     629             : void
     630          35 : whatnow0(char *s) { whatnow(pariOut, s,0); }
     631             : 
     632             : #include "gp_init.h"

Generated by: LCOV version 1.16