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