/*
* mainloop.c
*
* 2002/09/01 path variable has two default values :
* - the current dir
* - the install prog dir
* thanks to Masao KAWAMURA
*
* do_path function modified to let these two items
* unchnged when the path function is called.
*
* 2002/06/02 out_matrix, out_cmatrix and out_imatrix now react to a change
* in window size.
*
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <float.h>
#include <stdarg.h>
#include "sysdep.h"
#include "output.h"
#include "input.h"
#include "funcs.h"
#include "graphics.h"
#include "interval.h"
#include "builtin.h"
#include "express.h"
#include "stack.h"
#include "meta.h"
#include "metaps.h"
#include "command.h"
#include "mainloop.h"
#include "udf.h"
#include "edit.h"
#include "scalp.h"
#include "help.h"
#ifdef YACAS
#include "yacas2e.h"
#endif
char *udfline;
/*
* path for euler file research
*/
int searchglobal=0;
FILE *metafile=0;
double epsilon,changedepsilon;
char titel[]="This is EULER, Version %s.\n\n"
"Type help(Return) for help.\n"
"Enter command: (%ld Bytes free.)\n\n";
int error,quit,surpressed,udf=0,errorout,outputing=1,stringon=0,trace=0;
char input_line[1024];
int nosubmref=0;
static header commandheader;
extern commandtyp command_list[];
int commandtype;
/***************** some builtin commands *****************/
int builtin (void)
/***** builtin
interpret a builtin command, number no.
*****/
{ unsigned long l;
commandtyp *p;
int comn;
if (*next==3)
{ next++;
#ifdef SPECIAL_ALIGNMENT
memmove((char *)(&comn),next,sizeof(int));
#else
comn=*((int *)next);
#endif
p=command_list+comn;
l=sizeof(int);
}
else if (udfon) return 0;
else p=preview_command(&l);
if (p)
{ next+=l;
p->f();
if (*next==';' || *next==',') next++;
commandtype=p->nr;
return 1;
}
return 0;
}
header *scan_expression (void)
/***** scan_expression
scans a variable, a value or a builtin command.
*****/
{ if (builtin()) return &commandheader;
return scan();
}
#define addsize(hd,size) ((header *)((char *)(hd)+size))
static void do_assignment (header *var)
/***** do_assignment
assign a value to a variable.
*****/
{ header *variable[8],*rightside[8],*rs,*v,*mark;
int rscount,varcount,i,j;
unsigned long offset,oldoffset,dif;
char *oldendlocal;
scan_space();
if (*next=='=')
{ next++;
nosubmref=1; rs=scan_value(); nosubmref=0;
if (error) return;
varcount=0;
/* count the variables, that get assigned something */
while (var<rs)
{ if (var->type!=s_reference && var->type!=s_submatrix
&& var->type!=s_csubmatrix && var->type!=s_isubmatrix)
{ output("Cannot assign to value!\n");
error=210;
}
variable[varcount]=var; var=nextof(var); varcount++;
if (varcount>=8)
{ output("To many commas!\n"); error=100; return;
}
}
/* count and note the values, that are assigned to the
variables */
rscount=0;
while (rs<(header *)newram)
{ rightside[rscount]=rs;
rs=nextof(rs); rscount++;
if (rscount>=8)
{ output("To many commas!\n"); error=101; return;
}
}
/* cannot assign 2 values to 3 variables , e.g. */
if (rscount>1 && rscount<varcount)
{ output("Illegal multiple assignment!\n"); error=102; return;
}
oldendlocal=endlocal;
offset=0;
/* do all the assignments */
if (varcount==1) var=assign(variable[0],rightside[0]);
else
for (i=0; i<varcount; i++)
{ oldoffset=offset;
/* assign a variable */
var=assign(addsize(variable[i],offset),
addsize(rightside[(rscount>1)?i:0],offset));
if (error) return;
offset=endlocal-oldendlocal;
if (oldoffset!=offset) /* size of var. changed */
{ v=addsize(variable[i],offset);
if (v->type==s_reference) mark=referenceof(v);
else mark=submrefof(v);
/* now shift all references of the var.s */
if (mark) /* not a new variable */
for (j=i+1; j<varcount; j++)
{ v=addsize(variable[j],offset);
dif=offset-oldoffset;
if (v->type==s_reference && referenceof(v)>mark)
referenceof(v)=addsize(referenceof(v),dif);
else if (submrefof(v)>mark)
submrefof(v)=addsize(submrefof(v),dif);
}
}
}
}
else /* just an expression which is a variable */
{ var=getvalue(var);
}
if (error) return;
if (*next!=';') give_out(var);
if (*next==',' || *next==';') next++;
}
int command (void)
/***** command
scan a command and interpret it.
return, if the user wants to quit.
*****/
{
header *expr;
int ret=c_none;
quit=0; error=0; errorout=0;
while(1)
{ scan_space();
if (*next) break;
else next_line();
}
if (*next==1) return ret;
#ifdef YACAS
if (*next=='>')
{ next+=1; do_yacas();
return 0;
}
#endif
expr=scan_expression();
if (!expr) { newram=endlocal; return ret; }
if (error)
{ newram=endlocal;
print_error(next);
next=input_line; input_line[0]=0;
return ret;
}
if (expr==&commandheader)
{ newram=endlocal;
return commandtype;
}
switch (expr->type)
{ case s_real :
case s_complex :
case s_matrix :
case s_cmatrix :
case s_imatrix :
case s_string :
case s_interval :
if (*next!=';') give_out(expr);
if (*next==',' || *next==';') next++;
break;
case s_reference :
case s_submatrix :
case s_csubmatrix :
case s_isubmatrix :
do_assignment(expr);
break;
default : break;
}
if (error) print_error(next);
newram=endlocal;
if (error) { next=input_line; input_line[0]=0; }
return ret;
}
/******************* main functions ************************/
void clear_fktext (void)
{ int i;
for (i=0; i<10; i++) fktext[i][0]=0;
}
#include <glib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
static int is_dir(char *dirname)
{
struct stat buf;
if (stat(dirname,&buf)==0) {
if (S_ISDIR(buf.st_mode))
return 1;
}
return 0;
}
static void define_eulercfg()
{
FILE *file;
char *filename, *dirname;
dirname = g_strconcat(g_get_home_dir(),"/.euler",NULL);
if (!is_dir(dirname)) {
mkdir(dirname,0755);
}
g_free(dirname);
filename = g_strconcat(g_get_home_dir(),"/.euler/euler.cfg",NULL);
file = fopen(filename, "r");
if (file) {
fclose(file);
g_free(filename);
return;
}
file = fopen(filename, "w");
g_free(filename);
if (file) {
fprintf(file,"path(\".;%s/share/euler/progs\");\n",INSTALL_DIR);
fprintf(file,"cd(\"%s/share/euler/progs\");\n",INSTALL_DIR);
fprintf(file,"load \"util.e\";\n");
fprintf(file,"load \"framed.e\";\n");
fprintf(file,"load \"x.e\";\n");
fprintf(file,"load \"remez.e\";\n");
fprintf(file,"load \"steffens.e\";\n");
fprintf(file,"load \"gauss.e\";\n");
fprintf(file,"load \"histo.e\";\n");
fprintf(file,"load \"interval.e\";\n");
fprintf(file,"load \"broyden.e\";\n");
fprintf(file,"load \"fminmax.e\";\n");
fprintf(file,"load \"3dplot.e\";\n");
fprintf(file,"load \"svd.e\";\n");
fprintf(file,"load \"splines.e\";\n");
fprintf(file,"load \"statist.e\";\n");
fprintf(file,"shortformat();\n");
fprintf(file,"shrinkwindow();\n");
fclose(file);
}
}
void main_loop (int argc, char *argv[])
{ int i;
char *eulercfg;
define_eulercfg();
#ifndef SPLIT_MEM
output2(titel,VERSION,(unsigned long)(ramend-ramstart));
#else
output2(titel,VERSION,(unsigned long)(ramend-varstart));
#endif
#ifndef SPLIT_MEM
newram=startlocal=endlocal=ramstart;
#else
newram=startlocal=endlocal=varstart;
#endif
udfend=ramstart;
changedepsilon=epsilon=10000*DBL_EPSILON;
/*
* setup default paths
*/
path[0]=(char *)malloc(2);
strcpy(path[0],".");
path[1]=(char *)malloc(strlen(INSTALL_DIR) + strlen("/share/euler/progs") + 1);
strcpy(path[1], INSTALL_DIR);
strcat(path[1], "/share/euler/progs");
npath=2;
sort_builtin(); sort_command(); make_xors(); clear_fktext();
accuinit();
#ifdef YACAS
init_yacas();
#endif
next=input_line; *next=0; /* clear input line */
eulercfg = g_strconcat("load \"",g_get_home_dir(),"/.euler/euler.cfg\";",NULL);
strcpy(input_line,eulercfg);
g_free(eulercfg);
for (i=1; i<argc; i++)
{ strcat(input_line," load \"");
strcat(input_line,argv[i]);
strcat(input_line,"\";");
}
while (!quit)
{ startglobal=startlocal;
endglobal=endlocal;
command(); /* interpret until "quit" */
if (trace<0) trace=0;
}
#ifdef YACAS
exit_yacas();
#endif
}
syntax highlighted by Code2HTML, v. 0.9.1