Testing latest pari + WASM + node.js... and it works?! Wow.
License: GPL3
ubuntu2004
/* Copyright (C) 2000 The PARI group.12This file is part of the PARI/GP package.34PARI/GP is free software; you can redistribute it and/or modify it under the5terms of the GNU General Public License as published by the Free Software6Foundation; either version 2 of the License, or (at your option) any later7version. It is distributed in the hope that it will be useful, but WITHOUT8ANY WARRANTY WHATSOEVER.910Check the License for details. You should have received a copy of it, along11with the package; see the file 'COPYING'. If not, write to the Free Software12Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */13#include "pari.h"14#include "paripriv.h"1516#ifdef _WIN3217# include "../systems/mingw/mingw.h"18#endif1920/* Return all chars, up to next separator21* [as strtok but must handle verbatim character string] */22char*23get_sep(const char *t)24{25char *buf = stack_malloc(strlen(t)+1);26char *s = buf;27int outer = 1;2829for(;;)30{31switch(*s++ = *t++)32{33case '"':34outer = !outer; break;35case '\0':36return buf;37case ';':38if (outer) { s[-1] = 0; return buf; }39break;40case '\\': /* gobble next char */41if (! (*s++ = *t++) ) return buf;42}43}44}4546/* "atoul" + optional [kmg] suffix */47static ulong48my_int(char *s)49{50ulong n = 0;51char *p = s;5253while (isdigit((int)*p)) {54ulong m;55if (n > (~0UL / 10)) pari_err(e_SYNTAX,"integer too large",s,s);56n *= 10; m = n;57n += *p++ - '0';58if (n < m) pari_err(e_SYNTAX,"integer too large",s,s);59}60if (n)61{62switch(*p)63{64case 'k': case 'K': n = umuluu_or_0(n,1000UL); p++; break;65case 'm': case 'M': n = umuluu_or_0(n,1000000UL); p++; break;66case 'g': case 'G': n = umuluu_or_0(n,1000000000UL); p++; break;67#ifdef LONG_IS_64BIT68case 't': case 'T': n = umuluu_or_0(n,1000000000000UL); p++; break;69#endif70}71if (!n) pari_err(e_SYNTAX,"integer too large",s,s);72}73if (*p) pari_err(e_SYNTAX,"I was expecting an integer here", s, s);74return n;75}7677long78get_int(const char *s, long dflt)79{80pari_sp av = avma;81char *p = get_sep(s);82long n;83int minus = 0;8485if (*p == '-') { minus = 1; p++; }86if (!isdigit((int)*p)) return gc_long(av, dflt);8788n = (long)my_int(p);89if (n < 0) pari_err(e_SYNTAX,"integer too large",s,s);90return gc_long(av, minus? -n: n);91}9293ulong94get_uint(const char *s)95{96pari_sp av = avma;97char *p = get_sep(s);98if (*p == '-') pari_err(e_SYNTAX,"arguments must be positive integers",s,s);99return gc_ulong(av, my_int(p));100}101102#if defined(__EMX__) || defined(_WIN32) || defined(__CYGWIN32__)103# define PATH_SEPARATOR ';' /* beware DOSish 'C:' disk drives */104#else105# define PATH_SEPARATOR ':'106#endif107108static const char *109pari_default_path(void) {110#if PATH_SEPARATOR == ';'111return ".;C:;C:/gp";112#elif defined(UNIX)113return ".:~:~/gp";114#else115return ".";116#endif117}118119static void120delete_dirs(gp_path *p)121{122char **v = p->dirs, **dirs;123if (v)124{125p->dirs = NULL; /* in case of error */126for (dirs = v; *dirs; dirs++) pari_free(*dirs);127pari_free(v);128}129}130131static void132expand_path(gp_path *p)133{134char **dirs, *s, *v = p->PATH;135int i, n = 0;136137delete_dirs(p);138if (*v)139{140v = pari_strdup(v);141for (s=v; *s; s++)142if (*s == PATH_SEPARATOR) {143*s = 0;144if (s == v || s[-1] != 0) n++; /* ignore empty path components */145}146dirs = (char**) pari_malloc((n + 2)*sizeof(char *));147148for (s=v, i=0; i<=n; i++)149{150char *end, *f;151while (!*s) s++; /* skip empty path components */152f = end = s + strlen(s);153while (f > s && *--f == '/') *f = 0; /* skip trailing '/' */154dirs[i] = path_expand(s);155s = end + 1; /* next path component */156}157pari_free((void*)v);158}159else160{161dirs = (char**) pari_malloc(sizeof(char *));162i = 0;163}164dirs[i] = NULL; p->dirs = dirs;165}166void167pari_init_paths(void)168{169expand_path(GP_DATA->path);170expand_path(GP_DATA->sopath);171}172173static void174delete_path(gp_path *p) { delete_dirs(p); free(p->PATH); }175void176pari_close_paths(void)177{178delete_path(GP_DATA->path);179delete_path(GP_DATA->sopath);180}181182/********************************************************************/183/* */184/* DEFAULTS */185/* */186/********************************************************************/187188long189getrealprecision(void)190{191return GP_DATA->fmt->sigd;192}193194long195setrealprecision(long n, long *prec)196{197GP_DATA->fmt->sigd = n;198*prec = ndec2prec(n);199precreal = prec2nbits(*prec);200return n;201}202203GEN204sd_toggle(const char *v, long flag, const char *s, int *ptn)205{206int state = *ptn;207if (v)208{209int n = (int)get_int(v,0);210if (n == state) return gnil;211if (n != !state)212{213char *t = stack_malloc(64 + strlen(s));214(void)sprintf(t, "default: incorrect value for %s [0:off / 1:on]", s);215pari_err(e_SYNTAX, t, v,v);216}217state = *ptn = n;218}219switch(flag)220{221case d_RETURN: return utoi(state);222case d_ACKNOWLEDGE:223if (state) pari_printf(" %s = 1 (on)\n", s);224else pari_printf(" %s = 0 (off)\n", s);225break;226}227return gnil;228}229230static void231sd_ulong_init(const char *v, const char *s, ulong *ptn, ulong Min, ulong Max)232{233if (v)234{235ulong n = get_uint(v);236if (n > Max || n < Min)237{238char *buf = stack_malloc(strlen(s) + 2 * 20 + 40);239(void)sprintf(buf, "default: incorrect value for %s [%lu-%lu]",240s, Min, Max);241pari_err(e_SYNTAX, buf, v,v);242}243*ptn = n;244}245}246247/* msg is NULL or NULL-terminated array with msg[0] != NULL. */248GEN249sd_ulong(const char *v, long flag, const char *s, ulong *ptn, ulong Min, ulong Max,250const char **msg)251{252ulong n = *ptn;253sd_ulong_init(v, s, ptn, Min, Max);254switch(flag)255{256case d_RETURN:257return utoi(*ptn);258case d_ACKNOWLEDGE:259if (!v || *ptn != n) {260if (!msg) /* no specific message */261pari_printf(" %s = %lu\n", s, *ptn);262else if (!msg[1]) /* single message, always printed */263pari_printf(" %s = %lu %s\n", s, *ptn, msg[0]);264else /* print (new)-n-th message */265pari_printf(" %s = %lu %s\n", s, *ptn, msg[*ptn]);266}267break;268}269return gnil;270}271272static void273err_intarray(char *t, char *p, const char *s)274{275char *b = stack_malloc(64 + strlen(s));276sprintf(b, "incorrect value for %s", s);277pari_err(e_SYNTAX, b, p, t);278}279static GEN280parse_intarray(const char *v, const char *s)281{282pari_sp av = avma;283char *p, *t = gp_filter(v);284long i, l;285GEN w;286if (*t != '[') err_intarray(t, t, s);287if (t[1] == ']') return gc_const(av, cgetalloc(t_VECSMALL, 1));288for (p = t+1, l=2; *p; p++)289if (*p == ',') l++;290else if (*p < '0' || *p > '9') break;291if (*p != ']') err_intarray(t, p, s);292w = cgetalloc(t_VECSMALL, l);293for (p = t+1, i=0; *p; p++)294{295long n = 0;296while (*p >= '0' && *p <= '9') n = 10*n + (*p++ -'0');297w[++i] = n;298}299return gc_const(av, w);300}301GEN302sd_intarray(const char *v, long flag, GEN *pz, const char *s)303{304if (v) { GEN z = *pz; *pz = parse_intarray(v, s); pari_free(z); }305switch(flag)306{307case d_RETURN: return zv_to_ZV(*pz);308case d_ACKNOWLEDGE: pari_printf(" %s = %Ps\n", s, zv_to_ZV(*pz));309}310return gnil;311}312313GEN314sd_realprecision(const char *v, long flag)315{316pariout_t *fmt = GP_DATA->fmt;317if (v)318{319ulong newnb = fmt->sigd;320long prec;321sd_ulong_init(v, "realprecision", &newnb, 1, prec2ndec(LGBITS));322if (fmt->sigd == (long)newnb) return gnil;323if (fmt->sigd >= 0) fmt->sigd = newnb;324prec = ndec2nbits(newnb);325if (prec == precreal) return gnil;326precreal = prec;327}328if (flag == d_RETURN) return stoi(nbits2ndec(precreal));329if (flag == d_ACKNOWLEDGE)330{331long n = nbits2ndec(precreal);332pari_printf(" realprecision = %ld significant digits", n);333if (fmt->sigd < 0)334pari_puts(" (all digits displayed)");335else if (n != fmt->sigd)336pari_printf(" (%ld digits displayed)", fmt->sigd);337pari_putc('\n');338}339return gnil;340}341342GEN343sd_realbitprecision(const char *v, long flag)344{345pariout_t *fmt = GP_DATA->fmt;346if (v)347{348ulong newnb = precreal;349long n;350sd_ulong_init(v, "realbitprecision", &newnb, 1, prec2nbits(LGBITS));351if ((long)newnb == precreal) return gnil;352n = nbits2ndec(newnb);353if (!n) n = 1;354if (fmt->sigd >= 0) fmt->sigd = n;355precreal = (long) newnb;356}357if (flag == d_RETURN) return stoi(precreal);358if (flag == d_ACKNOWLEDGE)359{360pari_printf(" realbitprecision = %ld significant bits", precreal);361if (fmt->sigd < 0)362pari_puts(" (all digits displayed)");363else364pari_printf(" (%ld decimal digits displayed)", fmt->sigd);365pari_putc('\n');366}367return gnil;368}369370GEN371sd_seriesprecision(const char *v, long flag)372{373const char *msg[] = {"significant terms", NULL};374return sd_ulong(v,flag,"seriesprecision",&precdl, 1,LGBITS,msg);375}376377static long378gp_get_color(char **st)379{380char *s, *v = *st;381int trans;382long c;383if (isdigit((int)*v))384{ c = atol(v); trans = 1; } /* color on transparent background */385else386{387if (*v == '[')388{389const char *a[3];390long i = 0;391for (a[0] = s = ++v; *s && *s != ']'; s++)392if (*s == ',') { *s = 0; a[++i] = s+1; }393if (*s != ']') pari_err(e_SYNTAX,"expected character: ']'",s, *st);394*s = 0; for (i++; i<3; i++) a[i] = "";395/* properties | color | background */396c = (atoi(a[2])<<8) | atoi(a[0]) | (atoi(a[1])<<4);397trans = (*(a[1]) == 0);398v = s + 1;399}400else { c = c_NONE; trans = 0; }401}402if (trans) c = c | (1L<<12);403while (*v && *v++ != ',') /* empty */;404if (c != c_NONE) disable_color = 0;405*st = v; return c;406}407408/* 1: error, 2: history, 3: prompt, 4: input, 5: output, 6: help, 7: timer */409GEN410sd_colors(const char *v, long flag)411{412long c,l;413if (v && !(GP_DATA->flags & (gpd_EMACS|gpd_TEXMACS)))414{415pari_sp av = avma;416char *s;417disable_color=1;418l = strlen(v);419if (l <= 2 && strncmp(v, "no", l) == 0)420v = "";421if (l <= 6 && strncmp(v, "darkbg", l) == 0)422v = "1, 5, 3, 7, 6, 2, 3"; /* Assume recent ReadLine. */423if (l <= 7 && strncmp(v, "lightbg", l) == 0)424v = "1, 6, 3, 4, 5, 2, 3"; /* Assume recent ReadLine. */425if (l <= 8 && strncmp(v, "brightfg", l) == 0) /* Good for windows consoles */426v = "9, 13, 11, 15, 14, 10, 11";427if (l <= 6 && strncmp(v, "boldfg", l) == 0) /* Good for darkbg consoles */428v = "[1,,1], [5,,1], [3,,1], [7,,1], [6,,1], , [2,,1]";429s = gp_filter(v);430for (c=c_ERR; c < c_LAST; c++) gp_colors[c] = gp_get_color(&s);431set_avma(av);432}433if (flag == d_ACKNOWLEDGE || flag == d_RETURN)434{435char s[128], *t = s;436long col[3], n;437for (*t=0,c=c_ERR; c < c_LAST; c++)438{439n = gp_colors[c];440if (n == c_NONE)441sprintf(t,"no");442else443{444decode_color(n,col);445if (n & (1L<<12))446{447if (col[0])448sprintf(t,"[%ld,,%ld]",col[1],col[0]);449else450sprintf(t,"%ld",col[1]);451}452else453sprintf(t,"[%ld,%ld,%ld]",col[1],col[2],col[0]);454}455t += strlen(t);456if (c < c_LAST - 1) { *t++=','; *t++=' '; }457}458if (flag==d_RETURN) return strtoGENstr(s);459pari_printf(" colors = \"%s\"\n",s);460}461return gnil;462}463464GEN465sd_format(const char *v, long flag)466{467pariout_t *fmt = GP_DATA->fmt;468if (v)469{470char c = *v;471if (c!='e' && c!='f' && c!='g')472pari_err(e_SYNTAX,"default: inexistent format",v,v);473fmt->format = c; v++;474475if (isdigit((int)*v))476{ while (isdigit((int)*v)) v++; } /* FIXME: skip obsolete field width */477if (*v++ == '.')478{479if (*v == '-') fmt->sigd = -1;480else481if (isdigit((int)*v)) fmt->sigd=atol(v);482}483}484if (flag == d_RETURN)485{486char *s = stack_malloc(64);487(void)sprintf(s, "%c.%ld", fmt->format, fmt->sigd);488return strtoGENstr(s);489}490if (flag == d_ACKNOWLEDGE)491pari_printf(" format = %c.%ld\n", fmt->format, fmt->sigd);492return gnil;493}494495GEN496sd_compatible(const char *v, long flag)497{498const char *msg[] = {499"(no backward compatibility)",500"(no backward compatibility)",501"(no backward compatibility)",502"(no backward compatibility)", NULL503};504ulong junk = 0;505return sd_ulong(v,flag,"compatible",&junk, 0,3,msg);506}507508GEN509sd_secure(const char *v, long flag)510{511if (v && GP_DATA->secure)512pari_ask_confirm("[secure mode]: About to modify the 'secure' flag");513return sd_toggle(v,flag,"secure", &(GP_DATA->secure));514}515516GEN517sd_debug(const char *v, long flag)518{519GEN r = sd_ulong(v,flag,"debug",&DEBUGLEVEL, 0,20,NULL);520if (v) setalldebug(DEBUGLEVEL);521return r;522}523524GEN525sd_debugfiles(const char *v, long flag)526{ return sd_ulong(v,flag,"debugfiles",&DEBUGFILES, 0,20,NULL); }527528GEN529sd_debugmem(const char *v, long flag)530{ return sd_ulong(v,flag,"debugmem",&DEBUGMEM, 0,20,NULL); }531532/* set D->hist to size = s / total = t */533static void534init_hist(gp_data *D, size_t s, ulong t)535{536gp_hist *H = D->hist;537H->total = t;538H->size = s;539H->v = (gp_hist_cell*)pari_calloc(s * sizeof(gp_hist_cell));540}541GEN542sd_histsize(const char *s, long flag)543{544gp_hist *H = GP_DATA->hist;545ulong n = H->size;546GEN r = sd_ulong(s,flag,"histsize",&n, 1,547(LONG_MAX / sizeof(long)) - 1,NULL);548if (n != H->size)549{550const ulong total = H->total;551long g, h, k, kmin;552gp_hist_cell *v = H->v, *w; /* v = old data, w = new one */553size_t sv = H->size, sw;554555init_hist(GP_DATA, n, total);556if (!total) return r;557558w = H->v;559sw= H->size;560/* copy relevant history entries */561g = (total-1) % sv;562h = k = (total-1) % sw;563kmin = k - minss(sw, sv);564for ( ; k > kmin; k--, g--, h--)565{566w[h] = v[g];567v[g].z = NULL;568if (!g) g = sv;569if (!h) h = sw;570}571/* clean up */572for ( ; v[g].z; g--)573{574gunclone(v[g].z);575if (!g) g = sv;576}577pari_free((void*)v);578}579return r;580}581582static void583TeX_define(const char *s, const char *def) {584fprintf(pari_logfile, "\\ifx\\%s\\undefined\n \\def\\%s{%s}\\fi\n", s,s,def);585}586static void587TeX_define2(const char *s, const char *def) {588fprintf(pari_logfile, "\\ifx\\%s\\undefined\n \\def\\%s#1#2{%s}\\fi\n", s,s,def);589}590591static FILE *592open_logfile(const char *s) {593FILE *log = fopen(s, "a");594if (!log) pari_err_FILE("logfile",s);595setbuf(log,(char *)NULL);596return log;597}598599GEN600sd_log(const char *v, long flag)601{602const char *msg[] = {603"(off)",604"(on)",605"(on with colors)",606"(TeX output)", NULL607};608ulong s = pari_logstyle;609GEN res = sd_ulong(v,flag,"log", &s, 0, 3, msg);610611if (!s != !pari_logstyle) /* Compare converts to boolean */612{ /* toggled LOG */613if (pari_logstyle)614{ /* close log */615if (flag == d_ACKNOWLEDGE)616pari_printf(" [logfile was \"%s\"]\n", current_logfile);617if (pari_logfile) { fclose(pari_logfile); pari_logfile = NULL; }618}619else620{621pari_logfile = open_logfile(current_logfile);622if (flag == d_ACKNOWLEDGE)623pari_printf(" [logfile is \"%s\"]\n", current_logfile);624else if (flag == d_INITRC)625pari_printf("Logging to %s\n", current_logfile);626}627}628if (pari_logfile && s != pari_logstyle && s == logstyle_TeX)629{630TeX_define("PARIbreak",631"\\hskip 0pt plus \\hsize\\relax\\discretionary{}{}{}");632TeX_define("PARIpromptSTART", "\\vskip\\medskipamount\\bgroup\\bf");633TeX_define("PARIpromptEND", "\\egroup\\bgroup\\tt");634TeX_define("PARIinputEND", "\\egroup");635TeX_define2("PARIout",636"\\vskip\\smallskipamount$\\displaystyle{\\tt\\%#1} = #2$");637}638/* don't record new value until we are sure everything is fine */639pari_logstyle = s; return res;640}641642GEN643sd_TeXstyle(const char *v, long flag)644{645const char *msg[] = { "(bits 0x2/0x4 control output of \\left/\\PARIbreak)",646NULL };647ulong n = GP_DATA->fmt->TeXstyle;648GEN z = sd_ulong(v,flag,"TeXstyle", &n, 0, 7, msg);649GP_DATA->fmt->TeXstyle = n; return z;650}651652GEN653sd_nbthreads(const char *v, long flag)654{ return sd_ulong(v,flag,"nbthreads",&pari_mt_nbthreads, 1,LONG_MAX,NULL); }655656GEN657sd_output(const char *v, long flag)658{659const char *msg[] = {"(raw)", "(prettymatrix)", "(prettyprint)",660"(external prettyprint)", NULL};661ulong n = GP_DATA->fmt->prettyp;662GEN z = sd_ulong(v,flag,"output", &n, 0,3,msg);663GP_DATA->fmt->prettyp = n;664GP_DATA->fmt->sp = (n != f_RAW);665return z;666}667668GEN669sd_parisizemax(const char *v, long flag)670{671ulong size = pari_mainstack->vsize, n = size;672GEN r = sd_ulong(v,flag,"parisizemax",&n, 0,LONG_MAX,NULL);673if (n != size) {674if (flag == d_INITRC)675paristack_setsize(pari_mainstack->rsize, n);676else677parivstack_resize(n);678}679return r;680}681682GEN683sd_parisize(const char *v, long flag)684{685ulong rsize = pari_mainstack->rsize, n = rsize;686GEN r = sd_ulong(v,flag,"parisize",&n, 10000,LONG_MAX,NULL);687if (n != rsize) {688if (flag == d_INITRC)689paristack_setsize(n, pari_mainstack->vsize);690else691paristack_newrsize(n);692}693return r;694}695696GEN697sd_threadsizemax(const char *v, long flag)698{699ulong size = GP_DATA->threadsizemax, n = size;700GEN r = sd_ulong(v,flag,"threadsizemax",&n, 0,LONG_MAX,NULL);701if (n != size)702GP_DATA->threadsizemax = n;703return r;704}705706GEN707sd_threadsize(const char *v, long flag)708{709ulong size = GP_DATA->threadsize, n = size;710GEN r = sd_ulong(v,flag,"threadsize",&n, 0,LONG_MAX,NULL);711if (n != size)712GP_DATA->threadsize = n;713return r;714}715716GEN717sd_primelimit(const char *v, long flag)718{ return sd_ulong(v,flag,"primelimit",&(GP_DATA->primelimit),7190,2*(ulong)(LONG_MAX-1024) + 1,NULL); }720721GEN722sd_simplify(const char *v, long flag)723{ return sd_toggle(v,flag,"simplify", &(GP_DATA->simplify)); }724725GEN726sd_strictmatch(const char *v, long flag)727{ return sd_toggle(v,flag,"strictmatch", &(GP_DATA->strictmatch)); }728729GEN730sd_strictargs(const char *v, long flag)731{ return sd_toggle(v,flag,"strictargs", &(GP_DATA->strictargs)); }732733GEN734sd_string(const char *v, long flag, const char *s, char **pstr)735{736char *old = *pstr;737if (v)738{739char *str, *ev = path_expand(v);740long l = strlen(ev) + 256;741str = (char *) pari_malloc(l);742strftime_expand(ev,str, l-1); pari_free(ev);743if (GP_DATA->secure)744{745char *msg=pari_sprintf("[secure mode]: About to change %s to '%s'",s,str);746pari_ask_confirm(msg);747pari_free(msg);748}749if (old) pari_free(old);750*pstr = old = pari_strdup(str);751pari_free(str);752}753else if (!old) old = (char*)"<undefined>";754if (flag == d_RETURN) return strtoGENstr(old);755if (flag == d_ACKNOWLEDGE) pari_printf(" %s = \"%s\"\n",s,old);756return gnil;757}758759GEN760sd_logfile(const char *v, long flag)761{762GEN r = sd_string(v, flag, "logfile", ¤t_logfile);763if (v && pari_logfile)764{765FILE *log = open_logfile(current_logfile);766fclose(pari_logfile); pari_logfile = log;767}768return r;769}770771GEN772sd_factor_add_primes(const char *v, long flag)773{ return sd_toggle(v,flag,"factor_add_primes", &factor_add_primes); }774775GEN776sd_factor_proven(const char *v, long flag)777{ return sd_toggle(v,flag,"factor_proven", &factor_proven); }778779GEN780sd_new_galois_format(const char *v, long flag)781{ return sd_toggle(v,flag,"new_galois_format", &new_galois_format); }782783GEN784sd_datadir(const char *v, long flag)785{786const char *str;787if (v)788{789mt_broadcast(snm_closure(is_entry("default"),790mkvec2(strtoGENstr("datadir"), strtoGENstr(v))));791if (pari_datadir) pari_free(pari_datadir);792pari_datadir = path_expand(v);793}794str = pari_datadir? pari_datadir: "none";795if (flag == d_RETURN) return strtoGENstr(str);796if (flag == d_ACKNOWLEDGE)797pari_printf(" datadir = \"%s\"\n", str);798return gnil;799}800801static GEN802sd_PATH(const char *v, long flag, const char* s, gp_path *p)803{804if (v)805{806mt_broadcast(snm_closure(is_entry("default"),807mkvec2(strtoGENstr(s), strtoGENstr(v))));808pari_free((void*)p->PATH);809p->PATH = pari_strdup(v);810if (flag == d_INITRC) return gnil;811expand_path(p);812}813if (flag == d_RETURN) return strtoGENstr(p->PATH);814if (flag == d_ACKNOWLEDGE)815pari_printf(" %s = \"%s\"\n", s, p->PATH);816return gnil;817}818GEN819sd_path(const char *v, long flag)820{ return sd_PATH(v, flag, "path", GP_DATA->path); }821GEN822sd_sopath(char *v, int flag)823{ return sd_PATH(v, flag, "sopath", GP_DATA->sopath); }824825static const char *DFT_PRETTYPRINTER = "tex2mail -TeX -noindent -ragged -by_par";826GEN827sd_prettyprinter(const char *v, long flag)828{829gp_pp *pp = GP_DATA->pp;830if (v && !(GP_DATA->flags & gpd_TEXMACS))831{832char *old = pp->cmd;833int cancel = (!strcmp(v,"no"));834835if (GP_DATA->secure)836pari_err(e_MISC,"[secure mode]: can't modify 'prettyprinter' default (to %s)",v);837if (!strcmp(v,"yes")) v = DFT_PRETTYPRINTER;838if (old && strcmp(old,v) && pp->file)839{840pariFILE *f;841if (cancel) f = NULL;842else843{844f = try_pipe(v, mf_OUT);845if (!f)846{847pari_warn(warner,"broken prettyprinter: '%s'",v);848return gnil;849}850}851pari_fclose(pp->file);852pp->file = f;853}854pp->cmd = cancel? NULL: pari_strdup(v);855if (old) pari_free(old);856if (flag == d_INITRC) return gnil;857}858if (flag == d_RETURN)859return strtoGENstr(pp->cmd? pp->cmd: "");860if (flag == d_ACKNOWLEDGE)861pari_printf(" prettyprinter = \"%s\"\n",pp->cmd? pp->cmd: "");862return gnil;863}864865/* compare entrees s1 s2 according to the attached function name */866static int867compare_name(const void *s1, const void *s2) {868entree *e1 = *(entree**)s1, *e2 = *(entree**)s2;869return strcmp(e1->name, e2->name);870}871static void872defaults_list(pari_stack *s)873{874entree *ep;875long i;876for (i = 0; i < functions_tblsz; i++)877for (ep = defaults_hash[i]; ep; ep = ep->next) pari_stack_pushp(s, ep);878}879/* ep attached to function f of arity 2. Call f(v,flag) */880static GEN881call_f2(entree *ep, const char *v, long flag)882{ return ((GEN (*)(const char*,long))ep->value)(v, flag); }883GEN884setdefault(const char *s, const char *v, long flag)885{886entree *ep;887if (!s)888{ /* list all defaults */889pari_stack st;890entree **L;891long i;892pari_stack_init(&st, sizeof(*L), (void**)&L);893defaults_list(&st);894qsort (L, st.n, sizeof(*L), compare_name);895for (i = 0; i < st.n; i++) (void)call_f2(L[i], NULL, d_ACKNOWLEDGE);896pari_stack_delete(&st);897return gnil;898}899ep = pari_is_default(s);900if (!ep)901{902pari_err(e_MISC,"unknown default: %s",s);903return NULL; /* LCOV_EXCL_LINE */904}905return call_f2(ep, v, flag);906}907908GEN909default0(const char *a, const char *b) { return setdefault(a,b, b? d_SILENT: d_RETURN); }910911/********************************************************************/912/* */913/* INITIALIZE GP_DATA */914/* */915/********************************************************************/916/* initialize path */917static void918init_path(gp_path *path, const char *v)919{920path->PATH = pari_strdup(v);921path->dirs = NULL;922}923924/* initialize D->fmt */925static void926init_fmt(gp_data *D)927{928#ifdef LONG_IS_64BIT929static pariout_t DFLT_OUTPUT = { 'g', 38, 1, f_PRETTYMAT, 0 };930#else931static pariout_t DFLT_OUTPUT = { 'g', 28, 1, f_PRETTYMAT, 0 };932#endif933D->fmt = &DFLT_OUTPUT;934}935936/* initialize D->pp */937static void938init_pp(gp_data *D)939{940gp_pp *p = D->pp;941p->cmd = pari_strdup(DFT_PRETTYPRINTER);942p->file = NULL;943}944945static char *946init_help(void)947{948char *h = os_getenv("GPHELP");949if (!h) h = (char*)paricfg_gphelp;950#ifdef _WIN32951win32_set_pdf_viewer();952#endif953if (h) h = pari_strdup(h);954return h;955}956957static void958init_graphs(gp_data *D)959{960const char *cols[] = { "",961"white","black","blue","violetred","red","green","grey","gainsboro"962};963const long N = 8;964GEN c = cgetalloc(t_VECSMALL, 3), s;965long i;966c[1] = 4;967c[2] = 5;968D->graphcolors = c;969c = (GEN)pari_malloc((N+1 + 4*N)*sizeof(long));970c[0] = evaltyp(t_VEC)|evallg(N+1);971for (i = 1, s = c+N+1; i <= N; i++, s += 4)972{973GEN lp = s;974lp[0] = evaltyp(t_STR)|evallg(4);975strcpy(GSTR(lp), cols[i]);976gel(c,i) = lp;977}978D->colormap = c;979}980981gp_data *982default_gp_data(void)983{984static gp_data __GPDATA, *D = &__GPDATA;985static gp_hist __HIST;986static gp_pp __PP;987static gp_path __PATH, __SOPATH;988static pari_timer __T, __Tw;989990D->flags = 0;991D->primelimit = 500000;992993/* GP-specific */994D->breakloop = 1;995D->echo = 0;996D->lim_lines = 0;997D->linewrap = 0;998D->recover = 1;999D->chrono = 0;10001001D->strictargs = 0;1002D->strictmatch = 1;1003D->simplify = 1;1004D->secure = 0;1005D->use_readline= 0;1006D->T = &__T;1007D->Tw = &__Tw;1008D->hist = &__HIST;1009D->pp = &__PP;1010D->path = &__PATH;1011D->sopath=&__SOPATH;1012init_fmt(D);1013init_hist(D, 5000, 0);1014init_path(D->path, pari_default_path());1015init_path(D->sopath, "");1016init_pp(D);1017init_graphs(D);1018D->plothsizes = cgetalloc(t_VECSMALL, 1);1019D->prompt_comment = (char*)"comment> ";1020D->prompt = pari_strdup("? ");1021D->prompt_cont = pari_strdup("");1022D->help = init_help();1023D->readline_state = DO_ARGS_COMPLETE;1024D->histfile = NULL;1025return D;1026}102710281029