996
|
1 /*
|
|
2 * a crude implementation of a trigger interpreter.
|
|
3 *
|
|
4 * Author: Bertram Felgenhauer (aka int-e), 2005-07-26,27
|
|
5 */
|
|
6 #include <stdio.h>
|
|
7 #include <stdlib.h>
|
|
8 #include <time.h>
|
|
9
|
|
10 unsigned char prog[1048576];
|
|
11 unsigned char trigger[256];
|
|
12
|
|
13 int main(int argc, char **argv)
|
|
14 {
|
|
15 int pc = 0, max, bits=0, input=0;
|
|
16 FILE *in;
|
|
17
|
|
18 srand(time(NULL));
|
|
19
|
|
20 if (argc<2) {
|
|
21 fprintf(stderr, "Usage: %s program [input]\n", argv[0]);
|
|
22 exit(1);
|
|
23 }
|
|
24 in = fopen(argv[1], "r");
|
|
25 if (!in) {
|
|
26 fprintf(stderr, "Could not open '%s'.", argv[1]);
|
|
27 exit(1);
|
|
28 }
|
|
29 max = fread(prog, 1, sizeof(prog), in);
|
|
30 fclose(in);
|
|
31 in = NULL;
|
|
32 input = EOF;
|
|
33 if (argc>2) {
|
|
34 in = fopen(argv[2], "r");
|
|
35 }
|
|
36 if (max == sizeof(prog)) {
|
|
37 fprintf(stderr, "Warning: only the first %d bytes of the program "
|
|
38 "were read.", sizeof(prog));
|
|
39 }
|
|
40 while (pc<max) {
|
|
41 if (pc<max-1 && prog[pc] == prog[pc+1]) {
|
|
42 if (pc<max-2 && prog[pc] == prog[pc+2]) {
|
|
43 if (pc<max-3 && prog[pc] == prog[pc+3]) {
|
|
44 /* AAAA pattern -> input */
|
|
45 if (!bits) {
|
|
46 if (in)
|
|
47 input = getc(in);
|
|
48 bits = 8;
|
|
49 }
|
|
50 if (input != EOF) {
|
|
51 bits--;
|
|
52 trigger[prog[pc]] = !!(input & (1<<bits));
|
|
53 }
|
|
54 pc += 4;
|
|
55 } else {
|
|
56 /* AAA pattern -> output */
|
|
57 putchar(prog[pc]);
|
|
58 pc += 3;
|
|
59 }
|
|
60 } else {
|
|
61 /* AAB pattern -> conditional jump */
|
|
62 if (pc>max-3) {
|
|
63 /* just AA at end of program -- exit silently */
|
|
64 return 0;
|
|
65 }
|
|
66 if (trigger[prog[pc]]) {
|
|
67 /* jump */
|
|
68 int nxt = pc+3;
|
|
69 int prv = pc-1;
|
|
70 for ( ; ; nxt++, prv--) {
|
|
71 int l = prv >= 0 && prog[pc+2] == prog[prv];
|
|
72 int r = nxt < max && prog[pc+2] == prog[nxt];
|
|
73
|
|
74 if (l && (!r || rand()/(RAND_MAX/2))) {
|
|
75 pc = prv;
|
|
76 break;
|
|
77 } else if (r) {
|
|
78 pc = nxt;
|
|
79 break;
|
|
80 }
|
|
81 if (nxt >= max && prv < 0) {
|
|
82 /* label not found */
|
|
83 pc += 3;
|
|
84 break;
|
|
85 }
|
|
86 }
|
|
87 } else {
|
|
88 /* skip */
|
|
89 pc += 3;
|
|
90 }
|
|
91 }
|
|
92 } else {
|
|
93 /* A pattern -> toggle */
|
|
94 trigger[prog[pc]] ^= 1;
|
|
95 pc++;
|
|
96 }
|
|
97 }
|
|
98 return 0;
|
|
99 }
|