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_gp_output)(GEN z) = NULL;
37 : void (*cb_pari_end_output)(void) = NULL;
38 :
39 : static void
40 0 : gp_ask_confirm(const char *s)
41 : {
42 0 : err_printf(s);
43 0 : err_printf(". OK ? (^C if not)\n");
44 0 : pari_hit_return();
45 0 : }
46 :
47 : /* numerr < 0: after changing PARI stack size
48 : * numerr > 0: normal error, including SIGINT */
49 : static void
50 12542 : gp_err_recover(long numerr)
51 : {
52 12542 : longjmp(env[s_env.n-1], numerr);
53 : }
54 :
55 : /* numerr >= 0 */
56 : static void
57 12111 : gp_pre_recover(long numerr)
58 : {
59 12111 : out_puts(pariErr, "\n"); pariErr->flush();
60 12111 : gp_err_recover(numerr);
61 0 : }
62 :
63 : static void
64 132143 : reset_ctrlc(void)
65 : {
66 : #if defined(_WIN32) || defined(__CYGWIN32__)
67 : win32ctrlc = 0;
68 : #endif
69 132143 : }
70 :
71 : static int
72 85003 : is_silent(char *s) { return s[strlen(s) - 1] == ';'; }
73 :
74 : static int stdin_isatty = 0;
75 : static int
76 1919 : is_interactive(void)
77 1919 : { return pari_infile == stdin && stdin_isatty; }
78 :
79 : /*******************************************************************/
80 : /** **/
81 : /** INITIALIZATION **/
82 : /** **/
83 : /*******************************************************************/
84 : static void
85 2 : print_shortversion(void)
86 : {
87 2 : const ulong mask = (1UL<<PARI_VERSION_SHIFT) - 1;
88 2 : ulong n = paricfg_version_code, major, minor, patch;
89 :
90 2 : patch = n & mask; n >>= PARI_VERSION_SHIFT;
91 2 : minor = n & mask; n >>= PARI_VERSION_SHIFT;
92 2 : major = n;
93 2 : printf("%lu.%lu.%lu\n", major,minor,patch); exit(0);
94 : }
95 :
96 : static void
97 2 : usage(char *s)
98 : {
99 2 : printf("### Usage: %s [options] [GP files]\n", s);
100 2 : printf("Available options:\n");
101 2 : printf(" [-f,--fast]\t\tFast start: do not read .gprc\n");
102 2 : printf(" [-q,--quiet]\t\tQuiet mode: do not print banner and history numbers\n");
103 2 : printf(" [-s stacksize]\tStart with the PARI stack of given size (in bytes)\n");
104 2 : printf(" [--default key=val]\tExecute default(key,val) on startup\n");
105 2 : printf(" [--emacs]\t\tRun as if in Emacs shell\n");
106 2 : printf(" [--help]\t\tPrint this message\n");
107 2 : printf(" [--test]\t\tTest mode. No history, wrap long lines (bench only)\n");
108 2 : printf(" [--texmacs]\t\tRun as if using TeXmacs frontend\n");
109 2 : printf(" [--version]\t\tOutput version info and exit\n");
110 2 : printf(" [--version-short]\tOutput version number and exit\n\n");
111 2 : exit(0);
112 : }
113 :
114 : static void
115 2 : gp_head(void)
116 : {
117 2 : pari_print_version();
118 2 : pari_putc('\n');
119 2 : pari_center("Copyright (C) 2000-2023 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 : if (pari_mainstack->vsize)
127 0 : pari_printf("\nparisizemax = %lu, primelimit = %lu",
128 0 : pari_mainstack->vsize,GP_DATA->primelimit);
129 : else
130 2 : pari_printf("\nparisize = %lu, primelimit = %lu",
131 2 : pari_mainstack->rsize,GP_DATA->primelimit);
132 2 : if (pari_mt_nbthreads > 1)
133 0 : pari_printf(", nbthreads = %lu", pari_mt_nbthreads);
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 1816 : 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 1816 : char *b = NULL, *p = NULL, *s = NULL;
191 1816 : ulong f = GP_DATA->flags;
192 1816 : long i = 1, initrc = 1;
193 :
194 : (void)&p; (void)&b; (void)&s; /* -Wall gcc-2.95 */
195 :
196 1816 : pari_stack_init(&s_P,sizeof(*P),(void**)&P);
197 1816 : pari_stack_alloc(&s_P, 64);
198 1816 : pari_outfile = stderr;
199 5430 : while (i < argc)
200 : {
201 3622 : char *t = argv[i];
202 :
203 3622 : if (*t++ != '-') break;
204 3622 : i++;
205 3622 : START:
206 3622 : 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 1802 : case 'q':
214 1802 : f |= gpd_QUIET; if (*t) goto START;
215 1802 : 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 1783 : case '-':
227 1783 : if (strcmp(t, "version-short") == 0) { print_shortversion(); exit(0); }
228 1781 : if (strcmp(t, "version") == 0) {
229 4 : init_trivial_stack(); pari_print_version();
230 4 : free_trivial_stack(); exit(0);
231 : }
232 1777 : 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 1775 : if (strcmp(t, "texmacs") == 0) { f |= gpd_TEXMACS; break; }
238 1775 : if (strcmp(t, "emacs") == 0) { f |= gpd_EMACS; break; }
239 1775 : 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 1808 : if (f & gpd_TEST) stdin_isatty = 0;
250 1808 : GP_DATA->flags = f;
251 : #ifdef READLINE
252 1808 : GP_DATA->use_readline = stdin_isatty;
253 : #endif
254 1808 : if (!is_interactive()) GP_DATA->breakloop = 0;
255 1808 : if (initrc) gp_initrc(p_A);
256 1808 : for ( ; i < argc; i++) pari_stack_pushp(p_A, pari_strdup(argv[i]));
257 :
258 : /* override the values from gprc */
259 1808 : if (p) (void)sd_primelimit(p, d_INITRC);
260 1808 : if (s) (void)sd_parisize(s, d_INITRC);
261 1812 : 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 1806 : pari_stack_delete(&s_P);
266 1806 : pari_outfile = stdout;
267 1806 : }
268 :
269 : /*******************************************************************/
270 : /** **/
271 : /** TEST MODE **/
272 : /** **/
273 : /*******************************************************************/
274 : static int
275 246361 : test_is_interactive(void) { return 0; }
276 :
277 : static void
278 57408 : test_output(GEN z) { init_linewrap(76); gen_output(z); }
279 : void
280 1769 : init_test(void)
281 : {
282 1769 : disable_color = 1;
283 1769 : init_linewrap(76);
284 1769 : pari_errfile = stdout;
285 1769 : cb_gp_output = test_output;
286 1769 : cb_pari_is_interactive = test_is_interactive;
287 1769 : }
288 :
289 : /*******************************************************************/
290 : /** **/
291 : /** FORMAT GP OUTPUT **/
292 : /** **/
293 : /*******************************************************************/
294 : /* REGULAR */
295 : static void
296 4 : normal_output(GEN z, long n)
297 : {
298 4 : long l = 0;
299 : char *s;
300 : /* history number */
301 4 : if (n)
302 : {
303 : char buf[64];
304 4 : if (!(GP_DATA->flags & gpd_QUIET))
305 : {
306 2 : term_color(c_HIST);
307 2 : sprintf(buf, "%%%ld = ", n);
308 2 : pari_puts(buf);
309 2 : l = strlen(buf);
310 : }
311 : }
312 : /* output */
313 4 : term_color(c_OUTPUT);
314 4 : s = GENtostr(z);
315 4 : if (GP_DATA->lim_lines)
316 2 : lim_lines_output(s, l, GP_DATA->lim_lines);
317 : else
318 2 : pari_puts(s);
319 4 : pari_free(s);
320 4 : term_color(c_NONE); pari_putc('\n');
321 4 : }
322 :
323 : static void
324 57412 : gp_output(GEN z)
325 : {
326 57412 : if (cb_gp_output) { cb_gp_output(z); return; }
327 4 : if (GP_DATA->fmt->prettyp == f_PRETTY)
328 0 : { if (tex2mail_output(z, GP_DATA->hist->total)) return; }
329 4 : normal_output(z, GP_DATA->hist->total);
330 4 : pari_flush();
331 : }
332 :
333 : static GEN
334 1806 : gp_main_loop(long ismain)
335 : {
336 1806 : VOLATILE GEN z = gnil;
337 1806 : VOLATILE long t = 0, r = 0;
338 1806 : VOLATILE pari_sp av = avma;
339 : filtre_t F;
340 1806 : Buffer *b = filtered_buffer(&F);
341 : struct gp_context rec;
342 : long er;
343 1806 : if ((er = setjmp(env[s_env.n-1])))
344 : { /* recover: jump from error [ > 0 ] or allocatemem [ -1 ] */
345 12512 : if (er > 0) { /* true error */
346 12102 : if (!(GP_DATA->recover)) exit(1);
347 12102 : gp_context_restore(&rec);
348 : /* true error not from main instance, let caller sort it out */
349 12102 : if (!ismain) { kill_buffers_upto_including(b); return NULL; }
350 : } else { /* allocatemem */
351 410 : tmp_restore(rec.file.file);
352 410 : gp_context_save(&rec);
353 : }
354 12512 : set_avma(av = pari_mainstack->top);
355 12512 : parivstack_reset();
356 12512 : kill_buffers_upto(b);
357 12512 : pari_alarm(0);
358 : }
359 : for(;;)
360 : {
361 133774 : gp_context_save(&rec);
362 133774 : if (! gp_read_line(&F, NULL))
363 : {
364 1806 : if (popinfile()) gp_quit(0);
365 0 : if (ismain) continue;
366 0 : pop_buffer(); return z;
367 : }
368 131968 : if (ismain)
369 : {
370 131968 : reset_ctrlc();
371 131968 : timer_start(GP_DATA->T);
372 131968 : walltimer_start(GP_DATA->Tw);
373 131968 : pari_set_last_newline(1);
374 : }
375 131968 : if (gp_meta(b->buf,ismain)) continue;
376 111709 : z = pari_compile_str(b->buf);
377 111632 : z = closure_evalres(z);
378 99218 : if (!ismain) continue;
379 :
380 99218 : t = timer_delay(GP_DATA->T);
381 99218 : r = walltimer_delay(GP_DATA->Tw);
382 99218 : if (!pari_last_was_newline()) pari_putc('\n');
383 99218 : pari_alarm(0);
384 99218 : if (t && GP_DATA->chrono)
385 : {
386 0 : if (pari_mt_nbthreads==1)
387 : {
388 0 : pari_puts("time = ");
389 0 : pari_puts(gp_format_time(t));
390 : }
391 : else
392 : {
393 0 : pari_puts("cpu time = ");
394 0 : pari_puts(gp_format_time(t));
395 0 : pari_puts(", real time = ");
396 0 : pari_puts(gp_format_time(r));
397 : }
398 0 : pari_puts(".\n");
399 : }
400 99218 : if (GP_DATA->simplify) z = simplify_shallow(z);
401 99218 : pari_add_hist(z, t, r);
402 99218 : if (z != gnil && ! is_silent(b->buf) ) gp_output(z);
403 99218 : set_avma(av);
404 99218 : parivstack_reset();
405 : }
406 : }
407 :
408 : /* as gp_read_file, before running the main gp instance */
409 : static void
410 0 : read_main(const char *s)
411 : {
412 : GEN z;
413 0 : if (setjmp(env[s_env.n-1]))
414 0 : z = NULL;
415 : else {
416 0 : FILE *f = switchin(s);
417 0 : if (file_is_binary(f)) {
418 0 : z = readbin(s,f, NULL);
419 0 : popinfile();
420 : }
421 0 : else z = gp_main_loop(0);
422 : }
423 0 : if (!z) err_printf("... skipping file '%s'\n", s);
424 0 : set_avma(pari_mainstack->top);
425 0 : }
426 :
427 : static const char *
428 126 : break_loop_prompt(long n)
429 : {
430 126 : return n==0 ? "GP prompt" : n==1? "break> ": stack_sprintf("break[%ld]> ", n);
431 : }
432 :
433 : static long frame_level=0, dbg_level = 0;
434 :
435 : static int
436 63 : break_loop(int numerr)
437 : {
438 : filtre_t F;
439 : Buffer *b;
440 63 : int sigint = numerr<0, go_on = sigint;
441 : struct gp_context rec1, rec2;
442 : const char *prompt, *msg;
443 63 : long nenv, oldframe_level = frame_level;
444 : pari_sp av;
445 :
446 63 : if (numerr == e_SYNTAX) return 0;
447 63 : if (numerr == e_STACK) { evalstate_clone(); set_avma(pari_mainstack->top); }
448 63 : gp_context_save(&rec1);
449 :
450 63 : b = filtered_buffer(&F);
451 63 : nenv=pari_stack_new(&s_env);
452 63 : prompt = gp_format_prompt(break_loop_prompt(nenv));
453 63 : iferr_env = NULL;
454 63 : dbg_level = 0;
455 63 : frame_level = closure_context(oldframe_level, dbg_level);
456 63 : pari_infile = newfile(stdin, "stdin", mf_IN)->file;
457 63 : term_color(c_ERR); pari_putc('\n');
458 63 : if (sigint)
459 7 : msg = "Break loop: <Return> to continue; 'break' to go back to %s";
460 : else
461 56 : msg = "Break loop: type 'break' to go back to %s";
462 63 : msg = stack_sprintf(msg, break_loop_prompt(nenv-1));
463 63 : print_errcontext(pariOut, msg, NULL, NULL);
464 63 : term_color(c_NONE);
465 63 : av = avma;
466 : for(;;)
467 91 : {
468 : GEN x;
469 : long er, br_status;
470 154 : set_avma(av);
471 154 : gp_context_save(&rec2);
472 154 : if ((er=setjmp(env[nenv])))
473 : {
474 35 : if (er < 0)
475 : {
476 7 : s_env.n = 1;
477 7 : frame_level = oldframe_level;
478 7 : longjmp(env[s_env.n-1], er);
479 : }
480 28 : gp_context_restore(&rec2);
481 28 : iferr_env = NULL;
482 28 : closure_err(dbg_level);
483 28 : compilestate_restore(&rec1.eval.comp);
484 28 : (void) closure_context(oldframe_level, dbg_level);
485 28 : pari_infile = newfile(stdin, "stdin", mf_IN)->file;
486 : }
487 182 : term_color(c_NONE);
488 182 : if (!gp_read_line(&F, prompt))
489 0 : br_status = br_BREAK; /* EOF */
490 : else
491 : {
492 : /* Empty input ? Continue if entry on sigint (exit debugger frame) */
493 182 : if (! *(b->buf) && sigint) break;
494 175 : reset_ctrlc();
495 175 : if (gp_meta(b->buf,0)) continue;
496 175 : x = pari_compile_str(b->buf);
497 175 : x = closure_evalbrk(x, &br_status);
498 : }
499 140 : switch (br_status)
500 : {
501 0 : case br_NEXT: case br_MULTINEXT:
502 0 : popinfile(); /* exit frame. Don't exit debugger if s_env.n > 2 */
503 49 : go_on = 0; goto BR_EXIT;
504 49 : case br_BREAK: case br_RETURN:
505 49 : killallfiles(); /* completely exit the debugger */
506 49 : go_on = 0; goto BR_EXIT;
507 : }
508 91 : if (x!=gnil && !is_silent(b->buf)) { term_color(c_OUTPUT); gen_output(x); }
509 : }
510 56 : BR_EXIT:
511 56 : s_env.n=nenv;
512 56 : frame_level = oldframe_level;
513 56 : gp_context_restore(&rec1);
514 56 : pop_buffer(); return go_on;
515 : }
516 :
517 : #ifdef __CYGWIN32__
518 : void
519 : cyg_environment(int argc, char ** argv)
520 : {
521 : char *ti_dirs = getenv("TERMINFO_DIRS");
522 : char *argv0, *p;
523 : char *newdir;
524 : long n;
525 :
526 : if (!argc || !argv) return;
527 : argv0 = *argv;
528 : if (!argv0 || !*argv0) return;
529 : p = strrchr(argv0, '/');
530 : if (!p)
531 : p = argv0 = "";
532 : else
533 : p++;
534 : n = p - argv0;
535 : if (ti_dirs)
536 : {
537 : n += 14 + strlen(ti_dirs) + 1 + 8 + 1;
538 : newdir = malloc(n);
539 : if (!newdir) return;
540 : snprintf(newdir, n-8, "TERMINFO_DIRS=%s:%s", ti_dirs, argv0);
541 : }
542 : else
543 : {
544 : n += 14 + 8 + 1;
545 : newdir = malloc(n);
546 : if (!newdir) return;
547 : snprintf(newdir, n-8, "TERMINFO_DIRS=%s", argv0);
548 : }
549 : strcpy(newdir+n-9,"terminfo");
550 : putenv(newdir);
551 : }
552 : #endif
553 :
554 : int
555 1816 : main(int argc, char **argv)
556 : {
557 : char **A;
558 : pari_stack s_A;
559 :
560 1816 : GP_DATA = default_gp_data();
561 1816 : pari_stack_init(&s_env, sizeof(*env), (void**)&env);
562 1816 : (void)pari_stack_new(&s_env);
563 :
564 1816 : if (setjmp(env[s_env.n-1]))
565 : {
566 2 : puts("### Errors on startup, exiting...\n\n");
567 2 : exit(1);
568 : }
569 : #ifdef DEBUG_FLOATS
570 : feenableexcept(FE_INVALID);
571 : #endif
572 : #ifdef __CYGWIN32__
573 : cyg_environment(argc, argv);
574 : #endif
575 1816 : stdin_isatty = pari_stdin_isatty();
576 1816 : pari_init_defaults();
577 1816 : pari_library_path = DL_DFLT_NAME;
578 1816 : pari_stack_init(&s_A,sizeof(*A),(void**)&A);
579 : /* must be defined here in case an error is raised in pari_init_opts, e.g.
580 : * when parsing function prototypes */
581 1816 : cb_pari_err_recover = gp_err_recover;
582 1816 : pari_init_opts(8000000, 0, INIT_SIGm | INIT_noPRIMEm | INIT_noIMTm);
583 1816 : cb_pari_pre_recover = gp_pre_recover;
584 1816 : cb_pari_break_loop = break_loop;
585 1816 : cb_pari_is_interactive = is_interactive;
586 :
587 1816 : read_opt(&s_A, argc,argv);
588 1806 : pari_init_primes(GP_DATA->primelimit);
589 : #ifdef SIGALRM
590 1806 : (void)os_signal(SIGALRM,gp_alarm_handler);
591 : #endif
592 1806 : pari_add_module(functions_gp);
593 :
594 1806 : pari_set_plot_engine(gp_get_plot);
595 1806 : cb_pari_quit = gp_quit;
596 1806 : cb_pari_whatnow = whatnow;
597 1806 : cb_pari_sigint = gp_sigint_fun;
598 1806 : cb_pari_handle_exception = gp_handle_exception;
599 1806 : cb_pari_ask_confirm = gp_ask_confirm;
600 1806 : pari_init_paths();
601 1806 : pari_mt_init(); /* MPI: will not return on slaves (pari_MPI_rank = 0) */
602 : #ifdef _WIN32
603 : if (stdin_isatty) win32_set_codepage();
604 : #endif
605 : #ifdef READLINE
606 1806 : init_readline();
607 : #endif
608 1806 : if (GP_DATA->flags & gpd_EMACS) init_emacs();
609 1806 : if (GP_DATA->flags & gpd_TEXMACS) init_texmacs();
610 :
611 1806 : timer_start(GP_DATA->T);
612 1806 : walltimer_start(GP_DATA->Tw);
613 1806 : if (!(GP_DATA->flags & gpd_QUIET)) gp_head();
614 1806 : if (GP_DATA->flags & gpd_TEST) init_test();
615 1806 : if (s_A.n)
616 : {
617 0 : FILE *l = pari_logfile;
618 : long i;
619 0 : pari_logfile = NULL;
620 0 : for (i = 0; i < s_A.n; pari_free(A[i]),i++) read_main(A[i]);
621 : /* Reading one of the input files above can set pari_logfile.
622 : * Don't restore in that case. */
623 0 : if (!pari_logfile) pari_logfile = l;
624 : }
625 1806 : pari_stack_delete(&s_A);
626 1806 : (void)gp_main_loop(1);
627 0 : gp_quit(0);
628 : return 0; /* LCOV_EXCL_LINE */
629 : }
630 :
631 : void
632 7 : pari_breakpoint(void)
633 : {
634 7 : if (!pari_last_was_newline()) pari_putc('\n');
635 7 : closure_err(0);
636 7 : if (cb_pari_break_loop && cb_pari_break_loop(-1)) return;
637 0 : cb_pari_err_recover(e_MISC);
638 : }
639 :
640 : void
641 7 : dbg_down(long k)
642 : {
643 7 : if (k<0) k=0;
644 7 : dbg_level -= k;
645 7 : if (dbg_level<0) dbg_level=0;
646 7 : gp_err_recover(e_NONE);
647 0 : }
648 :
649 : GEN
650 7 : dbg_err(void) { GEN E = pari_err_last(); return E? gcopy(E):gnil; }
651 :
652 : void
653 14 : dbg_up(long k)
654 : {
655 14 : if (k<0) k=0;
656 14 : dbg_level += k;
657 14 : if (dbg_level>frame_level) dbg_level=frame_level;
658 14 : gp_err_recover(e_NONE);
659 0 : }
660 :
661 : void
662 1806 : gp_quit(long code)
663 : {
664 1806 : pari_kill_plot_engine();
665 1806 : pari_close();
666 1806 : kill_buffers_upto(NULL);
667 1806 : if (!(GP_DATA->flags & gpd_QUIET)) pari_puts("Goodbye!\n");
668 1806 : if (cb_pari_end_output) cb_pari_end_output();
669 1806 : exit(code);
670 : }
671 :
672 : void
673 35 : whatnow0(char *s) { whatnow(pariOut, s,0); }
674 :
675 : #include "gp_init.h"
|