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