clean up code
[bf.git] / bf.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4
5 struct nest {
6 long pos;
7 struct nest *next;
8 };
9
10 int main(int argc, char *argv[])
11 {
12 size_t offset, stacksize;
13 char *buf, *ptr;
14 struct nest *temp, *stack;
15 FILE *in;
16
17 if(argc != 2){
18 fprintf(stderr, "Usage: %s PROGRAM\n", argv[0]);
19 return EXIT_FAILURE;
20 }
21
22 if((buf = malloc(stacksize = 1)) == NULL){
23 perror("malloc");
24 return EXIT_FAILURE;
25 }
26 buf[0] = 0;
27 ptr = buf;
28
29 if((in = fopen(argv[1], "r")) == NULL){
30 perror("fopen");
31 return EXIT_FAILURE;
32 }
33
34 while(1){
35 switch(fgetc(in)){
36 case EOF:
37 free(buf);
38 return EXIT_SUCCESS;
39 case '>':
40 ++ptr;
41 if(ptr >= buf+stacksize){
42 offset = ptr-buf;
43 if((buf = realloc(buf, stacksize *= 2)) == NULL){
44 perror("realloc");
45 return EXIT_FAILURE;
46 }
47 ptr = buf+offset;
48 memset(ptr, 0, stacksize/2);
49 }
50 break;
51 case '<':
52 if(ptr == buf){
53 fprintf(stderr, "There is no stack position -1...\n");
54 return EXIT_FAILURE;
55 }
56 --ptr;
57 break;
58 case '+':
59 ++*ptr;
60 break;
61 case '-':
62 --*ptr;
63 break;
64 case '.':
65 putchar(*ptr);
66 break;
67 case ',':
68 *ptr = getchar();
69 break;
70 case '[':
71 if(*ptr){
72 temp = stack;
73 if((stack = malloc(sizeof(struct nest))) == NULL){
74 perror("realloc");
75 return EXIT_FAILURE;
76 }
77 stack->next = temp;
78 if((stack->pos = ftell(in)) == -1){
79 perror("ftell");
80 return EXIT_FAILURE;
81 }
82 } else {
83 while(fgetc(in) != ']');
84 }
85 break;
86 case ']':
87 if(fseek(in, stack->pos-1, SEEK_SET) == -1){
88 perror("fseek");
89 return EXIT_FAILURE;
90 }
91 temp = stack;
92 stack = stack->next;
93 free(temp);
94 break;
95 default:
96 break;
97 }
98 }
99 }