1*47862Sbostic /*- 2*47862Sbostic * %sccs.include.proprietary.c% 3*47862Sbostic */ 48867Smckusick 5*47862Sbostic #ifndef lint 6*47862Sbostic static char sccsid[] = "@(#)quiz.c 4.8 (Berkeley) 04/08/91"; 7*47862Sbostic #endif /* not lint */ 88867Smckusick 98867Smckusick #include <stdio.h> 108867Smckusick #include <signal.h> 1141774Sbostic #include "pathnames.h" 1241774Sbostic 138867Smckusick #define NF 10 148867Smckusick #define NL 300 158867Smckusick #define NC 200 168867Smckusick #define SL 100 178867Smckusick #define NA 10 188867Smckusick 198867Smckusick int tflag; 208867Smckusick int xx[NL]; 218867Smckusick char score[NL]; 228867Smckusick int rights; 238867Smckusick int wrongs; 248867Smckusick int guesses; 258867Smckusick FILE *input; 268867Smckusick int nl = 0; 278867Smckusick int na = NA; 288867Smckusick int inc; 298867Smckusick int ptr = 0; 308867Smckusick int nc = 0; 318867Smckusick char line[150]; 328867Smckusick char response[100]; 338867Smckusick char *tmp[NF]; 348867Smckusick int select[NF]; 358867Smckusick 368867Smckusick readline() 378867Smckusick { 3833196Sbostic register int ch; 398867Smckusick char *t; 408867Smckusick loop: 4133196Sbostic for(t=line;(ch=getc(input))!=-1;t++) { 4233196Sbostic *t = ch; 438867Smckusick nc++; 448867Smckusick if(*t==' '&&(t==line||t[-1]==' ')) 458867Smckusick t--; 468867Smckusick if(*t=='\n') { 478867Smckusick if(t[-1]=='\\') /*inexact test*/ 488867Smckusick continue; 498867Smckusick while(t>line&&t[-1]==' ') 508867Smckusick *--t = '\n'; 518867Smckusick *++t = 0; 528867Smckusick return(1); 538867Smckusick } 548867Smckusick if(t-line>=NC) { 558867Smckusick printf("Too hard for me\n"); 568867Smckusick do { 5733196Sbostic if ((ch = getc(input)) == EOF) 588867Smckusick return(0); 5933196Sbostic } while(ch!='\n'); 6033196Sbostic *line = '\n'; 618867Smckusick goto loop; 628867Smckusick } 638867Smckusick } 648867Smckusick return(0); 658867Smckusick } 668867Smckusick 678867Smckusick char *eu; 688867Smckusick char *ev; 698867Smckusick cmp(u,v) 708867Smckusick char *u,*v; 718867Smckusick { 728867Smckusick int x; 738867Smckusick eu = u; 748867Smckusick ev = v; 758867Smckusick x = disj(1); 768867Smckusick if(x!=1) 778867Smckusick return(x); 788867Smckusick return(eat(1,0)); 798867Smckusick } 808867Smckusick 818867Smckusick disj(s) 828867Smckusick { 838867Smckusick int t, x; 848867Smckusick char *u; 858867Smckusick u = eu; 868867Smckusick t = 0; 878867Smckusick for(;;) { 888867Smckusick x = string(s); 898867Smckusick if(x>1) 908867Smckusick return(x); 918867Smckusick switch(*ev) { 928867Smckusick case 0: 938867Smckusick case ']': 948867Smckusick case '}': 958867Smckusick return(t|x&s); 968867Smckusick case '|': 978867Smckusick ev++; 988867Smckusick t |= s; 998867Smckusick s = 0; 1008867Smckusick continue; 1018867Smckusick } 1028867Smckusick if(s) eu = u; 1038867Smckusick if(string(0)>1) 1048867Smckusick return(2); 1058867Smckusick switch(*ev) { 1068867Smckusick case 0: 1078867Smckusick case ']': 1088867Smckusick return(0); 1098867Smckusick case '}': 1108867Smckusick return(1); 1118867Smckusick case '|': 1128867Smckusick ev++; 1138867Smckusick continue; 1148867Smckusick default: 1158867Smckusick return(2); 1168867Smckusick } 1178867Smckusick } 1188867Smckusick } 1198867Smckusick 1208867Smckusick string(s) 1218867Smckusick { 1228867Smckusick int x; 1238867Smckusick for(;;) { 1248867Smckusick switch(*ev) { 1258867Smckusick case 0: 1268867Smckusick case '|': 1278867Smckusick case ']': 1288867Smckusick case '}': 1298867Smckusick return(1); 1308867Smckusick case '\\': 1318867Smckusick ev++; 1328867Smckusick if(*ev==0) 1338867Smckusick return(2); 1348867Smckusick if(*ev=='\n') { 1358867Smckusick ev++; 1368867Smckusick continue; 1378867Smckusick } 1388867Smckusick default: 1398867Smckusick if(eat(s,*ev)==1) 1408867Smckusick continue; 1418867Smckusick return(0); 1428867Smckusick case '[': 1438867Smckusick ev++; 1448867Smckusick x = disj(s); 1458867Smckusick if(*ev!=']' || x>1) 1468867Smckusick return(2); 1478867Smckusick ev++; 1488867Smckusick if(s==0) 1498867Smckusick continue; 1508867Smckusick if(x==0) 1518867Smckusick return(0); 1528867Smckusick continue; 1538867Smckusick case '{': 1548867Smckusick ev++; 1558867Smckusick x = disj(s); 1568867Smckusick if(*ev!='}'||x>1) 1578867Smckusick return(2); 1588867Smckusick ev++; 1598867Smckusick continue; 1608867Smckusick } 1618867Smckusick } 1628867Smckusick } 1638867Smckusick 1648867Smckusick eat(s,c) 1658867Smckusick char c; 1668867Smckusick { 1678867Smckusick if(*ev!=c) 1688867Smckusick return(2); 1698867Smckusick if(s==0) { 1708867Smckusick ev++; 1718867Smckusick return(1); 1728867Smckusick } 1738867Smckusick if(fold(*eu)!=fold(c)) 1748867Smckusick return(0); 1758867Smckusick eu++; 1768867Smckusick ev++; 1778867Smckusick return(1); 1788867Smckusick } 1798867Smckusick 1808867Smckusick fold(c) 1818867Smckusick char c; 1828867Smckusick { 1838867Smckusick if(c<'A'||c>'Z') 1848867Smckusick return(c); 1858867Smckusick return(c|040); 1868867Smckusick } 1878867Smckusick 1888867Smckusick publish(t) 1898867Smckusick char *t; 1908867Smckusick { 1918867Smckusick ev = t; 1928867Smckusick pub1(1); 1938867Smckusick } 1948867Smckusick 1958867Smckusick pub1(s) 1968867Smckusick { 1978867Smckusick for(;;ev++){ 1988867Smckusick switch(*ev) { 1998867Smckusick case '|': 2008867Smckusick s = 0; 2018867Smckusick ev; 2028867Smckusick continue; 2038867Smckusick case ']': 2048867Smckusick case '}': 2058867Smckusick case 0: 2068867Smckusick return; 2078867Smckusick case '[': 2088867Smckusick case '{': 2098867Smckusick ev++; 2108867Smckusick pub1(s); 2118867Smckusick ev; 2128867Smckusick continue; 2138867Smckusick case '\\': 2148867Smckusick if(*++ev=='\n') 2158867Smckusick continue; 2168867Smckusick default: 2178867Smckusick if(s) 2188867Smckusick putchar(*ev); 2198867Smckusick } 2208867Smckusick } 2218867Smckusick } 2228867Smckusick 2238867Smckusick segment(u,w) 2248867Smckusick char *u, *w[]; 2258867Smckusick { 2268867Smckusick char *s; 2278867Smckusick int i; 2288867Smckusick char *t; 2298867Smckusick s = u; 2308867Smckusick for(i=0;i<NF;i++) { 2318867Smckusick u = s; 2328867Smckusick t = w[i]; 2338867Smckusick while(*s!=':'&&*s!='\n'&&s-u<SL) { 2348867Smckusick if(*s=='\\') { 2358867Smckusick if(s[1] == '\n') { 2368867Smckusick s += 2; 2378867Smckusick continue; 2388867Smckusick } 2398867Smckusick *t++ = *s++; 2408867Smckusick } 2418867Smckusick *t++ = *s++; 2428867Smckusick } 2438867Smckusick 2448867Smckusick while(*s!=':'&&*s!='\n') 2458867Smckusick s++; 2468867Smckusick *t = 0; 2478867Smckusick if(*s++=='\n') { 2488867Smckusick return(i+1); 2498867Smckusick } 2508867Smckusick } 2518867Smckusick printf("Too many facts about one thing\n"); 2528867Smckusick } 2538867Smckusick 2548867Smckusick perm(u,m,v,n,p) 2558867Smckusick int p[]; 2568867Smckusick char *u[], *v[]; 2578867Smckusick { 2588867Smckusick int i, j; 2598867Smckusick int x; 2608867Smckusick for(i=0;i<m;i++) { 2618867Smckusick for(j=0;j<n;j++) { 2628867Smckusick x = cmp(u[i],v[j]); 2638867Smckusick if(x>1) badinfo(); 2648867Smckusick if(x==0) 2658867Smckusick continue; 2668867Smckusick p[i] = j; 2678867Smckusick goto uloop; 2688867Smckusick } 2698867Smckusick return(0); 2708867Smckusick uloop: ; 2718867Smckusick } 2728867Smckusick return(1); 2738867Smckusick } 2748867Smckusick 2758867Smckusick find(u,m) 2768867Smckusick char *u[]; 2778867Smckusick { 2788867Smckusick int n; 2798867Smckusick while(readline()){ 2808867Smckusick n = segment(line,tmp); 2818867Smckusick if(perm(u,m,tmp+1,n-1,select)) 2828867Smckusick return(1); 2838867Smckusick } 2848867Smckusick return(0); 2858867Smckusick } 2868867Smckusick 2878867Smckusick readindex() 2888867Smckusick { 2898867Smckusick xx[0] = nc = 0; 2908867Smckusick while(readline()) { 2918867Smckusick xx[++nl] = nc; 2928867Smckusick if(nl>=NL) { 2938867Smckusick printf("I've forgotten some of it;\n"); 2948867Smckusick printf("I remember %d items.\n", nl); 2958867Smckusick break; 2968867Smckusick } 2978867Smckusick } 2988867Smckusick } 2998867Smckusick 3008867Smckusick talloc() 3018867Smckusick { 3028867Smckusick int i; 30317680Sralph char *malloc(); 30417680Sralph 3058867Smckusick for(i=0;i<NF;i++) 3068867Smckusick tmp[i] = malloc(SL); 3078867Smckusick } 3088867Smckusick 30946755Sbostic void done(); 31046755Sbostic 3118867Smckusick main(argc,argv) 3128867Smckusick char *argv[]; 3138867Smckusick { 3148867Smckusick register j; 3158867Smckusick int i; 3168867Smckusick int x; 3178867Smckusick int z; 3188867Smckusick char *info; 3198867Smckusick int tvec[2]; 3208867Smckusick char *t; 3218867Smckusick int count; 32241774Sbostic info = _PATH_INDEX; 3238867Smckusick time(tvec); 3248867Smckusick inc = tvec[1]&077774|01; 3258867Smckusick loop: 3268867Smckusick if(argc>1&&*argv[1]=='-') { 3278867Smckusick switch(argv[1][1]) { 3288867Smckusick case 'i': 3298867Smckusick if(argc>2) 3308867Smckusick info = argv[2]; 3318867Smckusick argc -= 2; 3328867Smckusick argv += 2; 3338867Smckusick goto loop; 3348867Smckusick case 't': 3358867Smckusick tflag = 1; 3368867Smckusick argc--; 3378867Smckusick argv++; 3388867Smckusick goto loop; 3398867Smckusick } 3408867Smckusick } 3418867Smckusick input = fopen(info,"r"); 3428867Smckusick if(input==NULL) { 3438867Smckusick printf("No info\n"); 3448867Smckusick exit(0); 3458867Smckusick } 3468867Smckusick talloc(); 3478867Smckusick if(argc<=2) 3488867Smckusick instruct(info); 3498867Smckusick signal(SIGINT,done); 3508867Smckusick argv[argc] = 0; 3518867Smckusick if(find(&argv[1],argc-1)==0) 3528867Smckusick dunno(); 3538867Smckusick fclose(input); 3548867Smckusick input = fopen(tmp[0],"r"); 3558867Smckusick if(input==NULL) 3568867Smckusick dunno(); 3578867Smckusick readindex(); 3588867Smckusick if(!tflag || na>nl) 3598867Smckusick na = nl; 36046266Sbostic setvbuf(stdout, (char *)NULL, _IONBF, 0); 3618867Smckusick for(;;) { 3628867Smckusick i = next(); 3638867Smckusick fseek(input,xx[i]+0L,0); 3648867Smckusick z = xx[i+1]-xx[i]; 3658867Smckusick for(j=0;j<z;j++) 3668867Smckusick line[j] = getc(input); 3678867Smckusick segment(line,tmp); 3688867Smckusick if(*tmp[select[0]] == '\0' || *tmp[select[1]] == '\0') { 3698867Smckusick score[i] = 1; 3708867Smckusick continue; 3718867Smckusick } 3728867Smckusick publish(tmp[select[0]]); 3738867Smckusick printf("\n"); 3748867Smckusick for(count=0;;count++) { 3758867Smckusick if(query(response)==0) { 3768867Smckusick publish(tmp[select[1]]); 3778867Smckusick printf("\n"); 3788867Smckusick if(count==0) wrongs++; 3798867Smckusick score[i] = tflag?-1:1; 3808867Smckusick break; 3818867Smckusick } 3828867Smckusick x = cmp(response,tmp[select[1]]); 3838867Smckusick if(x>1) badinfo(); 3848867Smckusick if(x==1) { 3858867Smckusick printf("Right!\n"); 3868867Smckusick if(count==0) rights++; 3878867Smckusick if(++score[i]>=1 && na<nl) 3888867Smckusick na++; 3898867Smckusick break; 3908867Smckusick } 3918867Smckusick printf("What?\n"); 3928867Smckusick if(count==0) wrongs++; 3938867Smckusick score[i] = tflag?-1:1; 3948867Smckusick } 3958867Smckusick guesses += count; 3968867Smckusick } 3978867Smckusick } 3988867Smckusick 3998867Smckusick query(r) 4008867Smckusick char *r; 4018867Smckusick { 4028867Smckusick char *t; 4038867Smckusick for(t=r;;t++) { 4048867Smckusick if(read(0,t,1)==0) 4058867Smckusick done(); 4068867Smckusick if(*t==' '&&(t==r||t[-1]==' ')) 4078867Smckusick t--; 4088867Smckusick if(*t=='\n') { 4098867Smckusick while(t>r&&t[-1]==' ') 4108867Smckusick *--t = '\n'; 4118867Smckusick break; 4128867Smckusick } 4138867Smckusick } 4148867Smckusick *t = 0; 4158867Smckusick return(t-r); 4168867Smckusick } 4178867Smckusick 4188867Smckusick next() 4198867Smckusick { 4208867Smckusick int flag; 4218867Smckusick inc = inc*3125&077777; 4228867Smckusick ptr = (inc>>2)%na; 4238867Smckusick flag = 0; 4248867Smckusick while(score[ptr]>0) 4258867Smckusick if(++ptr>=na) { 4268867Smckusick ptr = 0; 4278867Smckusick if(flag) done(); 4288867Smckusick flag = 1; 4298867Smckusick } 4308867Smckusick return(ptr); 4318867Smckusick } 4328867Smckusick 43346755Sbostic void 4348867Smckusick done() 4358867Smckusick { 43631539Sbostic if (rights + wrongs) { 43731539Sbostic printf("\nRights %d, wrongs %d, ", rights, wrongs); 43831539Sbostic if (guesses) 43931539Sbostic printf("extra guesses %d, ", guesses); 44031539Sbostic printf("score %d%%\n",100 * rights / (rights + wrongs)); 44131539Sbostic } 4428867Smckusick exit(0); 4438867Smckusick } 4448867Smckusick instruct(info) 44546755Sbostic char *info; 4468867Smckusick { 4478867Smckusick char *t; 4488867Smckusick int i, n; 4498867Smckusick printf("Subjects:\n\n"); 4508867Smckusick while(readline()) { 4518867Smckusick printf("-"); 4528867Smckusick n = segment(line,tmp); 4538867Smckusick for(i=1;i<n;i++) { 4548867Smckusick printf(" "); 4558867Smckusick publish(tmp[i]); 4568867Smckusick } 4578867Smckusick printf("\n"); 4588867Smckusick } 4598867Smckusick printf("\n"); 4608867Smckusick input = fopen(info,"r"); 4618867Smckusick if(input==NULL) 4628867Smckusick abort(); 4638867Smckusick readline(); 4648867Smckusick segment(line,tmp); 4658867Smckusick printf("For example,\n"); 4668867Smckusick printf(" quiz "); 4678867Smckusick publish(tmp[1]); 4688867Smckusick printf(" "); 4698867Smckusick publish(tmp[2]); 4708867Smckusick printf("\nasks you a "); 4718867Smckusick publish(tmp[1]); 4728867Smckusick printf(" and you answer the "); 4738867Smckusick publish(tmp[2]); 4748867Smckusick printf("\n quiz "); 4758867Smckusick publish(tmp[2]); 4768867Smckusick printf(" "); 4778867Smckusick publish(tmp[1]); 4788867Smckusick printf("\nworks the other way around\n"); 4798867Smckusick printf("\nType empty line to get correct answer.\n"); 4808867Smckusick exit(0); 4818867Smckusick } 4828867Smckusick 4838867Smckusick badinfo(){ 4848867Smckusick printf("Bad info %s\n",line); 4858867Smckusick } 4868867Smckusick 4878867Smckusick dunno() 4888867Smckusick { 4898867Smckusick printf("I don't know about that\n"); 4908867Smckusick exit(0); 4918867Smckusick } 492