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