summaryrefslogtreecommitdiffstats
path: root/tools/h5ls.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/h5ls.c')
-rw-r--r--tools/h5ls.c253
1 files changed, 185 insertions, 68 deletions
diff --git a/tools/h5ls.c b/tools/h5ls.c
index ae14077..f525136 100644
--- a/tools/h5ls.c
+++ b/tools/h5ls.c
@@ -15,6 +15,12 @@
#include <H5private.h>
#include <h5tools.h>
+/*
+ * If defined then include the file name as part of the object name when
+ * printing full object names. Otherwise leave the file name off.
+ */
+#define H5LS_PREPEND_FILENAME
+
/* Command-line switches */
static int verbose_g = 0; /*lots of extra output */
static int width_g = 80; /*output width in characters */
@@ -271,6 +277,9 @@ display_string(FILE *stream, const char *s, hbool_t escape_spaces)
* Thursday, November 5, 1998
*
* Modifications:
+ * Robb Matzke, 1999-06-11
+ * Added the C9x types, but we still prefer to display the types
+ * from the C language itself (like `int' vs. `int32_t').
*
*-------------------------------------------------------------------------
*/
@@ -303,6 +312,54 @@ display_native_type(hid_t type, int UNUSED indent)
printf("native double");
} else if (H5Tequal(type, H5T_NATIVE_LDOUBLE)) {
printf("native long double");
+ } else if (H5Tequal(type, H5T_NATIVE_INT8)) {
+ printf("native int8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT8)) {
+ printf("native uint8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT16)) {
+ printf("native int16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT16)) {
+ printf("native uint16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT32)) {
+ printf("native int32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT32)) {
+ printf("native uint32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT64)) {
+ printf("native int64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT64)) {
+ printf("native uint64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST8)) {
+ printf("native int_least8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST8)) {
+ printf("native uint_least8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST16)) {
+ printf("native int_least16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST16)) {
+ printf("native uint_least16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST32)) {
+ printf("native int_least32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST32)) {
+ printf("native uint_least32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST64)) {
+ printf("native int_least64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST64)) {
+ printf("native uint_least64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST8)) {
+ printf("native int_fast8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST8)) {
+ printf("native uint_fast8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST16)) {
+ printf("native int_fast16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST16)) {
+ printf("native uint_fast16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST32)) {
+ printf("native int_fast32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST32)) {
+ printf("native uint_fast32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST64)) {
+ printf("native int_fast64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST64)) {
+ printf("native uint_fast64_t");
} else if (H5Tequal(type, H5T_NATIVE_B8)) {
printf("native 8-bit field");
} else if (H5Tequal(type, H5T_NATIVE_B16)) {
@@ -973,6 +1030,8 @@ display_opaque_type(hid_t type, int indent)
* Thursday, November 5, 1998
*
* Modifications:
+ * Robb Matzke, 1999-06-11
+ * Prints the OID of shared data types.
*
*-------------------------------------------------------------------------
*/
@@ -980,6 +1039,7 @@ static void
display_type(hid_t type, int indent)
{
H5T_class_t data_class = H5Tget_class(type);
+ H5G_stat_t sb;
/* Bad data type */
if (type<0) {
@@ -987,9 +1047,17 @@ display_type(hid_t type, int indent)
return;
}
- /* Shared? */
- if (H5Tcommitted(type)) printf("shared ");
-
+ /* Shared? If so then print the type's OID */
+ if (H5Tcommitted(type)) {
+ if (H5Gget_objinfo(type, ".", FALSE, &sb)>=0) {
+ printf("shared-%lu:%lu:%lu:%lu ",
+ sb.fileno[1], sb.fileno[0],
+ sb.objno[1], sb.objno[0]);
+ } else {
+ printf("shared ");
+ }
+ }
+
/* Print the type */
if (display_native_type(type, indent) ||
display_ieee_type(type, indent) ||
@@ -1480,7 +1548,8 @@ ragged_list2(hid_t UNUSED ra, const char UNUSED *name)
* links don't correspond to actual objects we simply print the
* link information and return failure.
*
- * Return: Success: never succeeds
+ * Return: Success: 0 - an invalid object but successful return
+ * of this function.
*
* Failure: -1
*
@@ -1500,9 +1569,9 @@ link_open(hid_t location, const char *name)
if (NULL==HDmemchr(buf, 0, sizeof(buf))) {
strcpy(buf+sizeof(buf)-4, "...");
}
- puts(buf);
+ fputs(buf, stdout);
- return -1;
+ return 0;
}
@@ -1594,7 +1663,7 @@ 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) {
+ if (verbose_g>0 && H5G_LINK!=sb.type) {
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]);
@@ -1612,7 +1681,7 @@ list (hid_t group, const char *name, void *_iter)
puts("\"");
}
}
- if (sb.type>0 && dispatch_g[sb.type].list2) {
+ if (sb.type>=0 && dispatch_g[sb.type].list2) {
(dispatch_g[sb.type].list2)(obj, fullname);
}
@@ -1620,7 +1689,9 @@ list (hid_t group, const char *name, void *_iter)
* Close the object.
*/
done:
- if (sb.type>0 && obj>=0) (dispatch_g[sb.type].close)(obj);
+ if (sb.type>=0 && obj>=0 && dispatch_g[sb.type].close) {
+ (dispatch_g[sb.type].close)(obj);
+ }
if (fullname) free(fullname);
return 0;
}
@@ -1631,8 +1702,7 @@ list (hid_t group, const char *name, void *_iter)
*
* Purpose: Returns a malloc'd buffer that contains the PATH and BASE
* names separated by a single slash. It also removes duplicate
- * and trailing slashes and insures that the name begins with a
- * slash.
+ * and trailing slashes.
*
* Return: Success: Ptr to fixed name from malloc()
*
@@ -1653,8 +1723,10 @@ fix_name(const char *path, const char *base)
int len=0;
if (path) {
- /* Slash, followed by path, followed by slash */
- if ('/'!=*path) prev = s[len++] = '/';
+ /* Path, followed by slash */
+#ifdef H5LS_PREPEND_FILENAME
+ if ('/'!=*path) s[len++] = '/';
+#endif
for (/*void*/; *path; path++) {
if ('/'!=*path || '/'!=prev) prev = s[len++] = *path;
}
@@ -1779,15 +1851,20 @@ get_width(void)
int
main (int argc, char *argv[])
{
- hid_t file, plist=H5P_DEFAULT, root;
- const char *fname = NULL;
+ hid_t file=-1, plist=-1, root=-1;
+ char *fname=NULL, *oname=NULL, *x;
const char *progname;
const char *s = NULL;
char *rest, *container=NULL;
int argno;
H5G_stat_t sb;
iter_t iter;
+ static char root_name[] = "/";
+ /* Turn off HDF5's automatic error printing unless you're debugging h5ls */
+ H5Eset_auto(NULL, NULL);
+
+ /* Build display table */
DISPATCH(H5G_DATASET, "Dataset", H5Dopen, H5Dclose,
dataset_list1, dataset_list2);
DISPATCH(H5G_GROUP, "Group", H5Gopen, H5Gclose,
@@ -1799,8 +1876,8 @@ main (int argc, char *argv[])
DISPATCH(H5G_RAGGED, "Ragged Array", H5Gopen, H5Gclose,
NULL, ragged_list2);
- /*init the programtype var fromthe tools lib*/
- programtype = H5LS;
+ /* Init the program type for the tools lib*/
+ programtype = H5LS; /*global*/
/* Name of this program without the path */
if ((progname=strrchr(argv[0], '/'))) progname++;
@@ -1839,6 +1916,18 @@ main (int argc, char *argv[])
usage(progname);
exit(1);
}
+ } else if (!strcmp(argv[argno], "--width")) {
+ if (argno+1>=argc) {
+ usage(progname);
+ exit(1);
+ } else {
+ s = argv[++argno];
+ }
+ width_g = (int)strtol(s, &rest, 0);
+ if (width_g<=0 || *rest) {
+ usage(progname);
+ exit(1);
+ }
} else if (!strcmp(argv[argno], "--verbose")) {
verbose_g++;
} else if (!strcmp(argv[argno], "--version")) {
@@ -1914,66 +2003,94 @@ main (int argc, char *argv[])
}
/*
- * 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 no arguments remain then print a usage message (instead of doing
+ * absolutely nothing ;-)
*/
- if (argno<argc) {
- fname = argv[argno++];
- } else {
+ if (argno>=argc) {
usage(progname);
exit(1);
}
- 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);
-
+
/*
- * The remaining optional arguments are the names of the objects to list.
- * If there are no arguments then list `/'.
+ * Each remaining argument is an hdf5 file followed by an optional slash
+ * and object name.
+ *
+ * Example: ../dir1/foo/bar/baz
+ * \_________/\______/
+ * file obj
+ *
+ * The dichotomy is determined by calling H5Fopen() repeatedly until it
+ * succeeds. The first call uses the entire name and each subsequent call
+ * chops off the last component. If we reach the beginning of the name
+ * then there must have been something wrong with the file (perhaps it
+ * doesn't exist).
*/
- if (argno>=argc) {
- if (grp_literal_g) {
- root = H5Gopen(file, "/");
- iter.container = "/";
- list(root, "/", &iter);
- H5Gclose(root);
- } else {
- H5Gget_objinfo(file, "/", TRUE, &sb);
- sym_insert(&sb, "/");
- iter.container = "/";
- H5Giterate(file, "/", NULL, list, &iter);
+ while (argno<argc) {
+ fname = argv[argno++];
+ oname = NULL;
+ file = -1;
+
+ while (fname && *fname) {
+ /* Choose a file driver*/
+ plist = H5Pcreate(H5P_FILE_ACCESS);
+ if (strchr(fname, '%')) {
+ H5Pset_family(plist, 0, H5P_DEFAULT);
+ }
+
+ /* Try to open the file */
+ H5E_BEGIN_TRY {
+ file = H5Fopen(fname, H5F_ACC_RDONLY, plist);
+ } H5E_END_TRY;
+ H5Pclose(plist);
+ if (file>=0) break; /*success*/
+
+ /* Shorten the file name; lengthen the object name */
+ x = oname;
+ oname = strrchr(fname, '/');
+ if (x) *x = '/';
+ if (!oname) break;
+ *oname = '\0';
}
- } else {
- for (/*void*/; argno<argc; argno++) {
- if (H5Gget_objinfo(file, argv[argno], TRUE, &sb)>=0 &&
- H5G_GROUP==sb.type && !grp_literal_g) {
- /*
- * Specified name is a group. List the complete contents of
- * the group.
- */
- sym_insert(&sb, argv[argno]);
- iter.container = container = fix_name("", argv[argno]);
- H5Giterate(file, argv[argno], NULL, list, &iter);
- free(container);
-
- } else if ((root=H5Gopen(file, "/"))<0) {
- exit(1); /*major problem!*/
+ if (file<0) {
+ fprintf(stderr, "%s: unable to open file\n", fname);
+ }
+ if (oname) oname++;
+ if (!oname || !*oname) oname = root_name;
+
+ /* Open the object and display it's information */
+ if (H5Gget_objinfo(file, oname, TRUE, &sb)>=0 &&
+ H5G_GROUP==sb.type && !grp_literal_g) {
+ /*
+ * Specified name is a group. List the complete contents of the
+ * group.
+ */
+ sym_insert(&sb, oname);
+#ifdef H5LS_PREPEND_FILENAME
+ iter.container = container = fix_name(fname, oname);
+#else
+ iter.container = container = fix_name("", oname);
+#endif
+ H5Giterate(file, oname, NULL, list, &iter);
+ free(container);
+
+ } else if ((root=H5Gopen(file, "/"))<0) {
+ exit(1); /*major problem!*/
- } else {
- /*
- * Specified name is a non-group object -- list that object.
- * The container for the object is everything up to the base
- * name.
- */
- iter.container = "/";
- list(root, argv[argno], &iter);
- if (H5Gclose(root)<0) exit(1);
- }
+ } else {
+ /*
+ * Specified name is a non-group object -- list that object. The
+ * container for the object is everything up to the base name.
+ */
+#ifdef H5LS_PREPEND_FILENAME
+ iter.container = fname;
+#else
+ iter.container = "/";
+#endif
+ list(root, oname, &iter);
+ if (H5Gclose(root)<0) exit(1);
}
+ H5Fclose(file);
}
-
- if (H5Fclose(file)<0) exit(1);
+
return 0;
}