Annotation of OpenXM/src/kan96xx/Kan/stackmachine.c, Revision 1.9
1.9 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/Kan/stackmachine.c,v 1.8 2001/12/19 23:39:53 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.7 takayama 819: continue ;
1.1 maekawa 820: } else { }
821: if (DebugStack >= 1) { printOperandStack(); }
822: token = getokenSM(GET);
823: if ((tmp=executeToken(token)) < 0) break;
824: /***if (tmp == 1) fprintf(stderr," --- exit --- \n");*/
825: }
826: }
827:
828:
829: void ctrlC(sig)
1.7 takayama 830: int sig;
1.1 maekawa 831: {
832: extern void ctrlC();
833: extern int ErrorMessageMode;
834: extern int SGClock;
835: extern int UserCtrlC;
836: extern int OXlock;
837:
838: signal(sig,SIG_IGN);
839: /* see 133p */
840:
841: if (SGClock) {
842: UserCtrlC = 1;
843: fprintf(stderr,"ctrl-c is locked because of gc.\n");
844: signal(SIGINT,ctrlC);
845: return;
846: }
847: if (OXlock) {
848: if (UserCtrlC > 0) UserCtrlC++;
849: else UserCtrlC = 1;
850: if (UserCtrlC > 3) {
851: fprintf(stderr,"OK. You are eager to cancel the computation.\n");
852: fprintf(stderr,"You should close the ox communication cannel.\n");
853: signal(SIGINT,ctrlC);
854: unlockCtrlCForOx();
855: }
856: fprintf(stderr,"ctrl-c is locked because of ox lock %d.\n",UserCtrlC);
857: signal(SIGINT,ctrlC);
858: return;
859: }
860: if (ErrorMessageMode != 1) {
861: fprintf(Fstack,"User interruption by ctrl-C. We are in the top-level.\n");
862: fprintf(Fstack,"Type in quit in order to exit sm1.\n");
863: }
864: if (GotoP) {
865: fprintf(Fstack,"The interpreter was looking for the label <<%s>>. It is also aborted.\n",GotoLabel);
866: GotoP = 0;
867: }
868: stdOperandStack(); contextControl(CCRESTORE);
869: /*fprintf(Fstack,"Warning! The handler of ctrl-C has a bug, so you might have a core-dump.\n");*/
870: /*
871: $(x0+1)^50$ $x1 x0 + x1^20$ 2 groebner_n
872: ctrl-C
873: $(x0+1)^50$ $x1 x0 + x1^20$ 2 groebner_n
874: It SOMETIMES makes core dump.
875: */
876: getokenSM(INIT); /* It might fix the bug above. 1992/11/14 */
877: signal(SIGINT,ctrlC);
1.9 ! takayama 878: #if defined(__CYGWIN__)
! 879: siglongjmp(EnvOfStackMachine,2);
! 880: #else
1.1 maekawa 881: longjmp(EnvOfStackMachine,2); /* returns 2 for ctrl-C */
1.9 ! takayama 882: #endif
1.1 maekawa 883: }
884:
885: int executeToken(token)
1.7 takayama 886: struct tokens token;
1.1 maekawa 887: {
888: struct object ob;
889: int primitive;
890: int size;
891: int status;
892: struct tokens *tokenArray;
893: int i,h0,h1;
894: extern int WarningMessageMode;
895: extern int Strict;
896:
897: if (GotoP) { /* for goto */
898: if (token.kind == ID && isLiteral(token.token)) {
899: if (strcmp(&((token.token)[1]),GotoLabel) == 0) {
1.7 takayama 900: GotoP = 0;
901: return(0); /* normal exit */
1.1 maekawa 902: }
903: }
904: return(0); /* normal exit */
905: }
906: if (token.kind == DOLLAR) {
907: ob.tag = Sdollar;
908: ob.lc.str = token.token;
909: Kpush(ob);
910: } else if (token.kind == ID) { /* ID */
911:
912: if (strcmp(token.token,"exit") == 0) return(1);
913: /* "exit" is not primitive here. */
914:
915: if (isLiteral(token.token)) {
916: /* literal object */
917: ob.tag = Sstring;
918: ob.lc.str = (char *)sGC_malloc((strlen(token.token)+1)*sizeof(char));
919: if (ob.lc.str == (char *)NULL) errorStackmachine("No space.");
920: strcpy(ob.lc.str, &((token.token)[1]));
921:
922: if (token.object.tag != Slist) {
1.7 takayama 923: fprintf(Fstack,"\n%%Warning: The hashing values for the <<%s>> are not set.\n",token.token);
924: token.object = lookupLiteralString(token.token);
1.1 maekawa 925: }
926: ob.rc.op = token.object.lc.op;
927: Kpush(ob);
928: } else if (isInteger(token.token)) {
929: /* integer object */
930: ob.tag = Sinteger ;
931: ob.lc.ival = strToInteger(token.token);
932: Kpush(ob);
933: } else {
934: if (token.object.tag != Slist) {
1.7 takayama 935: fprintf(Fstack,"\n%%Warning: The hashing values for the <<%s>> are not set.\n",token.token);
936: token = lookupTokens(token);
1.1 maekawa 937: }
938: h0 = ((token.object.lc.op)->lc).ival;
939: h1 = ((token.object.lc.op)->rc).ival;
940: ob=findUserDictionary(token.token,h0,h1,CurrentContextp);
941: primitive = ((token.object.rc.op)->lc).ival;
942: if (ob.tag >= 0) {
1.7 takayama 943: /* there is a definition in the user dictionary */
944: if (ob.tag == SexecutableArray) {
945: tokenArray = ob.lc.tokenArray;
946: size = ob.rc.ival;
947: for (i=0; i<size; i++) {
948: status = executeToken(tokenArray[i]);
949: if (status != 0) return(status);
950: }
951: }else {
952: Kpush(ob);
953: }
1.1 maekawa 954: } else if (primitive) {
1.7 takayama 955: /* system operator */
956: ob.tag = Soperator;
957: ob.lc.ival = primitive;
958: return(executePrimitive(ob));
1.1 maekawa 959: } else {
1.7 takayama 960: if (WarningMessageMode == 1 || WarningMessageMode == 2) {
961: char tmpc[1024];
962: if (strlen(token.token) < 900) {
963: sprintf(tmpc,"\n%%Warning: The identifier <<%s>> is not in the system dictionary\n%% nor in the user dictionaries. Push NullObject.\n",token.token);
964: }else {strcpy(tmpc,"Warning: identifier is not in the dictionaries.");}
965: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,tmpc));
966: }
967: if (WarningMessageMode != 1) {
968: fprintf(Fstack,"\n%%Warning: The identifier <<%s>> is not in the system dictionary\n%% nor in the user dictionaries. Push NullObject.\n",token.token);
969: /*fprintf(Fstack,"(%d,%d)\n",h0,h1);*/
970: }
971: if (Strict) {
972: errorStackmachine("Warning: identifier is not in the dictionaries");
973: }
974: Kpush(NullObject);
1.1 maekawa 975: }
976: }
977: } else if (token.kind == EXECUTABLE_STRING) {
978: Kpush(executableStringToExecutableArray(token.token));
979: } else if (token.kind == EXECUTABLE_ARRAY) {
980: Kpush(token.object);
981: } else if ((token.kind == -1) || (token.kind == -2)) { /* eof token */
982: return(-1);
983: } else {
984: /*fprintf(Fstack,"\n%%Error: Unknown token type\n");***/
985: fprintf(stderr,"\nUnknown token type = %d\n",token.kind);
986: fprintf(stderr,"\ntype in ctrl-\\ if you like to make core-dump.\n");
987: fprintf(stderr,"If you like to continue, type in RETURN key.\n");
988: fprintf(stderr,"Note that you cannot input null string.\n");
989: getchar();
990: errorStackmachine("Error: Unknown token type.\n");
991: /* return(-2); /* exit */
992: }
993: return(0); /* normal exit */
994: }
995:
996:
997:
998:
999: errorStackmachine(str)
1.7 takayama 1000: char *str;
1.1 maekawa 1001: {
1002: int i,j,k;
1003: static char *u="Usage:";
1004: char message0[1024];
1005: char *message;
1006: extern int ErrorMessageMode;
1007: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
1008: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,str));
1009: }
1010: if (ErrorMessageMode != 1) {
1011: message = message0;
1012: i = 0;
1013: while (i<6 && str[i]!='0') {
1014: if (str[i] != u[i]) break;
1015: i++;
1016: }
1017: if (i==6) {
1018: fprintf(stderr,"ERROR(sm): \n");
1019: while (str[i] != '\0' && str[i] != ' ') {
1.7 takayama 1020: i++;
1.1 maekawa 1021: }
1022: if (str[i] == ' ') {
1.7 takayama 1023: fprintf(stderr," %s\n",&(str[i+1]));
1024: k = 0;
1025: if (i-6 > 1022) message = (char *)sGC_malloc(sizeof(char)*i);
1026: for (j=6; j<i ; j++) {
1027: message[k] = str[j];
1028: message[k+1] = '\0';
1029: k++;
1030: }
1031: Kusage2(stderr,message);
1.1 maekawa 1032: }else{
1.7 takayama 1033: Kusage2(stderr,&(str[6]));
1.1 maekawa 1034: }
1035: }else {
1036: fprintf(stderr,"ERROR(sm): ");
1037: fprintf(stderr,str);
1038: }
1039: fprintf(stderr,"\n");
1040: }
1041: if (GotoP) {
1042: fprintf(Fstack,"The interpreter was looking for the label <<%s>>. It is also aborted.\n",GotoLabel);
1043: GotoP = 0;
1044: }
1045: stdOperandStack(); contextControl(CCRESTORE);
1046: getokenSM(INIT); /* It might fix the bug. 1996/3/10 */
1047: /* fprintf(stderr,"Now, Long jump!\n"); */
1048: longjmp(EnvOfStackMachine,1);
1049: }
1050:
1051: warningStackmachine(str)
1.7 takayama 1052: char *str;
1.1 maekawa 1053: {
1054: extern int WarningMessageMode;
1055: extern int Strict;
1056: if (WarningMessageMode == 1 || WarningMessageMode == 2) {
1057: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,str));
1058: }
1059: if (WarningMessageMode != 1) {
1060: fprintf(stderr,"WARNING(sm): ");
1061: fprintf(stderr,str);
1062: }
1063: if (Strict) errorStackmachine(" ");
1064: return(0);
1065: }
1066:
1067:
1068: /* exports */
1069: /* NOTE: If you call this function and an error occured,
1070: you have to reset the jump buffer by setjmp(EnvOfStackMachine).
1071: cf. kxx/memo1.txt, kxx/stdserver00.c 1998, 2/6 */
1072: KSexecuteString(s)
1.7 takayama 1073: char *s;
1.1 maekawa 1074: {
1075: struct tokens token;
1076: struct object ob;
1077: int tmp;
1078: extern int CatchCtrlC;
1079: int jval;
1080: static int recursive = 0;
1081: extern int ErrorMessageMode;
1082: extern int KSPushEnvMode;
1083: jmp_buf saved_EnvOfStackMachine;
1084: void (*sigfunc)();
1085: int localCatchCtrlC ;
1086:
1087: localCatchCtrlC = CatchCtrlC;
1088: /* If CatchCtrlC is rewrited in this program,
1089: we crash. So, we use localCatchCtrlC. */
1090:
1091: if (localCatchCtrlC) {
1092: sigfunc = signal(SIGINT,SIG_IGN);
1093: signal(SIGINT,ctrlC);
1094: }
1095:
1096: if (KSPushEnvMode) {
1097: *saved_EnvOfStackMachine = *EnvOfStackMachine;
1.9 ! takayama 1098: #if defined(__CYGWIN__)
! 1099: if (jval = sigsetjmp(EnvOfStackMachine,1)) {
! 1100: #else
1.1 maekawa 1101: if (jval = setjmp(EnvOfStackMachine)) {
1.9 ! takayama 1102: #endif
1.1 maekawa 1103: *EnvOfStackMachine = *saved_EnvOfStackMachine;
1104: if (jval == 2) {
1.7 takayama 1105: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
1106: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
1107: }
1.1 maekawa 1108: }
1109: recursive--;
1110: if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1111: return(-1);
1112: }else{ }
1113: }else{
1114: if (recursive == 0) {
1.9 ! takayama 1115: #if defined(__CYGWIN__)
! 1116: if (jval=sigsetjmp(EnvOfStackMachine,1)) {
! 1117: #else
1.1 maekawa 1118: if (jval=setjmp(EnvOfStackMachine)) {
1.9 ! takayama 1119: #endif
1.7 takayama 1120: if (jval == 2) {
1121: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
1122: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
1123: }
1124: }
1125: recursive = 0;
1126: if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1127: return(-1);
1.1 maekawa 1128: }else { }
1129: }
1130: }
1131:
1132: recursive++;
1133: token.token = s;
1134: token.kind = EXECUTABLE_STRING;
1135: executeToken(token);
1136: token.kind = ID;
1137: token.token = "exec";
1138: token = lookupTokens(token); /* no use */
1139: tmp = findSystemDictionary(token.token);
1140: ob.tag = Soperator;
1141: ob.lc.ival = tmp;
1142: executePrimitive(ob);
1143: recursive--;
1144: if (KSPushEnvMode) *EnvOfStackMachine = *saved_EnvOfStackMachine;
1145: if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1146: return(0);
1147: }
1148:
1149: KSdefineMacros() {
1150: struct tokens token;
1151: int tmp;
1152: struct object ob;
1153:
1154: if (StandardMacros && (strlen(SMacros))) {
1155: token.kind = EXECUTABLE_STRING;
1156: token.token = SMacros;
1.7 takayama 1157: executeToken(token); /* execute startup commands */
1.1 maekawa 1158: token.kind = ID;
1159: token.token = "exec";
1160: token = lookupTokens(token); /* no use */
1161: tmp = findSystemDictionary(token.token);
1162: ob.tag = Soperator;
1163: ob.lc.ival = tmp;
1.7 takayama 1164: executePrimitive(ob); /* exec */
1.1 maekawa 1165: }
1166: return(0);
1167:
1168: }
1169:
1170: void KSstart() {
1171: struct tokens token;
1172: int tmp;
1173: struct object ob;
1174: extern int Quiet;
1175:
1176: stackmachine_init(); KinitKan();
1177: getokenSM(INIT); initSystemDictionary();
1178:
1179: /* The following line may cause a core dump, if you do not setjmp properly
1180: after calling KSstart().*/
1181: /*
1.7 takayama 1182: if (setjmp(EnvOfStackMachine)) {
1.1 maekawa 1183: fprintf(stderr,"KSstart(): An error or interrupt in reading macros, files and command strings.\n");
1184: exit(10);
1.7 takayama 1185: } else { } */
1.1 maekawa 1186:
1187: /* setup quiet mode or not */
1188: token.kind = EXECUTABLE_STRING;
1189: if (Quiet) {
1190: token.token = " /@@@.quiet 1 def ";
1191: }else {
1192: token.token = " /@@@.quiet 0 def ";
1193: }
1194: executeToken(token); /* execute startup commands */
1195: token.kind = ID;
1196: token.token = "exec";
1197: token = lookupTokens(token); /* set hashing values */
1198: tmp = findSystemDictionary(token.token);
1199: ob.tag = Soperator;
1200: ob.lc.ival = tmp;
1201: executePrimitive(ob); /* exec */
1202:
1203: KSdefineMacros();
1204: }
1205:
1206: void KSstop() {
1207: Kclose(); stackmachine_close();
1208: }
1209:
1210:
1211: struct object KSpop() {
1212: return(Kpop());
1213: }
1214:
1215: void KSpush(ob)
1.7 takayama 1216: struct object ob;
1.1 maekawa 1217: {
1218: Kpush(ob);
1.4 takayama 1219: }
1220:
1221: struct object KSpeek(k) {
1222: return(peek(k));
1.1 maekawa 1223: }
1224:
1225: char *KSstringPop() {
1226: /* pop a string */
1227: struct object rob;
1228: rob = Kpop();
1229: if (rob.tag == Sdollar) {
1230: return(rob.lc.str);
1231: }else{
1232: return((char *)NULL);
1233: }
1234: }
1235:
1236: char *KSpopString() {
1237: return(KSstringPop());
1238: }
1239:
1240: int KSset(char *name) {
1241: char *tmp2;
1242: char tmp[1024];
1243: tmp2 = tmp;
1244: if (strlen(name) < 1000) {
1245: sprintf(tmp2," /%s set ",name);
1246: }else{
1247: tmp2 = sGC_malloc(sizeof(char)*(strlen(name)+20));
1248: if (tmp2 == (char *)NULL) errorStackmachine("Out of memory.");
1249: sprintf(tmp2," /%s set ",name);
1250: }
1251: return( KSexecuteString(tmp2) );
1252: }
1253:
1254: int KSpushBinary(int size,char *data) {
1255: /* struct object KbinaryToObject(int size, char *data); */
1256: errorStackmachine("KSpushBinary is not implemented.\n");
1257: return(-1);
1258: }
1259:
1260: char *KSpopBinary(int *size) {
1261: /* char *KobjectToBinary(struct object ob,int *size); */
1262: errorStackmachine("KSpopBinary is not implemented.\n");
1263: *size = 0;
1264: return((char *)NULL);
1265: }
1266:
1267: int pushErrorStack(struct object obj)
1268: {
1269: if (CurrentOperandStack == &ErrorStack) {
1270: fprintf(stderr,"You cannot call pushErrorStack when ErrorStack is the CurrentOperandStack. \n");
1271: return(-1);
1272: }
1273: (ErrorStack.ostack)[(ErrorStack.sp)++] = obj;
1274: /* printf("ErrorStack.sp = %d\n",ErrorStack.sp); */
1275: if ((ErrorStack.sp) >= (ErrorStack.size)) {
1276: ErrorStack.sp = 0;
1277: fprintf(stderr,"pushErrorStack():ErrorStack overflow. It is reset.\n");
1278: /* Note that it avoids recursive call.*/
1279: return(-1);
1280: }
1281: return(0);
1282: }
1283:
1284: struct object popErrorStack(void) {
1285: if (CurrentOperandStack == &ErrorStack) {
1286: fprintf(stderr,"You cannot call popErrorStack when ErrorStack is the CurrentOperandStack. \n");
1287: return(NullObject);
1288: }
1289: if ((ErrorStack.sp) <= 0) {
1290: return( NullObject );
1291: }else{
1292: return( (ErrorStack.ostack)[--(ErrorStack.sp)]);
1293: }
1294: }
1295:
1296: char *popErrorStackByString(void) {
1297: struct object obj;
1298: struct object eobj;
1299: eobj = popErrorStack();
1300: if (ectag(eobj) != CLASSNAME_ERROR_PACKET) {
1301: return(NULL);
1302: }else{
1303: obj = *(KopErrorPacket(eobj));
1304: }
1305: if (obj.tag != Sarray || getoaSize(obj) != 3) {
1306: fprintf(stderr,"errorPacket format error.\n");
1307: printObject(eobj,0,stderr); fflush(stderr);
1308: return("class errorPacket format error. Bug of sm1.");
1309: }
1310: obj = getoa(obj,2);
1311: if (obj.tag != Sdollar) {
1312: fprintf(stderr,"errorPacket format error at position 2..\n");
1313: printObject(eobj,0,stderr); fflush(stderr);
1314: return("class errorPacket format error at the position 2. Bug of sm1.");
1315: }
1316: return(KopString(obj));
1317: }
1318:
1319:
1320: int KScheckErrorStack(void)
1321: {
1322: return(ErrorStack.sp);
1323: }
1324:
1325: struct object KnewErrorPacket(int serial,int no,char *message)
1326: {
1327: struct object obj;
1328: struct object *myop;
1329: char *s;
1330: /* Set extended tag. */
1331: obj.tag = Sclass; obj.lc.ival = CLASSNAME_ERROR_PACKET ;
1332: myop = (struct object *)sGC_malloc(sizeof(struct object));
1333: if (myop == (struct object *)NULL) errorStackmachine("No memory\n");
1334: *myop = newObjectArray(3);
1335: /*fprintf(stderr,"newErrorPacket() in stackmachine.c: [%d, %d, %s] \n",serial,no,message); **kxx:CMO_ERROR */
1336: putoa((*myop),0,KpoInteger(serial));
1337: putoa((*myop),1,KpoInteger(no));
1338: s = (char *)sGC_malloc(sizeof(char)*(strlen(message)+2));
1339: if (s == (char *)NULL) errorStackmachine("No memory\n");
1340: strcpy(s,message);
1341: putoa((*myop),2,KpoString(s));
1342: obj.rc.op = myop;
1343: return(obj);
1344: }
1345:
1346:
1347: struct object KnewErrorPacketObj(struct object ob1)
1348: {
1349: struct object obj;
1350: struct object *myop;
1351: char *s;
1352: /* Set extended tag. */
1353: obj.tag = Sclass; obj.lc.ival = CLASSNAME_ERROR_PACKET ;
1354: myop = (struct object *)sGC_malloc(sizeof(struct object));
1355: if (myop == (struct object *)NULL) errorStackmachine("No memory\n");
1356: *myop = ob1;
1357: obj.rc.op = myop;
1358: return(obj);
1359: }
1360:
1361: void *sGC_malloc(size_t n) { /* synchronized function */
1362: void *c;
1363: int id;
1364: extern int SGClock, UserCtrlC;
1365:
1366: SGClock = 1;
1367: c = GC_malloc(n);
1368: SGClock = 0;
1369: if (UserCtrlC) {
1370: UserCtrlC = 0;
1371: id = getpid();
1372: kill(id,SIGINT);
1373: return(c);
1374: }else{
1375: return(c);
1376: }
1377: }
1378:
1379: void *sGC_realloc(void *p,size_t new) { /* synchronized function */
1380: void *c;
1381: int id;
1382: extern int SGClock, UserCtrlC;
1383:
1384: SGClock = 1;
1385: c = GC_realloc(p,new);
1386: SGClock = 0;
1387: if (UserCtrlC) {
1388: UserCtrlC = 0;
1389: id = getpid();
1390: kill(id,SIGINT);
1391: return(c);
1392: }else{
1393: return(c);
1394: }
1395: }
1396:
1397: void sGC_free(void *c) { /* synchronized function */
1398: int id;
1399: extern int SGClock, UserCtrlC;
1400:
1401: SGClock = 1;
1402: GC_free(c);
1403: SGClock = 0;
1404: if (UserCtrlC) {
1405: UserCtrlC = 0;
1406: id = getpid();
1407: kill(id,SIGINT);
1408: return;
1409: }else{
1410: return;
1411: }
1412: }
1413:
1414: void lockCtrlCForOx() {
1415: extern int OXlock;
1416: extern int OXlockSaved;
1417: OXlockSaved = OXlock;
1418: OXlock = 1;
1419: }
1420:
1421: void unlockCtrlCForOx() {
1422: int id;
1423: extern int OXlock, UserCtrlC;
1424: extern int OXlockSaved;
1425: OXlockSaved = OXlock;
1426: OXlock = 0;
1427: if (UserCtrlC) {
1428: UserCtrlC = 0;
1429: id = getpid();
1430: kill(id,SIGINT);
1431: return;
1432: }else{
1433: return;
1434: }
1435: }
1436:
1437: void restoreLockCtrlCForOx() {
1438: extern int OXlock;
1439: extern int OXlockSaved;
1440: OXlock = OXlockSaved;
1441: }
1442:
1443: int KSstackPointer() {
1444: return(Osp);
1445: }
1446:
1447: struct object KSdupErrors() {
1448: struct object rob;
1449: struct object ob;
1450: int i;
1451: int n;
1452: int m;
1453:
1454: n = KSstackPointer();
1455: m = 0;
1456: for (i=0; i<n; i++) {
1457: ob = peek(i);
1458: if (ob.tag == Sclass && ectag(ob) == CLASSNAME_ERROR_PACKET) {
1459: m++;
1460: }
1461: }
1462: rob = newObjectArray(m);
1463: m = 0;
1464: for (i=0; i<n; i++) {
1465: ob = peek(i);
1466: if (ob.tag == Sclass && ectag(ob) == CLASSNAME_ERROR_PACKET) {
1467: putoa(rob, m, ob);
1468: m++;
1469: }
1470: }
1471: return(rob);
1472: }
1473:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>