SC Spreadhseet Calculator on sysV/386
Piercarlo Grandi
pcg at cs.aber.ac.uk
Thu Oct 11 07:36:18 AEST 1990
On 28 Sep 90 16:49:08 GMT, richard at pegasus.com (Richard Foulk) said:
>>>Does anybody out there have sc running properly on sco unix or xenix
>>>sysV/386.
>Version 6.8 wouldn't compile with the AT&T compiler under ESIX-D. "interp.c"
>bombed off with "Fatal error in /lib/comp." GCC produced a working
>binary, but it did die with a core dump while I was going through the
>tutorial file provided with the package.
richard> On ISC 2.0.2 is works okay except that multiple divide-by-zero
richard> errors will cause it to core dump (I think it dies no the fifth
richard> one).
Here are a set of patches that eliminate some problems with sc 6.8, and
minimize the cases where divide-by-zero occur. In particular constant
expressions are only evaluated at load time, and non constant
expressions *are not* evaluated at load time, because this is both
useless and non sensical, because certain things may not be set up until
the entire spreadhseet has been loaded.
===================================================================
RCS file: interp.c,v
retrieving revision 6.8
diff -c -r6.8 interp.c
*** /tmp/,RCSt1a00165 Wed Sep 19 22:51:47 1990
--- interp.c Wed Sep 19 22:40:30 1990
***************
*** 769,777 ****
eval_fpe(signo) /* Trap for FPE errors in eval */
int signo;
{
#ifdef IEEE_MATH
! (void)fpsetsticky((fp_except)0); /* Clear exception */
#endif /* IEEE_MATH */
longjmp(fpe_save, 1);
}
--- 769,782 ----
eval_fpe(signo) /* Trap for FPE errors in eval */
int signo;
{
+ #ifdef i386
+ asm(" fnclex");
+ asm(" fwait");
+ #else
#ifdef IEEE_MATH
! (void)fpsetsticky((fp_except)0); /* Clear exception */
#endif /* IEEE_MATH */
+ #endif
longjmp(fpe_save, 1);
}
***************
*** 1130,1135 ****
--- 1135,1141 ----
int i, j, *chgct;
#endif
{
+ (void) signal(SIGFPE, eval_fpe);
if (p->flags & is_strexpr) {
char *v;
if (setjmp(fpe_save)) {
***************
*** 1525,1569 ****
struct enode *e;
{
double val;
! exprerr = 0;
! (void) signal(SIGFPE, eval_fpe);
! if (setjmp(fpe_save)) {
! error ("Floating point exception in cell %s", v_name(v->row, v->col));
val = (double)0.0;
! } else {
! val = eval(e);
! }
! (void) signal(SIGFPE, quit);
! if (exprerr) {
! efree((struct ent *)0, e);
! return;
}
! if (constant(e)) {
! if (!loading)
! v->v = val * prescale;
! else
! v->v = val;
if (!(v->flags & is_strexpr)) {
efree(v, v->expr);
v->expr = (struct enode *)0;
}
efree((struct ent *)0, e);
- v->flags |= (is_changed|is_valid);
- changed++;
- modflg++;
- return;
}
! efree (v, v->expr);
! v->expr = e;
! v->flags |= (is_changed|is_valid);
! v->flags &= ~is_strexpr;
#ifdef EXPRTREE
! totoptree(v);
#endif
! changed++;
! modflg++;
}
void
--- 1531,1581 ----
struct enode *e;
{
double val;
+ unsigned isconstant = constant(e);
! if (loading && !isconstant)
val = (double)0.0;
! else
! {
! exprerr = 0;
! (void) signal(SIGFPE, eval_fpe);
! if (setjmp(fpe_save)) {
! error ("Floating point exception in cell %s", v_name(v->row, v->col));
! val = (double)0.0;
! } else {
! val = eval(e);
! }
! (void) signal(SIGFPE, quit);
! if (exprerr) {
! efree((struct ent *)0, e);
! return;
! }
}
!
! if (isconstant) {
! if (!loading && prescale < (double)0.9999999)
! val *= prescale;
! v->v = val;
!
if (!(v->flags & is_strexpr)) {
efree(v, v->expr);
v->expr = (struct enode *)0;
}
efree((struct ent *)0, e);
}
! else
! {
! efree (v, v->expr);
! v->expr = e;
! v->flags &= ~is_strexpr;
#ifdef EXPRTREE
! totoptree(v);
#endif
! }
!
! v->flags |= (is_changed|is_valid);
! changed++; modflg++;
}
void
===================================================================
RCS file: lex.c,v
retrieving revision 6.8
diff -c -r6.8 lex.c
*** /tmp/,RCSt1a00165 Wed Sep 19 22:51:52 1990
--- lex.c Mon Sep 17 11:06:40 1990
***************
*** 56,61 ****
--- 56,78 ----
jmp_buf wakeup;
jmp_buf fpe_buf;
+ #ifdef SIGVOID
+ void
+ #endif
+ fpe_trap(signo)
+ int signo;
+ {
+ #ifdef i386
+ asm(" fnclex");
+ asm(" fwait");
+ #else
+ #ifdef IEEE_MATH
+ (void)fpsetsticky((fp_except)0); /* Clear exception */
+ #endif /* IEEE_MATH */
+ #endif
+ longjmp(fpe_buf, 1);
+ }
+
struct key {
char *key;
int val;
***************
*** 136,146 ****
}
}
} else if ((*p == '.') || isdigit(*p)) {
! double v = 0;
int temp;
char *nstart = p;
if (*p != '.') {
! do v = v*10 + (double)(*p-'0');
while (isdigit(*++p));
}
if (*p=='.' || *p == 'e' || *p == 'E') {
--- 153,177 ----
}
}
} else if ((*p == '.') || isdigit(*p)) {
! #ifdef SIGVOID
! void (*sig_save)();
! #else
! int (*sig_save)();
! #endif
! double v = 0.0;
int temp;
char *nstart = p;
+
+ sig_save = signal(SIGFPE, fpe_trap);
+ if (setjmp(fpe_buf)) {
+ (void) signal(SIGFPE, sig_save);
+ yylval.fval = v;
+ error("Floating point exception\n");
+ return FNUMBER;
+ }
+
if (*p != '.') {
! do v = v*10.0 + (double) ((unsigned) *p - '0');
while (isdigit(*++p));
}
if (*p=='.' || *p == 'e' || *p == 'E') {
***************
*** 163,168 ****
--- 194,200 ----
}
}
}
+ (void) signal(SIGFPE, sig_save);
} else if (*p=='"') {
char *ptr;
ptr = p+1;
***************
*** 539,557 ****
time_out(signo)
int signo;
{
! #ifdef IEEE_MATH
! (void)fpsetsticky((fp_except)0); /* Clear exception */
! #endif /* IEEE_MATH */
! longjmp(wakeup, -1);
! }
!
! #ifdef SIGVOID
! void
! #endif
! fpe_trap(signo)
! int signo;
! {
! longjmp(fpe_buf, 1);
}
/*
--- 571,577 ----
time_out(signo)
int signo;
{
! longjmp(wakeup, 1);
}
/*
--
Piercarlo "Peter" Grandi | ARPA: pcg%uk.ac.aber.cs at nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg at cs.aber.ac.uk
More information about the Comp.unix.sysv386
mailing list