CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Path: gap4r8 / src / gap.c
Views: 418346
1
/****************************************************************************
2
**
3
*W gap.c GAP source Frank Celler
4
*W & Martin Schönert
5
**
6
**
7
*Y Copyright (C) 1996, Lehrstuhl D für Mathematik, RWTH Aachen, Germany
8
*Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
9
*Y Copyright (C) 2002 The GAP Group
10
**
11
** This file contains the various read-eval-print loops and related stuff.
12
*/
13
#include <stdio.h>
14
#include <assert.h>
15
#include <string.h> /* memcpy */
16
#include <stdlib.h>
17
18
#include "system.h" /* system dependent part */
19
20
#ifdef HAVE_SYS_STAT_H
21
#include <sys/stat.h>
22
#endif
23
24
#include <sys/time.h>
25
#include <unistd.h> /* move this and wrap execvp later */
26
27
#include "gasman.h" /* garbage collector */
28
#include "objects.h" /* objects */
29
#include "scanner.h" /* scanner */
30
31
#include "gap.h" /* error handling, initialisation */
32
#include "tls.h" /* thread-local storage */
33
34
#include "read.h" /* reader */
35
36
#include "gvars.h" /* global variables */
37
#include "calls.h" /* generic call mechanism */
38
#include "opers.h" /* generic operations */
39
40
#include "ariths.h" /* basic arithmetic */
41
42
#include "integer.h" /* integers */
43
#include "rational.h" /* rationals */
44
#include "cyclotom.h" /* cyclotomics */
45
#include "finfield.h" /* finite fields and ff elements */
46
47
#include "bool.h" /* booleans */
48
#include "macfloat.h" /* machine doubles */
49
#include "permutat.h" /* permutations */
50
#include "trans.h" /* transformations */
51
#include "pperm.h" /* partial perms */
52
53
#include "records.h" /* generic records */
54
#include "precord.h" /* plain records */
55
56
#include "lists.h" /* generic lists */
57
#include "listoper.h" /* operations for generic lists */
58
#include "listfunc.h" /* functions for generic lists */
59
#include "plist.h" /* plain lists */
60
#include "set.h" /* plain sets */
61
#include "vector.h" /* functions for plain vectors */
62
#include "vecffe.h" /* functions for fin field vectors */
63
#include "blister.h" /* boolean lists */
64
#include "range.h" /* ranges */
65
#include "string.h" /* strings */
66
#include "vecgf2.h" /* functions for GF2 vectors */
67
#include "vec8bit.h" /* functions for other compressed
68
GF(q) vectors */
69
#include "objfgelm.h" /* objects of free groups */
70
#include "objpcgel.h" /* objects of polycyclic groups */
71
#include "objscoll.h" /* single collector */
72
#include "objccoll.h" /* combinatorial collector */
73
#include "objcftl.h" /* from the left collect */
74
75
#include "dt.h" /* deep thought */
76
#include "dteval.h" /* deep thought evaluation */
77
78
#include "sctable.h" /* structure constant table */
79
#include "costab.h" /* coset table */
80
#include "tietze.h" /* tietze helper functions */
81
82
#include "code.h" /* coder */
83
84
#include "exprs.h" /* expressions */
85
#include "stats.h" /* statements */
86
#include "funcs.h" /* functions */
87
88
#include "intrprtr.h" /* interpreter */
89
90
#include "compiler.h" /* compiler */
91
92
#include "compstat.h" /* statically linked modules */
93
94
#include "saveload.h" /* saving and loading */
95
96
#include "streams.h" /* streams package */
97
#include "sysfiles.h" /* file input/output */
98
#include "weakptr.h" /* weak pointers */
99
#include "profile.h" /* profiling */
100
#ifdef GAPMPI
101
#include "gapmpi.h" /* ParGAP/MPI */
102
#endif
103
104
#include "thread.h"
105
#include "tls.h"
106
#include "aobjects.h"
107
108
#include "vars.h" /* variables */
109
110
#include "intfuncs.h"
111
#include "iostream.h"
112
113
/****************************************************************************
114
**
115
116
*V Last . . . . . . . . . . . . . . . . . . . . . . global variable 'last'
117
**
118
** 'Last', 'Last2', and 'Last3' are the global variables 'last', 'last2',
119
** and 'last3', which are automatically assigned the result values in the
120
** main read-eval-print loop.
121
*/
122
UInt Last;
123
124
125
/****************************************************************************
126
**
127
*V Last2 . . . . . . . . . . . . . . . . . . . . . . global variable 'last2'
128
*/
129
UInt Last2;
130
131
132
/****************************************************************************
133
**
134
*V Last3 . . . . . . . . . . . . . . . . . . . . . . global variable 'last3'
135
*/
136
UInt Last3;
137
138
139
/****************************************************************************
140
**
141
*V Time . . . . . . . . . . . . . . . . . . . . . . global variable 'time'
142
**
143
** 'Time' is the global variable 'time', which is automatically assigned the
144
** time the last command took.
145
*/
146
UInt Time;
147
148
149
/****************************************************************************
150
**
151
*F ViewObjHandler . . . . . . . . . handler to view object and catch errors
152
**
153
** This is the function actually called in Read-Eval-View loops.
154
** We might be in trouble if the library has not (yet) loaded and so ViewObj
155
** is not yet defined, or the fallback methods not yet installed. To avoid
156
** this problem, we check, and use PrintObj if there is a problem
157
**
158
** We also install a hook to use the GAP level function 'CustomView' if
159
** it exists. This can for example be used to restrict the amount of output
160
** or to show long output in a pager or .....
161
**
162
** This function also supplies the \n after viewing.
163
*/
164
UInt ViewObjGVar;
165
UInt CustomViewGVar;
166
167
void ViewObjHandler ( Obj obj )
168
{
169
volatile Obj func;
170
volatile Obj cfunc;
171
syJmp_buf readJmpError;
172
173
/* get the functions */
174
func = ValAutoGVar(ViewObjGVar);
175
cfunc = ValAutoGVar(CustomViewGVar);
176
177
/* if non-zero use this function, otherwise use `PrintObj' */
178
memcpy( readJmpError, TLS(ReadJmpError), sizeof(syJmp_buf) );
179
if ( ! READ_ERROR() ) {
180
if ( cfunc != 0 && TNUM_OBJ(cfunc) == T_FUNCTION ) {
181
CALL_1ARGS(cfunc, obj);
182
}
183
else if ( func != 0 && TNUM_OBJ(func) == T_FUNCTION ) {
184
ViewObj(obj);
185
}
186
else {
187
PrintObj( obj );
188
}
189
Pr( "\n", 0L, 0L );
190
memcpy( TLS(ReadJmpError), readJmpError, sizeof(syJmp_buf) );
191
}
192
else {
193
memcpy( TLS(ReadJmpError), readJmpError, sizeof(syJmp_buf) );
194
}
195
}
196
197
198
/****************************************************************************
199
**
200
*F main( <argc>, <argv> ) . . . . . . . main program, read-eval-print loop
201
*/
202
UInt QUITTINGGVar;
203
204
205
typedef struct {
206
const Char * name;
207
Obj * address;
208
} StructImportedGVars;
209
210
#ifndef MAX_IMPORTED_GVARS
211
#define MAX_IMPORTED_GVARS 1024
212
#endif
213
214
static StructImportedGVars ImportedGVars[MAX_IMPORTED_GVARS];
215
static Int NrImportedGVars;
216
217
static StructImportedGVars ImportedFuncs[MAX_IMPORTED_GVARS];
218
static Int NrImportedFuncs;
219
220
char *original_argv0;
221
static char **sysargv;
222
static char **sysenviron;
223
224
Obj ShellContext = 0;
225
Obj BaseShellContext = 0;
226
UInt ShellContextDepth;
227
228
229
Obj Shell ( Obj context,
230
UInt canReturnVoid,
231
UInt canReturnObj,
232
UInt lastDepth,
233
UInt setTime,
234
Char *prompt,
235
Obj preCommandHook,
236
UInt catchQUIT,
237
Char *inFile,
238
Char *outFile)
239
{
240
UInt time = 0;
241
UInt status;
242
UInt dualSemicolon;
243
UInt oldindent;
244
UInt oldPrintDepth;
245
Obj res;
246
Obj oldShellContext;
247
Obj oldBaseShellContext;
248
Int oldRecursionDepth;
249
oldShellContext = TLS(ShellContext);
250
TLS(ShellContext) = context;
251
oldBaseShellContext = TLS(BaseShellContext);
252
TLS(BaseShellContext) = context;
253
TLS(ShellContextDepth) = 0;
254
oldRecursionDepth = TLS(RecursionDepth);
255
256
/* read-eval-print loop */
257
if (!OpenOutput(outFile))
258
ErrorQuit("SHELL: can't open outfile %s",(Int)outFile,0);
259
260
if(!OpenInput(inFile))
261
{
262
CloseOutput();
263
ErrorQuit("SHELL: can't open infile %s",(Int)inFile,0);
264
}
265
266
oldPrintDepth = TLS(PrintObjDepth);
267
TLS(PrintObjDepth) = 0;
268
oldindent = TLS(Output)->indent;
269
TLS(Output)->indent = 0;
270
271
while ( 1 ) {
272
273
/* start the stopwatch */
274
if (setTime)
275
time = SyTime();
276
277
/* read and evaluate one command */
278
TLS(Prompt) = prompt;
279
ClearError();
280
TLS(PrintObjDepth) = 0;
281
TLS(Output)->indent = 0;
282
TLS(RecursionDepth) = 0;
283
284
/* here is a hook: */
285
if (preCommandHook) {
286
if (!IS_FUNC(preCommandHook))
287
{
288
Pr("#E CommandHook was non-function, ignoring\n",0L,0L);
289
}
290
else
291
{
292
Call0ArgsInNewReader(preCommandHook);
293
/* Recover from a potential break loop: */
294
TLS(Prompt) = prompt;
295
ClearError();
296
}
297
}
298
299
/* now read and evaluate and view one command */
300
status = ReadEvalCommand(TLS(ShellContext), &dualSemicolon);
301
if (TLS(UserHasQUIT))
302
break;
303
304
305
/* handle ordinary command */
306
if ( status == STATUS_END && TLS(ReadEvalResult) != 0 ) {
307
308
/* remember the value in 'last' */
309
if (lastDepth >= 3)
310
AssGVar( Last3, VAL_GVAR( Last2 ) );
311
if (lastDepth >= 2)
312
AssGVar( Last2, VAL_GVAR( Last ) );
313
if (lastDepth >= 1)
314
AssGVar( Last, TLS(ReadEvalResult) );
315
316
/* print the result */
317
if ( ! dualSemicolon ) {
318
ViewObjHandler( TLS(ReadEvalResult) );
319
}
320
321
}
322
323
/* handle return-value or return-void command */
324
else if (status & STATUS_RETURN_VAL)
325
if(canReturnObj)
326
break;
327
else
328
Pr( "'return <object>' cannot be used in this read-eval-print loop\n",
329
0L, 0L );
330
331
else if (status & STATUS_RETURN_VOID)
332
if(canReturnVoid )
333
break;
334
else
335
Pr( "'return' cannot be used in this read-eval-print loop\n",
336
0L, 0L );
337
338
/* handle quit command or <end-of-file> */
339
else if ( status & (STATUS_EOF | STATUS_QUIT ) ) {
340
TLS(RecursionDepth) = 0;
341
TLS(UserHasQuit) = 1;
342
break;
343
}
344
345
/* handle QUIT */
346
else if (status & (STATUS_QQUIT)) {
347
TLS(UserHasQUIT) = 1;
348
break;
349
}
350
351
/* stop the stopwatch */
352
if (setTime)
353
AssGVar( Time, INTOBJ_INT( SyTime() - time ) );
354
355
if (TLS(UserHasQuit))
356
{
357
FlushRestOfInputLine();
358
TLS(UserHasQuit) = 0; /* quit has done its job if we are here */
359
}
360
361
}
362
363
TLS(PrintObjDepth) = oldPrintDepth;
364
TLS(Output)->indent = oldindent;
365
CloseInput();
366
CloseOutput();
367
TLS(BaseShellContext) = oldBaseShellContext;
368
TLS(ShellContext) = oldShellContext;
369
TLS(RecursionDepth) = oldRecursionDepth;
370
if (TLS(UserHasQUIT))
371
{
372
if (catchQUIT)
373
{
374
TLS(UserHasQUIT) = 0;
375
MakeReadWriteGVar(QUITTINGGVar);
376
AssGVar(QUITTINGGVar, True);
377
MakeReadOnlyGVar(QUITTINGGVar);
378
return Fail;
379
}
380
else
381
ReadEvalError();
382
}
383
384
if (status & (STATUS_EOF | STATUS_QUIT | STATUS_QQUIT))
385
{
386
return Fail;
387
}
388
if (status & STATUS_RETURN_VOID)
389
{
390
res = NEW_PLIST(T_PLIST_EMPTY,0);
391
SET_LEN_PLIST(res,0);
392
return res;
393
}
394
if (status & STATUS_RETURN_VAL)
395
{
396
res = NEW_PLIST(T_PLIST_HOM,1);
397
SET_LEN_PLIST(res,1);
398
SET_ELM_PLIST(res,1,TLS(ReadEvalResult));
399
return res;
400
}
401
assert(0);
402
return (Obj) 0;
403
}
404
405
406
407
Obj FuncSHELL (Obj self, Obj args)
408
{
409
Obj context = 0;
410
UInt canReturnVoid = 0;
411
UInt canReturnObj = 0;
412
Int lastDepth = 0;
413
UInt setTime = 0;
414
Obj prompt = 0;
415
Obj preCommandHook = 0;
416
Obj infile;
417
Obj outfile;
418
Obj res;
419
Char promptBuffer[81];
420
UInt catchQUIT = 0;
421
422
if (!IS_PLIST(args) || LEN_PLIST(args) != 10)
423
ErrorMayQuit("SHELL takes 10 arguments",0,0);
424
425
context = ELM_PLIST(args,1);
426
if (TNUM_OBJ(context) != T_LVARS)
427
ErrorMayQuit("SHELL: 1st argument should be a local variables bag",0,0);
428
429
if (ELM_PLIST(args,2) == True)
430
canReturnVoid = 1;
431
else if (ELM_PLIST(args,2) == False)
432
canReturnVoid = 0;
433
else
434
ErrorMayQuit("SHELL: 2nd argument (can return void) should be true or false",0,0);
435
436
if (ELM_PLIST(args,3) == True)
437
canReturnObj = 1;
438
else if (ELM_PLIST(args,3) == False)
439
canReturnObj = 0;
440
else
441
ErrorMayQuit("SHELL: 3rd argument (can return object) should be true or false",0,0);
442
443
if (!IS_INTOBJ(ELM_PLIST(args,4)))
444
ErrorMayQuit("SHELL: 4th argument (last depth) should be a small integer",0,0);
445
lastDepth = INT_INTOBJ(ELM_PLIST(args,4));
446
if (lastDepth < 0 )
447
{
448
Pr("#W SHELL: negative last depth treated as zero",0,0);
449
lastDepth = 0;
450
}
451
else if (lastDepth > 3 )
452
{
453
Pr("#W SHELL: last depth greater than 3 treated as 3",0,0);
454
lastDepth = 3;
455
}
456
457
if (ELM_PLIST(args,5) == True)
458
setTime = 1;
459
else if (ELM_PLIST(args,5) == False)
460
setTime = 0;
461
else
462
ErrorMayQuit("SHELL: 5th argument (set time) should be true or false",0,0);
463
464
prompt = ELM_PLIST(args,6);
465
if (!IsStringConv(prompt) || GET_LEN_STRING(prompt) > 80)
466
ErrorMayQuit("SHELL: 6th argument (prompt) must be a string of length at most 80 characters",0,0);
467
promptBuffer[0] = '\0';
468
strlcat(promptBuffer, CSTR_STRING(prompt), sizeof(promptBuffer));
469
470
preCommandHook = ELM_PLIST(args,7);
471
472
if (preCommandHook == False)
473
preCommandHook = 0;
474
else if (!IS_FUNC(preCommandHook))
475
ErrorMayQuit("SHELL: 7th argument (preCommandHook) must be function or false",0,0);
476
477
478
infile = ELM_PLIST(args,8);
479
if (!IsStringConv(infile))
480
ErrorMayQuit("SHELL: 8th argument (infile) must be a string",0,0);
481
482
outfile = ELM_PLIST(args,9);
483
if (!IsStringConv(infile))
484
ErrorMayQuit("SHELL: 9th argument (outfile) must be a string",0,0);
485
486
if (ELM_PLIST(args,10) == True)
487
catchQUIT = 1;
488
else if (ELM_PLIST(args,10) == False)
489
catchQUIT = 0;
490
else
491
ErrorMayQuit("SHELL: 10th argument (catch QUIT) should be true or false",0,0);
492
493
res = Shell(context, canReturnVoid, canReturnObj, lastDepth, setTime, promptBuffer, preCommandHook, catchQUIT,
494
CSTR_STRING(infile), CSTR_STRING(outfile));
495
496
TLS(UserHasQuit) = 0;
497
return res;
498
}
499
#ifdef HAVE_REALPATH
500
501
static void StrAppend(char **st, const char *st2)
502
{
503
Int len,len2;
504
if (*st == NULL)
505
len = 0;
506
else
507
len = strlen(*st);
508
len2 = strlen(st2);
509
*st = realloc(*st,len+len2+1);
510
if (*st == NULL) {
511
printf("Extremely unexpected out of memory error. Giving up.\n");
512
exit(1);
513
}
514
memcpy(*st + len, st2, len2);
515
}
516
517
static void DoFindMyself(char *myself, char **mypath, char **gappath)
518
{
519
char *tmppath;
520
char *p;
521
522
/* First we find our own position in the filesystem: */
523
*mypath = realpath(myself,NULL);
524
if (*mypath == NULL) {
525
printf("Could not determine my own path, giving up.\n");
526
exit(-1);
527
}
528
tmppath = NULL;
529
StrAppend(&tmppath,*mypath);
530
p = tmppath+strlen(tmppath);
531
while (*p != '/') p--;
532
*p = 0;
533
StrAppend(&tmppath,"/../..");
534
*gappath = realpath(tmppath,NULL);
535
if (*gappath == NULL) {
536
printf("Could not determine GAP path, giving up.\n");
537
exit(-2);
538
}
539
free(tmppath);
540
}
541
542
543
int DoCreateStartupScript(int argc, char *argv[], int withws)
544
{
545
/* This is used to create a startup shell script, possibly using
546
* a saved workspace in a standard location. */
547
/* We can use malloc/realloc here arbitrarily since this GAP
548
* process will never start its memory manager before terminating! */
549
char *mypath;
550
char *gappath;
551
char *tmppath;
552
char *p;
553
FILE *f;
554
int i;
555
556
DoFindMyself(argv[0],&mypath,&gappath);
557
558
/* Now write out the startup script: */
559
f = fopen(argv[2],"w");
560
if (f == NULL) {
561
printf("Could not write startup script to\n %s\ngiving up.\n",argv[2]);
562
return -3;
563
}
564
fprintf(f,"#!/bin/sh\n");
565
fprintf(f,"# Created by %s\n",mypath);
566
fprintf(f,"GAP_DIR=\"%s\"\n",gappath);
567
fprintf(f,"GAP_PRG=\"%s\"\n",mypath);
568
fprintf(f,"GAP_ARCH=\"%s\"\n",SYS_ARCH);
569
tmppath = NULL;
570
StrAppend(&tmppath,SYS_ARCH);
571
p = tmppath;
572
while (*p != 0 && *p != '/') p++;
573
*p++ = 0;
574
fprintf(f,"GAP_ARCH_SYS=\"%s\"\n",tmppath);
575
fprintf(f,"GAP_ARCH_ABI=\"%s\"\n",p); // FIXME: WRONG
576
fprintf(f,"exec %s -l %s",mypath,gappath);
577
if (withws) {
578
tmppath[0] = 0;
579
StrAppend(&tmppath,mypath);
580
p = tmppath+strlen(tmppath);
581
while (*p != '/') p--;
582
p[1] = 0;
583
StrAppend(&tmppath,"workspace.gap");
584
fprintf(f," -L %s",tmppath);
585
}
586
for (i = 3;i < argc;i++) fprintf(f," %s",argv[i]);
587
fprintf(f," \"$@\"\n");
588
fclose(f);
589
#ifdef HAVE_CHMOD
590
chmod(argv[2],S_IRUSR | S_IWUSR | S_IXUSR |
591
S_IRGRP | S_IWGRP | S_IXGRP |
592
S_IROTH | S_IXOTH);
593
#else
594
printf("Warning: Do not have chmod to make script executable!\n");
595
#endif
596
free(tmppath);
597
free(mypath);
598
free(gappath);
599
return 0;
600
}
601
602
int DoCreateWorkspace(char *myself)
603
{
604
/* This is used to create an architecture-dependent saved
605
* workspace in a standard location. */
606
char *mypath;
607
char *gappath;
608
char *command;
609
char *tmppath;
610
char *p;
611
FILE *f;
612
613
DoFindMyself(myself,&mypath,&gappath);
614
615
/* Now we create a saved workspace: */
616
printf("Creating workspace...\n");
617
command = NULL;
618
StrAppend(&command,mypath);
619
StrAppend(&command," -r");
620
StrAppend(&command," -l ");
621
StrAppend(&command,gappath);
622
623
tmppath = NULL;
624
StrAppend(&tmppath,mypath);
625
p = tmppath+strlen(tmppath);
626
while (*p != '/') p--;
627
p[1] = 0;
628
StrAppend(&tmppath,"workspace.gap");
629
630
/* Now to the action: */
631
f = popen(command,"w");
632
if (f == NULL) {
633
printf("Could not start myself to save workspace, giving up.\n");
634
return -6;
635
}
636
fprintf(f,"??blabla\n");
637
fprintf(f,"SaveWorkspace(\"%s\");\n",tmppath);
638
fprintf(f,"quit;\n");
639
fflush(f);
640
pclose(f);
641
printf("\nDone creating workspace in\n %s\n",tmppath);
642
643
free(tmppath);
644
free(command);
645
free(gappath);
646
free(mypath);
647
648
return 0;
649
}
650
651
int DoFixGac(char *myself)
652
{
653
char *mypath;
654
char *gappath;
655
FILE *f;
656
char *gacpath;
657
char *gapbin;
658
char *newpath;
659
char *p,*q,*r;
660
char *buf,*buf2;
661
size_t len,written;
662
663
DoFindMyself(myself,&mypath,&gappath);
664
gacpath = NULL;
665
StrAppend(&gacpath,mypath);
666
p = gacpath + strlen(gacpath);
667
while (*p != '/') p--;
668
*p = 0;
669
gapbin = NULL;
670
StrAppend(&gapbin,gacpath);
671
StrAppend(&gacpath,"/gac");
672
newpath = NULL;
673
StrAppend(&newpath,gacpath);
674
StrAppend(&newpath,".new");
675
f = fopen(gacpath,"r");
676
if (f == NULL) {
677
printf("Could not open gac. Giving up.\n");
678
return -7;
679
}
680
buf = malloc(65536);
681
buf2 = malloc(65536+strlen(gapbin)+10);
682
if (buf == NULL || buf2 == NULL) {
683
printf("Could not allocate 128kB of memory. Giving up.\n");
684
return -8;
685
}
686
len = fread(buf,1,65534,f);
687
fclose(f);
688
689
/* Now manipulate it: */
690
p = buf;
691
p[len] = 0;
692
p[len+1] = 0;
693
q = buf2;
694
while (*p) {
695
if (!strncmp(p,"gap_bin=",8)) {
696
while (*p != '\n' && *p != 0) p++;
697
*q++ = 'g'; *q++ = 'a'; *q++ = 'p'; *q++ = '_';
698
*q++ = 'b'; *q++ = 'i'; *q++ = 'n'; *q++ = '=';
699
r = gapbin;
700
while (*r) *q++ = *r++;
701
*q++ = '\n';
702
} else {
703
while (*p != '\n' && *p != 0) *q++ = *p++;
704
*q++ = *p++;
705
}
706
}
707
len = q - buf2;
708
709
f = fopen(newpath,"w");
710
if (f == NULL) {
711
printf("Could not open gac.new. Giving up.\n");
712
return -9;
713
}
714
written = fwrite(buf2,1,len,f);
715
if (written < len) {
716
printf("Could not write gac.new. Giving up.\n");
717
fclose(f);
718
return -10;
719
}
720
if (fclose(f) < 0) {
721
printf("Could not close gac.new. Giving up.\n");
722
fclose(f);
723
return -11;
724
}
725
if (rename(newpath,gacpath) < 0) {
726
printf("Could not replace gac with new version. Giving up.\n");
727
return -12;
728
}
729
return 0;
730
}
731
#endif
732
733
#ifdef COMPILECYGWINDLL
734
#define main realmain
735
#endif
736
737
int main (
738
int argc,
739
char * argv [],
740
char * environ [] )
741
{
742
UInt type; /* result of compile */
743
Obj func; /* function (compiler) */
744
Int4 crc; /* crc of file to compile */
745
746
#ifdef HAVE_REALPATH
747
if (argc >= 3 && !strcmp(argv[1],"--createstartupscript")) {
748
return DoCreateStartupScript(argc,argv,0);
749
}
750
if (argc >= 3 && !strcmp(argv[1],"--createstartupscriptwithws")) {
751
return DoCreateStartupScript(argc,argv,1);
752
}
753
if (argc >= 2 && !strcmp(argv[1],"--createworkspace")) {
754
return DoCreateWorkspace(argv[0]);
755
}
756
if (argc >= 2 && !strcmp(argv[1],"--fixgac")) {
757
return DoFixGac(argv[0]);
758
}
759
#endif
760
761
original_argv0 = argv[0];
762
sysargv = argv;
763
sysenviron = environ;
764
765
/* Initialize assorted variables in this file */
766
/* BreakOnError = 1;
767
ErrorCount = 0; */
768
NrImportedGVars = 0;
769
NrImportedFuncs = 0;
770
TLS(UserHasQUIT) = 0;
771
TLS(UserHasQuit) = 0;
772
SystemErrorCode = 0;
773
774
/* initialize everything and read init.g which runs the GAP session */
775
InitializeGap( &argc, argv );
776
if (!TLS(UserHasQUIT)) { /* maybe the user QUIT from the initial
777
read of init.g somehow*/
778
/* maybe compile in which case init.g got skipped */
779
if ( SyCompilePlease ) {
780
if ( ! OpenInput(SyCompileInput) ) {
781
SyExit(1);
782
}
783
func = READ_AS_FUNC();
784
crc = SyGAPCRC(SyCompileInput);
785
if (strlen(SyCompileOptions) != 0)
786
SetCompileOpts(SyCompileOptions);
787
type = CompileFunc(
788
SyCompileOutput,
789
func,
790
SyCompileName,
791
crc,
792
SyCompileMagic1 );
793
if ( type == 0 )
794
SyExit( 1 );
795
SyExit( 0 );
796
}
797
}
798
SyExit(SystemErrorCode);
799
return 0;
800
}
801
802
/****************************************************************************
803
**
804
*F FuncID_FUNC( <self>, <val1> ) . . . . . . . . . . . . . . . return <val1>
805
*/
806
Obj FuncID_FUNC (
807
Obj self,
808
Obj val1 )
809
{
810
return val1;
811
}
812
813
/****************************************************************************
814
**
815
*F FuncRETURN_FIRST( <self>, <args> ) . . . . . . . . Return first argument
816
*/
817
Obj FuncRETURN_FIRST (
818
Obj self,
819
Obj args )
820
{
821
if (!IS_PLIST(args) || LEN_PLIST(args) < 1)
822
ErrorMayQuit("RETURN_FIRST requires one or more arguments",0,0);
823
824
return ELM_PLIST(args, 1);
825
}
826
827
/****************************************************************************
828
**
829
*F FuncRETURN_NOTHING( <self>, <arg> ) . . . . . . . . . . . Return nothing
830
*/
831
Obj FuncRETURN_NOTHING (
832
Obj self,
833
Obj arg )
834
{
835
return 0;
836
}
837
838
839
/****************************************************************************
840
**
841
*F FuncRuntime( <self> ) . . . . . . . . . . . . internal function 'Runtime'
842
**
843
** 'FuncRuntime' implements the internal function 'Runtime'.
844
**
845
** 'Runtime()'
846
**
847
** 'Runtime' returns the time spent since the start of GAP in milliseconds.
848
** How much time execution of statements take is of course system dependent.
849
** The accuracy of this number is also system dependent.
850
*/
851
Obj FuncRuntime (
852
Obj self )
853
{
854
return INTOBJ_INT( SyTime() );
855
}
856
857
858
Obj FuncRUNTIMES( Obj self)
859
{
860
Obj res;
861
res = NEW_PLIST(T_PLIST, 4);
862
SET_LEN_PLIST(res, 4);
863
SET_ELM_PLIST(res, 1, INTOBJ_INT( SyTime() ));
864
SET_ELM_PLIST(res, 2, INTOBJ_INT( SyTimeSys() ));
865
SET_ELM_PLIST(res, 3, INTOBJ_INT( SyTimeChildren() ));
866
SET_ELM_PLIST(res, 4, INTOBJ_INT( SyTimeChildrenSys() ));
867
return res;
868
}
869
870
871
/****************************************************************************
872
**
873
*F FuncSizeScreen( <self>, <args> ) . . . . internal function 'SizeScreen'
874
**
875
** 'FuncSizeScreen' implements the internal function 'SizeScreen' to get
876
** or set the actual screen size.
877
**
878
** 'SizeScreen()'
879
**
880
** In this form 'SizeScreen' returns the size of the screen as a list with
881
** two entries. The first is the length of each line, the second is the
882
** number of lines.
883
**
884
** 'SizeScreen( [ <x>, <y> ] )'
885
**
886
** In this form 'SizeScreen' sets the size of the screen. <x> is the length
887
** of each line, <y> is the number of lines. Either value may be missing,
888
** to leave this value unaffected. Note that those parameters can also be
889
** set with the command line options '-x <x>' and '-y <y>'.
890
*/
891
Obj FuncSizeScreen (
892
Obj self,
893
Obj args )
894
{
895
Obj size; /* argument and result list */
896
Obj elm; /* one entry from size */
897
UInt len; /* length of lines on the screen */
898
UInt nr; /* number of lines on the screen */
899
900
/* check the arguments */
901
while ( ! IS_SMALL_LIST(args) || 1 < LEN_LIST(args) ) {
902
args = ErrorReturnObj(
903
"Function: number of arguments must be 0 or 1 (not %d)",
904
LEN_LIST(args), 0L,
905
"you can replace the argument list <args> via 'return <args>;'" );
906
}
907
908
/* get the arguments */
909
if ( LEN_LIST(args) == 0 ) {
910
size = NEW_PLIST( T_PLIST, 0 );
911
SET_LEN_PLIST( size, 0 );
912
}
913
914
/* otherwise check the argument */
915
else {
916
size = ELM_LIST( args, 1 );
917
while ( ! IS_SMALL_LIST(size) || 2 < LEN_LIST(size) ) {
918
size = ErrorReturnObj(
919
"SizeScreen: <size> must be a list of length 2",
920
0L, 0L,
921
"you can replace <size> via 'return <size>;'" );
922
}
923
}
924
925
/* extract the length */
926
if ( LEN_LIST(size) < 1 || ELM0_LIST(size,1) == 0 ) {
927
len = 0;
928
}
929
else {
930
elm = ELMW_LIST(size,1);
931
while ( TNUM_OBJ(elm) != T_INT ) {
932
elm = ErrorReturnObj(
933
"SizeScreen: <x> must be an integer",
934
0L, 0L,
935
"you can replace <x> via 'return <x>;'" );
936
}
937
len = INT_INTOBJ( elm );
938
if ( len < 20 ) len = 20;
939
if ( MAXLENOUTPUTLINE < len ) len = MAXLENOUTPUTLINE;
940
}
941
942
/* extract the number */
943
if ( LEN_LIST(size) < 2 || ELM0_LIST(size,2) == 0 ) {
944
nr = 0;
945
}
946
else {
947
elm = ELMW_LIST(size,2);
948
while ( TNUM_OBJ(elm) != T_INT ) {
949
elm = ErrorReturnObj(
950
"SizeScreen: <y> must be an integer",
951
0L, 0L,
952
"you can replace <y> via 'return <y>;'" );
953
}
954
nr = INT_INTOBJ( elm );
955
if ( nr < 10 ) nr = 10;
956
}
957
958
/* set length and number */
959
if (len != 0)
960
{
961
SyNrCols = len;
962
SyNrColsLocked = 1;
963
}
964
if (nr != 0)
965
{
966
SyNrRows = nr;
967
SyNrRowsLocked = 1;
968
}
969
970
/* make and return the size of the screen */
971
size = NEW_PLIST( T_PLIST, 2 );
972
SET_LEN_PLIST( size, 2 );
973
SET_ELM_PLIST( size, 1, INTOBJ_INT(SyNrCols) );
974
SET_ELM_PLIST( size, 2, INTOBJ_INT(SyNrRows) );
975
return size;
976
977
}
978
979
980
/****************************************************************************
981
**
982
*F FuncWindowCmd( <self>, <args> ) . . . . . . . . execute a window command
983
*/
984
static Obj WindowCmdString;
985
986
Obj FuncWindowCmd (
987
Obj self,
988
Obj args )
989
{
990
Obj tmp;
991
Obj list;
992
Int len;
993
Int n, m;
994
Int i;
995
Char * ptr;
996
Char * qtr;
997
998
/* check arguments */
999
while ( ! IS_SMALL_LIST(args) ) {
1000
args = ErrorReturnObj( "argument list must be a list (not a %s)",
1001
(Int)TNAM_OBJ(args), 0L,
1002
"you can replace the argument list <args> via 'return <args>;'" );
1003
1004
}
1005
tmp = ELM_LIST(args,1);
1006
while ( ! IsStringConv(tmp) || 3 != LEN_LIST(tmp) ) {
1007
while ( ! IsStringConv(tmp) ) {
1008
tmp = ErrorReturnObj( "<cmd> must be a string (not a %s)",
1009
(Int)TNAM_OBJ(tmp), 0L,
1010
"you can replace <cmd> via 'return <cmd>;'" );
1011
}
1012
if ( 3 != LEN_LIST(tmp) ) {
1013
tmp = ErrorReturnObj( "<cmd> must be a string of length 3",
1014
0L, 0L,
1015
"you can replace <cmd> via 'return <cmd>;'" );
1016
}
1017
}
1018
1019
/* compute size needed to store argument string */
1020
len = 13;
1021
for ( i = 2; i <= LEN_LIST(args); i++ )
1022
{
1023
tmp = ELM_LIST( args, i );
1024
while ( TNUM_OBJ(tmp) != T_INT && ! IsStringConv(tmp) ) {
1025
tmp = ErrorReturnObj(
1026
"%d. argument must be a string or integer (not a %s)",
1027
i, (Int)TNAM_OBJ(tmp),
1028
"you can replace the argument <arg> via 'return <arg>;'" );
1029
SET_ELM_PLIST( args, i, tmp );
1030
}
1031
if ( TNUM_OBJ(tmp) == T_INT )
1032
len += 12;
1033
else
1034
len += 12 + LEN_LIST(tmp);
1035
}
1036
if ( SIZE_OBJ(WindowCmdString) <= len ) {
1037
ResizeBag( WindowCmdString, 2*len+1 );
1038
}
1039
1040
/* convert <args> into an argument string */
1041
ptr = (Char*) CSTR_STRING(WindowCmdString);
1042
1043
/* first the command name */
1044
memcpy( ptr, CSTR_STRING( ELM_LIST(args,1) ), 3 + 1 );
1045
ptr += 3;
1046
1047
/* and now the arguments */
1048
for ( i = 2; i <= LEN_LIST(args); i++ )
1049
{
1050
tmp = ELM_LIST(args,i);
1051
1052
if ( TNUM_OBJ(tmp) == T_INT ) {
1053
*ptr++ = 'I';
1054
m = INT_INTOBJ(tmp);
1055
for ( m = (m<0)?-m:m; 0 < m; m /= 10 )
1056
*ptr++ = (m%10) + '0';
1057
if ( INT_INTOBJ(tmp) < 0 )
1058
*ptr++ = '-';
1059
else
1060
*ptr++ = '+';
1061
}
1062
else {
1063
*ptr++ = 'S';
1064
m = LEN_LIST(tmp);
1065
for ( ; 0 < m; m/= 10 )
1066
*ptr++ = (m%10) + '0';
1067
*ptr++ = '+';
1068
qtr = CSTR_STRING(tmp);
1069
for ( m = LEN_LIST(tmp); 0 < m; m-- )
1070
*ptr++ = *qtr++;
1071
}
1072
}
1073
*ptr = 0;
1074
1075
/* now call the window front end with the argument string */
1076
qtr = CSTR_STRING(WindowCmdString);
1077
ptr = SyWinCmd( qtr, strlen(qtr) );
1078
len = strlen(ptr);
1079
1080
/* now convert result back into a list */
1081
list = NEW_PLIST( T_PLIST, 11 );
1082
SET_LEN_PLIST( list, 0 );
1083
i = 1;
1084
while ( 0 < len ) {
1085
if ( *ptr == 'I' ) {
1086
ptr++;
1087
for ( n=0,m=1; '0' <= *ptr && *ptr <= '9'; ptr++,m *= 10,len-- )
1088
n += (*ptr-'0') * m;
1089
if ( *ptr++ == '-' )
1090
n *= -1;
1091
len -= 2;
1092
AssPlist( list, i, INTOBJ_INT(n) );
1093
}
1094
else if ( *ptr == 'S' ) {
1095
ptr++;
1096
for ( n=0,m=1; '0' <= *ptr && *ptr <= '9'; ptr++,m *= 10,len-- )
1097
n += (*ptr-'0') * m;
1098
ptr++; /* ignore the '+' */
1099
C_NEW_STRING(tmp, n, ptr);
1100
ptr += n;
1101
len -= n+2;
1102
AssPlist( list, i, tmp );
1103
}
1104
else {
1105
ErrorQuit( "unknown return value '%s'", (Int)ptr, 0 );
1106
return 0;
1107
}
1108
i++;
1109
}
1110
1111
/* if the first entry is one signal an error */
1112
if ( ELM_LIST(list,1) == INTOBJ_INT(1) ) {
1113
C_NEW_STRING_CONST(tmp, "window system: ");
1114
SET_ELM_PLIST( list, 1, tmp );
1115
SET_LEN_PLIST( list, i-1 );
1116
return CALL_XARGS(Error,list);
1117
/* return FuncError( 0, list );*/
1118
}
1119
else {
1120
for ( m = 1; m <= i-2; m++ )
1121
SET_ELM_PLIST( list, m, ELM_PLIST(list,m+1) );
1122
SET_LEN_PLIST( list, i-2 );
1123
return list;
1124
}
1125
}
1126
1127
1128
/****************************************************************************
1129
**
1130
1131
*F * * * * * * * * * * * * * * error functions * * * * * * * * * * * * * * *
1132
*/
1133
1134
1135
1136
/****************************************************************************
1137
**
1138
*F FuncDownEnv( <self>, <level> ) . . . . . . . . . change the environment
1139
*/
1140
1141
Obj ErrorLVars0;
1142
Obj ErrorLVars;
1143
Int ErrorLLevel;
1144
1145
extern Obj BottomLVars;
1146
1147
1148
void DownEnvInner( Int depth )
1149
{
1150
/* if we really want to go up */
1151
if ( depth < 0 && -TLS(ErrorLLevel) <= -depth ) {
1152
depth = 0;
1153
TLS(ErrorLVars) = TLS(ErrorLVars0);
1154
TLS(ErrorLLevel) = 0;
1155
TLS(ShellContextDepth) = 0;
1156
TLS(ShellContext) = TLS(BaseShellContext);
1157
}
1158
else if ( depth < 0 ) {
1159
depth = -TLS(ErrorLLevel) + depth;
1160
TLS(ErrorLVars) = TLS(ErrorLVars0);
1161
TLS(ErrorLLevel) = 0;
1162
TLS(ShellContextDepth) = 0;
1163
TLS(ShellContext) = TLS(BaseShellContext);
1164
}
1165
1166
/* now go down */
1167
while ( 0 < depth
1168
&& TLS(ErrorLVars) != TLS(BottomLVars)
1169
&& PTR_BAG(TLS(ErrorLVars))[2] != TLS(BottomLVars) ) {
1170
TLS(ErrorLVars) = PTR_BAG(TLS(ErrorLVars))[2];
1171
TLS(ErrorLLevel)--;
1172
TLS(ShellContext) = PTR_BAG(TLS(ShellContext))[2];
1173
TLS(ShellContextDepth)--;
1174
depth--;
1175
}
1176
}
1177
1178
Obj FuncDownEnv (
1179
Obj self,
1180
Obj args )
1181
{
1182
Int depth;
1183
1184
if ( LEN_LIST(args) == 0 ) {
1185
depth = 1;
1186
}
1187
else if ( LEN_LIST(args) == 1 && IS_INTOBJ( ELM_PLIST(args,1) ) ) {
1188
depth = INT_INTOBJ( ELM_PLIST( args, 1 ) );
1189
}
1190
else {
1191
ErrorQuit( "usage: DownEnv( [ <depth> ] )", 0L, 0L );
1192
return 0;
1193
}
1194
if ( TLS(ErrorLVars) == 0 ) {
1195
Pr( "not in any function\n", 0L, 0L );
1196
return 0;
1197
}
1198
1199
DownEnvInner( depth);
1200
1201
/* return nothing */
1202
return 0;
1203
}
1204
1205
Obj FuncUpEnv (
1206
Obj self,
1207
Obj args )
1208
{
1209
Int depth;
1210
if ( LEN_LIST(args) == 0 ) {
1211
depth = 1;
1212
}
1213
else if ( LEN_LIST(args) == 1 && IS_INTOBJ( ELM_PLIST(args,1) ) ) {
1214
depth = INT_INTOBJ( ELM_PLIST( args, 1 ) );
1215
}
1216
else {
1217
ErrorQuit( "usage: UpEnv( [ <depth> ] )", 0L, 0L );
1218
return 0;
1219
}
1220
if ( TLS(ErrorLVars) == 0 ) {
1221
Pr( "not in any function\n", 0L, 0L );
1222
return 0;
1223
}
1224
1225
DownEnvInner(-depth);
1226
return 0;
1227
}
1228
1229
1230
Obj FuncPrintExecutingStatement(Obj self, Obj context)
1231
{
1232
Obj currLVars = TLS(CurrLVars);
1233
Expr call;
1234
if (context == TLS(BottomLVars))
1235
return (Obj) 0;
1236
SWITCH_TO_OLD_LVARS(context);
1237
call = BRK_CALL_TO();
1238
if ( call == 0 ) {
1239
Pr( "<compiled or corrupted statement> ", 0L, 0L );
1240
}
1241
#if T_PROCCALL_0ARGS
1242
else if ( FIRST_STAT_TNUM <= TNUM_STAT(call)
1243
&& TNUM_STAT(call) <= LAST_STAT_TNUM ) {
1244
#else
1245
else if ( TNUM_STAT(call) <= LAST_STAT_TNUM ) {
1246
#endif
1247
PrintStat( call );
1248
Pr(" at %s:%d",(UInt)CSTR_STRING(FILENAME_STAT(call)),LINE_STAT(call));
1249
}
1250
else if ( FIRST_EXPR_TNUM <= TNUM_EXPR(call)
1251
&& TNUM_EXPR(call) <= LAST_EXPR_TNUM ) {
1252
PrintExpr( call );
1253
Pr(" at %s:%d",(UInt)CSTR_STRING(FILENAME_STAT(call)),LINE_STAT(call));
1254
}
1255
SWITCH_TO_OLD_LVARS( currLVars );
1256
return (Obj) 0;
1257
}
1258
1259
/****************************************************************************
1260
**
1261
*F FuncCallFuncTrapError( <self>, <func> )
1262
**
1263
*/
1264
1265
/* syJmp_buf CatchBuffer; */
1266
Obj ThrownObject = 0;
1267
1268
Obj FuncCALL_WITH_CATCH( Obj self, Obj func, Obj args )
1269
{
1270
syJmp_buf readJmpError;
1271
Obj res;
1272
Obj currLVars;
1273
Obj result;
1274
Int recursionDepth;
1275
Stat currStat;
1276
if (!IS_FUNC(func))
1277
ErrorMayQuit("CALL_WITH_CATCH(<func>, <args>): <func> must be a function",0,0);
1278
if (!IS_LIST(args))
1279
ErrorMayQuit("CALL_WITH_CATCH(<func>, <args>): <args> must be a list",0,0);
1280
memcpy((void *)&readJmpError, (void *)&TLS(ReadJmpError), sizeof(syJmp_buf));
1281
currLVars = TLS(CurrLVars);
1282
currStat = TLS(CurrStat);
1283
recursionDepth = TLS(RecursionDepth);
1284
res = NEW_PLIST(T_PLIST_DENSE+IMMUTABLE,2);
1285
if (sySetjmp(TLS(ReadJmpError))) {
1286
SET_LEN_PLIST(res,2);
1287
SET_ELM_PLIST(res,1,False);
1288
SET_ELM_PLIST(res,2,TLS(ThrownObject));
1289
CHANGED_BAG(res);
1290
TLS(ThrownObject) = 0;
1291
TLS(CurrLVars) = currLVars;
1292
TLS(PtrLVars) = PTR_BAG(TLS(CurrLVars));
1293
TLS(PtrBody) = (Stat*)PTR_BAG(BODY_FUNC(CURR_FUNC));
1294
TLS(CurrStat) = currStat;
1295
TLS(RecursionDepth) = recursionDepth;
1296
} else {
1297
result = CallFuncList(func, args);
1298
SET_ELM_PLIST(res,1,True);
1299
if (result)
1300
{
1301
SET_LEN_PLIST(res,2);
1302
SET_ELM_PLIST(res,2,result);
1303
CHANGED_BAG(res);
1304
}
1305
else
1306
SET_LEN_PLIST(res,1);
1307
}
1308
memcpy((void *)&TLS(ReadJmpError), (void *)&readJmpError, sizeof(syJmp_buf));
1309
return res;
1310
}
1311
1312
Obj FuncJUMP_TO_CATCH( Obj self, Obj payload)
1313
{
1314
TLS(ThrownObject) = payload;
1315
syLongjmp(TLS(ReadJmpError), 1);
1316
return 0;
1317
}
1318
1319
1320
UInt UserHasQuit;
1321
UInt UserHasQUIT;
1322
UInt SystemErrorCode;
1323
1324
Obj FuncSetUserHasQuit( Obj Self, Obj value)
1325
{
1326
TLS(UserHasQuit) = INT_INTOBJ(value);
1327
if (TLS(UserHasQuit))
1328
TLS(RecursionDepth) = 0;
1329
return 0;
1330
}
1331
1332
1333
#define MAX_TIMEOUT_NESTING_DEPTH 1024
1334
1335
syJmp_buf AlarmJumpBuffers[MAX_TIMEOUT_NESTING_DEPTH];
1336
UInt NumAlarmJumpBuffers = 0;
1337
1338
Obj FuncTIMEOUTS_SUPPORTED(Obj self) {
1339
return SyHaveAlarms ? True: False;
1340
}
1341
1342
Obj FuncCALL_WITH_TIMEOUT( Obj self, Obj seconds, Obj microseconds, Obj func, Obj args )
1343
{
1344
Obj res;
1345
Obj currLVars;
1346
Obj result;
1347
Int recursionDepth;
1348
Stat currStat;
1349
1350
if (!SyHaveAlarms)
1351
ErrorMayQuit("CALL_WITH_TIMEOUT: timeouts not supported on this system", 0L, 0L);
1352
if (!IS_INTOBJ(seconds) || 0 > INT_INTOBJ(seconds))
1353
ErrorMayQuit("CALL_WITH_TIMEOUT(<seconds>, <microseconds>, <func>, <args>):"
1354
" <seconds> must be a non-negative small integer",0,0);
1355
if (!IS_INTOBJ(microseconds) || 0 > INT_INTOBJ(microseconds) || 999999999 < INT_INTOBJ(microseconds))
1356
ErrorMayQuit("CALL_WITH_TIMEOUT(<seconds>, <microseconds>, <func>, <args>):"
1357
" <microseconds> must be a non-negative small integer less than 10^9",0,0);
1358
if (!IS_FUNC(func))
1359
ErrorMayQuit("CALL_WITH_TIMEOUT(<seconds>, <microseconds>, <func>,<args>): <func> must be a function",0,0);
1360
if (!IS_LIST(args))
1361
ErrorMayQuit("CALL_WITH_TIMEOUT(<seconds>, <microseconds>, <func>,<args>): <args> must be a list",0,0);
1362
if (SyAlarmRunning) {
1363
ErrorMayQuit("CALL_WITH_TIMEOUT cannot currently be nested except via break loops."
1364
" There is already a timeout running", 0, 0);
1365
}
1366
if (NumAlarmJumpBuffers >= MAX_TIMEOUT_NESTING_DEPTH-1)
1367
ErrorMayQuit("Nesting depth of timeouts via break loops limited to %i", MAX_TIMEOUT_NESTING_DEPTH, 0L);
1368
currLVars = TLS(CurrLVars);
1369
currStat = TLS(CurrStat);
1370
recursionDepth = TLS(RecursionDepth);
1371
res = NEW_PLIST( T_PLIST_DENSE+IMMUTABLE, 2 );
1372
SET_LEN_PLIST(res, 1);
1373
if (sySetjmp(AlarmJumpBuffers[NumAlarmJumpBuffers++])) {
1374
/* Timeout happened */
1375
TLS(CurrLVars) = currLVars;
1376
TLS(PtrLVars) = PTR_BAG(TLS(CurrLVars));
1377
TLS(PtrBody) = (Stat*)PTR_BAG(BODY_FUNC(CURR_FUNC));
1378
TLS(CurrStat) = currStat;
1379
TLS(RecursionDepth) = recursionDepth;
1380
SET_ELM_PLIST(res, 1, False);
1381
} else {
1382
SyInstallAlarm( INT_INTOBJ(seconds), 1000*INT_INTOBJ(microseconds));
1383
result = CallFuncList(func, args);
1384
/* make sure the alarm is not still running */
1385
SyStopAlarm( NULL, NULL);
1386
/* Now the alarm might have gone off since we executed the last statement
1387
of func. So */
1388
if (SyAlarmHasGoneOff) {
1389
SyAlarmHasGoneOff = 0;
1390
UnInterruptExecStat();
1391
}
1392
assert(NumAlarmJumpBuffers);
1393
NumAlarmJumpBuffers--;
1394
SET_ELM_PLIST(res,1,True);
1395
if (result)
1396
{
1397
SET_LEN_PLIST(res,2);
1398
SET_ELM_PLIST(res,2,result);
1399
}
1400
}
1401
CHANGED_BAG(res);
1402
return res;
1403
}
1404
1405
Obj FuncSTOP_TIMEOUT( Obj self ) {
1406
UInt seconds, nanoseconds;
1407
if (!SyHaveAlarms || !SyAlarmRunning)
1408
return Fail;
1409
SyStopAlarm(&seconds, &nanoseconds);
1410
Obj state = NEW_PLIST(T_PLIST_CYC+IMMUTABLE, 3);
1411
SET_ELM_PLIST(state,1,INTOBJ_INT(seconds));
1412
SET_ELM_PLIST(state,2,INTOBJ_INT(nanoseconds/1000));
1413
SET_ELM_PLIST(state,3,INTOBJ_INT(NumAlarmJumpBuffers));
1414
SET_LEN_PLIST(state,3);
1415
return state;
1416
}
1417
1418
Obj FuncRESUME_TIMEOUT( Obj self, Obj state ) {
1419
if (!SyHaveAlarms || SyAlarmRunning)
1420
return Fail;
1421
if (!IS_PLIST(state) || LEN_PLIST(state) < 2)
1422
return Fail;
1423
if (!IS_INTOBJ(ELM_PLIST(state,1)) ||
1424
!IS_INTOBJ(ELM_PLIST(state,2)))
1425
return Fail;
1426
Int s = INT_INTOBJ(ELM_PLIST(state,1));
1427
Int us = INT_INTOBJ(ELM_PLIST(state,2));
1428
if (s < 0 || us < 0 || us > 999999)
1429
return Fail;
1430
Int depth = INT_INTOBJ(ELM_PLIST(state,3));
1431
if (depth < 0 || depth >= MAX_TIMEOUT_NESTING_DEPTH)
1432
return Fail;
1433
NumAlarmJumpBuffers = depth;
1434
SyInstallAlarm(s, 1000*us);
1435
return True;
1436
}
1437
1438
1439
1440
/****************************************************************************
1441
**
1442
*F ErrorQuit( <msg>, <arg1>, <arg2> ) . . . . . . . . . . . print and quit
1443
*/
1444
1445
static Obj ErrorMessageToGAPString(
1446
const Char * msg,
1447
Int arg1,
1448
Int arg2 )
1449
{
1450
Char message[120];
1451
Obj Message;
1452
SPrTo(message, sizeof(message), msg, arg1, arg2);
1453
message[sizeof(message)-1] = '\0';
1454
C_NEW_STRING_DYN(Message, message);
1455
return Message;
1456
}
1457
1458
Obj CallErrorInner (
1459
const Char * msg,
1460
Int arg1,
1461
Int arg2,
1462
UInt justQuit,
1463
UInt mayReturnVoid,
1464
UInt mayReturnObj,
1465
Obj lateMessage,
1466
UInt printThisStatement)
1467
{
1468
Obj EarlyMsg;
1469
Obj r = NEW_PREC(0);
1470
Obj l;
1471
EarlyMsg = ErrorMessageToGAPString(msg, arg1, arg2);
1472
AssPRec(r, RNamName("context"), TLS(CurrLVars));
1473
AssPRec(r, RNamName("justQuit"), justQuit? True : False);
1474
AssPRec(r, RNamName("mayReturnObj"), mayReturnObj? True : False);
1475
AssPRec(r, RNamName("mayReturnVoid"), mayReturnVoid? True : False);
1476
AssPRec(r, RNamName("printThisStatement"), printThisStatement? True : False);
1477
AssPRec(r, RNamName("lateMessage"), lateMessage);
1478
l = NEW_PLIST(T_PLIST_HOM+IMMUTABLE, 1);
1479
SET_ELM_PLIST(l,1,EarlyMsg);
1480
SET_LEN_PLIST(l,1);
1481
SET_BRK_CALL_TO(TLS(CurrStat));
1482
Obj res = CALL_2ARGS(ErrorInner,r,l);
1483
return res;
1484
}
1485
1486
void ErrorQuit (
1487
const Char * msg,
1488
Int arg1,
1489
Int arg2 )
1490
{
1491
CallErrorInner(msg, arg1, arg2, 1, 0, 0, False, 1);
1492
}
1493
1494
1495
/****************************************************************************
1496
**
1497
*F ErrorQuitBound( <name> ) . . . . . . . . . . . . . . . unbound variable
1498
*/
1499
void ErrorQuitBound (
1500
const Char * name )
1501
{
1502
ErrorQuit(
1503
"variable '%s' must have an assigned value",
1504
(Int)name, 0L );
1505
}
1506
1507
1508
/****************************************************************************
1509
**
1510
*F ErrorQuitFuncResult() . . . . . . . . . . . . . . . . must return a value
1511
*/
1512
void ErrorQuitFuncResult ( void )
1513
{
1514
ErrorQuit(
1515
"function must return a value",
1516
0L, 0L );
1517
}
1518
1519
1520
/****************************************************************************
1521
**
1522
*F ErrorQuitIntSmall( <obj> ) . . . . . . . . . . . . . not a small integer
1523
*/
1524
void ErrorQuitIntSmall (
1525
Obj obj )
1526
{
1527
ErrorQuit(
1528
"<obj> must be a small integer (not a %s)",
1529
(Int)TNAM_OBJ(obj), 0L );
1530
}
1531
1532
1533
/****************************************************************************
1534
**
1535
*F ErrorQuitIntSmallPos( <obj> ) . . . . . . . not a positive small integer
1536
*/
1537
void ErrorQuitIntSmallPos (
1538
Obj obj )
1539
{
1540
ErrorQuit(
1541
"<obj> must be a positive small integer (not a %s)",
1542
(Int)TNAM_OBJ(obj), 0L );
1543
}
1544
1545
/****************************************************************************
1546
**
1547
*F ErrorQuitIntPos( <obj> ) . . . . . . . not a positive small integer
1548
*/
1549
void ErrorQuitIntPos (
1550
Obj obj )
1551
{
1552
ErrorQuit(
1553
"<obj> must be a positive integer (not a %s)",
1554
(Int)TNAM_OBJ(obj), 0L );
1555
}
1556
1557
1558
/****************************************************************************
1559
**
1560
*F ErrorQuitBool( <obj> ) . . . . . . . . . . . . . . . . . . not a boolean
1561
*/
1562
void ErrorQuitBool (
1563
Obj obj )
1564
{
1565
ErrorQuit(
1566
"<obj> must be 'true' or 'false' (not a %s)",
1567
(Int)TNAM_OBJ(obj), 0L );
1568
}
1569
1570
1571
/****************************************************************************
1572
**
1573
*F ErrorQuitFunc( <obj> ) . . . . . . . . . . . . . . . . . not a function
1574
*/
1575
void ErrorQuitFunc (
1576
Obj obj )
1577
{
1578
ErrorQuit(
1579
"<obj> must be a function (not a %s)",
1580
(Int)TNAM_OBJ(obj), 0L );
1581
}
1582
1583
1584
/****************************************************************************
1585
**
1586
*F ErrorQuitNrArgs( <narg>, <args> ) . . . . . . . wrong number of arguments
1587
*/
1588
void ErrorQuitNrArgs (
1589
Int narg,
1590
Obj args )
1591
{
1592
ErrorQuit(
1593
"Function Calls: number of arguments must be %d (not %d)",
1594
narg, LEN_PLIST( args ) );
1595
}
1596
1597
/****************************************************************************
1598
**
1599
*F ErrorQuitRange3( <first>, <second>, <last> ) . . divisibility
1600
*/
1601
void ErrorQuitRange3 (
1602
Obj first,
1603
Obj second,
1604
Obj last)
1605
{
1606
ErrorQuit(
1607
"Range expression <last>-<first> must be divisible by <second>-<first>, not %d %d",
1608
INT_INTOBJ(last)-INT_INTOBJ(first), INT_INTOBJ(second)-INT_INTOBJ(first) );
1609
}
1610
1611
1612
/****************************************************************************
1613
**
1614
*F ErrorReturnObj( <msg>, <arg1>, <arg2>, <msg2> ) . . print and return obj
1615
*/
1616
Obj ErrorReturnObj (
1617
const Char * msg,
1618
Int arg1,
1619
Int arg2,
1620
const Char * msg2 )
1621
{
1622
Obj LateMsg;
1623
C_NEW_STRING_DYN(LateMsg, msg2);
1624
return CallErrorInner(msg, arg1, arg2, 0, 0, 1, LateMsg, 1);
1625
}
1626
1627
1628
/****************************************************************************
1629
**
1630
*F ErrorReturnVoid( <msg>, <arg1>, <arg2>, <msg2> ) . . . print and return
1631
*/
1632
void ErrorReturnVoid (
1633
const Char * msg,
1634
Int arg1,
1635
Int arg2,
1636
const Char * msg2 )
1637
{
1638
Obj LateMsg;
1639
C_NEW_STRING_DYN(LateMsg, msg2);
1640
CallErrorInner( msg, arg1, arg2, 0,1,0,LateMsg, 1);
1641
/* ErrorMode( msg, arg1, arg2, (Obj)0, msg2, 'x' ); */
1642
}
1643
1644
/****************************************************************************
1645
**
1646
*F ErrorMayQuit( <msg>, <arg1>, <arg2> ) . . . print and return
1647
*/
1648
void ErrorMayQuit (
1649
const Char * msg,
1650
Int arg1,
1651
Int arg2)
1652
{
1653
CallErrorInner(msg, arg1, arg2, 0, 0,0, False, 1);
1654
1655
}
1656
1657
Obj Error;
1658
Obj ErrorInner;
1659
1660
1661
/****************************************************************************
1662
**
1663
1664
*F * * * * * * * * * functions for creating the init file * * * * * * * * * *
1665
*/
1666
1667
/* deleted 9/5/11 */
1668
1669
/*************************************************************************
1670
**
1671
1672
*F * * * * * * * * * functions for dynamical/static modules * * * * * * * * *
1673
*/
1674
1675
1676
1677
/****************************************************************************
1678
**
1679
1680
*F FuncGAP_CRC( <self>, <name> ) . . . . . . . create a crc value for a file
1681
*/
1682
Obj FuncGAP_CRC (
1683
Obj self,
1684
Obj filename )
1685
{
1686
/* check the argument */
1687
while ( ! IsStringConv( filename ) ) {
1688
filename = ErrorReturnObj(
1689
"<filename> must be a string (not a %s)",
1690
(Int)TNAM_OBJ(filename), 0L,
1691
"you can replace <filename> via 'return <filename>;'" );
1692
}
1693
1694
/* compute the crc value */
1695
return INTOBJ_INT( SyGAPCRC( CSTR_STRING(filename) ) );
1696
}
1697
1698
1699
/****************************************************************************
1700
**
1701
*F FuncLOAD_DYN( <self>, <name>, <crc> ) . . . try to load a dynamic module
1702
*/
1703
Obj FuncLOAD_DYN (
1704
Obj self,
1705
Obj filename,
1706
Obj crc )
1707
{
1708
InitInfoFunc init;
1709
StructInitInfo * info;
1710
Obj crc1;
1711
Int res;
1712
1713
/* check the argument */
1714
while ( ! IsStringConv( filename ) ) {
1715
filename = ErrorReturnObj(
1716
"<filename> must be a string (not a %s)",
1717
(Int)TNAM_OBJ(filename), 0L,
1718
"you can replace <filename> via 'return <filename>;'" );
1719
}
1720
while ( ! IS_INTOBJ(crc) && crc!=False ) {
1721
crc = ErrorReturnObj(
1722
"<crc> must be a small integer or 'false' (not a %s)",
1723
(Int)TNAM_OBJ(crc), 0L,
1724
"you can replace <crc> via 'return <crc>;'" );
1725
}
1726
1727
/* try to read the module */
1728
init = SyLoadModule( CSTR_STRING(filename) );
1729
if ( (Int)init == 1 )
1730
ErrorQuit( "module '%s' not found", (Int)CSTR_STRING(filename), 0L );
1731
else if ( (Int) init == 3 )
1732
ErrorQuit( "symbol 'Init_Dynamic' not found", 0L, 0L );
1733
else if ( (Int) init == 5 )
1734
ErrorQuit( "forget symbol failed", 0L, 0L );
1735
1736
/* no dynamic library support */
1737
else if ( (Int) init == 7 ) {
1738
if ( SyDebugLoading ) {
1739
Pr( "#I LOAD_DYN: no support for dynamical loading\n", 0L, 0L );
1740
}
1741
return False;
1742
}
1743
1744
/* get the description structure */
1745
info = (*init)();
1746
if ( info == 0 )
1747
ErrorQuit( "call to init function failed", 0L, 0L );
1748
1749
/* check the crc value */
1750
if ( crc != False ) {
1751
crc1 = INTOBJ_INT( info->crc );
1752
if ( ! EQ( crc, crc1 ) ) {
1753
if ( SyDebugLoading ) {
1754
Pr( "#I LOAD_DYN: crc values do not match, gap ", 0L, 0L );
1755
PrintInt( crc );
1756
Pr( ", dyn ", 0L, 0L );
1757
PrintInt( crc1 );
1758
Pr( "\n", 0L, 0L );
1759
}
1760
return False;
1761
}
1762
}
1763
1764
/* link and init me */
1765
info->isGapRootRelative = 0;
1766
res = (info->initKernel)(info);
1767
UpdateCopyFopyInfo();
1768
1769
/* Start a new executor to run the outer function of the module
1770
in global context */
1771
ExecBegin( TLS(BottomLVars) );
1772
res = res || (info->initLibrary)(info);
1773
ExecEnd(res ? STATUS_ERROR : STATUS_END);
1774
if ( res ) {
1775
Pr( "#W init functions returned non-zero exit code\n", 0L, 0L );
1776
}
1777
RecordLoadedModule(info, CSTR_STRING(filename));
1778
1779
return True;
1780
}
1781
1782
1783
/****************************************************************************
1784
**
1785
*F FuncLOAD_STAT( <self>, <name>, <crc> ) . . . . try to load static module
1786
*/
1787
Obj FuncLOAD_STAT (
1788
Obj self,
1789
Obj filename,
1790
Obj crc )
1791
{
1792
StructInitInfo * info = 0;
1793
Obj crc1;
1794
Int k;
1795
Int res;
1796
1797
/* check the argument */
1798
while ( ! IsStringConv( filename ) ) {
1799
filename = ErrorReturnObj(
1800
"<filename> must be a string (not a %s)",
1801
(Int)TNAM_OBJ(filename), 0L,
1802
"you can replace <filename> via 'return <filename>;'" );
1803
}
1804
while ( !IS_INTOBJ(crc) && crc!=False ) {
1805
crc = ErrorReturnObj(
1806
"<crc> must be a small integer or 'false' (not a %s)",
1807
(Int)TNAM_OBJ(crc), 0L,
1808
"you can replace <crc> via 'return <crc>;'" );
1809
}
1810
1811
/* try to find the module */
1812
for ( k = 0; CompInitFuncs[k]; k++ ) {
1813
info = (*(CompInitFuncs[k]))();
1814
if ( info == 0 ) {
1815
continue;
1816
}
1817
if ( ! strcmp( CSTR_STRING(filename), info->name ) ) {
1818
break;
1819
}
1820
}
1821
if ( CompInitFuncs[k] == 0 ) {
1822
if ( SyDebugLoading ) {
1823
Pr( "#I LOAD_STAT: no module named '%s' found\n",
1824
(Int)CSTR_STRING(filename), 0L );
1825
}
1826
return False;
1827
}
1828
1829
/* check the crc value */
1830
if ( crc != False ) {
1831
crc1 = INTOBJ_INT( info->crc );
1832
if ( ! EQ( crc, crc1 ) ) {
1833
if ( SyDebugLoading ) {
1834
Pr( "#I LOAD_STAT: crc values do not match, gap ", 0L, 0L );
1835
PrintInt( crc );
1836
Pr( ", stat ", 0L, 0L );
1837
PrintInt( crc1 );
1838
Pr( "\n", 0L, 0L );
1839
}
1840
return False;
1841
}
1842
}
1843
1844
/* link and init me */
1845
info->isGapRootRelative = 0;
1846
res = (info->initKernel)(info);
1847
UpdateCopyFopyInfo();
1848
/* Start a new executor to run the outer function of the module
1849
in global context */
1850
ExecBegin( TLS(BottomLVars) );
1851
res = res || (info->initLibrary)(info);
1852
ExecEnd(res ? STATUS_ERROR : STATUS_END);
1853
if ( res ) {
1854
Pr( "#W init functions returned non-zero exit code\n", 0L, 0L );
1855
}
1856
RecordLoadedModule(info, CSTR_STRING(filename));
1857
1858
return True;
1859
}
1860
1861
1862
/****************************************************************************
1863
**
1864
*F FuncSHOW_STAT() . . . . . . . . . . . . . . . . . . . show static modules
1865
*/
1866
Obj FuncSHOW_STAT (
1867
Obj self )
1868
{
1869
Obj modules;
1870
Obj name;
1871
StructInitInfo * info;
1872
Int k;
1873
Int im;
1874
1875
/* count the number of install modules */
1876
for ( k = 0, im = 0; CompInitFuncs[k]; k++ ) {
1877
info = (*(CompInitFuncs[k]))();
1878
if ( info == 0 ) {
1879
continue;
1880
}
1881
im++;
1882
}
1883
1884
/* make a list of modules with crc values */
1885
modules = NEW_PLIST( T_PLIST, 2*im );
1886
SET_LEN_PLIST( modules, 2*im );
1887
1888
for ( k = 0, im = 1; CompInitFuncs[k]; k++ ) {
1889
info = (*(CompInitFuncs[k]))();
1890
if ( info == 0 ) {
1891
continue;
1892
}
1893
C_NEW_STRING_DYN(name, info->name);
1894
1895
SET_ELM_PLIST( modules, im, name );
1896
1897
/* compute the crc value */
1898
SET_ELM_PLIST( modules, im+1, INTOBJ_INT( info->crc ) );
1899
im += 2;
1900
}
1901
1902
return modules;
1903
}
1904
1905
1906
/****************************************************************************
1907
**
1908
*F FuncLoadedModules( <self> ) . . . . . . . . . . . list all loaded modules
1909
*/
1910
Obj FuncLoadedModules (
1911
Obj self )
1912
{
1913
Int i;
1914
StructInitInfo * m;
1915
Obj str;
1916
Obj list;
1917
1918
/* create a list */
1919
list = NEW_PLIST( T_PLIST, NrModules * 3 );
1920
SET_LEN_PLIST( list, NrModules * 3 );
1921
for ( i = 0; i < NrModules; i++ ) {
1922
m = Modules[i];
1923
if ( m->type == MODULE_BUILTIN ) {
1924
SET_ELM_PLIST( list, 3*i+1, ObjsChar[(Int)'b'] );
1925
CHANGED_BAG(list);
1926
C_NEW_STRING_DYN( str, m->name );
1927
SET_ELM_PLIST( list, 3*i+2, str );
1928
SET_ELM_PLIST( list, 3*i+3, INTOBJ_INT(m->version) );
1929
}
1930
else if ( m->type == MODULE_DYNAMIC ) {
1931
SET_ELM_PLIST( list, 3*i+1, ObjsChar[(Int)'d'] );
1932
CHANGED_BAG(list);
1933
C_NEW_STRING_DYN( str, m->name );
1934
SET_ELM_PLIST( list, 3*i+2, str );
1935
CHANGED_BAG(list);
1936
C_NEW_STRING_DYN( str, m->filename );
1937
SET_ELM_PLIST( list, 3*i+3, str );
1938
}
1939
else if ( m->type == MODULE_STATIC ) {
1940
SET_ELM_PLIST( list, 3*i+1, ObjsChar[(Int)'s'] );
1941
CHANGED_BAG(list);
1942
C_NEW_STRING_DYN( str, m->name );
1943
SET_ELM_PLIST( list, 3*i+2, str );
1944
CHANGED_BAG(list);
1945
C_NEW_STRING_DYN( str, m->filename );
1946
SET_ELM_PLIST( list, 3*i+3, str );
1947
}
1948
}
1949
return CopyObj( list, 0 );
1950
}
1951
1952
1953
/****************************************************************************
1954
**
1955
1956
1957
*F * * * * * * * * * * * * * * debug functions * * * * * * * * * * * * * * *
1958
*/
1959
1960
/****************************************************************************
1961
**
1962
1963
*F FuncGASMAN( <self>, <args> ) . . . . . . . . . expert function 'GASMAN'
1964
**
1965
** 'FuncGASMAN' implements the internal function 'GASMAN'
1966
**
1967
** 'GASMAN( "display" | "clear" | "collect" | "message" | "partial" )'
1968
*/
1969
Obj FuncGASMAN (
1970
Obj self,
1971
Obj args )
1972
{
1973
Obj cmd; /* argument */
1974
UInt i, k; /* loop variables */
1975
Char buf[41];
1976
1977
/* check the argument */
1978
while ( ! IS_SMALL_LIST(args) || LEN_LIST(args) == 0 ) {
1979
args = ErrorReturnObj(
1980
"usage: GASMAN( \"display\"|\"displayshort\"|\"clear\"|\"collect\"|\"message\"|\"partial\" )",
1981
0L, 0L,
1982
"you can replace the argument list <args> via 'return <args>;'" );
1983
}
1984
1985
/* loop over the arguments */
1986
for ( i = 1; i <= LEN_LIST(args); i++ ) {
1987
1988
/* evaluate and check the command */
1989
cmd = ELM_PLIST( args, i );
1990
again:
1991
while ( ! IsStringConv(cmd) ) {
1992
cmd = ErrorReturnObj(
1993
"GASMAN: <cmd> must be a string (not a %s)",
1994
(Int)TNAM_OBJ(cmd), 0L,
1995
"you can replace <cmd> via 'return <cmd>;'" );
1996
}
1997
1998
/* if request display the statistics */
1999
if ( strcmp( CSTR_STRING(cmd), "display" ) == 0 ) {
2000
Pr( "%40s ", (Int)"type", 0L );
2001
Pr( "%8s %8s ", (Int)"alive", (Int)"kbyte" );
2002
Pr( "%8s %8s\n", (Int)"total", (Int)"kbyte" );
2003
for ( k = 0; k < 256; k++ ) {
2004
if ( InfoBags[k].name != 0 ) {
2005
buf[0] = '\0';
2006
strlcat( buf, InfoBags[k].name, sizeof(buf) );
2007
Pr("%40s ", (Int)buf, 0L );
2008
Pr("%8d %8d ", (Int)InfoBags[k].nrLive,
2009
(Int)(InfoBags[k].sizeLive/1024));
2010
Pr("%8d %8d\n",(Int)InfoBags[k].nrAll,
2011
(Int)(InfoBags[k].sizeAll/1024));
2012
}
2013
}
2014
}
2015
2016
/* if request give a short display of the statistics */
2017
else if ( strcmp( CSTR_STRING(cmd), "displayshort" ) == 0 ) {
2018
Pr( "%40s ", (Int)"type", 0L );
2019
Pr( "%8s %8s ", (Int)"alive", (Int)"kbyte" );
2020
Pr( "%8s %8s\n", (Int)"total", (Int)"kbyte" );
2021
for ( k = 0; k < 256; k++ ) {
2022
if ( InfoBags[k].name != 0 &&
2023
(InfoBags[k].nrLive != 0 ||
2024
InfoBags[k].sizeLive != 0 ||
2025
InfoBags[k].nrAll != 0 ||
2026
InfoBags[k].sizeAll != 0) ) {
2027
buf[0] = '\0';
2028
strlcat( buf, InfoBags[k].name, sizeof(buf) );
2029
Pr("%40s ", (Int)buf, 0L );
2030
Pr("%8d %8d ", (Int)InfoBags[k].nrLive,
2031
(Int)(InfoBags[k].sizeLive/1024));
2032
Pr("%8d %8d\n",(Int)InfoBags[k].nrAll,
2033
(Int)(InfoBags[k].sizeAll/1024));
2034
}
2035
}
2036
}
2037
2038
/* if request display the statistics */
2039
else if ( strcmp( CSTR_STRING(cmd), "clear" ) == 0 ) {
2040
for ( k = 0; k < 256; k++ ) {
2041
#ifdef GASMAN_CLEAR_TO_LIVE
2042
InfoBags[k].nrAll = InfoBags[k].nrLive;
2043
InfoBags[k].sizeAll = InfoBags[k].sizeLive;
2044
#else
2045
InfoBags[k].nrAll = 0;
2046
InfoBags[k].sizeAll = 0;
2047
#endif
2048
}
2049
}
2050
2051
/* or collect the garbage */
2052
else if ( strcmp( CSTR_STRING(cmd), "collect" ) == 0 ) {
2053
CollectBags(0,1);
2054
}
2055
2056
/* or collect the garbage */
2057
else if ( strcmp( CSTR_STRING(cmd), "partial" ) == 0 ) {
2058
CollectBags(0,0);
2059
}
2060
2061
/* or display information about global bags */
2062
else if ( strcmp( CSTR_STRING(cmd), "global" ) == 0 ) {
2063
for ( i = 0; i < GlobalBags.nr; i++ ) {
2064
if ( *(GlobalBags.addr[i]) != 0 ) {
2065
Pr( "%50s: %12d bytes\n", (Int)GlobalBags.cookie[i],
2066
(Int)SIZE_BAG(*(GlobalBags.addr[i])) );
2067
}
2068
}
2069
}
2070
2071
/* or finally toggle Gasman messages */
2072
else if ( strcmp( CSTR_STRING(cmd), "message" ) == 0 ) {
2073
SyMsgsFlagBags = (SyMsgsFlagBags + 1) % 3;
2074
}
2075
2076
/* otherwise complain */
2077
else {
2078
cmd = ErrorReturnObj(
2079
"GASMAN: <cmd> must be %s or %s",
2080
(Int)"\"display\" or \"clear\" or \"global\" or ",
2081
(Int)"\"collect\" or \"partial\" or \"message\"",
2082
"you can replace <cmd> via 'return <cmd>;'" );
2083
goto again;
2084
}
2085
}
2086
2087
/* return nothing, this function is a procedure */
2088
return 0;
2089
}
2090
2091
Obj FuncGASMAN_STATS(Obj self)
2092
{
2093
Obj res;
2094
Obj row;
2095
Obj entry;
2096
UInt i,j;
2097
Int x;
2098
res = NEW_PLIST(T_PLIST_TAB_RECT + IMMUTABLE, 2);
2099
SET_LEN_PLIST(res, 2);
2100
for (i = 1; i <= 2; i++)
2101
{
2102
row = NEW_PLIST(T_PLIST_CYC + IMMUTABLE, 9);
2103
SET_ELM_PLIST(res, i, row);
2104
CHANGED_BAG(res);
2105
SET_LEN_PLIST(row, 9);
2106
for (j = 1; j <= 8; j++)
2107
{
2108
x = SyGasmanNumbers[i-1][j];
2109
2110
/* convert x to GAP integer. x may be too big to be a small int */
2111
if (x < (1L << NR_SMALL_INT_BITS))
2112
entry = INTOBJ_INT(x);
2113
else
2114
entry = SUM( PROD(INTOBJ_INT(x >> (NR_SMALL_INT_BITS/2)),
2115
INTOBJ_INT(1 << (NR_SMALL_INT_BITS/2))),
2116
INTOBJ_INT( x % ( 1 << (NR_SMALL_INT_BITS/2))));
2117
SET_ELM_PLIST(row, j, entry);
2118
}
2119
SET_ELM_PLIST(row, 9, INTOBJ_INT(SyGasmanNumbers[i-1][0]));
2120
}
2121
return res;
2122
}
2123
2124
Obj FuncGASMAN_MESSAGE_STATUS( Obj self )
2125
{
2126
return INTOBJ_INT(SyMsgsFlagBags);
2127
}
2128
2129
Obj FuncGASMAN_LIMITS( Obj self )
2130
{
2131
Obj list;
2132
list = NEW_PLIST(T_PLIST_CYC+IMMUTABLE, 3);
2133
SET_LEN_PLIST(list,3);
2134
SET_ELM_PLIST(list, 1, INTOBJ_INT(SyStorMin));
2135
SET_ELM_PLIST(list, 2, INTOBJ_INT(SyStorMax));
2136
SET_ELM_PLIST(list, 3, INTOBJ_INT(SyStorKill));
2137
return list;
2138
}
2139
2140
/****************************************************************************
2141
**
2142
*F FuncSHALLOW_SIZE( <self>, <obj> ) . . . . expert function 'SHALLOW_SIZE'
2143
*/
2144
Obj FuncSHALLOW_SIZE (
2145
Obj self,
2146
Obj obj )
2147
{
2148
if (IS_INTOBJ(obj) || IS_FFE(obj))
2149
return INTOBJ_INT(0);
2150
else
2151
return ObjInt_UInt( SIZE_BAG( obj ) );
2152
}
2153
2154
2155
/****************************************************************************
2156
**
2157
*F FuncTNUM_OBJ( <self>, <obj> ) . . . . . . . . expert function 'TNUM_OBJ'
2158
*/
2159
2160
Obj FuncTNUM_OBJ (
2161
Obj self,
2162
Obj obj )
2163
{
2164
Obj res;
2165
Obj str;
2166
const Char * cst;
2167
2168
res = NEW_PLIST( T_PLIST, 2 );
2169
SET_LEN_PLIST( res, 2 );
2170
2171
/* set the type */
2172
SET_ELM_PLIST( res, 1, INTOBJ_INT( TNUM_OBJ(obj) ) );
2173
cst = TNAM_OBJ(obj);
2174
C_NEW_STRING_DYN(str, cst);
2175
SET_ELM_PLIST( res, 2, str );
2176
2177
/* and return */
2178
return res;
2179
}
2180
2181
Obj FuncTNUM_OBJ_INT (
2182
Obj self,
2183
Obj obj )
2184
{
2185
2186
2187
return INTOBJ_INT( TNUM_OBJ(obj) ) ;
2188
}
2189
2190
/****************************************************************************
2191
**
2192
*F FuncOBJ_HANDLE( <self>, <obj> ) . . . . . . expert function 'OBJ_HANDLE'
2193
*/
2194
Obj FuncOBJ_HANDLE (
2195
Obj self,
2196
Obj obj )
2197
{
2198
UInt hand;
2199
UInt prod;
2200
Obj rem;
2201
2202
if ( IS_INTOBJ(obj) ) {
2203
return (Obj)INT_INTOBJ(obj);
2204
}
2205
else if ( TNUM_OBJ(obj) == T_INTPOS ) {
2206
hand = 0;
2207
prod = 1;
2208
while ( EQ( obj, INTOBJ_INT(0) ) == 0 ) {
2209
rem = RemInt( obj, INTOBJ_INT( 1 << 16 ) );
2210
obj = QuoInt( obj, INTOBJ_INT( 1 << 16 ) );
2211
hand = hand + prod * INT_INTOBJ(rem);
2212
prod = prod * ( 1 << 16 );
2213
}
2214
return (Obj) hand;
2215
}
2216
else {
2217
ErrorQuit( "<handle> must be a positive integer", 0L, 0L );
2218
return (Obj) 0;
2219
}
2220
}
2221
2222
2223
/****************************************************************************
2224
**
2225
*F FuncHANDLE_OBJ( <self>, <obj> ) . . . . . . expert function 'HANDLE_OBJ'
2226
*/
2227
Obj FuncHANDLE_OBJ (
2228
Obj self,
2229
Obj obj )
2230
{
2231
Obj hnum;
2232
Obj prod;
2233
Obj tmp;
2234
UInt hand;
2235
2236
hand = (UInt) obj;
2237
hnum = INTOBJ_INT(0);
2238
prod = INTOBJ_INT(1);
2239
while ( 0 < hand ) {
2240
tmp = PROD( prod, INTOBJ_INT( hand & 0xffff ) );
2241
prod = PROD( prod, INTOBJ_INT( 1 << 16 ) );
2242
hnum = SUM( hnum, tmp );
2243
hand = hand >> 16;
2244
}
2245
return hnum;
2246
}
2247
2248
Obj FuncMASTER_POINTER_NUMBER(Obj self, Obj o)
2249
{
2250
if ((void **) o >= (void **) MptrBags && (void **) o < (void **) OldBags) {
2251
return INTOBJ_INT( ((void **) o - (void **) MptrBags) + 1 );
2252
} else {
2253
return INTOBJ_INT( 0 );
2254
}
2255
}
2256
2257
Obj FuncFUNC_BODY_SIZE(Obj self, Obj f)
2258
{
2259
Obj body;
2260
if (TNUM_OBJ(f) != T_FUNCTION) return Fail;
2261
body = BODY_FUNC(f);
2262
if (body == 0) return INTOBJ_INT(0);
2263
else return INTOBJ_INT( SIZE_BAG( body ) );
2264
}
2265
2266
/****************************************************************************
2267
**
2268
*F FuncSWAP_MPTR( <self>, <obj1>, <obj2> ) . . . . . . . swap master pointer
2269
**
2270
** Never use this function unless you are debugging.
2271
*/
2272
Obj FuncSWAP_MPTR (
2273
Obj self,
2274
Obj obj1,
2275
Obj obj2 )
2276
{
2277
if ( TNUM_OBJ(obj1) == T_INT || TNUM_OBJ(obj1) == T_FFE ) {
2278
ErrorQuit("SWAP_MPTR: <obj1> must not be an integer or ffe", 0L, 0L);
2279
return 0;
2280
}
2281
if ( TNUM_OBJ(obj2) == T_INT || TNUM_OBJ(obj2) == T_FFE ) {
2282
ErrorQuit("SWAP_MPTR: <obj2> must not be an integer or ffe", 0L, 0L);
2283
return 0;
2284
}
2285
2286
SwapMasterPoint( obj1, obj2 );
2287
return 0;
2288
}
2289
2290
2291
/****************************************************************************
2292
**
2293
2294
*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *
2295
*/
2296
2297
2298
/****************************************************************************
2299
**
2300
2301
*F FillInVersion( <module>, <rev_c>, <rev_h> ) . . . fill in version number
2302
*/
2303
void FillInVersion (
2304
StructInitInfo * module )
2305
{
2306
}
2307
2308
2309
/****************************************************************************
2310
**
2311
*F RequireModule( <calling>, <required>, <version> ) . . . . require module
2312
*/
2313
void RequireModule (
2314
StructInitInfo * module,
2315
const Char * required,
2316
UInt version )
2317
{
2318
}
2319
2320
2321
/****************************************************************************
2322
**
2323
*F InitBagNamesFromTable( <table> ) . . . . . . . . . initialise bag names
2324
*/
2325
void InitBagNamesFromTable (
2326
StructBagNames * tab )
2327
{
2328
Int i;
2329
2330
for ( i = 0; tab[i].tnum != -1; i++ ) {
2331
InfoBags[tab[i].tnum].name = tab[i].name;
2332
}
2333
}
2334
2335
2336
/****************************************************************************
2337
**
2338
*F InitClearFiltsTNumsFromTable( <tab> ) . . . initialise clear filts tnums
2339
*/
2340
void InitClearFiltsTNumsFromTable (
2341
Int * tab )
2342
{
2343
Int i;
2344
2345
for ( i = 0; tab[i] != -1; i += 2 ) {
2346
ClearFiltsTNums[tab[i]] = tab[i+1];
2347
}
2348
}
2349
2350
2351
/****************************************************************************
2352
**
2353
*F InitHasFiltListTNumsFromTable( <tab> ) . . initialise tester filts tnums
2354
*/
2355
void InitHasFiltListTNumsFromTable (
2356
Int * tab )
2357
{
2358
Int i;
2359
2360
for ( i = 0; tab[i] != -1; i += 3 ) {
2361
HasFiltListTNums[tab[i]][tab[i+1]] = tab[i+2];
2362
}
2363
}
2364
2365
2366
/****************************************************************************
2367
**
2368
*F InitSetFiltListTNumsFromTable( <tab> ) . . initialise setter filts tnums
2369
*/
2370
void InitSetFiltListTNumsFromTable (
2371
Int * tab )
2372
{
2373
Int i;
2374
2375
for ( i = 0; tab[i] != -1; i += 3 ) {
2376
SetFiltListTNums[tab[i]][tab[i+1]] = tab[i+2];
2377
}
2378
}
2379
2380
2381
/****************************************************************************
2382
**
2383
*F InitResetFiltListTNumsFromTable( <tab> ) initialise unsetter filts tnums
2384
*/
2385
void InitResetFiltListTNumsFromTable (
2386
Int * tab )
2387
{
2388
Int i;
2389
2390
for ( i = 0; tab[i] != -1; i += 3 ) {
2391
ResetFiltListTNums[tab[i]][tab[i+1]] = tab[i+2];
2392
}
2393
}
2394
2395
2396
/****************************************************************************
2397
**
2398
*F InitGVarFiltsFromTable( <tab> ) . . . . . . . . . . . . . . . new filters
2399
*/
2400
void InitGVarFiltsFromTable (
2401
StructGVarFilt * tab )
2402
{
2403
Int i;
2404
2405
for ( i = 0; tab[i].name != 0; i++ ) {
2406
UInt gvar = GVarName( tab[i].name );
2407
AssGVar( gvar,
2408
NewFilter( NameGVarObj( gvar ), 1, ArgStringToList( tab[i].argument ), tab[i].handler ) );
2409
MakeReadOnlyGVar( gvar );
2410
}
2411
}
2412
2413
2414
/****************************************************************************
2415
**
2416
*F InitGVarAttrsFromTable( <tab> ) . . . . . . . . . . . . . new attributes
2417
*/
2418
void InitGVarAttrsFromTable (
2419
StructGVarAttr * tab )
2420
{
2421
Int i;
2422
2423
for ( i = 0; tab[i].name != 0; i++ ) {
2424
UInt gvar = GVarName( tab[i].name );
2425
AssGVar( gvar,
2426
NewAttribute( NameGVarObj( gvar ),
2427
1,
2428
ArgStringToList( tab[i].argument ),
2429
tab[i].handler ) );
2430
MakeReadOnlyGVar( gvar );
2431
}
2432
}
2433
2434
2435
/****************************************************************************
2436
**
2437
*F InitGVarPropsFromTable( <tab> ) . . . . . . . . . . . . . new properties
2438
*/
2439
void InitGVarPropsFromTable (
2440
StructGVarProp * tab )
2441
{
2442
Int i;
2443
2444
for ( i = 0; tab[i].name != 0; i++ ) {
2445
UInt gvar = GVarName( tab[i].name );
2446
AssGVar( gvar,
2447
NewProperty( NameGVarObj( gvar ),
2448
1,
2449
ArgStringToList( tab[i].argument ),
2450
tab[i].handler ) );
2451
MakeReadOnlyGVar( gvar );
2452
}
2453
}
2454
2455
2456
/****************************************************************************
2457
**
2458
*F InitGVarOpersFromTable( <tab> ) . . . . . . . . . . . . . new operations
2459
*/
2460
void InitGVarOpersFromTable (
2461
StructGVarOper * tab )
2462
{
2463
Int i;
2464
2465
for ( i = 0; tab[i].name != 0; i++ ) {
2466
UInt gvar = GVarName( tab[i].name );
2467
AssGVar( gvar,
2468
NewOperation( NameGVarObj( gvar ),
2469
tab[i].nargs,
2470
ArgStringToList( tab[i].args ),
2471
tab[i].handler ) );
2472
MakeReadOnlyGVar( gvar );
2473
}
2474
}
2475
2476
2477
/****************************************************************************
2478
**
2479
*F InitGVarFuncsFromTable( <tab> ) . . . . . . . . . . . . . . new functions
2480
*/
2481
void InitGVarFuncsFromTable (
2482
StructGVarFunc * tab )
2483
{
2484
Int i;
2485
2486
for ( i = 0; tab[i].name != 0; i++ ) {
2487
UInt gvar = GVarName( tab[i].name );
2488
AssGVar( gvar,
2489
NewFunction( NameGVarObj( gvar ),
2490
tab[i].nargs,
2491
ArgStringToList( tab[i].args ),
2492
tab[i].handler ) );
2493
MakeReadOnlyGVar( gvar );
2494
}
2495
}
2496
2497
2498
/****************************************************************************
2499
**
2500
*F InitHdlrFiltsFromTable( <tab> ) . . . . . . . . . . . . . . . new filters
2501
*/
2502
void InitHdlrFiltsFromTable (
2503
StructGVarFilt * tab )
2504
{
2505
Int i;
2506
2507
for ( i = 0; tab[i].name != 0; i++ ) {
2508
InitHandlerFunc( tab[i].handler, tab[i].cookie );
2509
InitFopyGVar( tab[i].name, tab[i].filter );
2510
}
2511
}
2512
2513
2514
/****************************************************************************
2515
**
2516
*F InitHdlrAttrsFromTable( <tab> ) . . . . . . . . . . . . . new attributes
2517
*/
2518
void InitHdlrAttrsFromTable (
2519
StructGVarAttr * tab )
2520
{
2521
Int i;
2522
2523
for ( i = 0; tab[i].name != 0; i++ ) {
2524
InitHandlerFunc( tab[i].handler, tab[i].cookie );
2525
InitFopyGVar( tab[i].name, tab[i].attribute );
2526
}
2527
}
2528
2529
2530
/****************************************************************************
2531
**
2532
*F InitHdlrPropsFromTable( <tab> ) . . . . . . . . . . . . . new properties
2533
*/
2534
void InitHdlrPropsFromTable (
2535
StructGVarProp * tab )
2536
{
2537
Int i;
2538
2539
for ( i = 0; tab[i].name != 0; i++ ) {
2540
InitHandlerFunc( tab[i].handler, tab[i].cookie );
2541
InitFopyGVar( tab[i].name, tab[i].property );
2542
}
2543
}
2544
2545
2546
/****************************************************************************
2547
**
2548
*F InitHdlrOpersFromTable( <tab> ) . . . . . . . . . . . . . new operations
2549
*/
2550
void InitHdlrOpersFromTable (
2551
StructGVarOper * tab )
2552
{
2553
Int i;
2554
2555
for ( i = 0; tab[i].name != 0; i++ ) {
2556
InitHandlerFunc( tab[i].handler, tab[i].cookie );
2557
InitFopyGVar( tab[i].name, tab[i].operation );
2558
}
2559
}
2560
2561
2562
/****************************************************************************
2563
**
2564
*F InitHdlrFuncsFromTable( <tab> ) . . . . . . . . . . . . . . new functions
2565
*/
2566
void InitHdlrFuncsFromTable (
2567
StructGVarFunc * tab )
2568
{
2569
Int i;
2570
2571
for ( i = 0; tab[i].name != 0; i++ ) {
2572
InitHandlerFunc( tab[i].handler, tab[i].cookie );
2573
}
2574
}
2575
2576
2577
/****************************************************************************
2578
**
2579
*F ImportGVarFromLibrary( <name>, <address> ) . . . import global variable
2580
*/
2581
2582
2583
void ImportGVarFromLibrary(
2584
const Char * name,
2585
Obj * address )
2586
{
2587
if ( NrImportedGVars == 1024 ) {
2588
Pr( "#W warning: too many imported GVars\n", 0L, 0L );
2589
}
2590
else {
2591
ImportedGVars[NrImportedGVars].name = name;
2592
ImportedGVars[NrImportedGVars].address = address;
2593
NrImportedGVars++;
2594
}
2595
if ( address != 0 ) {
2596
InitCopyGVar( name, address );
2597
}
2598
}
2599
2600
2601
/****************************************************************************
2602
**
2603
*F ImportFuncFromLibrary( <name>, <address> ) . . . import global function
2604
*/
2605
2606
2607
void ImportFuncFromLibrary(
2608
const Char * name,
2609
Obj * address )
2610
{
2611
if ( NrImportedFuncs == 1024 ) {
2612
Pr( "#W warning: too many imported Funcs\n", 0L, 0L );
2613
}
2614
else {
2615
ImportedFuncs[NrImportedFuncs].name = name;
2616
ImportedFuncs[NrImportedFuncs].address = address;
2617
NrImportedFuncs++;
2618
}
2619
if ( address != 0 ) {
2620
InitFopyGVar( name, address );
2621
}
2622
}
2623
2624
2625
/****************************************************************************
2626
**
2627
*F FuncExportToKernelFinished( <self> ) . . . . . . . . . . check functions
2628
*/
2629
Obj FuncExportToKernelFinished (
2630
Obj self )
2631
{
2632
UInt i;
2633
Int errs = 0;
2634
Obj val;
2635
2636
SyInitializing = 0;
2637
for ( i = 0; i < NrImportedGVars; i++ ) {
2638
if ( ImportedGVars[i].address == 0 ) {
2639
val = ValAutoGVar(GVarName(ImportedGVars[i].name));
2640
if ( val == 0 ) {
2641
errs++;
2642
if ( ! SyQuiet ) {
2643
Pr( "#W global variable '%s' has not been defined\n",
2644
(Int)ImportedFuncs[i].name, 0L );
2645
}
2646
}
2647
}
2648
else if ( *ImportedGVars[i].address == 0 ) {
2649
errs++;
2650
if ( ! SyQuiet ) {
2651
Pr( "#W global variable '%s' has not been defined\n",
2652
(Int)ImportedGVars[i].name, 0L );
2653
}
2654
}
2655
else {
2656
MakeReadOnlyGVar(GVarName(ImportedGVars[i].name));
2657
}
2658
}
2659
2660
for ( i = 0; i < NrImportedFuncs; i++ ) {
2661
if ( ImportedFuncs[i].address == 0 ) {
2662
val = ValAutoGVar(GVarName(ImportedFuncs[i].name));
2663
if ( val == 0 || ! IS_FUNC(val) ) {
2664
errs++;
2665
if ( ! SyQuiet ) {
2666
Pr( "#W global function '%s' has not been defined\n",
2667
(Int)ImportedFuncs[i].name, 0L );
2668
}
2669
}
2670
}
2671
else if ( *ImportedFuncs[i].address == ErrorMustEvalToFuncFunc
2672
|| *ImportedFuncs[i].address == ErrorMustHaveAssObjFunc )
2673
{
2674
errs++;
2675
if ( ! SyQuiet ) {
2676
Pr( "#W global function '%s' has not been defined\n",
2677
(Int)ImportedFuncs[i].name, 0L );
2678
}
2679
}
2680
else {
2681
MakeReadOnlyGVar(GVarName(ImportedFuncs[i].name));
2682
}
2683
}
2684
2685
return errs == 0 ? True : False;
2686
}
2687
2688
2689
/****************************************************************************
2690
**
2691
*F FuncSleep( <self>, <secs> )
2692
**
2693
*/
2694
2695
Obj FuncSleep( Obj self, Obj secs )
2696
{
2697
Int s;
2698
2699
while( ! IS_INTOBJ(secs) )
2700
secs = ErrorReturnObj( "<secs> must be a small integer", 0L, 0L,
2701
"you can replace <secs> via 'return <secs>;'" );
2702
2703
2704
if ( (s = INT_INTOBJ(secs)) > 0)
2705
SySleep((UInt)s);
2706
2707
/* either we used up the time, or we were interrupted. */
2708
if (SyIsIntr())
2709
{
2710
ClearError(); /* The interrupt may still be pending */
2711
ErrorReturnVoid("user interrupt in sleep", 0L, 0L,
2712
"you can 'return;' as if the sleep was finished");
2713
}
2714
2715
return (Obj) 0;
2716
}
2717
2718
// Common code in the next 3 methods.
2719
static int SetExitValue(Obj code)
2720
{
2721
if (code == False || code == Fail)
2722
SystemErrorCode = 1;
2723
else if (code == True)
2724
SystemErrorCode = 0;
2725
else if (IS_INTOBJ(code))
2726
SystemErrorCode = INT_INTOBJ(code);
2727
else
2728
return 0;
2729
return 1;
2730
}
2731
2732
/****************************************************************************
2733
**
2734
*F FuncGAP_EXIT_CODE() . . . . . . . . Set the code with which GAP exits.
2735
**
2736
*/
2737
2738
Obj FuncGAP_EXIT_CODE( Obj self, Obj code )
2739
{
2740
if (!SetExitValue(code))
2741
ErrorQuit("GAP_EXIT_CODE: Argument must be boolean or integer", 0L, 0L);
2742
return (Obj) 0;
2743
}
2744
2745
2746
/****************************************************************************
2747
**
2748
*F FuncQUIT_GAP()
2749
**
2750
*/
2751
2752
Obj FuncQUIT_GAP( Obj self, Obj args )
2753
{
2754
if ( LEN_LIST(args) == 0 ) {
2755
SystemErrorCode = 0;
2756
}
2757
else if ( LEN_LIST(args) != 1
2758
|| !SetExitValue(ELM_PLIST(args, 1) ) ) {
2759
ErrorQuit( "usage: QUIT_GAP( [ <return value> ] )", 0L, 0L );
2760
return 0;
2761
}
2762
TLS(UserHasQUIT) = 1;
2763
ReadEvalError();
2764
return (Obj)0;
2765
}
2766
2767
/****************************************************************************
2768
**
2769
*F FuncFORCE_QUIT_GAP()
2770
**
2771
*/
2772
2773
Obj FuncFORCE_QUIT_GAP( Obj self, Obj args )
2774
{
2775
if ( LEN_LIST(args) == 0 )
2776
{
2777
SyExit(SystemErrorCode);
2778
}
2779
else if ( LEN_LIST(args) != 1
2780
|| !SetExitValue(ELM_PLIST(args, 1) ) ) {
2781
ErrorQuit( "usage: FORCE_QUIT_GAP( [ <return value> ] )", 0L, 0L );
2782
return 0;
2783
}
2784
SyExit(SystemErrorCode);
2785
return (Obj) 0; /* should never get here */
2786
}
2787
2788
2789
/****************************************************************************
2790
**
2791
*F KERNEL_INFO() ......................record of information from the kernel
2792
**
2793
** The general idea is to put all kernel-specific info in here, and clean up
2794
** the assortment of global variables previously used
2795
*/
2796
2797
Obj FuncKERNEL_INFO(Obj self) {
2798
Obj res = NEW_PREC(0);
2799
UInt r,lenvec,lenstr,lenstr2;
2800
Char *p;
2801
Obj tmp,list,str;
2802
UInt i,j;
2803
2804
/* GAP_ARCHITECTURE */
2805
C_NEW_STRING_DYN( tmp, SyArchitecture );
2806
RetypeBag( tmp, IMMUTABLE_TNUM(TNUM_OBJ(tmp)) );
2807
r = RNamName("GAP_ARCHITECTURE");
2808
AssPRec(res,r,tmp);
2809
/* KERNEL_VERSION */
2810
C_NEW_STRING_DYN( tmp, SyKernelVersion );
2811
RetypeBag( tmp, IMMUTABLE_TNUM(TNUM_OBJ(tmp)) );
2812
r = RNamName("KERNEL_VERSION");
2813
AssPRec(res,r,tmp);
2814
C_NEW_STRING_DYN( tmp, SyBuildVersion );
2815
RetypeBag( tmp, IMMUTABLE_TNUM(TNUM_OBJ(tmp)) );
2816
r = RNamName("BUILD_VERSION");
2817
AssPRec(res,r,tmp);
2818
C_NEW_STRING_DYN( tmp, SyBuildDateTime );
2819
RetypeBag( tmp, IMMUTABLE_TNUM(TNUM_OBJ(tmp)) );
2820
r = RNamName("BUILD_DATETIME");
2821
AssPRec(res,r,tmp);
2822
/* GAP_ROOT_PATH */
2823
/* do we need this. Could we rebuild it from the command line in GAP
2824
if so, should we */
2825
list = NEW_PLIST( T_PLIST+IMMUTABLE, MAX_GAP_DIRS );
2826
for ( i = 0, j = 1; i < MAX_GAP_DIRS; i++ ) {
2827
if ( SyGapRootPaths[i][0] ) {
2828
C_NEW_STRING_DYN( tmp, SyGapRootPaths[i] );
2829
RetypeBag( tmp, IMMUTABLE_TNUM(TNUM_OBJ(tmp)) );
2830
SET_ELM_PLIST( list, j, tmp );
2831
j++;
2832
}
2833
}
2834
SET_LEN_PLIST( list, j-1 );
2835
r = RNamName("GAP_ROOT_PATHS");
2836
AssPRec(res,r,list);
2837
/* And also the DotGapPath if available */
2838
#if HAVE_DOTGAPRC
2839
C_NEW_STRING_DYN( tmp, DotGapPath );
2840
RetypeBag( tmp, IMMUTABLE_TNUM(TNUM_OBJ(tmp)) );
2841
r = RNamName("DOT_GAP_PATH");
2842
AssPRec(res,r,tmp);
2843
#endif
2844
2845
/* make command line and environment available to GAP level */
2846
for (lenvec=0; SyOriginalArgv[lenvec]; lenvec++);
2847
tmp = NEW_PLIST( T_PLIST+IMMUTABLE, lenvec );
2848
SET_LEN_PLIST( tmp, lenvec );
2849
for (i = 0; i<lenvec; i++) {
2850
C_NEW_STRING_DYN( str, SyOriginalArgv[i] );
2851
SET_ELM_PLIST(tmp, i+1, str);
2852
CHANGED_BAG(tmp);
2853
}
2854
r = RNamName("COMMAND_LINE");
2855
AssPRec(res,r, tmp);
2856
2857
tmp = NEW_PREC(0);
2858
for (i = 0; sysenviron[i]; i++) {
2859
for (p = sysenviron[i]; *p != '='; p++)
2860
;
2861
lenstr2 = (UInt) (p-sysenviron[i]);
2862
p++; /* Move pointer behind = character */
2863
lenstr = strlen(p);
2864
if (lenstr2 > lenstr)
2865
str = NEW_STRING(lenstr2);
2866
else
2867
str = NEW_STRING(lenstr);
2868
strncat(CSTR_STRING(str),sysenviron[i],lenstr2);
2869
r = RNamName(CSTR_STRING(str));
2870
*(CSTR_STRING(str)) = 0;
2871
strncat(CSTR_STRING(str),p, lenstr);
2872
SET_LEN_STRING(str, lenstr);
2873
SHRINK_STRING(str);
2874
AssPRec(tmp,r , str);
2875
}
2876
r = RNamName("ENVIRONMENT");
2877
AssPRec(res,r, tmp);
2878
2879
/* and also the CONFIGNAME of the running GAP kernel */
2880
C_NEW_STRING_DYN( str, CONFIGNAME );
2881
r = RNamName("CONFIGNAME");
2882
AssPRec(res, r, str);
2883
2884
/* export if we want to use readline */
2885
r = RNamName("HAVE_LIBREADLINE");
2886
if (SyUseReadline)
2887
AssPRec(res, r, True);
2888
else
2889
AssPRec(res, r, False);
2890
2891
return res;
2892
2893
}
2894
2895
2896
/****************************************************************************
2897
**
2898
*V GVarFuncs . . . . . . . . . . . . . . . . . . list of functions to export
2899
*/
2900
static StructGVarFunc GVarFuncs [] = {
2901
2902
{ "Runtime", 0, "",
2903
FuncRuntime, "src/gap.c:Runtime" },
2904
2905
{ "RUNTIMES", 0, "",
2906
FuncRUNTIMES, "src/gap.c:RUNTIMES" },
2907
2908
{ "SizeScreen", -1, "args",
2909
FuncSizeScreen, "src/gap.c:SizeScreen" },
2910
2911
{ "ID_FUNC", 1, "object",
2912
FuncID_FUNC, "src/gap.c:ID_FUNC" },
2913
2914
{ "RETURN_FIRST", -1, "object",
2915
FuncRETURN_FIRST, "src/gap.c:RETURN_FIRST" },
2916
2917
{ "RETURN_NOTHING", -1, "object",
2918
FuncRETURN_NOTHING, "src/gap.c:RETURN_NOTHING" },
2919
2920
{ "ExportToKernelFinished", 0, "",
2921
FuncExportToKernelFinished, "src/gap.c:ExportToKernelFinished" },
2922
2923
{ "DownEnv", -1, "args",
2924
FuncDownEnv, "src/gap.c:DownEnv" },
2925
2926
{ "UpEnv", -1, "args",
2927
FuncUpEnv, "src/gap.c:UpEnv" },
2928
2929
{ "GAP_CRC", 1, "filename",
2930
FuncGAP_CRC, "src/gap.c:GAP_CRC" },
2931
2932
{ "LOAD_DYN", 2, "filename, crc",
2933
FuncLOAD_DYN, "src/gap.c:LOAD_DYN" },
2934
2935
{ "LOAD_STAT", 2, "filename, crc",
2936
FuncLOAD_STAT, "src/gap.c:LOAD_STAT" },
2937
2938
{ "SHOW_STAT", 0, "",
2939
FuncSHOW_STAT, "src/gap.c:SHOW_STAT" },
2940
2941
{ "GASMAN", -1, "args",
2942
FuncGASMAN, "src/gap.c:GASMAN" },
2943
2944
{ "GASMAN_STATS", 0, "",
2945
FuncGASMAN_STATS, "src/gap.c:GASMAN_STATS" },
2946
2947
{ "GASMAN_MESSAGE_STATUS", 0, "",
2948
FuncGASMAN_MESSAGE_STATUS, "src/gap.c:GASMAN_MESSAGE_STATUS" },
2949
2950
{ "GASMAN_LIMITS", 0, "",
2951
FuncGASMAN_LIMITS, "src/gap.c:GASMAN_LIMITS" },
2952
2953
{ "SHALLOW_SIZE", 1, "object",
2954
FuncSHALLOW_SIZE, "src/gap.c:SHALLOW_SIZE" },
2955
2956
{ "TNUM_OBJ", 1, "object",
2957
FuncTNUM_OBJ, "src/gap.c:TNUM_OBJ" },
2958
2959
{ "TNUM_OBJ_INT", 1, "object",
2960
FuncTNUM_OBJ_INT, "src/gap.c:TNUM_OBJ_INT" },
2961
2962
{ "OBJ_HANDLE", 1, "object",
2963
FuncOBJ_HANDLE, "src/gap.c:OBJ_HANDLE" },
2964
2965
{ "HANDLE_OBJ", 1, "object",
2966
FuncHANDLE_OBJ, "src/gap.c:HANDLE_OBJ" },
2967
2968
{ "SWAP_MPTR", 2, "obj1, obj2",
2969
FuncSWAP_MPTR, "src/gap.c:SWAP_MPTR" },
2970
2971
{ "LoadedModules", 0, "",
2972
FuncLoadedModules, "src/gap.c:LoadedModules" },
2973
2974
{ "WindowCmd", 1, "arg-list",
2975
FuncWindowCmd, "src/gap.c:WindowCmd" },
2976
2977
2978
{ "Sleep", 1, "secs",
2979
FuncSleep, "src/gap.c:Sleep" },
2980
2981
{ "GAP_EXIT_CODE", 1, "exit code",
2982
FuncGAP_EXIT_CODE, "src/gap.c:GAP_EXIT_CODE" },
2983
2984
{ "QUIT_GAP", -1, "args",
2985
FuncQUIT_GAP, "src/gap.c:QUIT_GAP" },
2986
2987
{ "FORCE_QUIT_GAP", -1, "args",
2988
FuncFORCE_QUIT_GAP, "src/gap.c:FORCE_QUIT_GAP" },
2989
2990
{ "SHELL", -1, "context, canReturnVoid, canReturnObj, lastDepth, setTime, prompt, promptHook, infile, outfile",
2991
FuncSHELL, "src/gap.c:FuncSHELL" },
2992
2993
{ "CALL_WITH_CATCH", 2, "func, args",
2994
FuncCALL_WITH_CATCH, "src/gap.c:CALL_WITH_CATCH" },
2995
2996
{ "TIMEOUTS_SUPPORTED", 0, "",
2997
FuncTIMEOUTS_SUPPORTED, "src/gap.c:TIMEOUTS_SUPPORTED" },
2998
2999
{ "CALL_WITH_TIMEOUT", 4, "seconds, microseconds, func, args",
3000
FuncCALL_WITH_TIMEOUT, "src/gap.c:CALL_WITH_TIMEOUT" },
3001
3002
{"STOP_TIMEOUT", 0, "",
3003
FuncSTOP_TIMEOUT, "src/gap.c:FuncSTOP_TIMEOUT" },
3004
3005
{"RESUME_TIMEOUT", 1, "state",
3006
FuncRESUME_TIMEOUT, "src/gap.c:FuncRESUME_TIMEOUT" },
3007
3008
{ "JUMP_TO_CATCH", 1, "payload",
3009
FuncJUMP_TO_CATCH, "src/gap.c:JUMP_TO_CATCH" },
3010
3011
3012
{ "KERNEL_INFO", 0, "",
3013
FuncKERNEL_INFO, "src/gap.c:KERNEL_INFO" },
3014
3015
{ "SetUserHasQuit", 1, "value",
3016
FuncSetUserHasQuit, "src/gap.c:SetUserHasQuit" },
3017
3018
{ "MASTER_POINTER_NUMBER", 1, "ob",
3019
FuncMASTER_POINTER_NUMBER, "src/gap.c:MASTER_POINTER_NUMBER" },
3020
3021
{ "FUNC_BODY_SIZE", 1, "f",
3022
FuncFUNC_BODY_SIZE, "src/gap.c:FUNC_BODY_SIZE" },
3023
3024
{ "PRINT_CURRENT_STATEMENT", 1, "context",
3025
FuncPrintExecutingStatement, "src/gap.c:PRINT_CURRENT_STATEMENT" },
3026
3027
3028
{ 0 }
3029
3030
};
3031
3032
3033
/****************************************************************************
3034
**
3035
3036
*F InitKernel( <module> ) . . . . . . . . initialise kernel data structures
3037
*/
3038
static Int InitKernel (
3039
StructInitInfo * module )
3040
{
3041
/* init the completion function */
3042
InitGlobalBag( &ThrownObject, "src/gap.c:ThrownObject" );
3043
3044
/* list of exit functions */
3045
InitGlobalBag( &WindowCmdString, "src/gap.c:WindowCmdString" );
3046
3047
/* init filters and functions */
3048
InitHdlrFuncsFromTable( GVarFuncs );
3049
3050
3051
3052
/* establish Fopy of ViewObj */
3053
ImportFuncFromLibrary( "ViewObj", 0L );
3054
ImportFuncFromLibrary( "Error", &Error );
3055
ImportFuncFromLibrary( "ErrorInner", &ErrorInner );
3056
3057
3058
#if HAVE_SELECT
3059
InitCopyGVar("OnCharReadHookActive",&OnCharReadHookActive);
3060
InitCopyGVar("OnCharReadHookInFds",&OnCharReadHookInFds);
3061
InitCopyGVar("OnCharReadHookInFuncs",&OnCharReadHookInFuncs);
3062
InitCopyGVar("OnCharReadHookOutFds",&OnCharReadHookOutFds);
3063
InitCopyGVar("OnCharReadHookOutFuncs",&OnCharReadHookOutFuncs);
3064
InitCopyGVar("OnCharReadHookExcFds",&OnCharReadHookExcFds);
3065
InitCopyGVar("OnCharReadHookExcFuncs",&OnCharReadHookExcFuncs);
3066
#endif
3067
3068
/* return success */
3069
return 0;
3070
}
3071
3072
3073
/****************************************************************************
3074
**
3075
*F PostRestore( <module> ) . . . . . . . . . . . . . after restore workspace
3076
*/
3077
static Int PostRestore (
3078
StructInitInfo * module )
3079
{
3080
UInt var;
3081
3082
/* library name and other stuff */
3083
var = GVarName( "DEBUG_LOADING" );
3084
MakeReadWriteGVar(var);
3085
AssGVar( var, (SyDebugLoading ? True : False) );
3086
MakeReadOnlyGVar(var);
3087
3088
/* construct the `ViewObj' variable */
3089
ViewObjGVar = GVarName( "ViewObj" );
3090
CustomViewGVar = GVarName( "CustomView" );
3091
3092
/* construct the last and time variables */
3093
Last = GVarName( "last" );
3094
Last2 = GVarName( "last2" );
3095
Last3 = GVarName( "last3" );
3096
Time = GVarName( "time" );
3097
AssGVar(Time, INTOBJ_INT(0));
3098
QUITTINGGVar = GVarName( "QUITTING" );
3099
3100
/* return success */
3101
return 0;
3102
}
3103
3104
3105
/****************************************************************************
3106
**
3107
*F InitLibrary( <module> ) . . . . . . . initialise library data structures
3108
*/
3109
static Int InitLibrary (
3110
StructInitInfo * module )
3111
{
3112
/* init filters and functions */
3113
InitGVarFuncsFromTable( GVarFuncs );
3114
3115
/* create windows command buffer */
3116
WindowCmdString = NEW_STRING( 1000 );
3117
3118
/* return success */
3119
return PostRestore( module );
3120
}
3121
3122
3123
/****************************************************************************
3124
**
3125
*F InitInfoGap() . . . . . . . . . . . . . . . . . . table of init functions
3126
*/
3127
static StructInitInfo module = {
3128
MODULE_BUILTIN, /* type */
3129
"gap", /* name */
3130
0, /* revision entry of c file */
3131
0, /* revision entry of h file */
3132
0, /* version */
3133
0, /* crc */
3134
InitKernel, /* initKernel */
3135
InitLibrary, /* initLibrary */
3136
0, /* checkInit */
3137
0, /* preSave */
3138
0, /* postSave */
3139
PostRestore /* postRestore */
3140
};
3141
3142
StructInitInfo * InitInfoGap ( void )
3143
{
3144
return &module;
3145
}
3146
3147
3148
/****************************************************************************
3149
**
3150
3151
*V InitFuncsBuiltinModules . . . . . list of builtin modules init functions
3152
*/
3153
static InitInfoFunc InitFuncsBuiltinModules[] = {
3154
3155
/* global variables */
3156
InitInfoGVars,
3157
3158
/* objects */
3159
InitInfoObjects,
3160
3161
/* profiling information */
3162
InitInfoProfile,
3163
3164
/* scanner, reader, interpreter, coder, caller, compiler */
3165
InitInfoScanner,
3166
InitInfoRead,
3167
InitInfoCalls,
3168
InitInfoExprs,
3169
InitInfoStats,
3170
InitInfoCode,
3171
InitInfoVars, /* must come after InitExpr and InitStats */
3172
InitInfoFuncs,
3173
InitInfoOpers,
3174
InitInfoIntrprtr,
3175
InitInfoCompiler,
3176
3177
/* arithmetic operations */
3178
InitInfoAriths,
3179
InitInfoInt,
3180
InitInfoIntFuncs,
3181
InitInfoRat,
3182
InitInfoCyc,
3183
InitInfoFinfield,
3184
InitInfoPermutat,
3185
InitInfoTrans,
3186
InitInfoPPerm,
3187
InitInfoBool,
3188
InitInfoMacfloat,
3189
3190
/* record packages */
3191
InitInfoRecords,
3192
InitInfoPRecord,
3193
3194
/* list packages */
3195
InitInfoLists,
3196
InitInfoListOper,
3197
InitInfoListFunc,
3198
InitInfoPlist,
3199
InitInfoSet,
3200
InitInfoVector,
3201
InitInfoVecFFE,
3202
InitInfoBlist,
3203
InitInfoRange,
3204
InitInfoString,
3205
InitInfoGF2Vec,
3206
InitInfoVec8bit,
3207
3208
/* free and presented groups */
3209
InitInfoFreeGroupElements,
3210
InitInfoCosetTable,
3211
InitInfoTietze,
3212
InitInfoPcElements,
3213
InitInfoSingleCollector,
3214
InitInfoCombiCollector,
3215
InitInfoPcc,
3216
InitInfoDeepThought,
3217
InitInfoDTEvaluation,
3218
3219
/* algebras */
3220
InitInfoSCTable,
3221
3222
/* save and load workspace, weak pointers */
3223
InitInfoWeakPtr,
3224
InitInfoSaveLoad,
3225
3226
/* input and output */
3227
InitInfoStreams,
3228
InitInfoSysFiles,
3229
InitInfoIOStream,
3230
3231
/* main module */
3232
InitInfoGap,
3233
3234
#ifdef GAPMPI
3235
/* ParGAP/MPI module */
3236
InitInfoGapmpi,
3237
#endif
3238
3239
0
3240
};
3241
3242
3243
/****************************************************************************
3244
**
3245
*F Modules . . . . . . . . . . . . . . . . . . . . . . . . . list of modules
3246
*/
3247
#ifndef MAX_MODULES
3248
#define MAX_MODULES 1000
3249
#endif
3250
3251
3252
#ifndef MAX_MODULE_FILENAMES
3253
#define MAX_MODULE_FILENAMES (MAX_MODULES*50)
3254
#endif
3255
3256
Char LoadedModuleFilenames[MAX_MODULE_FILENAMES];
3257
Char *NextLoadedModuleFilename = LoadedModuleFilenames;
3258
3259
3260
StructInitInfo * Modules [ MAX_MODULES ];
3261
UInt NrModules;
3262
UInt NrBuiltinModules;
3263
3264
3265
/****************************************************************************
3266
**
3267
*F RecordLoadedModule( <module> ) . . . . . . . . store module in <Modules>
3268
*/
3269
3270
void RecordLoadedModule (
3271
StructInitInfo * info,
3272
Char *filename )
3273
{
3274
UInt len;
3275
if ( NrModules == MAX_MODULES ) {
3276
Pr( "panic: no room to record module\n", 0L, 0L );
3277
}
3278
len = strlen(filename);
3279
if (NextLoadedModuleFilename + len + 1
3280
> LoadedModuleFilenames+MAX_MODULE_FILENAMES) {
3281
Pr( "panic: no room for module filename\n", 0L, 0L );
3282
}
3283
*NextLoadedModuleFilename = '\0';
3284
memcpy(NextLoadedModuleFilename, filename, len+1);
3285
info->filename = NextLoadedModuleFilename;
3286
NextLoadedModuleFilename += len +1;
3287
Modules[NrModules++] = info;
3288
}
3289
3290
3291
/****************************************************************************
3292
**
3293
*F InitializeGap() . . . . . . . . . . . . . . . . . . . . . . intialize GAP
3294
**
3295
** Each module (builtin or compiled) exports a sturctures which contains
3296
** information about the name, version, crc, init function, save and restore
3297
** functions.
3298
**
3299
** The init process is split into three different functions:
3300
**
3301
** `InitKernel': This function setups the internal data structures and
3302
** tables, registers the global bags and functions handlers, copies and
3303
** fopies. It is not allowed to create objects, gvar or rnam numbers. This
3304
** function is used for both starting and restoring.
3305
**
3306
** `InitLibrary': This function creates objects, gvar and rnam number, and
3307
** does assignments of auxillary C variables (for example, pointers from
3308
** objects, length of hash lists). This function is only used for starting.
3309
**
3310
** `PostRestore': Everything in `InitLibrary' execpt creating objects. In
3311
** general `InitLibrary' will create all objects and then calls
3312
** `PostRestore'. This function is only used when restoring.
3313
*/
3314
#ifndef BOEHM_GC
3315
extern TNumMarkFuncBags TabMarkFuncBags [ 256 ];
3316
#endif
3317
3318
static Obj POST_RESTORE;
3319
3320
void InitializeGap (
3321
int * pargc,
3322
char * argv [] )
3323
{
3324
/* UInt type; */
3325
UInt i;
3326
Int ret;
3327
3328
3329
/* initialize the basic system and gasman */
3330
#ifdef GAPMPI
3331
/* ParGAP/MPI needs to call MPI_Init() first to remove command line args */
3332
InitGapmpi( pargc, &argv );
3333
#endif
3334
3335
InitSystem( *pargc, argv );
3336
3337
/* Initialise memory -- have to do this here to make sure we are at top of C stack */
3338
InitBags( SyAllocBags, SyStorMin,
3339
0, (Bag*)(((UInt)pargc/SyStackAlign)*SyStackAlign), SyStackAlign,
3340
SyCacheSize, 0, SyAbortBags );
3341
InitMsgsFuncBags( SyMsgsBags );
3342
3343
3344
/* get info structures for the build in modules */
3345
NrModules = 0;
3346
for ( i = 0; InitFuncsBuiltinModules[i]; i++ ) {
3347
if ( NrModules == MAX_MODULES ) {
3348
FPUTS_TO_STDERR( "panic: too many builtin modules\n" );
3349
SyExit(1);
3350
}
3351
Modules[NrModules++] = InitFuncsBuiltinModules[i]();
3352
# ifdef DEBUG_LOADING
3353
FPUTS_TO_STDERR( "#I InitInfo(builtin " );
3354
FPUTS_TO_STDERR( Modules[NrModules-1]->name );
3355
FPUTS_TO_STDERR( ")\n" );
3356
# endif
3357
}
3358
NrBuiltinModules = NrModules;
3359
3360
/* call kernel initialisation */
3361
for ( i = 0; i < NrBuiltinModules; i++ ) {
3362
if ( Modules[i]->initKernel ) {
3363
# ifdef DEBUG_LOADING
3364
FPUTS_TO_STDERR( "#I InitKernel(builtin " );
3365
FPUTS_TO_STDERR( Modules[i]->name );
3366
FPUTS_TO_STDERR( ")\n" );
3367
# endif
3368
ret =Modules[i]->initKernel( Modules[i] );
3369
if ( ret ) {
3370
FPUTS_TO_STDERR( "#I InitKernel(builtin " );
3371
FPUTS_TO_STDERR( Modules[i]->name );
3372
FPUTS_TO_STDERR( ") returned non-zero value\n" );
3373
}
3374
}
3375
}
3376
3377
InitGlobalBag(&POST_RESTORE, "gap.c: POST_RESTORE");
3378
InitFopyGVar( "POST_RESTORE", &POST_RESTORE);
3379
3380
/* you should set 'COUNT_BAGS' as well */
3381
# ifdef DEBUG_LOADING
3382
if ( SyRestoring ) {
3383
Pr( "#W after setup\n", 0L, 0L );
3384
Pr( "#W %36s ", (Int)"type", 0L );
3385
Pr( "%8s %8s ", (Int)"alive", (Int)"kbyte" );
3386
Pr( "%8s %8s\n", (Int)"total", (Int)"kbyte" );
3387
for ( i = 0; i < 256; i++ ) {
3388
if ( InfoBags[i].name != 0 && InfoBags[i].nrAll != 0 ) {
3389
char buf[41];
3390
3391
buf[0] = '\0';
3392
strlcat( buf, InfoBags[i].name, sizeof(buf) );
3393
Pr("#W %36s ", (Int)buf, 0L );
3394
Pr("%8d %8d ", (Int)InfoBags[i].nrLive,
3395
(Int)(InfoBags[i].sizeLive/1024));
3396
Pr("%8d %8d\n",(Int)InfoBags[i].nrAll,
3397
(Int)(InfoBags[i].sizeAll/1024));
3398
}
3399
}
3400
}
3401
# endif
3402
3403
#ifndef BOEHM_GC
3404
/* and now for a special hack */
3405
for ( i = LAST_CONSTANT_TNUM+1; i <= LAST_REAL_TNUM; i++ ) {
3406
if (TabMarkFuncBags[i + COPYING] == MarkAllSubBagsDefault)
3407
TabMarkFuncBags[ i+COPYING ] = TabMarkFuncBags[ i ];
3408
}
3409
#endif
3410
3411
/* if we are restoring, load the workspace and call the post restore */
3412
if ( SyRestoring ) {
3413
LoadWorkspace(SyRestoring);
3414
for ( i = 0; i < NrModules; i++ ) {
3415
if ( Modules[i]->postRestore ) {
3416
# ifdef DEBUG_LOADING
3417
FPUTS_TO_STDERR( "#I PostRestore(builtin " );
3418
FPUTS_TO_STDERR( Modules[i]->name );
3419
FPUTS_TO_STDERR( ")\n" );
3420
# endif
3421
ret = Modules[i]->postRestore( Modules[i] );
3422
if ( ret ) {
3423
FPUTS_TO_STDERR( "#I PostRestore(builtin " );
3424
FPUTS_TO_STDERR( Modules[i]->name );
3425
FPUTS_TO_STDERR( ") returned non-zero value\n" );
3426
}
3427
}
3428
}
3429
SyRestoring = NULL;
3430
3431
3432
/* Call POST_RESTORE which is a GAP function that now takes control,
3433
calls the post restore functions and then runs a GAP session */
3434
if (POST_RESTORE != (Obj) 0 &&
3435
IS_FUNC(POST_RESTORE))
3436
if (!READ_ERROR())
3437
CALL_0ARGS(POST_RESTORE);
3438
}
3439
3440
3441
/* otherwise call library initialisation */
3442
else {
3443
WarnInitGlobalBag = 1;
3444
# ifdef DEBUG_HANDLER_REGISTRATION
3445
CheckAllHandlers();
3446
# endif
3447
3448
SyInitializing = 1;
3449
for ( i = 0; i < NrBuiltinModules; i++ ) {
3450
if ( Modules[i]->initLibrary ) {
3451
# ifdef DEBUG_LOADING
3452
FPUTS_TO_STDERR( "#I InitLibrary(builtin " );
3453
FPUTS_TO_STDERR( Modules[i]->name );
3454
FPUTS_TO_STDERR( ")\n" );
3455
# endif
3456
ret = Modules[i]->initLibrary( Modules[i] );
3457
if ( ret ) {
3458
FPUTS_TO_STDERR( "#I InitLibrary(builtin " );
3459
FPUTS_TO_STDERR( Modules[i]->name );
3460
FPUTS_TO_STDERR( ") returned non-zero value\n" );
3461
}
3462
}
3463
}
3464
WarnInitGlobalBag = 0;
3465
}
3466
3467
/* check initialisation */
3468
for ( i = 0; i < NrModules; i++ ) {
3469
if ( Modules[i]->checkInit ) {
3470
# ifdef DEBUG_LOADING
3471
FPUTS_TO_STDERR( "#I CheckInit(builtin " );
3472
FPUTS_TO_STDERR( Modules[i]->name );
3473
FPUTS_TO_STDERR( ")\n" );
3474
# endif
3475
ret = Modules[i]->checkInit( Modules[i] );
3476
if ( ret ) {
3477
FPUTS_TO_STDERR( "#I CheckInit(builtin " );
3478
FPUTS_TO_STDERR( Modules[i]->name );
3479
FPUTS_TO_STDERR( ") returned non-zero value\n" );
3480
}
3481
}
3482
}
3483
3484
/* read the init files
3485
this now actually runs the GAP session, we only get
3486
past here when we're about to exit.
3487
*/
3488
if ( SySystemInitFile[0] ) {
3489
if (!READ_ERROR()) {
3490
if ( READ_GAP_ROOT(SySystemInitFile) == 0 ) {
3491
/* if ( ! SyQuiet ) { */
3492
Pr( "gap: hmm, I cannot find '%s' maybe",
3493
(Int)SySystemInitFile, 0L );
3494
Pr( " use option '-l <gaproot>'?\n If you ran the GAP"
3495
" binary directly, try running the 'gap.sh' or 'gap.bat'"
3496
" script instead.", 0L, 0L );
3497
}
3498
}
3499
else
3500
{
3501
Pr("Caught error at top-most level, probably quit from library loading",0L,0L);
3502
SyExit(1);
3503
}
3504
/* } */
3505
}
3506
3507
}
3508
3509
/****************************************************************************
3510
**
3511
*E gap.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
3512
*/
3513
3514