fix memory bug and free the buffer when finished
[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 = 1;
13 char *b = malloc(stacksize);
14 b[0] = 0;
15 char *ptr = b;
16 struct nest *t, *callstack = NULL;
17 FILE *in;
18
19 if(argc != 2){
20 fprintf(stderr, "Usage: %s PROGRAM\n", argv[0]);
21 return EXIT_FAILURE;
22 }
23
24 if((in = fopen(argv[1], "r")) == NULL){
25 perror("fopen");
26 return EXIT_FAILURE;
27 }
28
29 while(1){
30 switch(fgetc(in)){
31 case EOF:
32 free(b);
33 return EXIT_SUCCESS;
34 case '>':
35 ++ptr;
36 if(ptr >= b+stacksize){
37 offset = ptr-b;
38 b = realloc(b, stacksize *= 2);
39 ptr = b+offset;
40 memset(ptr, 0, stacksize/2);
41 }
42 break;
43 case '<':
44 if(ptr == b){
45 fprintf(stderr, "There is no stack position -1...\n");
46 return EXIT_FAILURE;
47 }
48 --ptr;
49 break;
50 case '+':
51 ++*ptr;
52 break;
53 case '-':
54 --*ptr;
55 break;
56 case '.':
57 putchar(*ptr);
58 break;
59 case ',':
60 *ptr = getchar();
61 break;
62 case '[':
63 if(*ptr){
64 t = callstack;
65 callstack = malloc(sizeof(struct nest));
66 callstack->next = t;
67 if((callstack->pos = ftell(in)) == -1){
68 perror("ftell");
69 return EXIT_FAILURE;
70 }
71 } else {
72 while(fgetc(in) != ']');
73 }
74 break;
75 case ']':
76 if(fseek(in, callstack->pos-1, SEEK_SET) == -1){
77 perror("fseek");
78 return EXIT_FAILURE;
79 }
80 t = callstack;
81 callstack = callstack->next;
82 free(t);
83 break;
84 default:
85 break;
86 }
87 }
88 }