ack/lang/cem/ctest/ctsetjmp/stjmp.c
1988-04-26 14:33:11 +00:00

243 lines
3.8 KiB
C

# include "setjmp.h"
# include <stdio.h>
# ifndef NOSIGNAL
# include <signal.h>
# endif not NOSIGNAL
/*
* setjmptest
* A program to test setjmp(III) and longjmp,
* in particular with respect to register variables
*/
int whichtest;
int nerrors;
main() {
jmp_buf envm;
register int i;
test1();
test2();
test3();
test4();
test5();
test6();
if (nerrors) return nerrors;
i = 1;
if (setjmp(envm) == 0) {
i = 2;
longjmp(envm, 1);
}
else {
if (i == 2) {
printf("Setjmp/longjmp work ok, even with register variables\n");
}
else if (i == 1) {
printf("WARNING: The setjmp/longjmp of this machine restore register variables\n\
to the value they had at the time of the \"setjmp\"\n");
}
else {
printf("Aha, I just found one last error\n");
return 1;
}
}
return 0;
}
e(n) {
nerrors++;
fprintf(stderr,"Error %d in test %d\n",n,whichtest);
}
test1() {
register p;
printf("TEST 1 : one integer register variable\n");
whichtest = 1;
p = 200;
garbage();
if (p != 200) e(1);
}
test2() {
register p,q;
printf("TEST 2 : two integer register variables\n");
whichtest = 2;
p = 200; q = 300;
garbage();
if (p != 200) e(1);
if (q != 300) e(2);
}
test3() {
register p,q,r;
printf("TEST 3 : three integer register variables\n");
whichtest = 3;
p = 200; q = 300; r = 400;
garbage();
if (p != 200) e(1);
if (q != 300) e(2);
if (r != 400) e(3);
}
char buf[512];
test4() {
register char *p;
printf("TEST 4 : one pointer register variable\n");
whichtest = 4;
p = &buf[100];
garbage();
if (p != &buf[100]) e(1);
}
test5() {
register char *p,*q;
printf("TEST 5 : two pointer register variables\n");
whichtest = 5;
p = &buf[100]; q = &buf[200];
garbage();
if (p != &buf[100]) e(1);
if (q != &buf[200]) e(2);
}
test6() {
register char *p,*q,*r;
printf("TEST 6 : three pointer register variables\n");
whichtest = 6;
p = &buf[100]; q = &buf[200]; r = &buf[300];
garbage();
if (p != &buf[100]) e(1);
if (q != &buf[200]) e(2);
if (r != &buf[300]) e(3);
}
jmp_buf env;
/* return address of local variable.
This way we can check that the stack is not polluted.
*/
char *
addr() {
char a;
return &a;
}
garbage() {
register i,j,k;
register char *p,*q,*r;
char *a, *tmp;
int t;
p = &buf[300];
q = &buf[400];
r = &buf[500];
i = 10; j = 20; k = 30;
switch(setjmp(env)) {
case 0:
a = addr();
longjmp(env,1);
break;
case 1:
if (i != 10) e(11);
if (j != 20) e(12);
if (k != 30) e(13);
if (p != &buf[300]) e(14);
if (q != &buf[400]) e(15);
if (r != &buf[500]) e(16);
tmp = addr();
if (a != tmp) e(17);
level1();
break;
case 2:
if (i != 10) e(21);
if (j != 20) e(22);
if (k != 30) e(23);
if (p != &buf[300]) e(24);
if (q != &buf[400]) e(25);
if (r != &buf[500]) e(26);
if (a != tmp) e(27);
level2();
break;
case 3:
if (i != 10) e(31);
if (j != 20) e(32);
if (k != 30) e(33);
if (p != &buf[300]) e(34);
if (q != &buf[400]) e(35);
if (r != &buf[500]) e(36);
if (a != tmp) e(37);
# ifndef NOSIGNAL
hard();
case 4:
if (i != 10) e(41);
if (j != 20) e(42);
if (k != 30) e(43);
if (p != &buf[300]) e(44);
if (q != &buf[400]) e(45);
if (r != &buf[500]) e(46);
if (a != tmp) e(47);
#endif
return;
break;
default:
e(100);
}
e(200);
}
level1() {
register char *p;
register i;
i = 1000;
p = &buf[10];
i = 200;
p = &buf[20];
longjmp(env,2);
}
level2() {
register char *p;
register i;
i = 0200;
p = &buf[2];
*p = i;
dolev();
}
dolev() {
register char *p;
register i;
i = 010;
p = &buf[3];
*p = i;
longjmp(env,3);
}
# ifndef NOSIGNAL
catch() {
printf(" signal caught\n");
longjmp(env,4);
}
hard() {
register char *p;
signal(SIGHUP,catch);
for(p = buf;p <= &buf[511]; p++) *p = 025;
printf("Sending signal ...");
kill(getpid(),SIGHUP);
}
# endif not NOSIGNAL