clean up and speed up
authorMart Lubbers <mart@martlubbers.net>
Thu, 25 Aug 2016 14:33:10 +0000 (16:33 +0200)
committerMart Lubbers <mart@martlubbers.net>
Thu, 25 Aug 2016 14:33:10 +0000 (16:33 +0200)
bf.c

diff --git a/bf.c b/bf.c
index 23aa2da..af9f001 100644 (file)
--- a/bf.c
+++ b/bf.c
@@ -1,6 +1,13 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <errno.h>
+
+#define die(s, as...) {fprintf(stderr, s, ## as); return EXIT_FAILURE;}
+#define check_fail(v, s, f) if((v) == f) die("%s(): %s\n", s, strerror(errno))
+#define check_null(v, s) check_fail(v, s, NULL)
+
+#define INITIALBUFSIZE 2
 
 struct nest {
        long pos;
@@ -9,51 +16,37 @@ struct nest {
 
 int main(int argc, char *argv[])
 {
-       size_t offset, stacksize;
+       size_t offset, stacksize, depth;
        char *buf, *ptr;
        struct nest *temp, *stack;
        FILE *in;
 
        if(argc != 2){
-               fprintf(stderr, "Usage: %s PROGRAM\n", argv[0]);
-               return EXIT_FAILURE;
+               die("Usage: %s PROGRAM\n", argv[0]);
        }
    
-       if((buf = malloc(stacksize = 1)) == NULL){
-               perror("malloc");
-               return EXIT_FAILURE;
-       }
-       buf[0] = 0;
+       check_null(in = fopen(argv[1], "r"), "fopen");
+       check_null(buf = calloc(stacksize = INITIALBUFSIZE, 1), "calloc");
        ptr = buf;
 
-       if((in = fopen(argv[1], "r")) == NULL){
-               perror("fopen");
-               return EXIT_FAILURE;
-       }
-
        while(1){
                switch(fgetc(in)){
                        case EOF:
                                free(buf);
+                               check_fail(fclose(in), "fclose", -1);
                                return EXIT_SUCCESS;
                        case '>':
-                               ++ptr;
-                               if(ptr >= buf+stacksize){
+                               if(++ptr >= buf+stacksize){
                                        offset = ptr-buf;
-                                       if((buf = realloc(buf, stacksize *= 2)) == NULL){
-                                               perror("realloc");
-                                               return EXIT_FAILURE;
-                                       }
+                                       check_null(buf = realloc(buf, stacksize *=2), "realloc");
                                        ptr = buf+offset;
                                        memset(ptr, 0, stacksize/2);
                                }
                                break;
                        case '<':
-                               if(ptr == buf){
-                                       fprintf(stderr, "There is no stack position -1...\n");
-                                       return EXIT_FAILURE;
+                               if(ptr-- == buf){
+                                       die("There is no stack position -1\n");
                                }
-                               --ptr;
                                break;
                        case '+':
                                ++*ptr;
@@ -70,30 +63,27 @@ int main(int argc, char *argv[])
                        case '[':
                                if(*ptr){
                                        temp = stack;
-                                       if((stack = malloc(sizeof(struct nest))) == NULL){
-                                               perror("realloc");
-                                               return EXIT_FAILURE;
-                                       }
+                                       check_null(stack = malloc(sizeof(struct nest)), "malloc");
                                        stack->next = temp;
-                                       if((stack->pos = ftell(in)) == -1){
-                                               perror("ftell");
-                                               return EXIT_FAILURE;
-                                       }
+                                       check_fail(stack->pos = ftell(in), "ftell", -1);
                                } else {
-                                       while(fgetc(in) != ']');
+                                       depth = 1;
+                                       while(depth > 0){
+                                               switch(fgetc(in)){
+                                                       case ']':
+                                                               depth--;
+                                                               break;
+                                                       case '[':
+                                                               depth++;
+                                               }
+                                       }
                                }
                                break;
                        case ']':
-                               if(fseek(in, stack->pos-1, SEEK_SET) == -1){
-                                       perror("fseek");
-                                       return EXIT_FAILURE;
-                               }
+                               check_fail(fseek(in, stack->pos-1, SEEK_SET), "fseek", -1);
                                temp = stack;
                                stack = stack->next;
                                free(temp);
-                               break;
-                       default:
-                               break;
                }
        }
 }