diff options
-rw-r--r-- | release_docs/RELEASE.txt | 2 | ||||
-rw-r--r-- | tools/h5dump/h5dump.c | 766 | ||||
-rw-r--r-- | tools/h5ls/h5ls.c | 6 | ||||
-rw-r--r-- | tools/lib/h5diff_util.c | 2 | ||||
-rw-r--r-- | tools/lib/h5tools.c | 7 | ||||
-rw-r--r-- | tools/lib/h5tools_ref.c | 383 | ||||
-rw-r--r-- | tools/lib/h5tools_ref.h | 20 | ||||
-rw-r--r-- | tools/lib/h5tools_str.c | 6 | ||||
-rw-r--r-- | tools/lib/h5tools_utils.c | 396 | ||||
-rw-r--r-- | tools/lib/h5tools_utils.h | 31 |
10 files changed, 792 insertions, 827 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 20d13de..eac8edb 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -54,6 +54,8 @@ New Features Tools: ------ + - Sped up h5dump on files with large numbers of objects. + QAK - 2005/08/25 F90 API: -------- diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c index 6525832..2c5d73a 100644 --- a/tools/h5dump/h5dump.c +++ b/tools/h5dump/h5dump.c @@ -52,9 +52,11 @@ const char *progname = "h5dump"; int d_status = EXIT_SUCCESS; static int unamedtype = 0; /* shared data type with no name */ -extern size_t prefix_len; static table_t *group_table = NULL, *dset_table = NULL, *type_table = NULL; -extern char *prefix; + +static size_t prefix_len = 1024; +static char *prefix; + static const char *driver = NULL; /* The driver to open the file with. */ static const dump_header *dump_header_format; @@ -84,7 +86,6 @@ static int doxml = 0; static int useschema = 1; static const char *xml_dtd_uri = NULL; static const char *xmlnsprefix="hdf5:"; -hid_t thefile = -1; /** end XML **/ @@ -97,6 +98,7 @@ static herr_t dump_all(hid_t group, const char *name, void *op_data); static void check_compression(hid_t); #endif /* LATER */ static int xml_name_to_XID(const char *, char *, int , int ); +static void init_prefix(char **prfx, size_t prfx_len); static h5dump_t dataformat = { 0, /*raw */ @@ -676,18 +678,23 @@ print_datatype(hid_t type,unsigned in_group) hid_t super; hid_t tmp_type; htri_t is_vlstr=FALSE; - herr_t ret; /* Generic return value */ if (!in_group && H5Tcommitted(type) > 0) { + obj_t *obj; /* Found object */ + H5Gget_objinfo(type, ".", TRUE, &statbuf); - ret = search_obj(type_table, statbuf.objno); + obj = search_obj(type_table, statbuf.objno); + + if (obj) { + if (!obj->recorded) { + unsigned long objno[2]; /*object number */ - if (ret >= 0) { - if (!type_table->objs[ret].recorded) - HDfprintf(stdout,"\"/#%lu:%lu\"", type_table->objs[ret].objno[0], - type_table->objs[ret].objno[1]); + objno[0] = (unsigned long)(obj->objno); + objno[1] = (unsigned long)(obj->objno >> 8*sizeof(long)); + HDfprintf(stdout,"\"/#%lu:%lu\"", objno[0], objno[1]); + } else - printf("\"%s\"", type_table->objs[ret].objname); + printf("\"%s\"", obj->objname); } else { error_msg(progname, "unknown committed type.\n"); d_status = EXIT_FAILURE; @@ -1328,7 +1335,6 @@ dump_all(hid_t group, const char *name, void * op_data) hid_t obj; char *targbuf, *tmp = NULL; H5G_stat_t statbuf; - int i; herr_t ret = SUCCEED; H5Gget_objinfo(group, name, FALSE, &statbuf); @@ -1458,9 +1464,11 @@ dump_all(hid_t group, const char *name, void * op_data) H5Gget_objinfo(obj, ".", TRUE, &statbuf); if (statbuf.nlink > 1) { - i = search_obj(dset_table, statbuf.objno); + obj_t *found_obj; /* Found object */ + + found_obj = search_obj(dset_table, statbuf.objno); - if (i < 0) { + if (found_obj == NULL) { indentation(indent); begin_obj(dump_header_format->datasetbegin, name, dump_header_format->datasetblockbegin); @@ -1475,15 +1483,14 @@ dump_all(hid_t group, const char *name, void * op_data) ret = FAIL; H5Dclose(obj); goto done; - } else if (dset_table->objs[i].displayed) { + } else if (found_obj->displayed) { indentation(indent); if (!doxml) { begin_obj(dump_header_format->datasetbegin, name, dump_header_format->datasetblockbegin); indentation(indent + COL); - printf("%s \"%s\"\n", HARDLINK, - dset_table->objs[i].objname); + printf("%s \"%s\"\n", HARDLINK, found_obj->objname); indentation(indent); end_obj(dump_header_format->datasetend, dump_header_format->datasetblockend); @@ -1512,7 +1519,7 @@ dump_all(hid_t group, const char *name, void * op_data) (strcmp(prefix, "") ? t_prefix : "/")); indentation(indent + COL); - xml_name_to_XID(dset_table->objs[i].objname,pointerxid,100,1); + xml_name_to_XID(found_obj->objname,pointerxid,100,1); printf("<%sDatasetPtr OBJ-XID=\"%s\" H5Path=\"%s\"/>\n", xmlnsprefix, pointerxid,t_tmp); @@ -1531,7 +1538,7 @@ dump_all(hid_t group, const char *name, void * op_data) H5Dclose(obj); goto done; } else { - dset_table->objs[i].displayed = 1; + found_obj->displayed = TRUE; } } @@ -1619,7 +1626,7 @@ dump_group(hid_t gid, const char *name) H5G_stat_t statbuf; hid_t dset, type; char type_name[1024], *tmp; - int i, xtype = H5G_UNKNOWN; /* dump all */ + int xtype = H5G_UNKNOWN; /* dump all */ tmp = malloc(strlen(prefix) + strlen(name) + 2); strcpy(tmp, prefix); @@ -1633,36 +1640,44 @@ dump_group(hid_t gid, const char *name) dump_comment(gid); - if (!strcmp(name, "/") && unamedtype) + if (!strcmp(name, "/") && unamedtype) { + unsigned u; /* Local index variable */ + /* dump unamed type in root group */ - for (i = 0; i < type_table->nobjs; i++) - if (!type_table->objs[i].recorded) { - dset = H5Dopen(gid, type_table->objs[i].objname); + for (u = 0; u < type_table->nobjs; u++) + if (!type_table->objs[u].recorded) { + unsigned long objno[2]; /*object number */ + + dset = H5Dopen(gid, type_table->objs[u].objname); type = H5Dget_type(dset); - sprintf(type_name, "#%lu:%lu", - type_table->objs[i].objno[0], - type_table->objs[i].objno[1]); - dump_named_datatype(type, type_name); + + objno[0] = (unsigned long)(type_table->objs[u].objno); + objno[1] = (unsigned long)(type_table->objs[u].objno >> 8*sizeof(long)); + sprintf(type_name, "#%lu:%lu", objno[0], objno[1]); + dump_function_table->dump_named_datatype_function(type, type_name); + H5Tclose(type); H5Dclose(dset); } + } /* end if */ H5Gget_objinfo(gid, ".", TRUE, &statbuf); if (statbuf.nlink > 1) { - i = search_obj(group_table, statbuf.objno); + obj_t *found_obj; /* Found object */ - if (i < 0) { + found_obj = search_obj(group_table, statbuf.objno); + + if (found_obj == NULL) { indentation(indent); error_msg(progname, "internal error (file %s:line %d)\n", __FILE__, __LINE__); d_status = EXIT_FAILURE; - } else if (group_table->objs[i].displayed) { + } else if (found_obj->displayed) { indentation(indent); - printf("%s \"%s\"\n", HARDLINK, group_table->objs[i].objname); + printf("%s \"%s\"\n", HARDLINK, found_obj->objname); } else { - - group_table->objs[i].displayed = 1; + found_obj->displayed = TRUE; H5Aiterate(gid, NULL, dump_attr, NULL); H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); } @@ -1748,53 +1763,6 @@ dump_dataset(hid_t did, const char *name, struct subset_t *sset) } /*------------------------------------------------------------------------- - * Function: dump_tables - * - * Purpose: display the contents of tables for debugging purposes - * - * Return: void - * - * Programmer: Ruey-Hsia Li - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void -dump_tables(void) -{ -#ifdef H5DUMP_DEBUG - register int i; - - printf("group_table: # of entries = %d\n", group_table->nobjs); - - for (i = 0; i < group_table->nobjs; i++) - HDfprintf(stdout,"%lu %lu %s %d %d\n", group_table->objs[i].objno[0], - group_table->objs[i].objno[1], - group_table->objs[i].objname, - group_table->objs[i].displayed, group_table->objs[i].recorded); - - printf("\ndset_table: # of entries = %d\n", dset_table->nobjs); - - for (i = 0; i < dset_table->nobjs; i++) - HDfprintf(stdout,"%lu %lu %s %d %d\n", dset_table->objs[i].objno[0], - dset_table->objs[i].objno[1], - dset_table->objs[i].objname, - dset_table->objs[i].displayed, dset_table->objs[i].recorded); - - printf("\ntype_table: # of entries = %d\n", type_table->nobjs); - - for (i = 0; i < type_table->nobjs; i++) - HDfprintf(stdout,"%lu %lu %s %d %d\n", type_table->objs[i].objno[0], - type_table->objs[i].objno[1], - type_table->objs[i].objname, - type_table->objs[i].displayed, type_table->objs[i].recorded); -#else - return; -#endif /* H5DUMP_DEBUG */ -} - -/*------------------------------------------------------------------------- * Function: dump_dims * * Purpose: Dump the dimensions handed to it in a comma separated list @@ -2605,35 +2573,27 @@ dump_fcpl(hid_t fid) static void dump_fcontents(hid_t fid) { - hid_t did, tid, gid; - char type_name[1024]; - int i; + printf("%s %s\n",FILE_CONTENTS, BEGIN); - printf("%s %s\n",FILE_CONTENTS, BEGIN); + /* special case of unamed types in root group */ + if (unamedtype) { + unsigned u; - /* special case of unamed types in root group */ - if (unamedtype) - { - gid=H5Gopen(fid,"/"); - for (i = 0; i < type_table->nobjs; i++) - if (!type_table->objs[i].recorded) - { - did = H5Dopen(gid, type_table->objs[i].objname); - tid = H5Dget_type(did); - sprintf(type_name, "/#%lu:%lu", - type_table->objs[i].objno[0], - type_table->objs[i].objno[1]); - H5Tclose(tid); - H5Dclose(did); - printf(" %-10s %s\n", "datatype", type_name ); - } - H5Gclose(gid); - } + for (u = 0; u < type_table->nobjs; u++) { + if (!type_table->objs[u].recorded) { + unsigned long objno[2]; /*object number */ - /* print objects in the files */ - h5trav_getinfo(fid, NULL, 1); + objno[0] = (unsigned long)(type_table->objs[u].objno); + objno[1] = (unsigned long)(type_table->objs[u].objno >> 8*sizeof(long)); + printf(" %-10s /#%lu:%lu\n", "datatype", objno[0], objno[1]); + } + } + } + + /* print objects in the files */ + h5trav_getinfo(fid, NULL, 1); - printf(" %s\n",END); + printf(" %s\n",END); } @@ -2897,20 +2857,21 @@ handle_datasets(hid_t fid, char *dset, void *data) H5Gget_objinfo(dsetid, ".", TRUE, &statbuf); if (statbuf.nlink > 1) { - int idx = search_obj(dset_table, statbuf.objno); + obj_t *found_obj; /* Found object */ + + found_obj = search_obj(dset_table, statbuf.objno); - if (idx >= 0) { - if (dset_table->objs[idx].displayed) { + if (found_obj) { + if (found_obj->displayed) { begin_obj(dump_header_format->datasetbegin, dset, dump_header_format->datasetblockbegin); indentation(indent + COL); - printf("%s \"%s\"\n", HARDLINK, - dset_table->objs[idx].objname); + printf("%s \"%s\"\n", HARDLINK, found_obj->objname); indentation(indent); end_obj(dump_header_format->datasetend, dump_header_format->datasetblockend); } else { - dset_table->objs[idx].displayed = 1; + found_obj->displayed = TRUE; dump_dataset(dsetid, dset, sset); } } else { @@ -3046,21 +3007,20 @@ handle_datatypes(hid_t fid, char *type, void UNUSED * data) if ((type_id = H5Topen(fid, type)) < 0) { /* check if type is unamed data type */ - int idx = 0; + unsigned idx = 0; while (idx < type_table->nobjs ) { - char name[128], name1[128]; + char name[128]; if (!type_table->objs[idx].recorded) { + unsigned long objno[2]; /*object number */ + /* unamed data type */ - sprintf(name, "#%lu:%lu\n", - type_table->objs[idx].objno[0], - type_table->objs[idx].objno[1]); - sprintf(name1, "/#%lu:%lu\n", - type_table->objs[idx].objno[0], - type_table->objs[idx].objno[1]); - - if (!strncmp(name, type, strlen(type)) || !strncmp(name1, type, strlen(type))) + objno[0] = (unsigned long)(type_table->objs[idx].objno); + objno[1] = (unsigned long)(type_table->objs[idx].objno >> 8*sizeof(long)); + sprintf(name, "/#%lu:%lu", objno[0], objno[1]); + + if (!HDstrcmp(name, type)) break; } @@ -3433,6 +3393,7 @@ main(int argc, const char *argv[]) find_objs_t info; struct handler_t *hand; int i; + unsigned u; dump_header_format = &standardformat; dump_function_table = &ddl_function_table; @@ -3490,30 +3451,11 @@ main(int argc, const char *argv[]) } /* allocate and initialize internal data structure */ - init_table(&group_table); - init_table(&type_table); - init_table(&dset_table); init_prefix(&prefix, prefix_len); - /* init the find_objs_t */ - info.threshold = 0; - info.prefix_len = prefix_len; - info.prefix = calloc((size_t)info.prefix_len, 1); - info.group_table = group_table; - info.type_table = type_table; - info.dset_table = dset_table; - info.status = d_status; - - thefile = fid; /* find all objects that might be targets of a refernce */ - if ((gid = H5Gopen(fid, "/")) < 0) { - error_msg(progname, "unable to open root group\n"); - d_status = EXIT_FAILURE; - goto done; - } - ref_path_table_put(gid, "/"); - H5Giterate(fid, "/", NULL, fill_ref_path_table, NULL); - H5Gclose(gid); + init_ref_path_table(fid); /* Insert the root group into the ref. path table */ + H5Giterate(fid, "/", NULL, fill_ref_path_table, (void *)""); if (doxml) { /* initialize XML */ @@ -3538,22 +3480,24 @@ main(int argc, const char *argv[]) } /* find all shared objects */ - H5Giterate(fid, "/", NULL, find_objs, (void *)&info); - - /* does there exist unamed committed data type */ - for (i = 0; i < type_table->nobjs; i++) - if (type_table->objs[i].recorded == 0) - unamedtype = 1; - - dump_tables(); - - if (info.status) { + if(init_objs(fid, &info, &group_table, &dset_table, &type_table) < 0) { error_msg(progname, "internal error (file %s:line %d)\n", __FILE__, __LINE__); d_status = EXIT_FAILURE; goto done; } + /* does there exist unamed committed data type */ + for (u = 0; u < type_table->nobjs; u++) + if (!type_table->objs[u].recorded) { + unamedtype = 1; + break; + } /* end if */ + +#ifdef H5DUMP_DEBUG + dump_tables(&info); +#endif /* H5DUMP_DEBUG */ + /* start to dump - display file header information */ if (!doxml) { begin_obj(dump_header_format->filebegin, fname, @@ -3637,26 +3581,12 @@ done: free_handler(hand, argc); - for(i=0; i<info.group_table->nobjs; i++) { - if(info.group_table->objs[i].objname) - free(info.group_table->objs[i].objname); - } - free(group_table->objs); - - for(i=0; i<info.dset_table->nobjs; i++) { - if(info.dset_table->objs[i].objname) - free(info.dset_table->objs[i].objname); - } - free(dset_table->objs); - - for(i=0; i<info.type_table->nobjs; i++) { - if(info.type_table->objs[i].objname) - free(info.type_table->objs[i].objname); - } - free(type_table->objs); + /* Free tables for objects */ + free_table(group_table); + free_table(dset_table); + free_table(type_table); free(prefix); - free(info.prefix); /* To Do: clean up XML table */ @@ -3787,18 +3717,21 @@ print_enum(hid_t type) int xml_name_to_XID(const char *str , char *outstr, int outlen, int gen) { - ref_path_table_entry_t *r; + haddr_t objno; /* Object ID for object at path */ + unsigned long _objno[2]; /*object number */ if (outlen < 22) return 1; - r = ref_path_table_lookup(str); - if (r == NULL) { - if (strlen(str) == 0) { - r = ref_path_table_lookup("/"); - if (r == NULL) { + objno = ref_path_table_lookup(str); + if (objno == HADDR_UNDEF) { + if (HDstrlen(str) == 0) { + objno = ref_path_table_lookup("/"); + if (objno == HADDR_UNDEF) { if (gen) { - r = ref_path_table_gen_fake(str); - sprintf(outstr,"xid_%lu-%lu",r->statbuf.objno[0],r->statbuf.objno[1]); + objno = ref_path_table_gen_fake(str); + _objno[0] = (unsigned long)(objno); + _objno[1] = (unsigned long)(objno >> 8*sizeof(long)); + sprintf(outstr,"xid_%lu-%lu", _objno[0], _objno[1]); return 0; } else { return 1; @@ -3806,8 +3739,10 @@ xml_name_to_XID(const char *str , char *outstr, int outlen, int gen) } } else { if (gen) { - r = ref_path_table_gen_fake(str); - sprintf(outstr,"xid_%lu-%lu",r->statbuf.objno[0],r->statbuf.objno[1]); + objno = ref_path_table_gen_fake(str); + _objno[0] = (unsigned long)(objno); + _objno[1] = (unsigned long)(objno >> 8*sizeof(long)); + sprintf(outstr,"xid_%lu-%lu", _objno[0], _objno[1]); return 0; } else { return 1; @@ -3815,7 +3750,9 @@ xml_name_to_XID(const char *str , char *outstr, int outlen, int gen) } } - sprintf(outstr,"xid_%lu-%lu",r->statbuf.objno[0],r->statbuf.objno[1]); + _objno[0] = (unsigned long)(objno); + _objno[1] = (unsigned long)(objno >> 8*sizeof(long)); + sprintf(outstr,"xid_%lu-%lu", _objno[0], _objno[1]); return(0); } @@ -4047,27 +3984,28 @@ xml_print_datatype(hid_t type, unsigned in_group) size_t msize; int nmembs; htri_t is_vlstr=FALSE; - herr_t ret; if (!in_group && H5Tcommitted(type) > 0) { + obj_t *found_obj; /* Found object */ + /* detect a shared datatype, output only once */ H5Gget_objinfo(type, ".", TRUE, &statbuf); - ret = search_obj(type_table, statbuf.objno); + found_obj = search_obj(type_table, statbuf.objno); - if (ret >= 0) { + if (found_obj) { /* This should be defined somewhere else */ /* These 2 cases are handled the same right now, but probably will have something different eventually */ char * dtxid = malloc(100); - xml_name_to_XID(type_table->objs[ret].objname,dtxid,100,1); - if (!type_table->objs[ret].recorded) { + xml_name_to_XID(found_obj->objname,dtxid,100,1); + if (!found_obj->recorded) { /* 'anonymous' NDT. Use it's object num. as it's name. */ printf("<%sNamedDataTypePtr OBJ-XID=\"/%s\"/>\n", xmlnsprefix, dtxid); } else { /* point to the NDT by name */ - char *t_objname = xml_escape_the_name(type_table->objs[ret].objname); + char *t_objname = xml_escape_the_name(found_obj->objname); printf("<%sNamedDataTypePtr OBJ-XID=\"%s\" H5Path=\"%s\"/>\n", xmlnsprefix, dtxid,t_objname); free(t_objname); @@ -4409,23 +4347,24 @@ xml_print_datatype(hid_t type, unsigned in_group) static void xml_dump_datatype(hid_t type) { - int i; H5G_stat_t statbuf; indent += COL; indentation(indent); if (H5Tcommitted(type) > 0) { + obj_t *found_obj; /* Found object */ + /* Data type is a shared or named data type */ H5Gget_objinfo(type, ".", TRUE, &statbuf); - i = search_obj(type_table, statbuf.objno); + found_obj = search_obj(type_table, statbuf.objno); - if (i >= 0) { + if (found_obj) { /* Shared data type, must be entered as an object */ /* These 2 cases are the same now, but may change */ char * dtxid = malloc(100); - xml_name_to_XID(type_table->objs[i].objname,dtxid,100,1); - if (!type_table->objs[i].recorded) { + xml_name_to_XID(found_obj->objname,dtxid,100,1); + if (!found_obj->recorded) { /* anonymous stored data type: following the dumper's current practice: @@ -4436,7 +4375,7 @@ xml_dump_datatype(hid_t type) } else { /* pointer to a named data type already in XML */ - char *t_objname = xml_escape_the_name(type_table->objs[i].objname); + char *t_objname = xml_escape_the_name(found_obj->objname); printf("<%sNamedDataTypePtr OBJ-XID=\"%s\" H5Path=\"%s\" />\n", xmlnsprefix, dtxid,t_objname); free(t_objname); @@ -4860,7 +4799,6 @@ xml_dump_group(hid_t gid, const char *name) hid_t dset, type; char type_name[1024], *tmp = NULL; char *par = NULL; - int i; int isRoot = 0; int xtype; char *ptrstr; @@ -4891,110 +4829,115 @@ xml_dump_group(hid_t gid, const char *name) H5Gget_objinfo(gid, ".", TRUE, &statbuf); if (statbuf.nlink > 1) { + obj_t *found_obj; /* Found object */ + /* Group with more than one link to it... */ - i = search_obj(group_table, statbuf.objno); + found_obj = search_obj(group_table, statbuf.objno); - if (i < 0) { + if (found_obj == NULL) { indentation(indent); error_msg(progname, "internal error (file %s:line %d)\n", __FILE__, __LINE__); d_status = EXIT_FAILURE; - } else if (group_table->objs[i].displayed) { - /* already seen: enter a groupptr */ - char *t_name = xml_escape_the_name(name); - char *grpxid = malloc(100); - char *parentxid = malloc(100); - if (isRoot) { - /* probably can't happen! */ - xml_name_to_XID("/",grpxid,100,1); - printf("<%sRootGroup OBJ-XID=\"%s\" H5Path=\"%s\">\n", - xmlnsprefix,grpxid,"/"); - } else { - t_objname = xml_escape_the_name(group_table->objs[i].objname); - par_name = xml_escape_the_name(par); - xml_name_to_XID(tmp,grpxid,100,1); - xml_name_to_XID(par,parentxid,100,1); - printf("<%sGroup Name=\"%s\" OBJ-XID=\"%s-%d\" H5Path=\"%s\" " - "Parents=\"%s\" H5ParentPaths=\"%s\">\n", - xmlnsprefix,t_name, grpxid, get_next_xid(), - t_objname, parentxid, par_name); + } else { + char *t_name = xml_escape_the_name(name); + char *grpxid = malloc(100); + char *parentxid = malloc(100); + + if (found_obj->displayed) { + /* already seen: enter a groupptr */ + if (isRoot) { + /* probably can't happen! */ + xml_name_to_XID("/",grpxid,100,1); + printf("<%sRootGroup OBJ-XID=\"%s\" H5Path=\"%s\">\n", + xmlnsprefix,grpxid,"/"); + } else { + t_objname = xml_escape_the_name(found_obj->objname); + par_name = xml_escape_the_name(par); + xml_name_to_XID(tmp,grpxid,100,1); + xml_name_to_XID(par,parentxid,100,1); + printf("<%sGroup Name=\"%s\" OBJ-XID=\"%s-%d\" H5Path=\"%s\" " + "Parents=\"%s\" H5ParentPaths=\"%s\">\n", + xmlnsprefix,t_name, grpxid, get_next_xid(), + t_objname, parentxid, par_name); + free(t_objname); + free(par_name); + } + + indentation(indent + COL); + ptrstr = malloc(100); + t_objname = xml_escape_the_name(found_obj->objname); + par_name = xml_escape_the_name(par); + xml_name_to_XID(par,parentxid,100,1); + xml_name_to_XID(found_obj->objname,ptrstr,100,1); + printf("<%sGroupPtr OBJ-XID=\"%s\" H5Path=\"%s\" " + "Parents=\"%s\" H5ParentPaths=\"%s\" />\n", + xmlnsprefix, + ptrstr, t_objname, parentxid, par_name); free(t_objname); free(par_name); - } - free(t_name); - free(grpxid); - indentation(indent + COL); - ptrstr = malloc(100); - t_objname = xml_escape_the_name(group_table->objs[i].objname); - par_name = xml_escape_the_name(par); - xml_name_to_XID(par,parentxid,100,1); - xml_name_to_XID(group_table->objs[i].objname,ptrstr,100,1); - printf("<%sGroupPtr OBJ-XID=\"%s\" H5Path=\"%s\" " - "Parents=\"%s\" H5ParentPaths=\"%s\" />\n", - xmlnsprefix, - ptrstr, t_objname, parentxid, par_name); - free(t_objname); - free(parentxid); + } else { - } else { + /* first time this group has been seen -- describe it */ + if (isRoot) { + xml_name_to_XID("/",grpxid,100,1); + printf("<%sRootGroup OBJ-XID=\"%s\" H5Path=\"%s\">\n", + xmlnsprefix,grpxid,"/"); + } else { + char *t_tmp = xml_escape_the_name(tmp); + par_name = xml_escape_the_name(par); + xml_name_to_XID(tmp,grpxid,100,1); + xml_name_to_XID(par,parentxid,100,1); + printf("<%sGroup Name=\"%s\" OBJ-XID=\"%s\" H5Path=\"%s\" " + "Parents=\"%s\" H5ParentPaths=\"%s\" >\n", + xmlnsprefix,t_name, grpxid, t_tmp, parentxid, par_name); + free(t_tmp); + free(par_name); + } + found_obj->displayed = TRUE; - /* first time this group has been seen -- describe it */ - char *t_name = xml_escape_the_name(name); - char *grpxid = malloc(100); - char *parentxid = malloc(100); - if (isRoot) { - xml_name_to_XID("/",grpxid,100,1); - printf("<%sRootGroup OBJ-XID=\"%s\" H5Path=\"%s\">\n", - xmlnsprefix,grpxid,"/"); - } else { - char *t_tmp = xml_escape_the_name(tmp); - par_name = xml_escape_the_name(par); - xml_name_to_XID(tmp,grpxid,100,1); - xml_name_to_XID(par,parentxid,100,1); - printf("<%sGroup Name=\"%s\" OBJ-XID=\"%s\" H5Path=\"%s\" " - "Parents=\"%s\" H5ParentPaths=\"%s\" >\n", - xmlnsprefix,t_name, grpxid, t_tmp, parentxid, par_name); - free(t_tmp); - free(par_name); - } - free(t_name); - free(grpxid); - free(parentxid); - group_table->objs[i].objname = HDstrdup(prefix); - group_table->objs[i].displayed = 1; - - /* 1. do all the attributes of the group */ - H5Aiterate(gid, NULL, - dump_function_table->dump_attribute_function, NULL); - - if (!strcmp(name, "/") && unamedtype) { - /* Very special case: dump unamed type in root group */ - for (i = 0; i < type_table->nobjs; i++) { - if (!type_table->objs[i].recorded) { - dset = H5Dopen(gid, type_table->objs[i].objname); - type = H5Dget_type(dset); - sprintf(type_name, "#%lu:%lu", - type_table->objs[i].objno[0], - type_table->objs[i].objno[1]); - dump_function_table->dump_named_datatype_function(type, type_name); - H5Tclose(type); - H5Dclose(dset); - } - } - } + /* 1. do all the attributes of the group */ + H5Aiterate(gid, NULL, + dump_function_table->dump_attribute_function, NULL); - /* iterate through all the members */ - xtype = H5G_TYPE; - H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); - xtype = H5G_DATASET; - H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); - xtype = H5G_GROUP; - H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); - xtype = H5G_LINK; - H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); + if (!strcmp(name, "/") && unamedtype) { + unsigned u; - } + /* Very special case: dump unamed type in root group */ + for (u = 0; u < type_table->nobjs; u++) { + if (!type_table->objs[u].recorded) { + unsigned long objno[2]; /*object number */ + + dset = H5Dopen(gid, type_table->objs[u].objname); + type = H5Dget_type(dset); + + objno[0] = (unsigned long)(type_table->objs[u].objno); + objno[1] = (unsigned long)(type_table->objs[u].objno >> 8*sizeof(long)); + sprintf(type_name, "#%lu:%lu", objno[0], objno[1]); + dump_function_table->dump_named_datatype_function(type, type_name); + + H5Tclose(type); + H5Dclose(dset); + } + } + } + + /* iterate through all the members */ + xtype = H5G_TYPE; + H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); + xtype = H5G_DATASET; + H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); + xtype = H5G_GROUP; + H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); + xtype = H5G_LINK; + H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); + + } + free(t_name); + free(grpxid); + free(parentxid); + } } else { /* only link -- must be first time! */ @@ -5024,15 +4967,21 @@ xml_dump_group(hid_t gid, const char *name) H5Aiterate(gid, NULL, dump_function_table->dump_attribute_function, NULL); if (!strcmp(name, "/") && unamedtype) { + unsigned u; + /* Very special case: dump unamed type in root group */ - for (i = 0; i < type_table->nobjs; i++) { - if (!type_table->objs[i].recorded) { - dset = H5Dopen(gid, type_table->objs[i].objname); + for (u = 0; u < type_table->nobjs; u++) { + if (!type_table->objs[u].recorded) { + unsigned long objno[2]; /*object number */ + + dset = H5Dopen(gid, type_table->objs[u].objname); type = H5Dget_type(dset); - sprintf(type_name, "#%lu:%lu", - type_table->objs[i].objno[0], - type_table->objs[i].objno[1]); + + objno[0] = (unsigned long)(type_table->objs[u].objno); + objno[1] = (unsigned long)(type_table->objs[u].objno >> 8*sizeof(long)); + sprintf(type_name, "#%lu:%lu", objno[0], objno[1]); dump_function_table->dump_named_datatype_function(type, type_name); + H5Tclose(type); H5Dclose(dset); } @@ -5411,118 +5360,120 @@ check_filters(hid_t dcpl) static void xml_dump_fill_value(hid_t dcpl, hid_t type) { -size_t sz; -size_t i; -hsize_t space; -void * buf; -char * path; -char * name; - indent += COL; - indentation(indent); - printf("<%sData>\n",xmlnsprefix); - indent += COL; + size_t sz; + size_t i; + hsize_t space; + void * buf; + char * name; - space = H5Tget_size(type); - buf = malloc((size_t)space); + indent += COL; + indentation(indent); + printf("<%sData>\n",xmlnsprefix); + indent += COL; - H5Pget_fill_value(dcpl, type, buf); + space = H5Tget_size(type); + buf = malloc((size_t)space); - if (H5Tget_class(type) == H5T_REFERENCE) { - path = lookup_ref_path(*(hobj_ref_t *)buf); + H5Pget_fill_value(dcpl, type, buf); - indentation(indent); - printf("<%sDataFromFile>\n",xmlnsprefix); - if (!path) { - printf("\"%s\"\n", "NULL"); - } else { - char *t_path = xml_escape_the_string(path, -1); + if (H5Tget_class(type) == H5T_REFERENCE) { + const char * path; - printf("\"%s\"\n", t_path); - free(t_path); - } - indentation(indent); - printf("</%sDataFromFile>\n",xmlnsprefix); - } else if (H5Tget_class(type) == H5T_STRING) { - /* ????? */ - indentation(indent); - printf("<!-- String fill values not yet implemented. -->\n"); - indentation(indent); - printf("<%sNoData />\n",xmlnsprefix); - } else { - /* all other data */ - switch (H5Tget_class(type)) { - case H5T_INTEGER: - indentation(indent); - printf("<%sDataFromFile>\n",xmlnsprefix); - indentation(indent); - printf("\"%d\"\n",*(int *)buf); - indentation(indent); - printf("</%sDataFromFile>\n",xmlnsprefix); - break; - case H5T_FLOAT: - indentation(indent); - printf("<%sDataFromFile>\n",xmlnsprefix); - indentation(indent); - printf("\"%f\"\n",*(float *)buf); - indentation(indent); - printf("</%sDataFromFile>\n",xmlnsprefix); - break; - case H5T_BITFIELD: - case H5T_OPAQUE: - indentation(indent); - printf("<%sDataFromFile>\n",xmlnsprefix); - sz = H5Tget_size(type); - indentation(indent); - printf("\""); - for (i = 0; i < sz; i++) { - printf("%x ",*(unsigned int *)buf); - buf = (char *)buf + sizeof(unsigned int); - } - printf("\"\n"); - indentation(indent); - printf("</%sDataFromFile>\n",xmlnsprefix); - break; - case H5T_ENUM: - indentation(indent); - printf("<%sDataFromFile>\n",xmlnsprefix); - name = H5Tget_member_name(type, *(unsigned *)buf); - indentation(indent); - printf("\"%s\"\n",name); - indentation(indent); - printf("</%sDataFromFile>\n",xmlnsprefix); - break; - case H5T_ARRAY: - indentation(indent); - printf("<!-- Array fill values not yet implemented. -->\n"); - indentation(indent); - printf("<%sNoData />\n",xmlnsprefix); - break; - case H5T_TIME: - indentation(indent); - printf("<!-- Time fill not yet implemented. -->\n"); - indentation(indent); - printf("<%sNoData />\n",xmlnsprefix); - break; - case H5T_COMPOUND: - indentation(indent); - printf("<!-- Compound fill not yet implemented. -->\n"); - indentation(indent); - printf("<%sNoData />\n",xmlnsprefix); - break; - case H5T_VLEN: - indentation(indent); - printf("<!-- VL fill not yet implemented. -->\n"); - indentation(indent); - printf("<%sNoData />\n",xmlnsprefix); - break; - default: - indentation(indent); - printf("<!-- Unknown fill datatype: %d -->\n", H5Tget_class(type)); - indentation(indent); - printf("<%sNoData/>\n",xmlnsprefix); - break; - } - } + path = lookup_ref_path(*(hobj_ref_t *)buf); + + indentation(indent); + printf("<%sDataFromFile>\n",xmlnsprefix); + if (!path) { + printf("\"%s\"\n", "NULL"); + } else { + char *t_path = xml_escape_the_string(path, -1); + + printf("\"%s\"\n", t_path); + free(t_path); + } + indentation(indent); + printf("</%sDataFromFile>\n",xmlnsprefix); + } else if (H5Tget_class(type) == H5T_STRING) { + /* ????? */ + indentation(indent); + printf("<!-- String fill values not yet implemented. -->\n"); + indentation(indent); + printf("<%sNoData />\n",xmlnsprefix); + } else { + /* all other data */ + switch (H5Tget_class(type)) { + case H5T_INTEGER: + indentation(indent); + printf("<%sDataFromFile>\n",xmlnsprefix); + indentation(indent); + printf("\"%d\"\n",*(int *)buf); + indentation(indent); + printf("</%sDataFromFile>\n",xmlnsprefix); + break; + case H5T_FLOAT: + indentation(indent); + printf("<%sDataFromFile>\n",xmlnsprefix); + indentation(indent); + printf("\"%f\"\n",*(float *)buf); + indentation(indent); + printf("</%sDataFromFile>\n",xmlnsprefix); + break; + case H5T_BITFIELD: + case H5T_OPAQUE: + indentation(indent); + printf("<%sDataFromFile>\n",xmlnsprefix); + sz = H5Tget_size(type); + indentation(indent); + printf("\""); + for (i = 0; i < sz; i++) { + printf("%x ",*(unsigned int *)buf); + buf = (char *)buf + sizeof(unsigned int); + } + printf("\"\n"); + indentation(indent); + printf("</%sDataFromFile>\n",xmlnsprefix); + break; + case H5T_ENUM: + indentation(indent); + printf("<%sDataFromFile>\n",xmlnsprefix); + name = H5Tget_member_name(type, *(unsigned *)buf); + indentation(indent); + printf("\"%s\"\n",name); + indentation(indent); + printf("</%sDataFromFile>\n",xmlnsprefix); + break; + case H5T_ARRAY: + indentation(indent); + printf("<!-- Array fill values not yet implemented. -->\n"); + indentation(indent); + printf("<%sNoData />\n",xmlnsprefix); + break; + case H5T_TIME: + indentation(indent); + printf("<!-- Time fill not yet implemented. -->\n"); + indentation(indent); + printf("<%sNoData />\n",xmlnsprefix); + break; + case H5T_COMPOUND: + indentation(indent); + printf("<!-- Compound fill not yet implemented. -->\n"); + indentation(indent); + printf("<%sNoData />\n",xmlnsprefix); + break; + case H5T_VLEN: + indentation(indent); + printf("<!-- VL fill not yet implemented. -->\n"); + indentation(indent); + printf("<%sNoData />\n",xmlnsprefix); + break; + default: + indentation(indent); + printf("<!-- Unknown fill datatype: %d -->\n", H5Tget_class(type)); + indentation(indent); + printf("<%sNoData/>\n",xmlnsprefix); + break; + } + } free(buf); indent -= COL; indentation(indent); @@ -6036,3 +5987,22 @@ h5_fileaccess(void) return fapl; } + +/*------------------------------------------------------------------------- + * Function: init_prefix + * + * Purpose: allocate and initialize prefix + * + * Return: void + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +init_prefix(char **prfx, size_t prfx_len) +{ + assert(prfx_len > 0); + *prfx = HDcalloc(prfx_len, 1); +} + diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c index 3d08921..f022689 100644 --- a/tools/h5ls/h5ls.c +++ b/tools/h5ls/h5ls.c @@ -78,7 +78,6 @@ static herr_t list (hid_t group, const char *name, void *cd); static void display_type(hid_t type, int ind); static char *fix_name(const char *path, const char *base); -hid_t thefile; const char *progname="h5ls"; int d_status; @@ -1813,10 +1812,11 @@ list (hid_t group, const char *name, void *_iter) /* Show detailed information about the object, beginning with information * which is common to all objects. */ if (verbose_g>0 && H5G_LINK!=sb.type) { - if (sb.type>=0) H5Aiterate(obj, NULL, list_attr, NULL); + if (sb.type>=0) + H5Aiterate(obj, NULL, list_attr, NULL); printf(" %-10s %lu:%lu:%lu:%lu\n", "Location:", sb.fileno[1], sb.fileno[0], sb.objno[1], sb.objno[0]); - printf(" %-10s %u\n", "Links:", sb.nlink); + printf(" %-10s %u\n", "Links:", sb.nlink); if (sb.mtime>0) { if (simple_output_g) tm=gmtime(&(sb.mtime)); else tm=localtime(&(sb.mtime)); diff --git a/tools/lib/h5diff_util.c b/tools/lib/h5diff_util.c index a023a02..3fff991 100644 --- a/tools/lib/h5diff_util.c +++ b/tools/lib/h5diff_util.c @@ -222,7 +222,7 @@ diff_basename(const char *name) size_t i; if (name==NULL) - return; + return(NULL); /* Find the end of the base name */ i = strlen(name); diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index 45fb639..8fc8eab 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -24,9 +24,9 @@ #include <stdlib.h> #include "h5tools.h" +#include "h5tools_ref.h" #include "h5tools_str.h" #include "h5tools_utils.h" -#include "hdf5.h" #include "H5private.h" /* @@ -139,6 +139,9 @@ h5tools_close(void) rawdatastream = NULL; } + /* Clean up the reference path table, if it's been used */ + term_ref_path_table(); + /* Shut down the library */ H5close(); @@ -445,7 +448,7 @@ h5tools_simple_prefix(FILE *stream, const h5dump_t *info, /* Calculate new prefix */ h5tools_str_prefix(&prefix, info, elmtno, ctx->ndims, ctx->p_min_idx, - ctx->p_max_idx,ctx); + ctx->p_max_idx, ctx); /* Write new prefix to output */ if (ctx->indent_level >= 0) { diff --git a/tools/lib/h5tools_ref.c b/tools/lib/h5tools_ref.c index 3480181..e1c3d1b 100644 --- a/tools/lib/h5tools_ref.c +++ b/tools/lib/h5tools_ref.c @@ -16,6 +16,7 @@ #include <stdlib.h> #include "h5tools_ref.h" #include "H5private.h" +#include "H5SLprivate.h" #include "h5tools.h" #include "h5tools_utils.h" @@ -34,15 +35,109 @@ * method of selecting which one. */ +typedef struct { + haddr_t objno; /* Object ID (i.e. address) */ + const char *path; /* Object path */ +} ref_path_node_t; + +static H5SL_t *ref_path_table = NULL; /* the "table" (implemented with a skip list) */ +static hid_t thefile; -extern hid_t thefile; -size_t prefix_len = 1024; -char *prefix; extern char *progname; extern int d_status; +static int ref_path_table_put(const char *, haddr_t objno); +static hbool_t ref_path_table_find(haddr_t objno); + +/*------------------------------------------------------------------------- + * Function: init_ref_path_table + * + * Purpose: Enter the root group ("/") into the path table + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +init_ref_path_table(hid_t fid) +{ + H5G_stat_t sb; + haddr_t objno; + char *root_path; + + /* Set file ID for later queries (XXX: this should be fixed) */ + thefile = fid; + + /* Create skip list to store reference path information */ + if((ref_path_table = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)16))==NULL) + return (-1); + + if((root_path = HDstrdup("/")) == NULL) + return (-1); + + if(H5Gget_objinfo(fid, "/", TRUE, &sb)<0) { + /* fatal error? */ + HDfree(root_path); + return (-1); + } + + /* Insert into table (takes ownership of path) */ + objno = ((haddr_t)sb.objno[1] << (8*sizeof(long))) | (haddr_t)sb.objno[0]; + ref_path_table_put(root_path, objno); + + return(0); +} + +/*------------------------------------------------------------------------- + * Function: free_ref_path_info + * + * Purpose: Free the key for a reference path table node + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +free_ref_path_info(void *item, void UNUSED *key, void UNUSED *operator_data/*in,out*/) +{ + ref_path_node_t *node = (ref_path_node_t *)item; + + HDfree(node->path); + HDfree(node); -ref_path_table_entry_t *ref_path_table = NULL; /* the table */ + return(0); +} + +/*------------------------------------------------------------------------- + * Function: term_ref_path_table + * + * Purpose: Terminate the reference path table + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +term_ref_path_table(void) +{ + /* Destroy reference path table, freeing all memory */ + if(ref_path_table) + H5SL_destroy(ref_path_table, free_ref_path_info, NULL); + + return(0); +} /*------------------------------------------------------------------------- * Function: ref_path_table_lookup @@ -59,37 +154,62 @@ ref_path_table_entry_t *ref_path_table = NULL; /* the table */ * *------------------------------------------------------------------------- */ -ref_path_table_entry_t * +haddr_t ref_path_table_lookup(const char *thepath) { - hobj_ref_t ref; - ref_path_table_entry_t *pte = ref_path_table; - - if (ref_path_table == NULL) - return NULL; + H5G_stat_t sb; + haddr_t objno; + haddr_t ret_value; - if ( H5Rcreate(&ref, thefile, thepath, H5R_OBJECT, -1) < 0) + /* Get object ID for object at path */ + if(H5Gget_objinfo(thefile, thepath, TRUE, &sb)<0) /* fatal error ? */ - return NULL; + return HADDR_UNDEF; - while(pte!=NULL) { - if(ref==pte->obj_ref) - return pte; - pte = pte->next; - } + /* Return OID or HADDR_UNDEF */ + objno = ((haddr_t)sb.objno[1] << (8*sizeof(long))) | (haddr_t)sb.objno[0]; + ret_value = ref_path_table_find(objno) ? objno : HADDR_UNDEF; - return NULL; + return(ret_value); +} + +/*------------------------------------------------------------------------- + * Function: ref_path_table_find + * + * Purpose: Looks up a table entry given a object number. + * Used during construction of the table. + * + * Return: TRUE/FALSE on success, can't fail + * + * Programmer: Quincey Koziol + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +ref_path_table_find(haddr_t objno) +{ + HDassert(ref_path_table); + + if(H5SL_search(ref_path_table, &objno) == NULL) + return FALSE; + else + return TRUE; } /*------------------------------------------------------------------------- * Function: ref_path_table_put * - * Purpose: Enter the 'obj' with 'path' in the table if - * not already there. + * Purpose: Enter the 'obj' with 'path' in the table (assumes its not + * already there) + * * Create an object reference, pte, and store them * in the table. * - * Return: The object reference for the object. + * NOTE: Takes ownership of the path name string passed in! + * + * Return: Non-negative on success, negative on failure * * Programmer: REMcG * @@ -97,43 +217,21 @@ ref_path_table_lookup(const char *thepath) * *------------------------------------------------------------------------- */ -ref_path_table_entry_t * -ref_path_table_put(hid_t obj, const char *path) +static int +ref_path_table_put(const char *path, haddr_t objno) { - ref_path_table_entry_t *pte; - - /* look up 'obj'. If already in table, return */ - pte = ref_path_table_lookup(path); - if (pte != NULL) - return pte; - - /* if not found, then make new entry */ + ref_path_node_t *new_node; - pte = (ref_path_table_entry_t *) malloc(sizeof(ref_path_table_entry_t)); - if (pte == NULL) - /* fatal error? */ - return NULL; - - pte->obj = obj; + HDassert(ref_path_table); + HDassert(path); - if ( H5Rcreate(&pte->obj_ref, thefile, path, H5R_OBJECT, -1) < 0) { - /* fatal error? */ - free(pte); - return NULL; - } + if((new_node = HDmalloc(sizeof(ref_path_node_t))) == NULL) + return(-1); - pte->apath = HDstrdup(path); + new_node->objno = objno; + new_node->path = path; - if(H5Gget_objinfo(thefile, path, TRUE, &pte->statbuf)<0) { - /* fatal error? */ - free(pte); - return NULL; - } - - pte->next = ref_path_table; - ref_path_table = pte; - - return pte; + return(H5SL_insert(ref_path_table, new_node, &(new_node->objno))); } /* @@ -142,7 +240,7 @@ ref_path_table_put(hid_t obj, const char *path) int xid = 1; int get_next_xid() { - return xid++; + return xid++; } /* @@ -154,55 +252,33 @@ int get_next_xid() { haddr_t fake_xid = HADDR_MAX; haddr_t get_fake_xid () { - return (fake_xid--); + return (fake_xid--); } /* * for an object that does not have an object id (e.g., soft link), * create a table entry with a fake object id as the key. + * + * Assumes 'path' is for an object that is not in the table. + * */ -ref_path_table_entry_t * +haddr_t ref_path_table_gen_fake(const char *path) { - union { - hobj_ref_t rr; - char cc[16]; - unsigned long ll[2]; - } uu; - H5G_stat_t sb; - ref_path_table_entry_t *pte; - - /* look up 'obj'. If already in table, return */ - pte = ref_path_table_lookup(path); - if (pte != NULL) - return pte; - - /* if not found, then make new entry */ - - pte = (ref_path_table_entry_t *) malloc(sizeof(ref_path_table_entry_t)); - if (pte == NULL) - /* fatal error? */ - return NULL; - - pte->obj = (hid_t)-1; - - sb.objno[0] = (unsigned long)get_fake_xid(); - sb.objno[1] = (unsigned long)get_fake_xid(); + const char *dup_path; + haddr_t fake_objno; - memcpy(&pte->statbuf,&sb,sizeof(H5G_stat_t)); + if((dup_path = HDstrdup(path)) == NULL) + return HADDR_UNDEF; - uu.ll[0] = sb.objno[0]; - uu.ll[1] = sb.objno[1]; + /* Generate fake ID for string */ + fake_objno = get_fake_xid(); - memcpy(&pte->obj_ref,(char *)&uu.rr,sizeof(pte->obj_ref)); + /* Insert "fake" object into table (takes ownership of path) */ + ref_path_table_put(dup_path, fake_objno); - pte->apath = HDstrdup(path); - - pte->next = ref_path_table; - ref_path_table = pte; - - return pte; + return(fake_objno); } /*------------------------------------------------------------------------- @@ -218,17 +294,18 @@ ref_path_table_gen_fake(const char *path) * *------------------------------------------------------------------------- */ -char * -lookup_ref_path(hobj_ref_t ref) +const char * +lookup_ref_path(haddr_t ref) { - ref_path_table_entry_t *pte = ref_path_table; + ref_path_node_t *node; - while(pte!=NULL) { - if (ref==pte->obj_ref) - return pte->apath; - pte = pte->next; - } - return NULL; + /* Be safer for h5ls */ + if(!ref_path_table) + return(NULL); + + node = H5SL_search(ref_path_table, &ref); + + return(node ? node->path : NULL); } /*------------------------------------------------------------------------- @@ -246,84 +323,46 @@ lookup_ref_path(hobj_ref_t ref) *------------------------------------------------------------------------- */ herr_t -fill_ref_path_table(hid_t group, const char *name, void UNUSED * op_data) +fill_ref_path_table(hid_t group, const char *obj_name, void *op_data) { - hid_t obj; - char *tmp; - size_t tmp_len; + const char *obj_prefix = (const char *)op_data; H5G_stat_t statbuf; - ref_path_table_entry_t *pte; - char *thepath; - - H5Gget_objinfo(group, name, FALSE, &statbuf); - tmp_len = strlen(prefix) + strlen(name) + 2; - tmp = (char *) malloc(tmp_len); - - if (tmp == NULL) - return FAIL; - - thepath = (char *) malloc(tmp_len); - - if (thepath == NULL) { - free(tmp); - return FAIL; - } - - strcpy(tmp, prefix); - - strcpy(thepath, prefix); - strcat(thepath, "/"); - strcat(thepath, name); - - switch (statbuf.type) { - case H5G_DATASET: - if ((obj = H5Dopen(group, name)) >= 0) { - pte = ref_path_table_lookup(thepath); - if (pte == NULL) - ref_path_table_put(obj, thepath); - H5Dclose(obj); - } else { - error_msg(progname, "unable to get dataset \"%s\"\n", name); - d_status = EXIT_FAILURE; - } - break; - case H5G_GROUP: - if ((obj = H5Gopen(group, name)) >= 0) { - if (prefix_len <= tmp_len) { - prefix_len = tmp_len + 1; - prefix = realloc(prefix, prefix_len); + haddr_t objno; + + H5Gget_objinfo(group, obj_name, FALSE, &statbuf); + objno = ((haddr_t)statbuf.objno[1] << (8*sizeof(long))) | (haddr_t)statbuf.objno[0]; + + /* Check if the object is in the path table */ + if (!ref_path_table_find(objno)) { + size_t tmp_len; + char *thepath; + + /* Compute length for this object's path */ + tmp_len = HDstrlen(obj_prefix) + HDstrlen(obj_name) + 2; + + /* Allocate room for the path for this object */ + if ((thepath = (char *) HDmalloc(tmp_len)) == NULL) + return FAIL; + + /* Build the name for this object */ + HDstrcpy(thepath, obj_prefix); + HDstrcat(thepath, "/"); + HDstrcat(thepath, obj_name); + + /* Insert the object into the path table */ + ref_path_table_put(thepath, objno); + + if(statbuf.type == H5G_GROUP) { + /* Iterate over objects in this group, using this group's + * name as their prefix + */ + if(H5Giterate(group, obj_name, NULL, fill_ref_path_table, thepath) < 0) { + error_msg(progname, "unable to dump group \"%s\"\n", obj_name); + d_status = EXIT_FAILURE; } - - strcat(strcat(prefix, "/"), name); - pte = ref_path_table_lookup(thepath); - if (pte == NULL) { - ref_path_table_put(obj, thepath); - H5Giterate(obj, ".", NULL, fill_ref_path_table, NULL); - strcpy(prefix, tmp); - } - H5Gclose(obj); - } else { - error_msg(progname, "unable to dump group \"%s\"\n", name); - d_status = EXIT_FAILURE; - } - break; - case H5G_TYPE: - if ((obj = H5Topen(group, name)) >= 0) { - pte = ref_path_table_lookup(thepath); - if (pte == NULL) - ref_path_table_put(obj, thepath); - H5Tclose(obj); - } else { - error_msg(progname, "unable to get dataset \"%s\"\n", name); - d_status = EXIT_FAILURE; - } - break; - default: - break; + } } - free(tmp); - free(thepath); return 0; } diff --git a/tools/lib/h5tools_ref.h b/tools/lib/h5tools_ref.h index 35c1ce3..abe2034 100644 --- a/tools/lib/h5tools_ref.h +++ b/tools/lib/h5tools_ref.h @@ -17,32 +17,22 @@ #include "hdf5.h" -typedef struct ref_path_table_entry_t { - hid_t obj; - hobj_ref_t obj_ref; - char *apath; - H5G_stat_t statbuf; - struct ref_path_table_entry_t *next; -}ref_path_table_entry_t; - #ifdef __cplusplus extern "C" { #endif -char* lookup_ref_path(hobj_ref_t ref); +int init_ref_path_table(hid_t fid); +const char *lookup_ref_path(haddr_t ref); herr_t fill_ref_path_table(hid_t, const char *, void *); int get_next_xid(void); haddr_t get_fake_xid (void); -struct ref_path_table_entry_t *ref_path_table_lookup(const char *); -ref_path_table_entry_t *ref_path_table_put(hid_t obj, const char *path); -struct ref_path_table_entry_t *ref_path_table_gen_fake(const char *); +haddr_t ref_path_table_lookup(const char *); +haddr_t ref_path_table_gen_fake(const char *); +int term_ref_path_table(void); #ifdef __cplusplus } #endif - - #endif - diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index f5ea1f4..26d2fdc 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -25,8 +25,8 @@ #include "H5private.h" #include "h5tools.h" /*for h5dump_t structure */ -#include "h5tools_str.h" /*function prototypes */ #include "h5tools_ref.h" +#include "h5tools_str.h" /*function prototypes */ /* * If REPEAT_VERBOSE is defined then character strings will be printed so @@ -856,7 +856,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5dump_t *info, hid_t container, if (h5tools_is_zero(vp, H5Tget_size(type))) { h5tools_str_append(str, "NULL"); } else { - char *path=NULL; + const char *path; otype = H5Rget_obj_type(container, H5R_OBJECT, vp); obj = H5Rdereference(container, H5R_OBJECT, vp); H5Gget_objinfo(obj, ".", FALSE, &sb); @@ -888,7 +888,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5dump_t *info, hid_t container, sb.fileno[1], sb.fileno[0], sb.objno[1], sb.objno[0]); /* Print name */ - path = lookup_ref_path(*(hobj_ref_t *)vp); + path = lookup_ref_path(*(haddr_t *)vp); if (path) { h5tools_str_append(str, " "); h5tools_str_append(str, path); diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c index 8029805..90be357 100644 --- a/tools/lib/h5tools_utils.c +++ b/tools/lib/h5tools_utils.c @@ -39,7 +39,13 @@ int opt_ind = 1; /*token pointer */ const char *opt_arg; /*flag argument (or value) */ /* local functions */ -static void add_obj(table_t *table, unsigned long *objno, char *objname); +static void init_table(table_t **tbl); +#ifdef H5DUMP_DEBUG +static void dump_table(char* tablename, table_t *table); +#endif /* H5DUMP_DEBUG */ +static void add_obj(table_t *table, unsigned long *objno, char *objname, hbool_t recorded); +static char * build_obj_path_name(const char *prefix, const char *name); +static herr_t find_objs_cb(hid_t group, const char *name, void *op_data); /*------------------------------------------------------------------------- @@ -309,66 +315,95 @@ print_version(const char *progname) * *------------------------------------------------------------------------- */ -void +static void init_table(table_t **tbl) { - int i; table_t *table = HDmalloc(sizeof(table_t)); table->size = 20; table->nobjs = 0; table->objs = HDmalloc(table->size * sizeof(obj_t)); - for (i = 0; i < table->size; i++) { - table->objs[i].objno[0] = table->objs[i].objno[1] = 0; - table->objs[i].displayed = 0; - table->objs[i].recorded = 0; - table->objs[i].objflag = 0; - table->objs[i].objname = NULL; - } - *tbl = table; } /*------------------------------------------------------------------------- - * Function: init_prefix + * Function: free_table * - * Purpose: allocate and initialize prefix + * Purpose: free tables for shared groups, datasets, + * and committed types * * Return: void * + * Programmer: Paul Harten + * * Modifications: * *------------------------------------------------------------------------- */ void -init_prefix(char **prefix, size_t prefix_len) +free_table(table_t *table) { - assert(prefix_len > 0); - *prefix = HDcalloc(prefix_len, 1); + unsigned u; /* Local index value */ + + /* Free the names for the objects in the table */ + for(u = 0; u < table->nobjs; u++) + if(table->objs[u].objname) + HDfree(table->objs[u].objname); + + HDfree(table->objs); } +#ifdef H5DUMP_DEBUG /*------------------------------------------------------------------------- - * Function: free_table + * Function: dump_table * - * Purpose: free tables for shared groups, datasets, - * and committed types + * Purpose: display the contents of tables for debugging purposes * * Return: void * - * Programmer: Paul Harten + * Programmer: Ruey-Hsia Li + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +dump_table(char* tablename, table_t *table) +{ + unsigned u; + + printf("%s: # of entries = %d\n", tablename,table->nobjs); + for (u = 0; u < table->nobjs; u++) + HDfprintf(stdout,"%a %s %d %d\n", table->objs[u].objno, + table->objs[u].objname, + table->objs[u].displayed, table->objs[u].recorded); +} + + +/*------------------------------------------------------------------------- + * Function: dump_tables + * + * Purpose: display the contents of tables for debugging purposes + * + * Return: void + * + * Programmer: Ruey-Hsia Li * * Modifications: * *------------------------------------------------------------------------- */ void -free_table(table_t **table) +dump_tables(find_objs_t *info) { - HDfree((*table)->objs); + dump_table("group_table", info->group_table); + dump_table("dset_table", info->dset_table); + dump_table("type_table", info->type_table); } +#endif /* H5DUMP_DEBUG */ /*------------------------------------------------------------------------- @@ -386,23 +421,53 @@ free_table(table_t **table) * *------------------------------------------------------------------------- */ -int -search_obj(table_t *table, unsigned long *objno) +obj_t * +search_obj(table_t *table, unsigned long *_objno) { - int i; + haddr_t objno = ((haddr_t)_objno[1] << (8*sizeof(long))) | (haddr_t)_objno[0]; + unsigned u; - for (i = 0; i < table->nobjs; i++) - if (table->objs[i].objno[0] == *objno && table->objs[i].objno[1] == *(objno + 1)) - return i; + for (u = 0; u < table->nobjs; u++) + if (table->objs[u].objno == objno) + return &(table->objs[u]); - return FAIL; + return NULL; } /*------------------------------------------------------------------------- - * Function: find_objs + * Function: build_obj_path_name * - * Purpose: Find objects, committed types and store them in tables + * Purpose: Allocate space & build path name from prefix & name + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static char * +build_obj_path_name(const char *prefix, const char *name) +{ + char *path; + + path = HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2); + HDstrcpy(path, prefix); + HDstrcat(path,"/"); + HDstrcat(path,name); /* absolute name of the data set */ + + return(path); +} /* end build_obj_path_name() */ + + +/*------------------------------------------------------------------------- + * Function: find_objs_cb + * + * Purpose: Callback to find objects, committed types and store them in tables * * Return: Success: SUCCEED * @@ -414,218 +479,124 @@ search_obj(table_t *table, unsigned long *objno) * *------------------------------------------------------------------------- */ -herr_t -find_objs(hid_t group, const char *name, void *op_data) +static herr_t +find_objs_cb(hid_t group, const char *name, void *op_data) { - hid_t obj, type; H5G_stat_t statbuf; - char *tmp; find_objs_t *info = (find_objs_t*)op_data; - int i; - - if (info->threshold > 1) - /*will get an infinite loop if greater than 1*/ - return FAIL; + herr_t ret_value = 0; H5Gget_objinfo(group, name, TRUE, &statbuf); - tmp = HDmalloc(HDstrlen(info->prefix) + HDstrlen(name) + 2); - HDstrcpy(tmp, info->prefix); - switch (statbuf.type) { + char *tmp; + case H5G_GROUP: - if ((obj = H5Gopen(group, name)) >= 0) { - while (info->prefix_len < (HDstrlen(info->prefix) + HDstrlen(name) + 2)) { - info->prefix_len *= 2; - info->prefix = HDrealloc(info->prefix, - info->prefix_len * sizeof(char)); - } + if (search_obj(info->group_table, statbuf.objno) == NULL) { + char *old_prefix; - HDstrcat(HDstrcat(info->prefix,"/"), name); + tmp = build_obj_path_name(info->prefix, name); + add_obj(info->group_table, statbuf.objno, tmp, TRUE); - if (statbuf.nlink > info->threshold) { - if (search_obj(info->group_table, statbuf.objno) == FAIL) { - add_obj(info->group_table, statbuf.objno, info->prefix); - H5Giterate(obj, ".", NULL, find_objs, (void *)info); - } - } else { - H5Giterate (obj, ".", NULL, find_objs, (void *)info); - } + old_prefix = info->prefix; + info->prefix = tmp; - HDstrcpy(info->prefix, tmp); - H5Gclose (obj); - } else { - info->status = 1; - } + if(H5Giterate(group, name, NULL, find_objs_cb, (void *)info) < 0) + ret_value = FAIL; + info->prefix = old_prefix; + } /* end if */ break; case H5G_DATASET: - HDstrcat(tmp,"/"); - HDstrcat(tmp,name); /* absolute name of the data set */ + if (search_obj(info->dset_table, statbuf.objno) == NULL) { + hid_t dset; - if (statbuf.nlink > info->threshold && - search_obj(info->dset_table, statbuf.objno) == FAIL) - add_obj(info->dset_table, statbuf.objno, tmp); + tmp = build_obj_path_name(info->prefix, name); + add_obj(info->dset_table, statbuf.objno, tmp, TRUE); - if ((obj = H5Dopen (group, name)) >= 0) { - type = H5Dget_type(obj); + if ((dset = H5Dopen (group, name)) >= 0) { + hid_t type; - if (H5Tcommitted(type) > 0) { - H5Gget_objinfo(type, ".", TRUE, &statbuf); + type = H5Dget_type(dset); - if (search_obj(info->type_table, statbuf.objno) == FAIL) { - add_obj(info->type_table, statbuf.objno, tmp); - info->type_table->objs[info->type_table->nobjs - 1].objflag = 0; - } - } + if (H5Tcommitted(type) > 0) { + H5Gget_objinfo(type, ".", TRUE, &statbuf); - H5Tclose(type); - H5Dclose (obj); - } else { - info->status = 1; - } + if (search_obj(info->type_table, statbuf.objno) == NULL) { + char *type_name = HDstrdup(tmp); + add_obj(info->type_table, statbuf.objno, type_name, FALSE); + } /* end if */ + } + + H5Tclose(type); + H5Dclose(dset); + } else { + ret_value = FAIL; + } + } /* end if */ break; case H5G_TYPE: - HDstrcat(tmp,"/"); - HDstrcat(tmp,name); /* absolute name of the type */ - i = search_obj(info->type_table, statbuf.objno); - - if (i == FAIL) { - add_obj(info->type_table, statbuf.objno, tmp) ; - - /* named data type */ - info->type_table->objs[info->type_table->nobjs-1].recorded = 1; - - /* named data type */ - info->type_table->objs[info->type_table->nobjs-1].objflag = 1; - } else { - free(info->type_table->objs[i].objname); - info->type_table->objs[i].objname = HDstrdup(tmp); - info->type_table->objs[i].recorded = 1; - - /* named data type */ - info->type_table->objs[info->type_table->nobjs-1].objflag = 1; - } - + { + obj_t *found_obj; + + tmp = build_obj_path_name(info->prefix, name); + if ((found_obj = search_obj(info->type_table, statbuf.objno)) == NULL) + add_obj(info->type_table, statbuf.objno, tmp, TRUE); + else { + /* Use latest version of name */ + HDfree(found_obj->objname); + found_obj->objname = HDstrdup(tmp); + + /* Mark named datatype as having valid name */ + found_obj->recorded = TRUE; + } /* end else */ break; + } default: + /* Ignore links, etc. */ break; } - HDfree(tmp); - return SUCCEED; -} - - -/*------------------------------------------------------------------------- - * Function: dump_table - * - * Purpose: display the contents of tables for debugging purposes - * - * Return: void - * - * Programmer: Ruey-Hsia Li - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -void -dump_table(char* tablename, table_t *table) -{ - int i; - - printf("%s: # of entries = %d\n", tablename,table->nobjs); - - for (i = 0; i < table->nobjs; i++) - printf("\t%lu %lu %s %d\n", - table->objs[i].objno[0], - table->objs[i].objno[1], - table->objs[i].objname, - table->objs[i].objflag); -} - - -/*------------------------------------------------------------------------- - * Function: get_table_idx - * - * Purpose: Determine if objects are in a link loop - * - * Return: Success: table index of object detected to be in loop - * - * Failure: FAIL - * - * Programmer: Paul Harten - * - *------------------------------------------------------------------------- - */ -int -get_table_idx(table_t *table, unsigned long *objno) -{ - return search_obj(table, objno); -} - - -/*------------------------------------------------------------------------- - * Function: get_tableflag - * - * Purpose: Return the i'th element's flag setting - * - * Return: Boolean setting of the i'th element of the object table flag - * - * Programmer: Paul Harten - * - *------------------------------------------------------------------------- - */ -int -get_tableflag(table_t *table, int idx) -{ - return table->objs[idx].objflag; + return ret_value; } /*------------------------------------------------------------------------- - * Function: set_tableflag + * Function: init_objs * - * Purpose: Set the i'th element of the object table's flag to TRUE + * Purpose: Initialize tables for groups, datasets & named datatypes * * Return: Success: SUCCEED * - * Failure: N/A - * - * Programmer: Paul Harten - * - *------------------------------------------------------------------------- - */ -int -set_tableflag(table_t *table, int idx) -{ - table->objs[idx].objflag = TRUE; - return SUCCEED; -} - - -/*------------------------------------------------------------------------- - * Function: get_objectname - * - * Purpose: Get name of i'th object in table - * - * Return: Success: strdup() of object name character string + * Failure: FAIL * - * Failure: NULL and sets errno to ENOMEM + * Programmer: Ruey-Hsia Li * - * Programmer: Paul Harten + * Modifications: * *------------------------------------------------------------------------- */ -char * -get_objectname(table_t *table, int idx) +herr_t +init_objs(hid_t fid, find_objs_t *info, table_t **group_table, + table_t **dset_table, table_t **type_table) { - return HDstrdup(table->objs[idx].objname); + /* Initialize the tables */ + init_table(group_table); + init_table(dset_table); + init_table(type_table); + + /* Init the find_objs_t */ + info->prefix = ""; + info->group_table = *group_table; + info->type_table = *type_table; + info->dset_table = *dset_table; + + /* Find all shared objects */ + return(H5Giterate(fid, "/", NULL, find_objs_cb, (void *)info)); } @@ -644,26 +615,23 @@ get_objectname(table_t *table, int idx) *------------------------------------------------------------------------- */ static void -add_obj(table_t *table, unsigned long *objno, char *objname) +add_obj(table_t *table, unsigned long *_objno, char *objname, hbool_t record) { - int i; + haddr_t objno = ((haddr_t)_objno[1] << (8*sizeof(long))) | (haddr_t)_objno[0]; + unsigned u; + /* See if we need to make table larger */ if (table->nobjs == table->size) { table->size *= 2; table->objs = HDrealloc(table->objs, table->size * sizeof(obj_t)); - - for (i = table->nobjs; i < table->size; i++) { - table->objs[i].objno[0] = table->objs[i].objno[1] = 0; - table->objs[i].displayed = 0; - table->objs[i].recorded = 0; - table->objs[i].objflag = 0; - table->objs[i].objname = NULL; - } } - i = table->nobjs++; - table->objs[i].objno[0] = objno[0]; - table->objs[i].objno[1] = objno[1]; - free(table->objs[i].objname); - table->objs[i].objname = HDstrdup(objname); + /* Increment number of objects in table */ + u = table->nobjs++; + + /* Set information about object */ + table->objs[u].objno = objno; + table->objs[u].objname = objname; + table->objs[u].recorded = record; + table->objs[u].displayed = 0; } diff --git a/tools/lib/h5tools_utils.h b/tools/lib/h5tools_utils.h index cd97eab..73260bd 100644 --- a/tools/lib/h5tools_utils.h +++ b/tools/lib/h5tools_utils.h @@ -79,29 +79,25 @@ extern int get_option(int argc, const char **argv, const char *opt, /*struct taken from the dumper. needed in table struct*/ typedef struct obj_t { - unsigned long objno[2]; + haddr_t objno; char *objname; - int displayed; - int recorded; - int objflag; + hbool_t displayed; /* Flag to indicate that the object has been displayed */ + hbool_t recorded; /* Flag for named datatypes to indicate they were found in the group hierarchy */ } obj_t; /*struct for the tables that the find_objs function uses*/ typedef struct table_t { - int size; - int nobjs; + size_t size; + size_t nobjs; obj_t *objs; } table_t; /*this struct stores the information that is passed to the find_objs function*/ typedef struct find_objs_t { - size_t prefix_len; char *prefix; - unsigned int threshold; /* should be 0 or 1 */ table_t *group_table; table_t *type_table; table_t *dset_table; - int status; } find_objs_t; extern int nCols; /*max number of columns for outputting */ @@ -111,15 +107,12 @@ extern void indentation(int); extern void print_version(const char *progname); extern void error_msg(const char *progname, const char *fmt, ...); extern void warn_msg(const char *progname, const char *fmt, ...); -extern void free_table(table_t **table); -extern void dump_table(char *name, table_t *table); -extern int get_table_idx(table_t *table, unsigned long *); -extern int get_tableflag(table_t*, int); -extern int set_tableflag(table_t*, int); -extern char *get_objectname(table_t*, int); -extern herr_t find_objs(hid_t group, const char *name, void *op_data); -extern int search_obj(table_t *temp, unsigned long *); -extern void init_table(table_t **tbl); -extern void init_prefix(char **temp, size_t); +extern void free_table(table_t *table); +#ifdef H5DUMP_DEBUG +extern void dump_tables(find_objs_t *info) +#endif /* H5DUMP_DEBUG */ +extern herr_t init_objs(hid_t fid, find_objs_t *info, table_t **group_table, + table_t **dset_table, table_t **type_table); +extern obj_t *search_obj(table_t *temp, unsigned long *objno); #endif /* H5TOOLS_UTILS_H__ */ |