/* * Euler - a numerical lab * * platform : all * * file : command.c -- builtin command handling */ #include #include #include #include #include #include #include #include "command.h" #include "builtin.h" #include "express.h" #include "input.h" #include "meta.h" #include "metaps.h" #include "graphics.h" #include "output.h" #include "help.h" #include "udf.h" #include "mainloop.h" #define EXTENSION ".e" #define BOOKEXTENSION ".en" int promptnotebook=1,booktype=0; FILE *infile=0,*outfile=0; char* path[32]; int npath=0; static int printcomments=1; static void load_file (void) /***** load_file interpret a file. *****/ { char filename[256]; char oldline[1024],fn[256],*oldnext; int oldbooktype=booktype,pn; header *hd; FILE *oldinfile; if (udfon) { output("Cannot load a file in a function!\n"); error=221; return; } scan_space(); if (*next=='(') { hd=scan_value(); if (error) return; if (hd->type!=s_string) { output("String value expected!\n"); error=1; return; } strcpy(filename,stringof(hd)); } else { scan_namemax(filename,256); } if (error) return; oldinfile=infile; pn=-1; retry : if (pn>=0) { strcpy(fn,path[pn]); strcat(fn,PATH_DELIM_STR); strcat(fn,filename); } else strcpy(fn,filename); infile=fopen(fn,"r"); if (!infile) { strcat(fn,EXTENSION); infile=fopen(fn,"r"); pn++; if (!infile) { if (pn>=npath) { output1("Could not open %s!\n",filename); error=53; infile=oldinfile; return; } else goto retry; } } strcpy(oldline,input_line); oldnext=next; *input_line=0; next=input_line; booktype=0; while (!error && infile && !quit) command(); booktype=oldbooktype; if (infile) fclose(infile); infile=oldinfile; strcpy(input_line,oldline); next=oldnext; } static void load_book (void) /***** load_book interpret a notebook file. *****/ { header *hd; char name[256]; char oldline[1024],fn[256],*oldnext; int oldbooktype=booktype; FILE *oldinfile; if (udfon) { output("Cannot load a notebook in a function!\n"); error=221; return; } scan_space(); if (*next=='(') { hd=scan_value(); if (error) return; if (hd->type!=s_string) { output("String value expected!\n"); error=1; return; } strcpy(name,stringof(hd)); } else { scan_namemax(name,256); } if (error) return; oldinfile=infile; infile=fopen(name,"r"); if (!infile) { strcpy(fn,name); strcat(fn,BOOKEXTENSION); infile=fopen(fn,"r"); if (!infile) { output1("Could not open %s!\n",stringof(name)); error=53; infile=oldinfile; return; } } strcpy(oldline,input_line); oldnext=next; *input_line=0; next=input_line; booktype=1; while (!error && infile && !quit) { startglobal=startlocal; endglobal=endlocal; command(); } booktype=oldbooktype; if (infile) fclose(infile); infile=oldinfile; strcpy(input_line,oldline); next=oldnext; } static void do_clg (void) { graphic_mode(); gclear(); gflush(); } static void do_cls (void) { text_mode(); clear_screen(); } void clear (void) /***** clear clears the stack and remove all variables and functions. *****/ { char name[32]; scan_space(); if (*next==';' || *next==',' || *next==0) { endlocal=startlocal; } else while(1) { scan_name(name); if (error) return; kill_local(name); scan_space(); if (*next==',') { next++; continue; } else break; } } static void do_clear (void) { if (udfon) { output("Cannot clear in a function!\n"); error=120; return; } clear(); } static void do_quit (void) { quit=1; } static void do_exec (void) { header *name; char *s; name=scan_value(); if (error) return; if (name->type!=s_string) { output("Cannot execute a number or matrix!\n"); error=130; return; } s=stringof(name); while (*s && !isspace(*s)) s++; if (*s) *s++=0; if (execute(stringof(name),s)) { output("Execution failed or program returned a failure!\n"); error=131; } } static void do_forget (void) { char name[16]; header *hd; int r; if (udfon) { output("Cannot forget functions in a function!\n"); error=720; return; } while (1) { scan_space(); scan_name(name); r=xor(name); hd=(header *)ramstart; while ((char *)hdxor && !strcmp(hd->name,name)) break; hd=nextof(hd); } if ((char *)hd>=udfend) { output1("Function %s not found!\n",name); error=160; return; } kill_udf(name); scan_space(); if (*next!=',') break; else next++; } } extern int builtin_count; extern builtintyp builtin_list[]; extern int command_count; extern commandtyp command_list[]; static void do_list (void) { header *hd; int i, c, cend, lw=linelength/16; output(" *** Builtin functions:\n"); for (i=0; i=builtin_count) cend=builtin_count; for (c=i; c=command_count) cend=command_count; for (c=i; ctype!=s_udf) break; if (i>=lw) { i=0; output("\n"); } output1("%-16s",hd->name); if (test_key()==escape) return; hd=nextof(hd); i++; } output("\n"); } static void listvar1 (char *s, header *hd) { output1("%-20sType: %s\n",hd->name,s); } static void listvar2 (char *s, header *hd) { output1("%-20sType: %s (%dx%d)\n",hd->name,s,dimsof(hd)->r,dimsof(hd)->c); } static void listvar3 (char *s, header *hd) { output1("%-20sType: %s (%dx%0d)",hd->name,s, submdimsof(hd)->r,submdimsof(hd)->c); } static void do_listvar (void) { header *hd=(header *)startlocal; while (hd<(header *)endlocal) { switch (hd->type) { case s_real : listvar1("Real",hd); break; case s_interval : listvar1("Interval",hd); break; case s_complex : listvar1("Complex",hd); break; case s_string : listvar1("String",hd); break; case s_matrix : listvar2("Real Matrix",hd); break; case s_cmatrix : listvar2("Complex Matrix",hd); break; case s_imatrix : listvar2("Interval Matrix",hd); break; case s_reference : listvar1("Reference",hd); break; case s_submatrix : listvar3("Real Submatrix",hd); break; case s_isubmatrix : listvar3("Interval Submatrix",hd); break; case s_csubmatrix : listvar3("Complex Submatrix",hd); break; default: listvar1("Unknown Type",hd); break; } hd=nextof(hd); if (test_key()==escape) break; } } static void do_dump (void) { header *file; if (outfile) { if (fclose(outfile)) { output("Error while closing dumpfile.\n"); } outfile=0; } scan_space(); if (*next==';' || *next==',' || *next==0) { if (*next) next++; return; } file=scan_value(); if (error || file->type!=s_string) { output("Dump needs a filename!\n"); error=201; return; } outfile=fopen(stringof(file),"a"); if (!outfile) { output1("Could not open %s.\n",stringof(file)); } } static void do_dir (void) { header *file; int len, npl, i, j, k, imax; char **entries=NULL; int n_entries=0; scan_space(); if (*next==';' || *next==',' || *next==0) { file=new_string("*",5,""); } else file=scan_value(); if (error || file->type!=s_string) { output("Dir needs a string!\n"); error=201; return; } len = scan_dir(".",stringof(file),&entries,&n_entries); len +=2; npl = linelength/len; imax = n_entries/npl; if (n_entries % npl) imax++; for (i=0; i=n_entries) break; output1("%s", entries[npl*i+j]); l=strlen(entries[npl*i+j]); for (k=0;ktype!=s_string) { output("Path needs a string!\n"); error=201; return; } p=stringof(ppath); for (i=2; is && *(q-1)==PATH_DELIM_CHAR) q--; *q=0; if (*p==';') p++; path[npath]=(char *)malloc(strlen(s)+1); strcpy(path[npath],s); npath++; } if (*next!=';') goto out; } static void do_cd (void) { header *hd; char name[256]; char *s; scan_space(); if (*next==';' || *next==',' || *next==0) { s=cd(""); output1("%s\n",s); return; } if (*next=='(') { hd=scan_value(); if (error) return; if (hd->type!=s_string) { output("String value expected!\n"); error=1; return; } strcpy(name,stringof(hd)); } else { scan_namemax(name,256); } if (error) return; s=cd(name); if (*next!=';') output1("%s\n",s); if (*next==',' || *next==';') next++; } static void do_meta (void) { header *file; scan_space(); file=scan_value(); if (error || file->type!=s_string) { output("Meta needs a filename!\n"); error=201; return; } if (!dump_meta(stringof(file))) { output1("Could not open %s.\n",stringof(file)); } } static void do_postscript (void) { header *file; scan_space(); file=scan_value(); if (error || file->type!=s_string) { output("postscript needs a filename!\n"); error=201; return; } if (!dump_postscript(stringof(file))) output1("Could not open %s.\n",stringof(file)); } static void do_remove (void) { header *hd; char name[256]; if (*next=='(') { hd=scan_value(); if (error) return; if (hd->type!=s_string) { output("String value expected!\n"); error=1; return; } strcpy(name,stringof(hd)); } else { scan_namemax(name,256); } if (error) return; remove(name); } static void do_do (void) { int udfold; char name[16]; char *oldnext=next,*udflineold; header *var; scan_space(); scan_name(name); if (error) return; var=searchudf(name); if (!var || var->type!=s_udf) { output("Need a udf!\n"); error=220; return; } udflineold=udfline; udfline=next=udfof(var); udfold=udfon; udfon=1; while (!error && udfon==1) { command(); if (udfon==2) break; if (test_key()==escape) { output("User interrupted!\n"); error=58; break; } } if (error) output1("Error in function %s\n",var->name); if (udfon==0) { output1("Return missing in %s!\n",var->name); error=55; } udfon=udfold; udfline=udflineold; if (udfon) next=oldnext; else { next=input_line; *next=0; } } static void do_mdump (void) { header *hd; #ifndef SPLIT_MEM output1("ramstart : 0\nstartlocal : %ld\n",startlocal-ramstart); output1("endlocal : %ld\n",endlocal-ramstart); output1("newram : %ld\n",newram-ramstart); output1("ramend : %ld\n",ramend-ramstart); #else output1("ramstart : 0\nstartlocal : %ld\n",startlocal-varstart); output1("endlocal : %ld\n",endlocal-varstart); output1("newram : %ld\n",newram-varstart); output1("ramend : %ld\n",ramend-varstart); #endif hd=(header *)ramstart; #ifdef SPLIT_MEM while ((char *)hdname); output1("size %6ld ",(long)hd->size); output1("type %d\n",hd->type); hd=nextof(hd); } hd=(header *)varstart; #endif while ((char *)hdname); #else output1("%6ld : %16s, ",(char *)hd-varstart,hd->name); #endif output1("size %6ld ",(long)hd->size); output1("type %d\n",hd->type); hd=nextof(hd); } } static void hex_out1 (int n) { if (n<10) output1("%c",n+'0'); else output1("%c",n-10+'A'); } static void hex_out (unsigned int n) { hex_out1(n/16); hex_out1(n%16); output(" "); } static void string_out (unsigned char *p) { int i; unsigned char a; for (i=0; i<16; i++) { a=*p++; output1("%c",(a<' ')?'_':a); } } static void do_hexdump (void) { char name[16]; unsigned char *p,*end; int i=0,j; unsigned long count=0; header *hd; scan_space(); scan_name(name); if (error) return; hd=searchvar(name); if (!hd) hd=searchudf(name); if (error || hd==0) return; p=(unsigned char *)hd; end=p+hd->size; output1("\n%5lx ",count); while (p=16) { i=0; string_out(p-16); output1("\n%5lx ",count); if (test_key()==escape) break; } } for (j=i; j<16; j++) output(" "); string_out(p-i); output("\n"); } void do_help (void) { char name[256]; header *hd; int count,i,defaults; char *p,*end,*pnote; builtintyp *b; scan_space(); p=name; while (*next!=0 && *next!=' ') { *p++=*next++; if (p-name>254) break; } *p=0; if (!*name) strcpy(name,"help"); b=find_builtin(name); if (b) { if (b->nargs>=0) { output1( "%s is a builtin function with %d argument(s).\n" ,name,b->nargs); } else output1( "%s is a builtin function.\n" ,name); } hd=searchudf(name); if (hd && hd->type==s_udf) { if (b) output1("%s is also a user defined function.\n",name); output1("function %s (",name); end=udfof(hd); p=helpof(hd); memmove(&count,p,sizeof(inttyp)); p+=sizeof(inttyp); pnote=p; for (i=0; iname,p2->name); } void sort_command (void) { command_count=0; while (command_list[command_count].name) command_count++; qsort(command_list,command_count,sizeof(commandtyp), (int (*)(const void *, const void *))command_compare); } commandtyp *preview_command (unsigned long *l) { commandtyp h; char name[16],*a,*n; *l=0; a=next; n=name; while (*l<15 && isalpha(*a)) { *n++=*a++; *l+=1; } *n=0; if (isalpha(*a)) return 0; h.name=name; return (commandtyp *)bsearch(&h,command_list,command_count,sizeof(commandtyp), (int (*)(const void *, const void *))command_compare); }