23 char *progname
= NULL
;
25 char mem
[MEMSIZE
] = {0};
31 FILE *fd
= ret
? stderr
: stdout
;
32 fprintf (fd
, "usage: %s [-i file] [-h] [-m memory] [-o file] [-v]\n", progname
);
33 fprintf (fd
, " -i : input file\n");
34 fprintf (fd
, " -h : help message\n");
35 fprintf (fd
, " -m : memory [0..0]\n");
36 fprintf (fd
, " -o : output file\n");
37 fprintf (fd
, " -v : verbose level (%d)\n", verbose
);
44 int main (int argc
, char *argv
[])
55 char *pt
= progname
= argv
[0];
57 if ((*pt
== '/') || (*pt
== '\\')) {
64 while ((c
= getopt(argc
, argv
, "i:m:o:hv:")) != EOF
) {
70 for (i
= 0; i
< MEMSIZE
; i
++) {
72 mem
[i
] = strtol (optarg
, &optarg
, 10);
73 VERBOSE (DEBUG
, fprintf (stderr
, "%s: mem[%d] = %d\n", progname
, i
, mem
[i
]));
77 VERBOSE (WARNING
, fprintf (stderr
, "%s: too many memory values\n", progname
));
85 verbose
= atoi (optarg
);
89 return usage (c
!= 'h');
92 if (argc
- optind
!= 0) {
93 VERBOSE (ERROR
, fprintf (stderr
, "%s: invalid option -- %s\n", progname
, argv
[optind
]));
97 /* check input file */
99 fid
= fopen (input
, "r");
101 VERBOSE (ERROR
, fprintf (stderr
, "%s: can't open file '%s' for reading\n", progname
, input
));
108 /* read input file */
109 while (!feof (fid
)) {
110 buffer
= (char *) realloc (buffer
, size
+ BUFSIZE
);
111 if (buffer
== NULL
) {
112 VERBOSE (ERROR
, fprintf (stderr
, "%s: can't allocate memory\n", progname
));
115 memset (buffer
+ size
, 0, BUFSIZE
);
116 n
= fread (buffer
+ size
, 1, BUFSIZE
, fid
);
118 VERBOSE (ERROR
, fprintf (stderr
, "%s: can't read data from file '%s'\n", progname
, input
));
124 /* close input file */
126 VERBOSE (DEBUG
, fprintf (stderr
, "%s: read %d bytes\n", progname
, size
+ n
- BUFSIZE
));
128 /* check output file */
130 fid
= fopen (output
, "w");
132 VERBOSE (ERROR
, fprintf (stderr
, "%s: can't open file '%s' for writing\n", progname
, output
));
140 int rc
= process (buffer
, size
, fid
);
141 VERBOSE (INFO
, fprintf (stdout
, "\nmemory:"); int _i
; for (_i
= 0; _i
< MEMSIZE
; _i
++) fprintf (stdout
," %d", mem
[_i
]); fprintf (stdout
,"\n"));
143 /* close output file */
150 int process (char *buffer
, int nb
, FILE *out
) {
153 for (i
= 0; (i
< nb
) && (buffer
[i
] != 0); i
++) {
155 VERBOSE (DEBUG
, fprintf (stderr
, "%s: read '%c' (%u)\n", progname
, buffer
[i
], buffer
[i
]));
157 case '>': /* increase pointer */
160 case '<': /* decrease pointer */
163 case '+': /* increase pointer value */
164 if ((p
>= 0) && (p
< MEMSIZE
)) {
167 VERBOSE (ERROR
, fprintf (stderr
, "%s: invalid address (%d)\n", progname
, p
));
171 case '-': /* decrease pointer value */
172 if ((p
>= 0) && (p
< MEMSIZE
)) {
175 VERBOSE (ERROR
, fprintf (stderr
, "%s: invalid address (%d)\n", progname
, p
));
179 case '.': /* output pointer value */
180 if ((p
>= 0) && (p
< MEMSIZE
)) {
181 fprintf (out
, "%c", mem
[p
]);
183 VERBOSE (ERROR
, fprintf (stderr
, "%s: invalid address (%d)\n", progname
, p
));
187 case ',': /* read a byte and store it in memory */
188 if ((p
>= 0) && (p
< MEMSIZE
)) {
189 mem
[p
] = buffer
[++i
];
191 VERBOSE (ERROR
, fprintf (stderr
, "%s: invalid address (%d)\n", progname
, p
));
195 case '[': /* jump to right bracket if pointer is set to 0 */
198 while ((++i
< nb
) && (bracket
> 0)) {
199 bracket
+= (buffer
[i
] == '[') ? +1 : (buffer
[i
] == ']') ? -1 :0;
202 VERBOSE (ERROR
, fprintf (stderr
, "%s: brace not closed\n", progname
));
206 return process (buffer
+ i
+ 1, nb
- i
- 1, out
);
209 case ']': /* jump to left bracket if pointer is different to 0 */
218 VERBOSE (WARNING
, fprintf (stderr
, "%s: can't understand '%c'\n", progname
, buffer
[i
]));
221 //VERBOSE (DEBUG, int _i; fprintf (stderr, "%s: p: %d mem:", progname, p); for (_i = 0; _i < MEMSIZE; _i++) fprintf (stderr, " %d", mem[_i]); fprintf (stderr, "\n"));
229 // test: bf.exe -h | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
230 // test: bf.exe -_ 2> /dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }'
231 // test: bf.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
232 // test: echo '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.' | bf.exe -v1 | grep -q "Hello World!"
233 // test: echo '++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>++++++++++++++.>+++++++++++++++++.<<++.>+++++++++++++.>--.<<.>+++.+.--.>----.++++++.+.<++.>----.++.<<.>>+.-------.<<.>>++.<.>+++++.<<.>-.+.<.>---.>---.<-.++++++++.>----.<---.>+++++++.<---.++++++++.' | bf.exe -v1 | grep -q "Tu as decouvert un peu de brainfuck"
234 // test: echo ',4>++++++[<-------->-],3[<+>-]<.' | bf.exe -v1 | grep -q 7
236 // test: echo ',3>,2>>++++++++++++++++[-<+++<---<--->>>]<<[<[>>+>+<<<-]>>>[<<<+>>>-]<<-]>.' | bf.exe -v1 | grep -q 6
237 // test: echo ',3>,2[->>+<<]+<[->>>[>>>>>+<<<<<->+<<]<[>]>>>>>[-<<->>>>>>>]<[>]<<<<<<]>[>>>>->]<<<<<<[-]>[-]>>[-]>.' | bf.exe -v1 | grep -q 3
239 /* vim: set ts=4 sw=4 et: */