diff options
Diffstat (limited to 'tools/h5ls.c')
-rw-r--r-- | tools/h5ls.c | 357 |
1 files changed, 248 insertions, 109 deletions
diff --git a/tools/h5ls.c b/tools/h5ls.c index f77beaa..13e4830 100644 --- a/tools/h5ls.c +++ b/tools/h5ls.c @@ -26,6 +26,25 @@ static int verbose_g = 0; static int dump_g = 0; static int width_g = 80; +/* Information about how to display each type of object */ +static struct dispatch_t { + const char *name; + hid_t (*open)(hid_t loc, const char *name); + herr_t (*close)(hid_t obj); + herr_t (*list1)(hid_t obj); + herr_t (*list2)(hid_t obj); +} dispatch_g[H5G_NTYPES]; + +#define DISPATCH(TYPE,NAME,OPEN,CLOSE,LIST1,LIST2) { \ + dispatch_g[TYPE].name = (NAME); \ + dispatch_g[TYPE].open = (OPEN); \ + dispatch_g[TYPE].close = (CLOSE); \ + dispatch_g[TYPE].list1 = (LIST1); \ + dispatch_g[TYPE].list2 = (LIST2); \ +} + +static herr_t list (hid_t group, const char *name, void *cd); + /*------------------------------------------------------------------------- * Function: usage @@ -133,8 +152,8 @@ list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data) { hid_t attr; int i; - - printf ("%*s%s", 26, "", attr_name); + + printf(" %-10s %-10s", "Attribute:", attr_name); if ((attr = H5Aopen_name (obj, attr_name))) { hid_t space = H5Aget_space (attr); hsize_t size[64]; @@ -154,6 +173,149 @@ list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data) /*------------------------------------------------------------------------- + * Function: dataset_list1 + * + * Purpose: List information about a dataset which should appear on the + * same line as the dataset name. This information will precede + * information which is applicable to all objects which will be + * printed by the caller. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, August 27, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +dataset_list1(hid_t dset) +{ + hsize_t cur_size[64]; /*current dataset dimensions */ + hsize_t max_size[64]; /*maximum dataset dimensions */ + hid_t space; /*data space */ + int ndims; /*dimensionality */ + int i; + + /* + * Information that goes on the same row as the name. The name has + * already been printed. + */ + space = H5Dget_space(dset); + ndims = H5Sextent_dims(space, cur_size, max_size); + printf (" {"); + for (i=0; i<ndims; i++) { + HDfprintf (stdout, "%s%Hu", i?", ":"", cur_size[i]); + if (max_size[i]==H5S_UNLIMITED) { + HDfprintf (stdout, "/%s", "Inf"); + } else if (max_size[i]!=cur_size[i] || verbose_g>0) { + HDfprintf(stdout, "/%Hu", max_size[i]); + } + } + putchar('}'); + H5Sclose (space); + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: dataset_list2 + * + * Purpose: List information about a dataset which should appear after + * information which is general to all objects. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, August 27, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +dataset_list2(hid_t dset) +{ + hid_t dcpl; /*dataset creation property list*/ + int nf; /*number of filters */ + unsigned filt_flags; /*filter flags */ + H5Z_filter_t filt_id; /*filter identification number */ + unsigned cd_values[20]; /*filter client data values */ + size_t cd_nelmts; /*filter client number of values*/ + size_t cd_num; /*filter client data counter */ + char f_name[32]; /*filter name */ + char s[64]; /*temporary string buffer */ + int i; + + if (verbose_g>0) { + dcpl = H5Dget_create_plist(dset); + + /* Print information about raw data filters */ + if ((nf = H5Pget_nfilters(dcpl))>0) { + for (i=0; i<nf; i++) { + cd_nelmts = NELMTS(cd_values); + filt_id = H5Pget_filter(dcpl, i, &filt_flags, &cd_nelmts, + cd_values, sizeof(f_name), f_name); + f_name[sizeof(f_name)-1] = '\0'; + sprintf(s, "Filter-%d:", i); + printf(" %-10s %s-%u %s {", s, + f_name[0]?f_name:"method", + (unsigned)filt_id, + filt_flags & H5Z_FLAG_OPTIONAL?"OPT":""); + for (cd_num=0; cd_num<cd_nelmts; cd_num++) { + printf("%s%u", cd_num?", ":"", cd_values[cd_num]); + } + printf("}\n"); + } + } + H5Pclose(dcpl); + } + + if (dump_g) dump_dataset_values(dset); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: link_open + * + * Purpose: This gets called to open a symbolic link. Since symbolic + * links don't correspond to actual objects we simply print the + * link information and return failure. + * + * Return: Success: never succeeds + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, August 27, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hid_t +link_open(hid_t location, const char *name) +{ + char buf[64]; + + if (H5Gget_linkval (location, name, sizeof(buf), buf)<0) return -1; + if (NULL==HDmemchr(buf, 0, sizeof(buf))) { + strcpy(buf+sizeof(buf)-4, "..."); + } + puts(buf); + + return -1; +} + + +/*------------------------------------------------------------------------- * Function: list * * Purpose: Prints the group member name. @@ -170,113 +332,67 @@ list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data) *------------------------------------------------------------------------- */ static herr_t -list (hid_t group, const char *name, void __unused__ *op_data) +list (hid_t group, const char *name, void __unused__ *cd) { hid_t obj; - hid_t (*func)(void*); - void *edata; - int i, nf; char buf[512], comment[50]; - H5G_stat_t statbuf; + H5G_stat_t sb; struct tm *tm; + herr_t status; - /* Disable error reporting */ - H5Eget_auto (&func, &edata); - H5Eset_auto (NULL, NULL); - - /* Print info about each name */ - printf ("%-25s ", name); - - if ((obj=H5Dopen (group, name))>=0) { - hsize_t size[64]; - hsize_t maxsize[64]; - hid_t space = H5Dget_space (obj); - int ndims = H5Sextent_dims(space, size, maxsize); - printf ("Dataset {"); - for (i=0; i<ndims; i++) { - HDfprintf (stdout, "%s%Hu", i?", ":"", size[i]); - if (maxsize[i]==H5S_UNLIMITED) { - HDfprintf (stdout, "/%s", "Inf"); - } else if (maxsize[i]!=size[i] || verbose_g>0) { - HDfprintf(stdout, "/%Hu", maxsize[i]); - } - } - printf ("}\n"); - H5Dclose (space); - H5Aiterate (obj, NULL, list_attr, NULL); - - /* Print additional information about datasets */ - if (verbose_g>0) { - hid_t dcpl = H5Dget_create_plist(obj); - if ((nf = H5Pget_nfilters(dcpl))>0) { - for (i=0; i<nf; i++) { - unsigned filt_flags; - H5Z_filter_t filt_id; - unsigned cd_values[20]; - size_t cd_nelmts = NELMTS(cd_values); - size_t cd_num; - char f_name[32]; - filt_id = H5Pget_filter(dcpl, i, &filt_flags, &cd_nelmts, - cd_values, sizeof(f_name), f_name); - f_name[sizeof(f_name)-1] = '\0'; - sprintf(comment, "Filter-%d:", i); - printf(" %-10s %s-%u %s {", comment, - f_name[0]?f_name:"method", - (unsigned)filt_id, - filt_flags & H5Z_FLAG_OPTIONAL?"OPT":""); - for (cd_num=0; cd_num<cd_nelmts; cd_num++) { - printf("%s%u", cd_num?", ":"", cd_values[cd_num]); - } - printf("}\n"); - } - } - H5Pclose(dcpl); - } - H5Dclose (obj); - } else if ((obj=H5Gopen (group, name))>=0) { - printf ("Group\n"); - H5Aiterate (obj, NULL, list_attr, NULL); - H5Gclose (obj); - } else if (H5Gget_linkval (group, name, sizeof(buf), buf)>=0) { - if (NULL==HDmemchr (buf, 0, sizeof(buf))) { - strcpy (buf+sizeof(buf)-4, "..."); - } - printf (" -> %s\n", buf); - } else if ((obj=H5Topen (group, name))>=0) { - printf ("Data type\n"); - H5Aiterate (obj, NULL, list_attr, NULL); - H5Tclose (obj); - } else { - printf ("Unknown Type\n"); + /* Print the object name */ + printf("%-25s ", name); + + /* Get object information */ + H5E_BEGIN_TRY { + status = H5Gstat(group, name, FALSE, &sb); + } H5E_END_TRY; + if (status<0) { + puts("**NOT FOUND**"); + return 0; + } else if (sb.type<0 || sb.type>=H5G_NTYPES) { + printf("Unknown type=%d", sb.type); + return 0; } + if (dispatch_g[sb.type].name) fputs(dispatch_g[sb.type].name, stdout); + + /* + * Open the object. Not all objects can be opened. If this is the case + * then return right away. + */ + if (NULL==dispatch_g[sb.type].open || + (obj=(dispatch_g[sb.type].open)(group, name))<0) return 0; + /* + * List the first line of information for the object. + */ + if (dispatch_g[sb.type].list1) (dispatch_g[sb.type].list1)(obj); + putchar('\n'); + + /* + * Show detailed information about the object, beginning with information + * which is common to all objects. + */ if (verbose_g>0) { - if (H5Gstat(group, name, TRUE, &statbuf)>=0) { - printf(" %-10s %lu:%lu:%lu:%lu\n", - "Location:", statbuf.fileno[1], statbuf.fileno[0], - statbuf.objno[1], statbuf.objno[0]); - if (statbuf.mtime>0 && NULL!=(tm = localtime(&(statbuf.mtime)))) { - strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm); - printf(" %-10s %s\n", "Modtime:", buf); - } + 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); + if (sb.mtime>0 && NULL!=(tm=localtime(&(sb.mtime)))) { + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm); + printf(" %-10s %s\n", "Modtime:", buf); } - - /* Display the comment if the object has one */ comment[0] = '\0'; H5Gget_comment(group, name, sizeof(comment), comment); strcpy(comment+sizeof(comment)-4, "..."); if (comment[0]) printf(" %-10s %s\n", "Comment:", comment); + if (dispatch_g[sb.type].list2) (dispatch_g[sb.type].list2)(obj); } - if (dump_g && (obj=H5Dopen(group, name))>=0) { - /* Turn on error reporting before dumping the data */ - H5Eset_auto(func, edata); - dump_dataset_values(obj); - H5Dclose(obj); - } - - /* Restore error reporting */ - H5Eset_auto (func, edata); + /* + * Close the object. + */ + (dispatch_g[sb.type].close)(obj); return 0; } @@ -301,14 +417,22 @@ list (hid_t group, const char *name, void __unused__ *op_data) int main (int argc, char *argv[]) { - hid_t file, plist=H5P_DEFAULT; + hid_t file, plist=H5P_DEFAULT, root; const char *fname = NULL; - const char *gname = "/"; const char *progname; const char *s; char *rest; int argno; + DISPATCH(H5G_DATASET, "Dataset", H5Dopen, H5Dclose, + dataset_list1, dataset_list2); + DISPATCH(H5G_GROUP, "Group", H5Gopen, H5Gclose, + NULL, NULL); + DISPATCH(H5G_TYPE, "Type", H5Topen, H5Tclose, + NULL, NULL); + DISPATCH(H5G_LINK, "-> ", link_open, NULL, + NULL, NULL); + /* Name of this program without the path */ if ((progname=strrchr (argv[0], '/'))) progname++; else progname = argv[0]; @@ -380,29 +504,44 @@ main (int argc, char *argv[]) } } - /* Non-switch arguments */ + /* + * The first non-switch argument is a file name. If the file name + * contains a `%' then assume that a file family is being opened. + */ if (argno<argc) { fname = argv[argno++]; } else { usage(progname); exit(1); } - if (argno<argc) gname = argv[argno++]; - if (argno<argc) { - usage(progname); - exit(1); - } - - /* - * Open the file. If the file name contains a `%' then assume that a - * file family is being opened. - */ if (strchr (fname, '%')) { plist = H5Pcreate (H5P_FILE_ACCESS); H5Pset_family (plist, 0, H5P_DEFAULT); } if ((file = H5Fopen (fname, H5F_ACC_RDONLY, plist))<0) exit (1); - if (H5Giterate (file, gname, NULL, list, NULL)<0) exit (1); - if (H5Fclose (file)<0) exit (1); + + /* + * The remaining optional arguments are the names of the objects to list. + * If there are no arguments then list `/'. + */ + if (argno>=argc) { + H5Giterate(file, "/", NULL, list, NULL); + } else { + for (/*void*/; argno<argc; argno++) { + H5E_BEGIN_TRY { + root = H5Gopen (file, argv[argno]); + } H5E_END_TRY; + if (root>=0) { + H5Giterate(file, argv[argno], NULL, list, NULL); + } else if ((root=H5Gopen(file, "/"))<0) { + exit(1); + } else { + list(root, argv[argno], NULL); + } + if (H5Gclose(root)<0) exit(1); + } + } + + if (H5Fclose(file)<0) exit(1); return 0; } |