This is umath.c in view mode; [Download] [Up]
/* Math */
#include <signal.h>
#include "w.h"
#include "bw.h"
#include "pw.h"
#include "tw.h"
#include "vs.h"
#include "zstr.h"
#include "umath.h"
char *merr;
void fperr()
{
if(!merr) merr="Float point exception";
signal(SIGFPE,fperr);
}
struct var
{
char *name;
int set;
double val;
struct var *next;
} *vars=0;
struct var *get(str)
char *str;
{
struct var *v;
for(v=vars;v;v=v->next) if(!zcmp(v->name,str)) return v;
v=(struct var *)malloc(sizeof(struct var));
v->set=0;
v->next=vars;
vars=v;
v->name=zdup(str);
return v;
}
char *ptr;
struct var *dumb;
double expr(prec,rtv)
struct var **rtv;
{
double x=0.0;
struct var *v=0;
while(*ptr==' ' || *ptr=='\t') ++ptr;
if(*ptr>='a' && *ptr<='z' || *ptr>='A' && *ptr<='Z' || *ptr=='_')
{
char *s=ptr, c;
while(*ptr>='a' && *ptr<='z' || *ptr>='A' && *ptr<='Z' || *ptr=='_' ||
*ptr>='0' && *ptr<='9') ++ptr;
c= *ptr; *ptr=0;
v=get(s);
x=v->val;
*ptr=c;
}
else if(*ptr>='0' && *ptr<='9' || *ptr=='.')
{
sscanf(ptr,"%lf",&x);
while(*ptr>='0' && *ptr<='9' || *ptr=='.' || *ptr=='e' || *ptr=='E') ++ptr;
}
else if(*ptr=='(')
{
++ptr;
x=expr(0,&v);
if(*ptr==')') ++ptr;
else { if(!merr) merr="Missing )"; }
}
else if(*ptr=='-')
{
++ptr;
x= -expr(10,&dumb);
}
loop:
while(*ptr==' ' || *ptr=='\t') ++ptr;
if(*ptr=='*' && 5>prec)
{
++ptr;
x*=expr(5,&dumb);
goto loop;
}
else if(*ptr=='/' && 5>prec)
{
++ptr;
x/=expr(5,&dumb);
goto loop;
}
else if(*ptr=='+' && 4>prec)
{
++ptr;
x+=expr(4,&dumb);
goto loop;
}
else if(*ptr=='-' && 4>prec)
{
++ptr;
x-=expr(4,&dumb);
goto loop;
}
else if(*ptr=='=' && 2>=prec)
{
++ptr;
x=expr(2,&dumb);
if(v) v->val=x, v->set=1;
else { if(!merr) merr="Left side of = is not an l-value"; }
goto loop;
}
*rtv=v;
return x;
}
double calc(bw,s)
BW *bw;
char *s;
{
double result;
struct var *v;
BW *tbw=bw->parent->main->object;
v=get("top"); v->val=tbw->top->line+1; v->set=1;
v=get("lines"); v->val=tbw->b->eof->line+1; v->set=1;
v=get("line"); v->val=tbw->cursor->line+1; v->set=1;
v=get("col"); v->val=tbw->cursor->col+1; v->set=1;
v=get("byte"); v->val=tbw->cursor->byte+1; v->set=1;
v=get("height"); v->val=tbw->h; v->set=1;
v=get("width"); v->val=tbw->w; v->set=1;
ptr=s;
merr=0;
up: result=expr(0,&dumb);
if(!merr)
{
while(*ptr==' ' || *ptr=='\t') ++ptr;
if(*ptr==';')
{
++ptr;
while(*ptr==' ' || *ptr=='\t') ++ptr;
if(*ptr) goto up;
}
else if(*ptr) merr="Extra junk after end of expr";
}
return result;
}
int domath(bw,s,object,notify) /* Main user interface */
BW *bw;
char *s;
void *object;
int *notify;
{
double result=calc(bw,s);
if(notify) *notify=1;
if(merr) { msgnw(bw,merr); return -1; }
vsrm(s);
sprintf(msgbuf,"%lg",result);
if(bw->parent->watom->what!=TYPETW)
{
binsm(bw->cursor,sz(msgbuf));
pfwrd(bw->cursor,zlen(msgbuf));
bw->cursor->xcol=piscol(bw->cursor);
}
else msgnw(bw,msgbuf);
return 0;
}
B *mathhist=0;
int umath(bw)
BW *bw;
{
signal(SIGFPE,fperr);
if(wmkpw(bw,"=",&mathhist,domath,"math",NULL,NULL,NULL,NULL)) return 0;
else return -1;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.