1 #include "config.h"
2 #include <assert.h>
3 #include <fcntl.h>
4 #ifdef STDC_HEADERS
5 #include <stdlib.h>
6 #endif
7 #include <stdio.h>
8 #ifdef HAVE_MEMORY_H
9 #include <memory.h>
10 #endif
11 #ifdef HAVE_MALLOC_H
12 #include <malloc.h>
13 #endif
14 #include <string.h>
15 #include "fm.h"
16 
17 #include "test_funcs.h"
18 
19 extern void init_written_data();
20 
21 char *comment_array[] =
22 {"this is a comment in the file",
23  "this is another comment in the file"};
24 
25 first_rec rec1_array[13];
26 
27 second_rec rec2_array[4];
28 
29 third_rec rec3_array[5];
30 
31 fourth_rec rec4;
32 
33 fifth_rec rec5;
34 
35 sixth_rec rec6_array[4];
36 
37 nested_rec rec7_array[1];
38 
39 later_rec rec8_array[3];
40 
41 ninth_rec rec9_array[6];
42 
43 string_array_rec string_array_array[6];
44 
45 DeriveMsg derive;
46 
47 multi_array_rec multi_array;
48 
49 multi_array_rec2 multi_array2;
50 
51 multi_array_rec fortran_array;
52 
53 triangle_param triangle;
54 
55 add_rec add_action_record;
56 
57 char *first_xml = "\
58 <FirstRecord integer_attribute=<PBIO:data field_id=0> double_attribute=<PBIO:data field_id=1> character_attribute=<PBIO:data field_id=2>>\n";
59 
60 char *string_xml = "\
61 <StringRecord integer_attribute=<PBIO:data field_id=0>>\n\
62     <Short value=<PBIO:data field_id=1>>\n\
63     <Long  value=<PBIO:data field_id=2>>\n\
64     <String>\n\
65        <PBIO:data field_id=3>\n\
66     </String>\n\
67     <Double value=<PBIO:data field_id=4>> \n\
68     <Character value=<PBIO:data field_id=5>>\n\
69 </StringRecord>\n";
70 
71 char *third_xml = "\
72 <TwoStringRecord integer_attribute=<PBIO:data field_name=\"integer field\">>\n\
73     <Long  value=<PBIO:data field_name=\"long field\">>\n\
74     <UnsignedInt  value=<PBIO:data field_name=\"uint field\">>\n\
75     <UnsignedLong  value=<PBIO:data field_name=\"ulong field\">>\n\
76     <String>\n\
77        <PBIO:data field_id=4>\n\
78     </String>\n\
79     <Double value=<PBIO:data field_id=5>> \n\
80     <StringTwo>\n\
81        <PBIO:data field_name=\"string field2\">\n\
82     </StringTwo>\n\
83     <Character value=<PBIO:data field_id=7>>\n\
84     <Enumeration value=<PBIO:data field_id=8>>\n\
85 </TwoStringRecord>\n";
86 
87 char *fourth_xml = "\
88 <StaticArrayRecord  ifield=<PBIO:data field_name=ifield>>\n\
89 <IntArray><PBIO:array>\n\
90 	<ArrayElement>\n\
91 		<PBIO:array_data_mark  field_name=int_array>\n\
92 	</ArrayElement>\n\
93 </PBIO:array></IntArray>\n\
94 <DoubleArray><PBIO:array>\n\
95 	<DoubleElement>\n\
96 		<PBIO:array_data_mark  field_name=\"double field\">\n\
97 	</DoubleElement>\n\
98 </PBIO:array></DoubleArray>\n\
99 </StaticArrayRecord>\n";
100 
101 char *embedded_xml = "\
102 <EmbeddedRecord  ifield=<PBIO:data field_name=ifield> \
103 string=\"<PBIO:data field_name=\"string field\">\" \
104 double=<PBIO:data field_name=\"dfield\">>\n";
105 
106 char *struct_array_xml = "\
107 <StructuredArray>\n\
108 <PBIO:array><PBIO:array_data_mark field_name=earray></PBIO:array>\
109 </StructuredArray>\n";
110 
111 char *var_array_xml = "\
112 <VariableLengthArrays>\n\
113 <VariableIntegerArray>\n\
114 <PBIO:array><PBIO:array_data_mark field_name=var_int_array> </PBIO:array>\
115 </VariableIntegerArray>\n\
116 <PBIO:array><PBIO:array_data_mark field_name=var_string_array></PBIO:array>\
117 </VariableLengthArrays>\n";
118 
119 char *later_xml = "\
120 <LaterRecord>\n\
121 int=<PBIO:data field_name=\"integer field\"> str=<PBIO:data field_name=\"string field\"> dbl=<PBIO:data field_name=\"double field\">\n\
122 </LaterRecord>\n";
123 
124 char *later2_xml = "\
125 <Later2Record>\n\
126 int=<PBIO:data field_name=\"integer field\"> str=<PBIO:data field_name=\"string field\"> dbl=<PBIO:data field_name=\"double field\">\n\
127 </Later2Record>\n";
128 
129 char *nested_xml = "\
130 <NestedRecord>\n\
131 int=<PBIO:data field_name=\"integer field\"> \n\
132 <Nested Element>\n\
133 <PBIO:data field_name=\"nested record\">\n\
134 </Nested Element>\n\
135 <String><PBIO:data field_name=\"string field\"></String>\n\
136 </NestedRecord>\n";
137 
138 char *event_xml = "<EventData len=<PBIO:data field_name=len>>\
139 <PBIO:array><PBIO:array_data_mark field_name=elem> </PBIO:array></EventData>\n";
140 
141 char *event_vec_xml = "\
142 <EventVector num_blocks=<PBIO:data field_name=vec_length>>\n\
143 <PBIO:array><PBIO:array_data_mark field_name=eventv></PBIO:array>\
144 </EventVector>\n";
145 
146 int
first_rec_eq(r1,r2)147 first_rec_eq(r1, r2)
148 first_rec *r1, *r2;
149 {
150     if (r1->integer_field != r2->integer_field)
151 	return 0;
152     if (r1->double_field != r2->double_field)
153 	return 0;
154     if (r1->char_field != r2->char_field)
155 	return 0;
156     return 1;
157 }
158 
159 int
second_rec_eq(r1,r2)160 second_rec_eq(r1, r2)
161 second_rec *r1, *r2;
162 {
163     if (r1->integer_field != r2->integer_field) {
164 	printf("integer_field 1 is %d (0x%x), integer_field 2 is %d (0x%x)\n",
165 	       r1->integer_field, r1->integer_field,
166 	       r2->integer_field, r2->integer_field);
167 	return 0;
168     }
169     if (r1->short_field != r2->short_field) {
170 	printf("short_field 1 is %d (0x%x), short_field 2 is %d (0x%x)\n",
171 	       r1->short_field, r1->short_field,
172 	       r2->short_field, r2->short_field);
173 	return 0;
174     }
175     if (r1->long_field != r2->long_field) {
176 	printf("long_field 1 is %ld (0x%lx), long_field 2 is %ld (0x%lx)\n",
177 	       r1->long_field, r1->long_field,
178 	       r2->long_field, r2->long_field);
179 	return 0;
180     }
181     if ((r1->string != NULL) || (r2->string != NULL)) {
182 	if ((r1->string != NULL) && (r2->string != NULL)) {
183 	    if (strcmp(r1->string, r2->string) != 0) {
184 		printf("second_rec String 1 is %s, string 2 is %s\n",
185 		       r1->string == NULL ? "(NULL)" : r1->string,
186 		       r2->string == NULL ? "(NULL)" : r2->string);
187 		return 0;
188 	    }
189 	} else {
190 	    printf("second_rec String 1 is %s, string 2 is %s\n",
191 		   r1->string == NULL ? "(NULL)" : r1->string,
192 		   r2->string == NULL ? "(NULL)" : r2->string);
193 	    return 0;
194 	}
195     }
196     if (r1->double_field != r2->double_field)
197 	return 0;
198     if (r1->char_field != r2->char_field)
199 	return 0;
200     return 1;
201 }
202 
203 int
third_rec_eq(r1,r2)204 third_rec_eq(r1, r2)
205 third_rec *r1, *r2;
206 {
207     if (r1->integer_field != r2->integer_field) {
208 	printf("integer field 1 is %d (0x%x), integer_field 2 is %d (0x%x)\n",
209 	       r1->integer_field, r1->integer_field, r2->integer_field, r2->integer_field);
210 	return 0;
211     }
212     if (r1->long_field != r2->long_field) {
213 	printf("long field 1 is %ld (0x%lx), long_field 2 is %ld (0x%lx)\n",
214 	       r1->long_field, r1->long_field, r2->long_field, r2->long_field);
215 	return 0;
216     }
217     if (r1->uint_field != r2->uint_field) {
218 	printf("uint field 1 is %u (0x%x), uint_field 2 is %u (0x%x)\n",
219 	       r1->uint_field, r1->uint_field, r2->uint_field, r2->uint_field);
220 	return 0;
221     }
222     if (r1->ulong_field != r2->ulong_field) {
223 	printf("ulong field 1 is %lu (0x%lx), ulong_field 2 is %lu (0x%lx)\n",
224 	       r1->ulong_field, r1->ulong_field, r2->ulong_field,
225 	       r2->ulong_field);
226 	return 0;
227     }
228     if ((r1->string != NULL) || (r2->string != NULL)) {
229 	if ((r1->string != NULL) && (r2->string != NULL)) {
230 	    if (strcmp(r1->string, r2->string) != 0) {
231 		printf("third_rec String 1 is %s, string 2 is %s\n",
232 		       r1->string == NULL ? "(NULL)" : r1->string,
233 		       r2->string == NULL ? "(NULL)" : r2->string);
234 		return 0;
235 	    }
236 	} else {
237 	    printf("third_rec String 1 is %s, string 2 is %s\n",
238 		   r1->string == NULL ? "(NULL)" : r1->string,
239 		   r2->string == NULL ? "(NULL)" : r2->string);
240 	    return 0;
241 	}
242     }
243     if (r1->double_field != r2->double_field) {
244 	printf("R1 double_field is %g , R2 is %g \n",
245 	       r1->double_field, r2->double_field);
246 	return 0;
247     }
248     if ((r1->string2 != NULL) || (r2->string2 != NULL)) {
249 	if ((r1->string2 != NULL) && (r2->string2 != NULL)) {
250 	    if (strcmp(r1->string2, r2->string2) != 0) {
251 		printf("third_rec String2 1 is %s, string2 2 is %s\n",
252 		       r1->string2 == NULL ? "(NULL)" : r1->string2,
253 		       r2->string2 == NULL ? "(NULL)" : r2->string2);
254 		return 0;
255 	    }
256 	} else {
257 	    printf("third_rec String2 1 is %s, string2 2 is %s\n",
258 		   r1->string2 == NULL ? "(NULL)" : r1->string2,
259 		   r2->string2 == NULL ? "(NULL)" : r2->string2);
260 	    return 0;
261 	}
262     }
263     if (r1->char_field != r2->char_field) {
264 	printf("char field 1 is %d (0x%x), char_field 2 is %d (0x%x)\n",
265 	       r1->char_field, r1->char_field, r2->char_field, r2->char_field);
266 	return 0;
267     }
268     if (r1->enum_field != r2->enum_field) {
269 	printf("enum field 1 is %d (0x%x), enum_field 2 is %d (0x%x)\n",
270 	       r1->enum_field, r1->enum_field, r2->enum_field, r2->enum_field);
271 	return 0;
272     }
273     return 1;
274 }
275 
276 #define ARRAY_SIZE 14
277 
278 int
fourth_rec_eq(r1,r2)279 fourth_rec_eq(r1, r2)
280 fourth_rec *r1, *r2;
281 {
282     int i, j;
283     if (r1->ifield != r2->ifield) {
284 	printf("Ifields not equal\n");
285 	return 0;
286     }
287     for (i = 0; i < ARRAY_SIZE; i++) {
288 	if (r1->int_array[i] != r2->int_array[i]) {
289 	    printf("Int_array element %d not equal\n", i);
290 	    return 0;
291 	}
292     }
293     for (i = 0; i < 2; i++) {
294 	for (j = 0; j < 2; j++) {
295 	    if (r1->double_array[i][j] != r2->double_array[i][j]) {
296 		printf("double_array[%d][%d] not equal\n", i, j);
297 		return 0;
298 	    }
299 	}
300     }
301     return 1;
302 }
303 
304 int
emb_rec_eq(r1,r2)305 emb_rec_eq(r1, r2)
306 embedded_rec *r1, *r2;
307 {
308     if (r1->ifield != r2->ifield) {
309 	printf("ifield 1 is %d (%x), ifield 2 is %d (%x)\n",
310 	       r1->ifield, (unsigned)r1->ifield,
311 	       r2->ifield, (unsigned)r2->ifield);
312 	return 0;
313     }
314     if ((r1->string != NULL) || (r2->string != NULL)) {
315 	if ((r1->string != NULL) && (r2->string != NULL)) {
316 	    if (strcmp(r1->string, r2->string) != 0) {
317 		printf("emb_rec String 1 is %s, string 2 is %s\n",
318 		       r1->string == NULL ? "(NULL)" : r1->string,
319 		       r2->string == NULL ? "(NULL)" : r2->string);
320 		return 0;
321 	    }
322 	} else {
323 	    printf("emb_rec String 1 is %s, string 2 is %s\n",
324 		   r1->string == NULL ? "(NULL)" : r1->string,
325 		   r2->string == NULL ? "(NULL)" : r2->string);
326 	    return 0;
327 	}
328     }
329     if (r1->dfield != r2->dfield) {
330 	printf("dfield 1 is %g, dfield 2 is %g\n", r1->dfield, r2->dfield);
331 	return 0;
332     }
333     return 1;
334 }
335 
336 int
fifth_rec_eq(r1,r2)337 fifth_rec_eq(r1, r2)
338 fifth_rec *r1, *r2;
339 {
340     int i;
341     for (i = 0; i < 4; i++) {
342 	if (!emb_rec_eq(&r1->earray[i], &r2->earray[i])) {
343 	    printf("Failure was fifth_rec entry %d\n", i);
344 	    return 0;
345 	}
346     }
347     return 1;
348 }
349 
350 int
sixth_rec_eq(r1,r2)351 sixth_rec_eq(r1, r2)
352 sixth_rec *r1, *r2;
353 {
354     int i;
355     if (r1->icount != r2->icount)
356 	return 0;
357     if ((r1->string != NULL) || (r2->string != NULL)) {
358 	if ((r1->string != NULL) && (r2->string != NULL)) {
359 	    if (strcmp(r1->string, r2->string) != 0) {
360 		printf("Sixth_rec String 1 is %s, string 2 is %s\n",
361 		       r1->string, r2->string);
362 		return 0;
363 	    }
364 	} else {
365 	    printf("Sixth_rec String 1 is %s, string 2 is %s\n",
366 		   r1->string == NULL ? "(NULL)" : r1->string,
367 		   r2->string == NULL ? "(NULL)" : r2->string);
368 	    return 0;
369 	}
370     }
371     for (i = 0; i < r1->icount; i++) {
372 	if (r1->var_int_array[i] != r2->var_int_array[i]) {
373 	    printf("R1 var_int_array[%d] is %ld (0x%x), R2 is %ld (0x%x) \n",
374 		   i, (long)r1->var_int_array[i], (unsigned)r1->var_int_array[i],
375 		   (long)r2->var_int_array[i], (unsigned)r2->var_int_array[i]);
376 	    return 0;
377 	}
378 	if (r1->var_double_array[i] != r2->var_double_array[i]) {
379 	    printf("R1 var_double_array[%d] is %g (0x%lx), R2 is %g (0x%lx) \n",
380 		   i, r1->var_double_array[i], (long)r1->var_double_array[i],
381 		   r2->var_double_array[i], (long)r2->var_double_array[i]);
382 	    return 0;
383 	}
384 	if (!second_rec_eq(&r1->var_string_array[i], &r2->var_string_array[i])) {
385 	    printf("var string array element [%d] was different\n", i);
386 	    return 0;
387 	}
388     }
389     if (r1->dfield != r2->dfield) {
390 	printf("dfield 1 is %g, dfield 2 is %g\n", r1->dfield, r2->dfield);
391 	return 0;
392     }
393     return 1;
394 }
395 
396 int
nested_rec_eq(r1,r2)397 nested_rec_eq(r1, r2)
398 nested_rec *r1, *r2;
399 {
400     if (r1->integer_field != r2->integer_field) {
401 	printf("nested, R1 integer = %d, R2 %d\n", r1->integer_field,
402 	       r2->integer_field);
403 	return 0;
404     }
405     if (!second_rec_eq(&r1->nested_rec, &r2->nested_rec)) {
406 	printf("Nested, second rec was not equal\n");
407 	return 0;
408     }
409     if ((r1->string != NULL) || (r2->string != NULL)) {
410 	if ((r1->string != NULL) && (r2->string != NULL)) {
411 	    if (strcmp(r1->string, r2->string) != 0) {
412 		printf("nested String 1 is %s, string 2 is %s\n",
413 		       r1->string == NULL ? "(NULL)" : r1->string,
414 		       r2->string == NULL ? "(NULL)" : r2->string);
415 		return 0;
416 	    }
417 	} else {
418 	    printf("nested String 1 is %s, string 2 is %s\n",
419 		   r1->string == NULL ? "(NULL)" : r1->string,
420 		   r2->string == NULL ? "(NULL)" : r2->string);
421 	    return 0;
422 	}
423     }
424     return 1;
425 }
426 
427 int
later_rec_eq(r1,r2)428 later_rec_eq(r1, r2)
429 later_rec *r1, *r2;
430 {
431     if (r1->integer_field != r2->integer_field)
432 	return 0;
433     if ((r1->string != NULL) || (r2->string != NULL)) {
434 	if ((r1->string != NULL) && (r2->string != NULL)) {
435 	    if (strcmp(r1->string, r2->string) != 0)
436 		return 0;
437 	} else {
438 	    return 0;
439 	}
440     }
441     if (r1->double_field != r2->double_field)
442 	return 0;
443     return 1;
444 }
445 
446 int
ninth_rec_eq(r1,r2)447 ninth_rec_eq(r1, r2)
448 ninth_rec *r1, *r2;
449 {
450     int i;
451     if (r1->vec_length != r2->vec_length)
452 	return 0;
453     for (i = 0; i < r1->vec_length; i++) {
454 	int j;
455 	if (r1->eventv[i].iov_len != r2->eventv[i].iov_len)
456 	    return 0;
457 
458 	for (j = 0; j< r1->eventv[i].iov_len; j++) {
459 	    if (((char*)r1->eventv[i].iov_base)[j] != ((char*)r2->eventv[i].iov_base)[j])
460 		return 0;
461 	}
462     }
463     return 1;
464 }
465 
466 int
string_array_eq(r1,r2)467 string_array_eq(r1, r2)
468 string_array_rec *r1, *r2;
469 {
470     int i;
471     if (r1->array_len != r2->array_len)
472 	return 0;
473     if ((r1->base_string != NULL) || (r2->base_string != NULL)) {
474 	if ((r1->base_string != NULL) && (r2->base_string != NULL)) {
475 	    if (strcmp(r1->base_string, r2->base_string) != 0)
476 		return 0;
477 	} else {
478 	    return 0;
479 	}
480     }
481     for (i = 0; i < r1->array_len; i++) {
482 	if ((r1->array[i] != NULL) || (r2->array[i] != NULL)) {
483 	    if ((r1->array[i] != NULL) && (r2->array[i] != NULL)) {
484 		if (strcmp(r1->array[i], r2->array[i]) != 0) {
485 		    printf("string array comparison failed for string entry %d, R1 is %s, R2 is %s\n", i,
486 			   r1->array[i] == NULL ? "(NULL)" : r1->array[i],
487 			   r2->array[i] == NULL ? "(NULL)" : r2->array[i]);
488 		    return 0;
489 		}
490 	    } else {
491 		printf("string array comparison failed for string entry %d, R1 is %s, R2 is %s\n", i,
492 		       r1->array[i] == NULL ? "(NULL)" : r1->array[i],
493 		       r2->array[i] == NULL ? "(NULL)" : r2->array[i]);
494 		return 0;
495 	    }
496 	}
497     }
498     return 1;
499 }
500 
501 int
502 /* compares a single element */
iofieldlist_eq(FMFieldList l1,FMFieldList l2)503 iofieldlist_eq(FMFieldList l1, FMFieldList l2)
504 {
505     if ((l1->field_name != NULL) || (l2->field_name != NULL)) {
506 	if ((l1->field_name != NULL) && (l2->field_name != NULL)) {
507 	    if (strcmp(l1->field_name, l2->field_name) != 0) {
508 		printf("field list names differ\n");
509 		return 0;
510 	    }
511 	} else {
512 	    printf("Field list names differ, null non-null");
513 	    return 0;
514 	}
515     }
516     if ((l1->field_type != NULL) || (l2->field_type != NULL)) {
517 	if ((l1->field_type != NULL) && (l2->field_type != NULL)) {
518 	    if (strcmp(l1->field_type, l2->field_type) != 0) {
519 		printf("field list types differ, %s, %s\n", l1->field_type, l2->field_type);
520 		return 0;
521 	    }
522 	} else {
523 	    printf("Field list types differ, null non-null");
524 	    return 0;
525 	}
526     }
527     if (l1->field_size != l2->field_size) {
528 	printf("Field list sizes differ\n");
529 	return 0;
530     }
531     if (l1->field_offset != l2->field_offset) {
532 	printf("Field list offsets differ\n");
533 	return 0;
534     }
535     return 1;
536 }
537 
538 int
deformatlist_eq(format_list_element * f1,format_list_element * f2)539 deformatlist_eq(format_list_element *f1, format_list_element *f2)
540 {
541     int i;
542     if ((f1->format_name != NULL) || (f2->format_name != NULL)) {
543 	if ((f1->format_name != NULL) && (f2->format_name != NULL)) {
544 	    if (strcmp(f1->format_name, f2->format_name) != 0) {
545 		printf("format list names differ, \"%s\" \"%s\"\n",
546 		       f1->format_name, f2->format_name);
547 		return 0;
548 	    }
549 	} else {
550 	    printf("format list names differ, null non-null");
551 	    return 0;
552 	}
553     }
554     if (f1->field_list_len != f2->field_list_len) {
555 	printf("Field list lens differ\n");
556 	return 0;
557     }
558     for (i=0; i < f1->field_list_len ; i++) {
559 	if (!iofieldlist_eq(&f1->field_list[i], &f2->field_list[i])) {
560 	    printf("Field list element %d of format list %s was different\n",
561 		   i, f1->format_name);
562 	    return 0;
563 	}
564     }
565     return 1;
566 }
567 
568 int
derive_eq(DeriveMsgPtr d1,DeriveMsgPtr d2)569 derive_eq(DeriveMsgPtr d1, DeriveMsgPtr d2)
570 {
571     int i;
572     if ((d1->chan_str != NULL) || (d2->chan_str != NULL)) {
573 	if ((d1->chan_str != NULL) && (d2->chan_str != NULL)) {
574 	    if (strcmp(d1->chan_str, d2->chan_str) != 0) {
575 		printf("chan strs differ\n");
576 		return 0;
577 	    }
578 	} else {
579 	    printf("chan strs differ, null non-null");
580 	    return 0;
581 	}
582     }
583     if (d1->cond != d2->cond) {
584 	printf("conds differ\n");
585 	return 0;
586     }
587     if (d1->client_channel_id.len != d2->client_channel_id.len) {
588 	printf("id lens differ\n");
589 	return 0;
590     }
591     if (memcmp(d1->client_channel_id.channel,
592 	       d2->client_channel_id.channel,
593 	       d1->client_channel_id.len) != 0) {
594 	printf("ids differ\n");
595 	return 0;
596     }
597     if ((d1->client_contact_str != NULL) || (d2->client_contact_str != NULL)) {
598 	if ((d1->client_contact_str != NULL) && (d2->client_contact_str != NULL)) {
599 	    if (strcmp(d1->client_contact_str, d2->client_contact_str) != 0) {
600 		printf("client_contact_strs differ\n");
601 		return 0;
602 	    }
603 	} else {
604 	    printf("client_contact_strs differ, null non-null");
605 	    return 0;
606 	}
607     }
608     if ((d1->filter != NULL) || (d2->filter != NULL)) {
609 	if ((d1->filter != NULL) && (d2->filter != NULL)) {
610 	    if (strcmp(d1->filter, d2->filter) != 0) {
611 		printf("filters differ\n");
612 		return 0;
613 	    }
614 	} else {
615 	    printf("filters differ, null non-null");
616 	    return 0;
617 	}
618     }
619     if (d1->field_list_len != d2->field_list_len) {
620 	printf("Field list lens differ\n");
621 	return 0;
622     }
623     for (i=0; i < d1->field_list_len ; i++) {
624 	if (!iofieldlist_eq(&d1->field_list[i], &d2->field_list[i])) {
625 	    printf("Field list element %d was different\n", i);
626 	    return 0;
627 	}
628     }
629     if (d1->format_list_len != d2->format_list_len) {
630 	printf("format list lens differ\n");
631 	return 0;
632     }
633     for (i=0; i < d1->format_list_len ; i++) {
634 	if (!deformatlist_eq(&d1->format_list[i], &d2->format_list[i])) {
635 	    printf("Format list element %d was different\n", i);
636 	    return 0;
637 	}
638     }
639     if (d1->init_data_len != d2->init_data_len) {
640 	printf("init data lens differ\n");
641 	return 0;
642     }
643     if (memcmp(d1->init_data_block, d2->init_data_block,
644 	       d1->init_data_len) != 0) {
645 	printf("init data differs\n");
646 	return 0;
647     }
648     return 1;
649 }
650 
651 int
multi_array_eq(multi_array_rec * r1,multi_array_rec * r2)652 multi_array_eq(multi_array_rec *r1, multi_array_rec *r2)
653 {
654     int i, j, k, l;
655     if (r1->ifield != r2->ifield) {
656 	printf("ifield differs\n");
657 	return 0;
658     }
659     for (i = 0; i < 2; i++) {
660 	for (j = 0; j < 2; j++) {
661 	    for (k = 0; k < 2; k++) {
662 		for (l = 0; l < 2; l++) {
663 		    if (r1->double_array[i][j][k][l] !=
664 			r2->double_array[i][j][k][l]) {
665 			printf("Differ in double array element %d, %d, %d, %d\n",
666 			       i, j, k, l);
667 			return 0;
668 		    }
669 		}
670 	    }
671 	}
672     }
673     for (i = 0; i < r1->ifield; i++) {
674 	for (j = 0; j < 2; j++) {
675 	    if (r1->int_array[i][j] != r2->int_array[i][j]) {
676 		printf("Differ in int_array element %d, %d = %x, %x\n",
677 		       i, j, r1->int_array[i][j], r2->int_array[i][j]);
678 		return 0;
679 	    }
680 	}
681     }
682     for (i = 0; i < 2; i++) {
683 	for (j = 0; j < r1->ifield; j++) {
684 	    if (r1->int_array2[i][j] != r2->int_array2[i][j]) {
685 		printf("Differ in int_array2 element %d, %d\n",
686 		       i, j);
687 		return 0;
688 	    }
689 	}
690     }
691     for (i = 0; i < r1->ifield; i++) {
692 	for (j = 0; j < r1->ifield; j++) {
693 	    for (k = 0; k < r1->ifield; k++) {
694 		if (r1->int_array3[i][j][k] != r2->int_array3[i][j][k]) {
695 		    printf("Differ in int_array3 element %d, %d, %d  - r1=%d, r2=%d\n",
696 			   i, j, k, r1->int_array3[i][j][k], r2->int_array3[i][j][k]);
697 		    return 0;
698 		}
699 	    }
700 	}
701     }
702     return 1;
703 }
704 
705 int
triangle_param_eq(triangle_param * r1,triangle_param * r2)706 triangle_param_eq(triangle_param *r1, triangle_param *r2)
707 {
708     int i;
709     if (r1->corner1x != r2->corner1x) {
710 	printf("corner1x differs\n");
711 	return 0;
712     }
713     if (r1->corner1y != r2->corner1y) {
714 	printf("corner1y differs\n");
715 	return 0;
716     }
717     if (r1->corner1z != r2->corner1z) {
718 	printf("corner1z differs\n");
719 	return 0;
720     }
721     if (r1->corner2x != r2->corner2x) {
722 	printf("corner2x differs\n");
723 	return 0;
724     }
725     if (r1->corner2y != r2->corner2y) {
726 	printf("corner2y differs\n");
727 	return 0;
728     }
729     if (r1->corner2z != r2->corner2z) {
730 	printf("corner2z differs\n");
731 	return 0;
732     }
733     if (r1->compression_type != r2->compression_type) {
734 	printf("compression_type differs\n");
735 	return 0;
736     }
737     if (r1->codebook_size != r2->codebook_size) {
738 	printf("codebook_size differs\n");
739 	return 0;
740     }
741     for (i= 0; i < r1->codebook_size; i++) {
742 	if (r1->codebook_data[i] != r2->codebook_data[i]) {
743 	    printf("codebook_data[%d] differs\n", i);
744 	    return 0;
745 	}
746     }
747     if (r1->timestamp != r2->timestamp) {
748 	printf("timestamp differs\n");
749 	return 0;
750     }
751     if (r1->nonce != r2->nonce) {
752 	printf("nonce differs\n");
753 	return 0;
754     }
755     if (r1->num_meshes != r2->num_meshes) {
756 	printf("num_meshes differs\n");
757 	return 0;
758     }
759 
760     for (i=0; i < r1->num_meshes; i++) {
761 	int j;
762 	if (r1->mesh_data[i].id != r2->mesh_data[i].id) {
763 	    printf("mesh_data[%d].id differs\n", i);
764 	    return 0;
765 	}
766 	if (r1->mesh_data[i].data_size != r2->mesh_data[i].data_size) {
767 	    printf("mesh_data[%d].data_size differs\n", i);
768 	    return 0;
769 	}
770 	if (r1->mesh_data[i].old_data_size != r2->mesh_data[i].old_data_size) {
771 	    printf("mesh_data[%d].old_data_size differs\n", i);
772 	    return 0;
773 	}
774 	if (r1->mesh_data[i].compressed_size != r2->mesh_data[i].compressed_size) {
775 	    printf("mesh_data[%d].compressed_size differs\n", i);
776 	    return 0;
777 	}
778 	for (j = 0; j < r1->mesh_data[i].compressed_size; j++) {
779 	    if (r1->mesh_data[i].compressed_data[j] != r2->mesh_data[i].compressed_data[j]) {
780 		printf("mesh_data[%d].compressed_data[%d] differs\n", i, j);
781 		return 0;
782 	    }
783 	}
784 	if (r1->mesh_data[i].corner1x != r2->mesh_data[i].corner1x) {
785 	    printf("mesh_data[%d].corner1x differs\n", i);
786 	    return 0;
787 	}
788 	if (r1->mesh_data[i].corner1y != r2->mesh_data[i].corner1y) {
789 	    printf("mesh_data[%d].corner1y differs\n", i);
790 	    return 0;
791 	}
792 	if (r1->mesh_data[i].corner1z != r2->mesh_data[i].corner1z) {
793 	    printf("mesh_data[%d].corner1z differs\n", i);
794 	    return 0;
795 	}
796 	if (r1->mesh_data[i].corner2x != r2->mesh_data[i].corner2x) {
797 	    printf("mesh_data[%d].corner2x differs\n", i);
798 	    return 0;
799 	}
800 	if (r1->mesh_data[i].corner2y != r2->mesh_data[i].corner2y) {
801 	    printf("mesh_data[%d].corner2y differs\n", i);
802 	    return 0;
803 	}
804 	if (r1->mesh_data[i].corner2z != r2->mesh_data[i].corner2z) {
805 	    printf("mesh_data[%d].corner2z differs\n", i);
806 	    return 0;
807 	}
808 	if (r1->mesh_data[i].atom_type != r1->mesh_data[i].atom_type) {
809 	    printf("mesh_data[%d].corner1x differs\n", i);
810 	    return 0;
811 	}
812     }
813     return 1;
814 }
815 
816 int
xml_format_list_eq(msg_format_list_element * f1,msg_format_list_element * f2)817 xml_format_list_eq(msg_format_list_element *f1, msg_format_list_element *f2)
818 {
819     int i;
820     if ((f1->format_name != NULL) || (f2->format_name != NULL)) {
821 	if ((f1->format_name != NULL) && (f2->format_name != NULL)) {
822 	    if (strcmp(f1->format_name, f2->format_name) != 0) {
823 		printf("format list names differ, \"%s\" \"%s\"\n",
824 		       f1->format_name, f2->format_name);
825 		return 0;
826 	    }
827 	} else {
828 	    printf("format list names differ, null non-null");
829 	    return 0;
830 	}
831     }
832     if ((f1->xml_markup != NULL) || (f2->xml_markup != NULL)) {
833 	if ((f1->xml_markup != NULL) && (f2->xml_markup != NULL)) {
834 	    if (strcmp(f1->xml_markup, f2->xml_markup) != 0) {
835 		printf("xml markups differ\n");
836 		return 0;
837 	    }
838 	} else {
839 	    printf("xml markups differ, null non-null");
840 	    return 0;
841 	}
842     }
843     if (f1->field_list_len != f2->field_list_len) {
844 	printf("Field list lens differ\n");
845 	return 0;
846     }
847     for (i=0; i < f1->field_list_len ; i++) {
848 	if (!iofieldlist_eq(&f1->field_list[i], &f2->field_list[i])) {
849 	    printf("Field list element %d of format list %s was different\n",
850 		   i, f1->format_name);
851 	    return 0;
852 	}
853     }
854     return 1;
855 }
856 
857 void
add_rec_dump(add_rec_ptr r)858 add_rec_dump(add_rec_ptr r)
859 {
860     int i;
861     printf("in_format_name %p \"%s\"\n", (char*)r->in_format_name,
862 	   r->in_format_name);
863     printf("func_str %p \"%s\"\n", (char*)r->func_str, r->func_str);
864     printf("out_formats %p \n", (char*)r->out_formats);
865     for (i = 0; i < r->format_count; i++) {
866 	int j;
867 	printf("out[%d].format_name %p \"%s\"\n", i, (char*)r->out_formats[i].format_name, r->out_formats[i].format_name);
868 	if (r->out_formats[i].xml_markup != NULL)
869 	    printf("out[%d].xml_markup %p \"%s\"\n", i, (char*)r->out_formats[i].xml_markup, r->out_formats[i].xml_markup);
870 	printf("out[%d].field_list %p \n", i, (char*)r->out_formats[i].field_list);
871 	for (j = 0; j < r->out_formats[i].field_list_len; j++) {
872 	    printf("out[%d].field_list[%d].field_name %p \"%s\"\n", i, j, (char*)r->out_formats[i].field_list[j].field_name, r->out_formats[i].field_list[j].field_name);
873 	    printf("out[%d].field_list[%d].field_type %p \"%s\"\n", i, j, (char*)r->out_formats[i].field_list[j].field_type, r->out_formats[i].field_list[j].field_type);
874 	}
875     }
876 }
877 
878 
879 int
add_rec_eq(add_rec_ptr r1,add_rec_ptr r2)880 add_rec_eq(add_rec_ptr r1, add_rec_ptr r2)
881 {
882     int i;
883     if (r1->action != r2->action) return 0;
884     if ((r1->in_format_name != NULL) || (r2->in_format_name != NULL)) {
885 	if ((r1->in_format_name != NULL) && (r2->in_format_name != NULL)) {
886 	    if (strcmp(r1->in_format_name, r2->in_format_name) != 0) {
887 		printf("in_format_names differ\n");
888 		return 0;
889 	    }
890 	} else {
891 	    printf("in_format_names differ, null non-null");
892 	    return 0;
893 	}
894     }
895     if ((r1->func_str != NULL) || (r2->func_str != NULL)) {
896 	if ((r1->func_str != NULL) && (r2->func_str != NULL)) {
897 	    if (strcmp(r1->func_str, r2->func_str) != 0) {
898 		printf("func_strs differ, \"%s\", \"%s\"\n", r1->func_str,
899 		       r2->func_str);
900 		return 0;
901 	    }
902 	} else {
903 	    printf("func_strs differ, null non-null");
904 	    return 0;
905 	}
906     }
907     if (r1->format_count != r2->format_count) return 0;
908     for (i=0; i<r1->format_count; i++) {
909 	if (xml_format_list_eq(&r1->out_formats[i], &r2->out_formats[i]) == 0)
910 	    return 0;
911     }
912     return 1;
913 }
914 
915 void
init_written_data()916 init_written_data()
917 {
918     int i, j, k, l, index;
919     memset((char *) &rec1_array, 0, sizeof(rec1_array));
920     rec1_array[0].integer_field = 14;
921     rec1_array[0].double_field = 2.717;
922     rec1_array[0].char_field = 'A';
923     rec1_array[1].integer_field = 17;
924     rec1_array[1].double_field = rec1_array[0].double_field * 3.0;
925     rec1_array[1].char_field = 'B';
926     rec1_array[2].integer_field = rec1_array[1].integer_field * 2;
927     rec1_array[2].double_field = rec1_array[1].double_field * 2.717;
928     rec1_array[2].char_field = 'C';
929     for (i = 0; i < 10; i++) {
930 	rec1_array[i + 3].integer_field = 2 * i * i;
931 	rec1_array[i + 3].double_field = 2.717 * (i * i);
932 	rec1_array[i + 3].char_field = 'D' + i;
933     }
934 
935     memset((char *) &rec2_array[0], 0, sizeof(rec2_array));
936     rec2_array[0].integer_field = 14;
937     rec2_array[0].short_field = 27;
938     rec2_array[0].long_field = 987234;
939     rec2_array[0].string = "testing";
940     rec2_array[0].double_field = 2.717;
941     rec2_array[0].char_field = 'A';
942 
943     rec2_array[1].integer_field = 14;
944     rec2_array[1].short_field = 27;
945     rec2_array[1].long_field = 987234;
946     rec2_array[1].string = NULL;
947     rec2_array[1].double_field = 2.717;
948     rec2_array[1].char_field = 'A';
949 
950     rec2_array[2].integer_field = 14;
951     rec2_array[2].short_field = 27;
952     rec2_array[2].long_field = 987234;
953     rec2_array[2].string = NULL;
954     rec2_array[2].double_field = 2.717;
955     rec2_array[2].char_field = 'A';
956 
957     rec2_array[3].integer_field = 14;
958     rec2_array[3].short_field = 27;
959     rec2_array[3].long_field = 987234;
960     rec2_array[3].string = "the end";
961     rec2_array[3].double_field = 2.717;
962     rec2_array[3].char_field = 'A';
963 
964     memset((char *) &rec3_array[0], 0, sizeof(rec3_array));
965     rec3_array[0].integer_field = 14;
966     rec3_array[0].long_field = 987234;
967     rec3_array[0].uint_field = 0xf7e589ce;	/* = 4159015374 */
968 #if SIZEOF_LONG==64
969     rec3_array[0].ulong_field = 0xf7e589ceec9dd130;
970 #else
971     rec3_array[0].ulong_field = 0xec9dd130;	/* = 3969765680 */
972 #endif
973     rec3_array[0].string = "testing";
974     rec3_array[0].double_field = 2.717;
975     rec3_array[0].string2 = "jambalaya";
976     rec3_array[0].char_field = 'A';
977     rec3_array[0].enum_field = Red_Stripe;
978 
979     rec3_array[1].integer_field = 14;
980     rec3_array[1].long_field = 987234;
981     rec3_array[1].uint_field = 0xf7e589ce;	/* = 4159015374 */
982 #if SIZEOF_LONG==64
983     rec3_array[1].ulong_field = 0xf7e589ceec9dd130;
984 #else
985     rec3_array[1].ulong_field = 0xec9dd130;	/* = 3969765680 */
986 #endif
987     rec3_array[1].string = NULL;
988     rec3_array[1].double_field = 2.717;
989     rec3_array[1].string2 = "jambalaya";
990     rec3_array[1].char_field = 'A';
991     rec3_array[1].enum_field = Paulaner;
992 
993     rec3_array[2].integer_field = 14;
994     rec3_array[2].long_field = 987234;
995     rec3_array[2].uint_field = 0xf7e589ce;	/* = 4159015374 */
996 #if SIZEOF_LONG==64
997     rec3_array[2].ulong_field = 0xf7e589ceec9dd130;
998 #else
999     rec3_array[2].ulong_field = 0xec9dd130;	/* = 3969765680 */
1000 #endif
1001     rec3_array[2].string = "testing";
1002     rec3_array[2].double_field = 2.717;
1003     rec3_array[2].string2 = NULL;
1004     rec3_array[2].char_field = 'A';
1005     rec3_array[2].enum_field = Pilsner;
1006 
1007     rec3_array[3].integer_field = 14;
1008     rec3_array[3].long_field = 987234;
1009     rec3_array[3].uint_field = 0xf7e589ce;	/* = 4159015374 */
1010 #if SIZEOF_LONG==64
1011     rec3_array[3].ulong_field = 0xf7e589ceec9dd130;
1012 #else
1013     rec3_array[3].ulong_field = 0xec9dd130;	/* = 3969765680 */
1014 #endif
1015     rec3_array[3].string = NULL;
1016     rec3_array[3].double_field = 2.717;
1017     rec3_array[3].string2 = NULL;
1018     rec3_array[3].char_field = 'A';
1019     rec3_array[3].enum_field = Red_Stripe;
1020 
1021     rec3_array[4].integer_field = 14;
1022     rec3_array[4].long_field = 987234;
1023     rec3_array[4].uint_field = 0xf7e589ce;	/* = 4159015374 */
1024 #if SIZEOF_LONG==64
1025     rec3_array[4].ulong_field = 0xf7e589ceec9dd130;
1026 #else
1027     rec3_array[4].ulong_field = 0xec9dd130;	/* = 3969765680 */
1028 #endif
1029     rec3_array[4].string = "testing";
1030     rec3_array[4].double_field = 2.717;
1031     rec3_array[4].string2 = "jambalaya";
1032     rec3_array[4].char_field = 'A';
1033     rec3_array[4].enum_field = Pilsner;
1034 
1035     memset((char *) &rec4, 0, sizeof(rec4));
1036     for (i = 0; i < ARRAY_SIZE; i++) {
1037 	rec4.int_array[i] = 297 + i;
1038     }
1039     rec4.double_array[0][0] = 1.0;
1040     rec4.double_array[0][1] = 2.0;
1041     rec4.double_array[1][0] = 3.0;
1042     rec4.double_array[1][1] = 4.0;
1043     rec4.ifield = -rec4.int_array[ARRAY_SIZE - 1];
1044 
1045     memset((char *) &rec5, 0, sizeof(rec5));
1046     rec5.earray[0].dfield = 4.0;
1047     rec5.earray[0].ifield = 4;
1048     rec5.earray[0].string = "string20";
1049     rec5.earray[1].dfield = 3.0;
1050     rec5.earray[1].ifield = 3;
1051     rec5.earray[1].string = "string15";
1052     rec5.earray[2].dfield = 2.0;
1053     rec5.earray[2].ifield = 2;
1054     rec5.earray[2].string = "string10";
1055     rec5.earray[3].dfield = 1.0;
1056     rec5.earray[3].ifield = 1;
1057     rec5.earray[3].string = "string5";
1058 
1059     k = 0;
1060     for (i = 1; i < 20; i += 5) {
1061 	rec6_array[k].string = malloc(10);
1062 	memset(rec6_array[k].string, 0, 10);
1063 	sprintf(rec6_array[k].string, "variant%d", i);
1064 	rec6_array[k].icount = 2 * i;
1065 	rec6_array[k].var_int_array = malloc(sizeof(((sixth_rec_ptr) 0)->var_int_array[0]) * rec6_array[k].icount);
1066 	rec6_array[k].var_double_array = malloc(sizeof(double) * rec6_array[k].icount);
1067 	rec6_array[k].var_string_array = malloc(sizeof(second_rec) * rec6_array[k].icount);
1068 	for (j = 0; j < rec6_array[k].icount; j++) {
1069 	    rec6_array[k].var_int_array[j] = 297 + j;
1070 	    rec6_array[k].var_double_array[j] = 2.717 * j;
1071 	    rec6_array[k].var_string_array[j].integer_field = 345 * j;
1072 	    rec6_array[k].var_string_array[j].short_field = j;
1073 	    rec6_array[k].var_string_array[j].long_field = 785 * j;
1074 	    rec6_array[k].var_string_array[j].string = malloc(15);
1075 	    memset(rec6_array[k].var_string_array[j].string, 0, 15);
1076 	    sprintf(rec6_array[k].var_string_array[j].string,
1077 		    "substring%d", j);
1078 	    rec6_array[k].var_string_array[j].double_field = 3.1415 * j;
1079 	    rec6_array[k].var_string_array[j].char_field = 'a' + 2 * j;
1080 	}
1081 	k++;
1082     }
1083     rec7_array[0].integer_field = 47;
1084     rec7_array[0].nested_rec.integer_field = 14;
1085     rec7_array[0].nested_rec.short_field = 27;
1086     rec7_array[0].nested_rec.long_field = 987234;
1087     rec7_array[0].nested_rec.string = "Another string";
1088     rec7_array[0].nested_rec.double_field = 2.717;
1089     rec7_array[0].nested_rec.char_field = 'A';
1090     rec7_array[0].string = "Yet another string";
1091 
1092     memset((char *) &rec8_array[0], 0, sizeof(rec8_array));
1093     rec8_array[0].integer_field = 9872346;
1094     rec8_array[0].string = "ABCD";
1095     rec8_array[0].double_field = 3.14159265358797323;
1096 
1097     rec8_array[1].integer_field = 23462346;
1098     rec8_array[1].string = "Efghij";
1099     rec8_array[1].double_field = 3.14159265358797323 * 2.0;
1100 
1101     rec8_array[2].integer_field = 2346987;
1102     rec8_array[2].string = "Klmn";
1103     rec8_array[2].double_field = 3.14159265358797323 * 3.0;
1104 
1105     index = 0;
1106     for (i = 1; i < 10; i += 2) {
1107         memset((char *) &rec9_array[index], 0, sizeof(ninth_rec));
1108 	memset((char *) &string_array_array[index], 0,
1109 	       sizeof(string_array_rec));
1110 	rec9_array[index].vec_length = i;
1111 	rec9_array[index].eventv = malloc(sizeof(((ninth_rec_ptr) 0)->eventv[0]) * rec9_array[index].vec_length);
1112 
1113 	string_array_array[index].array_len = i;
1114 	string_array_array[index].array = malloc(sizeof(char*) * i);
1115 
1116 	for (j = 0; j < rec9_array[index].vec_length; j++) {
1117 	    int k;
1118 	    rec9_array[index].eventv[j].iov_len = j + i;
1119 	    rec9_array[index].eventv[j].iov_base = malloc(j + i);
1120 	    string_array_array[index].array[j] = malloc(i + j + 2);
1121 
1122 	    for (k=0; k<j+i; k++) {
1123 		((char*)rec9_array[index].eventv[j].iov_base)[k] = 'A' + k + i/5;
1124 		string_array_array[index].array[j][k] = 'a' + k + i;
1125 	    }
1126 	    string_array_array[index].array[j][k] = 0;
1127 	}
1128 	if ((i %4) == 1) {
1129 	    string_array_array[index].base_string = NULL;
1130 	} else {
1131 	    string_array_array[index].base_string = strdup("Whoa there!");
1132 	}
1133 	index++;
1134     }
1135     derive.chan_str = "b013050800000000";
1136     derive.cond = 2;
1137     derive.client_channel_id.len = 12;
1138     derive.client_channel_id.channel = malloc(12);
1139     for(i=0; i < 12; i++) derive.client_channel_id.channel[i] = 2 * 1 + 1;
1140     derive.client_contact_str = "AAIAAEFQSUPEBc+CUFBJQ3yUAAA=";
1141     derive.filter = "{ return 1;}";
1142     derive.field_list_len = 3;
1143     derive.field_list = malloc(3*sizeof(derive.field_list[0]));
1144     derive.field_list[0].field_name = "num_points";
1145     derive.field_list[0].field_type = "integer";
1146     derive.field_list[0].field_size = 4;
1147     derive.field_list[0].field_offset = 0;
1148     derive.field_list[1].field_name = "image_data";
1149     derive.field_list[1].field_type = "PolygonPoints[num_points]";
1150     derive.field_list[1].field_size = 8;
1151     derive.field_list[1].field_offset = 4;
1152     derive.field_list[2].field_name = "";
1153     derive.field_list[2].field_type = "";
1154     derive.field_list[2].field_size = 0;
1155     derive.field_list[2].field_offset = 0;
1156     derive.format_list_len = 2;
1157     derive.format_list = malloc(2*sizeof(derive.format_list[0]));
1158     derive.format_list[0].format_name = "PipelinedPoint";
1159     derive.format_list[0].field_list_len = 7;
1160     derive.format_list[0].field_list =
1161       malloc(7*sizeof(derive.format_list[0].field_list[0]));
1162     derive.format_list[0].field_list[0].field_name = "x";
1163     derive.format_list[0].field_list[0].field_type = "integer";
1164     derive.format_list[0].field_list[0].field_size = 2;
1165     derive.format_list[0].field_list[0].field_offset = 0;
1166     derive.format_list[0].field_list[1].field_name = "y";
1167     derive.format_list[0].field_list[1].field_type = "integer";
1168     derive.format_list[0].field_list[1].field_size = 2;
1169     derive.format_list[0].field_list[1].field_offset = 2;
1170     derive.format_list[0].field_list[2].field_name = "z";
1171     derive.format_list[0].field_list[2].field_type = "integer";
1172     derive.format_list[0].field_list[2].field_size = 2;
1173     derive.format_list[0].field_list[2].field_offset = 4;
1174     derive.format_list[0].field_list[3].field_name = "r";
1175     derive.format_list[0].field_list[3].field_type = "integer";
1176     derive.format_list[0].field_list[3].field_size = 2;
1177     derive.format_list[0].field_list[3].field_offset = 6;
1178     derive.format_list[0].field_list[4].field_name = "g";
1179     derive.format_list[0].field_list[4].field_type = "integer";
1180     derive.format_list[0].field_list[4].field_size = 2;
1181     derive.format_list[0].field_list[4].field_offset = 8;
1182     derive.format_list[0].field_list[5].field_name = "b";
1183     derive.format_list[0].field_list[5].field_type = "integer";
1184     derive.format_list[0].field_list[5].field_size = 2;
1185     derive.format_list[0].field_list[5].field_offset = 10;
1186     derive.format_list[0].field_list[6].field_name = "";
1187     derive.format_list[0].field_list[6].field_type = "";
1188     derive.format_list[0].field_list[6].field_size = 0;
1189     derive.format_list[0].field_list[6].field_offset = 0;
1190     derive.format_list[1].format_name = "PolygonPoints";
1191     derive.format_list[1].field_list_len = 3;
1192     derive.format_list[1].field_list =
1193       malloc(3*sizeof(derive.format_list[1].field_list[0]));
1194     derive.format_list[1].field_list[0].field_name = "num_points";
1195     derive.format_list[1].field_list[0].field_type = "integer";
1196     derive.format_list[1].field_list[0].field_size = 4;
1197     derive.format_list[1].field_list[0].field_offset = 0;
1198     derive.format_list[1].field_list[1].field_name = "polygon_points";
1199     derive.format_list[1].field_list[1].field_type = "PipelinedPoint[num_points]";
1200     derive.format_list[1].field_list[1].field_size = 12;
1201     derive.format_list[1].field_list[1].field_offset = 4;
1202     derive.format_list[1].field_list[2].field_name = "";
1203     derive.format_list[1].field_list[2].field_type = "";
1204     derive.format_list[1].field_list[2].field_size = 0;
1205     derive.format_list[1].field_list[2].field_offset = 0;
1206     derive.init_data_block = NULL;
1207     derive.init_data_len = 0;
1208 
1209     multi_array.ifield = 4;
1210     multi_array2.ifield = 4;
1211     for (i = 0; i < 2; i++) {
1212 	for (j = 0; j < 2; j++) {
1213 	    for (k = 0; k < 2; k++) {
1214 		for (l = 0; l < 2; l++) {
1215 		    multi_array.double_array[i][j][k][l] =
1216 			1000*i + 100*j + 10*k +l;
1217 		    multi_array2.double_array[i][j][k][l] =
1218 			1000*i + 100*j + 10*k +l;
1219 		}
1220 	    }
1221 	}
1222     }
1223     multi_array.int_array = malloc(2*4*sizeof(int));
1224     multi_array2.int_array = malloc(2*4*sizeof(int));
1225     for (i = 0; i < 4; i++) {
1226 	for (j = 0; j < 2; j++) {
1227 	    multi_array.int_array[i][j] = 1000*i + 100*j;
1228 	}
1229     }
1230     multi_array.int_array2 = malloc(4*2*sizeof(int));
1231     multi_array2.int_array2 = malloc(4*2*sizeof(int));
1232     for (i = 0; i < 2; i++) {
1233 	for (j = 0; j < 4; j++) {
1234 	    multi_array.int_array2[i][j] = 1000*i + 100*j;
1235 	    (*multi_array2.int_array)[i][j] = 1000*i + 100*j;
1236 	}
1237     }
1238     for (i = 0; i < 4; i++) {
1239 	for (j = 0; j < 2; j++) {
1240 	    (*multi_array2.int_array2)[i][j] = 1000*i + 100*j;
1241 	}
1242     }
1243     multi_array.int_array3 = malloc(4*4*4*sizeof(int));
1244     multi_array2.int_array3 = malloc(4*4*4*sizeof(int));
1245     for (i = 0; i < 4; i++) {
1246 	for (j = 0; j < 4; j++) {
1247 	    for (k = 0; k < 4; k++) {
1248 		multi_array.int_array3[i][j][k] = 1000*i + 100*j + 10*k;
1249 		(*multi_array2.int_array3)[i][j][k] = 1000*i + 100*j + 10*k;
1250 	    }
1251 	}
1252     }
1253     fortran_array.ifield = 4;
1254     for (i = 0; i < 2; i++) {
1255 	for (j = 0; j < 2; j++) {
1256 	    for (k = 0; k < 2; k++) {
1257 		for (l = 0; l < 2; l++) {
1258 		    fortran_array.double_array[l][k][j][i] =
1259 			1000*i + 100*j + 10*k +l;
1260 		}
1261 	    }
1262 	}
1263     }
1264     fortran_array.int_array = malloc(2*4*sizeof(int));
1265     for (i = 0; i < 2; i++) {
1266 	for (j = 0; j < 4; j++) {
1267 	    (*((int (*)[4][2]) fortran_array.int_array))[j][i] = 1000*i + 100*j;
1268 	}
1269     }
1270     fortran_array.int_array2 = malloc(4*2*sizeof(int));
1271     for (i = 0; i < 4; i++) {
1272 	for (j = 0; j < 2; j++) {
1273 	    (*((int (*)[2][4]) fortran_array.int_array2))[j][i] = 1000*i + 100*j;
1274 	}
1275     }
1276     fortran_array.int_array3 = malloc(4*4*4*sizeof(int));
1277     for (i = 0; i < 4; i++) {
1278 	for (j = 0; j < 4; j++) {
1279 	    for (k = 0; k < 4; k++) {
1280 		fortran_array.int_array3[k][j][i] = 1000*i + 100*j + 10*k;
1281 	    }
1282 	}
1283     }
1284     triangle.corner1x = triangle.corner1y = triangle.corner1z = 4;
1285     triangle.corner2x = triangle.corner2y = triangle.corner2z = 6;
1286     triangle.compression_type = 5;
1287     triangle.codebook_size = 10;
1288     triangle.codebook_data = malloc(triangle.codebook_size * sizeof(int));
1289     for (i=0; i< triangle.codebook_size; i++) {
1290 	triangle.codebook_data[i] = i + 10;
1291     }
1292     triangle.timestamp = 12345;
1293     triangle.nonce = 5;
1294     triangle.num_meshes = 5;
1295     triangle.mesh_data = malloc(triangle.num_meshes * sizeof(triangle.mesh_data[0]));
1296     for (i=0; i < triangle.num_meshes; i++) {
1297 	int j;
1298 	triangle.mesh_data[i].id = i;
1299 	triangle.mesh_data[i].data_size = 20;
1300 	triangle.mesh_data[i].old_data_size = 20;
1301 	triangle.mesh_data[i].compressed_size = 5;
1302 	triangle.mesh_data[i].compressed_data = malloc(triangle.mesh_data[i].compressed_size * sizeof(int));
1303 	for (j = 0; j < triangle.mesh_data[i].compressed_size; j++) {
1304 	    triangle.mesh_data[i].compressed_data[j] = 2 * j + 40;
1305 	}
1306 	triangle.mesh_data[i].corner1x = triangle.mesh_data[i].corner1y =
1307 	    triangle.mesh_data[i].corner1z = i;
1308 	triangle.mesh_data[i].corner2x = triangle.mesh_data[i].corner2y =
1309 	    triangle.mesh_data[i].corner2z = i+1;
1310 	triangle.mesh_data[i].atom_type = 13;
1311     }
1312     add_action_record.action = 5;
1313     add_action_record.in_format_name = "my format";
1314     add_action_record.format_count = 2;
1315     add_action_record.out_formats = malloc(2*sizeof(add_action_record.out_formats[0]));
1316     add_action_record.out_formats[0].format_name = "PipelinedPoint";
1317     add_action_record.out_formats[0].xml_markup = NULL;
1318     add_action_record.out_formats[0].field_list_len = 7;
1319     add_action_record.out_formats[0].field_list =
1320       malloc(7*sizeof(add_action_record.out_formats[0].field_list[0]));
1321     add_action_record.out_formats[0].field_list[0].field_name = "x";
1322     add_action_record.out_formats[0].field_list[0].field_type = "integer";
1323     add_action_record.out_formats[0].field_list[0].field_size = 2;
1324     add_action_record.out_formats[0].field_list[0].field_offset = 0;
1325     add_action_record.out_formats[0].field_list[1].field_name = "y";
1326     add_action_record.out_formats[0].field_list[1].field_type = "integer";
1327     add_action_record.out_formats[0].field_list[1].field_size = 2;
1328     add_action_record.out_formats[0].field_list[1].field_offset = 2;
1329     add_action_record.out_formats[0].field_list[2].field_name = "z";
1330     add_action_record.out_formats[0].field_list[2].field_type = "integer";
1331     add_action_record.out_formats[0].field_list[2].field_size = 2;
1332     add_action_record.out_formats[0].field_list[2].field_offset = 4;
1333     add_action_record.out_formats[0].field_list[3].field_name = "r";
1334     add_action_record.out_formats[0].field_list[3].field_type = "integer";
1335     add_action_record.out_formats[0].field_list[3].field_size = 2;
1336     add_action_record.out_formats[0].field_list[3].field_offset = 6;
1337     add_action_record.out_formats[0].field_list[4].field_name = "g";
1338     add_action_record.out_formats[0].field_list[4].field_type = "integer";
1339     add_action_record.out_formats[0].field_list[4].field_size = 2;
1340     add_action_record.out_formats[0].field_list[4].field_offset = 8;
1341     add_action_record.out_formats[0].field_list[5].field_name = "b";
1342     add_action_record.out_formats[0].field_list[5].field_type = "integer";
1343     add_action_record.out_formats[0].field_list[5].field_size = 2;
1344     add_action_record.out_formats[0].field_list[5].field_offset = 10;
1345     add_action_record.out_formats[0].field_list[6].field_name = "";
1346     add_action_record.out_formats[0].field_list[6].field_type = "";
1347     add_action_record.out_formats[0].field_list[6].field_size = 0;
1348     add_action_record.out_formats[0].field_list[6].field_offset = 0;
1349     add_action_record.out_formats[1].format_name = "PolygonPoints";
1350     add_action_record.out_formats[1].xml_markup = NULL;
1351     add_action_record.out_formats[1].field_list_len = 3;
1352     add_action_record.out_formats[1].field_list =
1353       malloc(3*sizeof(add_action_record.out_formats[1].field_list[0]));
1354     add_action_record.out_formats[1].field_list[0].field_name = "num_points";
1355     add_action_record.out_formats[1].field_list[0].field_type = "integer";
1356     add_action_record.out_formats[1].field_list[0].field_size = 4;
1357     add_action_record.out_formats[1].field_list[0].field_offset = 0;
1358     add_action_record.out_formats[1].field_list[1].field_name = "polygon_points";
1359     add_action_record.out_formats[1].field_list[1].field_type = "PipelinedPoint[num_points]";
1360     add_action_record.out_formats[1].field_list[1].field_size = 12;
1361     add_action_record.out_formats[1].field_list[1].field_offset = 4;
1362     add_action_record.out_formats[1].field_list[2].field_name = "";
1363     add_action_record.out_formats[1].field_list[2].field_type = "";
1364     add_action_record.out_formats[1].field_list[2].field_size = 0;
1365     add_action_record.out_formats[1].field_list[2].field_offset = 0;
1366     add_action_record.func_str = "{ la la la }";
1367 }
1368 
1369 void
free_written_data()1370 free_written_data()
1371 {
1372     int i, j, k, index;
1373     k = 0;
1374     for (i = 1; i < 20; i += 5) {
1375 	for (j = 0; j < rec6_array[k].icount; j++) {
1376 	    free(rec6_array[k].var_string_array[j].string);
1377 	}
1378 	free(rec6_array[k].string);
1379 	free(rec6_array[k].var_int_array);
1380 	free(rec6_array[k].var_double_array);
1381 	free(rec6_array[k].var_string_array);
1382 	k++;
1383     }
1384     index = 0;
1385     for (i = 1; i < 10; i += 2) {
1386 	for (j = 0; j < rec9_array[index].vec_length; j++) {
1387 	    free(rec9_array[index].eventv[j].iov_base);
1388 	    free(string_array_array[index].array[j]);
1389 	}
1390 	free(rec9_array[index].eventv);
1391 	if (string_array_array[index].base_string != NULL)
1392 	    free(string_array_array[index].base_string);
1393 	free(string_array_array[index].array);
1394 	index++;
1395     }
1396     free(multi_array.int_array);
1397     free(multi_array.int_array2);
1398     free(multi_array.int_array3);
1399     free(multi_array2.int_array);
1400     free(multi_array2.int_array2);
1401     free(multi_array2.int_array3);
1402     free(fortran_array.int_array);
1403     free(fortran_array.int_array2);
1404     free(fortran_array.int_array3);
1405     free(derive.client_channel_id.channel);
1406     free(derive.field_list);
1407     free(derive.format_list[0].field_list);
1408     free(derive.format_list[1].field_list);
1409     free(derive.format_list);
1410     for (i=0; i<triangle.num_meshes; i++) {
1411 	free(triangle.mesh_data[i].compressed_data);
1412     }
1413     free(triangle.mesh_data);
1414     free(triangle.codebook_data);
1415     for (i=0; i<add_action_record.format_count; i++) {
1416 	free(add_action_record.out_formats[i].field_list);
1417     }
1418     free(add_action_record.out_formats);
1419 }
1420 
1421 FMField field_list[] = {
1422     {"integer field(14)", "integer",
1423        sizeof(int), FMOffset(first_rec_ptr, integer_field)},
1424     {"double field", "float",
1425        sizeof(double), FMOffset(first_rec_ptr, double_field)},
1426     {"char field(A)", "char",
1427        sizeof(char), FMOffset(first_rec_ptr, char_field)},
1428     { NULL, NULL, 0, 0}
1429 };
1430 
1431 FMStructDescRec first_format_list [] = {
1432     {"first format", field_list, sizeof(first_rec), NULL},
1433     {NULL, NULL, 0, NULL}};
1434 
1435 FMField newer_field_list[] = {
1436     {"ganzzahlfeld", "integer",
1437        sizeof(int), FMOffset(newer_rec_ptr, ganzzahl)},
1438     {"gleitkommazahlfeld", "float",
1439        sizeof(double), FMOffset(newer_rec_ptr, gleitkommazahl)},
1440     {"zeichenfeld", "char",
1441        sizeof(char), FMOffset(newer_rec_ptr, zeichen)},
1442     { NULL, NULL, 0, 0}
1443 };
1444 
1445 FMField field_list2[] = {
1446     {"integer field(-14)", "integer",
1447        sizeof(int), FMOffset(second_rec_ptr, integer_field)},
1448     {"short field", "integer",
1449        sizeof(short), FMOffset(second_rec_ptr, short_field)},
1450     {"long field(-9876129)", "integer",
1451        sizeof(long), FMOffset(second_rec_ptr, long_field)},
1452     {"string field", "string",
1453        sizeof(char *), FMOffset(second_rec_ptr, string)},
1454     {"double field(2.717)", "float",
1455        sizeof(double), FMOffset(second_rec_ptr, double_field)},
1456     {"char field", "char",
1457        sizeof(char), FMOffset(second_rec_ptr, char_field)},
1458     { NULL, NULL, 0, 0}
1459 };
1460 
1461 FMStructDescRec string_format_list[] = {
1462     {"string format", field_list2, sizeof(second_rec), NULL},
1463     {NULL, NULL, 0, NULL}};
1464 
1465 FMField field_list3[] = {
1466     {"integer field", "integer",
1467        sizeof(int), FMOffset(third_rec_ptr, integer_field)},
1468     {"long field", "integer",
1469        sizeof(long), FMOffset(third_rec_ptr, long_field)},
1470     {"uint field(4159015374)", "unsigned integer",
1471        sizeof(int), FMOffset(third_rec_ptr, uint_field)},
1472     {"ulong field(3969765680)", "unsigned integer",
1473        sizeof(long), FMOffset(third_rec_ptr, ulong_field)},
1474     {"string field", "string",
1475        sizeof(char *), FMOffset(third_rec_ptr, string)},
1476     {"double field(2.717)", "float",
1477        sizeof(double), FMOffset(third_rec_ptr, double_field)},
1478     {"string field2", "string",
1479        sizeof(char *), FMOffset(third_rec_ptr, string2)},
1480     {"char field", "char",
1481        sizeof(char), FMOffset(third_rec_ptr, char_field)},
1482     {"enum field(1)", "enumeration",
1483        sizeof(enum_type), FMOffset(third_rec_ptr, enum_field)},
1484     { NULL, NULL, 0, 0}
1485 };
1486 
1487 FMStructDescRec two_string_format_list[] = {
1488     {"two string format", field_list3, sizeof(third_rec), NULL},
1489     {NULL, NULL, 0, NULL}};
1490 
1491 FMField field_list4[] = {
1492     {"ifield", "integer",
1493        sizeof(long), FMOffset(fourth_rec_ptr, ifield)},
1494     {"int_array", FMArrayDecl(integer,ARRAY_SIZE),
1495        sizeof(int), FMOffset(fourth_rec_ptr, int_array[0])},
1496     {"double field", "float[2][2]",
1497        sizeof(double), FMOffset(fourth_rec_ptr, double_array[0][0])},
1498     { NULL, NULL, 0, 0}
1499 };
1500 
1501 FMStructDescRec fourth_format_list[] = {
1502     {"internal array format", field_list4, sizeof(fourth_rec), NULL},
1503     { NULL, NULL, 0, 0}
1504 };
1505 
1506 FMField embedded_field_list[] = {
1507     {"ifield", "integer",
1508        sizeof(short), FMOffset(embedded_rec_ptr, ifield)},
1509     {"string field", "string",
1510        sizeof(char *), FMOffset(embedded_rec_ptr, string)},
1511     {"dfield", "float",
1512        sizeof(double), FMOffset(embedded_rec_ptr, dfield)},
1513     {NULL, NULL, 0, 0}
1514 };
1515 
1516 FMField field_list5[] = {
1517     {"earray", "embedded[4]",
1518        sizeof(embedded_rec), FMOffset(fifth_rec_ptr, earray)},
1519     {NULL, NULL, 0, 0}
1520 };
1521 
1522 FMStructDescRec structured_format_list[] = {
1523     {"structured array format", field_list5, sizeof(fifth_rec), NULL},
1524     {"embedded", embedded_field_list, sizeof(embedded_rec), NULL},
1525     { NULL, NULL, 0, NULL}
1526 };
1527 
1528 FMField later_field_list[] = {
1529     {"integer field", "integer",
1530        sizeof(((later_rec_ptr)0)->integer_field), FMOffset(later_rec_ptr, integer_field)},
1531     {"string field", "string",
1532        sizeof(char *), FMOffset(later_rec_ptr, string)},
1533     {"double field", "float",
1534        sizeof(double), FMOffset(later_rec_ptr, double_field)},
1535     { NULL, NULL, 0, 0}
1536 };
1537 
1538 FMStructDescRec later_format_list[] = {
1539     {"later format", later_field_list, sizeof(later_rec), NULL},
1540     { NULL, NULL, 0, NULL}
1541 };
1542 
1543 
1544 FMField later_field_list2[] = {
1545     {"integer field", "integer",
1546        sizeof(((later_rec2_ptr)0)->integer_field),
1547        FMOffset(later_rec2_ptr, integer_field)},
1548     {"string field", "string",
1549        sizeof(char *), FMOffset(later_rec2_ptr, string)},
1550     {"double field", "float",
1551        sizeof(double), FMOffset(later_rec2_ptr, double_field)},
1552     { NULL, NULL, 0, 0}
1553 };
1554 
1555 FMField nested_field_list[] = {
1556     {"integer field", "integer",
1557        sizeof(((nested_rec_ptr)0)->integer_field),
1558        FMOffset(nested_rec_ptr, integer_field)},
1559     {"nested record", "string format",
1560        sizeof(second_rec), FMOffset(nested_rec_ptr, nested_rec)},
1561     {"string field", "string",
1562        sizeof(char *), FMOffset(nested_rec_ptr, string)},
1563     { NULL, NULL, 0, 0}
1564 };
1565 
1566 FMStructDescRec nested_format_list[] = {
1567     {"nested format", nested_field_list, sizeof(nested_rec), NULL},
1568     {"string format", field_list2, sizeof(second_rec), NULL},
1569     { NULL, NULL, 0, 0}
1570 };
1571 
1572 FMStructDescRec embedded_format_list[] = {
1573     {"embedded", embedded_field_list, sizeof(embedded_rec), NULL},
1574     { NULL, NULL, 0, 0}
1575 };
1576 
1577 FMField field_list6[] = {
1578     {"string field", "string",
1579        sizeof(char *), FMOffset(sixth_rec_ptr, string)},
1580     {"icount", "integer",
1581        sizeof(long), FMOffset(sixth_rec_ptr, icount)},
1582     {"var_int_array", "integer[icount]",
1583        sizeof(((sixth_rec_ptr)0)->var_int_array[0]), FMOffset(sixth_rec_ptr, var_int_array)},
1584     {"var_string_array", "string format[icount]",
1585        sizeof(second_rec), FMOffset(sixth_rec_ptr, var_string_array)},
1586     {"double field", "float",
1587        sizeof(double), FMOffset(sixth_rec_ptr, dfield)},
1588     {"var_double_array", "float[icount]",
1589        sizeof(double), FMOffset(sixth_rec_ptr, var_double_array)},
1590     { NULL, NULL, 0, 0}
1591 };
1592 
1593 FMStructDescRec variant_format_list[] = {
1594     {"variant array format", field_list6, sizeof(sixth_rec), NULL},
1595     {"string format", field_list2, sizeof(second_rec), NULL},
1596     { NULL, NULL, 0, 0}
1597 };
1598 
1599 FMField event_vec_elem_fields[] =
1600 {
1601     {"elem", "char[len]", sizeof(char), FMOffset(IOEncodeVector,iov_base)},
1602     {"len", "integer", sizeof(((IOEncodeVector)0)[0].iov_len),
1603      FMOffset(IOEncodeVector, iov_len)},
1604     {(char *) 0, (char *) 0, 0, 0}
1605 };
1606 
1607 FMField field_list9[] =
1608 {
1609     {"vec_length", "integer", sizeof(int),
1610      FMOffset(ninth_rec_ptr, vec_length)},
1611     {"eventv", "EventVecElem[vec_length]", sizeof(struct _io_encode_vec),
1612      FMOffset(ninth_rec_ptr, eventv)},
1613     {(char *) 0, (char *) 0, 0, 0}
1614 };
1615 
1616 FMStructDescRec ninth_format_list[] =
1617 {
1618     {"EventV", field_list9, sizeof(ninth_rec), NULL},
1619     {"EventVecElem", event_vec_elem_fields, sizeof(struct _io_encode_vec), NULL},
1620     {NULL, NULL, 0, NULL}
1621 };
1622 
1623 
1624 FMField string_array_field_list[] =
1625 {
1626     {"array_len", "integer", sizeof(int),
1627      FMOffset(string_array_rec_ptr, array_len)},
1628     {"base_string", "string", sizeof(char*),
1629      FMOffset(string_array_rec_ptr, base_string)},
1630     {"array", "string[array_len]", sizeof(char*),
1631      FMOffset(string_array_rec_ptr, array)},
1632     {(char *) 0, (char *) 0, 0, 0}
1633 
1634 };
1635 
1636 FMStructDescRec string_array_format_list[] =
1637 {
1638     {"string_array", string_array_field_list, sizeof(string_array_rec), NULL},
1639     {NULL, NULL, 0, NULL}
1640 };
1641 
1642 FMField channel_id_flds[] = {
1643     {"len", "integer", sizeof(int), FMOffset(channel_ID_struct *, len)},
1644     {"id", "char[len]", 1, FMOffset(channel_ID_struct *, channel)},
1645     {(char *) 0, (char *) 0, 0, 0}
1646 };
1647 
1648 FMField field_list_flds[] = {
1649     {"field_name", "string", sizeof(char *),
1650      FMOffset(FMFieldList, field_name)},
1651     {"field_type", "string", sizeof(char *),
1652      FMOffset(FMFieldList, field_type)},
1653     {"field_size", "integer", sizeof(int),
1654      FMOffset(FMFieldList, field_size)},
1655     {"field_offset", "integer", sizeof(int),
1656      FMOffset(FMFieldList, field_offset)},
1657     {(char *) 0, (char *) 0, 0, 0}
1658 };
1659 
1660 FMField format_list_field_list[] = {
1661     {"format_name", "string", sizeof(char *),
1662      FMOffset(format_list_element *, format_name)},
1663     {"field_list_len", "integer", sizeof(int),
1664      FMOffset(format_list_element *, field_list_len)},
1665     {"field_list", "IOfield_list[field_list_len]", sizeof(FMField),
1666      FMOffset(format_list_element *, field_list)}
1667     ,
1668     {(char *) 0, (char *) 0, 0, 0}
1669 };
1670 
1671 FMField derive_msg_field_list[] = {
1672     {"channel", "string", sizeof(char *),
1673      FMOffset(DeriveMsgPtr, chan_str)},
1674     {"condition", "integer", sizeof(int), FMOffset(DeriveMsgPtr, cond)},
1675     {"client_channel_id", "channel_ID", sizeof(channel_ID_struct),
1676      FMOffset(DeriveMsgPtr, client_channel_id)}
1677     ,
1678     {"client_contact_str", "string", sizeof(char *),
1679      FMOffset(DeriveMsgPtr, client_contact_str)},
1680     {"filter", "string", sizeof(char *), FMOffset(DeriveMsgPtr, filter)},
1681     {"field_list_len", "integer", sizeof(int),
1682      FMOffset(DeriveMsgPtr, field_list_len)},
1683     {"field_list", "IOfield_list[field_list_len]", sizeof(FMField),
1684      FMOffset(DeriveMsgPtr, field_list)}
1685     ,
1686     {"format_list_len", "integer", sizeof(int),
1687      FMOffset(DeriveMsgPtr, format_list_len)},
1688     {"format_list", "DEFormatList[format_list_len]",
1689      sizeof(format_list_element), FMOffset(DeriveMsgPtr, format_list)}
1690     ,
1691     {"init_data_block", "char[init_data_len]",
1692      1, FMOffset(DeriveMsgPtr, init_data_block)}
1693     ,
1694     {"init_data_len", "integer",
1695      sizeof(int), FMOffset(DeriveMsgPtr, init_data_len)},
1696     {(char *) 0, (char *) 0, 0, 0}
1697 };
1698 
1699 FMStructDescRec derive_format_list[] = {
1700     {"Channel Derive", derive_msg_field_list, sizeof(DeriveMsg), NULL},
1701     {"IOfield_list", field_list_flds, sizeof(FMField), NULL},
1702     {"DEFormatList", format_list_field_list, sizeof(format_list_element), NULL},
1703     {"channel_ID", channel_id_flds, sizeof(channel_ID_struct), NULL},
1704     {NULL, NULL, 0, NULL}
1705 };
1706 
1707 
1708 FMField multi_array_flds[] = {
1709     {"ifield", "integer", sizeof(long), FMOffset(multi_array_rec_ptr, ifield)},
1710     {"double_array", "float[2][2][2][2]", sizeof(double),
1711      FMOffset(multi_array_rec_ptr, double_array)},
1712     {"int_array", "integer[2][ifield]", sizeof(int),
1713      FMOffset(multi_array_rec_ptr, int_array)},
1714     {"int_array2", "integer[ifield][2]", sizeof(int),
1715      FMOffset(multi_array_rec_ptr, int_array2)},
1716     {"int_array3", "integer[ifield][ifield][ifield]", sizeof(int),
1717     FMOffset(multi_array_rec_ptr, int_array3)},
1718     {(char *) 0, (char *) 0, 0, 0}
1719 };
1720 
1721 FMStructDescRec multi_array_format_list[] = {
1722     {"multi_array", multi_array_flds, sizeof(multi_array), NULL},
1723     {NULL, NULL, 0, NULL}
1724 };
1725 
1726 FMField compressed_mesh[] = {
1727   {"id", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,id)},
1728   {"data_size", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,data_size)},
1729   {"old_data_size", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,old_data_size)},
1730   {"compressed_size", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,compressed_size)},
1731   {"compressed_data", "integer[compressed_size]", sizeof(int), FMOffset(compressed_mesh_param_ptr,compressed_data)},
1732   {"corner1x", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,corner1x)},
1733   {"corner1y", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,corner1y)},
1734   {"corner1z", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,corner1z)},
1735   {"corner2x", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,corner2x)},
1736   {"corner2y", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,corner2y)},
1737   {"corner2z", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,corner2z)},
1738   {"atom_type", "integer", sizeof(int), FMOffset(compressed_mesh_param_ptr,atom_type)},
1739   {NULL, NULL, 0 , 0}
1740 };
1741 
1742 FMField triangle_field[] = {
1743   //  {"num_ints", "integer", sizeof(int), FMOffset(triangle_param_ptr,num_ints)},
1744   //  {"triangle_data", "integer[num_ints]", sizeof(int), FMOffset(triangle_param_ptr,triangle_data)},
1745   {"corner1x", "integer", sizeof(int), FMOffset(triangle_param_ptr, corner1x)},
1746   {"corner1y", "integer", sizeof(int), FMOffset(triangle_param_ptr, corner1y)},
1747   {"corner1z", "integer", sizeof(int), FMOffset(triangle_param_ptr, corner1z)},
1748   {"corner2x", "integer", sizeof(int), FMOffset(triangle_param_ptr, corner2x)},
1749   {"corner2y", "integer", sizeof(int), FMOffset(triangle_param_ptr, corner2y)},
1750   {"corner2z", "integer", sizeof(int), FMOffset(triangle_param_ptr, corner2z)},
1751 
1752   {"compression_type", "integer", sizeof(int), FMOffset(triangle_param_ptr, compression_type)},
1753 
1754   {"codebook_size", "integer", sizeof(int), FMOffset(triangle_param_ptr,codebook_size)},
1755   {"codebook_data", "integer[codebook_size]", sizeof(int), FMOffset(triangle_param_ptr,codebook_data)},
1756 
1757   {"timestamp", "integer", sizeof(int), FMOffset(triangle_param_ptr,timestamp)},
1758   {"nonce", "integer", sizeof(int), FMOffset(triangle_param_ptr, nonce)},
1759   {"num_meshes", "integer", sizeof(int), FMOffset(triangle_param_ptr,num_meshes)},
1760   {"mesh_data", "compressed_mesh_param[num_meshes]", sizeof(compressed_mesh_param), FMOffset(triangle_param_ptr,mesh_data)},
1761 
1762   {NULL, NULL, 0 , 0}
1763 };
1764 
1765 FMStructDescRec triangle_format_list[] = {
1766     {"triangle_param", triangle_field, sizeof(triangle), NULL},
1767     {"compressed_mesh_param", compressed_mesh, sizeof(compressed_mesh_param), NULL},
1768     {NULL, NULL, 0, NULL}
1769 };
1770 
1771 FMField add_field_list[] =
1772 {
1773     {"action_type", "integer",
1774      sizeof(int), FMOffset(add_rec_ptr, action)},
1775     {"in_format_name", "string",
1776      sizeof(char*), FMOffset(add_rec_ptr, in_format_name)},
1777     {"func_str", "string",
1778      sizeof(char*), FMOffset(add_rec_ptr, func_str)},
1779     {"format_count", "integer",
1780      sizeof(int), FMOffset(add_rec_ptr, format_count)},
1781     {"out_formats", "XMLFormatList[format_count]",
1782      sizeof(msg_format_list_element), FMOffset(add_rec_ptr, out_formats)},
1783     {NULL, NULL, 0, 0}
1784 };
1785 
1786 FMStructDescRec add_action_format_list[] =
1787 {
1788     {"add_action", add_field_list, sizeof(add_action_record), NULL},
1789     {"XMLFormatList", xml_format_list_flds, sizeof(msg_format_list_element), NULL},
1790     {"IOfield_list", field_list_flds, sizeof(FMField), NULL},
1791     {NULL, NULL, 0, 0}
1792 };
1793 
1794 FMField xml_format_list_flds[] =
1795 {
1796     {"format_name", "string", sizeof(char *),
1797      FMOffset(msg_format_list_element*, format_name)},
1798     {"field_list_len", "integer", sizeof(int),
1799      FMOffset(msg_format_list_element*, field_list_len)},
1800     {"field_list", "IOfield_list[field_list_len]", sizeof(FMField),
1801      FMOffset(msg_format_list_element*, field_list)},
1802     {"xml_markup", "string",
1803      sizeof(char*), FMOffset(msg_format_list_element*, xml_markup)},
1804     {(char *) 0, (char *) 0, 0, 0}
1805 };
1806 
1807 FMField node_field_list[] =
1808 {
1809     {"node_num", "integer", sizeof(int), FMOffset(node_ptr, node_num)},
1810     {"link1", "*node", sizeof(struct node), FMOffset(node_ptr, link1)},
1811     {"link2", "*node", sizeof(struct node), FMOffset(node_ptr, link2)},
1812     {(char *) 0, (char *) 0, 0, 0}
1813 };
1814 
1815 FMStructDescRec node_format_list [] = {
1816     {"node", node_field_list, sizeof(struct node), NULL},
1817     {NULL, NULL, 0, NULL}
1818 };
1819 
1820 static int
already_visited(visit_table v,node_ptr n)1821 already_visited(visit_table v, node_ptr n)
1822 {
1823     int i;
1824     for (i=0; i < v->node_count; i++) {
1825 	if (v->nodes[i] == n) return 1;
1826     }
1827     v->nodes[v->node_count] = n;
1828     v->node_count++;
1829     return 0;
1830 }
1831 
calc_signature(node_ptr n,visit_table v)1832 extern int calc_signature(node_ptr n, visit_table v)
1833 {
1834     int n1, n2;
1835     if (n == NULL) return 0;
1836     if (already_visited(v, n)) {
1837 	return 5 * n->node_num;
1838     }
1839     n1 = calc_signature(n->link1, v);
1840     n2 = calc_signature(n->link1, v);
1841     return  3*n1 + 7 * n2 + n->node_num;
1842 }
1843