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 /* hdp_util.c,v 1.1 1994/04/18 15:49:18 georgev Exp */
15
16 #include "hdp.h"
17
18 const char *unknown_tag = "Unknown Tag";
19
20 char *
tagnum_to_name(intn num)21 tagnum_to_name(intn num)
22 {
23 char *ret;
24
25 if (num < 0)
26 ret = NULL;
27 else
28 ret = HDgettagsname((uint16)num);
29 if (ret == NULL)
30 ret = HDstrdup(unknown_tag);
31 return (ret);
32 } /* end tagnum_to_name() */
33
tagname_to_num(const char * name)34 intn tagname_to_num(const char *name)
35 {
36 return (HDgettagnum(name));
37 } /* end tagname_to_num() */
38
39 /*
40 * Routines to create a list of file names from the command line
41 */
42 /* assumes that curr_arg is pointing to the first file name */
43 filelist_t *
make_file_list(intn curr_arg,intn argc,char * argv[])44 make_file_list(intn curr_arg, intn argc, char *argv[])
45 {
46 intn i;
47 filelist_t *ret;
48
49 if (curr_arg > argc) /* consistency check */
50 return (NULL);
51
52 ret = (filelist_t *) HDmalloc(sizeof(filelist_t));
53 if (ret == NULL)
54 {
55 fprintf(stderr, "make_file_list: space allocation failed\n");
56 return (NULL);
57 }
58 ret->file_arr = (char **) HDmalloc(sizeof(char *) * ((argc - curr_arg) + 1));
59 if (ret->file_arr == NULL)
60 {
61 fprintf(stderr, "make_file_list: space allocation failed\n");
62 HDfree(ret);
63 return (NULL);
64 } /* end if */
65
66 ret->max_files = (argc - curr_arg);
67 ret->curr_file = 0;
68 for (i = 0; curr_arg < argc; i++, curr_arg++)
69 ret->file_arr[i] = HDstrdup(argv[curr_arg]);
70 return (ret);
71 } /* end make_file_list() */
72
get_next_file(filelist_t * f_list,intn advance)73 char * get_next_file(filelist_t * f_list, intn advance)
74 {
75 if (advance)
76 f_list->curr_file++;
77 if (f_list->curr_file >= f_list->max_files)
78 return (NULL);
79 return (f_list->file_arr[f_list->curr_file]);
80 } /* end get_next_file() */
81
82 /* free_node_vg_info_t frees a node of vgroup info */
free_node_vg_info_t(vg_info_t * aNode)83 vg_info_t* free_node_vg_info_t(
84 vg_info_t* aNode)
85 {
86 intn i;
87
88 if( aNode != NULL )
89 {
90 if (aNode->children != NULL)
91 {
92 for (i = 0; i < aNode->n_entries; i++)
93 if (aNode->children[i] != NULL)
94 {
95 HDfree(aNode->children[i]);
96 aNode->children[i] = NULL;
97 }
98 HDfree( aNode->children );
99 aNode->children = NULL;
100 }
101 if (aNode->type != NULL)
102 {
103 for (i = 0; i < aNode->n_entries; i++)
104 if (aNode->type[i] != NULL)
105 {
106 HDfree(aNode->type[i]);
107 aNode->type[i] = NULL;
108 }
109 HDfree( aNode->type );
110 aNode->type = NULL;
111 }
112 if (aNode->vg_name != NULL)
113 {
114 HDfree(aNode->vg_name);
115 aNode->vg_name = NULL;
116 }
117 }
118 return(aNode);
119 } /* end of free_node_vg_info_t */
120
121 /* free_struct_list use HDfree to free the list of vgroup info structs */
free_vginfo_list(vg_info_t ** nodelist,int32 num_items)122 vg_info_t ** free_vginfo_list(
123 vg_info_t **nodelist,
124 int32 num_items )
125 {
126 intn i;
127
128 /* if the list is not NULL, free each node then reset the list to NULL */
129 if (nodelist != NULL)
130 {
131 for (i = 0; i < num_items; i++)
132 if (nodelist[i] != NULL)
133 {
134 nodelist[i] = free_node_vg_info_t(nodelist[i]);
135 HDfree(nodelist[i]);
136 nodelist[i] = NULL;
137 }
138 HDfree(nodelist);
139 }
140 return( NULL );
141 } /* end of free_vginfo_list */
142
143 /* free_struct_list use HDfree to free the list of vgroup info structs */
free_node_obj_chosen_t(obj_chosen_t * aNode)144 obj_chosen_t ** free_node_obj_chosen_t(
145 obj_chosen_t *aNode)
146 {
147 if( aNode != NULL )
148 {
149 if (aNode->name != NULL)
150 {
151 fprintf(stderr, " namd = %s \n", aNode->name);
152 HDfree( aNode->name );
153 }
154 if (aNode->classname != NULL)
155 {
156 HDfree( aNode->classname );
157 }
158 HDfree(aNode);
159 }
160 return(NULL);
161 } /* end of free_node_obj_chosen_t */
162
163 /* free_struct_list use HDfree to free the list of vgroup info structs */
free_obj_chosen_t_list(obj_chosen_t ** nodelist,int32 num_items)164 void free_obj_chosen_t_list(
165 obj_chosen_t **nodelist,
166 int32 num_items )
167 {
168 intn i;
169
170 /* if the list is not NULL, free each node then reset the list to NULL */
171 if ((*nodelist) != NULL)
172 {
173 for (i = 0; i < num_items; i++)
174 {
175 if ((*nodelist)[i].name != NULL)
176 {
177 HDfree((*nodelist)[i].name);
178 }
179 if ((*nodelist)[i].classname != NULL)
180 {
181 HDfree((*nodelist)[i].classname);
182 }
183 }
184 HDfree((*nodelist));
185 (*nodelist) = NULL;
186 }
187 } /* end of free_obj_chosen_t_list */
188
189 /* free_str_list use HDfree to free the list of strings of characters */
free_str_list(char ** str_list,int32 num_items)190 char** free_str_list( char **str_list,
191 int32 num_items )
192 {
193 intn i;
194
195 if( str_list != NULL)
196 {
197 for( i = 0; i < num_items; i++ )
198 if (str_list[i] != NULL)
199 HDfree(str_list[i]);
200 HDfree( str_list );
201 }
202 return( NULL );
203 } /* end of free_str_list */
204
205 /* free_num_list use HDfree to free the list of integers; this routine
206 is short but can be used in many different places and very convenient */
free_num_list(int32 * num_list)207 int32* free_num_list( int32 *num_list )
208 {
209 if( num_list != NULL)
210 HDfree( num_list );
211 return( NULL );
212 } /* end of free_num_list */
213
214 void
free_file_list(filelist_t * f_list)215 free_file_list(filelist_t * f_list)
216 {
217 intn i;
218
219 for (i = 0; i < f_list->max_files; i++)
220 HDfree(f_list->file_arr[i]);
221 HDfree(f_list->file_arr);
222 HDfree(f_list);
223 } /* end free_file_list() */
224
225 /*
226 * Routines to manipulate group lists
227 */
228 groupinfo_t *
make_group_list(int32 fid,uint16 tag,uint16 ref)229 make_group_list(int32 fid, uint16 tag, uint16 ref)
230 {
231 intn nobj;
232 intn i;
233 groupinfo_t *ret;
234 int32 gid;
235
236 if (tag == DFTAG_RIG || tag == DFTAG_SDG || tag == DFTAG_NDG)
237 {
238 if ((gid = DFdiread(fid, tag, ref)) == FAIL)
239 return (NULL);
240 if ((nobj = DFdinobj(gid)) == FAIL)
241 return (NULL);
242 if ((ret = (groupinfo_t *) HDmalloc(sizeof(groupinfo_t))) == NULL)
243 {
244 fprintf(stderr, "make_group_list: space allocation failed\n");
245 return (NULL);
246 }
247 ret->max_dds = nobj;
248 ret->curr_dd = 0;
249 if (nobj > 0)
250 {
251 if ((ret->dd_arr = (DFdi *) HDmalloc(sizeof(DFdi) * nobj)) == NULL)
252 {
253 fprintf(stderr, "make_group_list: space allocation failed\n");
254 HDfree(ret);
255 return (NULL);
256 } /* end if */
257 for (i = 0; i < nobj; i++)
258 {
259 if (DFdiget(gid, &ret->dd_arr[i].tag, &ret->dd_arr[i].ref) == FAIL)
260 {
261 HDfree(ret->dd_arr);
262 HDfree(ret);
263 return (NULL);
264 } /* end if */
265 } /* end for */
266 } /* end if */
267 else
268 { /* paranoia sets in... */
269 ret->max_dds = ret->curr_dd = 0;
270 ret->dd_arr = NULL;
271 } /* end else */
272 } /* end if */
273 else
274 { /* check for Vgroup? */
275 int32 vkey;
276
277 /* Yes, I know this wastes time, but at least it allows uniform access */
278 /* to both types of groups in HDF files... */
279 if (vinit_done == FALSE)
280 { /* check whether we've already init'ed Vsets */
281 vinit_done = TRUE;
282 Vinitialize(fid);
283 } /* end if */
284 if ((vkey = Vattach(fid, ref, "r")) != FAIL)
285 {
286 if ((nobj = Vntagrefs(vkey)) != FAIL)
287 {
288 if( nobj > 0 ) { /* Albert fixed */
289 int32 *temp_tag;
290 int32 *temp_ref;
291
292 if ((temp_tag = (int32 *) HDmalloc(sizeof(int32) * nobj)) == NULL)
293 {
294 fprintf(stderr, "make_group_list: space allocation failed\n");
295 Vdetach(vkey);
296 return (NULL);
297 } /* end if */
298 if ((temp_ref = (int32 *) HDmalloc(sizeof(int32) * nobj)) == NULL)
299 {
300 fprintf(stderr, "make_group_list: space allocation failed\n");
301
302 Vdetach(vkey);
303 HDfree(temp_tag);
304 return (NULL);
305 } /* end if */
306
307 if (Vgettagrefs(vkey, temp_tag, temp_ref, nobj) == FAIL)
308 {
309 Vdetach(vkey);
310 HDfree(temp_tag);
311 HDfree(temp_ref);
312 return (NULL);
313 } /* end if */
314
315 if ((ret = (groupinfo_t *) HDmalloc(sizeof(groupinfo_t))) == NULL)
316 {
317 fprintf(stderr, "make_group_list: space allocation failed\n");
318
319 Vdetach(vkey);
320 HDfree(temp_tag);
321 HDfree(temp_ref);
322 return (NULL);
323 } /* end if */
324 ret->max_dds = nobj;
325 ret->curr_dd = 0;
326 if ((ret->dd_arr = (DFdi *) HDmalloc(sizeof(DFdi) * nobj)) == NULL)
327 {
328 fprintf(stderr, "make_group_list: space allocation failed\n");
329
330 Vdetach(vkey);
331 HDfree(temp_tag);
332 HDfree(temp_ref);
333 HDfree(ret);
334 return (NULL);
335 } /* end if */
336
337 for (i = 0; i < nobj; i++)
338 {
339 ret->dd_arr[i].tag = (uint16) temp_tag[i];
340 ret->dd_arr[i].ref = (uint16) temp_ref[i];
341 } /* end for */
342
343 HDfree(temp_tag);
344 HDfree(temp_ref);
345 } /* if nobj > 0 */
346 /* BMR: 7/28/00 must add this one, otherwise, HDfree fails later */
347 else /* nobj <= 0 */
348 return( NULL );
349 } /* end if */
350 else /* bad vkey? */
351 return (NULL);
352 Vdetach(vkey); /* release the Vgroup */
353 } /* end if */
354 else /* failed to attach */
355 return (NULL);
356 } /* end else */
357 return (ret);
358 } /* end make_group_list() */
359
360 DFdi *
get_next_group(groupinfo_t * g_list,intn advance)361 get_next_group(groupinfo_t * g_list, intn advance)
362 {
363 if (advance)
364 g_list->curr_dd++;
365 if (g_list->curr_dd >= g_list->max_dds)
366 return (NULL);
367 return (&g_list->dd_arr[g_list->curr_dd]);
368 } /* end get_next_group() */
369
370 int32
get_group_max(groupinfo_t * g_list)371 get_group_max(groupinfo_t * g_list)
372 {
373 if (g_list != NULL)
374 return (g_list->max_dds);
375 return (FAIL);
376 } /* end get_group_max() */
377
378 void
free_group_list(groupinfo_t * g_list)379 free_group_list(groupinfo_t * g_list)
380 {
381 if( g_list != NULL )
382 {
383 if( g_list->dd_arr != NULL )
384 HDfree(g_list->dd_arr);
385 HDfree(g_list);
386 }
387 } /* end free_group_list() */
388
389 /*
390 * Routines to manipulate tag/ref lists
391 */
392
393 objlist_t *
make_obj_list(int32 fid,uint32 options)394 make_obj_list(int32 fid, uint32 options)
395 {
396 intn nobj; /* number of DDs in the file */
397 int32 status; /* status of various HDF calls */
398 int32 aid; /* temporary AID to use while getting DD info */
399 int16 tmp_spec; /* temporary storage for special status */
400 objlist_t *obj_ret; /* pointer to the dd list to return */
401 objinfo_t *obj_ptr; /* temporary pointer to a working DD object */
402 sp_info_block_t info; /* temp. storage for special elem. info */
403 intn n, m; /* local counting variable */
404
405 /* get the number of all objects in the file */
406 nobj = Hnumber(fid, DFTAG_WILDCARD);
407 if (nobj == FAIL || nobj <= 0 ) /* BMR: added check for nobj<=0 */
408 return (NULL);
409
410 /* allocate space for the object list - exit at failure??? */
411 if ((obj_ret = (objlist_t *) HDmalloc(sizeof(objlist_t))) == NULL)
412 {
413 fprintf(stderr, "make_obj_list: space allocation failed\n");
414 return (NULL);
415 }
416
417 obj_ret->max_obj = nobj; /* set the number of objects */
418 obj_ret->curr_obj = 0;
419 obj_ret->raw_obj_arr = (objinfo_t *) HDmalloc(sizeof(objinfo_t) * nobj);
420
421 /* should it exit on failure ??? */
422 if( obj_ret->raw_obj_arr == NULL)
423 {
424 fprintf(stderr, "make_obj_list: space allocation failed\n");
425 HDfree(obj_ret);
426 return (NULL);
427 } /* end if */
428
429 /* Clear array of dd/object information */
430 HDmemset(obj_ret->raw_obj_arr, 0, sizeof(objinfo_t) * nobj);
431
432 /*
433 * Read all the tag/ref's in the file into an array
434 */
435 /* start the reading of an access element */
436 aid = Hstartread(fid, DFTAG_WILDCARD, DFREF_WILDCARD);
437 if (aid == FAIL)
438 {
439 HEprint(stderr, 0);
440 HDfree(obj_ret->raw_obj_arr);
441 HDfree(obj_ret);
442 return (NULL);
443 } /* end if */
444
445 /* for each element */
446 for (n = 0, status = SUCCEED; (n < nobj) && (status != FAIL); n++)
447 {
448 Hinquire(aid, NULL, &(obj_ret->raw_obj_arr[n].tag),
449 &(obj_ret->raw_obj_arr[n].ref), &(obj_ret->raw_obj_arr[n].length),
450 &(obj_ret->raw_obj_arr[n].offset), NULL, NULL, &tmp_spec);
451 if (options & CHECK_SPECIAL)
452 { /* are we looking for spec. elem. ? */
453 obj_ret->raw_obj_arr[n].is_special = (tmp_spec != 0);
454 if (obj_ret->raw_obj_arr[n].is_special)
455 { /* get the special info. */
456 if ((status = HDget_special_info(aid, &info)) == FAIL)
457 {
458 obj_ret->raw_obj_arr[n].is_special = 0;
459 } /* end if */
460 else
461 { /* copy over special information we found */
462 obj_ret->raw_obj_arr[n].spec_info = (sp_info_block_t *) HDmalloc(sizeof(sp_info_block_t));
463 if( obj_ret->raw_obj_arr[n].spec_info == NULL)
464 {
465 fprintf(stderr, "make_obj_list: space allocation failed\n");
466 obj_ret->raw_obj_arr[n].is_special = 0;
467 }
468 else
469 HDmemcpy(obj_ret->raw_obj_arr[n].spec_info, &info, sizeof(sp_info_block_t));
470 } /* end else */
471 } /* end if */
472 } /* end if */
473 status = Hnextread(aid, DFTAG_WILDCARD, DFREF_WILDCARD, DF_CURRENT);
474 } /* end for */
475
476 if (Hendaccess(aid) == FAIL)
477 {
478 HEprint(stderr, 0);
479 HDfree(obj_ret->raw_obj_arr);
480 HDfree(obj_ret);
481 return (NULL);
482 } /* end if */
483
484 /* Post-process the list of dd/objects, adding more information */
485 /* Also set up the pointers for the sorted list to be manipulated later */
486
487 obj_ret->srt_obj_arr = (objinfo_t **) HDmalloc(sizeof(objinfo_t *) * nobj);
488 if( obj_ret->srt_obj_arr == NULL )
489 {
490 fprintf(stderr, "make_obj_list: space allocation failed\n");
491 HDfree(obj_ret->raw_obj_arr);
492 HDfree(obj_ret);
493 return (NULL);
494 } /* end if */
495
496 /* Loop for more information */
497 for (n = 0; n < nobj; n++)
498 {
499 obj_ptr = obj_ret->srt_obj_arr[n] = &obj_ret->raw_obj_arr[n];
500
501 /* set the index value to a flag for later */
502 obj_ptr->index = (-1);
503
504 /* check for a group */
505 if (options & CHECK_GROUP)
506 { /* are we looking for groups ? */
507 if (obj_ptr->tag == DFTAG_RIG || obj_ptr->tag == DFTAG_SDG
508 || obj_ptr->tag == DFTAG_NDG || obj_ptr->tag == DFTAG_VG)
509 {
510 obj_ptr->is_group = TRUE;
511 obj_ptr->group_info = make_group_list(fid, obj_ptr->tag, obj_ptr->ref);
512 if( obj_ptr->group_info == NULL )
513 {
514 /* do not free these because even this element has no group
515 list, it still can be displayd */
516 /*
517 HDfree(obj_ret->raw_obj_arr);
518 HDfree(obj_ret);
519 return (NULL);
520 */
521 } /* end if */
522 } /* end if */
523 } /* end if */
524 } /* end for */
525
526 /* Loop once more to figure out the index information */
527 for (n = 0, obj_ptr = &obj_ret->raw_obj_arr[0]; n < nobj; n++, obj_ptr++)
528 {
529 if (obj_ptr->index == (-1))
530 { /* first object of this type in the file */
531 int32 temp_index = 0;
532 objinfo_t *temp_ptr; /* temporary pointer to a working DD object */
533
534 /* the object gets index of 0 */
535 obj_ptr->index = 0;
536
537 /* look for other objects of this tag */
538 for (m = n, temp_ptr = obj_ptr + 1; m+1 < nobj; m++, temp_ptr++)
539 {
540 if (temp_ptr->tag == obj_ptr->tag)
541 temp_ptr->index = ++temp_index; /* set next index */
542 } /* end for */
543 } /* end if */
544 } /* end for */
545
546 obj_ret->options = options;
547 return (obj_ret);
548 } /* end make_dd_list() */
549
get_next_obj(objlist_t * o_list,intn advance)550 objinfo_t* get_next_obj(
551 objlist_t * o_list, intn advance )
552 {
553 if( advance )
554 o_list->curr_obj++;
555 if( o_list->curr_obj >= o_list->max_obj )
556 return (NULL);
557 return( o_list->srt_obj_arr[o_list->curr_obj] );
558 } /* end get_next_obj() */
559
goto_nth_obj(objlist_t * o_list,intn n)560 objinfo_t* goto_nth_obj(
561 objlist_t * o_list, intn n )
562 {
563 if( n >= 0 && n < o_list->max_obj )
564 o_list->curr_obj = n;
565 return( o_list->srt_obj_arr[o_list->curr_obj] );
566 } /* end goto_nth_obj() */
567
reset_obj_list(objlist_t * o_list)568 void reset_obj_list(
569 objlist_t * o_list )
570 {
571 if( o_list != NULL )
572 o_list->curr_obj = 0;
573 } /* end reset_obj_list() */
574
free_obj_list(objlist_t * o_list)575 void free_obj_list(
576 objlist_t * o_list )
577 {
578 intn i; /* local counting variable */
579 objinfo_t *obj_ptr; /* temporary pointer to a working DD object */
580
581 /* BMR: verify that o_list is not nil before accessing */
582 if( o_list != NULL )
583 {
584 for (i = 0, obj_ptr = o_list->raw_obj_arr; i < o_list->max_obj;
585 i++, obj_ptr++)
586 {
587 /* group_info can be NULL while is_group is set, how to handle
588 this one??? BMR 8/1/2000
589 if( obj_ptr->is_group && obj_ptr->group_info != NULL ) */
590 if( obj_ptr->is_group )
591 free_group_list( obj_ptr->group_info );
592 if( obj_ptr->is_special )
593 HDfree( obj_ptr->spec_info );
594 } /* end for */
595 HDfree(o_list->srt_obj_arr);
596 HDfree(o_list->raw_obj_arr);
597 HDfree(o_list);
598 }
599 else
600 fprintf(stderr, ">>>free_obj_list failed - attempting to free a NULL list \n");
601 } /* end free_obj_list() */
602
sort_obj_list_by_tag(const void * p1,const void * p2)603 int sort_obj_list_by_tag(const void *p1, const void *p2)
604 {
605 const objinfo_t *a = (const objinfo_t *) *((const void **) p1);
606 const objinfo_t *b = (const objinfo_t *) *((const void **) p2);
607
608 if (a->tag > b->tag)
609 return (1);
610 if (a->tag < b->tag)
611 return (-1);
612 if (a->ref > b->ref)
613 return (1);
614 if (a->ref < b->ref)
615 return (-1);
616 return (0);
617 } /* end sort_obj_info_by_tag() */
618
619 #if 0 /* No longer possible since objects can have more than one label
620 * -GV 6/12/97 */
621 int sort_obj_list_by_name(const void *p1, const void *p2)
622 {
623 const objinfo_t *a = (const objinfo_t *) *((void **) p1);
624 const objinfo_t *b = (const objinfo_t *) *((void **) p2);
625
626 /* Any label has priority over no label, else sort alphabetically */
627 if (a->has_label)
628 {
629 if (b->has_label)
630 return (HDstrcmp(a->lab_info, b->lab_info));
631 else
632 return (1);
633 } /* end if */
634 else
635 {
636 if (b->has_label)
637 return (-1);
638 else
639 return (0);
640 } /* end else */
641 } /* end sort_obj_info_by_tag() */
642 #endif
643
sort_obj_list(objlist_t * o_list,sort_t sort_type)644 void sort_obj_list(objlist_t * o_list, sort_t sort_type)
645 {
646 switch (sort_type)
647 {
648 #if 0 /* No longer possible since objects can have more than one label
649 * -GV 6/12/97 */
650 case ONAME: /* sort by name order */
651 qsort(o_list->srt_obj_arr, o_list->max_obj, sizeof(objinfo_t *), sort_obj_list_by_name);
652 break;
653 #endif
654 case OGROUP: /* sort by group order */
655 break; /* not currently implemented */
656
657 case OTAG: /* sort by tag order */
658 qsort(o_list->srt_obj_arr, o_list->max_obj, sizeof(objinfo_t *), sort_obj_list_by_tag);
659 break;
660
661 case OFILE: /* sort by file order */
662 default:
663 break;
664 } /* end switch() */
665 } /* end sort_obj_list() */
666
667 /* Misc. utility functions */
int32_compare(const void * a,const void * b)668 int int32_compare(const void *a, const void *b)
669 {
670 if (*(const int32 *) a > *(const int32 *) b)
671 return (1);
672 else if (*(const int32 *) a < *(const int32 *) b)
673 return (-1);
674 else
675 return (0);
676 } /* end int32_compare() */
677
sort(int32 * chosen,int32 choices)678 void sort(int32 *chosen, int32 choices)
679 {
680 qsort((void *) chosen, choices, sizeof(int32), int32_compare);
681 }
682
683 /* resetBuff frees the passed-in pointer and resets it to NULL,
684 if it is not NULL. Its purpose is to make cleaning up simpler
685 throughout the entire dumper */
resetBuff(VOIDP * ptr)686 void resetBuff( VOIDP *ptr )
687 {
688 if( *ptr != NULL )
689 {
690 HDfree(*ptr);
691 *ptr = NULL;
692 }
693 }
694
695 /* parse_number_opts take a list of numbers separated by commas then
696 retrieves the numbers and stores them in the structure provided by
697 the caller. This routine is used by all the routines
698 parse_dumpxx_opts to parse the index or ref list that accompanies
699 option -i or -r */
700 void
parse_number_opts(char * argv[],int * curr_arg,number_filter_t * filter)701 parse_number_opts( char *argv[],
702 int *curr_arg,
703 number_filter_t *filter)
704 {
705 int32 numItems = 0, i;
706 char *tempPtr = NULL;
707 char *ptr = NULL;
708 int32 *newlist;
709
710 /* put a temp ptr at the beginning of the given list of numbers,
711 separated by commas, for example, 1,2,3 */
712 ptr = argv[*curr_arg];
713
714 /* check if it's the end of the command */
715 if( ptr == NULL )
716 {
717 printf("Missing values for option\n");
718 exit(1);
719 }
720
721 /* then traverse the list and count the number of items in it */
722 while ((tempPtr = HDstrchr(ptr, ',')) != NULL)
723 {
724 numItems++; /* count number of items in the list */
725 ptr = tempPtr + 1;/* forward pointer to next item, after a comma */
726 } /* end while */
727 if (*ptr != '\0') /* count the last item */
728 numItems++;
729
730 if (filter->num_list != NULL)
731 {
732 /* Update number of items that will be in the list */
733 numItems = numItems + filter->num_items;
734
735 /* Allocate a new list */
736 newlist = (int32 *) HDmalloc(sizeof(intn) * numItems);
737 CHECK_ALLOC(newlist, "newlist", "parse_number_opts" );
738
739 /* If filter->num_list is already allocated, transfer pointers over
740 to the new list and deallocate the old list of pointers */
741 if (filter->num_list != NULL)
742 {
743 for (i=0; i < filter->num_items; i++)
744 newlist[i] = filter->num_list[i];
745 HDfree(filter->num_list);
746 }
747
748 /* Set _cdfs to the new list */
749 filter->num_list = newlist;
750 newlist = NULL;
751 }
752
753 else
754 {
755 /* allocate space to hold all the items in the list */
756 filter->num_list = (int32 *) HDmalloc(sizeof(intn) * numItems);
757 CHECK_ALLOC(filter->num_list, "filter->num_list", "parse_number_opts" );
758 }
759
760 /* go back to the beginning of the list and read in the numbers */
761 ptr = argv[*curr_arg];
762 i = 0; /* index of the list */
763 while ( i < numItems )
764 {
765 tempPtr = HDstrchr(ptr, ',');
766 if( tempPtr != NULL )
767 *tempPtr = '\0'; /* end the string of digits */
768 filter->num_list[i] = atoi(ptr); /* convert string to digits */
769 ptr = tempPtr + 1;
770 i++;
771 }
772 filter->num_items = numItems; /* save the number of items */
773 } /* parse_number_opts */
774
775 /* parse_string_opts take a list of strings separated by commas then
776 retrieves the strings and stores them in the structure provided by
777 the caller. This routine is used by all the routines
778 parse_dumpxx_opts to parse the name or class list that accompanies
779 option -n or -c */
780 void
parse_string_opts(char * argv[],int * curr_arg,char_filter_t * filter)781 parse_string_opts( char *argv[],
782 int *curr_arg,
783 char_filter_t *filter)
784 {
785 int32 numItems = 0, i;
786 char *tempPtr = NULL;
787 char *ptr = NULL;
788
789 /* put a temp pointer at the beginning of the list of strings,
790 separated by commas */
791 ptr = argv[*curr_arg];
792
793 /* check if it's the end of the command */
794 if( ptr == NULL )
795 {
796 printf("Missing values for option\n");
797 exit(1);
798 }
799
800 /* then traverse the list and count the number of strings in it */
801 while ((tempPtr = HDstrchr(ptr, ',')) != NULL)
802 {
803 numItems++;
804 ptr=tempPtr+1;
805 } /* end while */
806 if (*ptr != '\0') /* count the last item */
807 numItems++;
808
809 /* allocate space to hold pointers that will point to the given strings */
810 filter->str_list = (char **) HDmalloc(sizeof(char *) * numItems);
811 CHECK_ALLOC( filter->str_list, "filter->str_list", "parse_string_opts" );
812
813 /* go back to the beginning of the list and read in the given strings */
814 ptr = argv[*curr_arg];
815 i = 0; /* init the index of the list */
816 while ( i < numItems )
817 {
818 tempPtr = HDstrchr(ptr, ','); /* find the end of a string */
819 if( tempPtr != NULL )
820 *tempPtr = '\0'; /* end the string with a NULL char */
821
822 /* allocate space for each string */
823 filter->str_list[i] = (char *)HDmalloc(sizeof(char) * (HDstrlen(ptr)+1));
824 CHECK_ALLOC( filter->str_list[i], "filter->str_list[i]", "parse_string_opts" );
825 HDstrcpy(filter->str_list[i], ptr); /* get the current string */
826 ptr = tempPtr + 1; /* move pointer to next item or end of list */
827 i++;
828 } /* end while */
829
830 filter->num_items = numItems; /* save the number of items */
831
832 } /* parse_string_opts */
833
init_obj_chosen_node(obj_chosen_t * aNode)834 void init_obj_chosen_node(obj_chosen_t *aNode)
835 {
836 aNode->index = -1;
837 aNode->refnum = -1;
838 aNode->name = NULL;
839 aNode->classname = NULL;
840 aNode->type_of_info = INVALID;
841 }
842
parse_value_opts(char * argv[],int * curr_arg,dump_info_t ** dump_opts,info_type_t info_type)843 void parse_value_opts( char *argv[],
844 int *curr_arg,
845 dump_info_t **dump_opts,
846 info_type_t info_type)
847 {
848 int32 numItems = 0, i;
849 char *tempPtr = NULL;
850 char *ptr = NULL;
851 obj_chosen_t *newlist;
852
853 /* put a temp ptr at the beginning of the given list of numbers,
854 separated by commas, for example, 1,2,3 */
855 ptr = argv[*curr_arg];
856
857 /* check if it's the end of the command */
858 if( ptr == NULL )
859 {
860 printf("Missing values for option\n");
861 exit(1);
862 }
863
864 /* then traverse the list and count the number of items in it */
865 while ((tempPtr = HDstrchr(ptr, ',')) != NULL)
866 {
867 numItems++; /* count number of items in the list */
868 ptr = tempPtr + 1;/* forward pointer to next item, after a comma */
869 } /* end while */
870 if (*ptr != '\0') /* count the last item */
871 numItems++;
872
873 if ((*dump_opts)->all_types != NULL)
874 {
875 /* Update number of chosen SDSs so far */
876 numItems = numItems + (*dump_opts)->num_chosen;
877
878 /* Allocate a new list */
879 newlist = (obj_chosen_t *) HDmalloc(sizeof(obj_chosen_t) * numItems);
880 CHECK_ALLOC(newlist, "newlist", "parse_value_opts" );
881
882 /* transfer pointers from (*dump_opts)->all_types over to the new list
883 and deallocate the old list of pointers */
884 for (i=0; i < (*dump_opts)->num_chosen; i++)
885 newlist[i] = (*dump_opts)->all_types[i];
886 for (i=(*dump_opts)->num_chosen; i < numItems; i++)
887 init_obj_chosen_node(&newlist[i]);
888
889 /* Set (*dump_opts)->all_types to the new list */
890 (*dump_opts)->all_types = newlist;
891 newlist = NULL;
892 }
893 else
894 {
895 /* allocate space to hold all the items in the list */
896 (*dump_opts)->all_types = (obj_chosen_t *) HDmalloc(sizeof(obj_chosen_t) * numItems);
897 CHECK_ALLOC((*dump_opts)->all_types, "filter", "parse_value_opts" );
898
899 /* Initialize all nodes */
900 for (i=0; i < numItems; i++)
901 init_obj_chosen_node(&(*dump_opts)->all_types[i]);
902 }
903
904 /* go back to the beginning of the list and read in the numbers */
905 ptr = argv[*curr_arg];
906
907 /* index of the list, it should start at 0 or at the number of SDSs chosen so far */
908 i = (*dump_opts)->num_chosen != NO_SPECIFIC ? (*dump_opts)->num_chosen : 0;
909 while ( i < numItems )
910 {
911 tempPtr = HDstrchr(ptr, ',');
912 if (tempPtr != NULL)
913 *tempPtr = '\0'; /* end the string of digits */
914 switch (info_type)
915 {
916 case IS_INDEX:
917 /* convert the string of characters to digits and store for refnum */
918 (*dump_opts)->all_types[i].index = atoi(ptr);
919 break;
920
921 case IS_REFNUM:
922 /* convert the string of characters to digits and store for refnum */
923 (*dump_opts)->all_types[i].refnum = atoi(ptr);
924 break;
925
926 case IS_NAME:
927 /* get the current string of characters for name */
928 (*dump_opts)->all_types[i].name = (char *)HDmalloc(sizeof(char) * (HDstrlen(ptr)+1));
929 CHECK_ALLOC((*dump_opts)->all_types[i].name, "(*dump_opts)->all_types[i].name", "parse_string_opts" );
930 HDstrcpy((*dump_opts)->all_types[i].name, ptr);
931 break;
932
933 case IS_CLASS:
934 /* get the current string of characters for class name */
935 (*dump_opts)->all_types[i].classname = (char *)HDmalloc(sizeof(char) * (HDstrlen(ptr)+1));
936 CHECK_ALLOC((*dump_opts)->all_types[i].classname, "(*dump_opts)->all_types[i].classname", "parse_string_opts" );
937 HDstrcpy((*dump_opts)->all_types[i].classname, ptr);
938 break;
939
940 default:
941 /* shouldn't be anything else */
942 fprintf(stderr, "Calling function passed in incorrect info_type_t: %%d\n", info_type);
943 exit(1);
944 break;
945 } /* end of switch */
946 (*dump_opts)->all_types[i].type_of_info = info_type;
947 ptr = tempPtr + 1;
948 i++;
949 }
950 (*dump_opts)->num_chosen = numItems; /* save the number of chosen SDSs so far */
951 } /* parse_value_opts */
952
953 /* validate_pos makes sure that number is > 0 so we are not going to
954 allocate 0 elements
955 This routine is replaced by the macro called CHECK_POS just because
956 the error checkings are being done that way! 7/27/00
957 */
958
959 /* if there are any specific datasets requested, alloc_index_list
960 allocates space for the list of indices of these requested items */
961 void
alloc_index_list(int32 ** index_list,int32 num_chosen)962 alloc_index_list(
963 int32 **index_list,
964 int32 num_chosen )
965 {
966 int32 i = -1; /* used to pass into HDmemfill as dummmy? */
967
968 *index_list = (int32 *) HDmalloc(sizeof(int32) * num_chosen);
969 CHECK_ALLOC( *index_list, "index_list", "alloc_index_list" );
970
971 i = (-1);
972 HDmemfill(*index_list, &i, sizeof(int32), num_chosen);
973 } /* end of alloc_index_list */
974
975 /* Given a compression type code, returns a character string that
976 indicates that compression method. */
977 char
comp_method_txt(comp_coder_t comp_type)978 *comp_method_txt(comp_coder_t comp_type)
979 {
980 switch (comp_type)
981 {
982 case COMP_CODE_NONE:
983 return ("NONE");
984 case COMP_CODE_RLE:
985 return ("RLE");
986 case COMP_CODE_NBIT:
987 return ("NBIT");
988 case COMP_CODE_SKPHUFF:
989 return ("SKPHUFF");
990 case COMP_CODE_DEFLATE:
991 return ("DEFLATE");
992 case COMP_CODE_SZIP:
993 return ("SZIP");
994 case COMP_CODE_JPEG:
995 return ("JPEG");
996 case COMP_CODE_IMCOMP:
997 return ("IMCOMP");
998 default:
999 return ("INVALID");
1000 }
1001 }
1002
1003