1 #include "config.h"
2
3 #ifdef HAVE_UNISTD_H
4 #include <unistd.h>
5 #endif
6 #ifdef HAVE_MALLOC_H
7 #include <malloc.h>
8 #endif
9 #ifdef HAVE_STRING_H
10 #include <string.h>
11 #endif
12 #include <sys/types.h>
13 #include <ctype.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #ifdef HAVE_MEMORY_H
17 #include <memory.h>
18 #endif
19 #include <limits.h>
20
21 #include "assert.h"
22 #include "fm.h"
23 #include "fm_internal.h"
24
25 struct _xml_output_info {
26 char *prestring; /* output this before this field */
27 int field_num;
28 FMFieldPtr field_ptr;
29 FMdata_type base_type;
30 FMVarInfoStruct *iovar; /* for dynamic arrays, array size */
31 char *element_prestring;
32 char *element_poststring;
33 char *poststring; /* output this after this field */
34 };
35
36 typedef struct dstring {
37 char *string;
38 int length;
39 int max_alloc;
40 } *ffs_dstring;
41
42 static int get_int_attr(int *int_ptr, char *name, char *start, char *end);
43 static int get_str_attr(char **str_ptr, char *name, char *start, char *end);
44 static void internal_record_to_XML_string(FMFormat format, void *data,
45 void *string_base, ffs_dstring ds,
46 int encoded);
47 static void
48 generic_field_to_XML(FMFormat format, int field,
49 void *data, void *string_base, int encode,
50 ffs_dstring ds);
51
52
53 static int
is_tag(char * tag,char * xml_stream)54 is_tag(char *tag, char *xml_stream)
55 {
56 int len = strlen(tag);
57 if (strncmp(xml_stream, tag, len) != 0) return 0;
58 if (isalnum((int)xml_stream[len])) return 0; /* not end of stream tag */
59 if (xml_stream[len] == '_') return 0;
60 if (xml_stream[len] == '-') return 0;
61 return 1;
62 }
63
64 extern void
free_XML_output_info(xml_output_info info)65 free_XML_output_info(xml_output_info info)
66 {
67 int i = 0;
68 while(info[i].field_ptr == NULL) {
69 if (info[i].prestring != NULL) free(info[i].prestring);
70 if (info[i].poststring != NULL) free(info[i].poststring);
71 if (info[i].element_prestring != NULL)
72 free(info[i].element_prestring);
73 if (info[i].element_poststring != NULL)
74 free(info[i].element_poststring);
75 }
76 free(info);
77 }
78
79
80
81 static void
expand_dstring(ffs_dstring ds,int min)82 expand_dstring(ffs_dstring ds, int min)
83 {
84 int len = ds->max_alloc;
85 int add = ds->max_alloc >> 3; /* add an eighth */
86 if (add < min) add = min;
87 if (add < 128) add = 128;
88 ds->string = realloc(ds->string, len + add);
89 ds->max_alloc = len + add;
90 }
91
92 static void
dcatstr(ffs_dstring ds,char * str)93 dcatstr(ffs_dstring ds, char *str)
94 {
95 int len = strlen(str);
96 if (ds->length + len + 1 > ds->max_alloc) {
97 expand_dstring(ds, len + 1);
98 }
99 strcat(&ds->string[ds->length], str);
100 ds->length += len;
101 }
102
103 static ffs_dstring
new_dstring()104 new_dstring()
105 {
106 ffs_dstring dstr = malloc(sizeof(struct dstring));
107 dstr->string = malloc(64);
108 dstr->string[0] = 0;
109 dstr->length = 0;
110 dstr->max_alloc = 64;
111 return dstr;
112 }
113
114 static ffs_dstring
record_to_XML_string(FMFormat format,void * data,int encoded)115 record_to_XML_string(FMFormat format, void *data, int encoded)
116 {
117 ffs_dstring dstr = new_dstring();
118 internal_record_to_XML_string(format, data, data, dstr, encoded);
119 return dstr;
120 }
121
122 static ffs_dstring
raw_to_XML_string(c,format,data,encoded)123 raw_to_XML_string(c, format, data, encoded)
124 FMContext c;
125 FMFormat format;
126 void *data;
127 int encoded;
128 {
129 int index;
130 ffs_dstring ds;
131 if (FMhas_XML_info(format)) {
132 return record_to_XML_string(format, data, encoded);
133 }
134 ds = new_dstring();
135 dcatstr(ds, "<");
136 dcatstr(ds, format->format_name);
137 dcatstr(ds, ">\n");
138 for (index = 0; index < format->field_count; index++) {
139 generic_field_to_XML(format, index, data, data,
140 encoded, ds);
141 }
142 dcatstr(ds, "</");
143 dcatstr(ds, format->format_name);
144 dcatstr(ds, ">\n");
145 return ds;
146 }
147
148 extern void
149 dump_raw_IOrecord_as_XML(c, format, data)
150 FMContext c;
151 FMFormat format;
152 void *data;
153 {
154 ffs_dstring dstr = raw_to_XML_string(c, format, data, 1);
155 printf("%s", dstr->string);
156 }
157
158 extern char*
FMunencoded_to_XML_string(FMContext fmcontext,FMFormat format,void * data)159 FMunencoded_to_XML_string(FMContext fmcontext, FMFormat format, void *data)
160 {
161 ffs_dstring dstr = raw_to_XML_string((FMContext)fmcontext, format, data, 0);
162 char *str = dstr->string;
163 free(dstr);
164 return str;
165 }
166
167 extern void
internal_dump_XML_record(FMFormat format,void * data,void * string_base,int encoded)168 internal_dump_XML_record(FMFormat format, void *data, void *string_base, int encoded)
169 {
170 struct dstring ds;
171 ds.string = malloc(64);
172 ds.string[0] = 0;
173 ds.length = 0;
174 ds.max_alloc = 64;
175 internal_record_to_XML_string(format, data, string_base, &ds, encoded);
176 printf("%s", ds.string);
177 free(ds.string);
178 }
179
180 static long
get_static_array_element_count(FMVarInfoList var)181 get_static_array_element_count(FMVarInfoList var)
182 {
183 int i;
184 long count = 1;
185 if (var == NULL) return 1;
186 for (i = 0; i < var->dimen_count; i++) {
187 if (var->dimens[i].static_size != 0) {
188 count = count * var->dimens[i].static_size;
189 } else {
190 return -1;
191 }
192 }
193 return count;
194 }
195
196 static void
internal_record_to_XML_string(FMFormat format,void * data,void * string_base,ffs_dstring ds,int encoded)197 internal_record_to_XML_string(FMFormat format, void *data, void *string_base, ffs_dstring ds, int encoded)
198
199 {
200 int i = -1;
201 xml_output_info info;
202 if (!FMhas_XML_info(format)) {
203 FMdump_XML(format, data, encoded);
204 return;
205 }
206 info = format->xml_out;
207 while(info[++i].field_ptr != NULL) {
208 int j;
209 int array_dimen = get_static_array_element_count(info[i].iovar);
210 void *base = (char*)data;
211 FMFieldPtr field_ptr = info[i].field_ptr;
212 struct _FMgetFieldStruct dummy_ptr;
213 if (info[i].prestring != NULL) {
214 dcatstr(ds, info[i].prestring);
215 /* printf("%s", info[i].prestring);*/
216 }
217 if (array_dimen == -1) {
218 array_dimen = FMget_array_element_count(format, info[i].iovar, base, 1);
219 dummy_ptr = *field_ptr;
220 dummy_ptr.size = format->pointer_size;
221 dummy_ptr.data_type = integer_type;
222 base = get_FMaddr(&dummy_ptr, base, string_base, encoded);
223 dummy_ptr = *field_ptr;
224 field_ptr = &dummy_ptr;
225 dummy_ptr.offset = 0;
226 }
227 for(j=0; j<array_dimen; j++) {
228 if (info[i].element_prestring != NULL) {
229 dcatstr(ds, info[i].element_prestring);
230 /* printf("%s", info[i].element_prestring);*/
231 }
232 switch(info[i].base_type) {
233 case integer_type:
234 {
235 char tmp[64];
236 long l;
237 l = get_FMlong(field_ptr, base);
238 sprintf(tmp, "%ld", l);
239 dcatstr(ds, tmp);
240 break;
241 }
242 case unsigned_type:
243 case enumeration_type:
244 {
245 char tmp[64];
246 unsigned long l;
247 l = get_FMulong(field_ptr, base);
248 sprintf(tmp, "%lu", l);
249 dcatstr(ds, tmp);
250 break;
251 }
252 case boolean_type:
253 {
254 unsigned long l;
255 l = get_FMulong(field_ptr, base);
256 if (l)
257 dcatstr(ds, "true");
258 else
259 dcatstr(ds, "false");
260 break;
261 }
262 case float_type:
263 {
264 char tmp[64];
265 double d;
266 d = get_FMdouble(field_ptr, base);
267 sprintf(tmp, "%g", d);
268 dcatstr(ds, tmp);
269 break;
270 }
271 case char_type:
272 {
273 char tmp[2];
274 tmp[0] = get_FMchar(field_ptr, base);
275 tmp[1] = 0;
276 dcatstr(ds, tmp);
277 break;
278 }
279 case string_type:
280 {
281 char *s;
282 s = get_FMaddr(field_ptr, base, string_base, encoded);
283 if (s) dcatstr(ds, s);
284 break;
285 }
286 case unknown_type:
287 {
288 int field = info[i].field_num;
289 int offset = field_ptr->offset;
290 FMFormat sub = format->field_subformats[field];
291 if (sub != NULL) {
292 internal_record_to_XML_string(sub, (char*)base+offset,
293 string_base, ds, encoded);
294 } else {
295 dcatstr(ds, "<INCONSISTENCY! SUBFORMAT NOT FOUND FOR FIELD TYPE \"");
296 dcatstr(ds, (char*)format->field_list[field].field_type);
297 dcatstr(ds, "\">\n");
298 }
299 break;
300 }
301 } /* end switch */
302 if (info[i].element_poststring != NULL) {
303 dcatstr(ds, info[i].element_poststring);
304 }
305 if ((info[i].element_prestring == NULL) &&
306 (info[i].element_poststring == NULL)
307 && (info[i].base_type != unknown_type)) {
308 dcatstr(ds, " ");
309 }
310
311 base = (char *) base + field_ptr->size;
312 }
313 if (info[i].poststring != NULL) {
314 dcatstr(ds, info[i].poststring);
315 }
316 }
317 }
318
319 extern void
FMdump_XML(FMFormat format,void * data,int encoded)320 FMdump_XML(FMFormat format, void *data, int encoded)
321 {
322 internal_dump_XML_record(format, data, data, encoded);
323 }
324
325 static int
get_field_num(int * field_num_ptr,FMFormat format,char * left,char * right)326 get_field_num(int* field_num_ptr, FMFormat format, char *left, char *right)
327 {
328 char *field_name = NULL;
329 int field_num;
330 if (!get_str_attr(&field_name, "field_name", left, right)) {
331 if (!get_int_attr(&field_num, "field_id", left, right)) {
332 printf("Neither Field_name nor Field_id attribute found\n");
333 return 0;
334 }
335 } else {
336 field_num = 0;
337 while(strcmp(format->field_list[field_num].field_name,
338 field_name) != 0) {
339 field_num++;
340 if (field_num >= format->field_count) {
341 printf("Field name %s not found in format\n", field_name);
342 free(field_name);
343 return 0;
344 }
345 }
346 free(field_name);
347 }
348 if (field_num >= format->field_count) {
349 printf("Field number %d too big\n", field_num);
350 return 0;
351 }
352 *field_num_ptr = field_num;
353 return 1;
354 }
355
356 extern void *
get_optinfo_FMFormat(FMFormat format,int info_type,int * len_p)357 get_optinfo_FMFormat(FMFormat format, int info_type, int *len_p)
358 {
359 int i = 0;
360 if (format->opt_info == NULL) return NULL;
361 while(format->opt_info[i].info_type != 0) {
362 if (format->opt_info[i].info_type == info_type) {
363 *len_p = format->opt_info[i].info_len;
364 return (void*)format->opt_info[i].info_block;
365 }
366 i++;
367 }
368 return NULL;
369 }
370
371 extern FMfloat_format fm_my_float_format;
372
373 static xml_output_info
build_XML_output_info(FMFormat format)374 build_XML_output_info(FMFormat format)
375 {
376 int i = 0, last_mark;
377 char *XML_opt_data = NULL;
378 int XML_data_len = 0;
379 xml_output_info info = NULL;
380 int info_count = 0;
381
382 XML_opt_data = get_optinfo_FMFormat(format, 0x584D4C20, &XML_data_len);
383
384 if (XML_opt_data == NULL) return NULL;
385 last_mark = 0;
386 i = -1;
387 while (++i < XML_data_len) {
388 if (XML_opt_data[i] != '<') {
389 continue;
390 }
391 if (is_tag("/FFS:array", &XML_opt_data[i+1])) {
392 /* array terminatfmn */
393 int post_len = i - last_mark + 1;
394 info[info_count].element_poststring = malloc(post_len);
395 strncpy(info[info_count].element_poststring,
396 &XML_opt_data[last_mark], post_len -1);
397 info[info_count].element_poststring[post_len -1] = 0;
398 info_count++;
399 i += 13;
400 last_mark = i;
401 continue;
402 }
403 if (is_tag("FFS:data", &XML_opt_data[i+1])) {
404 int pre_len = i - last_mark;
405 FMdata_type data_type;
406 int field_num;
407 long junk;
408 char *right_end = strchr(&XML_opt_data[i+9], '>');
409 char *prestring = malloc(pre_len + 1);
410 FMFieldPtr field_ptr = NULL;
411
412 strncpy(prestring, &XML_opt_data[last_mark], pre_len);
413 prestring[pre_len] = 0;
414 if (!get_field_num(&field_num, format, XML_opt_data + i + 9,
415 right_end)) {
416 i = right_end - XML_opt_data;
417 continue;
418 }
419 data_type = FMarray_str_to_data_type(format->field_list[field_num].field_type,
420 &junk);
421 field_ptr = malloc(sizeof(struct _FMgetFieldStruct));
422 field_ptr->offset = format->field_list[field_num].field_offset;
423 field_ptr->size = format->field_list[field_num].field_size;
424 field_ptr->data_type = data_type;
425 field_ptr->byte_swap = format->byte_reversal;
426 field_ptr->src_float_format = format->float_format;
427 field_ptr->target_float_format = fm_my_float_format;
428 if (info_count == 0) {
429 info = malloc(sizeof(*info) * 2);
430 } else {
431 info = realloc(info, sizeof(*info) * (info_count + 2));
432 }
433 info[info_count+1].field_ptr = NULL;
434 info[info_count].prestring = prestring;
435 info[info_count].field_ptr = field_ptr;
436 info[info_count].base_type = data_type;
437 info[info_count].poststring = NULL;
438 info[info_count].field_num = field_num;
439 info[info_count].iovar = &format->var_list[field_num];
440 info[info_count].element_prestring = NULL;
441 info[info_count].element_poststring = NULL;
442 info_count++;
443 i = right_end - XML_opt_data;
444 last_mark = i + 1;
445 continue;
446 }
447 if (is_tag("FFS:array", &XML_opt_data[i+1])) {
448 /* array terminatfmn */
449 int pre_len = i - last_mark;
450 char *right_end = strchr(&XML_opt_data[i+10], '>');
451 char *prestring = malloc(pre_len + 1);
452
453 strncpy(prestring, &XML_opt_data[last_mark], pre_len);
454 prestring[pre_len] = 0;
455 if (info_count == 0) {
456 info = malloc(sizeof(*info) * 2);
457 } else {
458 info = realloc(info, sizeof(*info) * (info_count + 2));
459 }
460 info[info_count+1].field_ptr = NULL;
461 info[info_count].prestring = prestring;
462 info[info_count].poststring = NULL;
463 i = right_end - XML_opt_data;
464 last_mark = i + 1;
465 continue;
466 }
467 if (is_tag("FFS:array_data_mark", &XML_opt_data[i+1])) {
468 /* array terminatfmn */
469 int pre_len = i - last_mark;
470 int field_num;
471 char *right_end = strchr(&XML_opt_data[i+9], '>');
472 char *prestring = malloc(pre_len + 1);
473 long elements;
474 FMdata_type data_type;
475 FMFieldPtr field_ptr = NULL;
476
477 strncpy(prestring, &XML_opt_data[last_mark], pre_len);
478 prestring[pre_len] = 0;
479 if (!get_field_num(&field_num, format, XML_opt_data + i + 9,
480 right_end)) {
481 i = right_end - XML_opt_data;
482 continue;
483 }
484 info[info_count].element_prestring = prestring;
485 data_type = FMarray_str_to_data_type(format->field_list[field_num].field_type,
486 &elements);
487 info[info_count].iovar = &format->var_list[field_num];
488 info[info_count].base_type = data_type;
489 info[info_count].field_num = field_num;
490 field_ptr = malloc(sizeof(struct _FMgetFieldStruct));
491 field_ptr->offset = format->field_list[field_num].field_offset;
492 field_ptr->size = format->field_list[field_num].field_size;
493 field_ptr->data_type = data_type;
494 field_ptr->byte_swap = format->byte_reversal;
495 field_ptr->src_float_format = format->float_format;
496 field_ptr->target_float_format = fm_my_float_format;
497 info[info_count].field_ptr = field_ptr;
498 i = right_end - XML_opt_data;
499 last_mark = i + 1;
500 continue;
501 }
502 }
503 if (info_count != 0) {
504 int post_len = XML_data_len - last_mark;
505 char *poststring = malloc(post_len + 1);
506 strncpy(poststring, &XML_opt_data[last_mark], post_len);
507 poststring[post_len] = 0;
508 info[info_count-1].poststring = poststring;
509 info[info_count].field_ptr = NULL;
510 /* for(i=0; i < info_count; i++) {
511 printf("XML field info:\n");
512 printf(" prestring = \"%s\"\n", info[i].prestring);
513 printf(" field num = \"%d\"\n", info[i].field_num);
514 printf(" field name = \"%s\"\n",
515 format->field_list[info[i].field_num].field_name);
516 printf(" poststring = \"%s\"\n", info[i].poststring == NULL ?
517 "(NULL)":info[i].poststring);
518 }*/
519 return info;
520 } else {
521 return NULL;
522 }
523 }
524
525 static int
get_int_attr(int * int_ptr,char * name,char * start,char * end)526 get_int_attr(int *int_ptr, char *name, char *start, char *end)
527 {
528 int name_len = strlen(name);
529 start -= 1;
530 while(++start < (end - name_len)) {
531 if (*start == *name) {
532 /* first char eq, check further */
533 if (is_tag(name, start)) {
534 char *point = &start[name_len];
535 char *tmp;
536 while (isspace((int)*point)) point++;
537 if (point > end) continue;
538 if (*point != '=') continue;
539 point++;
540 *int_ptr = strtol(point, &tmp, 10);
541 if (tmp != point) {
542 return 1;
543 } else {
544 return 0;
545 }
546 }
547 }
548 }
549 return 0;
550 }
551
552 static int
get_str_attr(char ** str_ptr,char * name,char * start,char * end)553 get_str_attr(char **str_ptr, char *name, char *start, char *end)
554 {
555 int name_len = strlen(name);
556 start -= 1;
557 while(++start < (end - name_len)) {
558 if (*start == *name) {
559 /* first char eq, check further */
560 if (is_tag(name, start)) {
561 char *point = &start[name_len];
562 char *attr = NULL;
563 while (isspace((int)*point)) point++;
564 if (point > end) continue;
565 if (*point != '=') continue;
566 point++;
567 while (isspace((int)*point)) point++;
568 if (point > end) continue;
569 if (*point == '"') {
570 /* begin quote */
571 char *end_quote = strchr(point+1, '"');
572 point++;
573 if ((end_quote == 0) || (end_quote > end)) continue;
574 attr = malloc(end_quote - point + 1);
575 strncpy(attr, point, end_quote - point);
576 attr[end_quote - point] = 0;
577 *str_ptr = attr;
578 return 1;
579 } else {
580 char *next_space = point;
581 while(isalnum((int)*next_space) || (*next_space=='_'))
582 next_space++;
583 attr = malloc(next_space - point+1);
584 strncpy(attr, point, next_space - point);
585 attr[next_space - point] = 0;
586 *str_ptr = attr;
587 return 1;
588 }
589 }
590 }
591 }
592 return 0;
593 }
594
595 extern int
FMhas_XML_info(FMFormat format)596 FMhas_XML_info(FMFormat format)
597 {
598 if (format->xml_out == (void*) -1) return 0;
599 if (format->xml_out == NULL) {
600 /* search opt info */
601 format->xml_out = build_XML_output_info(format);
602 if (format->xml_out == NULL) {
603 format->xml_out = (void*)-1;
604 return 0;
605 }
606 }
607 return 1;
608 }
609
610 extern void
611 dump_FMfield_as_XML(c, format, field, data, string_base, encode, verbose)
612 FMContext c;
613 FMFormat format;
614 int field;
615 void *data;
616 void *string_base;
617 int encode;
618 int verbose;
619 {
620 ffs_dstring ds = new_dstring();
621 generic_field_to_XML(format, field, data, string_base, encode,
622 ds);
623 printf("%s", ds->string);
624 free(ds->string);
625 free(ds);
626 }
627
628 extern int
629 add_single_value_as_XML(field_type, field_size, field_offset,
630 data, string_base, byte_reversal, float_format,
631 encode, ds)
632 const char *field_type;
633 int field_size;
634 int field_offset;
635 void *data;
636 void *string_base;
637 int byte_reversal;
638 int float_format;
639 int encode;
640 ffs_dstring ds;
641 {
642 FMgetFieldStruct descr; /* OK */
643 char str[64];
644 descr.offset = field_offset;
645 descr.size = field_size;
646 descr.data_type = FMstr_to_data_type(field_type);
647 descr.byte_swap = byte_reversal;
648 descr.src_float_format = float_format;
649 descr.target_float_format = fm_my_float_format;
650
651 str[0] = 0;
652 if (descr.data_type == integer_type) {
653 if (field_size <= sizeof(long)) {
654 long tmp = get_FMlong(&descr, data);
655 sprintf(str, "%ld", tmp);
656 } else if (field_size == 2 * sizeof(long) && field_size == 8) {
657 unsigned long low_long;
658 long high_long;
659 get_FMlong8(&descr, data, &low_long, &high_long);
660 if (high_long == 0) {
661 sprintf(str, "%ld ", low_long);
662 } else {
663 sprintf(str, "0x%lx%08lx ", high_long, low_long);
664 }
665 } else if (field_size > sizeof(long)) {
666 sprintf(str, "<scalar type=\"long\" />");
667 } else {
668 sprintf(str, "<scalar type=\"int\" size=\"%d\" />", field_size);
669 }
670 } else if (descr.data_type == unsigned_type) {
671 if (field_size <= sizeof(unsigned long)) {
672 unsigned long tmp = get_FMulong(&descr, data);
673 sprintf(str, "%lu ", tmp);
674 } else if (field_size == 2 * sizeof(long) && field_size == 8) {
675 unsigned long low_long, high_long;
676 get_FMulong8(&descr, data, &low_long, &high_long);
677 if (high_long == 0) {
678 sprintf(str, "%lu ", low_long);
679 } else {
680 sprintf(str, "0x%lx%08lx ", high_long, low_long);
681 }
682 } else if (field_size > sizeof(long)) {
683 sprintf(str, "<scalar type=\"unsignedLong\" />");
684 } else {
685 sprintf(str, "<scalar type=\"unsignedInt\" size=\"%d\" />", field_size);
686 }
687 } else if (descr.data_type == enumeration_type) {
688 sprintf(str, "%u ", *(int *) ((char *) data + field_offset));
689 } else if (descr.data_type == boolean_type) {
690 if (*(int *) ((char *) data + field_offset) == 0) {
691 strcpy(str, "false ");
692 } else {
693 strcpy(str, "true ");
694 }
695 } else if (descr.data_type == float_type) {
696 if (field_size == sizeof(float)) {
697 float tmp = get_FMfloat(&descr, data);
698 sprintf(str, "%g ", tmp);
699 } else if (field_size == sizeof(double)) {
700 double tmp = get_FMdouble(&descr, data);
701 sprintf(str, "%g ", tmp);
702 #if SIZEOF_LONG_DOUBLE != 0 && SIZEOF_LONG_DOUBLE != SIZEOF_DOUBLE
703 } else if (field_size == sizeof(long double)) {
704 long double tmp;
705 memcpy(&tmp, (float *) ((char *) data + field_offset),
706 sizeof(double));
707 sprintf(str, "%Lg ", tmp);
708 #endif
709 } else {
710 if (field_size < sizeof(float)) {
711 sprintf(str, "<scalar type=\"small-float\" />");
712 } else if (field_size > sizeof(double)) {
713 sprintf(str, "<scalar type=\"big-float\" />");
714 } else {
715 sprintf(str, "<scalar type=\"float\" size=\"%u\" />", field_size);
716 }
717 }
718 } else if (descr.data_type == char_type) {
719 sprintf(str, "%c ", *(char *) ((char *) data + field_offset));
720 } else if (descr.data_type == string_type) {
721 char *tmp_str = (char *) get_FMaddr(&descr, data, string_base, encode);
722 if (tmp_str != 0) {
723 dcatstr(ds, tmp_str);
724 return 1;
725 }
726 } else {
727 return 0;
728 }
729 dcatstr(ds, str);
730 return 1;
731 }
732
733 static void
add_value_as_XML(field_type,field_size,field_offset,format,field,data,string_base,byte_reversal,float_format,encode,in_array,ds)734 add_value_as_XML(field_type, field_size, field_offset, format, field, data,
735 string_base, byte_reversal, float_format, encode,
736 in_array, ds)
737 const char *field_type;
738 int field_size;
739 int field_offset;
740 FMFormat format;
741 int field;
742 void *data;
743 void *string_base;
744 int byte_reversal;
745 int float_format;
746 int encode;
747 int in_array;
748 ffs_dstring ds;
749 {
750 if (add_single_value_as_XML(field_type, field_size, field_offset,
751 data, string_base, byte_reversal,
752 float_format, encode, ds)) {
753 /* nothing */
754 } else {
755 char *typ = base_data_type(field_type);
756 if ((format = format->field_subformats[field]) != NULL) {
757 int index;
758 if (in_array) {
759 dcatstr(ds, "<");
760 dcatstr(ds, format->format_name);
761 dcatstr(ds, ">\n");
762 } else {
763 dcatstr(ds, "\n");
764 }
765 for (index = 0; index < format->field_count; index++) {
766 generic_field_to_XML(format, index,
767 (void *) ((char *) data + field_offset),
768 string_base, encode, ds);
769 }
770 if (in_array) {
771 dcatstr(ds, "</");
772 dcatstr(ds, format->format_name);
773 dcatstr(ds, ">\n");
774 }
775 } else {
776 printf("<scalar type=\"unknown\" />\n");
777 }
778 free(typ);
779 }
780 }
781
782 static void
generic_field_to_XML(format,field,data,string_base,encode,ds)783 generic_field_to_XML(format, field, data, string_base, encode, ds)
784 FMFormat format;
785 int field;
786 void *data;
787 void *string_base;
788 int encode;
789 ffs_dstring ds;
790 {
791 FMFieldList fmfield = &format->field_list[field];
792 FMVarInfoList iovar = &format->var_list[field];
793 int field_offset = fmfield->field_offset;
794 int field_size = fmfield->field_size;
795 const char *field_type = fmfield->field_type;
796 int byte_reversal = format->byte_reversal;
797 int float_format = format->float_format;
798 char *left_paren = NULL;
799
800 if (encode == 0) byte_reversal = 0;
801
802 dcatstr(ds, "<");
803 dcatstr(ds, (char*)fmfield->field_name);
804 dcatstr(ds, ">");
805 if ((left_paren = strchr(field_type, '[')) == NULL) {
806 add_value_as_XML(field_type, field_size, field_offset, format, field, data,
807 string_base, byte_reversal, float_format,
808 encode, 0, ds);
809 } else if (strchr(left_paren + 1, '[') == NULL) {
810 /* single dimen array */
811 long dimension = 0;
812 char sub_type[64];
813 int sub_field_size;
814 int offset = fmfield->field_offset;
815 dcatstr(ds, "\n");
816 *left_paren = 0;
817 strcpy(sub_type, field_type);
818 *left_paren = '[';
819 dimension = strtol(left_paren + 1, NULL, 10);
820
821 if ((dimension == LONG_MIN) || (dimension == LONG_MAX) ||
822 (dimension == 0)) {
823 if (!iovar->var_array) {
824 fprintf(stderr, "Couldn't parse array size in \"%s\"\n",
825 field_type);
826 return;
827 } else {
828 FMgetFieldStruct descr; /* OK */
829 long tmp_offset;
830
831 dimension = FMget_array_element_count(format, iovar, data, encode);
832
833 descr.offset = fmfield->field_offset;
834 descr.size = format->pointer_size;
835 descr.data_type = integer_type;
836 descr.byte_swap = byte_reversal;
837 tmp_offset = get_FMlong(&descr, data);
838 if (encode) {
839 data = (char *) string_base + tmp_offset;
840 } else {
841 data = (void *) tmp_offset;
842 }
843 offset = 0;
844 }
845 sub_field_size = fmfield->field_size;
846 } else {
847 /* normal internal array */
848 sub_field_size = fmfield->field_size;
849 }
850 for (; dimension > 0; dimension--) {
851 add_value_as_XML(sub_type, sub_field_size, offset, format, field, data,
852 string_base, byte_reversal, float_format,
853 encode, 1, ds);
854 offset += sub_field_size;
855 }
856 } else {
857 /* double dimen array */
858 long dimension1 = 0;
859 long dimension2 = 0;
860 char *temp_ptr;
861 char sub_type[64];
862 int sub_field_size, offset = fmfield->field_offset;
863 dcatstr(ds, "\n");
864 *left_paren = 0;
865 strcpy(sub_type, field_type);
866 dimension1 = strtol(left_paren + 1, &temp_ptr, 10);
867 dimension2 = strtol(temp_ptr + 2, &temp_ptr, 10);
868
869 if ((dimension2 == LONG_MIN) || (dimension2 == LONG_MAX) ||
870 (dimension2 == 0) || (dimension1 == 0)) {
871 *left_paren = '[';
872 fprintf(stderr, "Couldn't parse array size in \"%s\"\n",
873 field_type);
874 return;
875 }
876 *left_paren = '[';
877 sub_field_size = fmfield->field_size;
878 for (; dimension2 > 0; dimension2--) {
879 int i = 0;
880 for (; i < dimension1; i++) {
881 add_value_as_XML(sub_type, sub_field_size, offset, format, field,
882 data, string_base, byte_reversal,
883 float_format, encode, 1, ds);
884 offset += sub_field_size;
885 }
886 }
887 }
888
889 dcatstr(ds, "</");
890 dcatstr(ds, (char*)fmfield->field_name);
891 dcatstr(ds, ">\n");
892 }
893
894