4597949 [rkeene@sledge /home/rkeene/projects/bf/sf]$ cat -n sfc.c
  1 #include <stdlib.h>
  2 #include <unistd.h>
  3 #include <string.h>
  4 #include <stdio.h>
  5 #include <math.h>
  6 
  7 int main(int argc, char **argv) {
  8     char buf[2048], *buf_p, *tmp, *val;
  9     char *outbuf = NULL, *outbuf_p = NULL;
 10     char *filename;
 11     char *sect = NULL, *cmd;
 12     FILE *fp;
 13     long long arg;
 14     long long code_size;
 15     size_t buflen;
 16     int cs_byte = 0;
 17     int invalid_data = 0;
 18     int retval = 0;
 19     int linenumber = 0;
 20     size_t i, outbuf_len, highest_outbuf, iv_dest, iv_loc;
 21     int intnum;
 22 
 23     if (argc != 2) {
 24         printf("Usage: sfc <filename>\n");
 25         return(1);
 26     }
 27 
 28     filename = argv[1];
 29     fp = fopen(filename, "r");
 30 
 31     if (!fp) {
 32         fprintf(stderr, "Error opening file (%s).\n", filename);
 33         perror("fopen");
 34         return(1);
 35     }
 36 
 37     while (1) {
 38         if (invalid_data) {
 39             fprintf(stderr, "Error compiling %s (at line %i), aborting.\n", filename, linenumber);
 40             break;
 41         }
 42 
 43         fgets(buf, sizeof(buf), fp);
 44         if (feof(fp)) {
 45             break;
 46         }
 47 
 48         buf[sizeof(buf) - 1] = '\0';
 49 
 50         linenumber++;
 51 
 52         buf_p = buf;
 53 
 54         /* Trim off any leading spaces */
 55         while (*buf_p == ' ' || *buf_p == '\t') {
 56             buf_p++;
 57         }
 58 
 59         /* COmments indicate end of line/string. */
 60         tmp = strchr(buf_p, '#');
 61         if (tmp) {
 62             *tmp = '\0';
 63         }
 64 
 65         /* Determine the length of the line. */
 66         buflen = strlen(buf_p);
 67         if (buflen < 1) {
 68             continue;
 69         }
 70 
 71         /* Trim off pesky newline charectars. */
 72         if (buf_p[buflen - 1] == '\n') {
 73             buf_p[buflen - 1] = '\0';
 74             buflen--;
 75         }
 76 
 77         /* Skip blank lines */
 78         if (buflen == 0) {
 79             continue;
 80         }
 81 
 82         if (*buf_p == '[') {
 83             /* Process sections */
 84 
 85             if (sect) {
 86                 free(sect);
 87             }
 88 
 89             tmp = buf_p + 1;
 90             tmp[strlen(tmp) - 1] = '\0';
 91             sect = strdup(tmp);
 92 
 93             if (strcmp(sect, "init") == 0) {
 94             } else if (strcmp(sect, "main") == 0) {
 95                 outbuf_p = outbuf + 1;
 96             } else if (strcmp(sect, "data") == 0) {
 97                 outbuf_p = outbuf + 1 + code_size + 1024;
 98             } else {
 99                 if (strncmp(sect, "int", 3) == 0) {
100                     intnum = atoi(sect + 3);
101                     iv_dest = outbuf_p - outbuf;
102                     iv_loc = 1 + code_size + (4 * intnum);
103 
104                     outbuf[iv_loc] = (iv_dest >> 24) & 0xff;
105                     outbuf[iv_loc + 1] = (iv_dest >> 16) & 0xff;
106                     outbuf[iv_loc + 2] = (iv_dest >> 8) & 0xff;
107                     outbuf[iv_loc + 3] = iv_dest & 0xff;
108                 } else {
109                     invalid_data = 1;
110                     continue;
111                 }
112             }
113 
114             continue;
115         } else {
116             if (!sect) {
117                 invalid_data = 1;
118                 continue;
119             }
120 
121 
122             if (strcmp(sect, "init") == 0) {
123                 cmd = buf_p;
124                 tmp = strpbrk(cmd, " \t");
125                 if (tmp) {
126                     *tmp = '\0';
127                     tmp++;
128                     arg = strtoll(tmp, NULL, 0);
129                 } else {
130                     arg = -1;
131                 }
132 
133                 /* Process directives */
134                 if (strcmp(cmd, "code_size") == 0) {
135                     cs_byte = log(arg / 1024) / log(2) + 0.999;
136 
137                     if (cs_byte <= 0 || cs_byte >= 256) {
138                         invalid_data = 1;
139                         continue;
140                     }
141 
142                     code_size = pow(2, cs_byte) * 1024;
143 
144                     outbuf_len = 1 + code_size + 1024 + (640 * 1024);
145                     outbuf = calloc(outbuf_len, 1);
146                     outbuf_p = outbuf;
147 
148                     if (!outbuf) {
149                         invalid_data = 1;
150                         continue;
151                     }
152 
153                     *outbuf_p = cs_byte; outbuf_p++;
154                 } else {
155                     invalid_data = 1;
156                     continue;
157                 }
158             } else if (strcmp(sect, "data") == 0) {
159                 /* Save direct data */
160 
161                 for (tmp = buf_p; (val = strsep(&tmp, " \t"));) {
162                     arg = strtoll(val, NULL, 16);
163                     *outbuf_p = arg; outbuf_p++;
164                 }
165             } else {
166                 cmd = buf_p;
167                 tmp = strpbrk(cmd, " \t");
168                 if (tmp) {
169                     *tmp = '\0';
170                     tmp++;
171                     arg = strtoll(tmp, NULL, 0);
172                 } else {
173                     arg = -1;
174                 }
175 
176                 /*
177                  * The "init" section must come before
178                  * anything else, abandon otherwise.
179                  */
180                 if (!outbuf) {
181                     invalid_data = 1;
182                     continue;
183                 }
184 
185                 /* Process commands */
186                 if (strcmp(cmd, "add") == 0) {
187                     if (arg == -1) {
188                         arg = 1;
189                     }
190                     *outbuf_p = '+'; outbuf_p++;
191                     *outbuf_p = arg; outbuf_p++;
192                 } else if (strcmp(cmd, "sub") == 0) {
193                     if (arg == -1) {
194                         arg = 1;
195                     }
196 
197                     *outbuf_p = '-'; outbuf_p++;
198                     *outbuf_p = arg; outbuf_p++;
199                 } else if (strcmp(cmd, "left") == 0) {
200                     if (arg == -1) {
201                         arg = 1;
202                     }
203 
204                     *outbuf_p = '<'; outbuf_p++;
205                     *outbuf_p = arg; outbuf_p++;
206                 } else if (strcmp(cmd, "right") == 0) {
207                     if (arg == -1) {
208                         arg = 1;
209                     }
210 
211                     *outbuf_p = '>'; outbuf_p++;
212                     *outbuf_p = arg; outbuf_p++;
213                 } else if (strcmp(cmd, "loop_begin") == 0) {
214                     *outbuf_p = '['; outbuf_p++;
215                     *outbuf_p = 0; outbuf_p++;
216                 } else if (strcmp(cmd, "loop_end") == 0) {
217                     *outbuf_p = ']'; outbuf_p++;
218                     *outbuf_p = 0; outbuf_p++;
219                 } else if (strcmp(cmd, "int") == 0) {
220                     if (arg == -1) {
221                         invalid_data = 1;
222                         continue;
223                     }
224 
225                     *outbuf_p = '*'; outbuf_p++;
226                     *outbuf_p = arg; outbuf_p++;
227                 } else if (strcmp(cmd, "ret") == 0) {
228                     *outbuf_p = '!'; outbuf_p++;
229                     *outbuf_p = 0; outbuf_p++;
230                 } else {
231                     invalid_data = 1;
232                     continue;
233                 }
234             }
235         }
236 
237     }
238 
239     fclose(fp);
240 
241     if (!invalid_data) {
242         for (i = outbuf_len; i >= 0; i--) {
243             if (outbuf[i]) {
244                 highest_outbuf = i;
245                 break;
246             }
247         }
248 
249         for (i = 0; i <= highest_outbuf; i++) {
250             write(STDOUT_FILENO, outbuf + i, 1);
251         }
252     } else {
253         retval = 1;
254     }
255 
256     return(retval);
257 }
4597950 [rkeene@sledge /home/rkeene/projects/bf/sf]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2008-07-24 19:49:03