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