Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Testing latest pari + WASM + node.js... and it works?! Wow.

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