1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 
11 
12 #include <dx/dx.h>
13 #include <ctype.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <math.h>
17 #include "exp_gai.h"
18 
19 #define MAXRANK 16
20 #define OFF 0
21 #define ON 1
22 
23 static struct ap_info {
24    char *spacedformat;
25    char *plainformat;
26    int width;
27 } ap[] = {
28 	/* strings */
29 	{NULL,     NULL,             1},   /* use pstring instead */
30 	/* unsigned bytes */
31 	{"%3u",   "%u",              3},
32 	/* bytes */
33 	{"%3d",   "%d",              3},
34 	/* unsigned shorts */
35 	{"%6u",   "%u",              6},
36 	/* shorts */
37 	{"%6d",   "%d",              6},
38 	/* unsigned ints */
39 	{"%9u",   "%u",	            9},
40 	/* ints */
41 	{"%9d",   "%d",              9},
42 	/* floats */
43 	{"%12.7g",  "%g",           12},
44 	/* doubles */
45 	{"%15g",    "%g",           15},
46 };
47 
48 struct array_info {
49 	ArrayHandle 	handle;
50 	char *		format;		/* format for printf statement */
51 	Type 		type;		/* TYPE of value */
52 	int 		dim;		/* dim of item */
53 	int 		width;		/* width of longest value printed */
54 	Pointer		last;		/* last value for sequential access */
55 };
56 
57 struct how {
58 	FILE *	dfp;
59 	int quote;
60 	int header;
61 	int tabbed;
62 };
63 
64 static Error object_ex(Object o,struct how *h);
65 static Error array_ex(Array a ,struct how *h);
66 static Error field_ex(Field f,struct how *h);
67 static Error group_ex(Group g,struct how *h);
68 static Error xform_ex(Xform o,struct how *h);
69 static Error screen_ex(Screen o,struct how *h);
70 static Error clipped_ex(Clipped o,struct how *h);
71 static void pstring(FILE *fp, int width, int quote, int tab, char *cp);
72 static Error pvalue(struct array_info *arinfo,struct how *h,int item,int blank,int first);
73 static void pblank(struct array_info *info,struct how *h);
74 static void gethandle(Array a, struct array_info *info,int tab);
75 static void freehandle(struct array_info *info);
76 static Error object_header(Object o,struct how *h);
77 static Error group_header(Group g, struct how *h);
78 static void field_header(Field f, struct how *h);
79 static void array_header(Array a, struct how *h);
80 static Error xform_header(Xform o, struct how *h);
81 static Error screen_header(Screen o, struct how *h);
82 static Error clipped_header(Clipped o, struct how *h);
83 
_dxfExportArray(Object o,char * filename,char * format)84 Object _dxfExportArray(Object o, char *filename, char *format)
85 {
86    char *cp,*lcp,lcasefmt[64];
87    int rc;
88    struct how f;
89    char *name;
90 
91    if (!o) {
92       DXSetError(ERROR_BAD_PARAMETER,"#10000","input");
93       return NULL;
94    }
95 
96    if (!filename) {
97       DXSetError(ERROR_BAD_PARAMETER,"#10000","filename");
98       return NULL;
99    }
100 
101    /* should we add an extension ? */
102    f.dfp = fopen(filename,"w+");
103    if (!f.dfp) {
104       DXSetError(ERROR_BAD_PARAMETER,"#12248",filename);
105       goto error;
106    }
107 
108    /* turn format into lower case and look for keywords */
109    f.quote = OFF;
110    f.header = OFF;
111    f.tabbed = OFF;
112    if (format) {
113       for (cp=format, lcp=lcasefmt; *cp && lcp < &lcasefmt[64]; cp++, lcp++)
114 	 *lcp = isupper(*cp) ? tolower(*cp) : *cp;
115       *lcp = '\0';
116 
117       /* what keywords ? */
118       for (cp=lcasefmt; *cp; ) {
119 	 if (isspace(*cp)) {
120 	    cp++;
121 	    continue;
122 	 }
123 	 if (!strncmp(cp, "array", 5)) {
124 	    cp += 5;
125 	    continue;
126 	 }
127 	 if (!strncmp(cp, "spreadsheet", 11)) {
128 	    cp += 11;
129 	    continue;
130 	 }
131 	 if (!strncmp(cp, "quotes", 6)) {
132 	    cp += 6;
133 	    f.quote = ON;
134 	    continue;
135 	 }
136 	 if (!strncmp(cp, "headers", 7)) {
137 	    cp += 7;
138 	    f.header = ON;
139 	    continue;
140 	 }
141 	 if (!strncmp(cp, "tabbed", 6)) {
142 	    cp += 6;
143 	    f.tabbed = ON;
144 	    continue;
145 	 }
146 	 DXSetError(ERROR_BAD_PARAMETER,"#12238",cp);
147 	 rc =ERROR;
148 	 goto error;
149       }
150    }
151 
152    if (f.header == ON) {
153       /* name of object */
154       if(DXGetStringAttribute((Object)o,"name",&name)){
155          pstring(f.dfp,0,0,0,name);
156          fprintf(f.dfp,"\n");
157       }
158       if (!object_header(o,&f))
159          goto error;
160    }
161 
162    rc = object_ex(o,&f);
163 
164    fclose(f.dfp);
165 
166    if (rc !=OK)
167       return ERROR;
168 
169    return (o);
170 
171 error:
172    if (f.dfp)
173       fclose(f.dfp);
174    return NULL;
175 
176 }
177 
object_ex(Object o,struct how * f)178 static Error object_ex(Object o, struct how *f)
179 {
180    int rc=0;
181 
182    /* only support groups, fields, and arrays ? */
183    switch (DXGetObjectClass(o)) {
184 
185       case CLASS_GROUP:
186 	 rc = group_ex((Group)o,f);
187 	 break;
188       case CLASS_FIELD:
189 	 rc = field_ex((Field)o,f);
190 	 break;
191       case CLASS_ARRAY:
192 	 rc = array_ex((Array)o,f);
193 	 break;
194       case CLASS_XFORM:
195 	 rc = xform_ex((Xform)o,f);
196 	 break;
197       case CLASS_SCREEN:
198 	 rc = screen_ex((Screen)o,f);
199 	 break;
200       case CLASS_CLIPPED:
201 	 rc = clipped_ex((Clipped)o,f);
202 	 break;
203       default:
204 	 DXSetError(ERROR_DATA_INVALID,"cannot export this object in array format");
205    }
206 
207    if (rc != OK)
208       return ERROR;
209 
210    return OK;
211 }
212 
213 
field_ex(Field f,struct how * h)214 static Error field_ex(Field f, struct how *h)
215 {
216    int i,n,numarrays=0; 	/* number of arrays written */
217    int items,count;
218    Array a;
219    char *depon,*name;
220    struct array_info *arinfo;
221    int *printthis;
222    InvalidComponentHandle invalidhandle=NULL;
223    int array_beg = 1;		/* set to 0 if positions component exists */
224 
225    printthis=NULL;
226    arinfo=NULL;
227    for (count=0; (a=(Array)DXGetEnumeratedComponentValue((Field)f,count,NULL));
228 	     count++)
229       ;
230    /* initialize arrays */
231    if (!(printthis = (int *)DXAllocate((count+1) * sizeof(int))))
232       goto error;
233    if (!(arinfo = (struct array_info *)DXAllocate((count+1) *
234 						  sizeof(struct array_info))))
235       goto error;
236 
237    /* Export position dep arrays (default) */
238    for (i=0; (a=(Array)DXGetEnumeratedComponentValue((Field)f,i,&name)); i++){
239       if (DXGetStringAttribute((Object)a,"dep",&depon) &&
240           !strcmp("positions",depon) && strcmp("invalid positions",name) ) {
241 	 printthis[i] = ON;
242          numarrays++;
243       }
244       else
245 	 printthis[i] = OFF;
246    }
247 
248    /* are there invalid positions */
249    if(DXGetComponentValue((Field)f,"invalid positions")){
250       invalidhandle=DXCreateInvalidComponentHandle((Object)f,NULL,"positions");
251       if (!invalidhandle)
252 	 goto error;
253    }
254 
255    numarrays=1;
256    /* fill info about each array to be printed (ie. format,type, ...) */
257    for (i=0; (a=(Array)DXGetEnumeratedComponentValue((Field)f,i,&name)); i++){
258       if (printthis[i]==ON){
259 	 DXGetArrayInfo((Array)a,&items,NULL,NULL,NULL,NULL);
260 	 if (!strcmp(name,"positions")) {
261 	    gethandle((Array)a,&arinfo[0],h->tabbed);
262 	    array_beg = 0;
263 	 }
264 	 else {
265 	    gethandle((Array)a,&arinfo[numarrays],h->tabbed);
266 	    numarrays++;
267 	 }
268       }
269    }
270 
271    /* loop through arrays printing one item at a time */
272    for (i=0; i<items; i++) {
273       if (invalidhandle && DXIsElementInvalidSequential(invalidhandle,i) ) {
274          if (array_beg == 0) { 		/* print all positions even invalid ones */
275 	    if (!pvalue(&arinfo[0],h,i,0,1))
276 	       goto error;
277 	 }
278 	 else {
279 	    if (!pvalue(&arinfo[array_beg],h,i,1,1))
280 	       goto error;
281 	 }
282 	 for (n=array_beg+1; n<numarrays; n++)
283             if (!pvalue(&arinfo[n],h,i,1,0))
284 	       goto error;
285       }
286       else {
287 	 if (!pvalue(&arinfo[array_beg],h,i,0,1))
288 	    goto error;
289          for (n=array_beg+1; n<numarrays; n++){
290             if (!pvalue(&arinfo[n],h,i,0,0))
291 	       goto error;
292          }
293       }
294       fprintf(h->dfp,"\n");
295    }
296 
297    fprintf(h->dfp,"\n");	/* blank line separating fields */
298 
299    /* free the handles */
300    for (n=array_beg; n<numarrays; n++)
301       freehandle(&arinfo[n]);
302    if (arinfo) DXFree((Pointer)arinfo);
303    if (printthis) DXFree((Pointer)printthis);
304    if (invalidhandle) DXFreeInvalidComponentHandle(invalidhandle);
305    return OK;
306 
307 error:
308    if (arinfo) {
309       for (n=array_beg; n<numarrays; n++)
310          freehandle(&arinfo[n]);
311       DXFree((Pointer)arinfo);
312    }
313    if (printthis) DXFree((Pointer)printthis);
314    if (invalidhandle) DXFreeInvalidComponentHandle(invalidhandle);
315    return ERROR;
316 }
317 
318 
group_ex(Group g,struct how * h)319 static Error group_ex(Group g, struct how *h)
320 {
321    int i;
322    Object o;
323    char *name;
324 
325    for (i=0; (o=DXGetEnumeratedMember(g,i,&name)); i++){
326       if (!object_ex((Object)o,h))
327 	 return ERROR;
328    }
329 
330    return OK;
331 }
332 
array_ex(Array a,struct how * h)333 static Error array_ex(Array a, struct how *h)
334 {
335    int i,items;
336    struct array_info *arinfo;
337 
338    if (!(arinfo = (struct array_info *)DXAllocate(sizeof(struct array_info))))
339       goto error;
340 
341    DXGetArrayInfo((Array)a,&items,NULL,NULL,NULL,NULL);
342    gethandle((Array)a,&arinfo[0],h->tabbed);
343    for (i=0; i<items; i++) {
344       if (!pvalue(&arinfo[0],h,i,0,1))
345          goto error;
346       fprintf(h->dfp,"\n");
347    }
348    DXFree((Pointer)arinfo);
349    return OK;
350 
351 error:
352    if (arinfo) DXFree((Pointer)arinfo);
353    return ERROR;
354 }
355 
xform_ex(Xform o,struct how * h)356 static Error xform_ex(Xform o,struct how *h)
357 {
358    Object subo;
359    DXGetXformInfo(o,&subo,NULL);
360    if (!object_ex((Object)subo,h))
361       return ERROR;
362 
363    return OK;
364 }
365 
screen_ex(Screen o,struct how * h)366 static Error screen_ex(Screen o,struct how *h)
367 {
368    Object subo;
369    DXGetScreenInfo(o,&subo,NULL,NULL);
370    if (!object_ex((Object)subo,h))
371       return ERROR;
372 
373    return OK;
374 }
375 
clipped_ex(Clipped o,struct how * h)376 static Error clipped_ex(Clipped o, struct how *h)
377 {
378    Object subo;
379    DXGetClippedInfo(o,&subo,NULL);
380    if (!object_ex((Object)subo,h))
381       return ERROR;
382 
383    return OK;
384 }
385 
386 
pvalue(struct array_info * arinfo,struct how * h,int item,int blank,int first)387 static Error pvalue(struct array_info *arinfo,struct how *h,int item,int blank,int first)
388 {
389    int dim;
390    Type type;
391    char *format;
392    Pointer scratch;
393    int k;
394    float *nextf;
395    int *nexti;
396    byte *nextb;
397    short *nexts;
398    uint *nextui;
399    ubyte *nextub;
400    ushort *nextus;
401    double *nextd;
402    char *nextstr;
403    char *del;
404    char *space = " ";
405    char *tab = "\t";
406 
407    dim = arinfo->dim;
408    format = arinfo->format;
409    type = arinfo->type;
410    if (h->tabbed == OFF)
411       del = space;
412    else
413       del = tab;
414    switch(type) {
415       case(TYPE_FLOAT):
416 	 scratch = (Pointer)DXAllocate(dim * sizeof(float));
417 	 nextf = (float *)DXAllocate(dim * sizeof(float));
418          nextf = (float *)DXIterateArray(arinfo->handle,item,
419 				    arinfo->last,scratch);
420 	 arinfo->last = (Pointer)nextf;
421 	 for (k=0; k<dim; k++) {
422 	    if (first == ON)
423 	       first = OFF;
424 	    else
425 	       fprintf(h->dfp,del);
426 	    if (blank == ON)
427 	       pblank(arinfo,h);
428 	    else
429 	       fprintf(h->dfp,format,nextf[k]);
430 	 }
431          break;
432       case(TYPE_INT):
433 	 scratch = (Pointer)DXAllocate(dim * sizeof(int));
434 	 nexti = (int *)DXAllocate(dim * sizeof(int));
435          nexti = (int *)DXIterateArray(arinfo->handle,item,
436 				    arinfo->last,scratch);
437 	 arinfo->last = (Pointer)nexti;
438 	 for (k=0; k<dim; k++) {
439 	    if (first == ON)
440 	       first = OFF;
441 	    else
442 	       fprintf(h->dfp,del);
443 	    if (blank == ON)
444 	       pblank(arinfo,h);
445 	    else
446 	       fprintf(h->dfp,format,nexti[k]);
447 	 }
448 	 break;
449       case(TYPE_UINT):
450 	 scratch = (Pointer)DXAllocate(dim * sizeof(uint));
451 	 nextui = (uint *)DXAllocate(dim * sizeof(uint));
452          nextui = (uint *)DXIterateArray(arinfo->handle,item,
453 				    arinfo->last,scratch);
454 	 arinfo->last = (Pointer)nextui;
455 	 for (k=0; k<dim; k++) {
456 	    if (first == ON)
457 	       first = OFF;
458 	    else
459 	       fprintf(h->dfp,del);
460 	    if (blank == ON)
461 	       pblank(arinfo,h);
462 	    else
463 	       fprintf(h->dfp,format,nextui[k]);
464 	 }
465 	 break;
466       case(TYPE_BYTE):
467 	 scratch = (Pointer)DXAllocate(dim * sizeof(byte));
468 	 nextb = (byte *)DXAllocate(dim * sizeof(byte));
469          nextb = (byte *)DXIterateArray(arinfo->handle,item,
470 				    arinfo->last,scratch);
471 	 arinfo->last = (Pointer)nextb;
472 	 for (k=0; k<dim; k++) {
473 	    if (first == ON)
474 	       first = OFF;
475 	    else
476 	       fprintf(h->dfp,del);
477 	    if (blank == ON)
478 	       pblank(arinfo,h);
479 	    else
480 	       fprintf(h->dfp,format,nextb[k]);
481 	 }
482 	 break;
483       case(TYPE_UBYTE):
484 	 scratch = (Pointer)DXAllocate(dim * sizeof(ubyte));
485 	 nextub = (ubyte *)DXAllocate(dim * sizeof(ubyte));
486          nextub = (ubyte *)DXIterateArray(arinfo->handle,item,
487 				    arinfo->last,scratch);
488 	 arinfo->last = (Pointer)nextub;
489 	 for (k=0; k<dim; k++) {
490 	    if (first == ON)
491 	       first = OFF;
492 	    else
493 	       fprintf(h->dfp,del);
494 	    if (blank == ON)
495 	       pblank(arinfo,h);
496 	    else
497 	       fprintf(h->dfp,format,nextub[k]);
498 	 }
499 	 break;
500       case(TYPE_SHORT):
501 	 scratch = (Pointer)DXAllocate(dim * sizeof(short));
502 	 nexts = (short *)DXAllocate(dim * sizeof(short));
503          nexts = (short *)DXIterateArray(arinfo->handle,item,
504 				    arinfo->last,scratch);
505 	 arinfo->last = (Pointer)nexts;
506 	 for (k=0; k<dim; k++) {
507 	    if (first == ON)
508 	       first = OFF;
509 	    else
510 	       fprintf(h->dfp,del);
511 	    if (blank == ON)
512 	       pblank(arinfo,h);
513 	    else
514 	       fprintf(h->dfp,format,nexts[k]);
515 	 }
516 	 break;
517       case(TYPE_USHORT):
518 	 scratch = (Pointer)DXAllocate(dim * sizeof(ushort));
519 	 nextus = (ushort *)DXAllocate(dim * sizeof(ushort));
520          nextus = (ushort *)DXIterateArray(arinfo->handle,item,
521 				    arinfo->last,scratch);
522 	 arinfo->last = (Pointer)nextus;
523 	 for (k=0; k<dim; k++) {
524 	    if (first == ON)
525 	       first = OFF;
526 	    else
527 	       fprintf(h->dfp,del);
528 	    if (blank == ON)
529 	       pblank(arinfo,h);
530 	    else
531 	       fprintf(h->dfp,format,nextus[k]);
532 	 }
533 	 break;
534       case(TYPE_DOUBLE):
535 	 scratch = (Pointer)DXAllocate(dim * sizeof(double));
536 	 nextd = (double *)DXAllocate(dim * sizeof(double));
537          nextd = (double *)DXIterateArray(arinfo->handle,item,
538 				    arinfo->last,scratch);
539 	 arinfo->last = (Pointer)nextd;
540 	 for (k=0; k<dim; k++) {
541 	    if (first == ON)
542 	       first = OFF;
543 	    else
544 	       fprintf(h->dfp,del);
545 	    if (blank == ON)
546 	       pblank(arinfo,h);
547 	    else
548 	       fprintf(h->dfp,format,nextd[k]);
549 	 }
550 	 break;
551       case(TYPE_STRING):
552 	 scratch = (Pointer)DXAllocate(arinfo->dim + 1);
553 	 nextstr = (char *)DXIterateArray(arinfo->handle,item,
554 				  arinfo->last,scratch);
555 	 arinfo->last = (Pointer)nextstr;
556 	 if (first == OFF)
557 	    fprintf(h->dfp,del);
558 	 if (blank == ON)
559 	    pblank(arinfo,h);
560 	 else {
561 	    pstring(h->dfp, dim, h->quote,h->tabbed,nextstr);
562 	 }
563 	 break;
564       default:
565 	 DXSetError(ERROR_DATA_INVALID,"not implemented");
566 	 goto error;
567    }
568 
569    DXFree((Pointer)scratch);
570    return OK;
571 
572 error:
573    return ERROR;
574 }
575 
pstring(FILE * fp,int width,int quote,int tab,char * cp)576 static void pstring(FILE *fp, int width, int quote, int tab, char *cp)
577 {
578    int i,fill;
579 
580    if (!cp) {
581       fprintf(fp," ");
582       return;
583    }
584 
585    if (tab == OFF){
586       /* make each string the same length by adding spaces */
587       if ((fill = width - (int)strlen(cp)) > 0){
588          for (i=0; i<fill; i++)
589 	    putc(' ',fp);
590       }
591    }
592 
593    /* if quotes put them here */
594    if (quote == ON)
595       putc('"',fp);
596 
597    while(*cp) {
598       switch(*cp) {
599 #ifndef DXD_NO_ANSI_ALERT
600 	case '\a': putc('\\', fp); putc('a', fp);  break;
601 #endif
602 	case '\b': putc('\\', fp); putc('b', fp);  break;
603 	case '\f': putc('\\', fp); putc('f', fp);  break;
604 	case '\n': putc('\\', fp); putc('n', fp);  break;
605 	case '\r': putc('\\', fp); putc('r', fp);  break;
606 	case '\t': putc('\\', fp); putc('t', fp);  break;
607 	case '\v': putc('\\', fp); putc('v', fp);  break;
608 	case '\\': putc('\\', fp); putc('\\', fp); break;
609 	case '"':  putc('\\', fp); putc('"', fp);  break;
610 	default:
611 	   if (isprint(*cp))
612 	      putc(*cp, fp);
613 	   else
614 	      fprintf(fp, "\\%03o", (uint)*cp);  /* octal code */
615       }
616       ++cp;
617    }
618    if (quote == ON)
619       putc('"',fp);
620 }
621 
pblank(struct array_info * info,struct how * h)622 static void pblank(struct array_info *info,struct how *h)
623 {
624    int width,i;
625 
626    /* print blanks of same width as colums */
627    if ( h->tabbed == ON){
628       fprintf(h->dfp," ");
629       return;
630    }
631 
632    width = (info->width *info->dim);
633 
634    for (i=0; i<width; i++)
635       putc(' ',h->dfp);
636 
637    /* if strings with quotes ON add 2 extra blanks */
638    if (info->type == TYPE_STRING && h->quote == ON) {
639       putc(' ',h->dfp); putc(' ',h->dfp);
640    }
641 
642    fprintf(h->dfp,"  ");
643 
644 }
645 
gethandle(Array a,struct array_info * info,int tab)646 static void gethandle(Array a, struct array_info *info,int tab)
647 {
648    int items,rank;
649    Type type;
650    Category cat;
651    int shape[MAXRANK];
652    int numtype;
653 
654 
655 	 DXGetArrayInfo(a,&items,&type,&cat,&rank,shape);
656 
657 	 switch(type) {
658 	    case TYPE_STRING:	numtype = 0; break;
659 	    case TYPE_UBYTE:	numtype = 1; break;
660 	    case TYPE_BYTE:	numtype = 2; break;
661 	    case TYPE_USHORT:	numtype = 3; break;
662 	    case TYPE_SHORT: 	numtype = 4; break;
663 	    case TYPE_UINT:	numtype = 5; break;
664 	    case TYPE_INT:	numtype = 6; break;
665 	    case TYPE_FLOAT:	numtype = 7; break;
666 	    case TYPE_DOUBLE: 	numtype = 8; break;
667 	    default:
668 	       return;
669 	 }
670 
671 	 if (tab == 1)		/* tabbed uses plain format */
672 	    info->format = ap[numtype].plainformat;
673 	 else
674 	    info->format = ap[numtype].spacedformat;
675 	 info->dim = (rank < 1) ? 1 : shape[0];
676 	 info->type = type;
677 	 info->width = ap[numtype].width;
678 	 info->handle = DXCreateArrayHandle(a);
679 	 info->last = NULL;
680 }
681 
freehandle(struct array_info * ar)682 static void freehandle(struct array_info *ar)
683 {
684    DXFreeArrayHandle(ar->handle);
685 }
686 
687 
688 /* this section is for printing the headers */
689 
object_header(Object o,struct how * f)690 static Error object_header(Object o,struct how *f)
691 {
692    int rc=OK;
693 
694    /* only support groups, fields, and arrays ? */
695    switch (DXGetObjectClass(o)) {
696 
697       case CLASS_GROUP:
698 	 rc = group_header((Group)o,f);
699 	 break;
700       case CLASS_FIELD:
701 	 field_header((Field)o,f);
702 	 break;
703       case CLASS_ARRAY:
704 	 array_header((Array)o,f);
705 	 break;
706       case CLASS_XFORM:
707 	 rc = xform_header((Xform)o,f);
708 	 break;
709       case CLASS_SCREEN:
710 	 rc = screen_header((Screen)o,f);
711 	 break;
712       case CLASS_CLIPPED:
713 	 rc = clipped_header((Clipped)o,f);
714 	 break;
715 
716       default:
717 	 DXSetError(ERROR_DATA_INVALID,"cannot export this object in array format");
718          return ERROR;
719    }
720 
721    if (rc == ERROR)
722       return ERROR;
723 
724    return OK;
725 }
726 
727 int indent = 0;
728 char indent_char[3] = "  ";
729 
group_header(Group g,struct how * h)730 static Error group_header(Group g, struct how *h)
731 {
732    char *name;
733    int n,i,j;
734    Object o;
735    float pos;		/* series positions */
736 
737    /* how many fields or groups */
738    DXGetMemberCount((Group)g,&n);
739    fprintf(h->dfp,"%d members",n);
740    fprintf(h->dfp,"\n");
741 
742    indent++;
743    switch (DXGetGroupClass(g)){
744    case (CLASS_GROUP):
745    case (CLASS_MULTIGRID):
746    case (CLASS_COMPOSITEFIELD):
747       for (i=0; (o=DXGetEnumeratedMember((Group)g,i,&name)); i++){
748          /* indent */
749 	 for (j=0; j<indent; j++)
750             fprintf(h->dfp,"%s",indent_char);
751          if (name != NULL) {
752 	    pstring(h->dfp,0,0,0,name);
753             fprintf(h->dfp,"\n");
754          }
755          if (!object_header((Object)o,h))
756 	    return ERROR;
757       }
758       break;
759    case (CLASS_SERIES):
760       for (i=0; i<n; i++){
761          /* indent */
762 	 for (j=0; j<indent; j++)
763             fprintf(h->dfp,"%s",indent_char);
764 	 o = DXGetSeriesMember((Series)g,i,&pos);
765 	 fprintf(h->dfp,"series position %g \n",pos);
766          if (!object_header((Object)o,h))
767 	    return ERROR;
768       }
769       break;
770     default:
771       break;
772    }
773 
774    indent--;
775    return OK;
776 }
777 
778 
field_header(Field f,struct how * h)779 static void field_header(Field f,struct how *h)
780 {
781    char *name, *depon;
782    int i,j,first=ON;
783    Array a,*terms = NULL;
784    Type type;
785    int rank,items,shape[MAXRANK];
786    /* int dim; */
787    char *cmp;
788    char *del;
789    char *space = " ";
790    char *tab = "\t";
791 
792    if (h->tabbed == ON)
793       del = tab;
794    else
795       del = space;
796 
797    /* name of field */
798    if (DXGetStringAttribute((Object)f,"name",&name)){
799       pstring(h->dfp,0,0,0,name);
800       fprintf(h->dfp," ");
801    }
802 
803    /* dimensions of the grid from connections */
804    a = (Array)DXGetComponentValue((Field)f,"connections");
805    if (a && DXGetArrayClass(a)==CLASS_MESHARRAY){
806       if (DXQueryGridConnections(a,&rank,shape)){
807          fprintf(h->dfp,"dimensions = ");
808          for (i=0; i<rank; i++)
809 	    fprintf(h->dfp,"%d ",shape[i]);
810 	 fprintf(h->dfp,"\n");
811       }
812       else if (DXGetMeshArrayInfo((MeshArray)a,&rank,terms)) {
813          fprintf(h->dfp,"dimensions = ");
814          for (i=0; i<rank; i++){
815             DXGetArrayInfo((Array)terms[i],&items,NULL,NULL,NULL,NULL);
816             fprintf(h->dfp,"%d ",items);
817          }
818 	 fprintf(h->dfp,"\n");
819       }
820    }
821    else{
822       DXWarning("cannot get dimensions");
823       fprintf(h->dfp,"\n");
824    }
825 
826    /* which components are printed */
827    if ((a = (Array)DXGetComponentValue((Field)f,"positions")) != NULL){
828       DXGetArrayInfo((Array)a,NULL,NULL,NULL,&rank,shape);
829       /* dim = (rank < 1) ? 1 : shape[0]; */
830       if (rank > 0) {
831 	 for (i=0; i<shape[0]; i++){
832 	    if (i > 0)
833 	       fprintf(h->dfp,del);
834 	    fprintf(h->dfp,"positions_cmp%d",i);
835 	 }
836       }
837       else
838 	 fprintf(h->dfp,"positions");
839       first = OFF;
840    }
841 
842    /* Export position dep arrays (default) */
843    for (i=0; (a=(Array)DXGetEnumeratedComponentValue((Field)f,i,&name)); i++){
844       if (DXGetStringAttribute((Object)a,"dep",&depon) &&
845           !strcmp("positions",depon) && strcmp("invalid positions",name)
846 	  && strcmp("positions",name) ) {
847 	 if (first == OFF)
848 	    fprintf(h->dfp,del);
849 	 DXGetArrayInfo((Array)a,NULL,&type,NULL,&rank,shape);
850 	 /* dim = (rank < 1) ? 1 : shape[0]; */
851 	 if (type != TYPE_STRING && rank > 0 && shape[0] > 1) {
852 	    cmp = (char *)DXAllocate(strlen(name)+6);
853 	    for (j=0; j<shape[0]; j++) {
854 	       if (j > 0) fprintf(h->dfp, del);
855 	       sprintf(cmp,"%s_cmp%d",name,j);
856 	       pstring(h->dfp,0,0,0,cmp);
857 	    }
858 	    DXFree(cmp);
859 	 }
860 	 else
861 	    pstring(h->dfp,0,0,0,name);
862 	 first = OFF;
863       }
864    }
865    fprintf(h->dfp,"\n");
866 }
867 
array_header(Array a,struct how * h)868 static void array_header(Array a,struct how *h)
869 {
870    char *name;
871 
872    /* name of Array */
873    if (DXGetStringAttribute((Object)a,"name",&name)){
874       pstring(h->dfp,0,0,0,name);
875       fprintf(h->dfp,"\n");
876    }
877 }
878 
xform_header(Xform o,struct how * h)879 static Error xform_header(Xform o,struct how *h)
880 {
881    Object subo;
882    char *name;
883 
884    /* name of object */
885    if(DXGetStringAttribute((Object)o,"name",&name)){
886       pstring(h->dfp,0,0,0,name);
887       fprintf(h->dfp,", ");
888    }
889    fprintf(h->dfp,"tranformed object,");
890    DXGetXformInfo(o,&subo,NULL);
891    if (!object_header((Object)subo,h))
892       return ERROR;
893 
894    return OK;
895 }
896 
screen_header(Screen o,struct how * h)897 static Error screen_header(Screen o,struct how *h)
898 {
899    Object subo;
900    char *name;
901 
902    /* name of object */
903    if(DXGetStringAttribute((Object)o,"name",&name)){
904       pstring(h->dfp,0,0,0,name);
905       fprintf(h->dfp,", ");
906    }
907    fprintf(h->dfp,"screen object,");
908    DXGetScreenInfo(o,&subo,NULL,NULL);
909    if (!object_header((Object)subo,h))
910       return ERROR;
911 
912    return OK;
913 }
914 
clipped_header(Clipped o,struct how * h)915 static Error clipped_header(Clipped o, struct how *h)
916 {
917    Object subo;
918    char *name;
919 
920    /* name of object */
921    if(DXGetStringAttribute((Object)o,"name",&name)){
922       pstring(h->dfp,0,0,0,name);
923       fprintf(h->dfp,", ");
924    }
925    fprintf(h->dfp,"clipped object,");
926    DXGetClippedInfo(o,&subo,NULL);
927    if (!object_header((Object)subo,h))
928       return ERROR;
929 
930    return OK;
931 }
932 
933