#include "stdio.h" #include "signal.h" #include "lrnref" char last[100]; char logf[100]; char subdir[100]; extern char * ctime(); copy(prompt, fin) FILE *fin; { FILE *fout, *f; char s[100], t[100], s1[100], *r, *tod; char nm[30]; int *p, tv[2]; extern int intrpt(), *action(); extern char *wordb(); int nmatch = 0; if (subdir[0]==0) sprintf(subdir, "../../%s", sname); for (;;) { if (pgets(s, prompt, fin) == 0) if (fin == stdin) { /* fprintf(stderr, "Don't type control-D\n"); */ /* this didn't work out very well */ continue; } else break; trim(s); /* change the sequence %s to lesson directory */ /* if needed */ for (r = s; *r; r++) if (*r == '%') { sprintf(s1, s, subdir, subdir, subdir); strcpy(s, s1); break; } r = wordb(s, t); p = action(t); if (*p == ONCE) { /* some actions done only once per script */ if (wrong) { /* we are on 2nd time */ scopy(fin, NULL); continue; } strcpy(s, r); r = wordb(s, t); p = action(t); } if (p == 0) { if (comfile >= 0) { write(comfile, s, strlen(s)); write(comfile, "\n", 1); } else { signal(SIGINT, SIG_IGN); status = mysys(s); signal(SIGINT, intrpt); } if (incopy) { fprintf(incopy, "%s\n", s); strcpy(last, s); } continue; } switch (*p) { case READY: if (incopy && r) { fprintf(incopy, "%s\n", r); strcpy(last, r); } return; case PRINT: if (wrong) scopy(fin, NULL); /* don't repeat message */ else if (r) list(r); else scopy(fin, stdout); break; case NOP: break; case MATCH: if (nmatch > 0) /* we have already passed */ scopy(fin, NULL); else if ((status = strcmp(r, last)) == 0) { /* did we pass this time? */ nmatch++; scopy(fin, stdout); } else scopy(fin, NULL); break; case BAD: if (strcmp(r, last) == 0) { scopy(fin, stdout); } else scopy(fin, NULL); break; case SUCCEED: scopy(fin, (status == 0) ? stdout : NULL); break; case FAIL: scopy(fin, (status != 0) ? stdout : NULL); break; case CREATE: fout = fopen(r, "w"); scopy(fin, fout); fclose(fout); break; case CMP: status = cmp(r); /* contains two file names */ break; case MV: sprintf(nm, "%s/L%s.%s", subdir, todo, r); fcopy(r, nm); break; case USER: case NEXT: more = 1; return; case COPYIN: incopy = fopen(".copy", "w"); break; case UNCOPIN: fclose(incopy); incopy = NULL; break; case COPYOUT: maktee(); break; case UNCOPOUT: untee(); break; case PIPE: comfile = makpipe(); break; case UNPIPE: close(comfile); wait(0); comfile = -1; break; case YES: case NO: if (incopy) { fprintf(incopy, "%s\n", s); strcpy(last, s); } return; case WHERE: printf("You are in lesson %s\n", todo); fflush(stdout); break; case BYE: more=0; return; case CHDIR: printf("cd not allowed\n"); fflush(stdout); break; case LEARN: printf("You are already in learn.\n"); fflush(stdout); break; case LOG: if (!logging) break; if (logf[0] == 0) sprintf(logf, "%s/log/%s", direct, sname); f = fopen( (r? r : logf), "a"); if (f == NULL) break; time(tv); tod = ctime(tv); tod[24] = 0; fprintf(f, "%s L%-6s %s %2d %s\n", tod, todo, status? "fail" : "pass", speed, pwline); fclose(f); break; } } return; } pgets(s, prompt, f) FILE *f; { if (prompt) { if (comfile < 0) printf("$ "); fflush(stdout); } if (fgets(s, 100,f)) return(1); else return(0); } trim(s) char *s; { while (*s) s++; if (*--s == '\n') *s=0; } scopy(fi, fo) /* copy fi to fo until a line with # */ FILE *fi, *fo; { int c; while ((c = getc(fi)) != '#' && c != EOF) { do { if (fo != NULL) putc(c, fo); if (c == '\n') break; } while ((c = getc(fi)) != EOF); } if (c == '#') ungetc(c, fi); fflush(fo); } cmp(r) /* compare two files for status */ char *r; { char *s; FILE *f1, *f2; int c1, c2, stat; for (s = r; *s != ' ' && *s != '\0'; s++) ; *s++ = 0; /* r contains file 1 */ while (*s == ' ') s++; f1 = fopen(r, "r"); f2 = fopen(s, "r"); if (f1 == NULL || f2 == NULL) return(1); /* failure */ stat = 0; for (;;) { c1 = getc(f1); c2 = getc(f2); if (c1 != c2) { stat = 1; break; } if (c1 == EOF || c2 == EOF) break; } fclose(f1); fclose(f2); return(stat); } char * wordb(s, t) /* in s, t is prefix; return tail */ char *s, *t; { int c; while (c = *s++) { if (c == ' ' || c == '\t') break; *t++ = c; } *t = 0; while (*s == ' ' || *s == '\t') s++; return(c ? s : NULL); }