Annotation of OpenXM_contrib/pari-2.2/src/gp/gp.c, Revision 1.1
1.1 ! noro 1: /* $Id: gp.c,v 1.83 2001/09/29 18:32:02 karim Exp $
! 2:
! 3: Copyright (C) 2000 The PARI group.
! 4:
! 5: This file is part of the PARI/GP package.
! 6:
! 7: PARI/GP is free software; you can redistribute it and/or modify it under the
! 8: terms of the GNU General Public License as published by the Free Software
! 9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
! 10: ANY WARRANTY WHATSOEVER.
! 11:
! 12: Check the License for details. You should have received a copy of it, along
! 13: with the package; see the file 'COPYING'. If not, write to the Free Software
! 14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
! 15:
! 16: /*******************************************************************/
! 17: /** **/
! 18: /** PARI CALCULATOR **/
! 19: /** **/
! 20: /*******************************************************************/
! 21: #include "pari.h"
! 22: #ifdef _WIN32
! 23: # include <windows.h>
! 24: # ifndef WINCE
! 25: # include <process.h>
! 26: # endif
! 27: #endif
! 28: #ifdef HAS_STRFTIME
! 29: # include <time.h>
! 30: #endif
! 31: #include "../language/anal.h"
! 32: #include "gp.h"
! 33:
! 34: #ifdef READLINE
! 35: extern void init_readline();
! 36: long use_readline = 1;
! 37: int readline_init = 1;
! 38: BEGINEXTERN
! 39: # if defined(__cplusplus) && defined(__SUNPRO_CC)
! 40: /* readline.h gives a bad definition of readline() */
! 41: extern char*readline(char*);
! 42: # else
! 43: # ifdef READLINE_LIBRARY
! 44: # include <readline.h>
! 45: # else
! 46: # include <readline/readline.h>
! 47: # endif
! 48: # endif
! 49: extern int isatty(int);
! 50: extern void add_history(char*);
! 51: ENDEXTERN
! 52: #endif
! 53:
! 54: char* _analyseur(void);
! 55: void _set_analyseur(char *s);
! 56: void err_recover(long numerr);
! 57: void free_graph(void);
! 58: void gp_expand_path(char *v);
! 59: int gp_init_entrees(module *modlist, entree **hash, int force);
! 60: long gptimer(void);
! 61: void init80(long n);
! 62: void init_defaults(int force);
! 63: void initout(int initerr);
! 64: void init_graph(void);
! 65: void init_lim_lines(char *s, long max);
! 66: extern void install0(char *name, char *code, char *gpname, char *lib);
! 67: void pari_sig_init(void (*f)(int));
! 68: int whatnow(char *s, int flag);
! 69:
! 70: #if 0 /* to debug TeXmacs interface */
! 71: #define DATA_BEGIN ((char) 'B')
! 72: #define DATA_END ((char) 'E')
! 73: #else
! 74: #define DATA_BEGIN ((char) 2)
! 75: #define DATA_END ((char) 5)
! 76: #endif
! 77: #define DATA_ESCAPE ((char) 27)
! 78:
! 79: #define MAX_PROMPT_LEN 128
! 80: #define DFT_PROMPT "? "
! 81: #define COMMENTPROMPT "comment> "
! 82: #define DFT_INPROMPT ""
! 83: static GEN *hist;
! 84: static char *help_prg,*path;
! 85: static char prompt[MAX_PROMPT_LEN];
! 86: static char thestring[256];
! 87: static char *prettyprinter;
! 88: static char *prettyprinter_dft = "tex2mail -TeX -noindent -ragged -by_par";
! 89: static pariFILE *prettyprinter_file;
! 90: static long prettyp, test_mode, quiet_mode, gpsilent, simplifyflag;
! 91: static long chrono, pariecho, primelimit, parisize, strictmatch;
! 92: static long tglobal, histsize, paribufsize, lim_lines;
! 93: static int tm_is_waiting = 0, handle_C_C = 0;
! 94: static gp_format fmt;
! 95:
! 96: typedef struct Buffer {
! 97: char *buf;
! 98: long len;
! 99: jmp_buf env;
! 100: int flenv;
! 101: } Buffer;
! 102:
! 103: #define current_buffer (bufstack?((Buffer*)(bufstack->value)):NULL)
! 104: static stack *bufstack = NULL;
! 105:
! 106: #define LBRACE '{'
! 107: #define RBRACE '}'
! 108: #define pariputs_opt(s) if (!quiet_mode) pariputs(s)
! 109: #define skip_space(s) while (isspace((int)*s)) s++
! 110: #define skip_alpha(s) while (isalpha((int)*s)) s++
! 111: #define ask_filtre(t) filtre("",NULL,t)
! 112:
! 113: static void
! 114: usage(char *s)
! 115: {
! 116: printf("### Usage: %s [options]\n", s);
! 117: printf("Options are:\n");
! 118: printf("\t[-b buffersize]\tDeprecated\n");
! 119: printf("\t[-emacs]\tRun as if in Emacs shell\n");
! 120: printf("\t[-f]\t\tFaststart: do not read .gprc\n");
! 121: printf("\t[--help]\tPrint this message\n");
! 122: printf("\t[-q]\t\tQuiet mode: do not print banner and history numbers\n");
! 123: printf("\t[-p primelimit]\tPrecalculate primes up to the limit\n");
! 124: printf("\t[-s stacksize]\tStart with the PARI stack of given size (in bytes)\n");
! 125: printf("\t[-test]\t\tTest mode. As -q, plus wrap long lines\n");
! 126: printf("\t[--version]\tOutput version info and exit\n\n");
! 127: exit(0);
! 128: }
! 129:
! 130: /* must be called BEFORE pari_init() */
! 131: static void
! 132: gp_preinit(int force)
! 133: {
! 134: static char *dflt;
! 135: char *help;
! 136: long i;
! 137:
! 138: if (force)
! 139: {
! 140: #if !defined(macintosh) || defined(__MWERKS__)
! 141: primelimit = 500000; parisize = 1000000*sizeof(long);
! 142: dflt = DFT_PROMPT;
! 143: #else
! 144: primelimit = 200000; parisize = 1000000;
! 145: dflt = "?\n";
! 146: #endif
! 147: }
! 148: strcpy(prompt, dflt);
! 149:
! 150: #if defined(UNIX) || defined(__EMX__)
! 151: # if defined(__EMX__) || defined(__CYGWIN32__)
! 152: path = pari_strdup(".;C:;C:/gp");
! 153: # else
! 154: path = pari_strdup(".:~:~/gp");
! 155: # endif
! 156: help = getenv("GPHELP");
! 157: # ifdef GPHELP
! 158: if (!help) help = GPHELP;
! 159: # endif
! 160: #else
! 161: path = pari_strdup(".");
! 162: help = NULL;
! 163: #endif
! 164: help_prg = help? pari_strdup(help): NULL;
! 165: prettyp = f_PRETTYMAT;
! 166: strictmatch = simplifyflag = 1;
! 167: tglobal = 0;
! 168: bufstack = NULL;
! 169: secure = test_mode = under_emacs = under_texmacs = chrono = pariecho = 0;
! 170: prettyprinter = prettyprinter_dft;
! 171: prettyprinter_file = NULL;
! 172: fmt.format = 'g'; fmt.field = 0;
! 173: #ifdef LONG_IS_64BIT
! 174: fmt.nb = 38;
! 175: #else
! 176: fmt.nb = 28;
! 177: #endif
! 178: lim_lines = 0;
! 179: histsize = 5000; paribufsize = 1024;
! 180: i = histsize*sizeof(GEN);
! 181: hist = (GEN *) gpmalloc(i); memset(hist,0,i);
! 182: for (i=0; i<c_LAST; i++) gp_colors[i] = c_NONE;
! 183: }
! 184:
! 185: #ifdef MAXPATHLEN
! 186: # define GET_SEP_SIZE MAXPATHLEN
! 187: #else
! 188: # define GET_SEP_SIZE 128
! 189: #endif
! 190: #define separe(c) ((c)==';' || (c)==':')
! 191:
! 192: /* Return all chars, up to next separator */
! 193: static char*
! 194: get_sep0(char *t, int colon)
! 195: {
! 196: static char buf[GET_SEP_SIZE], *lim = buf + GET_SEP_SIZE-1;
! 197: char *s = buf;
! 198: int outer=1;
! 199:
! 200: for(;;)
! 201: {
! 202: switch(*s++ = *t++)
! 203: {
! 204: case '"':
! 205: if (outer || (s >= buf+2 && s[-2] != '\\')) outer = !outer;
! 206: break;
! 207: case '\0':
! 208: return buf;
! 209: case ';':
! 210: if (outer) { s[-1]=0; return buf; } break;
! 211: case ':':
! 212: if (outer && colon) { s[-1]=0; return buf; } break;
! 213: }
! 214: if (s == lim) err(talker,"buffer overflow in get_sep");
! 215: }
! 216: }
! 217:
! 218: static char*
! 219: get_sep(char *t)
! 220: {
! 221: return get_sep0(t,1);
! 222: }
! 223:
! 224: static char*
! 225: get_sep_colon_ok(char *t)
! 226: {
! 227: return get_sep0(t,0);
! 228: }
! 229:
! 230: /* as above, t must be writeable, return 1 if we modified t */
! 231: static int
! 232: get_sep2(char *t)
! 233: {
! 234: int outer=1;
! 235: char *s = t;
! 236:
! 237: for(;;)
! 238: {
! 239: switch (*s++)
! 240: {
! 241: case '"':
! 242: if (outer || s[-2] != '\\') outer = !outer;
! 243: break;
! 244: case '\0':
! 245: return 0;
! 246: default:
! 247: if (outer && separe(*s)) { *s=0; return 1; }
! 248: }
! 249: }
! 250: }
! 251:
! 252: static long
! 253: get_int(char *s, long dflt)
! 254: {
! 255: char *p=get_sep(s);
! 256: long n=atol(p);
! 257:
! 258: if (*p == '-') p++;
! 259: while(isdigit((int)*p)) { p++; dflt=n; }
! 260: switch(*p)
! 261: {
! 262: case 'k': case 'K': dflt *= 1000; p++; break;
! 263: case 'm': case 'M': dflt *= 1000000; p++; break;
! 264: }
! 265: if (*p) err(talker2,"I was expecting an integer here", s, s);
! 266: return dflt;
! 267: }
! 268:
! 269: /* tell TeXmacs GP will start outputing data */
! 270: static void
! 271: tm_start_output()
! 272: {
! 273: if (!tm_is_waiting) { printf("%cverbatim:",DATA_BEGIN); fflush(stdout); }
! 274: tm_is_waiting = 1;
! 275: }
! 276:
! 277: /* tell TeXmacs GP is done and is waiting for new data */
! 278: static void
! 279: tm_end_output()
! 280: {
! 281: if (tm_is_waiting) { printf("%c", DATA_END); fflush(stdout); }
! 282: tm_is_waiting = 0;
! 283: }
! 284:
! 285: static void
! 286: gp_output(GEN x)
! 287: {
! 288: long tx=typ(x);
! 289:
! 290: if (fmt.nb >= 0 && is_intreal_t(tx))
! 291: ecrire(x, fmt.format, fmt.nb, fmt.field);
! 292: else
! 293: switch(prettyp)
! 294: {
! 295: case f_PRETTYMAT: matbrute(x, fmt.format, fmt.nb); break;
! 296: case f_PRETTY:
! 297: case f_PRETTYOLD: sor(x, fmt.format, fmt.nb, fmt.field); break;
! 298: case f_RAW : brute(x, fmt.format, fmt.nb); break;
! 299: case f_TEX : texe(x, fmt.format, fmt.nb); break;
! 300: }
! 301: }
! 302:
! 303: /* print a sequence of (NULL terminated) GEN */
! 304: void
! 305: print0(GEN *g, long flag)
! 306: {
! 307: int old=prettyp;
! 308:
! 309: if (flag < NBFORMATS) added_newline=1;
! 310: else
! 311: { flag -= NBFORMATS; added_newline=0; }
! 312: prettyp=flag;
! 313:
! 314: for( ; *g; g++)
! 315: if (typ(*g)==t_STR)
! 316: pariputs(GSTR(*g)); /* otherwise it's surrounded by "" */
! 317: else
! 318: gp_output(*g);
! 319:
! 320: if (added_newline) pariputc('\n');
! 321: prettyp=old; pariflush();
! 322: }
! 323:
! 324: /* write a sequence of (NULL terminated) GEN, to file s */
! 325: void
! 326: write0(char *s, GEN *g, long flag)
! 327: {
! 328: int i = added_newline;
! 329: s = expand_tilde(s);
! 330: if (secure)
! 331: {
! 332: fprintferr("[secure mode]: about to write to '%s'. OK ? (^C if not)\n",s);
! 333: hit_return();
! 334: }
! 335: switchout(s); free(s);
! 336: print0(g,flag); added_newline = i;
! 337: switchout(NULL);
! 338: }
! 339:
! 340: void
! 341: gpwritebin(char *s, GEN x)
! 342: {
! 343: s = expand_tilde(s);
! 344: if (secure)
! 345: {
! 346: fprintferr("[secure mode]: about to write to '%s'. OK ? (^C if not)\n",s);
! 347: hit_return();
! 348: }
! 349: writebin(s,x); free(s);
! 350: }
! 351:
! 352: Buffer *
! 353: new_buffer()
! 354: {
! 355: Buffer *b = (Buffer*) gpmalloc(sizeof(Buffer));
! 356: b->len = paribufsize;
! 357: b->buf = gpmalloc(b->len);
! 358: b->flenv = 0; return b;
! 359: }
! 360:
! 361: void
! 362: del_buffer(Buffer *b)
! 363: {
! 364: if (!b) return;
! 365: free(b->buf); free((void*)b);
! 366: }
! 367:
! 368: static void
! 369: pop_buffer()
! 370: {
! 371: Buffer *b = (Buffer*) pop_stack(&bufstack);
! 372: del_buffer(b);
! 373: }
! 374:
! 375: /* kill all buffers until B is met or nothing is left */
! 376: static void
! 377: kill_all_buffers(Buffer *B)
! 378: {
! 379: for(;;) {
! 380: Buffer *b = current_buffer;
! 381: if (b == B || !b) break;
! 382: pop_buffer();
! 383: }
! 384: }
! 385:
! 386: static void
! 387: jump_to_buffer()
! 388: {
! 389: Buffer *b;
! 390: while ( (b = current_buffer) )
! 391: {
! 392: if (b->flenv) break;
! 393: pop_buffer();
! 394: }
! 395: if (!b) longjmp(environnement, 0);
! 396: longjmp(b->env, 0);
! 397: }
! 398:
! 399: static void
! 400: jump_to_given_buffer(Buffer *buf)
! 401: {
! 402: Buffer *b;
! 403: while ( (b = current_buffer) )
! 404: {
! 405: if (b == buf) break;
! 406: pop_buffer();
! 407: }
! 408: if (!b->env) { b = NULL; err(warner,"no environmnent tied to buffer"); }
! 409: if (!b) longjmp(environnement, 0);
! 410: longjmp(b->env, 0);
! 411: }
! 412:
! 413: /********************************************************************/
! 414: /* */
! 415: /* DEFAULTS */
! 416: /* */
! 417: /********************************************************************/
! 418: static void
! 419: do_strftime(char *s, char *buf)
! 420: {
! 421: #ifdef HAS_STRFTIME
! 422: time_t t = time(NULL);
! 423: strftime(buf,MAX_PROMPT_LEN-1,s,localtime(&t));
! 424: #else
! 425: strcpy(buf,s);
! 426: #endif
! 427: }
! 428:
! 429: static GEN
! 430: sd_numeric(char *v, int flag, char *s, long *ptn, long Min, long Max,
! 431: char **msg)
! 432: {
! 433: long n;
! 434: if (*v == 0) n = *ptn;
! 435: else
! 436: {
! 437: n = get_int(v,0);
! 438: if (*ptn == n) return gnil;
! 439: if (n > Max || n < Min)
! 440: {
! 441: sprintf(thestring, "default: incorrect value for %s [%ld-%ld]",
! 442: s, Min, Max);
! 443: err(talker2, thestring, v,v);
! 444: }
! 445: *ptn = n;
! 446: }
! 447: switch(flag)
! 448: {
! 449: case d_RETURN: return stoi(n);
! 450: case d_ACKNOWLEDGE:
! 451: if (msg)
! 452: {
! 453: if (!*msg)
! 454: msg++; /* single msg, always printed */
! 455: else
! 456: msg += n; /* one per possible value */
! 457: pariputsf(" %s = %ld %s\n", s, n, *msg);
! 458: }
! 459: else if (Max != 1 || Min != 0)
! 460: pariputsf(" %s = %ld\n", s, n);
! 461: else /* toggle */
! 462: {
! 463: if (n==1) pariputsf(" %s = 1 (on)\n", s);
! 464: else pariputsf(" %s = 0 (off)\n", s);
! 465: } /* fall through */
! 466: default: return gnil;
! 467: }
! 468: }
! 469:
! 470: #define PRECDIGIT (long)((prec-2.)*pariK)
! 471: static GEN
! 472: sd_realprecision(char *v, int flag)
! 473: {
! 474: if (*v)
! 475: {
! 476: long newnb = get_int(v, fmt.nb);
! 477: long newprec = (long) (newnb*pariK1 + 3);
! 478:
! 479: if (fmt.nb == newnb && prec == newprec) return gnil;
! 480: if (newnb < 0) err(talker,"default: negative real precision");
! 481: fmt.nb = newnb; prec = newprec;
! 482: }
! 483: if (flag == d_RETURN) return stoi(fmt.nb);
! 484: if (flag == d_ACKNOWLEDGE)
! 485: {
! 486: long n = PRECDIGIT;
! 487: pariputsf(" realprecision = %ld significant digits", n);
! 488: if (n != fmt.nb) pariputsf(" (%ld digits displayed)", fmt.nb);
! 489: pariputc('\n');
! 490: }
! 491: return gnil;
! 492: }
! 493: #undef PRECDIGIT
! 494:
! 495: static GEN
! 496: sd_seriesprecision(char *v, int flag)
! 497: {
! 498: char *msg[] = {NULL, "significant terms"};
! 499: return sd_numeric(v,flag,"seriesprecision",&precdl, 0,LGBITS,msg);
! 500: }
! 501:
! 502: static GEN
! 503: sd_format(char *v, int flag)
! 504: {
! 505: if (*v)
! 506: {
! 507: char c = *v;
! 508: if (c!='e' && c!='f' && c!='g')
! 509: err(talker2,"default: inexistent format",v,v);
! 510: fmt.format = c; v++;
! 511:
! 512: if (isdigit((int)*v))
! 513: { fmt.field=atol(v); while (isdigit((int)*v)) v++; }
! 514: if (*v++ == '.')
! 515: {
! 516: if (*v == '-') fmt.nb = -1;
! 517: else
! 518: if (isdigit((int)*v)) fmt.nb=atol(v);
! 519: }
! 520: }
! 521: if (flag == d_RETURN)
! 522: {
! 523: sprintf(thestring, "%c%ld.%ld", fmt.format, fmt.field, fmt.nb);
! 524: return strtoGENstr(thestring,0);
! 525: }
! 526: if (flag == d_ACKNOWLEDGE)
! 527: pariputsf(" format = %c%ld.%ld\n", fmt.format, fmt.field, fmt.nb);
! 528: return gnil;
! 529: }
! 530:
! 531: static long
! 532: gp_get_color(char **st)
! 533: {
! 534: char *s, *v = *st;
! 535: int c, trans;
! 536: if (isdigit((int)*v))
! 537: { c = atol(v); trans = 1; } /* color on transparent background */
! 538: else
! 539: {
! 540: if (*v == '[')
! 541: {
! 542: char *a[3];
! 543: int i = 0;
! 544: for (a[0] = s = ++v; *s && *s != ']'; s++)
! 545: if (*s == ',') { *s = 0; a[++i] = s+1; }
! 546: if (*s != ']') err(talker2,"expected character: ']'",s, *st);
! 547: *s = 0; for (i++; i<3; i++) a[i] = "";
! 548: /* properties | color | background */
! 549: c = (atoi(a[2])<<8) | atoi(a[0]) | (atoi(a[1])<<4);
! 550: trans = (*(a[1]) == 0);
! 551: v = s + 1;
! 552: }
! 553: else { c = c_NONE; trans = 0; }
! 554: }
! 555: if (trans) c = c | (1<<12);
! 556: while (*v && *v++ != ',') /* empty */;
! 557: if (c != c_NONE) disable_color=0;
! 558: *st = v; return c;
! 559: }
! 560:
! 561: static GEN
! 562: sd_colors(char *v, int flag)
! 563: {
! 564: long c,l;
! 565: if (*v && !under_emacs && !under_texmacs)
! 566: {
! 567: disable_color=1;
! 568: l = strlen(v);
! 569: if (l <= 2 && strncmp(v, "no", l) == 0)
! 570: v = "";
! 571: if (l <= 6 && strncmp(v, "darkbg", l) == 0)
! 572: v = "1, 5, 3, 7, 6, 2, 3"; /* Assume recent ReadLine. */
! 573: if (l <= 7 && strncmp(v, "lightbg", l) == 0)
! 574: v = "1, 6, 3, 4, 5, 2, 3"; /* Assume recent ReadLine. */
! 575: if (l <= 6 && strncmp(v, "boldfg", l) == 0) /* Good for darkbg consoles */
! 576: v = "[1,,1], [5,,1], [3,,1], [7,,1], [6,,1], [2,,1], [3,,1]";
! 577: v = filtre(v,NULL, f_INIT|f_REG);
! 578: for (c=c_ERR; c < c_LAST; c++)
! 579: gp_colors[c] = gp_get_color(&v);
! 580: }
! 581: if (flag == d_ACKNOWLEDGE || flag == d_RETURN)
! 582: {
! 583: char *s = thestring;
! 584: int col[3], n;
! 585: for (*s=0,c=c_ERR; c < c_LAST; c++)
! 586: {
! 587: n = gp_colors[c];
! 588: if (n == c_NONE)
! 589: sprintf(s,"no");
! 590: else
! 591: {
! 592: decode_color(n,col);
! 593: if (n & (1<<12))
! 594: {
! 595: if (col[0])
! 596: sprintf(s,"[%d,,%d]",col[1],col[0]);
! 597: else
! 598: sprintf(s,"%d",col[1]);
! 599: }
! 600: else
! 601: sprintf(s,"[%d,%d,%d]",col[1],col[2],col[0]);
! 602: }
! 603: s += strlen(s);
! 604: if (c < c_LAST - 1) { *s++=','; *s++=' '; }
! 605: }
! 606: if (flag==d_RETURN) return strtoGENstr(thestring,0);
! 607: pariputsf(" colors = \"%s\"\n",thestring);
! 608: }
! 609: return gnil;
! 610: }
! 611:
! 612: static GEN
! 613: sd_compatible(char *v, int flag)
! 614: {
! 615: char *msg[] = {
! 616: "(no backward compatibility)",
! 617: "(warn when using obsolete functions)",
! 618: "(use old functions, don't ignore case)",
! 619: "(use old functions, ignore case)", NULL
! 620: };
! 621: long old = compatible;
! 622: GEN r = sd_numeric(v,flag,"compatible",&compatible, 0,3,msg);
! 623:
! 624: if (old != compatible && flag != d_INITRC)
! 625: {
! 626: int res = gp_init_entrees(new_fun_set? pari_modules: pari_oldmodules,
! 627: functions_hash, 0);
! 628: if (res) err(warner,"user functions re-initialized");
! 629: }
! 630: return r;
! 631: }
! 632:
! 633: static GEN
! 634: sd_secure(char *v, int flag)
! 635: {
! 636: if (*v && secure)
! 637: {
! 638: fprintferr("[secure mode]: Do you want to modify the 'secure' flag? (^C if not)\n");
! 639: hit_return();
! 640: }
! 641: return sd_numeric(v,flag,"secure",&secure, 0,1,NULL);
! 642: }
! 643:
! 644: static GEN
! 645: sd_buffersize(char *v, int flag)
! 646: { return sd_numeric(v,flag,"buffersize",&paribufsize, 1,
! 647: (VERYBIGINT / sizeof(long)) - 1,NULL); }
! 648: static GEN
! 649: sd_debug(char *v, int flag)
! 650: { return sd_numeric(v,flag,"debug",&DEBUGLEVEL, 0,20,NULL); }
! 651:
! 652: static GEN
! 653: sd_rl(char *v, int flag)
! 654: {
! 655: #ifdef READLINE
! 656: # if 0 /* Works - even when init_readline() was called */
! 657: if (readline_init && *v == '0')
! 658: err(talker, "Too late to switch off readline mode");
! 659: # endif
! 660: if (!readline_init && *v && *v != '0') {
! 661: init_readline();
! 662: readline_init = 1;
! 663: }
! 664: return sd_numeric(v,flag,"readline",&use_readline, 0,20,NULL);
! 665: #else /* !( defined READLINE ) */
! 666: long dummy;
! 667: return sd_numeric(v,flag,"readline",&dummy, 0,20,NULL);
! 668: #endif
! 669: }
! 670:
! 671: static GEN
! 672: sd_debugfiles(char *v, int flag)
! 673: { return sd_numeric(v,flag,"debugfiles",&DEBUGFILES, 0,20,NULL); }
! 674:
! 675: static GEN
! 676: sd_debugmem(char *v, int flag)
! 677: { return sd_numeric(v,flag,"debugmem",&DEBUGMEM, 0,20,NULL); }
! 678:
! 679: static GEN
! 680: sd_echo(char *v, int flag)
! 681: { return sd_numeric(v,flag,"echo",&pariecho, 0,1,NULL); }
! 682:
! 683: static GEN
! 684: sd_lines(char *v, int flag)
! 685: { return sd_numeric(v,flag,"lines",&lim_lines, 0,VERYBIGINT,NULL); }
! 686:
! 687: static GEN
! 688: sd_histsize(char *v, int flag)
! 689: {
! 690: long n = histsize;
! 691: GEN r = sd_numeric(v,flag,"histsize",&n, 1,
! 692: (VERYBIGINT / sizeof(long)) - 1,NULL);
! 693: if (n != histsize)
! 694: {
! 695: long i = n*sizeof(GEN);
! 696: GEN *gg = (GEN *) gpmalloc(i); memset(gg,0,i);
! 697:
! 698: if (tglobal)
! 699: {
! 700: long k = (tglobal-1) % n;
! 701: long kmin = k - min(n,histsize), j = k;
! 702:
! 703: i = (tglobal-1) % histsize;
! 704: while (k > kmin)
! 705: {
! 706: gg[j] = hist[i];
! 707: hist[i] = NULL;
! 708: if (!i) i = histsize;
! 709: if (!j) j = n;
! 710: i--; j--; k--;
! 711: }
! 712: while (hist[i])
! 713: {
! 714: gunclone(hist[i]);
! 715: if (!i) i = histsize;
! 716: i--;
! 717: }
! 718: }
! 719: free((void*)hist); hist=gg; histsize=n;
! 720: }
! 721: return r;
! 722: }
! 723:
! 724: static GEN
! 725: sd_log(char *v, int flag)
! 726: {
! 727: long vlog = logfile? 1: 0, old = vlog;
! 728: GEN r = sd_numeric(v,flag,"log",&vlog, 0,1,NULL);
! 729: if (vlog != old)
! 730: {
! 731: if (vlog)
! 732: {
! 733: logfile = fopen(current_logfile, "a");
! 734: if (!logfile) err(openfiler,"logfile",current_logfile);
! 735: #ifndef WINCE
! 736: setbuf(logfile,(char *)NULL);
! 737: #endif
! 738: }
! 739: else
! 740: {
! 741: if (flag == d_ACKNOWLEDGE)
! 742: pariputsf(" [logfile was \"%s\"]\n", current_logfile);
! 743: fclose(logfile); logfile=NULL;
! 744: }
! 745: }
! 746: return r;
! 747: }
! 748:
! 749: static GEN
! 750: sd_output(char *v, int flag)
! 751: {
! 752: char *msg[] = {"(raw)", "(prettymatrix)", "(prettyprint)", "(external prettyprint)", NULL};
! 753: return sd_numeric(v,flag,"output",&prettyp, 0,3,msg);
! 754: }
! 755:
! 756: extern void err_clean();
! 757:
! 758: void
! 759: allocatemem0(unsigned long newsize)
! 760: {
! 761: parisize = allocatemoremem(newsize);
! 762: err_clean();
! 763: jump_to_buffer();
! 764: }
! 765:
! 766: static GEN
! 767: sd_parisize(char *v, int flag)
! 768: {
! 769: long n = parisize;
! 770: GEN r = sd_numeric(v,flag,"parisize",&n, 10000,VERYBIGINT,NULL);
! 771: if (n != parisize)
! 772: {
! 773: if (flag != d_INITRC) allocatemem0(n);
! 774: parisize = n;
! 775: }
! 776: return r;
! 777: }
! 778:
! 779: static GEN
! 780: sd_primelimit(char *v, int flag)
! 781: {
! 782: long n = primelimit;
! 783: GEN r = sd_numeric(v,flag,"primelimit",&n, 0,VERYBIGINT,NULL);
! 784: if (n != primelimit)
! 785: {
! 786: if (flag != d_INITRC)
! 787: {
! 788: byteptr ptr = initprimes(n);
! 789: free(diffptr); diffptr = ptr;
! 790: }
! 791: primelimit = n;
! 792: }
! 793: return r;
! 794: }
! 795:
! 796: static GEN
! 797: sd_simplify(char *v, int flag)
! 798: { return sd_numeric(v,flag,"simplify",&simplifyflag, 0,1,NULL); }
! 799:
! 800: static GEN
! 801: sd_strictmatch(char *v, int flag)
! 802: { return sd_numeric(v,flag,"strictmatch",&strictmatch, 0,1,NULL); }
! 803:
! 804: static GEN
! 805: sd_timer(char *v, int flag)
! 806: { return sd_numeric(v,flag,"timer",&chrono, 0,1,NULL); }
! 807:
! 808: static GEN
! 809: sd_filename(char *v, int flag, char *s, char **f)
! 810: {
! 811: if (*v)
! 812: {
! 813: char *old = *f;
! 814: v = expand_tilde(v);
! 815: do_strftime(v,thestring); free(v);
! 816: *f = pari_strdup(thestring); free(old);
! 817: }
! 818: if (flag == d_RETURN) return strtoGENstr(*f,0);
! 819: if (flag == d_ACKNOWLEDGE) pariputsf(" %s = \"%s\"\n",s,*f);
! 820: return gnil;
! 821: }
! 822:
! 823: static GEN
! 824: sd_logfile(char *v, int flag)
! 825: {
! 826: GEN r = sd_filename(v, flag, "logfile", ¤t_logfile);
! 827: if (*v && logfile)
! 828: {
! 829: fclose(logfile);
! 830: logfile = fopen(current_logfile, "a");
! 831: if (!logfile) err(openfiler,"logfile",current_logfile);
! 832: #ifndef WINCE
! 833: setbuf(logfile,(char *)NULL);
! 834: #endif
! 835: }
! 836: return r;
! 837: }
! 838:
! 839: static GEN
! 840: sd_psfile(char *v, int flag)
! 841: { return sd_filename(v, flag, "psfile", ¤t_psfile); }
! 842:
! 843: static void
! 844: err_secure(char *d, char *v)
! 845: { err(talker,"[secure mode]: can't modify '%s' default (to %s)",d,v); }
! 846:
! 847: static GEN
! 848: sd_help(char *v, int flag)
! 849: {
! 850: char *str;
! 851: if (*v)
! 852: {
! 853: if (secure) err_secure("help",v);
! 854: if (help_prg) free(help_prg);
! 855: help_prg = expand_tilde(v);
! 856: }
! 857: str = help_prg? help_prg: "none";
! 858: if (flag == d_RETURN) return strtoGENstr(str,0);
! 859: if (flag == d_ACKNOWLEDGE)
! 860: pariputsf(" help = \"%s\"\n", str);
! 861: return gnil;
! 862: }
! 863:
! 864: static GEN
! 865: sd_path(char *v, int flag)
! 866: {
! 867: if (*v)
! 868: {
! 869: char *old = path;
! 870: path = pari_strdup(v); free(old);
! 871: if (flag == d_INITRC) return gnil;
! 872: gp_expand_path(path);
! 873: }
! 874: if (flag == d_RETURN) return strtoGENstr(path,0);
! 875: if (flag == d_ACKNOWLEDGE)
! 876: pariputsf(" path = \"%s\"\n",path);
! 877: return gnil;
! 878: }
! 879:
! 880: static GEN
! 881: sd_prettyprinter(char *v, int flag)
! 882: {
! 883: if (*v && !under_texmacs)
! 884: {
! 885: char *old = prettyprinter;
! 886: int cancel = (!strcmp(v,"no"));
! 887:
! 888: if (secure) err_secure("prettyprinter",v);
! 889: if (!strcmp(v,"yes")) v = prettyprinter_dft;
! 890: if (old && strcmp(old,v) && prettyprinter_file)
! 891: {
! 892: pariFILE *f;
! 893: if (cancel) f = NULL;
! 894: else
! 895: {
! 896: f = try_pipe(v, mf_OUT | mf_TEST);
! 897: if (!f)
! 898: {
! 899: err(warner,"broken prettyprinter: '%s'",v);
! 900: return gnil;
! 901: }
! 902: }
! 903: pari_fclose(prettyprinter_file);
! 904: prettyprinter_file = f;
! 905: }
! 906: prettyprinter = cancel? NULL: pari_strdup(v);
! 907: if (old && old != prettyprinter_dft) free(old);
! 908: if (flag == d_INITRC) return gnil;
! 909: }
! 910: if (flag == d_RETURN) return strtoGEN(prettyprinter? prettyprinter: "");
! 911: if (flag == d_ACKNOWLEDGE)
! 912: pariputsf(" prettyprinter = \"%s\"\n",prettyprinter? prettyprinter: "");
! 913: return gnil;
! 914: }
! 915:
! 916: static GEN
! 917: sd_prompt(char *v, int flag)
! 918: {
! 919: if (*v)
! 920: {
! 921: strncpy(prompt,v,MAX_PROMPT_LEN);
! 922: #ifdef macintosh
! 923: strcat(prompt,"\n");
! 924: #endif
! 925: }
! 926: if (flag == d_RETURN) return strtoGENstr(prompt,0);
! 927: if (flag == d_ACKNOWLEDGE)
! 928: pariputsf(" prompt = \"%s\"\n",prompt);
! 929: return gnil;
! 930: }
! 931:
! 932: default_type gp_default_list[] =
! 933: {
! 934: {"buffersize",(void*)sd_buffersize},
! 935: {"colors",(void*)sd_colors},
! 936: {"compatible",(void*)sd_compatible},
! 937: {"debug",(void*)sd_debug},
! 938: {"debugfiles",(void*)sd_debugfiles},
! 939: {"debugmem",(void*)sd_debugmem},
! 940: {"echo",(void*)sd_echo},
! 941: {"format",(void*)sd_format},
! 942: {"help",(void*)sd_help},
! 943: {"histsize",(void*)sd_histsize},
! 944: {"lines",(void*)sd_lines},
! 945: {"log",(void*)sd_log},
! 946: {"logfile",(void*)sd_logfile},
! 947: {"output",(void*)sd_output},
! 948: {"parisize",(void*)sd_parisize},
! 949: {"path",(void*)sd_path},
! 950: {"primelimit",(void*)sd_primelimit},
! 951: {"prettyprinter",(void*)sd_prettyprinter},
! 952: {"prompt",(void*)sd_prompt},
! 953: {"psfile",(void*)sd_psfile},
! 954: {"realprecision",(void*)sd_realprecision},
! 955: {"readline",(void*)sd_rl},
! 956: {"secure",(void*)sd_secure},
! 957: {"seriesprecision",(void*)sd_seriesprecision},
! 958: {"simplify",(void*)sd_simplify},
! 959: {"strictmatch",(void*)sd_strictmatch},
! 960: {"timer",(void *)sd_timer},
! 961: {NULL,NULL} /* sentinel */
! 962: };
! 963:
! 964: static void
! 965: help_default()
! 966: {
! 967: default_type *dft;
! 968:
! 969: for (dft=gp_default_list; dft->fun; dft++)
! 970: ((void (*)(ANYARG)) dft->fun)("", d_ACKNOWLEDGE);
! 971: }
! 972:
! 973: static GEN
! 974: setdefault(char *s,char *v, int flag)
! 975: {
! 976: default_type *dft;
! 977:
! 978: if (!*s) { help_default(); return gnil; }
! 979: for (dft=gp_default_list; dft->fun; dft++)
! 980: if (!strcmp(s,dft->name))
! 981: {
! 982: if (flag == d_EXISTS) return gun;
! 983: return ((GEN (*)(ANYARG)) dft->fun)(v,flag);
! 984: }
! 985: if (flag == d_EXISTS) return gzero;
! 986: err(talker,"unknown default: %s",s);
! 987: return NULL; /* not reached */
! 988: }
! 989:
! 990: /********************************************************************/
! 991: /** **/
! 992: /** HELP **/
! 993: /** **/
! 994: /********************************************************************/
! 995: static int
! 996: has_ext_help()
! 997: {
! 998: if (help_prg)
! 999: {
! 1000: char *buf = pari_strdup(help_prg), *s = buf;
! 1001: FILE *file;
! 1002:
! 1003: while (*s && *s != ' ') s++;
! 1004: *s = 0; file = fopen(buf,"r");
! 1005: if (file) { fclose(file); return 1; }
! 1006: free(buf);
! 1007: }
! 1008: return 0;
! 1009: }
! 1010:
! 1011: static int
! 1012: compare_str(char **s1, char **s2) { return strcmp(*s1, *s2); }
! 1013:
! 1014: /* Print all elements of list in columns, pausing every nbli lines
! 1015: * if nbli is non-zero.
! 1016: * list is a NULL terminated list of function names
! 1017: */
! 1018: void
! 1019: print_fun_list(char **list, int nbli)
! 1020: {
! 1021: long i=0, j=0, maxlen=0, nbcol,len, w = term_width();
! 1022: char **l;
! 1023:
! 1024: while (list[i]) i++;
! 1025: qsort (list, i, sizeof(char *), (QSCOMP)compare_str);
! 1026:
! 1027: for (l=list; *l; l++)
! 1028: {
! 1029: len = strlen(*l);
! 1030: if (len > maxlen) maxlen=len;
! 1031: }
! 1032: maxlen++; nbcol= w / maxlen;
! 1033: if (nbcol * maxlen == w) nbcol--;
! 1034: if (!nbcol) nbcol = 1;
! 1035:
! 1036: pariputc('\n'); i=0;
! 1037: for (l=list; *l; l++)
! 1038: {
! 1039: pariputs(*l); i++;
! 1040: if (i >= nbcol)
! 1041: {
! 1042: i=0; pariputc('\n');
! 1043: if (nbli && j++ > nbli) { j = 0; hit_return(); }
! 1044: continue;
! 1045: }
! 1046: len = maxlen - strlen(*l);
! 1047: while (len--) pariputc(' ');
! 1048: }
! 1049: if (i) pariputc('\n');
! 1050: }
! 1051:
! 1052: #define LIST_LEN 1023
! 1053: static void
! 1054: commands(int n)
! 1055: {
! 1056: int hashpos, s = 0, olds = LIST_LEN;
! 1057: entree *ep;
! 1058: char **list = (char **) gpmalloc((olds+1)*sizeof(char *));
! 1059:
! 1060: for (hashpos = 0; hashpos < functions_tblsz; hashpos++)
! 1061: for (ep = functions_hash[hashpos]; ep; ep = ep->next)
! 1062: if ((n<0 && ep->menu) || ep->menu == n)
! 1063: {
! 1064: list[s++] = ep->name;
! 1065: if (s >= olds)
! 1066: {
! 1067: int news = olds + (LIST_LEN + 1)*sizeof(char *);
! 1068: list = (char**) gprealloc(list,news,olds);
! 1069: olds = news;
! 1070: }
! 1071: }
! 1072: list[s]=NULL; print_fun_list(list,term_height()-4); free(list);
! 1073: }
! 1074:
! 1075: static void
! 1076: print_def_arg(GEN x)
! 1077: {
! 1078: if (x == gzero) return;
! 1079: pariputc('=');
! 1080: if (typ(x)==t_STR)
! 1081: pariputs(GSTR(x)); /* otherwise it's surrounded by "" */
! 1082: else
! 1083: bruteall(x,'g',-1,1);
! 1084: }
! 1085:
! 1086: static void
! 1087: print_user_fun(entree *ep)
! 1088: {
! 1089: gp_args *f= (gp_args*)ep->args;
! 1090: GEN q = (GEN)ep->value, *arg = f->arg;
! 1091: int i, narg;
! 1092:
! 1093: q++; /* skip initial NULL */
! 1094: pariputs(ep->name); pariputc('(');
! 1095: narg = f->narg;
! 1096: for (i=1; i<=narg; i++, arg++)
! 1097: {
! 1098: entree *ep = varentries[*q++];
! 1099: pariputs(ep? ep->name:"#");
! 1100: print_def_arg(*arg);
! 1101: if (i == narg) { arg++; break; }
! 1102: pariputs(", ");
! 1103: }
! 1104: pariputs(") = ");
! 1105: narg = f->nloc;
! 1106: if (narg)
! 1107: {
! 1108: pariputs("local(");
! 1109: for (i=1; i<=narg; i++, arg++)
! 1110: {
! 1111: entree *ep = varentries[*q++];
! 1112: pariputs(ep? ep->name:"#");
! 1113: print_def_arg(*arg);
! 1114: if (i == narg) break;
! 1115: pariputs(", ");
! 1116: }
! 1117: pariputs("); ");
! 1118: }
! 1119: pariputs((char*)q);
! 1120: }
! 1121:
! 1122: static void
! 1123: print_user_member(entree *ep)
! 1124: {
! 1125: GEN q = (GEN)ep->value;
! 1126: entree *ep2;
! 1127:
! 1128: q++; /* skip initial NULL */
! 1129: ep2 = varentries[*q++];
! 1130: pariputs(ep2? ep2->name:"#");
! 1131: pariputsf(".%s = ", ep->name);
! 1132: pariputs((char*)q);
! 1133: }
! 1134:
! 1135: static void
! 1136: user_fun()
! 1137: {
! 1138: entree *ep;
! 1139: int hash;
! 1140:
! 1141: for (hash = 0; hash < functions_tblsz; hash++)
! 1142: for (ep = functions_hash[hash]; ep; ep = ep->next)
! 1143: if (EpVALENCE(ep) == EpUSER)
! 1144: {
! 1145: pariputc(LBRACE); print_user_fun(ep);
! 1146: pariputc(RBRACE); pariputs("\n\n");
! 1147: }
! 1148: }
! 1149:
! 1150: static void
! 1151: user_member()
! 1152: {
! 1153: entree *ep;
! 1154: int hash;
! 1155:
! 1156: for (hash = 0; hash < functions_tblsz; hash++)
! 1157: for (ep = members_hash[hash]; ep; ep = ep->next)
! 1158: if (EpVALENCE(ep) == EpMEMBER)
! 1159: {
! 1160: pariputc(LBRACE); print_user_member(ep);
! 1161: pariputc(RBRACE); pariputs("\n\n");
! 1162: }
! 1163: }
! 1164:
! 1165: static void
! 1166: center(char *s)
! 1167: {
! 1168: long i, pad = term_width() - strlen(s);
! 1169: char *u = thestring;
! 1170:
! 1171: if (pad<0) pad=0; else pad >>= 1;
! 1172: for (i=0; i<pad; i++) *u++ = ' ';
! 1173: while (*s) *u++ = *s++;
! 1174: *u++='\n'; *u=0; pariputs(thestring);
! 1175: }
! 1176:
! 1177: static void
! 1178: community()
! 1179: {
! 1180: long len = strlen(GPMISCDIR) + 1024;
! 1181: char *s = gpmalloc(len);
! 1182:
! 1183: sprintf(s, "The standard distribution of GP/PARI includes a reference \
! 1184: manual, a tutorial, a reference card and quite a few examples. They should \
! 1185: have been installed in the directory '%s'. If not you should ask the person \
! 1186: who installed PARI on your system where they can be found. You can also \
! 1187: download them from the PARI WWW site 'http://www.parigp-home.de/'",
! 1188: GPMISCDIR);
! 1189: print_text(s); free(s);
! 1190:
! 1191: pariputs("\nThree mailing lists are devoted to PARI:\n\
! 1192: - pari-announce (moderated) to announce major version changes.\n\
! 1193: - pari-dev for everything related to the development of PARI, including\n\
! 1194: suggestions, technical questions, bug reports and patch submissions.\n\
! 1195: - pari-users for everything else!\n");
! 1196: print_text("\
! 1197: To subscribe, send an empty message to <listname>-subscribe@list.cr.yp.to. You \
! 1198: can only send messages to the lists you have subscribed to! An archive is kept \
! 1199: at the WWW site mentioned above. You can also reach the authors directly by \
! 1200: email: pari@math.u-bordeaux.fr (answer not guaranteed)."); }
! 1201:
! 1202: static void
! 1203: gentypes(void)
! 1204: {
! 1205: pariputs("List of the PARI types:\n\
! 1206: t_INT : long integers [ cod1 ] [ cod2 ] [ man_1 ] ... [ man_k ]\n\
! 1207: t_REAL : long real numbers [ cod1 ] [ cod2 ] [ man_1 ] ... [ man_k ]\n\
! 1208: t_INTMOD : integermods [ code ] [ mod ] [ integer ]\n\
! 1209: t_FRAC : irred. rationals [ code ] [ num. ] [ den. ]\n\
! 1210: t_FRACN : rational numbers [ code ] [ num. ] [ den. ]\n\
! 1211: t_COMPLEX: complex numbers [ code ] [ real ] [ imag ]\n\
! 1212: t_PADIC : p-adic numbers [ cod1 ] [ cod2 ] [ p ] [ p^r ] [ int ]\n\
! 1213: t_QUAD : quadratic numbers [ cod1 ] [ mod ] [ real ] [ imag ]\n\
! 1214: t_POLMOD : poly mod [ code ] [ mod ] [ polynomial ]\n\
! 1215: -------------------------------------------------------------\n\
! 1216: t_POL : polynomials [ cod1 ] [ cod2 ] [ man_1 ] ... [ man_k ]\n\
! 1217: t_SER : power series [ cod1 ] [ cod2 ] [ man_1 ] ... [ man_k ]\n\
! 1218: t_RFRAC : irred. rat. func. [ code ] [ num. ] [ den. ]\n\
! 1219: t_RFRACN : rational function [ code ] [ num. ] [ den. ]\n\
! 1220: t_QFR : real qfb [ code ] [ a ] [ b ] [ c ] [ del ]\n\
! 1221: t_QFI : imaginary qfb [ code ] [ a ] [ b ] [ c ]\n\
! 1222: t_VEC : row vector [ code ] [ x_1 ] ... [ x_k ]\n\
! 1223: t_COL : column vector [ code ] [ x_1 ] ... [ x_k ]\n\
! 1224: t_MAT : matrix [ code ] [ col_1 ] ... [ col_k ]\n\
! 1225: t_LIST : list [ code ] [ cod2 ] [ x_1 ] ... [ x_k ]\n\
! 1226: t_STR : string [ code ] [ man_1 ] ... [ man_k ]\n\
! 1227: \n");
! 1228: }
! 1229:
! 1230: static void
! 1231: menu_commands(void)
! 1232: {
! 1233: pariputs("Help topics:\n\
! 1234: 0: list of user-defined identifiers (variable, alias, function)\n\
! 1235: 1: Standard monadic or dyadic OPERATORS\n\
! 1236: 2: CONVERSIONS and similar elementary functions\n\
! 1237: 3: TRANSCENDENTAL functions\n\
! 1238: 4: NUMBER THEORETICAL functions\n\
! 1239: 5: Functions related to ELLIPTIC CURVES\n\
! 1240: 6: Functions related to general NUMBER FIELDS\n\
! 1241: 7: POLYNOMIALS and power series\n\
! 1242: 8: Vectors, matrices, LINEAR ALGEBRA and sets\n\
! 1243: 9: SUMS, products, integrals and similar functions\n\
! 1244: 10: GRAPHIC functions\n\
! 1245: 11: PROGRAMMING under GP\n\
! 1246: 12: The PARI community\n\
! 1247: \n\
! 1248: Further help (list of relevant functions): ?n (1<=n<=11).\n\
! 1249: Also:\n\
! 1250: ? functionname (short on-line help)\n\
! 1251: ?\\ (keyboard shortcuts)\n\
! 1252: ?. (member functions)\n");
! 1253: if (has_ext_help()) pariputs("\
! 1254: Extended help looks available:\n\
! 1255: ?? (opens the full user's manual in a dvi previewer)\n\
! 1256: ?? tutorial (same with the GP tutorial)\n\
! 1257: ?? refcard (same with the GP reference card)\n\
! 1258: \n\
! 1259: ?? keyword (long help text about \"keyword\" from the user's manual)\n\
! 1260: ??? keyword (a propos: list of related functions).");
! 1261: }
! 1262:
! 1263: static void
! 1264: slash_commands(void)
! 1265: {
! 1266: pariputs("# : enable/disable timer\n\
! 1267: ## : print time for last result\n\
! 1268: \\\\ : comment up to end of line\n\
! 1269: \\a {n} : print result in raw format (readable by PARI)\n\
! 1270: \\b {n} : print result in beautified format\n\
! 1271: \\c : list all commands (same effect as ?*)\n\
! 1272: \\d : print all defaults\n\
! 1273: \\e {n} : enable/disable echo (set echo=n)\n\
! 1274: \\g {n} : set debugging level\n\
! 1275: \\gf{n} : set file debugging level\n\
! 1276: \\gm{n} : set memory debugging level\n\
! 1277: \\h {m-n}: hashtable information\n\
! 1278: \\l {f} : enable/disable logfile (set logfile=f)\n\
! 1279: \\m {n} : print result in prettymatrix format\n\
! 1280: \\o {n} : change output method (0=raw, 1=prettymatrix, 2=prettyprint)\n\
! 1281: \\p {n} : change real precision\n\
! 1282: \\ps{n} : change series precision\n\
! 1283: \\q : quit completely this GP session\n\
! 1284: \\r {f} : read in a file\n\
! 1285: \\s {n} : print stack information\n\
! 1286: \\t : print the list of PARI types\n\
! 1287: \\u : print the list of user-defined functions\n\
! 1288: \\um : print the list of user-defined member functions\n\
! 1289: \\v : print current version of GP\n\
! 1290: \\w {nf} : write to a file\n\
! 1291: \\x {n} : print complete inner structure of result\n\
! 1292: \\y {n} : disable/enable automatic simplification (set simplify=n)\n\
! 1293: \n\
! 1294: {f}=optional filename. {n}=optional integer\n");
! 1295: }
! 1296:
! 1297: static void
! 1298: member_commands(void)
! 1299: {
! 1300: pariputs("Member functions, followed by relevant objects\n\n\
! 1301: a1-a6, b2-b8, c4-c6 : coeff. of the curve. ell\n\
! 1302: area : area ell\n\
! 1303: bnf : big number field bnf, bnr\n\
! 1304: clgp : class group bnf, bnr\n\
! 1305: cyc : cyclic decomposition (SNF) clgp bnf, bnr\n\
! 1306: diff, codiff: different and codifferent nf, bnf, bnr\n\
! 1307: disc : discriminant ell, nf, bnf, bnr\n\
! 1308: e, f : inertia/residues degree prid\n\
! 1309: fu : fundamental units bnf, bnr\n\
! 1310: futu : [u,w] where u=unit group, w=torsion bnf, bnr\n\
! 1311: gen : generators prid, clgp bnf, bnr\n\
! 1312: j : j-invariant ell\n\
! 1313: mod : modulus\n\
! 1314: nf : number field bnf, bnr\n\
! 1315: no : number of elements clgp bnf, bnr\n\
! 1316: omega, eta: [omega1,omega2] and [eta1, eta2] ell\n\
! 1317: p : rational prime contained in prid prid\n\
! 1318: pol : defining polynomial nf, bnf, bnr\n\
! 1319: reg : regulator bnf, bnr\n\
! 1320: roots: roots ell nf, bnf, bnr\n\
! 1321: sign : signature nf, bnf, bnr\n\
! 1322: t2 : t2 matrix nf, bnf, bnr\n\
! 1323: tate : Tate's [u^2,u,q] ell\n\
! 1324: tu : torsion unit and its order bnf, bnr\n\
! 1325: tufu : [w,u] where u=unit group, w=torsion bnf, bnr\n\
! 1326: w : Mestre's w ell\n\
! 1327: zk : integral basis nf, bnf, bnr\n\
! 1328: zkst : structure of (Z_K/m)^* (valid for idealstar also) bnr\n");
! 1329: }
! 1330:
! 1331: #define QUOTE "_QUOTE"
! 1332: #define DOUBQUOTE "_DOUBQUOTE"
! 1333: #define BACKQUOTE "_BACKQUOTE"
! 1334:
! 1335: static char *
! 1336: _cat(char *s, char *t)
! 1337: {
! 1338: *s = 0; strcat(s,t); return s + strlen(t);
! 1339: }
! 1340:
! 1341: static char *
! 1342: filter_quotes(char *s)
! 1343: {
! 1344: int i, l = strlen(s);
! 1345: int quote = 0;
! 1346: int backquote = 0;
! 1347: int doubquote = 0;
! 1348: char *str, *t;
! 1349:
! 1350: for (i=0; i < l; i++)
! 1351: switch(s[i])
! 1352: {
! 1353: case '\'': quote++; break;
! 1354: case '`' : backquote++; break;
! 1355: case '"' : doubquote++;
! 1356: }
! 1357: str = (char*)gpmalloc(l + quote * (strlen(QUOTE)-1)
! 1358: + doubquote * (strlen(DOUBQUOTE)-1)
! 1359: + backquote * (strlen(BACKQUOTE)-1) + 1);
! 1360: t = str;
! 1361: for (i=0; i < l; i++)
! 1362: switch(s[i])
! 1363: {
! 1364: case '\'': t = _cat(t, QUOTE); break;
! 1365: case '`' : t = _cat(t, BACKQUOTE); break;
! 1366: case '"' : t = _cat(t, DOUBQUOTE); break;
! 1367: default: *t++ = s[i];
! 1368: }
! 1369: *t = 0; return str;
! 1370: }
! 1371:
! 1372: #define MAX_LINE_LEN 255
! 1373: static void
! 1374: external_help(char *s, int num)
! 1375: {
! 1376: long nbli = term_height()-3, li = 0;
! 1377: char buf[MAX_LINE_LEN+1], *str, *opt = "", *ar = "";
! 1378: pariFILE *z;
! 1379: FILE *f;
! 1380:
! 1381: if (!help_prg) err(talker,"no external help program");
! 1382: s = filter_quotes(s);
! 1383: str = gpmalloc(strlen(help_prg) + strlen(s) + 64);
! 1384: if (num < 0)
! 1385: opt = "-k";
! 1386: else if (s[strlen(s)-1] != '@')
! 1387: { ar = thestring; sprintf(ar,"@%d",num); }
! 1388: sprintf(str,"%s -fromgp %s %c%s%s%c",help_prg,opt, SHELL_Q,s,ar,SHELL_Q);
! 1389: z = try_pipe(str,0); f = z->file;
! 1390: free(str); free(s);
! 1391: while (fgets(buf,MAX_LINE_LEN,f))
! 1392: {
! 1393: if (!strncmp("ugly_kludge_done",buf,16)) break;
! 1394: buf[MAX_LINE_LEN]=0; pariputs(buf);
! 1395: if (++li > nbli) { hit_return(); li = 0; }
! 1396: }
! 1397: pari_fclose(z);
! 1398: }
! 1399:
! 1400: char *keyword_list[]={
! 1401: "operator",
! 1402: "user",
! 1403: "member",
! 1404: "integer",
! 1405: "real",
! 1406: "readline",
! 1407: "refcard",
! 1408: "tutorial",
! 1409: "nf",
! 1410: "bnf",
! 1411: "bnr",
! 1412: "ell",
! 1413: NULL
! 1414: };
! 1415:
! 1416: static int
! 1417: ok_external_help(char *s)
! 1418: {
! 1419: long n;
! 1420: if (!*s) return 1;
! 1421: if (!isalpha((int)*s)) return 3; /* operator or section number */
! 1422: if (!strncmp(s,"t_",2)) return 2; /* type name */
! 1423:
! 1424: for (n=0; keyword_list[n]; n++)
! 1425: if (!strcmp(s,keyword_list[n])) return 3;
! 1426: return 0;
! 1427: }
! 1428:
! 1429: /* don't mess readline display */
! 1430: static void
! 1431: aide_print(char *s1, char *s2, int flag)
! 1432: {
! 1433: if ((flag & h_RL) == 0) err(talker, "%s: %s", s1, s2);
! 1434: pariputsf("%s: %s\n", s1, s2);
! 1435: }
! 1436:
! 1437: static void
! 1438: aide0(char *s, int flag)
! 1439: {
! 1440: long n, long_help = flag & h_LONG;
! 1441: entree *ep,*ep1;
! 1442: char *s1;
! 1443:
! 1444: s = get_sep(s);
! 1445: if (isdigit((int)*s))
! 1446: {
! 1447: n=atoi(s);
! 1448: if (n == 12) { community(); return; }
! 1449: if (n<0 || n > 12)
! 1450: err(talker2,"no such section in help: ?",s,s);
! 1451: if (long_help) external_help(s,3); else commands(n);
! 1452: return;
! 1453: }
! 1454: /* Get meaningful entry on \ps 5 */
! 1455: if (*s == '\\') { s1 = s+1; skip_alpha(s1); *s1 = '\0';}
! 1456:
! 1457: if (flag & h_APROPOS) { external_help(s,-1); return; }
! 1458: if (long_help && (n = ok_external_help(s))) { external_help(s,n); return; }
! 1459: switch (*s)
! 1460: {
! 1461: case '*' : commands(-1); return;
! 1462: case '\0': menu_commands(); return;
! 1463: case '\\': slash_commands(); return;
! 1464: case '.' : member_commands(); return;
! 1465: }
! 1466: ep = is_entry(s);
! 1467: if (ep && long_help)
! 1468: {
! 1469: if (!strcmp(ep->name, "default"))
! 1470: {
! 1471: char *t = s+7, *e;
! 1472: skip_space(t);
! 1473: if (*t == '(') {
! 1474: t++; skip_space(t);
! 1475: e = t; skip_alpha(e); *e = '\0'; /* safe: get_sep() made it a copy */
! 1476: if (is_default(t)) { external_help(t, 2); return; }
! 1477: }
! 1478: }
! 1479: }
! 1480: if (!ep)
! 1481: {
! 1482: n = is_default(s)? 2: 3;
! 1483: if (long_help)
! 1484: external_help(s,n);
! 1485: else
! 1486: {
! 1487: if (n == 2) { aide_print(s,"default",h_RL); return; }
! 1488: n = whatnow(s,1);
! 1489: if (n) err(obsoler,s,s, s,n);
! 1490: aide_print(s,"unknown identifier",flag);
! 1491: }
! 1492: return;
! 1493: }
! 1494:
! 1495: ep1 = ep; ep = do_alias(ep);
! 1496: if (ep1 != ep) pariputsf("%s is aliased to:\n\n",s);
! 1497:
! 1498: switch(EpVALENCE(ep))
! 1499: {
! 1500: case EpUSER:
! 1501: if (!ep->help || long_help) print_user_fun(ep);
! 1502: if (!ep->help) return;
! 1503: if (long_help) { pariputs("\n\n"); long_help=0; }
! 1504: break;
! 1505:
! 1506: case EpGVAR:
! 1507: case EpVAR:
! 1508: if (!ep->help) { aide_print(s, "user defined variable",h_RL); return; }
! 1509: long_help=0; break;
! 1510:
! 1511: case EpINSTALL:
! 1512: if (!ep->help) { aide_print(s, "installed function",h_RL); return; }
! 1513: long_help=0; break;
! 1514: }
! 1515: if (long_help) { external_help(ep->name,3); return; }
! 1516: if (ep->help) { print_text(ep->help); return; }
! 1517:
! 1518: err(bugparier,"aide (no help found)");
! 1519: }
! 1520:
! 1521: void
! 1522: aide(char *s, int flag)
! 1523: {
! 1524: if ((flag & h_RL) == 0)
! 1525: {
! 1526: if (*s == '?') { flag |= h_LONG; s++; }
! 1527: if (*s == '?') { flag |= h_APROPOS; s++; }
! 1528: }
! 1529: term_color(c_HELP); aide0(s,flag); term_color(c_NONE);
! 1530: if ((flag & h_RL) == 0) pariputc('\n');
! 1531: }
! 1532:
! 1533: /********************************************************************/
! 1534: /** **/
! 1535: /** METACOMMANDS **/
! 1536: /** **/
! 1537: /********************************************************************/
! 1538:
! 1539: static void
! 1540: print_entree(entree *ep, long hash)
! 1541: {
! 1542: pariputsf(" %s ",ep->name); pariputsf(VOIR_STRING1,(ulong)ep);
! 1543: pariputsf(":\n hash = %3ld, valence = %3ld, menu = %2ld, code = %s\n",
! 1544: hash, ep->valence, ep->menu, ep->code? ep->code: "NULL");
! 1545: if (ep->next)
! 1546: {
! 1547: pariputsf(" next = %s ",(ep->next)->name);
! 1548: pariputsf(VOIR_STRING1,(ulong)(ep->next));
! 1549: }
! 1550: pariputs("\n");
! 1551: }
! 1552:
! 1553: static void
! 1554: print_hash_list(char *s)
! 1555: {
! 1556: long m,n;
! 1557: entree *ep;
! 1558:
! 1559: if (isalpha((int)*s))
! 1560: {
! 1561: ep = is_entry_intern(s,functions_hash,&n);
! 1562: if (!ep) err(talker,"no such function");
! 1563: print_entree(ep,n); return;
! 1564: }
! 1565: if (isdigit((int)*s) || *s == '$')
! 1566: {
! 1567: m = functions_tblsz-1; n = atol(s);
! 1568: if (*s=='$') n = m;
! 1569: if (m<n) err(talker,"invalid range in print_entree");
! 1570: while (isdigit((int)*s)) s++;
! 1571:
! 1572: if (*s++ != '-') m = n;
! 1573: else
! 1574: {
! 1575: if (*s !='$') m = min(atol(s),m);
! 1576: if (m<n) err(talker,"invalid range in print_entree");
! 1577: }
! 1578:
! 1579: for(; n<=m; n++)
! 1580: {
! 1581: pariputsf("*** hashcode = %ld\n",n);
! 1582: for (ep=functions_hash[n]; ep; ep=ep->next)
! 1583: print_entree(ep,n);
! 1584: }
! 1585: return;
! 1586: }
! 1587: if (*s=='-')
! 1588: {
! 1589: for (n=0; n<functions_tblsz; n++)
! 1590: {
! 1591: m=0;
! 1592: for (ep=functions_hash[n]; ep; ep=ep->next) m++;
! 1593: pariputsf("%3ld:%3ld ",n,m);
! 1594: if (n%9 == 8) pariputc('\n');
! 1595: }
! 1596: pariputc('\n'); return;
! 1597: }
! 1598: for (n=0; n<functions_tblsz; n++)
! 1599: for (ep=functions_hash[n]; ep; ep=ep->next)
! 1600: print_entree(ep,n);
! 1601: }
! 1602:
! 1603: static char *
! 1604: what_readline()
! 1605: {
! 1606: #ifdef READLINE
! 1607: if (use_readline)
! 1608: return "v"READLINE" enabled";
! 1609: else
! 1610: #endif
! 1611: return "disabled";
! 1612: }
! 1613:
! 1614: static void
! 1615: print_version()
! 1616: {
! 1617: char buf[64];
! 1618:
! 1619: center(PARIVERSION); center(PARIINFO);
! 1620: sprintf(buf,"(readline %s, extended help%s available)", what_readline(),
! 1621: has_ext_help()? "": " not");
! 1622: center(buf);
! 1623: }
! 1624:
! 1625: static void
! 1626: gp_head()
! 1627: {
! 1628: print_version(); pariputs("\n");
! 1629: center("Copyright (C) 2000 The PARI Group");
! 1630: print_text("\nPARI/GP is free software, covered by the GNU General Public \
! 1631: License, and comes WITHOUT ANY WARRANTY WHATSOEVER");
! 1632: pariputs("\n\
! 1633: Type ? for help, \\q to quit.\n\
! 1634: Type ?12 for how to get moral (and possibly technical) support.\n\n");
! 1635: sd_realprecision ("",d_ACKNOWLEDGE);
! 1636: sd_seriesprecision("",d_ACKNOWLEDGE);
! 1637: sd_format ("",d_ACKNOWLEDGE);
! 1638: pariputsf("\nparisize = %ld, primelimit = %ld\n", parisize, primelimit);
! 1639: }
! 1640:
! 1641: static void
! 1642: fix_buffer(Buffer *b, long newlbuf)
! 1643: {
! 1644: b->buf = gprealloc(b->buf, newlbuf, b->len);
! 1645: b->len = paribufsize = newlbuf;
! 1646: }
! 1647:
! 1648: void
! 1649: gp_quit()
! 1650: {
! 1651: free_graph(); freeall();
! 1652: kill_all_buffers(NULL);
! 1653: if (INIT_SIG) pari_sig_init(SIG_DFL);
! 1654: term_color(c_NONE);
! 1655: pariputs_opt("Goodbye!\n");
! 1656: if (under_texmacs) tm_end_output();
! 1657: exit(0);
! 1658: }
! 1659:
! 1660: /* history management function:
! 1661: * flag < 0, called from freeall()
! 1662: * flag = 0, called from %num in anal.c:truc()
! 1663: * flag > 0, called from %` in anal.c:truc(), p > 0
! 1664: */
! 1665: static GEN
! 1666: gp_history(long p, long flag, char *old, char *entrypoint)
! 1667: {
! 1668: int er1 = 0;
! 1669: if (flag < 0) { free((void *)hist); return NULL; }
! 1670: if (!tglobal) er1 = 1;
! 1671: if (flag)
! 1672: {
! 1673: p = tglobal - p;
! 1674: if (p <= 0) er1 = 1;
! 1675: }
! 1676: else if (p > tglobal)
! 1677: err(talker2,"I can't see into the future",old,entrypoint);
! 1678: if (!p) p = tglobal;
! 1679: if (tglobal - p >= histsize) er1 = 1;
! 1680: p = (p-1) % histsize;
! 1681: if (er1 || !hist[p])
! 1682: err(talker2,"I can't remember before the big bang",old,entrypoint);
! 1683: return hist[p];
! 1684: }
! 1685:
! 1686: extern char *GENtostr0(GEN x, void(*do_out)(GEN));
! 1687:
! 1688: static void
! 1689: texmacs_output(GEN z, long n)
! 1690: {
! 1691: char *sz = GENtostr0(z, &outtex);
! 1692: printf("%clatex:", DATA_BEGIN);
! 1693: printf("\\magenta\\%%%ld = $\\blue ", n);
! 1694: printf("%s$%c", sz,DATA_END); free(sz);
! 1695: fflush(stdout);
! 1696: }
! 1697:
! 1698: /* Wait for prettyprinter for finish, to prevent new prompt from overwriting
! 1699: * the output. Fill the output buffer, wait until it is read.
! 1700: * Better than sleep(2): give possibility to print */
! 1701: static void
! 1702: prettyp_wait()
! 1703: {
! 1704: char *s = " \n";
! 1705: int i = 400;
! 1706:
! 1707: pariputs("\n\n"); pariflush(); /* start translation */
! 1708: while (--i) pariputs(s);
! 1709: pariputs("\n"); pariflush();
! 1710: }
! 1711:
! 1712: /* initialise external prettyprinter (tex2mail) */
! 1713: static int
! 1714: prettyp_init()
! 1715: {
! 1716: if (!prettyprinter_file)
! 1717: prettyprinter_file = try_pipe(prettyprinter, mf_OUT | mf_TEST);
! 1718: if (prettyprinter_file) return 1;
! 1719:
! 1720: err(warner,"broken prettyprinter: '%s'",prettyprinter);
! 1721: if (prettyprinter != prettyprinter_dft) free(prettyprinter);
! 1722: prettyprinter = NULL; return 0;
! 1723: }
! 1724:
! 1725: /* n = history number. if n = 0 no history */
! 1726: static int
! 1727: tex2mail_output(GEN z, long n)
! 1728: {
! 1729: FILE *o_out;
! 1730: int o_prettyp;
! 1731:
! 1732: if (!(prettyprinter && prettyp_init())) return 0;
! 1733: o_out = pari_outfile; /* save state */
! 1734: o_prettyp = prettyp;
! 1735:
! 1736: /* Emit first: there may be lines before the prompt */
! 1737: if (n) term_color(c_OUTPUT);
! 1738: pariflush();
! 1739: pari_outfile = prettyprinter_file->file;
! 1740: prettyp = f_TEX;
! 1741:
! 1742: /* history number */
! 1743: if (n)
! 1744: {
! 1745: if (*term_get_color(c_HIST) || *term_get_color(c_OUTPUT))
! 1746: {
! 1747: char col1[80];
! 1748: strcpy(col1, term_get_color(c_HIST));
! 1749: sprintf(thestring, "\\LITERALnoLENGTH{%s}\\%%%ld = \\LITERALnoLENGTH{%s}",
! 1750: col1, n, term_get_color(c_OUTPUT));
! 1751: }
! 1752: else
! 1753: sprintf(thestring, "\\%%%ld = ", n);
! 1754: pariputs_opt(thestring);
! 1755: }
! 1756: /* output */
! 1757: gp_output(z);
! 1758:
! 1759: /* flush and restore */
! 1760: prettyp_wait();
! 1761: prettyp = o_prettyp;
! 1762: pari_outfile = o_out;
! 1763: if (n) term_color(c_NONE);
! 1764: return 1;
! 1765: }
! 1766:
! 1767: static void
! 1768: normal_output(GEN z, long n)
! 1769: {
! 1770: /* history number */
! 1771: term_color(c_HIST);
! 1772: sprintf(thestring, "%%%ld = ", n);
! 1773: pariputs_opt(thestring);
! 1774: /* output */
! 1775: term_color(c_OUTPUT);
! 1776: init_lim_lines(thestring,lim_lines);
! 1777: gp_output(z);
! 1778: init_lim_lines(NULL,lim_lines);
! 1779: term_color(c_NONE); pariputc('\n');
! 1780: }
! 1781:
! 1782: static GEN
! 1783: gpreadbin(char *s)
! 1784: {
! 1785: GEN x = readbin(s,infile);
! 1786: popinfile(); return x;
! 1787: }
! 1788:
! 1789: static void
! 1790: escape0(char *tch)
! 1791: {
! 1792: char *s, c;
! 1793:
! 1794: if (compatible != NONE)
! 1795: {
! 1796: s = tch;
! 1797: while (*s)
! 1798: if (*s++ == '=')
! 1799: {
! 1800: GEN (*f)(char*, int) = NULL;
! 1801: int len = (s-tch) - 1;
! 1802:
! 1803: if (!strncmp(tch,"precision",len)) f = sd_realprecision;
! 1804: else if (!strncmp(tch,"serieslength",len)) f = sd_seriesprecision;
! 1805: else if (!strncmp(tch,"format",len)) f = sd_format;
! 1806: else if (!strncmp(tch,"prompt",len)) f = sd_prompt;
! 1807: if (f) { f(get_sep(s), d_ACKNOWLEDGE); return; }
! 1808: break;
! 1809: }
! 1810: }
! 1811: s = tch;
! 1812: switch ((c = *s++))
! 1813: {
! 1814: case 'w': case 'x': case 'a': case 'b': case 'B': case 'm':
! 1815: { /* history things */
! 1816: long d;
! 1817: GEN x;
! 1818: if (c != 'w' && c != 'x') d = get_int(s,0);
! 1819: else
! 1820: {
! 1821: d = atol(s); if (*s == '-') s++;
! 1822: while (isdigit((int)*s)) s++;
! 1823: }
! 1824: x = gp_history(d, 0, tch+1,tch-1);
! 1825: switch (c)
! 1826: {
! 1827: case 'a': brute (x, fmt.format, -1); break;
! 1828: case 'm': matbrute(x, fmt.format, -1); break;
! 1829: case 'B': if (tex2mail_output(x,0)) return; /* fall through */
! 1830: case 'b': sor (x, fmt.format, -1, fmt.field); break;
! 1831: case 'x': voir(x, get_int(s, -1));
! 1832: case 'w':
! 1833: {
! 1834: GEN g[2]; g[0] = x; g[1] = NULL;
! 1835: s = get_sep_colon_ok(s); if (!*s) s = current_logfile;
! 1836: write0(s, g, f_RAW); return;
! 1837: }
! 1838: }
! 1839: pariputc('\n'); return;
! 1840: }
! 1841:
! 1842: case 'c': commands(-1); break;
! 1843: case 'd': help_default(); break;
! 1844: case 'e':
! 1845: s = get_sep(s);
! 1846: if (!*s) s = pariecho?"0":"1";
! 1847: sd_echo(s,d_ACKNOWLEDGE); break;
! 1848: case 'g':
! 1849: switch (*s)
! 1850: {
! 1851: case 'm': sd_debugmem(++s,d_ACKNOWLEDGE); break;
! 1852: case 'f': sd_debugfiles(++s,d_ACKNOWLEDGE); break;
! 1853: default : sd_debug(s,d_ACKNOWLEDGE); break;
! 1854: }
! 1855: break;
! 1856: case 'h': print_hash_list(s); break;
! 1857: case 'l':
! 1858: s = get_sep_colon_ok(s);
! 1859: if (*s)
! 1860: {
! 1861: sd_logfile(s,d_ACKNOWLEDGE);
! 1862: if (logfile) break;
! 1863: }
! 1864: sd_log(logfile?"0":"1",d_ACKNOWLEDGE);
! 1865: break;
! 1866: case 'o': sd_output(s,d_ACKNOWLEDGE); break;
! 1867: case 'p':
! 1868: switch (*s)
! 1869: {
! 1870: case 's': sd_seriesprecision(++s,d_ACKNOWLEDGE); break;
! 1871: default : sd_realprecision(s,d_ACKNOWLEDGE); break;
! 1872: }
! 1873: break;
! 1874: case 'q': gp_quit(); break;
! 1875: case 'r':
! 1876: s = get_sep_colon_ok(s);
! 1877: switchin(s);
! 1878: if (file_is_binary(infile)) gpreadbin(s);
! 1879: break;
! 1880: case 's': etatpile(0); break;
! 1881: case 't': gentypes(); break;
! 1882: case 'u':
! 1883: switch (*s)
! 1884: {
! 1885: case 'm': user_member(); break;
! 1886: default: user_fun();
! 1887: }
! 1888: break;
! 1889: case 'v': print_version(); break;
! 1890: case 'y':
! 1891: s = get_sep(s);
! 1892: if (!*s) s = simplifyflag?"0":"1";
! 1893: sd_simplify(s,d_ACKNOWLEDGE); break;
! 1894: default: err(caracer1,tch-1,tch-2);
! 1895: }
! 1896: }
! 1897:
! 1898: static void
! 1899: escape(char *tch)
! 1900: {
! 1901: char *old = _analyseur();
! 1902: _set_analyseur(tch); /* for error messages */
! 1903: escape0(tch);
! 1904: _set_analyseur(old);
! 1905: }
! 1906: /********************************************************************/
! 1907: /* */
! 1908: /* GPRC */
! 1909: /* */
! 1910: /********************************************************************/
! 1911: #if defined(UNIX) || defined(__EMX__)
! 1912: # include <pwd.h>
! 1913: #endif
! 1914:
! 1915: static int
! 1916: get_preproc_value(char *s)
! 1917: {
! 1918: if (!strncmp(s,"EMACS",5)) return under_emacs || under_texmacs;
! 1919: if (!strncmp(s,"READL",5))
! 1920: {
! 1921: #ifdef READLINE
! 1922: if (use_readline)
! 1923: return 1;
! 1924: else
! 1925: #endif
! 1926: return 0;
! 1927: }
! 1928: return -1;
! 1929: }
! 1930:
! 1931: /* return $HOME or the closest we can find */
! 1932: static char *
! 1933: get_home(int *free_it)
! 1934: {
! 1935: char *drv, *pth = os_getenv("HOME");
! 1936: if (pth) return pth;
! 1937: if ((drv = os_getenv("HOMEDRIVE"))
! 1938: && (pth = os_getenv("HOMEPATH")))
! 1939: { /* looks like WinNT */
! 1940: char *buf = gpmalloc(strlen(pth) + strlen(drv) + 1);
! 1941: sprintf(buf, "%s%s",drv,pth);
! 1942: *free_it = 1; return buf;
! 1943: }
! 1944: #if defined(__EMX__) || defined(UNIX)
! 1945: {
! 1946: struct passwd *p = getpwuid(geteuid());
! 1947: if (p) return p->pw_dir;
! 1948: }
! 1949: #endif
! 1950: return ".";
! 1951: }
! 1952:
! 1953: static FILE *
! 1954: gprc_chk(char *s)
! 1955: {
! 1956: FILE *f = fopen(s, "r");
! 1957: if (f && !quiet_mode)
! 1958: {
! 1959: fprintferr("Reading GPRC: %s ...", s);
! 1960: added_newline = 0;
! 1961: }
! 1962: return f;
! 1963: }
! 1964:
! 1965: /* Look for [._]gprc: $GPRC, then in $HOME, /, C:/ */
! 1966: static FILE *
! 1967: gprc_get()
! 1968: {
! 1969: FILE *f = NULL;
! 1970: char *str, *s, c;
! 1971: long l;
! 1972: #ifdef macintosh
! 1973: f = gprc_chk("gprc");
! 1974: #else
! 1975: s = os_getenv("GPRC");
! 1976: if (s) f = gprc_chk(s);
! 1977: if (!f)
! 1978: {
! 1979: int free_it = 0;
! 1980: s = get_home(&free_it); l = strlen(s); c = s[l-1];
! 1981: str = strcpy(gpmalloc(l+7), s);
! 1982: if (free_it) free(s);
! 1983: s = str + l;
! 1984: if (c != '/' && c != '\\') *s++ = '/';
! 1985: #ifdef UNIX
! 1986: *s = '.'; /* .gprc */
! 1987: #else
! 1988: *s = '_'; /* _gprc */
! 1989: #endif
! 1990: strcpy(s+1, "gprc");
! 1991: f = gprc_chk(str); /* in $HOME */
! 1992: if (!f) f = gprc_chk(s); /* in . */
! 1993: if (!f) f = gprc_chk("/etc/gprc");
! 1994: if (!f) f = gprc_chk("C:/_gprc");
! 1995: free(str);
! 1996: }
! 1997: #endif
! 1998: return f;
! 1999: }
! 2000:
! 2001: static int get_line_from_file(char *prompt, Buffer *b, FILE *file);
! 2002: #define err_gprc(s,t,u) { fprintferr("\n"); err(talker2,s,t,u); }
! 2003:
! 2004: static char **
! 2005: gp_initrc()
! 2006: {
! 2007: char **flist, *s,*s1,*s2;
! 2008: FILE *file = gprc_get();
! 2009: long fnum = 4, find = 0;
! 2010: Buffer *b;
! 2011:
! 2012: if (!file) return NULL;
! 2013: flist = (char **) gpmalloc(fnum * sizeof(char*));
! 2014: b = new_buffer();
! 2015: for(;;)
! 2016: {
! 2017: if (!get_line_from_file(NULL,b,file))
! 2018: {
! 2019: del_buffer(b);
! 2020: if (!quiet_mode) fprintferr("Done.\n\n");
! 2021: fclose(file); flist[find] = NULL;
! 2022: return flist;
! 2023: }
! 2024: for (s = b->buf; *s; )
! 2025: {
! 2026: s1 = s; if (get_sep2(s)) s++;
! 2027: s += strlen(s1); /* point to next expr */
! 2028: if (*s1 == '#')
! 2029: { /* preprocessor directive */
! 2030: int z, NOT = 0;
! 2031: s1++;
! 2032: if (strncmp(s1,"if",2)) err_gprc("unknown directive",s1,b->buf);
! 2033: s1 += 2;
! 2034: if (!strncmp(s1,"not",3)) { NOT = !NOT; s1 += 3; }
! 2035: if (*s1 == '!') { NOT = !NOT; s1++; }
! 2036: z = get_preproc_value(s1);
! 2037: if (z < 0) err_gprc("unknown preprocessor variable",s1,b->buf);
! 2038: if (NOT) z = !z;
! 2039: if (!z) continue;
! 2040: s1 += 5;
! 2041: }
! 2042: if (!strncmp(s1,"read",4))
! 2043: { /* read file */
! 2044: s1 += 4;
! 2045: if (find == fnum-1)
! 2046: {
! 2047: long n = fnum << 1;
! 2048: flist = (char**)gprealloc(flist, n*sizeof(char*),
! 2049: fnum*sizeof(char*));
! 2050: fnum = n;
! 2051: }
! 2052: flist[find++] = s2 = gpmalloc(strlen(s1) + 1);
! 2053: if (*s1 == '"') (void)readstring(s1, s2);
! 2054: else strcpy(s2,s1);
! 2055: }
! 2056: else
! 2057: { /* set default */
! 2058: s2 = s1; while (*s2 && *s2 != '=') s2++;
! 2059: if (*s2 != '=') err_gprc("missing '='",s2,b->buf);
! 2060: *s2++ = 0;
! 2061: if (*s2 == '"') (void)readstring(s2, s2);
! 2062: setdefault(s1,s2,d_INITRC);
! 2063: }
! 2064: }
! 2065: }
! 2066: }
! 2067:
! 2068: /********************************************************************/
! 2069: /* */
! 2070: /* GP MAIN LOOP */
! 2071: /* */
! 2072: /********************************************************************/
! 2073: /* flag:
! 2074: * ti_NOPRINT don't print
! 2075: * ti_REGULAR print elapsed time (chrono = 1)
! 2076: * ti_LAST print last elapsed time (##)
! 2077: * ti_INTERRUPT received a SIGINT
! 2078: */
! 2079: static char *
! 2080: do_time(long flag)
! 2081: {
! 2082: static long last = 0;
! 2083: long delay = (flag == ti_LAST)? last: gptimer();
! 2084: char *s;
! 2085:
! 2086: last = delay;
! 2087: switch(flag)
! 2088: {
! 2089: case ti_REGULAR: s = "time = "; break;
! 2090: case ti_INTERRUPT: s = "user interrupt after "; break;
! 2091: case ti_LAST: s = " *** last result computed in "; break;
! 2092: default: return NULL;
! 2093: }
! 2094: strcpy(thestring,s); s=thestring+strlen(s);
! 2095: strcpy(s, term_get_color(c_TIME)); s+=strlen(s);
! 2096: if (delay >= 3600000)
! 2097: {
! 2098: sprintf(s, "%ldh, ", delay / 3600000); s+=strlen(s);
! 2099: delay %= 3600000;
! 2100: }
! 2101: if (delay >= 60000)
! 2102: {
! 2103: sprintf(s, "%ldmn, ", delay / 60000); s+=strlen(s);
! 2104: delay %= 60000;
! 2105: }
! 2106: if (delay >= 1000)
! 2107: {
! 2108: sprintf(s, "%ld,", delay / 1000); s+=strlen(s);
! 2109: delay %= 1000;
! 2110: if (delay < 100)
! 2111: {
! 2112: sprintf(s, "%s", (delay<10)? "00": "0");
! 2113: s+=strlen(s);
! 2114: }
! 2115: }
! 2116: sprintf(s, "%ld ms", delay); s+=strlen(s);
! 2117: strcpy(s, term_get_color(c_NONE));
! 2118: if (flag != ti_INTERRUPT) { s+=strlen(s); *s++='.'; *s++='\n'; *s=0; }
! 2119: return thestring;
! 2120: }
! 2121:
! 2122: static void
! 2123: gp_handle_SIGINT()
! 2124: {
! 2125: #ifdef _WIN32
! 2126: if (++win32ctrlc >= 5) _exit(3);
! 2127: #else
! 2128: if (under_texmacs) tm_start_output();
! 2129: err(siginter, do_time(ti_INTERRUPT));
! 2130: #endif
! 2131: }
! 2132:
! 2133: static void
! 2134: gp_sighandler(int sig)
! 2135: {
! 2136: char *msg;
! 2137: os_signal(sig,gp_sighandler);
! 2138: switch(sig)
! 2139: {
! 2140: #ifdef SIGBREAK
! 2141: case SIGBREAK: gp_handle_SIGINT(); return;
! 2142: #endif
! 2143: #ifdef SIGINT
! 2144: case SIGINT: gp_handle_SIGINT(); return;
! 2145: #endif
! 2146:
! 2147: #ifdef SIGSEGV
! 2148: case SIGSEGV:
! 2149: msg="GP (Segmentation Fault)";
! 2150: break;
! 2151: #endif
! 2152:
! 2153: #ifdef SIGBUS
! 2154: case SIGBUS:
! 2155: msg="GP (Bus Error)";
! 2156: break;
! 2157: #endif
! 2158:
! 2159: #ifdef SIGFPE
! 2160: case SIGFPE:
! 2161: msg="GP (Floating Point Exception)";
! 2162: break;
! 2163: #endif
! 2164:
! 2165: #ifdef SIGPIPE
! 2166: case SIGPIPE:
! 2167: if (prettyprinter_file && pari_outfile == prettyprinter_file->file)
! 2168: {
! 2169: pariFILE *f = prettyprinter_file;
! 2170: prettyprinter_file = NULL; /* to avoid oo recursion on error */
! 2171: pari_outfile = stdout; pari_fclose(f);
! 2172: }
! 2173: err(talker, "Broken Pipe, resetting file stack...");
! 2174: #endif
! 2175:
! 2176: default:
! 2177: msg="signal handling";
! 2178: }
! 2179: err(bugparier,msg);
! 2180: }
! 2181:
! 2182: static void
! 2183: brace_color(char *s, int c, int force)
! 2184: {
! 2185: if (disable_color || (gp_colors[c] == c_NONE && !force)) return;
! 2186: #ifdef RL_PROMPT_START_IGNORE
! 2187: *s++ = RL_PROMPT_START_IGNORE;
! 2188: #endif
! 2189: strcpy(s, term_get_color(c));
! 2190: #ifdef RL_PROMPT_START_IGNORE
! 2191: s+=strlen(s);
! 2192: *s++ = RL_PROMPT_END_IGNORE; *s = 0;
! 2193: #endif
! 2194: }
! 2195:
! 2196: static char *
! 2197: do_prompt()
! 2198: {
! 2199: static char buf[MAX_PROMPT_LEN + 24]; /* + room for color codes */
! 2200: char *s;
! 2201:
! 2202: if (test_mode) return prompt;
! 2203: s = buf; *s = 0;
! 2204: /* escape sequences bug readline, so use special bracing (if available) */
! 2205: brace_color(s, c_PROMPT, 0);
! 2206: s += strlen(s);
! 2207: if (filtre(s,NULL, f_COMMENT))
! 2208: strcpy(s, COMMENTPROMPT);
! 2209: else
! 2210: do_strftime(prompt,s);
! 2211: s += strlen(s);
! 2212: brace_color(s, c_INPUT, 1); return buf;
! 2213: }
! 2214:
! 2215: static void
! 2216: unblock_SIGINT()
! 2217: {
! 2218: #ifdef USE_SIGRELSE
! 2219: sigrelse(SIGINT);
! 2220: #elif USE_SIGSETMASK
! 2221: sigsetmask(0);
! 2222: #endif
! 2223: }
! 2224:
! 2225: /* Read from file (up to '\n' or EOF) and copy at s0 (points in b->buf) */
! 2226: static char *
! 2227: file_input(Buffer *b, char **s0, FILE *file, int TeXmacs)
! 2228: {
! 2229: int first = 1;
! 2230: char *s = *s0;
! 2231: long used0, used = s - b->buf;
! 2232:
! 2233: used0 = used;
! 2234: for(;;)
! 2235: {
! 2236: long left = b->len - used, ls;
! 2237: /* if from TeXmacs, tell him we need input */
! 2238: if (TeXmacs) { tm_start_output(); tm_end_output(); }
! 2239:
! 2240: if (left < 512)
! 2241: {
! 2242: fix_buffer(b, b->len << 1);
! 2243: left = b->len - used;
! 2244: *s0 = b->buf + used0;
! 2245: }
! 2246: s = b->buf + used;
! 2247: if (! fgets(s, left, file)) return first? NULL: *s0; /* EOF */
! 2248: ls = strlen(s); first = 0;
! 2249: if (ls+1 < left || s[ls-1] == '\n') return *s0; /* \n */
! 2250: used += ls;
! 2251: }
! 2252: }
! 2253:
! 2254: #ifdef READLINE
! 2255: static char *
! 2256: gprl_input(Buffer *b, char **s0, char *prompt)
! 2257: {
! 2258: long used = *s0 - b->buf;
! 2259: long left = b->len - used;
! 2260: char *s;
! 2261:
! 2262: if (! (s = readline(prompt)) ) return NULL; /* EOF */
! 2263: if ((ulong)left < strlen(s))
! 2264: {
! 2265: fix_buffer(b, b->len << 1);
! 2266: *s0 = b->buf + used;
! 2267: }
! 2268: return s;
! 2269: }
! 2270: #endif
! 2271:
! 2272: static void
! 2273: input_loop(Buffer *b, char *buf0, FILE *file, char *prompt)
! 2274: {
! 2275: const int TeXmacs = (under_texmacs && file == stdin);
! 2276: const int f_flag = prompt? f_REG: f_REG | f_KEEPCASE;
! 2277: char *end, *s = b->buf, *buf = buf0;
! 2278: int wait_for_brace = 0;
! 2279: int wait_for_input = 0;
! 2280:
! 2281: /* buffer is not empty, init filter */
! 2282: (void)ask_filtre(f_INIT);
! 2283: for(;;)
! 2284: {
! 2285: char *t = buf;
! 2286: if (!ask_filtre(f_COMMENT))
! 2287: { /* not in comment */
! 2288: skip_space(t);
! 2289: if (*t == LBRACE) { t++; wait_for_input = wait_for_brace = 1; }
! 2290: }
! 2291: end = filtre(t,s, f_flag);
! 2292:
! 2293: if (!*s) { if (!wait_for_input) break; }
! 2294: else
! 2295: {
! 2296: if (*(b->buf) == '?') break;
! 2297:
! 2298: s = end-1; /* *s = last input char */
! 2299: if (*s == '\\')
! 2300: {
! 2301: }
! 2302: else if (*s == '=')
! 2303: {
! 2304: wait_for_input = 1; s++;
! 2305: }
! 2306: else
! 2307: {
! 2308: if (!wait_for_brace) break;
! 2309: if (*s == RBRACE) { *s=0; break; }
! 2310: s++;
! 2311: }
! 2312: }
! 2313: /* read continuation line */
! 2314: #ifdef READLINE
! 2315: if (!file) { free(buf); buf = gprl_input(b,&s,""); }
! 2316: else
! 2317: #endif
! 2318: buf = file_input(b,&s,file,TeXmacs);
! 2319: if (!buf) break;
! 2320: }
! 2321: if (!file && buf) free(buf);
! 2322: }
! 2323:
! 2324: /* prompt = NULL --> from gprc. Return 1 if new input, and 0 if EOF */
! 2325: static int
! 2326: get_line_from_file(char *prompt, Buffer *b, FILE *file)
! 2327: {
! 2328: const int TeXmacs = (under_texmacs && file == stdin);
! 2329: char *buf, *s = b->buf;
! 2330:
! 2331: handle_C_C = 0;
! 2332: while (! (buf = file_input(b,&s,file,TeXmacs)) )
! 2333: { /* EOF */
! 2334: if (!handle_C_C)
! 2335: {
! 2336: if (TeXmacs) tm_start_output();
! 2337: return 0;
! 2338: }
! 2339: /* received ^C in fgets, retry (as is "\n" were input) */
! 2340: }
! 2341: input_loop(b,buf,file,prompt);
! 2342:
! 2343: if (*s && prompt) /* don't echo if from gprc */
! 2344: {
! 2345: if (pariecho)
! 2346: { pariputs(prompt); pariputs(s); pariputc('\n'); }
! 2347: else
! 2348: if (logfile) fprintf(logfile, "%s%s\n",prompt,s);
! 2349: pariflush();
! 2350: }
! 2351: if (under_texmacs) tm_start_output();
! 2352: return 1;
! 2353: }
! 2354:
! 2355: /* request one line interactively.
! 2356: * Return 0: EOF
! 2357: * 1: got one line from readline or infile */
! 2358: #ifndef READLINE
! 2359: static int
! 2360: get_line_from_user(char *prompt, Buffer *b)
! 2361: {
! 2362: pariputs(prompt);
! 2363: return get_line_from_file(prompt,b,infile);
! 2364: }
! 2365: #else
! 2366: static int
! 2367: get_line_from_user(char *prompt, Buffer *b)
! 2368: {
! 2369: if (use_readline)
! 2370: {
! 2371: static char *previous_hist = NULL;
! 2372: char *buf, *s = b->buf;
! 2373:
! 2374: if (! (buf = gprl_input(b,&s, prompt)) )
! 2375: { /* EOF */
! 2376: pariputs("\n"); return 0;
! 2377: }
! 2378: input_loop(b,buf,NULL,prompt);
! 2379: unblock_SIGINT(); /* bug in readline 2.0: need to unblock ^C */
! 2380:
! 2381: if (*s)
! 2382: {
! 2383: /* update history (don't add the same entry twice) */
! 2384: if (!previous_hist || strcmp(s,previous_hist))
! 2385: {
! 2386: if (previous_hist) free(previous_hist);
! 2387: previous_hist = pari_strdup(s); add_history(s);
! 2388: }
! 2389: /* update logfile */
! 2390: if (logfile) fprintf(logfile, "%s%s\n",prompt,s);
! 2391: }
! 2392: return 1;
! 2393: }
! 2394: else
! 2395: {
! 2396: pariputs(prompt);
! 2397: return get_line_from_file(prompt,b,infile);
! 2398: }
! 2399: }
! 2400: #endif
! 2401:
! 2402: static int
! 2403: is_interactive()
! 2404: {
! 2405: #if defined(UNIX) || defined(__EMX__)
! 2406: return (infile == stdin && !under_texmacs
! 2407: && (under_emacs || isatty(fileno(stdin))));
! 2408: #else
! 2409: return (infile == stdin && !under_texmacs);
! 2410: #endif
! 2411: }
! 2412:
! 2413: /* return 0 if no line could be read (EOF) */
! 2414: static int
! 2415: read_line(char *promptbuf, Buffer *b)
! 2416: {
! 2417: if (is_interactive())
! 2418: return get_line_from_user(promptbuf, b);
! 2419: else
! 2420: return get_line_from_file(DFT_PROMPT,b,infile);
! 2421: }
! 2422:
! 2423: static void
! 2424: chron(char *s)
! 2425: {
! 2426: if (*s)
! 2427: {
! 2428: char *old = s-1;
! 2429: if (*s == '#') { pariputs(do_time(ti_LAST)); s++; }
! 2430: if (*s) err(caracer1,s,old);
! 2431: }
! 2432: else { chrono = 1-chrono; sd_timer("",d_ACKNOWLEDGE); }
! 2433: }
! 2434:
! 2435: static int
! 2436: check_meta(char *buf)
! 2437: {
! 2438: switch(*buf++)
! 2439: {
! 2440: case '?': aide(buf, h_REGULAR); break;
! 2441: case '#': chron(buf); break;
! 2442: case '\\': escape(buf); break;
! 2443: case '\0': return 2;
! 2444: default: return 0;
! 2445: }
! 2446: return 1;
! 2447: }
! 2448:
! 2449: /* If there are other buffers open (bufstack != NULL), we are doing an
! 2450: * immediate read (with read, extern...) */
! 2451: static GEN
! 2452: gp_main_loop(int ismain)
! 2453: {
! 2454: long av, i,j;
! 2455: VOLATILE GEN z = gnil;
! 2456: Buffer *b = new_buffer();
! 2457: if (!setjmp(b->env))
! 2458: {
! 2459: b->flenv = 1;
! 2460: push_stack(&bufstack, (void*)b);
! 2461: }
! 2462: for(; ; setjmp(b->env))
! 2463: {
! 2464: if (ismain)
! 2465: {
! 2466: static long tloc, outtyp;
! 2467: tloc = tglobal; outtyp = prettyp; recover(0);
! 2468: if (setjmp(environnement))
! 2469: {
! 2470: char *s = (char*)global_err_data;
! 2471: if (s && *s) outerr(lisseq(s));
! 2472: avma = top; parisize = top - bot;
! 2473: j = tglobal - tloc; i = (tglobal-1)%histsize;
! 2474: while (j)
! 2475: {
! 2476: gunclone(hist[i]); hist[i]=NULL;
! 2477: if (!i) i = histsize;
! 2478: i--; j--;
! 2479: }
! 2480: tglobal = tloc; prettyp = outtyp;
! 2481: kill_all_buffers(b);
! 2482: }
! 2483: }
! 2484: added_newline = 1;
! 2485: if (paribufsize != b->len) fix_buffer(b, paribufsize);
! 2486:
! 2487: for(;;)
! 2488: {
! 2489: int r;
! 2490: r = read_line(do_prompt(), b);
! 2491: if (!disable_color) term_color(c_NONE);
! 2492: if (!r)
! 2493: {
! 2494: #ifdef _WIN32
! 2495: Sleep(10); if (win32ctrlc) dowin32ctrlc();
! 2496: #endif
! 2497: if (popinfile()) gp_quit();
! 2498: if (!ismain) { pop_buffer(); return z; }
! 2499: }
! 2500: else if (!check_meta(b->buf)) break;
! 2501: }
! 2502: if (ismain)
! 2503: {
! 2504: char c = b->buf[strlen(b->buf) - 1];
! 2505: gpsilent = separe(c);
! 2506: (void)gptimer();
! 2507: }
! 2508: av = avma;
! 2509: z = readseq(b->buf, strictmatch);
! 2510: if (!added_newline) pariputc('\n'); /* last output was print1() */
! 2511: if (! ismain) continue;
! 2512: if (chrono) pariputs(do_time(ti_REGULAR)); else do_time(ti_NOPRINT);
! 2513: if (z == gnil) continue;
! 2514:
! 2515: if (simplifyflag) z = simplify_i(z);
! 2516: i = tglobal % histsize; tglobal++;
! 2517: if (hist[i]) gunclone(hist[i]);
! 2518: hist[i] = z = gclone(z); avma = av;
! 2519: if (gpsilent) continue;
! 2520:
! 2521: if (test_mode) { init80(0); gp_output(z); pariputc('\n'); }
! 2522: else
! 2523: {
! 2524: if (under_texmacs)
! 2525: texmacs_output(z,tglobal);
! 2526: else if (prettyp != f_PRETTY || !tex2mail_output(z,tglobal))
! 2527: normal_output(z,tglobal);
! 2528: }
! 2529: pariflush();
! 2530: }
! 2531: }
! 2532:
! 2533: GEN
! 2534: read0(char *s)
! 2535: {
! 2536: switchin(s);
! 2537: if (file_is_binary(infile)) return gpreadbin(s);
! 2538: return gp_main_loop(0);
! 2539: }
! 2540:
! 2541: static void
! 2542: check_secure(char *s)
! 2543: {
! 2544: if (secure)
! 2545: err(talker, "[secure mode]: system commands not allowed\nTried to run '%s'",s);
! 2546: }
! 2547:
! 2548: GEN
! 2549: extern0(char *s)
! 2550: {
! 2551: check_secure(s);
! 2552: infile = try_pipe(s, mf_IN)->file;
! 2553: return gp_main_loop(0);
! 2554: }
! 2555:
! 2556: static int
! 2557: silent()
! 2558: {
! 2559: if (gpsilent) return 1;
! 2560: { char c = _analyseur()[1]; return separe(c); }
! 2561: }
! 2562:
! 2563: GEN
! 2564: default0(char *a, char *b, long flag)
! 2565: {
! 2566: if (flag) flag=d_RETURN;
! 2567: else
! 2568: flag = silent()? d_SILENT: d_ACKNOWLEDGE;
! 2569: return setdefault(a,b,flag);
! 2570: }
! 2571:
! 2572: GEN
! 2573: input0()
! 2574: {
! 2575: Buffer *b = new_buffer();
! 2576: GEN x;
! 2577:
! 2578: push_stack(&bufstack, (void*)b);
! 2579: while (! get_line_from_file(DFT_INPROMPT,b,infile))
! 2580: if (popinfile()) { fprintferr("no input ???"); gp_quit(); }
! 2581: x = lisseq(b->buf);
! 2582: pop_buffer(); return x;
! 2583: }
! 2584:
! 2585: void
! 2586: system0(char *s)
! 2587: {
! 2588: #if defined(UNIX) || defined(__EMX__)
! 2589: check_secure(s);
! 2590: system(s);
! 2591: #else
! 2592: err(archer);
! 2593: #endif
! 2594: }
! 2595:
! 2596: void
! 2597: error0(GEN *g)
! 2598: {
! 2599: term_color(c_ERR);
! 2600: if (!added_newline) pariputc('\n');
! 2601: pariputs("### User error:\n\n ");
! 2602: print0(g,f_RAW); term_color(c_NONE);
! 2603: err_recover(talker);
! 2604: }
! 2605:
! 2606: void errcontext(char *msg, char *s, char *entry);
! 2607:
! 2608: int
! 2609: break_loop(long numerr)
! 2610: {
! 2611: static FILE *oldinfile = NULL;
! 2612: static char *old = NULL;
! 2613: static Buffer *b = NULL;
! 2614: VOLATILE int go_on = 0;
! 2615: char *s, *t, *msg;
! 2616:
! 2617: if (b) jump_to_given_buffer(b);
! 2618: push_stack(&bufstack, (void*)new_buffer());
! 2619: b = current_buffer; /* buffer created above */
! 2620: if (setjmp(b->env))
! 2621: {
! 2622: msg = "back to break loop";
! 2623: s = t = NULL;
! 2624: }
! 2625: else
! 2626: {
! 2627: Buffer *oldb = (Buffer*)bufstack->prev->value;
! 2628: msg = "Starting break loop (type 'break' to go back to GP)";
! 2629: old = s = _analyseur();
! 2630: t = oldb->buf;
! 2631: /* something fishy, probably a ^C, or we overran analyseur */
! 2632: if (!s || !s[-1] || s < t || s >= t + oldb->len) s = NULL;
! 2633: b->flenv = 1; oldinfile = infile;
! 2634: }
! 2635:
! 2636: term_color(c_ERR); pariputc('\n');
! 2637: errcontext(msg, s, t); if (s) pariputc('\n');
! 2638: term_color(c_NONE);
! 2639: if (numerr == siginter) pariputs("['' or 'next' will continue]\n");
! 2640: infile = stdin;
! 2641: for(;;)
! 2642: {
! 2643: int flag;
! 2644: if (! read_line("> ", b)) break;
! 2645: if (!(flag = check_meta(b->buf)))
! 2646: {
! 2647: GEN x = lisseq(b->buf);
! 2648: if (did_break())
! 2649: {
! 2650: if (numerr == siginter && did_break() == br_NEXT)
! 2651: {
! 2652: (void)loop_break(); /* clear status flag */
! 2653: go_on = 1;
! 2654: }
! 2655: break;
! 2656: }
! 2657: if (x == gnil) continue;
! 2658:
! 2659: term_color(c_OUTPUT); gp_output(x);
! 2660: term_color(c_NONE); pariputc('\n');
! 2661: }
! 2662: if (numerr == siginter && flag == 2) { handle_C_C = go_on = 1; break; }
! 2663: }
! 2664: if (old && !s) _set_analyseur(old);
! 2665: b = NULL; infile = oldinfile;
! 2666: pop_buffer(); return go_on;
! 2667: }
! 2668:
! 2669: int
! 2670: gp_exception_handler(long numerr)
! 2671: {
! 2672: char *s = (char*)global_err_data;
! 2673: if (s && *s) { fprintferr("\n"); outerr(lisseq(s)); }
! 2674: else
! 2675: {
! 2676: if (numerr == errpile) avma = top;
! 2677: return break_loop(numerr);
! 2678: }
! 2679: return 0;
! 2680: }
! 2681:
! 2682: long
! 2683: setprecr(long n)
! 2684: {
! 2685: long m = fmt.nb;
! 2686:
! 2687: if (n>0) {fmt.nb = n; prec = (long)(n*pariK1 + 3);}
! 2688: return m;
! 2689: }
! 2690:
! 2691: static void
! 2692: testint(char *s, long *d)
! 2693: {
! 2694: if (!s) return;
! 2695: *d = get_int(s, 0);
! 2696: if (*d <= 0) err(talker,"arguments must be positive integers");
! 2697: }
! 2698:
! 2699: static char *
! 2700: read_arg(int *nread, char *t, long argc, char **argv)
! 2701: {
! 2702: int i = *nread;
! 2703: if (isdigit((int)*t)) return t;
! 2704: if (*t || i==argc) usage(argv[0]);
! 2705: *nread = i+1; return argv[i];
! 2706: }
! 2707:
! 2708: static char**
! 2709: read_opt(long argc, char **argv)
! 2710: {
! 2711: char *b=NULL, *p=NULL, *s=NULL, **pre;
! 2712: int i=1, initrc=1;
! 2713:
! 2714: pari_outfile=stderr;
! 2715: while (i<argc)
! 2716: {
! 2717: char *t = argv[i++];
! 2718:
! 2719: if (*t++ != '-') usage(argv[0]);
! 2720: switch(*t++)
! 2721: {
! 2722: case 'b': b = read_arg(&i,t,argc,argv); break;
! 2723: case 'p': p = read_arg(&i,t,argc,argv); break;
! 2724: case 's': s = read_arg(&i,t,argc,argv); break;
! 2725:
! 2726: case 'e':
! 2727: if (strncmp(t,"macs",4)) usage(argv[0]);
! 2728: under_emacs = 1; break;
! 2729: case 'q':
! 2730: quiet_mode = 1; break;
! 2731: case 't':
! 2732: if (strncmp(t,"est",3)) usage(argv[0]);
! 2733: disable_color = 1; test_mode = 1; /* fall through */
! 2734: case 'f':
! 2735: initrc = 0; break;
! 2736: case '-':
! 2737: if (strcmp(t, "version") == 0) { print_version(); exit(0); }
! 2738: if (strcmp(t, "texmacs") == 0) { under_texmacs = 1; break; }
! 2739: /* fall through */
! 2740: default:
! 2741: usage(argv[0]);
! 2742: }
! 2743: }
! 2744: if (under_texmacs) tm_start_output();
! 2745: pre = initrc? gp_initrc(): NULL;
! 2746:
! 2747: /* override the values from gprc */
! 2748: testint(b, &paribufsize); if (paribufsize < 10) paribufsize = 10;
! 2749: testint(p, &primelimit);
! 2750: testint(s, &parisize);
! 2751: if (under_emacs || under_texmacs) disable_color=1;
! 2752: pari_outfile=stdout; return pre;
! 2753: }
! 2754:
! 2755: #ifdef WINCE
! 2756: int
! 2757: WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
! 2758: LPWSTR lpCmdLine, int nShowCmd)
! 2759: {
! 2760: char **argv = NULL;
! 2761: int argc = 1;
! 2762: #else
! 2763: int
! 2764: main(int argc, char **argv)
! 2765: {
! 2766: #endif
! 2767: char **flist;
! 2768:
! 2769: init_defaults(1); gp_preinit(1);
! 2770: if (setjmp(environnement))
! 2771: {
! 2772: pariputs("### Errors on startup, exiting...\n\n");
! 2773: exit(1);
! 2774: }
! 2775: #ifdef __MWERKS__
! 2776: argc = ccommand(&argv);
! 2777: #endif
! 2778: flist = read_opt(argc,argv);
! 2779: pari_addfunctions(&pari_modules, functions_gp,helpmessages_gp);
! 2780: pari_addfunctions(&pari_modules, functions_highlevel,helpmessages_highlevel);
! 2781: pari_addfunctions(&pari_oldmodules, functions_oldgp,helpmessages_oldgp);
! 2782:
! 2783: init_graph(); INIT_SIG_off;
! 2784: pari_init(parisize, primelimit);
! 2785: INIT_SIG_on;
! 2786: pari_sig_init(gp_sighandler);
! 2787: #ifdef READLINE
! 2788: if (use_readline) {
! 2789: init_readline();
! 2790: readline_init = 1;
! 2791: }
! 2792: #endif
! 2793: gp_history_fun = gp_history;
! 2794: whatnow_fun = whatnow;
! 2795: output_fun = gp_output;
! 2796: default_exception_handler = gp_exception_handler;
! 2797: gp_expand_path(path);
! 2798:
! 2799: if (!quiet_mode) gp_head();
! 2800: if (flist)
! 2801: {
! 2802: long c=chrono, e=pariecho;
! 2803: FILE *l=logfile;
! 2804: char **s = flist;
! 2805: chrono=0; pariecho=0; logfile=NULL;
! 2806: for ( ; *s; s++) { read0(*s); free(*s); }
! 2807: chrono=c; pariecho=e; logfile=l; free(flist);
! 2808: }
! 2809: (void)gptimer(); (void)timer(); (void)timer2();
! 2810: (void)gp_main_loop(1);
! 2811: gp_quit(); return 0; /* not reached */
! 2812: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>