1 /*
2 * T5 - was created to reproduce a bug in the handling of dynamic arrays of structured types
3 */
4 #include "config.h"
5 #include "data_funcs.h"
6 #include "cod.h"
7 #include <stdlib.h>
8 #ifdef HAVE_MALLOC_H
9 #include "malloc.h"
10 #endif
11 #include "assert.h"
12 #include <stdio.h>
13 #include <string.h>
14
15 struct order_header {
16 int order_id;
17 int advertiser_number;
18 int agency_number;
19 int contract_number;
20 int start_date;
21 int end_date;
22 int estimate_number;
23 char class;
24 char *product_name;
25 int conflict_code1;
26 int conflict_code2;
27 };
28
29 struct spot_week {
30 unsigned char mo;
31 unsigned char tu;
32 unsigned char we;
33 unsigned char th;
34 unsigned char fr;
35 unsigned char sa;
36 unsigned char su;
37 };
38
39 struct spot {
40 int order_item_id;
41 unsigned char broadcast_week;
42 char *program_id;
43 short rate_section;
44 short length;
45 unsigned char bookend;
46 int start_date;
47 int end_date;
48 int cost_per_spot;
49 int spots_per_week;
50 struct spot_week spots_per_day;
51 };
52
53 struct station_order {
54 int station_id;
55 char *task_name;
56 char *salesperson_code;
57 int order_id;
58 int advertiser_number;
59 int agency_number;
60 int contract_number;
61 int start_date;
62 int end_date;
63 int estimate_number;
64 char class;
65 char *product_name;
66 int conflict_code1;
67 int conflict_code2;
68 int spot_count;
69 struct spot *spots;
70 };
71
72 FMField order_header_fields[] = {
73 {NULL, NULL, 0, 0}
74 };
75
76 FMField spot_week_fields[] = {
77 {"MO", "unsigned integer", sizeof(unsigned char),
78 FMOffset(struct spot_week *, mo)},
79 {"TU", "unsigned integer", sizeof(unsigned char),
80 FMOffset(struct spot_week *, tu)},
81 {"WE", "unsigned integer", sizeof(unsigned char),
82 FMOffset(struct spot_week *, we)},
83 {"TH", "unsigned integer", sizeof(unsigned char),
84 FMOffset(struct spot_week *, th)},
85 {"FR", "unsigned integer", sizeof(unsigned char),
86 FMOffset(struct spot_week *, fr)},
87 {"SA", "unsigned integer", sizeof(unsigned char),
88 FMOffset(struct spot_week *, sa)},
89 {"SU", "unsigned integer", sizeof(unsigned char),
90 FMOffset(struct spot_week *, su)},
91 {NULL, NULL, 0, 0}
92 };
93
94 FMField spot_fields[] = {
95 {"ORDER_ITEM_ID", "integer", sizeof(int),
96 FMOffset(struct spot *, order_item_id)},
97 {"BROADCAST_WEEK", "integer", sizeof(unsigned char),
98 FMOffset(struct spot *, broadcast_week)},
99 {"PROGRAM_ID", "string", sizeof(char *),
100 FMOffset(struct spot *, program_id)},
101 {"RATE_SECTION", "integer", sizeof(short),
102 FMOffset(struct spot *, rate_section)},
103 {"LENGTH", "integer", sizeof(short),
104 FMOffset(struct spot *, length)},
105 {"BOOKEND", "integer", sizeof(char),
106 FMOffset(struct spot *, bookend)},
107 {"START_DATE", "integer", sizeof(int),
108 FMOffset(struct spot *, start_date)},
109 {"END_DATE", "integer", sizeof(int),
110 FMOffset(struct spot *, end_date)},
111 {"COST_PER_SPOT", "integer", sizeof(int),
112 FMOffset(struct spot *, cost_per_spot)},
113 {"SPOTS_PER_WEEK", "integer", sizeof(int),
114 FMOffset(struct spot *, spots_per_week)},
115 {"SPOTS_PER_DAY", "spot_week", sizeof(struct spot_week),
116 FMOffset(struct spot *, spots_per_day)},
117 {NULL, NULL, 0, 0}
118 };
119
120 FMField station_order_fields[] = {
121 {"STATION_ID", "integer", sizeof(int),
122 FMOffset(struct station_order *, station_id)},
123 {"TASK_NAME", "string", sizeof(char *),
124 FMOffset(struct station_order *, task_name)},
125 {"SALESPERSON_CODE", "string", sizeof(char *),
126 FMOffset(struct station_order *, salesperson_code)},
127 {"MO_ORDER_ID", "integer", sizeof(int),
128 FMOffset(struct station_order *, order_id)},
129 {"ADVERTISER_NO", "integer", sizeof(int),
130 FMOffset(struct station_order *, advertiser_number)},
131 {"AGENCY_NO", "integer", sizeof(int),
132 FMOffset(struct station_order *, agency_number)},
133 {"CONTRACT_NO", "integer", sizeof(int),
134 FMOffset(struct station_order *, contract_number)},
135 {"FLIGHT_START_DATE", "integer", sizeof(int),
136 FMOffset(struct station_order *, start_date)},
137 {"FLIGHT_END_DATE", "integer", sizeof(int),
138 FMOffset(struct station_order *, end_date)},
139 {"ESTIMATE_NO", "integer", sizeof(int),
140 FMOffset(struct station_order *, estimate_number)},
141 {"CLASS", "char", sizeof(char),
142 FMOffset(struct station_order *, class)},
143 {"PRODUCT_NAME", "string", sizeof(char *),
144 FMOffset(struct station_order *, product_name)},
145 {"CONFLICT_CODE_1", "integer", sizeof(int),
146 FMOffset(struct station_order *, conflict_code1)},
147 {"CONFLICT_CODE_2", "integer", sizeof(int),
148 FMOffset(struct station_order *, conflict_code2)},
149 {"SPOT_COUNT", "integer", sizeof(int),
150 FMOffset(struct station_order *, spot_count)},
151 {"SPOTS", "spot[SPOT_COUNT]", sizeof(struct spot),
152 FMOffset(struct station_order *, spots)},
153 {NULL, NULL, 0, 0}
154 };
155
156 int
main(int argc,char ** argv)157 main(int argc, char **argv)
158 {
159 int verbose = 0;
160 int test_num = 0;
161 int run_only = -1;
162 char *read_file = NULL;
163 char *write_file = NULL;
164 while (argc > 1) {
165 if (strcmp(argv[1], "-v") == 0) {
166 verbose++;
167 } else if (strcmp(argv[1], "-w") == 0) {
168 if (argc <= 1) {
169 printf("Need argument to \"-w\"\n");
170 } else {
171 write_file = strdup(argv[2]);
172 }
173 argc--; argv++;
174 } else if (strcmp(argv[1], "-r") == 0) {
175 if (argc <= 1) {
176 printf("Need argument to \"-r\"\n");
177 } else {
178 read_file = strdup(argv[2]);
179 }
180 argc--; argv++;
181 } else if (strcmp(argv[1], "-o") == 0) {
182 sscanf(argv[2], "%d", &run_only);
183 argc--; argv++;
184 }
185 argc--; argv++;
186 }
187 if ((run_only == -1) || (run_only == test_num)) {
188 /* 0 */
189 static char extern_string[] = "int printf(string format, ...);";
190
191 static cod_extern_entry externs[] =
192 {
193 {"printf", (void*)(long)printf},
194 {(void*)0, (void*)0}
195 };
196 /* test external call */
197 static char code[] = "{\n\
198 order_out.STATION_ID = order.STATION_ID;\n\
199 order_out.TASK_NAME = order.TASK_NAME;\n\
200 order_out.SPOT_COUNT = order.SPOT_COUNT;\n\
201 order_out.SPOTS[1].BROADCAST_WEEK = 5;\n\
202 order_out.SPOT_COUNT = 4;\n\
203 if (order.SPOTS[0].PROGRAM_ID == \"EM2\") {\n\
204 order_out.SPOTS[0].PROGRAM_ID = \"My Favorite Martian\";\n\
205 }\n\
206 if (order.SPOTS[0].PROGRAM_ID == \"EM5\") {\n\
207 order_out.SPOTS[1].PROGRAM_ID = \"Dance Fever\";\n\
208 }\n\
209 if (order.SPOTS[1].PROGRAM_ID == \"EM2\") {\n\
210 order_out.SPOTS[2].PROGRAM_ID = \"Gilligan's Island\";\n\
211 }\n\
212 if (order.SPOTS[1].PROGRAM_ID == \"EM5\") {\n\
213 order_out.SPOTS[3].PROGRAM_ID = \"I Dream of Genie\";\n\
214 }\n\
215 }";
216
217 struct station_order order, out_order;
218 struct spot spots[2];
219 struct station_order *param = ℴ
220
221 cod_parse_context context = new_cod_parse_context();
222
223 cod_code gen_code;
224 void (*func)(void*, void*);
225
226 order.station_id = 11514;
227 order.task_name = "PollOrdersTask";
228 order.salesperson_code = "2-30-3001";
229 order.order_id = 1004;
230 order.advertiser_number = 2701;
231 order.agency_number = 1701;
232 order.contract_number = 0;
233 order.start_date = 61101;
234 order.end_date = 61701;
235 order.estimate_number = 0;
236 order.class = 'L';
237 order.product_name = "Fall Special";
238 order.conflict_code1 = 275;
239 order.conflict_code2 = 0;
240 order.spot_count = 2;
241
242 spots[0].order_item_id = 999;
243 spots[0].broadcast_week = 1;
244 spots[0].program_id = "EM5";
245 spots[0].rate_section = 2;
246 spots[0].length = 30;
247 spots[0].bookend = 1;
248 spots[0].start_date = 61101;
249 spots[0].end_date = 61701;
250 spots[0].cost_per_spot = 120;
251 spots[0].spots_per_week = 10;
252 spots[0].spots_per_day.mo = 5;
253 spots[0].spots_per_day.tu = 2;
254 spots[0].spots_per_day.we = 1;
255 spots[0].spots_per_day.th = 0;
256 spots[0].spots_per_day.fr = 2;
257 spots[0].spots_per_day.sa = 0;
258 spots[0].spots_per_day.su = 0;
259
260
261 spots[1].order_item_id = 999;
262 spots[1].broadcast_week = 2;
263 spots[1].program_id = "EM2";
264 spots[1].rate_section = 2;
265 spots[1].length = 30;
266 spots[1].bookend = 1;
267 spots[1].start_date = 61101;
268 spots[1].end_date = 61701;
269 spots[1].cost_per_spot = 120;
270 spots[1].spots_per_week = 10;
271 spots[1].spots_per_day.mo = 5;
272 spots[1].spots_per_day.tu = 2;
273 spots[1].spots_per_day.we = 1;
274 spots[1].spots_per_day.th = 0;
275 spots[1].spots_per_day.fr = 2;
276 spots[1].spots_per_day.sa = 0;
277 spots[1].spots_per_day.su = 0;
278
279 order.spots = (struct spot *)&spots;
280
281 if (write_file) {
282 FMStructDescRec formats[] = {
283 {"spot_week", spot_week_fields, sizeof(struct spot_week), NULL},
284 {"spot", spot_fields, sizeof(struct spot), NULL},
285 {"station_order", station_order_fields, sizeof(struct station_order), NULL},
286 {NULL, NULL, 0, NULL}};
287 write_buffer(write_file, &formats[0], &order, test_num);
288 }
289 cod_assoc_externs(context, externs);
290 cod_parse_for_context(extern_string, context);
291
292 if (read_file) {
293 FMFieldList fields = NULL;
294 FMContext c = create_local_FMcontext();
295 char *buf = read_buffer(c, read_file, test_num);
296 param = (struct station_order *)buf;
297 cod_add_encoded_param("order", buf, 0, c, context);
298 cod_add_simple_struct_type("spot_week", spot_week_fields, context);
299 cod_add_simple_struct_type("spot", spot_fields, context);
300 cod_add_simple_struct_type("station_order2", station_order_fields, context);
301 cod_add_param("order_out", "station_order2", 1, context);
302 } else {
303 cod_add_simple_struct_type("spot_week", spot_week_fields, context);
304 cod_add_simple_struct_type("spot", spot_fields, context);
305 cod_add_simple_struct_type("station_order", station_order_fields, context);
306 cod_subroutine_declaration("void proc(station_order *order, station_order *order_out)", context);
307
308 }
309 gen_code = cod_code_gen(code, context);
310 func = (void (*)(void*,void*))(long)gen_code->func;
311 memset(&out_order, 0, sizeof(out_order));
312 (func)((void*)param, (void*)&out_order);
313 if (out_order.station_id != order.station_id) {
314 fprintf(stderr, "Missed station_id\n");
315 return 1;
316 }
317
318 if (strcmp(out_order.task_name, order.task_name) != 0) {
319 fprintf(stderr, "Missed task_name\n");
320 return 1;
321 }
322
323 if (out_order.spot_count != 4) {
324 fprintf(stderr, "Missed spot_count\n");
325 return 1;
326 }
327 if (out_order.spots[0].program_id != NULL) {
328 fprintf(stderr, "Spots[0] not NULL\n");
329 return 1;
330 }
331 if (strcmp(out_order.spots[1].program_id, "Dance Fever") != 0) {
332 fprintf(stderr, "Spots[1] not right\n");
333 return 1;
334 }
335 if (strcmp(out_order.spots[2].program_id, "Gilligan's Island") != 0) {
336 fprintf(stderr, "Spots[2] not right\n");
337 return 1;
338 }
339 if (out_order.spots[3].program_id != NULL) {
340 fprintf(stderr, "Spots[3] not NULL\n");
341 return 1;
342 }
343 free(out_order.spots[2].program_id);
344 free(out_order.spots[1].program_id);
345 free(out_order.spots[0].program_id);
346 free(out_order.spots);
347 free(out_order.task_name);
348 cod_code_free(gen_code);
349 cod_free_parse_context(context);
350 }
351 return 0;
352 }
353