1 /*
2 * cod - T2
3 *
4 * Printf working? Float arrays? dynamic arrays?
5 */
6 #include "config.h"
7 #include "data_funcs.h"
8 #include "cod.h"
9 #include <stdlib.h>
10 #ifdef HAVE_MALLOC_H
11 #include "malloc.h"
12 #endif
13 #include "assert.h"
14 #include <stdio.h>
15 #include <string.h>
16
17 int
main(int argc,char ** argv)18 main(int argc, char **argv)
19 {
20 int test_num = 0;
21 int run_only = -1;
22 char *read_file = NULL;
23 char *write_file = NULL;
24 int verbose = 0;
25 while (argc > 1) {
26 if (strcmp(argv[1], "-v") == 0) {
27 verbose++;
28 } else if (strcmp(argv[1], "-w") == 0) {
29 if (argc <= 1) {
30 printf("Need argument to \"-w\"\n");
31 } else {
32 write_file = strdup(argv[2]);
33 }
34 argc--; argv++;
35 } else if (strcmp(argv[1], "-r") == 0) {
36 if (argc <= 1) {
37 printf("Need argument to \"-r\"\n");
38 } else {
39 read_file = strdup(argv[2]);
40 }
41 argc--; argv++;
42 } else if (strcmp(argv[1], "-o") == 0) {
43 sscanf(argv[2], "%d", &run_only);
44 argc--; argv++;
45 }
46 argc--; argv++;
47 }
48 if ((run_only == -1) || (run_only == test_num)) {
49 /* 0 */
50 static char extern_string[] = "int printf(string format, ...);";
51
52 static cod_extern_entry externs[] =
53 {
54 {"printf", (void*)(long)printf},
55 {(void*)0, (void*)0}
56 };
57 /* test external call */
58 static char code[] = "{\
59 printf(\"values are is %d, %g, %s\\n\", i, d, s);\
60 }";
61
62 cod_parse_context context = new_cod_parse_context();
63
64 cod_code gen_code;
65 void (*func)(int, double, char*);
66
67 cod_assoc_externs(context, externs);
68 cod_parse_for_context(extern_string, context);
69
70 cod_subroutine_declaration("void proc(int i, double d, string s)",
71 context);
72 gen_code = cod_code_gen(code, context);
73 func = (void (*)(int, double, char*))(long)gen_code->func;
74 printf("Expect -> \"values are is %d, %g, %s\"\n", 5, 3.14159, "hello!");
75 (func)(5, (double)3.14159, "hello!");
76
77 cod_code_free(gen_code);
78 cod_free_parse_context(context);
79 }
80 test_num++;
81 if ((run_only == -1) || (run_only == test_num)) {
82 /* 1 */
83 typedef struct test {
84 int count;
85 double *vals;
86 } test_struct, *test_struct_p;
87
88 static char extern_string[] = "int printf(string format, ...);";
89
90 static cod_extern_entry externs[] =
91 {
92 {"printf", (void*)(long)printf},
93 {(void*)0, (void*)0}
94 };
95 static char code[] = "{\
96 int i;\n\
97 double sum = 0.0;\n\
98 for(i = 0; i<input.count; i= i+1) {\n\
99 sum = sum + input.vals[i];\n\
100 }\n\
101 return sum;\n\
102 }";
103
104 static FMField input_field_list[] =
105 {
106 {"count", "integer", sizeof(int),
107 FMOffset(test_struct_p, count)},
108 {"vals", "float[count]", sizeof(double),
109 FMOffset(test_struct_p, vals)},
110 {(void*)0, (void*)0, 0, 0}
111 };
112
113 cod_parse_context context = new_cod_parse_context();
114 int i;
115 test_struct tmp;
116 test_struct *param = &tmp;
117 cod_code gen_code;
118 double (*func)(test_struct_p);
119
120 cod_assoc_externs(context, externs);
121 cod_parse_for_context(extern_string, context);
122 if (read_file) {
123 FMFieldList fields = NULL;
124 FMContext c = create_local_FMcontext();
125 char *buf = read_buffer(c, read_file, test_num);
126 param = (test_struct*)buf;
127 cod_add_encoded_param("input", buf, 0, c, context);
128 cod_set_return_type("double", context);
129 } else {
130 cod_add_simple_struct_type("input_type", input_field_list, context);
131 cod_subroutine_declaration("double proc(input_type *input)", context);
132 }
133 tmp.count = 10;
134 tmp.vals = (double*) malloc(tmp.count * sizeof(double));
135 for(i=0; i< tmp.count; i++) {
136 tmp.vals[i] = i + 0.1;
137 }
138
139 if (write_file) {
140 FMStructDescRec formats[] = {
141 {"struct", input_field_list, sizeof(tmp), NULL},
142 {NULL, NULL, 0, NULL}};
143 write_buffer(write_file, &formats[0], &tmp, test_num);
144 }
145 gen_code = cod_code_gen(code, context);
146 func = (double (*)(test_struct_p))(long) gen_code->func;
147 assert((func)(param) == 46.00);
148 free(tmp.vals);
149 cod_code_free(gen_code);
150 cod_free_parse_context(context);
151 }
152 test_num++;
153 if ((run_only == -1) || (run_only == test_num)) {
154 /* 2 */
155 typedef struct test {
156 int count;
157 int *vals;
158 } test_struct, *test_struct_p;
159
160 static char extern_string[] = "int printf(string format, ...);";
161
162 static cod_extern_entry externs[] =
163 {
164 {"printf", (void*)(long)printf},
165 {(void*)0, (void*)0}
166 };
167 static char code[] = "{\
168 int i;\n\
169 double sum = 0.0;\n\
170 for(i = 0; i<input.count; i= i+1) {\n\
171 sum = sum + input.vals[i];\n\
172 }\n\
173 return sum;\n\
174 /* comment */\n\
175 }";
176
177 static FMField input_field_list[] =
178 {
179 {"count", "integer", sizeof(int),
180 FMOffset(test_struct_p, count)},
181 {"vals", "integer[count]", sizeof(int),
182 FMOffset(test_struct_p, vals)},
183 {(void*)0, (void*)0, 0, 0}
184 };
185
186 cod_parse_context context = new_cod_parse_context();
187 int i;
188 test_struct tmp;
189 test_struct *param = &tmp;
190 cod_code gen_code;
191 int (*func)(test_struct_p);
192
193 cod_assoc_externs(context, externs);
194 cod_parse_for_context(extern_string, context);
195 if (read_file) {
196 FMFieldList fields = NULL;
197 FMContext c = create_local_FMcontext();
198 char *buf = read_buffer(c, read_file, test_num);
199 param = (test_struct*)buf;
200 cod_add_encoded_param("input", buf, 0, c, context);
201 cod_set_return_type("int", context);
202 } else {
203 cod_add_simple_struct_type("input_type", input_field_list, context);
204 cod_subroutine_declaration("int proc(input_type *input)", context);
205 }
206 tmp.count = 10;
207 tmp.vals = (int*) malloc(tmp.count * sizeof(int));
208 for(i=0; i< tmp.count; i++) {
209 tmp.vals[i] = i + 10;
210 }
211
212 if (write_file) {
213 FMStructDescRec formats[] =
214 {{"struct", input_field_list, sizeof(tmp), NULL},
215 {NULL, NULL, 0, NULL}};
216 write_buffer(write_file, &formats[0], &tmp, test_num);
217 }
218 gen_code = cod_code_gen(code, context);
219 func = (int (*)(test_struct_p))(long) gen_code->func;
220 assert((func)(param) == 145);
221 free(tmp.vals);
222 cod_code_free(gen_code);
223 cod_free_parse_context(context);
224 }
225 test_num++;
226 if ((run_only == -1) || (run_only == test_num)) {
227 /* 3 */
228 typedef struct test {
229 double *vals;
230 } test_struct, *test_struct_p;
231
232 static char extern_string[] = "int printf(string format, ...);";
233
234 static cod_extern_entry externs[] =
235 {
236 {"printf", (void*)(long)printf},
237 {(void*)0, (void*)0}
238 };
239 static char code[] = "{\
240 int i;\n\
241 double sum = 0.0;\n\
242 int count = 10;\n\
243 for(i = 0; i<count; i= i+1) {\n\
244 sum = sum + input.vals[i];\n\
245 }\n\
246 return sum;\n\
247 }";
248
249 static FMField input_field_list[] =
250 {
251 {"vals", "*float[10]", sizeof(double),
252 FMOffset(test_struct_p, vals)},
253 {(void*)0, (void*)0, 0, 0}
254 };
255
256 cod_parse_context context = new_cod_parse_context();
257 int i, count = 10;
258 test_struct tmp;
259 test_struct *param = &tmp;
260 cod_code gen_code;
261 double (*func)(test_struct_p);
262
263 cod_assoc_externs(context, externs);
264 cod_parse_for_context(extern_string, context);
265 if (read_file) {
266 FMFieldList fields = NULL;
267 FMContext c = create_local_FMcontext();
268 char *buf = read_buffer(c, read_file, test_num);
269 param = (test_struct*)buf;
270 cod_add_encoded_param("input", buf, 0, c, context);
271 cod_set_return_type("double", context);
272 } else {
273 cod_add_simple_struct_type("input_type", input_field_list, context);
274 cod_subroutine_declaration("double proc(input_type *input)", context);
275 }
276 count = 10;
277 tmp.vals = (double*) malloc(count * sizeof(double));
278 for(i=0; i< count; i++) {
279 tmp.vals[i] = i + 0.1;
280 }
281
282 if (write_file) {
283 FMStructDescRec formats[] = {
284 {"struct", input_field_list, sizeof(tmp), NULL},
285 {NULL, NULL, 0, NULL}};
286 write_buffer(write_file, &formats[0], &tmp, test_num);
287 }
288 gen_code = cod_code_gen(code, context);
289 func = (double (*)(test_struct_p))(long) gen_code->func;
290 assert((func)(param) == 46.00);
291 free(tmp.vals);
292 cod_code_free(gen_code);
293 cod_free_parse_context(context);
294 }
295 test_num++;
296 if ((run_only == -1) || (run_only == test_num)) {
297 /* 4 */
298 typedef struct test {
299 int count;
300 double *vals;
301 } test_struct, *test_struct_p;
302
303 static char extern_string[] = "int printf(string format, ...);";
304
305 static cod_extern_entry externs[] =
306 {
307 {"printf", (void*)(long)printf},
308 {(void*)0, (void*)0}
309 };
310 static char code[] = "{\
311 int i;\n\
312 double sum = 0.0;\n\
313 for(i = 0; i<input.count; i= i+1) {\n\
314 double *ptr = input.vals + i;\n \
315 sum = sum + (*ptr);\n\
316 }\n\
317 return sum;\n\
318 }";
319
320 static FMField input_field_list[] =
321 {
322 {"count", "integer", sizeof(int),
323 FMOffset(test_struct_p, count)},
324 {"vals", "float[count]", sizeof(double),
325 FMOffset(test_struct_p, vals)},
326 {(void*)0, (void*)0, 0, 0}
327 };
328
329 cod_parse_context context = new_cod_parse_context();
330 int i;
331 test_struct tmp;
332 test_struct *param = &tmp;
333 cod_code gen_code;
334 double (*func)(test_struct_p);
335
336 cod_assoc_externs(context, externs);
337 cod_parse_for_context(extern_string, context);
338 if (read_file) {
339 FMFieldList fields = NULL;
340 FMContext c = create_local_FMcontext();
341 char *buf = read_buffer(c, read_file, test_num);
342 param = (test_struct*)buf;
343 cod_add_encoded_param("input", buf, 0, c, context);
344 cod_set_return_type("double", context);
345 } else {
346 cod_add_simple_struct_type("input_type", input_field_list, context);
347 cod_subroutine_declaration("double proc(input_type *input)", context);
348 }
349 tmp.count = 10;
350 tmp.vals = (double*) malloc(tmp.count * sizeof(double));
351 for(i=0; i< tmp.count; i++) {
352 tmp.vals[i] = i + 0.1;
353 }
354
355 if (write_file) {
356 FMStructDescRec formats[] = {
357 {"struct", input_field_list, sizeof(tmp), NULL},
358 {NULL, NULL, 0, NULL}};
359 write_buffer(write_file, &formats[0], &tmp, test_num);
360 }
361 gen_code = cod_code_gen(code, context);
362 func = (double (*)(test_struct_p))(long) gen_code->func;
363 assert((func)(param) == 46.00);
364 free(tmp.vals);
365 cod_code_free(gen_code);
366 cod_free_parse_context(context);
367 }
368 test_num++;
369 if ((run_only == -1) || (run_only == test_num)) {
370 /* 5 */
371 /*
372 * This test tries to see if we're correctly dereferencing static pointers. Earlier this would overwrite the 'testing' variable, indexing through
373 * static memory instead of the malloc'd block.
374 */
375
376 typedef struct test {
377 int count;
378 double *vals;
379 } test_struct, *test_struct_p;
380
381 static char extern_string[] = "int printf(string format, ...); void*malloc(int size);";
382
383 static cod_extern_entry externs[] =
384 {
385 {"printf", (void*)(long)printf},
386 {"malloc", (void*)(long)malloc},
387 {(void*)0, (void*)0}
388 };
389 static char code[] = "{\
390 static float *ptr;\n\
391 static float testing = 46;\n\
392 ptr = malloc(3*sizeof(float));\n\
393 ptr[0] = 5;\n\
394 ptr[1] = 6;\n\
395 ptr[2] = 7;\n\
396 return testing;\n\
397 }";
398
399 static FMField input_field_list[] =
400 {
401 {"count", "integer", sizeof(int),
402 FMOffset(test_struct_p, count)},
403 {"vals", "float[count]", sizeof(double),
404 FMOffset(test_struct_p, vals)},
405 {(void*)0, (void*)0, 0, 0}
406 };
407
408 cod_parse_context context = new_cod_parse_context();
409 int i;
410 test_struct tmp;
411 test_struct *param = &tmp;
412 cod_code gen_code;
413 double (*func)(test_struct_p);
414
415 cod_assoc_externs(context, externs);
416 cod_parse_for_context(extern_string, context);
417 if (read_file) {
418 FMFieldList fields = NULL;
419 FMContext c = create_local_FMcontext();
420 char *buf = read_buffer(c, read_file, test_num);
421 param = (test_struct*)buf;
422 cod_add_encoded_param("input", buf, 0, c, context);
423 cod_set_return_type("double", context);
424 } else {
425 cod_add_simple_struct_type("input_type", input_field_list, context);
426 cod_subroutine_declaration("double proc(input_type *input)", context);
427 }
428 tmp.count = 10;
429 tmp.vals = (double*) malloc(tmp.count * sizeof(double));
430 for(i=0; i< tmp.count; i++) {
431 tmp.vals[i] = i + 0.1;
432 }
433
434 if (write_file) {
435 FMStructDescRec formats[] = {
436 {"struct", input_field_list, sizeof(tmp), NULL},
437 {NULL, NULL, 0, NULL}};
438 write_buffer(write_file, &formats[0], &tmp, test_num);
439 }
440 gen_code = cod_code_gen(code, context);
441 func = (double (*)(test_struct_p))(long) gen_code->func;
442 assert((func)(param) == 46.00);
443 free(tmp.vals);
444 cod_code_free(gen_code);
445 cod_free_parse_context(context);
446 }
447 test_num++;
448 return 0;
449 }
450