Annotation of OpenXM/src/kan96xx/Kan/stackmachine.c, Revision 1.10
1.10 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/Kan/stackmachine.c,v 1.9 2002/02/24 10:27:18 takayama Exp $ */
1.1 maekawa 2: /* stackmachin.c */
3:
4: #include <stdio.h>
5: #include "datatype.h"
6: #include "stackm.h"
7: #include "extern.h"
8: #include "gradedset.h"
9: #include "kclass.h"
10: #include <signal.h>
11: #include <sys/types.h>
12:
13:
14: /* #define OPERAND_STACK_SIZE 2000 */
15: #define OPERAND_STACK_SIZE 30000
16: #define SYSTEM_DICTIONARY_SIZE 200
1.8 takayama 17: /* #define USER_DICTIONARY_SIZE 1223, 3581, 27449 */
18: #define USER_DICTIONARY_SIZE 59359
1.1 maekawa 19: /* The value of USER_DICTIONARY_SIZE must be prime number, because of hashing
20: method */
21: #define ARGV_WORK_MAX (AGLIMIT+100)
22: #define EMPTY (char *)NULL
23:
24:
25: /* global variables */
26: struct object StandardStackA[OPERAND_STACK_SIZE];
27: int StandardStackP = 0;
28: int StandardStackMax = OPERAND_STACK_SIZE;
29: struct operandStack StandardStack;
30: /* Initialization of operandStack will be done in initSystemDictionary(). */
31: #define ERROR_STACK_SIZE 100
32: struct object ErrorStackA[ERROR_STACK_SIZE];
33: int ErrorStackP = 0;
34: int ErrorStackMax = ERROR_STACK_SIZE;
35: struct operandStack ErrorStack;
36: /* Initialization of ErrorStack will be done in initSystemDictionary(). */
37:
38: struct operandStack *CurrentOperandStack = &StandardStack;
39: struct object *OperandStack = StandardStackA;
40: int Osp = 0; /* OperandStack pointer */
41: int OspMax = OPERAND_STACK_SIZE;
42:
43: struct dictionary SystemDictionary[SYSTEM_DICTIONARY_SIZE];
44: int Sdp = 0; /* SystemDictionary pointer */
45: struct dictionary UserDictionary[USER_DICTIONARY_SIZE];
46:
47: struct context StandardContext ;
48: /* Initialization of StructContext will be done in initSystemDictionary(). */
49: /* hashInitialize is done in global.c (initStackmachine()) */
50: struct context *StandardContextp = &StandardContext;
51: struct context *CurrentContextp = &StandardContext;
52: struct context *PrimitiveContextp = &StandardContext;
53:
54:
55: static struct object ObjTmp; /* for poor compiler */
56:
57: int StandardMacros = 1;
58: int StartAFile = 0;
59: char *StartFile;
60:
61: int StartAString = 0;
62: char *StartString;
63:
64: char *GotoLabel = (char *)NULL;
65: int GotoP = 0;
66:
67: static char *SMacros =
68: #include "smacro.h"
69:
70: static isInteger(char *);
71: static strToInteger(char *);
72: static power(int s,int i);
73: static void pstack(void);
74: static struct object executableStringToExecutableArray(char *str);
75:
76: extern int SerialCurrent;
77:
78: int SGClock = 0;
79: int UserCtrlC = 0;
80: int OXlock = 0;
81: int OXlockSaved = 0;
82:
83: struct object * newObject()
84: {
85: struct object *r;
86: r = (struct object *)sGC_malloc(sizeof(struct object));
87: if (r == (struct object *)NULL) errorStackmachine("No memory\n");
88: r->tag = 0;
89: (r->lc).ival = 0;
90: (r->rc).ival = 0;
91: return(r);
92: }
93:
94: struct object newObjectArray(size)
1.7 takayama 95: int size;
1.1 maekawa 96: {
97: struct object rob;
98: struct object *op;
99: if (size < 0) return(NullObject);
100: if (size > 0) {
101: op = (struct object *)sGC_malloc(size*sizeof(struct object));
102: if (op == (struct object *)NULL) errorStackmachine("No memory\n");
103: }else{
104: op = (struct object *)NULL;
105: }
106: rob.tag = Sarray;
107: rob.lc.ival = size;
108: rob.rc.op = op;
109: return(rob);
110: }
111:
112: isNullObject(obj)
1.7 takayama 113: struct object obj;
1.1 maekawa 114: {
115: if (obj.tag == 0) return(1);
116: else return(0);
117: }
118:
119: int putSystemDictionary(str,ob)
1.7 takayama 120: char *str; /* key */
121: struct object ob; /* value */
1.1 maekawa 122: {
123: int i;
124: int j;
125: int flag = 0;
126:
127: for (i = Sdp-1; i>=0; i--) {
128: /*printf("Add %d %s\n",i,str);*/
129: if (strcmp(str,(SystemDictionary[i]).key) > 0) {
130: for (j=Sdp-1; j>=i+1; j--) {
1.7 takayama 131: (SystemDictionary[j+1]).key = (SystemDictionary[j]).key;
132: (SystemDictionary[j+1]).obj = (SystemDictionary[j]).obj;
1.1 maekawa 133: }
134: (SystemDictionary[i+1]).key = str;
135: (SystemDictionary[i+1]).obj = ob;
136: flag = 1;
137: break;
138: }
139: }
140: if (!flag) { /* str is the minimum element */
141: for (j=Sdp-1; j>=0; j--) {
142: (SystemDictionary[j+1]).key = (SystemDictionary[j]).key;
143: (SystemDictionary[j+1]).obj = (SystemDictionary[j]).obj;
144: }
145: (SystemDictionary[0]).key = str;
146: (SystemDictionary[0]).obj = ob;
147: }
148: Sdp++;
149: if (Sdp >= SYSTEM_DICTIONARY_SIZE) {
150: warningStackmachine("No space for system dictionary area.\n");
151: Sdp--;
152: return(-1);
153: }
154: return(Sdp-1);
155: }
156:
157: int findSystemDictionary(str)
158: /* only used for primitive functions */
159: /* returns 0, if there is no item. */
160: /* This function assumes that the dictionary is sorted by strcmp() */
161: char *str; /* key */
162: {
163: int first,last,rr,middle;
164:
165: /* binary search */
166: first = 0; last = Sdp-1;
167: while (1) {
168: if (first > last) {
169: return(0);
170: } else if (first == last) {
171: if (strcmp(str,(SystemDictionary[first]).key) == 0) {
1.7 takayama 172: return((SystemDictionary[first]).obj.lc.ival);
1.1 maekawa 173: }else {
1.7 takayama 174: return(0);
1.1 maekawa 175: }
176: } else if (last - first == 1) { /* This case is necessary */
177: if (strcmp(str,(SystemDictionary[first]).key) == 0) {
1.7 takayama 178: return((SystemDictionary[first]).obj.lc.ival);
1.1 maekawa 179: }else if (strcmp(str,(SystemDictionary[last]).key) == 0) {
1.7 takayama 180: return((SystemDictionary[last]).obj.lc.ival);
1.1 maekawa 181: }else return(0);
182: }
183:
184: middle = (first + last)/2;
185: rr = strcmp(str,(SystemDictionary[middle]).key);
186: if (rr < 0) { /* str < middle */
187: last = middle;
188: }else if (rr == 0) {
189: return((SystemDictionary[middle]).obj.lc.ival);
190: }else { /* str > middle */
191: first = middle;
192: }
193: }
194: }
195:
196: int putUserDictionary(str,h0,h1,ob,dic)
1.7 takayama 197: char *str; /* key */
198: int h0,h1; /* Hash values of the key */
199: struct object ob; /* value */
200: struct dictionary *dic;
1.1 maekawa 201: {
202: int x,r;
203: extern int Strict2;
204: x = h0;
205: if (str[0] == '\0') {
206: errorKan1("%s\n","putUserDictionary(): You are defining a value with the null key.");
207: }
208: while (1) {
209: if ((dic[x]).key == EMPTY) break;
210: if (strcmp((dic[x]).key,str) == 0) break;
211: x = (x+h1) % USER_DICTIONARY_SIZE;
212: if (x == h0) {
213: errorStackmachine("User dictionary is full. loop hashing.\n");
214: }
215: }
216: r = x;
217: if (Strict2) {
218: switch((dic[x]).attr) {
219: case PROTECT:
220: r = -PROTECT; /* Protected, but we rewrite it. */
221: break;
222: case ABSOLUTE_PROTECT:
223: r = -ABSOLUTE_PROTECT; /* Protected and we do not rewrite it. */
224: return(r);
225: default:
226: (dic[x]).attr = 0;
227: break;
228: }
229: }
230: (dic[x]).key = str;
231: (dic[x]).obj = ob;
232: (dic[x]).h0 = h0;
233: (dic[x]).h1 = h1;
234: return(r);
235: }
236:
237: struct object KputUserDictionary(char *str,struct object ob)
238: {
239: int r;
240: r = putUserDictionary(str,hash0(str),hash1(str),ob,CurrentContextp->userDictionary);
241: return(KpoInteger(r));
242: }
243:
244: struct object findUserDictionary(str,h0,h1,cp)
1.7 takayama 245: /* returns NoObject, if there is no item. */
246: char *str; /* key */
247: int h0,h1; /* The hashing values of the key. */
248: struct context *cp;
1.1 maekawa 249: {
250: int x;
251: struct dictionary *dic;
252: dic = cp->userDictionary;
253: x = h0;
254: while (1) {
255: if ((dic[x]).key == EMPTY) { break; }
256: if (strcmp((dic[x]).key,str) == 0) {
257: return( (dic[x]).obj );
258: }
259: x = (x+h1) % USER_DICTIONARY_SIZE;
260: if (x == h0) {
261: errorStackmachine("User dictionary is full. loop hashing in findUserDictionary.\n");
262: }
263: }
264: if (cp->super == (struct context *)NULL) return(NoObject);
265: else return(findUserDictionary(str,h0,h1,cp->super));
266:
267: }
268:
269: struct object KfindUserDictionary(char *str) {
270: return(findUserDictionary(str,hash0(str),hash1(str),CurrentContextp));
271: }
272:
273: int putUserDictionary2(str,h0,h1,attr,dic)
1.7 takayama 274: char *str; /* key */
275: int h0,h1; /* Hash values of the key */
276: int attr; /* attribute field */
277: struct dictionary *dic;
1.1 maekawa 278: {
279: int x;
280: int i;
281: if (SET_ATTR_FOR_ALL_WORDS & attr) {
282: for (i=0; i<USER_DICTIONARY_SIZE; i++) {
283: if ((dic[i]).key !=EMPTY) (dic[i]).attr = attr&(~SET_ATTR_FOR_ALL_WORDS);
284: }
285: return(0);
286: }
287: x = h0;
288: if (str[0] == '\0') {
289: errorKan1("%s\n","putUserDictionary2(): You are defining a value with the null key.");
290: }
291: while (1) {
292: if ((dic[x]).key == EMPTY) return(-1);
293: if (strcmp((dic[x]).key,str) == 0) break;
294: x = (x+h1) % USER_DICTIONARY_SIZE;
295: if (x == h0) {
296: errorStackmachine("User dictionary is full. loop hashing.\n");
297: }
298: }
299: (dic[x]).attr = attr;
300: return(x);
301: }
302:
303:
304: int putPrimitiveFunction(str,number)
1.7 takayama 305: char *str;
306: int number;
1.1 maekawa 307: {
308: struct object ob;
309: ob.tag = Soperator;
310: ob.lc.ival = number;
311: return(putSystemDictionary(str,ob));
312: }
313:
314: struct tokens lookupTokens(t)
1.7 takayama 315: struct tokens t;
1.1 maekawa 316: {
317: struct object *left;
318: struct object *right;
319: t.object.tag = Slist;
320: left = t.object.lc.op = newObject();
321: right = t.object.rc.op = newObject();
322: left->tag = Sinteger;
323: (left->lc).ival = hash0(t.token);
324: (left->rc).ival = hash1(t.token);
325: right->tag = Sinteger;
326: (right->lc).ival = findSystemDictionary(t.token);
327: return(t);
328: }
329:
330: struct object lookupLiteralString(s)
1.7 takayama 331: char *s; /* s must be a literal string */
1.1 maekawa 332: {
333: struct object ob;
334: ob.tag = Slist;
335: ob.lc.op = newObject();
336: ob.rc.op = (struct object *)NULL;
337: ob.lc.op->tag = Sinteger;
338: (ob.lc.op->lc).ival = hash0(&(s[1]));
339: (ob.lc.op->rc).ival = hash1(&(s[1]));
340: return(ob);
341: }
342:
343:
344: int hash0(str)
1.7 takayama 345: char *str;
1.1 maekawa 346: {
347: int h=0;
348: while (*str != '\0') {
349: h = ((h*128)+(*str)) % USER_DICTIONARY_SIZE;
350: str++;
351: }
352: return(h);
353: }
354:
355: int hash1(str)
1.7 takayama 356: char *str;
1.1 maekawa 357: {
358: return(8-(str[0]%8));
359: }
360:
361: void hashInitialize(struct dictionary *dic)
362: {
363: int i;
364: for (i=0; i<USER_DICTIONARY_SIZE; i++) {
365: (dic[i]).key = EMPTY; (dic[i]).attr = 0;
366: }
367: }
368:
369: static isInteger(str)
1.7 takayama 370: char *str;
1.1 maekawa 371: {
372: int i;
373: int n;
374: int start;
375:
376: n = strlen(str);
377: if ((str[0] == '+') || (str[0] == '-'))
378: start = 1;
379: else
380: start = 0;
381: if (start >= n) return(0);
382:
383: for (i=start; i<n; i++) {
384: if (('0' <= str[i]) && (str[i] <= '9')) ;
385: else return(0);
386: }
387: return(1);
388: }
389:
390: static strToInteger(str)
1.7 takayama 391: char *str;
1.1 maekawa 392: {
393: int i;
394: int n;
395: int r;
396: int start;
397:
398: if ((str[0] == '+') || (str[0] == '-'))
399: start = 1;
400: else
401: start = 0;
402: n = strlen(str);
403: r = 0;
404: for (i=n-1; i>=start ; i--) {
405: r += (int)(str[i]-'0') *power(10,n-1-i);
406: }
407: if (str[0] == '-') r = -r;
408: return(r);
409: }
410:
411: static power(s,i)
1.7 takayama 412: int s;
413: int i;
1.1 maekawa 414: {
415: if (i == 0) return 1;
416: else return( s*power(s,i-1) );
417: }
418:
419: int Kpush(ob)
1.7 takayama 420: struct object ob;
1.1 maekawa 421: {
422: OperandStack[Osp++] = ob;
423: if (Osp >= OspMax) {
424: warningStackmachine("Operand stack overflow. \n");
425: Osp--;
426: return(-1);
427: }
428: return(0);
429: }
430:
431: struct object Kpop()
432: {
433: if (Osp <= 0) {
434: return( NullObject );
435: }else{
436: return( OperandStack[--Osp]);
437: }
438: }
439:
440: struct object peek(k)
1.7 takayama 441: int k;
1.1 maekawa 442: {
443: if ((Osp-k-1) < 0) {
444: return( NullObject );
445: }else{
446: return( OperandStack[Osp-k-1]);
447: }
448: }
449:
450:
451: struct object newOperandStack(int size)
452: {
453: struct operandStack *os ;
454: struct object ob;
455: os = (struct operandStack *)sGC_malloc(sizeof(struct operandStack));
456: if (os == (void *)NULL) errorStackmachine("No more memory.");
457: if (size <= 0) errorStackmachine("Size of stack must be more than 1.");
458: os->size = size;
459: os->sp = 0;
460: os->ostack = (struct object *)sGC_malloc(sizeof(struct object)*(size+1));
461: if (os->ostack == (void *)NULL) errorStackmachine("No more memory.");
462: ob.tag = Sclass;
463: ob.lc.ival = CLASSNAME_OPERANDSTACK;
464: ob.rc.voidp = os;
465: return(ob);
466: }
467:
468: void setOperandStack(struct object ob) {
469: if (ob.tag != Sclass) errorStackmachine("The argument must be class.");
470: if (ob.lc.ival != CLASSNAME_OPERANDSTACK)
471: errorStackmachine("The argument must be class.OperandStack.");
472: CurrentOperandStack->ostack = OperandStack;
473: CurrentOperandStack->sp = Osp;
474: CurrentOperandStack->size = OspMax;
475: OperandStack = ((struct operandStack *)(ob.rc.voidp))->ostack;
476: Osp = ((struct operandStack *)(ob.rc.voidp))->sp;
477: OspMax = ((struct operandStack *)(ob.rc.voidp))->size;
478: CurrentOperandStack = ob.rc.voidp;
479: }
480:
481: void stdOperandStack(void) {
482: CurrentOperandStack->ostack = OperandStack;
483: CurrentOperandStack->sp = Osp;
484: CurrentOperandStack->size = OspMax;
485:
486: CurrentOperandStack = &StandardStack;
487: OperandStack = CurrentOperandStack->ostack;
488: Osp = CurrentOperandStack->sp;
489: OspMax = CurrentOperandStack->size;
490: }
491:
492: /* functions to handle contexts. */
493: void fprintContext(FILE *fp,struct context *cp) {
494: if (cp == (struct context *)NULL) {
495: fprintf(fp," Context=NIL \n");
496: return;
497: }
498: fprintf(fp," ContextName = %s, ",cp->contextName);
499: fprintf(fp,"Super = ");
500: if (cp->super == (struct context *)NULL) fprintf(fp,"NIL");
501: else {
502: fprintf(fp,"%s",cp->super->contextName);
503: }
504: fprintf(fp,"\n");
505: }
506:
507: struct context *newContext0(struct context *super,char *name) {
508: struct context *cp;
509: cp = sGC_malloc(sizeof(struct context));
510: if (cp == (struct context *)NULL) errorStackmachine("No memory (newContext0)");
511: cp->userDictionary=sGC_malloc(sizeof(struct dictionary)*USER_DICTIONARY_SIZE);
512: if (cp->userDictionary==(struct dictionary *)NULL)
513: errorStackmachine("No memory (newContext0)");
514: hashInitialize(cp->userDictionary);
515: cp->contextName = name;
516: cp->super = super;
517: return(cp);
518: }
519:
520: void KsetContext(struct object contextObj) {
521: if (contextObj.tag != Sclass) {
522: errorStackmachine("Usage:setcontext");
523: }
524: if (contextObj.lc.ival != CLASSNAME_CONTEXT) {
525: errorStackmachine("Usage:setcontext");
526: }
527: if (contextObj.rc.voidp == NULL) {
528: errorStackmachine("You cannot set NullContext to the CurrentContext.");
529: }
530: CurrentContextp = (struct context *)(contextObj.rc.voidp);
531: }
532:
533:
534: struct object getSuperContext(struct object contextObj) {
535: struct object rob;
536: struct context *cp;
537: if (contextObj.tag != Sclass) {
538: errorStackmachine("Usage:supercontext");
539: }
540: if (contextObj.lc.ival != CLASSNAME_CONTEXT) {
541: errorStackmachine("Usage:supercontext");
542: }
543: cp = (struct context *)(contextObj.rc.voidp);
544: if (cp->super == (struct context *)NULL) {
545: return(NullObject);
546: }else{
547: rob.tag = Sclass;
548: rob.lc.ival = CLASSNAME_CONTEXT;
549: rob.rc.voidp = cp->super;
550: }
551: return(rob);
552: }
553:
554: #define CSTACK_SIZE 1000
555: void contextControl(actionOfContextControl ctl) {
556: static struct context *cstack[CSTACK_SIZE];
557: static int cstackp = 0;
558: switch(ctl) {
559: case CCRESTORE:
560: if (cstackp == 0) return;
561: else {
562: CurrentContextp = cstack[0];
563: cstackp = 0;
564: }
565: break;
566: case CCPUSH:
567: if (cstackp < CSTACK_SIZE) {
568: cstack[cstackp] = CurrentContextp;
569: cstackp++;
570: }else{
571: contextControl(CCRESTORE);
572: errorStackmachine("Context stack (cstack) is overflow. CurrentContext is restored.\n");
573: }
574: break;
575: case CCPOP:
576: if (cstackp > 0) {
577: cstackp--;
578: CurrentContextp = cstack[cstackp];
579: }
580: break;
581: default:
582: break;
583: }
584: return;
585: }
586:
587:
588:
589: int isLiteral(str)
1.7 takayama 590: char *str;
1.1 maekawa 591: {
592: if (strlen(str) <2) return(0);
593: else {
594: if ((str[0] == '/') && (str[1] != '/')) return(1);
595: else return(0);
596: }
597: }
598:
599: void printOperandStack() {
600: int i;
601: struct object ob;
602: int vs;
603: vs = VerboseStack; VerboseStack = 2;
604: for (i=Osp-1; i>=0; i--) {
605: fprintf(Fstack,"[%d] ",i);
606: ob = OperandStack[i];
607: printObject(ob,1,Fstack);
608: }
609: VerboseStack = vs;
610: }
611:
612:
613:
614: static initSystemDictionary()
1.7 takayama 615: {
1.1 maekawa 616: StandardStack.ostack = StandardStackA;
617: StandardStack.sp = StandardStackP;
618: StandardStack.size = OPERAND_STACK_SIZE;
619:
620: ErrorStack.ostack = ErrorStackA;
621: ErrorStack.sp = ErrorStackP;
622: ErrorStack.size = ErrorStackMax;
623:
624: StandardContext.userDictionary = UserDictionary;
625: StandardContext.contextName = "StandardContext";
626: StandardContext.super = (struct context *)NULL;
627:
628: KdefinePrimitiveFunctions();
629:
1.7 takayama 630: }
1.1 maekawa 631:
632: struct object showSystemDictionary(int f) {
633: int i;
634: int maxl;
635: char format[1000];
636: int nl;
637: struct object rob;
638: rob = NullObject;
639: if (f != 0) {
640: rob = newObjectArray(Sdp);
641: for (i=0; i<Sdp; i++) {
642: putoa(rob,i,KpoString((SystemDictionary[i]).key));
643: }
644: return(rob);
645: }
646: maxl = 1;
647: for (i=0; i<Sdp; i++) {
648: if (strlen((SystemDictionary[i]).key) >maxl)
649: maxl = strlen((SystemDictionary[i]).key);
650: }
651: maxl += 3;
652: nl = 80/maxl;
653: if (nl < 2) nl = 2;
654: sprintf(format,"%%-%ds",maxl);
655: for (i=0; i<Sdp; i++) {
656: fprintf(Fstack,format,(SystemDictionary[i]).key);
657: if (i % nl == nl-1) fprintf(Fstack,"\n");
658: }
659: fprintf(Fstack,"\n");
660: return(rob);
661: }
662:
663: int showUserDictionary()
664: {
665: int i,j;
666: int maxl;
667: char format[1000];
668: int nl;
669: struct dictionary *dic;
670: dic = CurrentContextp->userDictionary;
671: fprintf(Fstack,"DictionaryName=%s, super= ",CurrentContextp->contextName);
672: if (CurrentContextp->super == (struct context *)NULL) {
673: fprintf(Fstack,"NIL\n");
674: }else{
675: fprintf(Fstack,"%s\n",CurrentContextp->super->contextName);
676: }
677: maxl = 1;
678: for (i=0; i<USER_DICTIONARY_SIZE; i++) {
679: if ((dic[i]).key != EMPTY) {
680: if (strlen((dic[i]).key) >maxl)
1.7 takayama 681: maxl = strlen((dic[i]).key);
1.1 maekawa 682: }
683: }
684: maxl += 3;
685: nl = 80/maxl;
686: if (nl < 2) nl = 2;
687: sprintf(format,"%%-%ds",maxl);
688: for (i=0,j=0; i<USER_DICTIONARY_SIZE; i++) {
689: if ((dic[i]).key != EMPTY) {
690: fprintf(Fstack,format,(dic[i]).key);
691: /*{ char *sss; int ii,h0,h1;
1.7 takayama 692: sss = dic[i].key;
693: h0 = dic[i].h0;
694: h1 = dic[i].h1;
695: for (ii=0; ii<strlen(sss); ii++) fprintf(Fstack,"%x ",sss[ii]);
696: fprintf(Fstack,": h0=%d, h1=%d, %d\n",h0,h1,i);
697: }*/
1.1 maekawa 698: if (j % nl == nl-1) fprintf(Fstack,"\n");
699: j++;
700: }
701: }
702: fprintf(Fstack,"\n");
703: }
704:
705:
706: static struct object executableStringToExecutableArray(s)
1.7 takayama 707: char *s;
1.1 maekawa 708: {
709: struct tokens *tokenArray;
710: struct object ob;
711: int i;
712: int size;
713: tokenArray = decomposeToTokens(s,&size);
714: ob.tag = SexecutableArray;
715: ob.lc.tokenArray = tokenArray;
716: ob.rc.ival = size;
717: for (i=0; i<size; i++) {
718: if ( ((ob.lc.tokenArray)[i]).kind == EXECUTABLE_STRING) {
719: ((ob.lc.tokenArray)[i]).kind = EXECUTABLE_ARRAY;
720: ((ob.lc.tokenArray)[i]).object =
1.7 takayama 721: executableStringToExecutableArray(((ob.lc.tokenArray)[i]).token);
1.1 maekawa 722: }
723: }
724: return(ob);
725: }
726: /**************** stack machine **************************/
727: void scanner() {
728: struct tokens token;
729: struct object ob;
730: extern int Quiet;
731: extern void ctrlC();
732: int tmp;
733: char *tmp2;
734: extern int ErrorMessageMode;
735: int jval;
736: getokenSM(INIT);
737: initSystemDictionary();
738:
1.9 takayama 739: #if defined(__CYGWIN__)
740: if (sigsetjmp(EnvOfStackMachine,1)) {
741: #else
1.1 maekawa 742: if (setjmp(EnvOfStackMachine)) {
1.9 takayama 743: #endif
1.1 maekawa 744: /* do nothing in the case of error */
745: fprintf(stderr,"An error or interrupt in reading macros, files and command strings.\n");
746: exit(10);
747: } else { }
748: if (signal(SIGINT,SIG_IGN) != SIG_IGN) {
749: signal(SIGINT,ctrlC);
750: }
751:
752: /* setup quiet mode or not */
753: token.kind = EXECUTABLE_STRING;
754: if (Quiet) {
755: token.token = " /@@@.quiet 1 def ";
756: }else {
757: token.token = " /@@@.quiet 0 def ";
758: }
759: executeToken(token); /* execute startup commands */
760: token.kind = ID;
761: token.token = "exec";
762: token = lookupTokens(token); /* set hashing values */
763: tmp = findSystemDictionary(token.token);
764: ob.tag = Soperator;
765: ob.lc.ival = tmp;
766: executePrimitive(ob); /* exec */
767:
768:
769: KSdefineMacros();
770:
771: if (StartAFile) {
772: tmp2 = StartFile;
773: StartFile = (char *)sGC_malloc(sizeof(char)*(strlen(StartFile)+
1.7 takayama 774: 40));
1.1 maekawa 775: sprintf(StartFile,"$%s$ run\n",tmp2);
776: token.kind = EXECUTABLE_STRING;
777: token.token = StartFile;
1.7 takayama 778: executeToken(token); /* execute startup commands */
1.1 maekawa 779: token.kind = ID;
780: token.token = "exec";
781: token = lookupTokens(token); /* set hashing values */
782: tmp = findSystemDictionary(token.token);
783: ob.tag = Soperator;
784: ob.lc.ival = tmp;
1.7 takayama 785: executePrimitive(ob); /* exec */
1.1 maekawa 786: }
787:
788: if (StartAString) {
789: token.kind = EXECUTABLE_STRING;
790: token.token = StartString;
1.7 takayama 791: executeToken(token); /* execute startup commands */
1.1 maekawa 792: token.kind = ID;
793: token.token = "exec";
794: token = lookupTokens(token); /* set hashing values */
795: tmp = findSystemDictionary(token.token);
796: ob.tag = Soperator;
797: ob.lc.ival = tmp;
1.7 takayama 798: executePrimitive(ob); /* exec */
1.1 maekawa 799: }
800:
801:
802: for (;;) {
1.9 takayama 803: #if defined(__CYGWIN__)
804: if (jval=sigsetjmp(EnvOfStackMachine,1)) {
805: #else
1.1 maekawa 806: if (jval=setjmp(EnvOfStackMachine)) {
1.9 takayama 807: #endif
1.1 maekawa 808: /* *** The following does not work properly. ****
1.7 takayama 809: if (jval == 2) {
810: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
811: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
812: }
813: }
814: **** */
1.1 maekawa 815: if (DebugStack >= 1) {
1.7 takayama 816: fprintf(Fstack,"\nscanner> ");
1.1 maekawa 817: }
818: KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */
1.10 ! takayama 819: KSexecuteString(" (Computation is interrupted.) ");
1.7 takayama 820: continue ;
1.1 maekawa 821: } else { }
822: if (DebugStack >= 1) { printOperandStack(); }
823: token = getokenSM(GET);
824: if ((tmp=executeToken(token)) < 0) break;
825: /***if (tmp == 1) fprintf(stderr," --- exit --- \n");*/
826: }
827: }
828:
829:
830: void ctrlC(sig)
1.7 takayama 831: int sig;
1.1 maekawa 832: {
833: extern void ctrlC();
834: extern int ErrorMessageMode;
835: extern int SGClock;
836: extern int UserCtrlC;
837: extern int OXlock;
838:
839: signal(sig,SIG_IGN);
840: /* see 133p */
1.10 ! takayama 841: cancelAlarm();
! 842: if (sig == SIGALRM) {
! 843: fprintf(stderr,"ctrlC by SIGALRM\n");
! 844: }
1.1 maekawa 845:
846: if (SGClock) {
847: UserCtrlC = 1;
848: fprintf(stderr,"ctrl-c is locked because of gc.\n");
1.10 ! takayama 849: signal(sig,ctrlC); if (sig == SIGALRM) alarm((unsigned int)10);
1.1 maekawa 850: return;
851: }
852: if (OXlock) {
853: if (UserCtrlC > 0) UserCtrlC++;
854: else UserCtrlC = 1;
855: if (UserCtrlC > 3) {
856: fprintf(stderr,"OK. You are eager to cancel the computation.\n");
857: fprintf(stderr,"You should close the ox communication cannel.\n");
858: signal(SIGINT,ctrlC);
859: unlockCtrlCForOx();
860: }
861: fprintf(stderr,"ctrl-c is locked because of ox lock %d.\n",UserCtrlC);
1.10 ! takayama 862: signal(sig,ctrlC); if (sig == SIGALRM) alarm((unsigned int)10);
1.1 maekawa 863: return;
864: }
865: if (ErrorMessageMode != 1) {
866: fprintf(Fstack,"User interruption by ctrl-C. We are in the top-level.\n");
867: fprintf(Fstack,"Type in quit in order to exit sm1.\n");
868: }
869: if (GotoP) {
870: fprintf(Fstack,"The interpreter was looking for the label <<%s>>. It is also aborted.\n",GotoLabel);
871: GotoP = 0;
872: }
873: stdOperandStack(); contextControl(CCRESTORE);
874: /*fprintf(Fstack,"Warning! The handler of ctrl-C has a bug, so you might have a core-dump.\n");*/
875: /*
876: $(x0+1)^50$ $x1 x0 + x1^20$ 2 groebner_n
877: ctrl-C
878: $(x0+1)^50$ $x1 x0 + x1^20$ 2 groebner_n
879: It SOMETIMES makes core dump.
880: */
881: getokenSM(INIT); /* It might fix the bug above. 1992/11/14 */
882: signal(SIGINT,ctrlC);
1.9 takayama 883: #if defined(__CYGWIN__)
884: siglongjmp(EnvOfStackMachine,2);
885: #else
1.1 maekawa 886: longjmp(EnvOfStackMachine,2); /* returns 2 for ctrl-C */
1.9 takayama 887: #endif
1.1 maekawa 888: }
889:
890: int executeToken(token)
1.7 takayama 891: struct tokens token;
1.1 maekawa 892: {
893: struct object ob;
894: int primitive;
895: int size;
896: int status;
897: struct tokens *tokenArray;
898: int i,h0,h1;
899: extern int WarningMessageMode;
900: extern int Strict;
901:
902: if (GotoP) { /* for goto */
903: if (token.kind == ID && isLiteral(token.token)) {
904: if (strcmp(&((token.token)[1]),GotoLabel) == 0) {
1.7 takayama 905: GotoP = 0;
906: return(0); /* normal exit */
1.1 maekawa 907: }
908: }
909: return(0); /* normal exit */
910: }
911: if (token.kind == DOLLAR) {
912: ob.tag = Sdollar;
913: ob.lc.str = token.token;
914: Kpush(ob);
915: } else if (token.kind == ID) { /* ID */
916:
917: if (strcmp(token.token,"exit") == 0) return(1);
918: /* "exit" is not primitive here. */
919:
920: if (isLiteral(token.token)) {
921: /* literal object */
922: ob.tag = Sstring;
923: ob.lc.str = (char *)sGC_malloc((strlen(token.token)+1)*sizeof(char));
924: if (ob.lc.str == (char *)NULL) errorStackmachine("No space.");
925: strcpy(ob.lc.str, &((token.token)[1]));
926:
927: if (token.object.tag != Slist) {
1.7 takayama 928: fprintf(Fstack,"\n%%Warning: The hashing values for the <<%s>> are not set.\n",token.token);
929: token.object = lookupLiteralString(token.token);
1.1 maekawa 930: }
931: ob.rc.op = token.object.lc.op;
932: Kpush(ob);
933: } else if (isInteger(token.token)) {
934: /* integer object */
935: ob.tag = Sinteger ;
936: ob.lc.ival = strToInteger(token.token);
937: Kpush(ob);
938: } else {
939: if (token.object.tag != Slist) {
1.7 takayama 940: fprintf(Fstack,"\n%%Warning: The hashing values for the <<%s>> are not set.\n",token.token);
941: token = lookupTokens(token);
1.1 maekawa 942: }
943: h0 = ((token.object.lc.op)->lc).ival;
944: h1 = ((token.object.lc.op)->rc).ival;
945: ob=findUserDictionary(token.token,h0,h1,CurrentContextp);
946: primitive = ((token.object.rc.op)->lc).ival;
947: if (ob.tag >= 0) {
1.7 takayama 948: /* there is a definition in the user dictionary */
949: if (ob.tag == SexecutableArray) {
950: tokenArray = ob.lc.tokenArray;
951: size = ob.rc.ival;
952: for (i=0; i<size; i++) {
953: status = executeToken(tokenArray[i]);
954: if (status != 0) return(status);
955: }
956: }else {
957: Kpush(ob);
958: }
1.1 maekawa 959: } else if (primitive) {
1.7 takayama 960: /* system operator */
961: ob.tag = Soperator;
962: ob.lc.ival = primitive;
963: return(executePrimitive(ob));
1.1 maekawa 964: } else {
1.7 takayama 965: if (WarningMessageMode == 1 || WarningMessageMode == 2) {
966: char tmpc[1024];
967: if (strlen(token.token) < 900) {
968: sprintf(tmpc,"\n%%Warning: The identifier <<%s>> is not in the system dictionary\n%% nor in the user dictionaries. Push NullObject.\n",token.token);
969: }else {strcpy(tmpc,"Warning: identifier is not in the dictionaries.");}
970: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,tmpc));
971: }
972: if (WarningMessageMode != 1) {
973: fprintf(Fstack,"\n%%Warning: The identifier <<%s>> is not in the system dictionary\n%% nor in the user dictionaries. Push NullObject.\n",token.token);
974: /*fprintf(Fstack,"(%d,%d)\n",h0,h1);*/
975: }
976: if (Strict) {
977: errorStackmachine("Warning: identifier is not in the dictionaries");
978: }
979: Kpush(NullObject);
1.1 maekawa 980: }
981: }
982: } else if (token.kind == EXECUTABLE_STRING) {
983: Kpush(executableStringToExecutableArray(token.token));
984: } else if (token.kind == EXECUTABLE_ARRAY) {
985: Kpush(token.object);
986: } else if ((token.kind == -1) || (token.kind == -2)) { /* eof token */
987: return(-1);
988: } else {
989: /*fprintf(Fstack,"\n%%Error: Unknown token type\n");***/
990: fprintf(stderr,"\nUnknown token type = %d\n",token.kind);
991: fprintf(stderr,"\ntype in ctrl-\\ if you like to make core-dump.\n");
992: fprintf(stderr,"If you like to continue, type in RETURN key.\n");
993: fprintf(stderr,"Note that you cannot input null string.\n");
994: getchar();
995: errorStackmachine("Error: Unknown token type.\n");
996: /* return(-2); /* exit */
997: }
998: return(0); /* normal exit */
999: }
1000:
1001:
1002:
1003:
1004: errorStackmachine(str)
1.7 takayama 1005: char *str;
1.1 maekawa 1006: {
1007: int i,j,k;
1008: static char *u="Usage:";
1009: char message0[1024];
1010: char *message;
1011: extern int ErrorMessageMode;
1.10 ! takayama 1012: cancelAlarm();
1.1 maekawa 1013: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
1014: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,str));
1015: }
1016: if (ErrorMessageMode != 1) {
1017: message = message0;
1018: i = 0;
1019: while (i<6 && str[i]!='0') {
1020: if (str[i] != u[i]) break;
1021: i++;
1022: }
1023: if (i==6) {
1024: fprintf(stderr,"ERROR(sm): \n");
1025: while (str[i] != '\0' && str[i] != ' ') {
1.7 takayama 1026: i++;
1.1 maekawa 1027: }
1028: if (str[i] == ' ') {
1.7 takayama 1029: fprintf(stderr," %s\n",&(str[i+1]));
1030: k = 0;
1031: if (i-6 > 1022) message = (char *)sGC_malloc(sizeof(char)*i);
1032: for (j=6; j<i ; j++) {
1033: message[k] = str[j];
1034: message[k+1] = '\0';
1035: k++;
1036: }
1037: Kusage2(stderr,message);
1.1 maekawa 1038: }else{
1.7 takayama 1039: Kusage2(stderr,&(str[6]));
1.1 maekawa 1040: }
1041: }else {
1042: fprintf(stderr,"ERROR(sm): ");
1043: fprintf(stderr,str);
1044: }
1045: fprintf(stderr,"\n");
1046: }
1047: if (GotoP) {
1048: fprintf(Fstack,"The interpreter was looking for the label <<%s>>. It is also aborted.\n",GotoLabel);
1049: GotoP = 0;
1050: }
1051: stdOperandStack(); contextControl(CCRESTORE);
1052: getokenSM(INIT); /* It might fix the bug. 1996/3/10 */
1053: /* fprintf(stderr,"Now, Long jump!\n"); */
1054: longjmp(EnvOfStackMachine,1);
1055: }
1056:
1057: warningStackmachine(str)
1.7 takayama 1058: char *str;
1.1 maekawa 1059: {
1060: extern int WarningMessageMode;
1061: extern int Strict;
1062: if (WarningMessageMode == 1 || WarningMessageMode == 2) {
1063: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,str));
1064: }
1065: if (WarningMessageMode != 1) {
1066: fprintf(stderr,"WARNING(sm): ");
1067: fprintf(stderr,str);
1068: }
1069: if (Strict) errorStackmachine(" ");
1070: return(0);
1071: }
1072:
1073:
1074: /* exports */
1075: /* NOTE: If you call this function and an error occured,
1076: you have to reset the jump buffer by setjmp(EnvOfStackMachine).
1077: cf. kxx/memo1.txt, kxx/stdserver00.c 1998, 2/6 */
1078: KSexecuteString(s)
1.7 takayama 1079: char *s;
1.1 maekawa 1080: {
1081: struct tokens token;
1082: struct object ob;
1083: int tmp;
1084: extern int CatchCtrlC;
1085: int jval;
1086: static int recursive = 0;
1087: extern int ErrorMessageMode;
1088: extern int KSPushEnvMode;
1089: jmp_buf saved_EnvOfStackMachine;
1090: void (*sigfunc)();
1091: int localCatchCtrlC ;
1092:
1093: localCatchCtrlC = CatchCtrlC;
1094: /* If CatchCtrlC is rewrited in this program,
1095: we crash. So, we use localCatchCtrlC. */
1096:
1097: if (localCatchCtrlC) {
1098: sigfunc = signal(SIGINT,SIG_IGN);
1099: signal(SIGINT,ctrlC);
1100: }
1101:
1102: if (KSPushEnvMode) {
1103: *saved_EnvOfStackMachine = *EnvOfStackMachine;
1.9 takayama 1104: #if defined(__CYGWIN__)
1105: if (jval = sigsetjmp(EnvOfStackMachine,1)) {
1106: #else
1.1 maekawa 1107: if (jval = setjmp(EnvOfStackMachine)) {
1.9 takayama 1108: #endif
1.1 maekawa 1109: *EnvOfStackMachine = *saved_EnvOfStackMachine;
1110: if (jval == 2) {
1.7 takayama 1111: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
1112: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
1113: }
1.1 maekawa 1114: }
1115: recursive--;
1116: if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1117: return(-1);
1118: }else{ }
1119: }else{
1120: if (recursive == 0) {
1.9 takayama 1121: #if defined(__CYGWIN__)
1122: if (jval=sigsetjmp(EnvOfStackMachine,1)) {
1123: #else
1.1 maekawa 1124: if (jval=setjmp(EnvOfStackMachine)) {
1.9 takayama 1125: #endif
1.7 takayama 1126: if (jval == 2) {
1127: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
1128: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
1129: }
1130: }
1131: recursive = 0;
1132: if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1133: return(-1);
1.1 maekawa 1134: }else { }
1135: }
1136: }
1137:
1138: recursive++;
1139: token.token = s;
1140: token.kind = EXECUTABLE_STRING;
1141: executeToken(token);
1142: token.kind = ID;
1143: token.token = "exec";
1144: token = lookupTokens(token); /* no use */
1145: tmp = findSystemDictionary(token.token);
1146: ob.tag = Soperator;
1147: ob.lc.ival = tmp;
1148: executePrimitive(ob);
1149: recursive--;
1150: if (KSPushEnvMode) *EnvOfStackMachine = *saved_EnvOfStackMachine;
1151: if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1152: return(0);
1153: }
1154:
1155: KSdefineMacros() {
1156: struct tokens token;
1157: int tmp;
1158: struct object ob;
1159:
1160: if (StandardMacros && (strlen(SMacros))) {
1161: token.kind = EXECUTABLE_STRING;
1162: token.token = SMacros;
1.7 takayama 1163: executeToken(token); /* execute startup commands */
1.1 maekawa 1164: token.kind = ID;
1165: token.token = "exec";
1166: token = lookupTokens(token); /* no use */
1167: tmp = findSystemDictionary(token.token);
1168: ob.tag = Soperator;
1169: ob.lc.ival = tmp;
1.7 takayama 1170: executePrimitive(ob); /* exec */
1.1 maekawa 1171: }
1172: return(0);
1173:
1174: }
1175:
1176: void KSstart() {
1177: struct tokens token;
1178: int tmp;
1179: struct object ob;
1180: extern int Quiet;
1181:
1182: stackmachine_init(); KinitKan();
1183: getokenSM(INIT); initSystemDictionary();
1184:
1185: /* The following line may cause a core dump, if you do not setjmp properly
1186: after calling KSstart().*/
1187: /*
1.7 takayama 1188: if (setjmp(EnvOfStackMachine)) {
1.1 maekawa 1189: fprintf(stderr,"KSstart(): An error or interrupt in reading macros, files and command strings.\n");
1190: exit(10);
1.7 takayama 1191: } else { } */
1.1 maekawa 1192:
1193: /* setup quiet mode or not */
1194: token.kind = EXECUTABLE_STRING;
1195: if (Quiet) {
1196: token.token = " /@@@.quiet 1 def ";
1197: }else {
1198: token.token = " /@@@.quiet 0 def ";
1199: }
1200: executeToken(token); /* execute startup commands */
1201: token.kind = ID;
1202: token.token = "exec";
1203: token = lookupTokens(token); /* set hashing values */
1204: tmp = findSystemDictionary(token.token);
1205: ob.tag = Soperator;
1206: ob.lc.ival = tmp;
1207: executePrimitive(ob); /* exec */
1208:
1209: KSdefineMacros();
1210: }
1211:
1212: void KSstop() {
1213: Kclose(); stackmachine_close();
1214: }
1215:
1216:
1217: struct object KSpop() {
1218: return(Kpop());
1219: }
1220:
1221: void KSpush(ob)
1.7 takayama 1222: struct object ob;
1.1 maekawa 1223: {
1224: Kpush(ob);
1.4 takayama 1225: }
1226:
1227: struct object KSpeek(k) {
1228: return(peek(k));
1.1 maekawa 1229: }
1230:
1231: char *KSstringPop() {
1232: /* pop a string */
1233: struct object rob;
1234: rob = Kpop();
1235: if (rob.tag == Sdollar) {
1236: return(rob.lc.str);
1237: }else{
1238: return((char *)NULL);
1239: }
1240: }
1241:
1242: char *KSpopString() {
1243: return(KSstringPop());
1244: }
1245:
1246: int KSset(char *name) {
1247: char *tmp2;
1248: char tmp[1024];
1249: tmp2 = tmp;
1250: if (strlen(name) < 1000) {
1251: sprintf(tmp2," /%s set ",name);
1252: }else{
1253: tmp2 = sGC_malloc(sizeof(char)*(strlen(name)+20));
1254: if (tmp2 == (char *)NULL) errorStackmachine("Out of memory.");
1255: sprintf(tmp2," /%s set ",name);
1256: }
1257: return( KSexecuteString(tmp2) );
1258: }
1259:
1260: int KSpushBinary(int size,char *data) {
1261: /* struct object KbinaryToObject(int size, char *data); */
1262: errorStackmachine("KSpushBinary is not implemented.\n");
1263: return(-1);
1264: }
1265:
1266: char *KSpopBinary(int *size) {
1267: /* char *KobjectToBinary(struct object ob,int *size); */
1268: errorStackmachine("KSpopBinary is not implemented.\n");
1269: *size = 0;
1270: return((char *)NULL);
1271: }
1272:
1273: int pushErrorStack(struct object obj)
1274: {
1275: if (CurrentOperandStack == &ErrorStack) {
1276: fprintf(stderr,"You cannot call pushErrorStack when ErrorStack is the CurrentOperandStack. \n");
1277: return(-1);
1278: }
1279: (ErrorStack.ostack)[(ErrorStack.sp)++] = obj;
1280: /* printf("ErrorStack.sp = %d\n",ErrorStack.sp); */
1281: if ((ErrorStack.sp) >= (ErrorStack.size)) {
1282: ErrorStack.sp = 0;
1283: fprintf(stderr,"pushErrorStack():ErrorStack overflow. It is reset.\n");
1284: /* Note that it avoids recursive call.*/
1285: return(-1);
1286: }
1287: return(0);
1288: }
1289:
1290: struct object popErrorStack(void) {
1291: if (CurrentOperandStack == &ErrorStack) {
1292: fprintf(stderr,"You cannot call popErrorStack when ErrorStack is the CurrentOperandStack. \n");
1293: return(NullObject);
1294: }
1295: if ((ErrorStack.sp) <= 0) {
1296: return( NullObject );
1297: }else{
1298: return( (ErrorStack.ostack)[--(ErrorStack.sp)]);
1299: }
1300: }
1301:
1302: char *popErrorStackByString(void) {
1303: struct object obj;
1304: struct object eobj;
1305: eobj = popErrorStack();
1306: if (ectag(eobj) != CLASSNAME_ERROR_PACKET) {
1307: return(NULL);
1308: }else{
1309: obj = *(KopErrorPacket(eobj));
1310: }
1311: if (obj.tag != Sarray || getoaSize(obj) != 3) {
1312: fprintf(stderr,"errorPacket format error.\n");
1313: printObject(eobj,0,stderr); fflush(stderr);
1314: return("class errorPacket format error. Bug of sm1.");
1315: }
1316: obj = getoa(obj,2);
1317: if (obj.tag != Sdollar) {
1318: fprintf(stderr,"errorPacket format error at position 2..\n");
1319: printObject(eobj,0,stderr); fflush(stderr);
1320: return("class errorPacket format error at the position 2. Bug of sm1.");
1321: }
1322: return(KopString(obj));
1323: }
1324:
1325:
1326: int KScheckErrorStack(void)
1327: {
1328: return(ErrorStack.sp);
1329: }
1330:
1331: struct object KnewErrorPacket(int serial,int no,char *message)
1332: {
1333: struct object obj;
1334: struct object *myop;
1335: char *s;
1336: /* Set extended tag. */
1337: obj.tag = Sclass; obj.lc.ival = CLASSNAME_ERROR_PACKET ;
1338: myop = (struct object *)sGC_malloc(sizeof(struct object));
1339: if (myop == (struct object *)NULL) errorStackmachine("No memory\n");
1340: *myop = newObjectArray(3);
1341: /*fprintf(stderr,"newErrorPacket() in stackmachine.c: [%d, %d, %s] \n",serial,no,message); **kxx:CMO_ERROR */
1342: putoa((*myop),0,KpoInteger(serial));
1343: putoa((*myop),1,KpoInteger(no));
1344: s = (char *)sGC_malloc(sizeof(char)*(strlen(message)+2));
1345: if (s == (char *)NULL) errorStackmachine("No memory\n");
1346: strcpy(s,message);
1347: putoa((*myop),2,KpoString(s));
1348: obj.rc.op = myop;
1349: return(obj);
1350: }
1351:
1352:
1353: struct object KnewErrorPacketObj(struct object ob1)
1354: {
1355: struct object obj;
1356: struct object *myop;
1357: char *s;
1358: /* Set extended tag. */
1359: obj.tag = Sclass; obj.lc.ival = CLASSNAME_ERROR_PACKET ;
1360: myop = (struct object *)sGC_malloc(sizeof(struct object));
1361: if (myop == (struct object *)NULL) errorStackmachine("No memory\n");
1362: *myop = ob1;
1363: obj.rc.op = myop;
1364: return(obj);
1365: }
1366:
1367: void *sGC_malloc(size_t n) { /* synchronized function */
1368: void *c;
1369: int id;
1370: extern int SGClock, UserCtrlC;
1371:
1372: SGClock = 1;
1373: c = GC_malloc(n);
1374: SGClock = 0;
1375: if (UserCtrlC) {
1376: UserCtrlC = 0;
1377: id = getpid();
1378: kill(id,SIGINT);
1379: return(c);
1380: }else{
1381: return(c);
1382: }
1383: }
1384:
1385: void *sGC_realloc(void *p,size_t new) { /* synchronized function */
1386: void *c;
1387: int id;
1388: extern int SGClock, UserCtrlC;
1389:
1390: SGClock = 1;
1391: c = GC_realloc(p,new);
1392: SGClock = 0;
1393: if (UserCtrlC) {
1394: UserCtrlC = 0;
1395: id = getpid();
1396: kill(id,SIGINT);
1397: return(c);
1398: }else{
1399: return(c);
1400: }
1401: }
1402:
1403: void sGC_free(void *c) { /* synchronized function */
1404: int id;
1405: extern int SGClock, UserCtrlC;
1406:
1407: SGClock = 1;
1408: GC_free(c);
1409: SGClock = 0;
1410: if (UserCtrlC) {
1411: UserCtrlC = 0;
1412: id = getpid();
1413: kill(id,SIGINT);
1414: return;
1415: }else{
1416: return;
1417: }
1418: }
1419:
1420: void lockCtrlCForOx() {
1421: extern int OXlock;
1422: extern int OXlockSaved;
1423: OXlockSaved = OXlock;
1424: OXlock = 1;
1425: }
1426:
1427: void unlockCtrlCForOx() {
1428: int id;
1429: extern int OXlock, UserCtrlC;
1430: extern int OXlockSaved;
1431: OXlockSaved = OXlock;
1432: OXlock = 0;
1433: if (UserCtrlC) {
1434: UserCtrlC = 0;
1435: id = getpid();
1436: kill(id,SIGINT);
1437: return;
1438: }else{
1439: return;
1440: }
1441: }
1442:
1443: void restoreLockCtrlCForOx() {
1444: extern int OXlock;
1445: extern int OXlockSaved;
1446: OXlock = OXlockSaved;
1447: }
1448:
1449: int KSstackPointer() {
1450: return(Osp);
1451: }
1452:
1453: struct object KSdupErrors() {
1454: struct object rob;
1455: struct object ob;
1456: int i;
1457: int n;
1458: int m;
1459:
1460: n = KSstackPointer();
1461: m = 0;
1462: for (i=0; i<n; i++) {
1463: ob = peek(i);
1464: if (ob.tag == Sclass && ectag(ob) == CLASSNAME_ERROR_PACKET) {
1465: m++;
1466: }
1467: }
1468: rob = newObjectArray(m);
1469: m = 0;
1470: for (i=0; i<n; i++) {
1471: ob = peek(i);
1472: if (ob.tag == Sclass && ectag(ob) == CLASSNAME_ERROR_PACKET) {
1473: putoa(rob, m, ob);
1474: m++;
1475: }
1476: }
1477: return(rob);
1478: }
1.10 ! takayama 1479:
! 1480: void cancelAlarm() {
! 1481: alarm((unsigned int) 0);
! 1482: signal(SIGALRM,SIG_DFL);
! 1483: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>