summaryrefslogtreecommitdiffstats
path: root/tools/h5ls
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-07-06 19:45:35 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-07-06 19:45:35 (GMT)
commit98754fa9d12090f5e048fdb05cc5e9ce9111676f (patch)
tree407e611b19ee551d8153779104022dd886a467e5 /tools/h5ls
parent29321bcafa9f1c6108bb92b5a844a9d4d9c2c8e7 (diff)
downloadhdf5-98754fa9d12090f5e048fdb05cc5e9ce9111676f.zip
hdf5-98754fa9d12090f5e048fdb05cc5e9ce9111676f.tar.gz
hdf5-98754fa9d12090f5e048fdb05cc5e9ce9111676f.tar.bz2
[svn-r19050] Description:
Bring r18704:19049 from trunk to revise_chunks branch. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in debug mode Mac OS X/32 10.6.3 (amazon) in debug mode Mac OS X/32 10.6.3 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
Diffstat (limited to 'tools/h5ls')
-rw-r--r--tools/h5ls/CMakeLists.txt245
-rw-r--r--tools/h5ls/Makefile.in2
-rw-r--r--tools/h5ls/h5ls.c349
-rw-r--r--tools/h5ls/testh5ls.sh.in49
4 files changed, 535 insertions, 110 deletions
diff --git a/tools/h5ls/CMakeLists.txt b/tools/h5ls/CMakeLists.txt
new file mode 100644
index 0000000..c2d9100
--- /dev/null
+++ b/tools/h5ls/CMakeLists.txt
@@ -0,0 +1,245 @@
+cmake_minimum_required (VERSION 2.8)
+PROJECT (HDF5_TOOLS_H5LS)
+
+#-----------------------------------------------------------------------------
+# Setup include Directories
+#-----------------------------------------------------------------------------
+INCLUDE_DIRECTORIES (${HDF5_TOOLS_SOURCE_DIR}/lib)
+INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test)
+
+# --------------------------------------------------------------------
+# If testing was NOT enabled, then we need to build the tools library
+# --------------------------------------------------------------------
+#-- Add the h5ls executable
+ADD_EXECUTABLE (h5ls ${HDF5_TOOLS_H5LS_SOURCE_DIR}/h5ls.c)
+H5_NAMING (h5ls)
+IF (WIN32)
+ IF (MSVC)
+ IF (NOT BUILD_SHARED_LIBS)
+ SET_TARGET_PROPERTIES (h5ls
+ PROPERTIES
+ LINK_FLAGS "/NODEFAULTLIB:MSVCRT"
+ )
+ ENDIF (NOT BUILD_SHARED_LIBS)
+ ENDIF (MSVC)
+ENDIF (WIN32)
+TARGET_LINK_LIBRARIES (h5ls ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+
+SET (H5_DEP_EXECUTABLES
+ h5ls
+)
+
+IF (BUILD_TESTING)
+ #-- Copy all the HDF5 files from the test directory into the source directory
+ SET (HDF5_REFERENCE_FILES
+ help-1.ls
+ help-2.ls
+ help-3.ls
+ nosuchfile.ls
+ tall-1.ls
+ tall-2.ls
+ tarray1.ls
+ tattr2.ls
+ tcomp-1.ls
+ tdataregbe.ls
+ tdataregle.ls
+ tdset-1.ls
+ tempty.ls
+ textlink-1.ls
+ textlinksrc-1.ls
+ textlinksrc-2.ls
+ textlinksrc-3.ls
+ textlinksrc-4.ls
+ textlinksrc-5.ls
+ textlinksrc-6.ls
+ textlinksrc-7.ls
+ textlinksrc-1-old.ls
+ textlinksrc-2-old.ls
+ textlinksrc-3-old.ls
+ textlinksrc-6-old.ls
+ textlinksrc-7-old.ls
+ tsoftlinks-1.ls
+ tsoftlinks-2.ls
+ tsoftlinks-3.ls
+ tsoftlinks-4.ls
+ tsoftlinks-5.ls
+ tgroup.ls
+ tgroup-1.ls
+ tgroup-2.ls
+ tgroup-3.ls
+ thlink-1.ls
+ tloop-1.ls
+ tnestcomp-1.ls
+ tsaf.ls
+ tslink-1.ls
+ tstr-1.ls
+ tudlink-1.ls
+ tvldtypes1.ls
+ tvldtypes2le.ls
+ tvldtypes2be.ls
+ )
+ SET (HDF5_REFERENCE_TEST_FILES
+ tall.h5
+ tarray1.h5
+ tattr2.h5
+ tcompound.h5
+ tdatareg.h5
+ tdset.h5
+ tempty.h5
+ textlink.h5
+ textlinksrc.h5
+ textlinktar.h5
+ tgroup.h5
+ thlink.h5
+ tloop.h5
+ tnestedcomp.h5
+ tsaf.h5
+ tslink.h5
+ tsoftlinks.h5
+ tstr.h5
+ tudlink.h5
+ tvldtypes1.h5
+ )
+
+ FOREACH (ls_file ${HDF5_REFERENCE_FILES})
+ SET (lsdest "${PROJECT_BINARY_DIR}/${ls_file}")
+ #MESSAGE (STATUS " Translating ${ls_file}")
+ ADD_CUSTOM_COMMAND (
+ TARGET h5ls
+ POST_BUILD
+ COMMAND ${XLATE_UTILITY}
+ ARGS ${HDF5_TOOLS_SOURCE_DIR}/testfiles/${ls_file} ${lsdest} -l3
+ )
+ ENDFOREACH (ls_file ${HDF5_REFERENCE_FILES})
+
+ FOREACH (h5_file ${HDF5_REFERENCE_TEST_FILES})
+ SET (dest "${PROJECT_BINARY_DIR}/${h5_file}")
+ #MESSAGE (STATUS " Copying ${h5_file}")
+ ADD_CUSTOM_COMMAND (
+ TARGET h5ls
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy_if_different ${HDF5_TOOLS_SOURCE_DIR}/testfiles/${h5_file} ${dest}
+ )
+ ENDFOREACH (h5_file ${HDF5_REFERENCE_TEST_FILES})
+
+ MACRO (ADD_H5_TEST resultfile resultcode)
+ ADD_TEST (
+ NAME H5LS-${resultfile}
+ COMMAND "${CMAKE_COMMAND}"
+ -D "TEST_PROGRAM=$<TARGET_FILE:h5ls>"
+ -D "TEST_ARGS=${ARGN}"
+ -D "TEST_FOLDER=${PROJECT_BINARY_DIR}"
+ -D "TEST_OUTPUT=${resultfile}.out"
+ -D "TEST_EXPECT=${resultcode}"
+ -D "TEST_REFERENCE=${resultfile}.ls"
+ -P "${HDF5_RESOURCES_DIR}/runTest.cmake"
+ )
+ ENDMACRO (ADD_H5_TEST file)
+
+ # test the help syntax
+ ADD_H5_TEST (help-1 0 -w80 -h)
+ ADD_H5_TEST (help-2 0 -w80 --help)
+ ADD_H5_TEST (help-3 0 -w80 -?)
+
+ # test simple command
+ ADD_H5_TEST (tall-1 0 -w80 tall.h5)
+ ADD_H5_TEST (tall-2 0 -w80 -r -d tall.h5)
+ ADD_H5_TEST (tgroup 0 -w80 tgroup.h5)
+ ADD_H5_TEST (tgroup-3 0 -w80 tgroup.h5/g1)
+
+ # test for displaying groups
+ # The following combination of arguments is expected to return an error message
+ # and return value 1
+ ADD_H5_TEST (tgroup-1 1 -w80 -r -g tgroup.h5)
+ ADD_H5_TEST (tgroup-2 0 -w80 -g tgroup.h5/g1)
+
+ # test for displaying simple space datasets
+ ADD_H5_TEST (tdset-1 0 -w80 -r -d tdset.h5)
+
+ # test for displaying soft links (dangle)
+ ADD_H5_TEST (tslink-1 0 -w80 -r tslink.h5)
+
+ # test for displaying more soft links with --follow-symlinks
+ ADD_H5_TEST (tsoftlinks-1 0 --follow-symlinks tsoftlinks.h5)
+ ADD_H5_TEST (tsoftlinks-2 0 --follow-symlinks -r tsoftlinks.h5)
+ ADD_H5_TEST (tsoftlinks-3 0 --follow-symlinks tsoftlinks.h5/group1)
+ ADD_H5_TEST (tsoftlinks-4 0 --follow-symlinks -r tsoftlinks.h5/group1)
+ ADD_H5_TEST (tsoftlinks-5 0 --follow-symlinks tsoftlinks.h5/soft_dset1)
+
+ # test for displaying external and user-defined links with --follow-symlinks
+ ADD_H5_TEST (textlink-1 0 -w80 -r textlink.h5)
+ ADD_H5_TEST (textlinksrc-1 0 -w80 --follow-symlinks -r textlinksrc.h5)
+ ADD_H5_TEST (textlinksrc-2 0 -w80 --follow-symlinks -rv textlinksrc.h5/ext_link5)
+ ADD_H5_TEST (textlinksrc-3 0 -w80 --follow-symlinks -r textlinksrc.h5/ext_link1)
+ ADD_H5_TEST (textlinksrc-4 0 -w80 -r textlinksrc.h5)
+ ADD_H5_TEST (textlinksrc-5 0 -w80 -r textlinksrc.h5/ext_link1)
+ ADD_H5_TEST (textlinksrc-6 0 -w80 --follow-symlinks textlinksrc.h5)
+ ADD_H5_TEST (textlinksrc-7 0 -w80 --follow-symlinks textlinksrc.h5/ext_link1)
+ ADD_H5_TEST (tudlink-1 0 -w80 -r tudlink.h5)
+
+ # test for displaying external links with -E
+ # the option -E will be depriciated but keep it for backward compatibility
+ ADD_H5_TEST (textlinksrc-1-old 0 -w80 -Er textlinksrc.h5)
+ ADD_H5_TEST (textlinksrc-2-old 0 -w80 -Erv textlinksrc.h5/ext_link5)
+ ADD_H5_TEST (textlinksrc-3-old 0 -w80 -Er textlinksrc.h5/ext_link1)
+ ADD_H5_TEST (textlinksrc-6-old 0 -w80 -E textlinksrc.h5)
+ ADD_H5_TEST (textlinksrc-7-old 0 -w80 -E textlinksrc.h5/ext_link1)
+
+ # tests for hard links
+ ADD_H5_TEST (thlink-1 0 -w80 thlink.h5)
+
+ # tests for compound data types
+ ADD_H5_TEST (tcomp-1 0 -w80 -r -d tcompound.h5)
+
+ #test for the nested compound type
+ ADD_H5_TEST (tnestcomp-1 0 -w80 -r -d tnestedcomp.h5)
+
+ # test for loop detection
+ ADD_H5_TEST (tloop-1 0 -w80 -r -d tloop.h5)
+
+ # test for string
+ ADD_H5_TEST (tstr-1 0 -w80 -r -d tstr.h5)
+
+ # test test file created from lib SAF team
+ ADD_H5_TEST (tsaf 0 -w80 -r -d tsaf.h5)
+
+ # test for variable length data types
+ ADD_H5_TEST (tvldtypes1 0 -w80 -r -d tvldtypes1.h5)
+
+ # test for array data types
+ ADD_H5_TEST (tarray1 0 -w80 -r -d tarray1.h5)
+
+ # test for empty data
+ ADD_H5_TEST (tempty 0 -w80 -d tempty.h5)
+
+ # test for all dataset types written to attributes
+ # enable -S for avoiding printing NATIVE types
+ ADD_H5_TEST (tattr2 0 -w80 -v -S tattr2.h5)
+
+ # test for non-existing file
+ ADD_H5_TEST (nosuchfile 1 nosuchfile.h5)
+
+ IF (WORDS_BIGENDIAN)
+ # test for variable length data types in verbose mode
+ ADD_H5_TEST (tvldtypes2be 0 -v tvldtypes1.h5)
+ # test for dataset region references data types in verbose mode
+ ADD_H5_TEST (tdataregbe 0 -v tdatareg.h5)
+ ELSE (WORDS_BIGENDIAN)
+ ADD_H5_TEST (tvldtypes2le 0 -v tvldtypes1.h5)
+ ADD_H5_TEST (tdataregle 0 -v tdatareg.h5)
+ ENDIF (WORDS_BIGENDIAN)
+
+ENDIF (BUILD_TESTING)
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+INSTALL (
+ TARGETS
+ h5ls
+ RUNTIME DESTINATION
+ bin/tools
+ COMPONENT
+ toolsapplications
+)
diff --git a/tools/h5ls/Makefile.in b/tools/h5ls/Makefile.in
index 54a9324..4949f8b 100644
--- a/tools/h5ls/Makefile.in
+++ b/tools/h5ls/Makefile.in
@@ -186,12 +186,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTRUMENT = @INSTRUMENT@
INSTRUMENT_LIBRARY = @INSTRUMENT_LIBRARY@
+LARGEFILE = @LARGEFILE@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
-LINUX_LFS = @LINUX_LFS@
LIPO = @LIPO@
LL_PATH = @LL_PATH@
LN_S = @LN_S@
diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c
index ab3a110..789e02a 100644
--- a/tools/h5ls/h5ls.c
+++ b/tools/h5ls/h5ls.c
@@ -29,25 +29,29 @@
#include "h5tools_utils.h"
#include "h5trav.h"
+/* Name of tool */
+#define PROGRAMNAME "h5ls"
+
#define NAME_BUF_SIZE 2048
-/* Struct to keep track of external link targets visited */
-typedef struct elink_trav_t {
+/* Struct to keep track of symbolic link targets visited */
+typedef struct symlink_trav_t {
size_t nalloc;
size_t nused;
struct {
+ H5L_type_t type;
char *file;
char *path;
} *objs;
-} elink_trav_t;
+} symlink_trav_t;
/* Struct to pass through to visitors */
typedef struct {
const char *fname; /* Filename */
hid_t fid; /* File ID */
hid_t gid; /* Group ID */
- hbool_t ext_target; /* Whether this is the target of an external link */
- elink_trav_t *elink_list; /* List of visited external links */
+ hbool_t symlink_target; /* Whether this is the target of an symbolic link */
+ symlink_trav_t *symlink_list; /* List of visited symbolic links */
int base_len; /* Length of base path name, if not root */
int name_start; /* # of leading characters to strip off path names on output */
}iter_t;
@@ -61,6 +65,7 @@ static hbool_t label_g = FALSE; /* label compound values? */
static hbool_t string_g = FALSE; /* print 1-byte numbers as ASCII? */
static hbool_t fullname_g = FALSE; /* print full path names */
static hbool_t recursive_g = FALSE; /* recursive descent listing */
+static hbool_t follow_symlink_g = FALSE; /* follow symbolic links */
static hbool_t follow_elink_g = FALSE; /* follow external links */
static hbool_t grp_literal_g = FALSE; /* list group, not contents */
static hbool_t hexdump_g = FALSE; /* show data as raw hexadecimal */
@@ -88,9 +93,6 @@ static struct dispatch_t {
static void display_type(hid_t type, int ind);
static herr_t visit_obj(hid_t file, const char *oname, iter_t *iter);
-const char *progname="h5ls";
-int d_status;
-
/*-------------------------------------------------------------------------
* Function: usage
@@ -111,31 +113,47 @@ usage (void)
{
fprintf(stderr, "\
usage: %s [OPTIONS] [OBJECTS...]\n\
- OPTIONS\n\
- -h, -?, --help Print a usage message and exit\n\
- -a, --address Print addresses for raw data\n\
- -d, --data Print the values of datasets\n\
- -e, --errors Show all HDF5 error reporting\n\
- -E, --external Allow traversal into external files\n\
- -f, --full Print full path names instead of base names\n\
- -g, --group Show information about a group, not its contents\n\
- -l, --label Label members of compound datasets\n\
- -r, --recursive List all groups recursively, avoiding cycles\n\
- -s, --string Print 1-byte integer datasets as ASCII\n\
- -S, --simple Use a machine-readable output format\n\
- -wN, --width=N Set the number of columns of output\n\
- -v, --verbose Generate more verbose output\n\
- -V, --version Print version number and exit\n\
- --vfd=DRIVER Use the specified virtual file driver\n\
- -x, --hexdump Show raw data in hexadecimal format\n\
+ OPTIONS\n\
+ -h, -?, --help Print a usage message and exit\n\
+ -a, --address Print addresses for raw data\n\
+ -d, --data Print the values of datasets\n\
+ -e, --errors Show all HDF5 error reporting\n\
+ --follow-symlinks Follow symbolic links (soft links and external links)\n\
+ to display target object information.\n\
+ Without this option, h5ls identifies a symbolic link\n\
+ as a soft link or external link and prints the value\n\
+ assigned to the symbolic link; it does not provide any\n\
+ information regarding the target object or determine\n\
+ whether the link is a dangling link.\n\
+ -f, --full Print full path names instead of base names\n\
+ -g, --group Show information about a group, not its contents\n\
+ -l, --label Label members of compound datasets\n\
+ -r, --recursive List all groups recursively, avoiding cycles\n\
+ -s, --string Print 1-byte integer datasets as ASCII\n\
+ -S, --simple Use a machine-readable output format\n\
+ -wN, --width=N Set the number of columns of output\n\
+ -v, --verbose Generate more verbose output\n\
+ -V, --version Print version number and exit\n\
+ --vfd=DRIVER Use the specified virtual file driver\n\
+ -x, --hexdump Show raw data in hexadecimal format\n\
+\n\
+ OBJECTS\n\
+ Each object consists of an HDF5 file name optionally followed by a\n\
+ slash and an object name within the file (if no object is specified\n\
+ within the file then the contents of the root group are displayed).\n\
+ The file name may include a printf(3C) integer format such as\n\
+ \"%%05d\" to open a file family.\n\
\n\
- OBJECTS\n\
- Each object consists of an HDF5 file name optionally followed by a\n\
- slash and an object name within the file (if no object is specified\n\
- within the file then the contents of the root group are displayed).\n\
- The file name may include a printf(3C) integer format such as\n\
- \"%%05d\" to open a file family.\n",
- progname);
+ Deprecated Options\n\
+ The following options have been deprecated in HDF5. While they remain\n\
+ available, they have been superseded as indicated and may be removed\n\
+ from HDF5 in the future. Use the indicated replacement option in all\n\
+ new work; where possible, existing scripts, et cetera, should also be\n\
+ updated to use the replacement option.\n\
+\n\
+ -E or --external Follow external links.\n\
+ Replaced by --follow-symlinks.\n",
+ h5tools_getprogname());
}
@@ -152,6 +170,8 @@ usage: %s [OPTIONS] [OBJECTS...]\n\
* Thursday, November 5, 1998
*
* Modifications:
+ * Add _H5LS_CONVERT_SPECIAL_CHAR_ #ifdef section and make it not to
+ * convert special chars to visible chars. (Jonathan Kim 06/24/2010)
*
*-------------------------------------------------------------------------
*/
@@ -160,6 +180,27 @@ display_string(FILE *stream, const char *s, hbool_t escape_spaces)
{
int nprint=0;
+#ifdef _H5LS_CONVERT_SPECIAL_CHAR_
+ /*-------------------------------------------------------------------
+ * _H5LS_CONVERT_SPECIAL_CHAR_ is not defined, so this code section
+ * will not be compiled.
+ * This code section is due to be removed after verifying no problem
+ * at customer sites. (However we may keep it just for the future
+ * reference as it survived over ten years)
+ *
+ * Reason for Obsolete:
+ * This portion of code converts special characters or '\' to string,
+ * so when those characters are in object or attribute name, h5ls display
+ * as visible characters.
+ * However if a user come up with object or attribute name with special
+ * character in programming, this code takes away control over '\'
+ * (escape character) from the user and causes confusion for the output,
+ * also it’s not possible to handle all the cases in this way.
+ * This also causes discrepancy from how the string data saved in
+ * HDF5 file.
+ * Also other HDF tools don’t convert characters like this, so this
+ * causes inconsistent output among tools.
+ *-------------------------------------------------------------/
for (/*void*/; s && *s; s++) {
switch (*s) {
case '"':
@@ -212,6 +253,17 @@ display_string(FILE *stream, const char *s, hbool_t escape_spaces)
break;
}
}
+#else
+ if (stream)
+ {
+ nprint = fprintf(stream,s);
+ }
+ else
+ {
+ nprint = strlen(s);
+ }
+#endif /* _H5LS_CONVERT_SPECIAL_CHAR_ */
+
return nprint;
}
@@ -469,6 +521,9 @@ display_precision(hid_t type, int ind)
case H5T_NPAD:
plsb_s = "unknown";
break;
+ default:
+ ;
+ break;
}
}
if (H5Tget_offset(type)+prec<8*H5Tget_size(type)) {
@@ -486,6 +541,9 @@ display_precision(hid_t type, int ind)
case H5T_NPAD:
pmsb_s = "unknown";
break;
+ default:
+ ;
+ break;
}
}
if (plsb_s || pmsb_s) {
@@ -646,6 +704,9 @@ display_float_type(hid_t type, int ind)
case H5T_NORM_ERROR:
norm_s = ", unknown normalization";
break;
+ default:
+ ;
+ break;
}
printf("\n%*s(significant for %lu bit%s at bit %lu%s)", ind, "",
(unsigned long)msize, 1==msize?"":"s", (unsigned long)mpos,
@@ -672,6 +733,9 @@ display_float_type(hid_t type, int ind)
case H5T_NPAD:
pad_s = "unknown";
break;
+ default:
+ ;
+ break;
}
printf("\n%*s(internal padding bits are %s)", ind, "", pad_s);
}
@@ -786,7 +850,7 @@ display_enum_type(hid_t type, int ind)
/* Get the names and raw values of all members */
name = calloc(nmembs, sizeof(char*));
- value = calloc(nmembs, MAX(H5Tget_size(type), dst_size));
+ value = (unsigned char *)calloc(nmembs, MAX(H5Tget_size(type), dst_size));
for (i=0; i<nmembs; i++) {
name[i] = H5Tget_member_name(type, i);
H5Tget_member_value(type, i, value+i*H5Tget_size(type));
@@ -889,6 +953,9 @@ display_string_type(hid_t type, int UNUSED ind)
case H5T_STR_ERROR:
pad_s = "unknown-format";
break;
+ default:
+ ;
+ break;
}
/* Character set */
@@ -917,6 +984,9 @@ display_string_type(hid_t type, int UNUSED ind)
case H5T_CSET_ERROR:
cset_s = "unknown-character-set";
break;
+ default:
+ ;
+ break;
}
if (H5Tis_variable_str(type)) {
@@ -1054,7 +1124,7 @@ display_array_type(hid_t type, int ind)
if (H5T_ARRAY!=H5Tget_class(type)) return FALSE;
ndims = H5Tget_array_ndims(type);
if (ndims) {
- dims = malloc(ndims*sizeof(dims[0]));
+ dims = (hsize_t *)malloc(ndims*sizeof(dims[0]));
H5Tget_array_dims2(type, dims);
/* Print dimensions */
@@ -1701,7 +1771,7 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void
iter_t *iter = (iter_t*)_iter;
/* Print the link's name, either full name or base name */
- if(!iter->ext_target)
+ if(!iter->symlink_target)
display_obj_name(stdout, iter, name, "");
/* Check object information */
@@ -1709,7 +1779,7 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void
printf("Unknown type(%d)", (int)oinfo->type);
obj_type = H5O_TYPE_UNKNOWN;
}
- if(iter->ext_target)
+ if(iter->symlink_target)
fputc('{', stdout);
if(obj_type >= 0 && dispatch_g[obj_type].name)
fputs(dispatch_g[obj_type].name, stdout);
@@ -1718,7 +1788,7 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void
if(first_seen) {
printf(", same as ");
display_string(stdout, first_seen, TRUE);
- if(!iter->ext_target)
+ if(!iter->symlink_target)
printf("\n");
} /* end if */
else {
@@ -1735,7 +1805,7 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void
/* List the first line of information for the object. */
if(obj_type >= 0 && dispatch_g[obj_type].list1)
(dispatch_g[obj_type].list1)(obj);
- if(!iter->ext_target || (verbose_g > 0))
+ if(!iter->symlink_target || (verbose_g > 0))
putchar('\n');
/* Show detailed information about the object, beginning with information
@@ -1787,18 +1857,18 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void
} /* end else */
done:
- if(iter->ext_target) {
+ if(iter->symlink_target) {
fputs("}\n", stdout);
- iter->ext_target = FALSE;
+ iter->symlink_target = FALSE;
}
return 0;
} /* end list_obj() */
/*-------------------------------------------------------------------------
- * Function: elink_trav_add
+ * Function: symlink_visit_add
*
- * Purpose: Add an external link to visited data structure
+ * Purpose: Add an symbolic link to visited data structure
*
* Return: 0 on success, -1 on failure
*
@@ -1807,16 +1877,26 @@ done:
*
* Date: September 5, 2008
*
+ * Modified:
+ * Jonathan Kim
+ * - Renamed from elink_trav_add to symlink_visit_add for both soft and
+ * external links. (May 25, 2010)
+ * - Add type parameter to distingush between soft and external link for
+ * sure, which prevent from mixing up visited link when the target names
+ * are same between the soft and external link, as code marks with the
+ * target name. (May 25,2010)
+ *
*-------------------------------------------------------------------------
*/
static herr_t
-elink_trav_add(elink_trav_t *visited, const char *file, const char *path)
+symlink_visit_add(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path)
{
size_t idx; /* Index of address to use */
void *tmp_ptr;
/* Allocate space if necessary */
- if(visited->nused == visited->nalloc) {
+ if(visited->nused == visited->nalloc)
+ {
visited->nalloc = MAX(1, visited->nalloc * 2);
if(NULL == (tmp_ptr = HDrealloc(visited->objs, visited->nalloc * sizeof(visited->objs[0]))))
return -1;
@@ -1825,24 +1905,36 @@ elink_trav_add(elink_trav_t *visited, const char *file, const char *path)
/* Append it */
idx = visited->nused++;
- if(NULL == (visited->objs[idx].file = HDstrdup(file))) {
- visited->nused--;
- return -1;
+
+ visited->objs[idx].type = type;
+ visited->objs[idx].file = NULL;
+ visited->objs[idx].path = NULL;
+
+ if (type == H5L_TYPE_EXTERNAL)
+ {
+ if(NULL == (visited->objs[idx].file = HDstrdup(file)))
+ {
+ visited->nused--;
+ return -1;
+ }
}
- if(NULL == (visited->objs[idx].path = HDstrdup(path))) {
+
+ if(NULL == (visited->objs[idx].path = HDstrdup(path)))
+ {
visited->nused--;
- HDfree (visited->objs[idx].file);
+ if (visited->objs[idx].file)
+ HDfree (visited->objs[idx].file);
return -1;
}
return 0;
-} /* end elink_trav_add() */
+} /* end symlink_visit_add() */
/*-------------------------------------------------------------------------
- * Function: elink_trav_visited
+ * Function: symlink_is_visited
*
- * Purpose: Check if an external link has already been visited
+ * Purpose: Check if an symbolic link has already been visited
*
* Return: TRUE/FALSE
*
@@ -1851,22 +1943,41 @@ elink_trav_add(elink_trav_t *visited, const char *file, const char *path)
*
* Date: September 5, 2008
*
+ * Modified:
+ * Jonathan Kim
+ * - Renamed from elink_trav_visited to symlink_is_visited for both soft and
+ * external links. (May 25, 2010)
+ * - Add type parameter to distingush between soft and external link for
+ * sure, which prevent from mixing up visited link when the target names
+ * are same between the soft and external link, as code marks with the
+ * target name. (May 25,2010)
+ *
*-------------------------------------------------------------------------
*/
static hbool_t
-elink_trav_visited(elink_trav_t *visited, const char *file, const char *path)
+symlink_is_visited(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path)
{
- size_t u; /* Local index variable */
+ size_t u; /* Local index variable */
- /* Look for elink */
+ /* Look for symlink */
for(u = 0; u < visited->nused; u++)
- /* Check for elink value already in array */
- if(!HDstrcmp(visited->objs[u].file, file) && !HDstrcmp(visited->objs[u].path, path))
- return(TRUE);
-
- /* Didn't find elink */
+ {
+ /* Check for symlink values already in array */
+ /* check type and path pair to distingush between symbolic links */
+ if ((visited->objs[u].type == type) && !HDstrcmp(visited->objs[u].path, path))
+ {
+ /* if external link, file need to be matched as well */
+ if (visited->objs[u].type == H5L_TYPE_EXTERNAL)
+ {
+ if (!HDstrcmp(visited->objs[u].file, file))
+ return (TRUE);
+ }
+ return (TRUE);
+ }
+ }
+ /* Didn't find symlink */
return(FALSE);
-} /* end elink_trav_visited() */
+} /* end symlink_is_visited() */
/*-------------------------------------------------------------------------
@@ -1886,7 +1997,7 @@ elink_trav_visited(elink_trav_t *visited, const char *file, const char *path)
static herr_t
list_lnk(const char *name, const H5L_info_t *linfo, void *_iter)
{
- char *buf;
+ char *buf=NULL;
iter_t *iter = (iter_t*)_iter;
/* Print the link's name, either full name or base name */
@@ -1894,18 +2005,52 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter)
switch(linfo->type) {
case H5L_TYPE_SOFT:
- if((buf = HDmalloc(linfo->u.val_size)) == NULL)
+ if((buf = (char*)HDmalloc(linfo->u.val_size)) == NULL)
goto done;
if(H5Lget_val(iter->fid, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) {
- HDfree(buf);
goto done;
} /* end if */
HDfputs("Soft Link {", stdout);
HDfputs(buf, stdout);
- HDfree(buf);
- HDfputs("}\n", stdout);
+ HDfputc('}', stdout);
+ if(follow_symlink_g)
+ {
+ hbool_t orig_grp_literal = grp_literal_g;
+ HDfputc(' ', stdout);
+
+ /* Check if we have already seen this softlink */
+ if(symlink_is_visited(iter->symlink_list, linfo->type, NULL, buf))
+ {
+ HDfputs("{Already Visited}\n", stdout);
+ goto done;
+ }
+
+ /* Add this link to the list of seen softlinks */
+ if(symlink_visit_add(iter->symlink_list, linfo->type, NULL, buf) < 0)
+ goto done;
+
+ /* Adjust user data to specify that we are operating on the
+ * target of an soft link */
+ iter->symlink_target = TRUE;
+
+ /* Prevent recursive listing of soft link target if
+ * recursive_g is off */
+ if(!recursive_g)
+ grp_literal_g = TRUE;
+ /* Recurse through the soft link */
+ if(visit_obj(iter->fid, name, iter) < 0)
+ {
+ grp_literal_g = orig_grp_literal;
+ goto done;
+ }
+
+ grp_literal_g = orig_grp_literal;
+ }
+ else
+ HDfputc('\n', stdout);
+
break;
case H5L_TYPE_EXTERNAL:
@@ -1913,16 +2058,13 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter)
const char *filename;
const char *path;
- if((buf = HDmalloc(linfo->u.val_size)) == NULL)
+ if((buf = (char*)HDmalloc(linfo->u.val_size)) == NULL)
goto done;
- if(H5Lget_val(iter->fid, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) {
- HDfree(buf);
+ if(H5Lget_val(iter->fid, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0)
goto done;
- } /* end if */
- if(H5Lunpack_elink_val(buf, linfo->u.val_size, NULL, &filename, &path) < 0) {
- HDfree(buf);
+
+ if(H5Lunpack_elink_val(buf, linfo->u.val_size, NULL, &filename, &path) < 0)
goto done;
- } /* end if */
HDfputs("External Link {", stdout);
HDfputs(filename, stdout);
@@ -1933,27 +2075,28 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter)
HDfputc('}', stdout);
/* Recurse through the external link */
- if(follow_elink_g) {
+ /* keep the follow_elink_g for backward compatibility with -E */
+ if(follow_symlink_g || follow_elink_g)
+ {
hbool_t orig_grp_literal = grp_literal_g;
-
HDfputc(' ', stdout);
/* Check if we have already seen this elink */
- if(elink_trav_visited(iter->elink_list, filename, path)) {
+ if(symlink_is_visited(iter->symlink_list, linfo->type, filename, path))
+ {
HDfputs("{Already Visited}\n", stdout);
- HDfree(buf);
goto done;
}
/* Add this link to the list of seen elinks */
- if(elink_trav_add(iter->elink_list, filename, path) < 0) {
- HDfree(buf);
+ if(symlink_visit_add(iter->symlink_list, linfo->type, filename, path) < 0)
+ {
goto done;
}
/* Adjust user data to specify that we are operating on the
* target of an external link */
- iter->ext_target = TRUE;
+ iter->symlink_target = TRUE;
/* Prevent recursive listing of external link target if
* recursive_g is off */
@@ -1962,7 +2105,6 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter)
/* Recurse through the external link */
if(visit_obj(iter->fid, name, iter) < 0) {
- HDfree(buf);
grp_literal_g = orig_grp_literal;
goto done;
}
@@ -1972,7 +2114,6 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter)
else
HDfputc('\n', stdout);
- HDfree(buf);
}
break;
@@ -1982,6 +2123,8 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter)
} /* end switch */
done:
+ if (buf)
+ HDfree(buf);
return 0;
} /* end list_lnk() */
@@ -2008,9 +2151,9 @@ visit_obj(hid_t file, const char *oname, iter_t *iter)
/* Retrieve info for object to list */
if(H5Oget_info_by_name(file, oname, &oi, H5P_DEFAULT) < 0) {
- if(iter->ext_target) {
+ if(iter->symlink_target) {
HDfputs("{**NOT FOUND**}\n", stdout);
- iter->ext_target = FALSE;
+ iter->symlink_target = FALSE;
}
else
display_obj_name(stdout, iter, oname, "**NOT FOUND**");
@@ -2020,7 +2163,7 @@ visit_obj(hid_t file, const char *oname, iter_t *iter)
/* Check for group iteration */
if(H5O_TYPE_GROUP == oi.type && !grp_literal_g) {
/* Get ID for group */
- if(!iter->ext_target && (iter->gid = H5Gopen2(file, oname, H5P_DEFAULT)) < 0) {
+ if(!iter->symlink_target && (iter->gid = H5Gopen2(file, oname, H5P_DEFAULT)) < 0) {
fprintf(stderr, "%s: unable to open '%s' as group\n", iter->fname, oname);
return 0; /* Previously "continue", when this code was in main().
* We don't "continue" here in order to close the file
@@ -2032,10 +2175,10 @@ visit_obj(hid_t file, const char *oname, iter_t *iter)
iter->name_start = iter->base_len;
/* Specified name is a group. List the complete contents of the group. */
- h5trav_visit(file, oname, (hbool_t) (display_root_g || iter->ext_target), recursive_g, list_obj, list_lnk, iter);
+ h5trav_visit(file, oname, (hbool_t) (display_root_g || iter->symlink_target), recursive_g, list_obj, list_lnk, iter);
/* Close group */
- if(!iter->ext_target)
+ if(!iter->symlink_target)
H5Gclose(iter->gid);
} /* end if */
else {
@@ -2182,6 +2325,9 @@ main(int argc, const char *argv[])
const char *preferred_driver = NULL;
int err_openfile = 0;
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
/* Initialize h5tools lib */
h5tools_init();
@@ -2208,6 +2354,8 @@ main(int argc, const char *argv[])
data_g = TRUE;
} else if(!HDstrcmp(argv[argno], "--errors")) {
show_errors_g = TRUE;
+ } else if(!HDstrcmp(argv[argno], "--follow-symlinks")) {
+ follow_symlink_g = TRUE;
} else if(!HDstrcmp(argv[argno], "--external")) {
follow_elink_g = TRUE;
} else if(!HDstrcmp(argv[argno], "--full")) {
@@ -2249,7 +2397,7 @@ main(int argc, const char *argv[])
} else if(!HDstrcmp(argv[argno], "--verbose")) {
verbose_g++;
} else if(!HDstrcmp(argv[argno], "--version")) {
- print_version(progname);
+ print_version(h5tools_getprogname());
leave(EXIT_SUCCESS);
} else if(!HDstrcmp(argv[argno], "--hexdump")) {
hexdump_g = TRUE;
@@ -2325,7 +2473,7 @@ main(int argc, const char *argv[])
break;
case 'V': /* --version */
- print_version(progname);
+ print_version(h5tools_getprogname());
leave(EXIT_SUCCESS);
case 'x': /* --hexdump */
@@ -2378,7 +2526,7 @@ main(int argc, const char *argv[])
while(argno < argc) {
H5L_info_t li;
iter_t iter;
- elink_trav_t elink_list;
+ symlink_trav_t symlink_list;
size_t u;
fname = HDstrdup(argv[argno++]);
@@ -2440,12 +2588,12 @@ main(int argc, const char *argv[])
iter.fname = fname;
iter.fid = file;
iter.gid = -1;
- iter.ext_target = FALSE;
- iter.elink_list = &elink_list;
+ iter.symlink_target = FALSE;
+ iter.symlink_list = &symlink_list;
- /* Initialize list of visited external links */
- elink_list.nused = elink_list.nalloc = 0;
- elink_list.objs = NULL;
+ /* Initialize list of visited symbolic links */
+ symlink_list.nused = symlink_list.nalloc = 0;
+ symlink_list.objs = NULL;
/* Check for root group as object name */
if(HDstrcmp(oname, root_name)) {
@@ -2474,11 +2622,14 @@ main(int argc, const char *argv[])
if(x)
HDfree(oname);
- for(u=0; u < elink_list.nused; u++) {
- HDfree(elink_list.objs[u].file);
- HDfree(elink_list.objs[u].path);
+ for(u=0; u < symlink_list.nused; u++)
+ {
+ if (symlink_list.objs[u].type == H5L_TYPE_EXTERNAL)
+ HDfree(symlink_list.objs[u].file);
+
+ HDfree(symlink_list.objs[u].path);
}
- HDfree(elink_list.objs);
+ HDfree(symlink_list.objs);
} /* end while */
if (err_openfile)
diff --git a/tools/h5ls/testh5ls.sh.in b/tools/h5ls/testh5ls.sh.in
index 5c81b6d..2f681ac 100644
--- a/tools/h5ls/testh5ls.sh.in
+++ b/tools/h5ls/testh5ls.sh.in
@@ -15,6 +15,10 @@
#
# Tests for the h5ls tool
+TESTNAME=h5ls
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
H5LS=h5ls # The tool name
H5LS_BIN=`pwd`/$H5LS # The path of the tool binary
@@ -26,6 +30,7 @@ WORDS_BIGENDIAN="@WORDS_BIGENDIAN@"
nerrors=0
verbose=yes
+h5haveexitcode=yes # default is yes
# The build (current) directory might be different than the source directory.
if test -z "$srcdir"; then
@@ -33,6 +38,13 @@ if test -z "$srcdir"; then
fi
test -d ../testfiles || mkdir ../testfiles
+# RUNSERIAL is used. Check if it can return exit code from executalbe correctly.
+if [ -n "$RUNSERIAL_NOEXITCODE" ]; then
+ echo "***Warning*** Serial Exit Code is not passed back to shell corretly."
+ echo "***Warning*** Exit code checking is skipped."
+ h5haveexitcode=no
+fi
+
# Print a line-line message left justified in a field of 70 characters
# beginning with the word "Testing".
TESTING() {
@@ -70,7 +82,7 @@ TOOLTEST() {
exitcode=$?
cat $actual_err >> $actual
- if [ $exitcode -ne $retvalexpect ]; then
+ if [ $h5haveexitcode = 'yes' -a $exitcode -ne $retvalexpect ]; then
echo "*FAILED*"
nerrors="`expr $nerrors + 1`"
if [ yes = "$verbose" ]; then
@@ -129,17 +141,32 @@ TOOLTEST tdset-1.ls 0 -w80 -r -d tdset.h5
# test for displaying soft links
TOOLTEST tslink-1.ls 0 -w80 -r tslink.h5
-# test for displaying external and user-defined links
+# test for displaying more soft links with --follow-symlinks
+TOOLTEST tsoftlinks-1.ls 0 --follow-symlinks tsoftlinks.h5
+TOOLTEST tsoftlinks-2.ls 0 --follow-symlinks -r tsoftlinks.h5
+TOOLTEST tsoftlinks-3.ls 0 --follow-symlinks tsoftlinks.h5/group1
+TOOLTEST tsoftlinks-4.ls 0 --follow-symlinks -r tsoftlinks.h5/group1
+TOOLTEST tsoftlinks-5.ls 0 --follow-symlinks tsoftlinks.h5/soft_dset1
+
+# test for displaying external and user-defined links with --follow-symlinks
TOOLTEST textlink-1.ls 0 -w80 -r textlink.h5
-TOOLTEST textlinksrc-1.ls 0 -w80 -Er textlinksrc.h5
-TOOLTEST textlinksrc-2.ls 0 -w80 -Erv textlinksrc.h5/ext_link5
-TOOLTEST textlinksrc-3.ls 0 -w80 -Er textlinksrc.h5/ext_link1
+TOOLTEST textlinksrc-1.ls 0 -w80 --follow-symlinks -r textlinksrc.h5
+TOOLTEST textlinksrc-2.ls 0 -w80 --follow-symlinks -rv textlinksrc.h5/ext_link5
+TOOLTEST textlinksrc-3.ls 0 -w80 --follow-symlinks -r textlinksrc.h5/ext_link1
TOOLTEST textlinksrc-4.ls 0 -w80 -r textlinksrc.h5
TOOLTEST textlinksrc-5.ls 0 -w80 -r textlinksrc.h5/ext_link1
-TOOLTEST textlinksrc-6.ls 0 -w80 -E textlinksrc.h5
-TOOLTEST textlinksrc-7.ls 0 -w80 -E textlinksrc.h5/ext_link1
+TOOLTEST textlinksrc-6.ls 0 -w80 --follow-symlinks textlinksrc.h5
+TOOLTEST textlinksrc-7.ls 0 -w80 --follow-symlinks textlinksrc.h5/ext_link1
TOOLTEST tudlink-1.ls 0 -w80 -r tudlink.h5
+# test for displaying external links with -E
+# the option -E will be depriciated but keep it for backward compatibility
+TOOLTEST textlinksrc-1-old.ls 0 -w80 -Er textlinksrc.h5
+TOOLTEST textlinksrc-2-old.ls 0 -w80 -Erv textlinksrc.h5/ext_link5
+TOOLTEST textlinksrc-3-old.ls 0 -w80 -Er textlinksrc.h5/ext_link1
+TOOLTEST textlinksrc-6-old.ls 0 -w80 -E textlinksrc.h5
+TOOLTEST textlinksrc-7-old.ls 0 -w80 -E textlinksrc.h5/ext_link1
+
# tests for hard links
TOOLTEST thlink-1.ls 0 -w80 thlink.h5
@@ -194,7 +221,9 @@ fi
TOOLTEST tdset_idx.ls 0 -w80 -d tdset_idx.h5
if test $nerrors -eq 0 ; then
- echo "All h5ls tests passed."
+ echo "All $TESTNAME tests passed."
+ exit $EXIT_SUCCESS
+else
+ echo "$TESTNAME tests failed with $nerrors errors."
+ exit $EXIT_FAILURE
fi
-
-exit $nerrors