Brainfuck Interpreter in C

A dead simple brainfuck interpreter in C, it was posted here first.

bfi.c:

  1 #include <stdio.h>
  2 #ifndef codesize
  3 #define codesize 30000
  4 #endif
  5 
  6 #define cellsize 30000
  7 
  8 const char *s_name =
  9 "    bfi"
 10 #if codesize != 30000
 11 "%d"
 12 #endif
 13 " - brainf*ck language interpreter 1.0 build - "__DATE__"\n"
 14 #if codesize != 30000
 15 "       **** Special version with %d code array in size ****\n"
 16 #endif
 17 "           ----- copyright (c) 2005 by 8pm@baidu.cbar\n";
 18 const char *s_license =
 19 " This program is free software; you can redistribute it and/or modify\n"
 20 " it under the terms of the GNU General Public License as published by\n"
 21 " the Free Software Foundation; either version 2 of the License, or\n"
 22 " (at your option) any later version.\n"
 23 "\n"
 24 " This program is distributed in the hope that it will be useful,\n"
 25 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
 26 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
 27 " GNU General Public License for more details.\n"
 28 "\n"
 29 " You should have received a copy of the GNU General Public License\n"
 30 " along with this program; if not, write to the\n"
 31 " Free Software Foundation, Inc.,\n"
 32 " 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"
 33 "\n"
 34 " usage: $ %s [source code]\n"
 35 "\n";
 36 
 37 const char *s_err_open =
 38 "[] error: unable to open file %s\n";
 39 const char *s_err_ovfl =
 40 "[] error: unable to run, program too large.\n";
 41 const char *s_err_unmt =
 42 "[] error: unmatch %c in source file.\n";
 43 
 44 char cell[cellsize], code[codesize];
 45 int n = 0, ip = 0, dp = 0;
 46 
 47 int load_program(FILE *fp, const int size)
 48 {
 49         int br = 0, p = 0;
 50         while (!feof(fp))
 51                 switch (n = fgetc(fp)) {
 52                 case '[': br += 2;
 53                 case ']': --br;
 54                 case '>':
 55                 case '<':
 56                 case '+':
 57                 case '-':
 58                 case '.':
 59                 case ',':
 60                         code[p++] = n;
 61                         if (p == size-1)
 62                                 return -1; /* program too large */
 63                 }
 64         code[p] = '\0';
 65         return br ? (br > 0) ? -2 /* unmatch [ */ : -3 /* unmatch ] */ : 0;
 66 }
 67 
 68 int main(int argc, char **argv)
 69 {
 70         FILE *fp = NULL;
 71         if (1 == argc) {
 72 #if codesize != 30000
 73                 fprintf(stderr, s_name, codesize/1000, codesize);
 74 #else
 75                 fprintf(stderr, s_name);
 76 #endif
 77                 fprintf(stderr, s_license, argv[0]);
 78                 return 0;
 79         }
 80         if (NULL == (fp=fopen(argv[1],"r"))) {
 81                 fprintf(stderr, s_err_open, argv[1]);
 82                 return -1;
 83         }
 84         n = load_program(fp, codesize);
 85         if (fp != stdin) fclose(fp);
 86         switch (n) {
 87         case -1: /* program too large */
 88                 fprintf(stderr, s_err_ovfl);
 89                 return -1;
 90         case -2: /* unmatch [ */
 91                 fprintf(stderr, s_err_unmt, '[');
 92                 return -2;
 93         case -3: /* unmatch ] */
 94                 fprintf(stderr, s_err_unmt, ']');
 95                 return -3;
 96         }
 97         n = ip = dp = 0;
 98         do {
 99                 n = 1;
100                 switch (code[ip]) {
101                 case '>': ++dp == cellsize ? dp = 0: 0; break;
102                 case '<': --dp == -1 ? dp += cellsize: 0; break;
103                 case '+': cell[dp]++; break;
104                 case '-': cell[dp]--; break;
105                 case '.': putchar(cell[dp]); fflush(stdout); break;
106                 case ',': cell[dp] = getchar(); break;
107                 case '[':
108                         if (!cell[dp])
109                                 while (n)
110                                         switch (code[++ip]) {
111                                         case '[': n++; break;
112                                         case ']': n--; break;
113                                         }
114                         break;
115                 case ']':
116                         if (cell[dp])
117                                 while (n)
118                                         switch (code[--ip]) {
119                                         case ']': n++; break;
120                                         case '[': n--; break;
121                                         }
122                         break;
123                 }
124         } while (code[++ip]);
125         return 0;
126 }