3 * (C) Copyright Dec 31 1995, Edmond J. Breen.
5 * This code may be copied for personal, non-profit use only.
9 /* In accordance with the practice of fair use, I hereby acknowledge
12 static char *PlaugerStr_=
13 "Portions of this work are derived from the Standard C library, (C), 1992 by P.J. Plauger, published by Prentice-Hall and are used with permission.";
16 /* Modified by Intel OpenCV team. The runEiC function has been changed
17 in order to catch exceptions thrown by parser and interpreter. */
42 #define signal sysv_signal
43 void (*sysv_signal(int sig, void (*func)(int a))) (int a);
47 extern void EiC_interpret(environ_t * env);
48 extern char *EiC_prolineString(char *str);
51 #define HERE printf("%s %d\n",__FILE__,__LINE__)
54 "*************************************************************************\n"
55 "EiC V4.3.1 - Copyright (c) 1995 to 2000,"
56 " by Edmond J. Breen\n"
57 "EiC comes `as is' and with ABSOLUTELY NO WARRANTY OF MERCHANTIBILITY AND\n"
58 " FITNESS OF PURPOSE\n"
59 "*************************************************************************\n"
65 size_t EiC_ENV_NextEntryNum()
67 return EiC_stab_NextEntryNum(&EiC_ENV->stab);
70 void EiC_ENV_CleanUp(size_t bot)
72 EiC_stab_CleanUp(&EiC_ENV->stab,bot);
75 /*END STRING TABLE ROUTINES*/
78 void EiC_reset_env_pointers(token_t * e1, int bp)
84 void EiC_markENV(char mark)
86 EiC_stab_Mark(&EiC_ENV->stab,mark);
89 void free_env_code(void)
94 code_t *c = &EiC_ENV->CODE;
96 while(c->prev) /* find start point */
100 /* rem free up other info also */
101 for (i = 0; i < c->nextinst; i++, inst++)
102 if (inst->opcode == jmptab) {
107 } else if (inst->opcode == assigntype) {
108 EiC_freetype(inst->val.p.p);
110 } else if(inst->opcode == halt) {
111 EiC_freetype(inst->val.p.p);
118 void EiC_SaveGlobalString(ptr_t *s)
120 int len = (char*)s->ep - (char*)s->sp;
121 s->sp = s->p = EiC_stab_SaveString(&EiC_ENV->stab,s->p);
122 s->ep = (char*)s->p + len;
125 /* signal handling routines
127 * If a new signal hangling rountines gets added
128 * make sure it gets also added in module/stdClib/src/signal.c
133 static int jmpOn = 0;
137 char * EiC_CurrentFile =NULL;
138 unsigned int EiC_CurrentLine = -1;
140 #define errStr(x) if(EiC_CurrentFile) EiC_error("\n" x ", file %s, line %d\n",EiC_CurrentFile,EiC_CurrentLine)
141 #define eic_disaster() EiC_error("exit EiC\n");exit(1)
145 size_t fopen_NextEntryNum(void);
146 void _ffexit(size_t);
148 void EiC_exit_call(int i)
151 size_t fopen_entry = fopen_NextEntryNum();
152 #if defined(WIN32) || defined(_DJGPP)
153 signal(SIGTERM, EiC_exit_call);
155 signal(SIGUSR1, EiC_exit_call);
157 _ffexit(fopen_entry);
158 if(jmpOn && jmpOn++ <= 1)
167 void EiC_bus_err(int i)
170 #if defined(WIN32) || defined(_DJGPP)
171 signal(SIGABRT,EiC_bus_err);
173 signal(SIGBUS, EiC_bus_err);
175 errStr("EiC bus error trapped");
176 if(jmpOn && jmpOn++ <= 1)
181 void EiC_ill_oper(int i)
183 signal(SIGILL, EiC_ill_oper);
184 errStr("EiC illegal operation attempted\n");
185 if(jmpOn && jmpOn++ <= 1)
190 void EiC_stor_access(int i)
192 signal(SIGSEGV, EiC_stor_access);
193 errStr("EiC illegal storage access");
194 if(jmpOn && jmpOn++ <= 1) {
200 void EiC_float_err(int i)
202 signal(SIGFPE, EiC_float_err);
203 errStr("EiC maths exception");
204 if(jmpOn && jmpOn++ <= 1)
210 void EiC_term_int(int i)
212 signal(SIGINT, EiC_term_int);
213 errStr("EiC interrupted");
214 if(jmpOn && jmpOn++ <= 1)
220 FILE *EiChist = NULL;
221 extern int EiC_verboseON, EiC_SHOWLINE, EiC_traceON, EiC_TIMER,
222 EiC_interActive, EiC_showIncludes;
223 int silent = 0, HistoryFile = 1;
225 int reStart = 0, prompt = 0;
226 int EiC_Interact = 1;
228 static int FREE_G_STRING = 1;
234 " An Extensible Interactive C interpreter\n"
235 " To start eic, type eic.\n"
236 " To exit eic, type :exit.\n"
238 "\teic [-Ipath] [-Dname[=var]] -[hHvVcCrR] [[file] [fileargs]]\n"
240 " C preprocessor directives:\n"
241 "\t-Ipath search for include files in path\n"
242 "\t-Dname define a symbolic name to the value 1\n"
243 "\t-Dname=var define a symbolic name to the value var\n"
244 "\t Note, there is no spaces allowed\n"
246 "\t-h -H causes this usage to be displayed\n"
247 "\t-v -V print EiC's Log information\n"
249 "\t-P show path of include files\n"
250 "\t-t -T turns trace on\n"
251 "\t-c -C turns timer on\n"
252 "\t-e echo HTML mode\n"
253 "\t-r restart EiC. Causes EiC to be re initiated\n"
254 "\t from the contents of EiChist.lst file\n"
255 "\t-R same as `r', but prompts the user to accept\n"
256 "\t or reject each input line first\n"
257 "\t-s -S run silently\n"
258 "\t-f run in script mode\n"
259 "\t-n no history file\n"
260 "\t-N don't use any startup.h files\n"
261 "\t-A Non-interactive-mode\n"
262 "\tfile EiC will execute `file' and then stop; for example:\n"
264 "\tfileargs command line arguments, which get passed onto file\n"
269 int do_sw_commands(char *cp)
273 case 'D': dodefine(cp); return 1;
274 case 'I': EiC_insertpath(cp); return 1;
279 case 'C': EiC_TIMER = 1; break;
282 /* connect stderr to stdout */
284 /* setup stdout to behave like stderr */
285 if(setvbuf(stdout,NULL,_IONBF,0) != 0)
286 EiC_error("failed to setup stdout\n");
287 /* inform the browser */
288 puts("Content-type: text/plain\n\n");
292 case 'V': puts(Version); exit(1);
294 case 'R': prompt = 1;
295 case 'r': reStart = 1; break;
298 case 'S': silent = 1; break;
300 case 'f': ScriptMode = 1; break;
301 case 'p': EiC_SHOWLINE = 1; break;
302 case 'P': EiC_showIncludes = 1; break;
304 case 'T': EiC_traceON = 1; break;
305 case 'n': HistoryFile = 0; break;
306 case 'N': StartUpH = 0; break;
307 case 'A': EiC_Interact = 0; break;
309 while(isspace(*cp)) cp++;
310 if(*cp == '-') /* assume script mode */
311 while(isspace(*++cp));
312 else if(*cp) /* catch for lines ending with whitespace */
321 void EiC_save_history(FILE *fp, int from);
323 extern int EiC_verboseON;
325 int EiC_Include_file(char *, int);
326 void EiC_marksyms(char);
329 extern char *EiC_nextproline();
330 extern int EiC_listcodeON, EiC_interpON,EiC_memdumpON;
331 extern unsigned long EiC_tot_memory;
332 extern size_t EiC_tot_alloc;
337 printf("\ninstr = %d sARsize = %d lsp = %d aARsize = %d\n"
338 "EiC_tot_alloc = %lu EiC_tot_memory = %lu\n",
339 EiC_ENV->CODE.nextinst,
343 (unsigned long)EiC_tot_alloc,
345 EiC_listcode(&EiC_ENV->CODE);
350 void EiC_remTempories(void);
351 void EiC_peephole(code_t *c);
352 int EiC_getHistLineNo(), hfrom = 0;
354 /* Hawk start change */
358 /* Hawk start change */
363 switch(setjmp(env)) {
367 EiCp_initiateReset();
370 hfrom = EiC_getHistLineNo();
372 inbuf = EiC_nextproline();
377 EiC_peephole(&getenvcode(EiC_ENV));
381 if (EiC_ENV->CODE.nextinst && EiC_interpON && !EiC_ParseError)
382 EiC_interpret(EiC_ENV);
386 EiC_messageDisplay("EiC reports an unRecognised jmp condition in starteic.c");
391 EiC_messageDisplay("Exit called: force clean up!\n");
397 /* Hawk start change */
404 EiC_clear_err_msgs();
407 EiC_xfreemark(eicgstring);
413 if(EiC_ENV->lsp != 0) {
414 EiC_messageDisplay("EiC::Reset Local Stack Pointer\n");
419 xmark(EiC_ENV->ARgar.val,eicstay);
424 /* Hawk start change */
431 EiC_save_history(EiChist,hfrom);
436 EiC_marksyms(NON_LEAK);
438 printf("--- XMEM DUMP\n");
439 xdumpnonmark("eicxdump", NON_LEAK);
445 #define FORMAT1 "\n#ifdef _STDLIBH\nexit(main());\n"\
446 "#else\nmain();\n#endif\n"
448 #define FORMAT2 "\n"\
450 "exit(main(_Argc,_Argv));\n"\
452 "main(_Argc,_Argv);\n"\
456 #define FORMAT3 "\n"\
458 "exit(main(_Argc,_Argv,_Envp));\n"\
460 "main(_Argc,_Argv,_Envp);\n"\
468 sym = EiC_lookup(stand_tab,"main");
472 EiC_messageDisplay("Error: Missing `main'\n");
476 if(EiC_gettype(sym->type) != t_func) {
477 EiC_messageDisplay("Error: `main' NOT DECLARED as a function\n");
480 /* check return type of main */
481 if(EiC_gettype(nextType(sym->type)) != t_int) {
482 EiC_messageDisplay("Error: function `main' MUST return an `int' type\n");
486 /* get number of arguments */
487 F = EiC_getInf(sym->type);
488 if(getFNp(F) <= 1) /* allow for void argument */
489 EiC_prolineString(FORMAT1);
490 else if(getFNp(F) <= 2)
491 EiC_prolineString(FORMAT2);
493 EiC_messageDisplay("Error: too many arguments being "
494 "passed to `main'\n");
495 /*EiC_prolineString(FORMAT3);*/
500 char * doargs(int argc, char **argv)
506 sprintf(buf,"int _Argc = %d;char *_Argv[] = {",argc);
508 /* get size of string needed */
511 sz += strlen(argv[i]) + 3; /* 3 comma + quotes */
512 /* needs to be NULL terminated */
513 sz += strlen("(void*)0};") + 2; /* 2 for NULL */
519 for(i=0;i<argc;++i) {
524 strcat(p,"(void*)0};");
529 void EiC_parseString(char * fmt,...)
534 int h = EiC_interActive;
535 int gs = FREE_G_STRING;
545 len = 2 * strlen(fmt);
546 str = malloc(len > 256 ? len : 256);
547 vsprintf(str,fmt,args);
549 EiC_interActive = 0; /* turn off interactive mode */
550 EiC_prolineString(str);
553 code = EiC_ENV->CODE;
554 EiC_ENV->CODE.nextinst = EiC_ENV->CODE.binst = 0;
555 EiC_ENV->CODE.inst = NULL;
556 EiC_ENV->CODE.prev = &code;
557 /* sp = EiC_ENV->sp;*/
561 /* rem: runEiC will call free_env_code */
562 EiC_ENV->CODE = code;
570 void EiC_callBack(void *c)
573 int gs = FREE_G_STRING;
580 code = EiC_ENV->CODE;
581 EiC_ENV->CODE = *(code_t*)c;
582 EiC_ENV->CODE.prev = &code; /* link */
584 EiC_interpret(EiC_ENV);
586 EiC_ENV->CODE.prev = NULL; /* unlink */
587 EiC_ENV->CODE = code;
592 void EiC_switches(char *switches)
595 char *p,*c = malloc(strlen(switches)+2);
597 p = strtok(c," \t\n");
601 p = strtok(NULL," \t\n");
607 int EiC_run(int argc, char **argv)
609 char * n2 = doargs(argc,argv);
610 int h = EiC_interActive;
613 EiC_interActive = 0; /* turn off interactive mode */
615 code = EiC_ENV->CODE;
616 EiC_ENV->CODE.nextinst = EiC_ENV->CODE.binst = 0;
617 EiC_ENV->CODE.inst = NULL;
618 EiC_ENV->CODE.prev = &code;
619 /*sp = EiC_ENV->sp;*/
622 EiC_prolineString(n2);
626 if(!EiC_Include_file(argv[0],1))
634 /* rem: runEiC will call free_env_code */
635 EiC_ENV->CODE.prev = NULL;
636 EiC_ENV->CODE = code;
637 /*EiC_ENV->sp = sp;*/
645 void EiC_getSwitchCommands(int *Argc, char ***Argv)
653 static int gotSwitches = 0;
662 if(argv[1][0] == '-') {
663 if(!do_sw_commands(&argv[1][1])) {
664 EiC_error("Unknown switch command [%s]\n",
675 if(!EiC_run(argc+1,argv+1))
676 EiC_error("Failed to run %s\n",argv[1]);
687 void EiC_startEiC(int argc, char **argv)
689 extern int EiC_load_history(char *fname,int prompt);
691 #if defined(WIN32) || defined(_DJGPP)
692 signal(SIGABRT, EiC_bus_err);
694 signal(SIGBUS, EiC_bus_err);
696 signal(SIGILL, EiC_ill_oper);
697 signal(SIGSEGV, EiC_stor_access);
698 signal(SIGFPE, EiC_float_err);
699 signal(SIGINT, EiC_term_int);
700 #if defined(WIN32) || defined(_DJGPP)
701 signal(SIGTERM, EiC_exit_call);
703 signal(SIGUSR1, EiC_exit_call);
707 EiC_getSwitchCommands(&argc,&argv);
712 if(!EiC_run(argc+1,argv+1))
713 EiC_error("Error: Failed to run %s\n",argv[1]);
719 fputs(Version,stdout);
724 EiC_setinfile("starteic.h");
727 char * name = "EiChist.lst";
729 puts("Re Initiating EiC -- please wait.");
730 if(EiC_load_history(name,prompt)) {
731 runEiC(); /* ensure that startup files have
732 been loaded and compiled */
733 EiChist = fopen(name,"w");
734 EiC_save_history(EiChist,0);
737 EiC_Include_file(name,1);
739 EiChist = fopen(name,"a");
741 EiC_error("Error: unable to load history file\n");
747 EiChist = fopen(name,"w");
749 EiC_messageDisplay("Failed to create EiChist.lst\n"
750 "Start No history file mode switch\n");
755 setvbuf(EiChist,NULL,_IOLBF,0);
760 setvbuf(stdout,NULL,_IONBF,0);
761 setvbuf(stderr,NULL,_IONBF,0);
763 /* Hawk start change */