1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF.  The full HDF copyright notice, including       *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /* $Id$ */
15 
16 /*****************************************************************************
17 *
18 * vshow.c
19 *
20 *   HDF Vset utility.
21 *
22 *   vshow:  dumps out vsets in a hdf file.
23 *
24 *   Usage:  vshow file [+|-[n]]
25 *       the '+' option indicates a full dump
26 *       the '-' option indicates a full dump with one record per line
27 *       'n' means only for the nth vdata.
28 *
29 *
30 ******************************************************************************/
31 #define VSET_INTERFACE
32 #include "hdf.h"
33 
34 static int  condensed;
35 
36 static int32 vsdumpfull
37             (int32 vs);
38 
39 static int32 fmtbyte
40             (char *x);
41 static int32 fmtchar
42             (char *x);
43 
44 #ifdef UNUSED
45 static int32 fmtint
46             (char *x);
47 #endif /* UNUSED */
48 
49 static int32 fmtfloat
50             (char *x);
51 
52 static int32 fmtulong
53             (char *x);
54 
55 static int32 fmtlong
56             (char *x);
57 
58 static int32 fmtshort
59             (char *x);
60 
61 static int32 fmtdouble
62             (char *x);
63 
64 static intn dumpattr
65             (int32 vid, intn full, intn isvs);
66 
67 int
main(int ac,char ** av)68 main(int ac, char **av)
69 {
70     int32       vg, vgt;
71     int32       vgotag, vgoref;
72     int32       vs;
73     int32       vsotag, vsoref;
74     HFILEID     f;
75     int32       vgid = -1;
76     int32       vsid = -1;
77     int32       vsno = 0;
78     int32       vstag;
79 
80     int32       i, t, nvg, n, ne, nv, interlace, vsize;
81     int32      *lonevs;         /* array to store refs of all lone vdatas */
82     int32       nlone;          /* total number of lone vdatas */
83     uint16	name_len;	/* length of vgroup's name or classname */
84 
85     char        fields[VSFIELDMAX*FIELDNAMELENMAX];
86     char        *vgname, *vgclass;
87     char        vsname[VSNAMELENMAX];
88     char        vsclass[VSNAMELENMAX];
89     char *name;
90     int32       fulldump = 0, full;
91 
92     if (ac == 3)
93         if (av[2][0] == '-' || av[2][0] == '+')
94           {
95               sscanf(&(av[2][1]), "%d", (int *)&vsno);
96               if (vsno == 0)
97                 {
98                     printf("FULL DUMP\n");
99                 }
100               else
101                 {
102                     printf("FULL DUMP on vs#%ld\n", (long) vsno);
103                 }
104               fulldump = 1;
105               if (av[2][0] == '+')
106                   condensed = 1;
107               else
108                   condensed = 0;
109           }
110 
111     if (ac < 2)
112       {
113           printf("%s: dumps HDF vsets info from hdf file\n", av[0]);
114           printf("usage: %s file [+|-[n]]\n", av[0]);
115           printf("\t +  gives full dump of all vdatas.\n");
116           printf("\t -  gives full dump of all vdatas one record per line.\n");
117           printf("\t n  gives full dump of vdata with id n.\n");
118           exit(0);
119       }
120 
121     if ((f = Hopen(av[1], DFACC_READ, 0)) == FAIL)
122     {
123         printf("\nFile (%s) failed to open.\n", av[1]);
124         exit(0);
125     }
126 
127     Vstart(f);
128     printf("\nFILE: %s\n", av[1]);
129 
130     nvg = 0;
131     while ((vgid = Vgetid(f, vgid)) != -1)
132       {
133           vg = Vattach(f, vgid, "r");
134           if (vg == FAIL)
135             {
136                 printf("cannot open vg id=%d\n", (int) vgid);
137             }
138           /* get the length of the vgname to allocate enough space */
139           Vgetnamelen(vg, &name_len);
140           vgname = (char *) HDmalloc(sizeof(char *) * (name_len+1));
141 	  if (vgname == NULL)
142 	  {
143              printf("Error: Out of memory. Cannot allocate %d bytes space. Quit.\n", name_len+1);
144              return(0);
145           }
146           Vinquire(vg, &n, vgname);
147           if (HDstrlen(vgname) == 0)
148               HDstrcat(vgname, "NoName");
149 
150           vgotag = VQuerytag(vg);
151           vgoref = VQueryref(vg);
152 
153           /* get the length of the vgname to allocate enough space */
154           Vgetclassnamelen(vg, &name_len);
155           vgclass = (char *) HDmalloc(sizeof(char *) * (name_len+1));
156 	  if (vgclass == NULL)
157 	  {
158              printf("Error: Out of memory. Cannot allocate %d bytes space. Quit.\n", name_len+1);
159              return(0);
160           }
161           Vgetclass(vg, vgclass);
162           if (HDstrlen(vgclass) == 0)
163               HDstrcat(vgclass, "NoClass");
164 
165           printf("\nvg:%d <%d/%d> (%s {%s}) has %d entries:\n",
166            (int) nvg, (int) vgotag, (int) vgoref, vgname, vgclass, (int) n);
167           dumpattr(vg, fulldump, 0);
168           for (t = 0; t < Vntagrefs(vg); t++)
169             {
170                 Vgettagref(vg, t, &vstag, &vsid);
171 
172                 /* ------ V D A T A ---------- */
173                 if (vstag == VSDESCTAG)
174                   {
175                       vs = VSattach(f, vsid, "r");
176 
177                       if (vs == FAIL)
178                         {
179                             printf("cannot open vs id=%d\n", (int) vsid);
180                             continue;
181                         }
182 
183                       VSinquire(vs, &nv, &interlace, fields, &vsize, vsname);
184                       vsotag = VSQuerytag(vs);
185                       vsoref = VSQueryref(vs);
186                       if (HDstrlen(vsname) == 0)
187                           HDstrcat(vsname, "NoName");
188                       VSgetclass(vs, vsclass);
189                       printf("  vs:%d <%d/%d> nv=%d i=%d fld [%s] vsize=%d (%s {%s})\n",
190                              (int) t, (int) vsotag, (int) vsoref, (int) nv, (int) interlace, fields, (int) vsize, vsname, vsclass);
191 
192                       if (fulldump && vsno == 0)
193                           vsdumpfull(vs);
194                       else if (fulldump && vsno == vsoref)
195                           vsdumpfull(vs);
196                       /* dump attributes */
197                       full = fulldump && (vsno == 0 || vsno == vsoref);
198                       dumpattr(vs, full, 1);
199 
200                       VSdetach(vs);
201                   }
202                 else if (vstag == DFTAG_VG)
203                   {
204                       /* ------ V G R O U P ----- */
205                       vgt = Vattach(f, vsid, "r");
206 
207                       if (vgt == FAIL)
208                         {
209                             printf("cannot open vg id=%d\n", (int) vsid);
210                             continue;
211                         }
212 
213                       /* get length of the vgclass to allocate enough space */
214                       Vgetclassnamelen(vgt, &name_len);
215                       vgclass = (char *) HDmalloc(sizeof(char *) * (name_len+1));
216 	              if (vgclass == NULL)
217 	              {
218                          printf("Error: Out of memory. Cannot allocate %d bytes space. Quit.\n", name_len+1);
219                          return(0);
220                       }
221                       Vgetclass(vg, vgclass);
222                       if (HDstrlen(vgclass) == 0)
223                           HDstrcat(vgclass, "NoClass");
224 
225                       /* get length of the vgname to allocate enough space */
226                       Vgetnamelen(vgt, &name_len);
227                       vgname = (char *) HDmalloc(sizeof(char *) * (name_len+1));
228 	              if (vgname == NULL)
229 	              {
230                          printf("Error: Out of memory. Cannot allocate %d bytes space. Quit.\n", name_len+1);
231                          return(0);
232                       }
233                       Vinquire(vgt, &ne, vgname);
234                       if (HDstrlen(vgname) == 0)
235                           HDstrcat(vgname, "NoName");
236                       vgotag = VQuerytag(vgt);
237                       vgoref = VQueryref(vgt);
238                       Vgetclass(vgt, vgclass);
239                       printf("  vg:%d <%d/%d> ne=%d (%s {%s})\n",
240                              (int) t, (int) vgotag, (int) vgoref, (int) ne, vgname, vgclass);
241                       dumpattr(vg, fulldump, 0);
242                       Vdetach(vgt);
243                   }
244                 else
245                   {
246                       name = HDgettagsname((uint16) vstag);
247                       if (!name)
248                           printf("  --:%d <%d/%d> %s\n", (int) t, (int) vstag, (int) vsid, "Unknown Tag");
249                       else
250                         {
251                             printf("  --:%d <%d/%d> %s\n", (int) t, (int) vstag, (int) vsid, name);
252                             HDfree(name);
253                         } /* end else */
254                   }
255             }   /* while */
256 
257           Vdetach(vg);
258           nvg++;
259 
260       }     /* while */
261 
262     if (nvg == 0)
263       {
264           printf("No vgroups in this file\n");
265       }
266 
267     nlone = VSlone(f, NULL, 0);
268     if (nlone > 0)
269       {
270 
271           printf("Lone vdatas:\n");
272           if (NULL == (lonevs = (int32 *) HDmalloc(sizeof(int) * (size_t)nlone)))
273             {
274                 printf("%s: File has %d lone vdatas but ", av[0], (int) nlone);
275                 printf("cannot alloc lonevs space. Quit.\n");
276                 exit(0);
277             }
278 
279           VSlone(f, lonevs, nlone);
280           for (i = 0; i < nlone; i++)
281             {
282                 vsid = lonevs[i];
283                 if (FAIL == (vs = VSattach(f, lonevs[i], "r")))
284                   {
285                       printf("cannot open vs id=%d\n", (int) vsid);
286                       continue;
287                   }
288                 VSinquire(vs, &nv, &interlace, fields, &vsize, vsname);
289                 if (HDstrlen(vsname) == 0)
290                     HDstrcat(vsname, "NoName");
291                 vsotag = VSQuerytag(vs);
292                 vsoref = VSQueryref(vs);
293                 VSgetclass(vs, vsclass);
294                 printf("L vs:%d <%d/%d> nv=%d i=%d fld [%s] vsize=%d (%s {%s})\n",
295                        (int) vsid, (int) vsotag, (int) vsoref, (int) nv, (int) interlace, fields, (int) vsize, vsname, vsclass);
296                 if (fulldump && vsno == 0)
297                     vsdumpfull(vs);
298                 else if (fulldump && vsno == vsoref)
299                     vsdumpfull(vs);
300                 full = fulldump && ( vsno == 0 || vsno == vsoref);
301                 dumpattr(vs, full, 1);
302                 VSdetach(vs);
303             }
304           HDfree(lonevs);
305       }
306 
307     Vend(f);
308     Hclose(f);
309 
310     return (0);
311 
312 }   /* main */
313 
314 static int32 cn = 0;
315 
316 /* ------------------------------------------------ */
317 /* printing functions used by vsdumpfull(). */
318 static int32
fmtbyte(char * x)319 fmtbyte(char *x)
320 {
321     cn += printf("%02x ", *x);
322     return (1);
323 }
324 
325 static int32
fmtchar(char * x)326 fmtchar(char *x)
327 {
328     cn++;
329     putchar(*x);
330     return (1);
331 }
332 
333 #ifdef UNUSED
334 static int32
fmtint(char * x)335 fmtint(char *x)
336 {
337     int         i = 0;
338     HDmemcpy(&i, x, sizeof(int32));
339     cn += printf("%d", i);
340     return (1);
341 }
342 #endif /* UNUSED */
343 
344 static int32
fmtfloat(char * x)345 fmtfloat(char *x)
346 {
347     float       f = (float)0.0;
348     HDmemcpy(&f, x, sizeof(float32));
349     cn += printf("%f", f);
350     return (1);
351 }
352 
353 static int32
fmtulong(char * x)354 fmtulong(char *x)
355 {
356     unsigned    l = 0;
357     HDmemcpy(&l, x, sizeof(int32));
358     cn += printf("%u", l);
359     return (1);
360 }
361 
362 static int32
fmtlong(char * x)363 fmtlong(char *x)
364 {
365     long        l = 0;
366     HDmemcpy(&l, x, sizeof(int32));
367     cn += printf("%ld", l);
368     return (1);
369 }
370 
371 static int32
fmtshort(char * x)372 fmtshort(char *x)
373 {
374     short       s = 0;
375     HDmemcpy(&s, x, sizeof(int16));
376     cn += printf("%d", s);
377     return (1);
378 }
379 
380 static int32
fmtdouble(char * x)381 fmtdouble(char *x)
382 {
383     double      d = 0.0;
384     HDmemcpy(&d, x, sizeof(float64));
385     cn += printf("%f", d);
386     return (1);
387 }
388 
389 #define BUFFER 1000000
390 
391 /* ------------------------------------------------ */
392 
393 static int32
vsdumpfull(int32 vs)394 vsdumpfull(int32 vs)
395 {
396     char        fields[VSFIELDMAX*FIELDNAMELENMAX];
397     char        vsname[100];
398     int32       j, i, t, interlace, nv, vsize;
399     uint8      *bb, *b;
400     DYN_VWRITELIST *w;
401     int32       (*fmtfn[VSFIELDMAX]) (char *);
402     int32       off[VSFIELDMAX];
403     int32       order[VSFIELDMAX];
404 
405     int32       bufsize;        /* size of the buffer we are using */
406     int32       chunk;          /* number of rows that will fit in the buffer */
407     int32       done;           /* number of rows we have done */
408     int32       count;          /* number of rows to do this time through the loop */
409 
410     int32       nf;             /* number of fields in this Vdata */
411 
412     VSinquire(vs, &nv, &interlace, fields, &vsize, vsname);
413 
414     if (nv * vsize > BUFFER)
415       {
416           bufsize = BUFFER;
417           chunk = BUFFER / vsize;
418       }
419     else
420       {
421           bufsize = nv * vsize;
422           chunk = nv;
423       }
424 
425     done = 0;
426     bb = (uint8 *) HDmalloc(bufsize);
427     if (bb == NULL)
428       {
429           printf("vsdumpfull malloc error\n");
430           return (0);
431       }
432 
433     VSsetfields(vs, fields);
434 
435     w = vswritelist(vs);
436 
437     nf = w->n;
438     for (i = 0; i < w->n; i++)
439       {
440           printf("%d: fld [%s], type=%d, order=%d\n", (int) i, w->name[i], w->type[i], w->order[i]);
441 
442           order[i] = (int32)w->order[i];
443           off[i] = DFKNTsize(w->type[i] | DFNT_NATIVE);
444 
445           switch (w->type[i])
446             {
447 
448                 case DFNT_CHAR:
449                 case DFNT_UCHAR:
450                     fmtfn[i] = fmtchar;
451                     break;
452 
453                 case DFNT_UINT8:
454                 case DFNT_INT8:
455                     fmtfn[i] = fmtbyte;
456                     break;
457 
458                 case DFNT_UINT16:
459                 case DFNT_INT16:
460                     fmtfn[i] = fmtshort;
461                     break;
462 
463                 case DFNT_UINT32:
464                       fmtfn[i] = fmtulong;
465                       break;
466 
467                 case DFNT_INT32:
468                     fmtfn[i] = fmtlong;
469                     break;
470 
471                 case DFNT_FLOAT32:
472                     fmtfn[i] = fmtfloat;
473                     break;
474 
475                 case DFNT_FLOAT64:
476                     fmtfn[i] = fmtdouble;
477                     break;
478 
479                 default:
480                     fprintf(stderr, "sorry, type [%d] not supported\n", (int) w->type[i]);
481                     break;
482 
483             }
484       }
485 
486     cn = 0;
487 
488     done = count = 0;
489     while (done != nv)
490       {
491 
492           /* figure out how many to read this time */
493           if ((nv - done) > chunk)
494               count = chunk;
495           else
496               count = nv - done;
497 
498           /* read and update bookkeeping */
499           VSread(vs, bb, count, interlace);
500           done += count;
501           b = bb;
502 
503           /* print out the data */
504           for (j = 0; j < count; j++)
505             {
506                 for (i = 0; i < nf; i++)
507                   {
508                       for (t = 0; t < order[i]; t++)
509                         {
510                             (fmtfn[i]) ((char *)b);
511                             b += off[i];
512                             putchar(' ');
513                             cn++;
514                         }
515                       putchar(' ');
516                       cn++;
517                   }
518 
519                 /*
520                  * if condensed == TRUE put as many as possible on one line else
521                  *   put one record per line
522                  */
523                 if (condensed)
524                   {
525                       if (cn > 65)
526                         {
527                             putchar('\n');
528                             cn = 0;
529                         }
530                   }
531                 else
532                   {
533                       putchar('\n');
534                   }
535             }
536 
537       }
538 
539     /* ============================================ */
540 
541     HDfree(bb);
542     printf("\n");
543 
544     return (1);
545 
546 }   /* vsdumpfull */
547 /* ------------------------------------------------ */
dumpattr(int32 vid,intn full,intn isvs)548 static intn dumpattr(int32 vid, intn full, intn isvs)
549 {
550    intn i, j, k, cn=0;
551    VDATA *vs;
552    vsinstance_t *vs_inst;
553    VGROUP *vg;
554    vginstance_t *v;
555    intn ret, nattrs, f_nattrs, alloc_flag=0;
556    vs_attr_t *vs_alist;
557    vg_attr_t *v_alist;
558    int32 i_type, i_count, i_size, off;
559    uint8 *buf=NULL, *ptr;
560    int32 (*fmtfn)(char *) =NULL;
561    char name[FIELDNAMELENMAX+1];
562    intn ret_val = SUCCEED;
563    uint8 attrbuf[BUFFER];
564 
565    if (isvs)  {
566       vs_inst = (vsinstance_t *)HAatom_object(vid);
567       if (vs_inst == NULL)  {
568          printf(">>>dumpattr:failed in getting vdata instance.\n");
569          ret_val = FAIL;
570          goto done;
571       }
572       vs = vs_inst->vs;
573       if (vs == NULL)  {
574          printf(">>>dumpattr:Failed in getting vs. \n");
575          ret_val = FAIL;
576          goto done;
577       }
578       if (0 == (nattrs = VSnattrs(vid))) {
579           printf(" 0 attributes.\n");
580           ret_val = SUCCEED;
581           goto done;
582       }
583       vs_alist = vs->alist;
584       if (!full) {
585           printf("     %d attributes:  attr_tag/ref     attr_of_field\n",
586                        nattrs);
587           for (i=0; i<nattrs; i++)  {
588              if (vs_alist->findex != (int)_HDF_VDATA)
589                  printf("     %d:               %d/%d               %d\n",
590                  i, vs_alist->atag, vs_alist->aref,(int)vs_alist->findex);
591              else
592                  printf("     %d:               %d/%d         %s\n",
593                  i, vs_alist->atag, vs_alist->aref, "VDATA");
594              vs_alist++;
595          }
596          ret_val = SUCCEED;
597          goto done;
598       }
599       printf("%d attributes:\n", nattrs);
600       for (j=-1; j<vs->wlist.n; j++)
601       {	  int32 temp;
602 
603 	  temp = (j == -1) ? (int)_HDF_VDATA : j;
604           f_nattrs = VSfnattrs(vid, temp);
605           if (f_nattrs == 0) continue;  /* no attr for this field */
606           if (j == -1)
607               printf("   Attrs of vdata:\n");
608           else
609   	      printf("   Attrs of field %d:\n", j);
610           for (i = 0; i<f_nattrs; i++)  {   /* dump the attrs */
611               ret = VSattrinfo(vid, temp, i, name, &i_type, &i_count, &i_size);
612               if (ret == FAIL) {
613                  printf(">>>dumpattr: failed in getting attr info.\n");
614                  continue;
615               }
616               printf("     %d: name=%s type=%d count=%d size=%d\n",
617                        i, name, (int)i_type, (int)i_count, (int)i_size);
618               if (i_size > BUFFER) {
619                   if (NULL == (buf = HDmalloc(i_size)))  {
620                      printf(">>>dumpattr:can't allocate buf.\n");
621                      continue;
622                   }
623                   alloc_flag = 1;
624                   if ( FAIL==VSgetattr(vid, temp, i, buf)) {
625                      printf(">>>dympattr: failed in VSgetattr.\n");
626                      continue;
627                   }
628               }
629               else
630               {
631                  if ( FAIL==VSgetattr(vid, temp, i, attrbuf)) {
632                      printf(">>>dympattr: failed in VSgetattr.\n");
633                      continue;
634                   }
635               }
636               /* format output */
637               switch (i_type)  {
638                  case DFNT_CHAR:
639                  case DFNT_UCHAR:
640                       fmtfn = fmtchar;
641                       break;
642                  case DFNT_UINT8:
643                  case DFNT_INT8:
644                       fmtfn = fmtbyte;
645                       break;
646                  case DFNT_UINT16:
647                  case DFNT_INT16:
648                       fmtfn = fmtshort;
649                       break;
650                  case DFNT_UINT32:
651                       fmtfn = fmtulong;
652                       break;
653                  case DFNT_INT32:
654                       fmtfn = fmtlong;
655                       break;
656                  case DFNT_FLOAT32:
657                       fmtfn = fmtfloat;
658                       break;
659                  case DFNT_FLOAT64:
660                       fmtfn = fmtdouble;
661                       break;
662                 default:
663                     printf(">>>dumpattr: sorry, type [%d] not supported\n", (int) i_type);
664                     break;
665               }
666               off = DFKNTsize(i_type | DFNT_NATIVE);
667               ptr = (alloc_flag) ? buf : attrbuf;
668               putchar('\t');
669               cn = 0;
670               for (k=0; k<i_count; k++)  {
671                   fmtfn((char *)ptr);
672                   ptr += off;
673                   putchar(' ');
674                   cn++;
675                   if (cn > 55)  {
676                      putchar('\n');
677                      putchar('\t');
678                      cn = 0;
679                   }
680               }
681               if (cn) putchar('\n');
682               if (alloc_flag) {
683                  if ( buf != NULL)
684                     HDfree(buf);
685                  alloc_flag = 0;
686               }
687           }  /*  attr */
688       }   /* field   */
689    }  /* isvs */
690 
691    else {  /* vgroup */
692       v = (vginstance_t *)HAatom_object(vid);
693       if (v== NULL)  {
694          printf(">>>dumpattr:failed in getting vgroup instance.\n");
695          ret_val = FAIL;
696          goto done;
697       }
698       vg = v->vg;
699       if (vg == NULL)  {
700          printf(">>>dumpattr:Failed in getting vg. \n");
701          ret_val = FAIL;
702          goto done;
703       }
704       if (0 == (nattrs = Vnattrs(vid)))  {
705           printf("  0 attributes.\n");
706           ret_val = SUCCEED;
707           goto done;
708       }
709       v_alist = vg->alist;
710       if (!full) {
711           printf("%d attributes:       attr_tag/ref  \n", nattrs);
712           for (i=0; i<nattrs; i++)  {
713              printf("     %d:               %d/%d    \n",
714                  i, v_alist->atag, v_alist->aref);
715              v_alist++;
716          }
717           ret_val = SUCCEED;
718           goto done;
719       }
720       printf("%d attributes:\n", nattrs);
721       for (i = 0; i<nattrs; i++)  {   /* dump the attrs */
722           ret = Vattrinfo(vid, i, name, &i_type, &i_count, &i_size);
723           if (ret == FAIL) {
724               printf(">>>dumpattr: failed in getting attr info.\n");
725               continue;
726           }
727           printf("   %d: name=%s type=%d count=%d size=%d\n",
728                      i,  name, (int)i_type, (int)i_count, (int)i_size);
729           if (i_size > BUFFER) {
730               if (NULL == (buf = HDmalloc(i_size)))  {
731                  printf(">>>dumpattr:can't allocate buf.\n");
732                  continue;
733               }
734               alloc_flag = 1;
735               if ( FAIL == Vgetattr(vid, i, buf)) {
736                  printf(">>>dympattr: failed in Vgetattr.\n");
737                  continue;
738               }
739           }
740           else
741           {
742              if ( FAIL == Vgetattr(vid, i, attrbuf)) {
743                  printf(">>>dympattr: failed in Vgetattr.\n");
744                  continue;
745               }
746           }
747           /* format output */
748           switch (i_type)  {
749              case DFNT_CHAR:
750              case DFNT_UCHAR:
751                   fmtfn = fmtchar;
752                   break;
753              case DFNT_UINT8:
754              case DFNT_INT8:
755                   fmtfn = fmtbyte;
756                   break;
757              case DFNT_UINT16:
758              case DFNT_INT16:
759                   fmtfn = fmtshort;
760                   break;
761              case DFNT_UINT32:
762                   fmtfn = fmtulong;
763                   break;
764              case DFNT_INT32:
765                   fmtfn = fmtlong;
766                   break;
767              case DFNT_FLOAT32:
768                   fmtfn = fmtfloat;
769                   break;
770              case DFNT_FLOAT64:
771                   fmtfn = fmtdouble;
772                   break;
773              default:
774                 printf(">>>dumpattr: sorry, type [%d] not supported\n", (int) i_type);
775                 break;
776           }
777           off = DFKNTsize(i_type | DFNT_NATIVE);
778           ptr = (alloc_flag) ? buf : attrbuf;
779           putchar('\t');
780           cn = 0;
781           for (k=0; k<i_count; k++)  {
782               fmtfn((char *)ptr);
783               ptr += off;
784               putchar(' ');
785               cn++;
786               if (cn > 55)  {
787                  putchar('\n');
788                  putchar('\t');
789                  cn = 0;
790               }
791           }
792           if (cn) putchar('\n');
793           if (alloc_flag) {
794              if ( buf != NULL)
795                 HDfree(buf);
796              alloc_flag = 0;
797           }
798       }  /*  attr */
799    }  /* vgroup */
800 
801    ret_val = SUCCEED;
802 
803 done:
804    return ret_val;
805 }
806 /* ------------------------------------- */
807