summaryrefslogtreecommitdiffstats
path: root/tools/src/h5dump/h5dump_ddl.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/src/h5dump/h5dump_ddl.c')
-rw-r--r--tools/src/h5dump/h5dump_ddl.c2178
1 files changed, 2178 insertions, 0 deletions
diff --git a/tools/src/h5dump/h5dump_ddl.c b/tools/src/h5dump/h5dump_ddl.c
new file mode 100644
index 0000000..182d570
--- /dev/null
+++ b/tools/src/h5dump/h5dump_ddl.c
@@ -0,0 +1,2178 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_dump.h"
+#include "h5tools_utils.h"
+#include "h5tools_ref.h"
+#include "h5trav.h"
+#include "h5dump_extern.h"
+#include "h5dump_ddl.h"
+
+typedef struct {
+ hid_t fid; /* File ID being traversed */
+ const char *op_name; /* Object name wanted */
+} trav_handle_udata_t;
+
+typedef struct {
+ const char *path; /* Path of object being searched */
+ const char *op_name; /* Object name wanted */
+} trav_attr_udata_t;
+
+/* callback function used by H5Literate() */
+static herr_t dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void *op_data);
+static int dump_extlink(hid_t group, const char *linkname, const char *objname);
+
+/*-------------------------------------------------------------------------
+ * Function: dump_datatype
+ *
+ * Purpose: Dump the datatype. Datatype can be HDF5 predefined
+ * atomic datatype or committed/transient datatype.
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_datatype(hid_t type)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ h5dump_type_table = type_table;
+ h5tools_dump_datatype(rawoutstream, outputformat, &ctx, type);
+ h5dump_type_table = NULL;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_dataspace
+ *
+ * Purpose: Dump the dataspace. Dataspace can be named dataspace,
+ * array, or others.
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_dataspace(hid_t space)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ h5tools_dump_dataspace(rawoutstream, outputformat, &ctx, space);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_attr_cb
+ *
+ * Purpose: attribute function callback called by H5Aiterate2, displays the attribute
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications: Pedro Vicente, October 4, 2007
+ * Added H5A_info_t parameter to conform with H5Aiterate2
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+dump_attr_cb(hid_t oid, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *info, void H5_ATTR_UNUSED *_op_data)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+
+ hid_t attr_id;
+ herr_t ret = SUCCEED;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ attr_id = H5Aopen(oid, attr_name, H5P_DEFAULT);
+ oid_output = display_oid;
+ data_output = display_data;
+ attr_data_output = display_attr_data;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ h5dump_type_table = type_table;
+ h5tools_dump_attribute(rawoutstream, outputformat, &ctx, attr_name, attr_id, display_ai, display_char);
+ h5dump_type_table = NULL;
+
+ if(attr_id < 0) {
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+
+ return ret;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_all_cb
+ *
+ * Purpose: function callback called by H5Literate,
+ * displays everything in the specified object
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ * RMcG, November 2000
+ * Added XML support. Also, optionally checks the op_data argument
+ *
+ * PVN, May 2008
+ * Dump external links
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void H5_ATTR_UNUSED *op_data)
+{
+ hid_t obj;
+ hid_t dapl_id = H5P_DEFAULT; /* dataset access property list ID */
+ herr_t ret = SUCCEED;
+ char *obj_path = NULL; /* Full path of object */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ /* Build the object's path name */
+ obj_path = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2);
+ if(!obj_path) {
+ ret = FAIL;
+ goto done;
+ }
+
+ HDstrcpy(obj_path, prefix);
+ HDstrcat(obj_path, "/");
+ HDstrcat(obj_path, name);
+
+ if(linfo->type == H5L_TYPE_HARD) {
+ H5O_info_t oinfo;
+
+ /* Stat the object */
+ if(H5Oget_info_by_name(group, name, &oinfo, H5P_DEFAULT) < 0) {
+ error_msg("unable to get object information for \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ goto done;
+ } /* end if */
+
+ switch(oinfo.type) {
+ case H5O_TYPE_GROUP:
+ if((obj = H5Gopen2(group, name, H5P_DEFAULT)) < 0) {
+ error_msg("unable to dump group \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ char *old_prefix; /* Pointer to previous prefix */
+
+ /* Keep copy of prefix before iterating into group */
+ old_prefix = HDstrdup(prefix);
+ HDassert(old_prefix);
+
+ /* Append group name to prefix */
+ add_prefix(&prefix, &prefix_len, name);
+
+ /* Iterate into group */
+ dump_function_table->dump_group_function(obj, name);
+
+ /* Restore old prefix name */
+ HDstrcpy(prefix, old_prefix);
+ HDfree(old_prefix);
+
+ /* Close group */
+ H5Gclose(obj);
+ }
+ break;
+
+ case H5O_TYPE_DATASET:
+ if(display_data) {
+ if ((dapl_id = H5Pcreate(H5P_DATASET_ACCESS)) < 0) {
+ error_msg("error in creating default access property list ID\n");
+ }
+ if (display_vds_first) {
+ if(H5Pset_virtual_view(dapl_id, H5D_VDS_FIRST_MISSING) < 0)
+ error_msg("error in setting access property list ID, virtual_view\n");
+ }
+ if (vds_gap_size > 0) {
+ if(H5Pset_virtual_printf_gap(dapl_id, (hsize_t)vds_gap_size) < 0)
+ error_msg("error in setting access property list ID, virtual_printf_gap\n");
+ }
+ }
+ if((obj = H5Dopen2(group, name, dapl_id)) >= 0) {
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(dset_table, oinfo.addr);
+
+ if(found_obj == NULL) {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->datasetbegin, name,
+ h5tools_dump_header_format->datasetblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->datasetblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend);
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ H5Dclose(obj);
+ goto done;
+ }
+ else if(found_obj->displayed) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->datasetbegin, name,
+ h5tools_dump_header_format->datasetblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\"", HARDLINK, found_obj->objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->datasetblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend);
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ H5Dclose(obj);
+ goto done;
+ }
+ else {
+ found_obj->displayed = TRUE;
+ }
+ } /* end if */
+
+ dump_function_table->dump_dataset_function(obj, name, NULL);
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ H5Dclose(obj);
+ }
+ else {
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ error_msg("unable to dump dataset \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ if((obj = H5Topen2(group, name, H5P_DEFAULT)) < 0) {
+ error_msg("unable to dump datatype \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ dump_function_table->dump_named_datatype_function(obj, name);
+ H5Tclose(obj);
+ }
+ break;
+
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ error_msg("unknown object \"%s\"\n", name);
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ } /* end if */
+ else {
+ char *targbuf;
+
+ switch(linfo->type) {
+ case H5L_TYPE_SOFT:
+ targbuf = (char *)HDmalloc(linfo->u.val_size);
+ HDassert(targbuf);
+
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->softlinkbegin, name,
+ h5tools_dump_header_format->softlinkblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+
+ if(H5Lget_val(group, name, targbuf, linfo->u.val_size, H5P_DEFAULT) < 0) {
+ error_msg("unable to get link value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ /* print the value of a soft link */
+ /* Standard DDL: no modification */
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "LINKTARGET \"%s\"", targbuf);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->softlinkblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->softlinkblockend);
+ if(HDstrlen(h5tools_dump_header_format->softlinkend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->softlinkend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->softlinkend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(targbuf);
+ break;
+
+ case H5L_TYPE_EXTERNAL:
+ targbuf = (char *)HDmalloc(linfo->u.val_size);
+ HDassert(targbuf);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->extlinkbegin, name,
+ h5tools_dump_header_format->extlinkblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ if(H5Lget_val(group, name, targbuf, linfo->u.val_size, H5P_DEFAULT) < 0) {
+ indentation(dump_indent);
+ error_msg("unable to get external link value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ } /* end if */
+ else {
+ const char *filename;
+ const char *targname;
+
+ if(H5Lunpack_elink_val(targbuf, linfo->u.val_size, NULL, &filename, &targname) < 0) {
+ indentation(dump_indent);
+ error_msg("unable to unpack external link value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ } /* end if */
+ else {
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "TARGETFILE \"%s\"", filename);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "TARGETPATH \"%s\"", targname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* dump the external link */
+ dump_extlink(group, name, targname);
+ ctx.indent_level--;
+ } /* end else */
+ } /* end else */
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->extlinkblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->extlinkblockend);
+ if(HDstrlen(h5tools_dump_header_format->extlinkend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->extlinkend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->extlinkend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ HDfree(targbuf);
+ break;
+
+ case H5L_TYPE_ERROR:
+ case H5L_TYPE_MAX:
+ HDassert(0);
+ /* fall through */
+ case H5L_TYPE_HARD:
+ default:
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->udlinkbegin, name,
+ h5tools_dump_header_format->udlinkblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "LINKCLASS %d", linfo->type);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->udlinkblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->udlinkblockend);
+ if(HDstrlen(h5tools_dump_header_format->udlinkend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->udlinkend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->udlinkend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ break;
+ } /* end switch */
+ } /* end else */
+
+done:
+
+ h5tools_str_close(&buffer);
+
+ if(obj_path)
+ HDfree(obj_path);
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: attr_iteration
+ *
+ * Purpose: Iterate and display attributes within the specified group
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+attr_iteration(hid_t gid, unsigned attr_crt_order_flags)
+{
+ /* attribute iteration: if there is a request to do H5_INDEX_CRT_ORDER and tracking order is set
+ in the group for attributes, then, sort by creation order, otherwise by name */
+ if(include_attrs) {
+ if((sort_by == H5_INDEX_CRT_ORDER) && (attr_crt_order_flags & H5P_CRT_ORDER_TRACKED)) {
+ if(H5Aiterate2(gid, sort_by, sort_order, NULL, dump_attr_cb, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end if */
+ else {
+ if(H5Aiterate2(gid, H5_INDEX_NAME, sort_order, NULL, dump_attr_cb, NULL) < 0) {
+ error_msg("error getting attribute information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end if */
+ } /* end else */
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: link_iteration
+ *
+ * Purpose: Iterate and display links within the specified group
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+link_iteration(hid_t gid, unsigned crt_order_flags)
+{
+
+ /* if there is a request to do H5_INDEX_CRT_ORDER and tracking order is set
+ in the group, then, sort by creation order, otherwise by name */
+ if((sort_by == H5_INDEX_CRT_ORDER) && (crt_order_flags & H5P_CRT_ORDER_TRACKED))
+ H5Literate(gid, sort_by, sort_order, NULL, dump_all_cb, NULL);
+ else
+ H5Literate(gid, H5_INDEX_NAME, sort_order, NULL, dump_all_cb, NULL);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_named_datatype
+ *
+ * Purpose: Dump named datatype
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ * Pedro Vicente, March 27, 2006
+ * added display of attributes
+ * Pedro Vicente, October 4, 2007, added parameters to H5Aiterate2() to allow for
+ * other iteration orders
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_named_datatype(hid_t tid, const char *name)
+{
+ H5O_info_t oinfo;
+ unsigned attr_crt_order_flags;
+ hid_t tcpl_id = -1; /* datatype creation property list ID */
+ hsize_t curr_pos = 0; /* total data element position */
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ if ((tcpl_id = H5Tget_create_plist(tid)) < 0) {
+ error_msg("error in getting creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the creation properties for attributes */
+ if (H5Pget_attr_creation_order(tcpl_id, &attr_crt_order_flags) < 0) {
+ error_msg("error in getting creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ if(H5Pclose(tcpl_id) < 0) {
+ error_msg("error in closing creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->datatypebegin, name,
+ h5tools_dump_header_format->datatypeblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ H5Oget_info(tid, &oinfo);
+
+ /* Must check for uniqueness of all objects if we've traversed an elink,
+ * otherwise only check if the reference count > 1.
+ */
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(type_table, oinfo.addr);
+
+ if (found_obj == NULL) {
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ else if (found_obj->displayed) {
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\"", HARDLINK, found_obj->objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ goto done;
+ }
+ else
+ found_obj->displayed = TRUE;
+ } /* end if */
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_print_datatype(rawoutstream, &buffer, outputformat, &ctx, tid, FALSE);
+
+ if(H5Tget_class(tid) != H5T_COMPOUND) {
+ h5tools_str_append(&buffer, ";");
+ }
+
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ /* print attributes */
+ dump_indent += COL;
+
+ attr_iteration(tid, attr_crt_order_flags);
+
+ dump_indent -= COL;
+
+done:
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->datatypeblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datatypeblockend);
+ if(HDstrlen(h5tools_dump_header_format->datatypeend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->datatypeend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datatypeend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_group
+ *
+ * Purpose: Dump everything within the specified group
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ * Call to dump_all_cb -- add parameter to select everything.
+ *
+ * Pedro Vicente, October 1, 2007
+ * handle several iteration orders for attributes and groups
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_group(hid_t gid, const char *name)
+{
+ H5O_info_t oinfo;
+ hid_t dset;
+ hid_t type;
+ hid_t gcpl_id;
+ unsigned crt_order_flags;
+ unsigned attr_crt_order_flags;
+ char type_name[1024];
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ if ((gcpl_id = H5Gget_create_plist(gid)) < 0) {
+ error_msg("error in getting group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties for attributes */
+ if (H5Pget_attr_creation_order(gcpl_id, &attr_crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties */
+ if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ if(H5Pclose(gcpl_id) < 0) {
+ error_msg("error in closing group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->groupbegin, name,
+ h5tools_dump_header_format->groupblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level++;
+ dump_indent += COL;
+
+ if(!HDstrcmp(name, "/") && unamedtype) {
+ unsigned u; /* Local index variable */
+
+ /* dump unamed type in root group */
+ for(u = 0; u < type_table->nobjs; u++)
+ if(!type_table->objs[u].recorded) {
+ dset = H5Dopen2(gid, type_table->objs[u].objname, H5P_DEFAULT);
+ type = H5Dget_type(dset);
+ sprintf(type_name, "#"H5_PRINTF_HADDR_FMT, type_table->objs[u].objno);
+ dump_function_table->dump_named_datatype_function(type, type_name);
+ H5Tclose(type);
+ H5Dclose(dset);
+ }
+ } /* end if */
+
+ if(display_oid)
+ h5tools_dump_oid(rawoutstream, outputformat, &ctx, gid);
+
+ h5tools_dump_comment(rawoutstream, outputformat, &ctx, gid);
+
+ H5Oget_info(gid, &oinfo);
+
+ /* Must check for uniqueness of all objects if we've traversed an elink,
+ * otherwise only check if the reference count > 1.
+ */
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(group_table, oinfo.addr);
+
+ if (found_obj == NULL) {
+ error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else if (found_obj->displayed) {
+ ctx.need_prefix = TRUE;
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\"", HARDLINK, found_obj->objname);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ else {
+ found_obj->displayed = TRUE;
+ attr_iteration(gid, attr_crt_order_flags);
+ link_iteration(gid, crt_order_flags);
+ }
+ }
+ else {
+ attr_iteration(gid, attr_crt_order_flags);
+ link_iteration(gid, crt_order_flags);
+ }
+
+ dump_indent -= COL;
+ ctx.indent_level--;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->groupblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->groupblockend);
+ if(HDstrlen(h5tools_dump_header_format->groupend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->groupend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->groupend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_dataset
+ *
+ * Purpose: Dump the specified data set
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ * Pedro Vicente, 2004, added dataset creation property list display
+ * Pedro Vicente, October 4, 2007, added parameters to H5Aiterate2() to allow for
+ * other iteration orders
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_dataset(hid_t did, const char *name, struct subset_t *sset)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ hid_t type, space;
+ unsigned attr_crt_order_flags;
+ hid_t dcpl_id; /* dataset creation property list ID */
+ h5tools_str_t buffer; /* string into which to render */
+ hsize_t curr_pos = 0; /* total data element position */
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ if ((dcpl_id = H5Dget_create_plist(did)) < 0) {
+ error_msg("error in getting creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the creation properties for attributes */
+ if (H5Pget_attr_creation_order(dcpl_id, &attr_crt_order_flags) < 0) {
+ error_msg("error in getting creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->datasetbegin, name,
+ h5tools_dump_header_format->datasetblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_dump_comment(rawoutstream, outputformat, &ctx, did);
+
+ dump_indent += COL;
+ ctx.indent_level++;
+
+ type = H5Dget_type(did);
+ h5dump_type_table = type_table;
+ h5tools_dump_datatype(rawoutstream, outputformat, &ctx, type);
+ h5dump_type_table = NULL;
+
+ space = H5Dget_space(did);
+ h5tools_dump_dataspace(rawoutstream, outputformat, &ctx, space);
+ H5Sclose(space);
+
+ if(display_oid) {
+ h5tools_dump_oid(rawoutstream, outputformat, &ctx, did);
+ }
+
+ if(display_dcpl) {
+ h5dump_type_table = type_table;
+ h5tools_dump_dcpl(rawoutstream, outputformat, &ctx, dcpl_id, type, did);
+ h5dump_type_table = NULL;
+ }
+ H5Pclose(dcpl_id);
+
+ if(display_data) {
+ unsigned data_loop = 1;
+ unsigned u;
+
+ if(display_packed_bits)
+ data_loop = packed_bits_num;
+ for(u = 0; u < data_loop; u++) {
+ if(display_packed_bits) {
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ packed_data_mask = packed_mask[u];
+ packed_data_offset = packed_offset[u];
+ packed_data_length = packed_length[u];
+ h5tools_print_packed_bits(&buffer, type);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+ }
+ switch(H5Tget_class(type)) {
+ case H5T_TIME:
+ ctx.indent_level++;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "DATA{ not yet implemented.}");
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ ctx.indent_level--;
+ break;
+
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_COMPOUND:
+ case H5T_REFERENCE:
+ case H5T_ENUM:
+ case H5T_VLEN:
+ case H5T_ARRAY:
+ {
+ h5tools_dump_data(rawoutstream, outputformat, &ctx, did, TRUE, sset, display_ai, display_char);
+ }
+ break;
+
+ case H5T_NO_CLASS:
+ case H5T_NCLASSES:
+ default:
+ HDassert(0);
+ break;
+ } /* end switch */
+ } /* for(u=0; u<data_loop; u++) */
+ }
+ H5Tclose(type);
+
+ if (!bin_output) {
+ attr_iteration(did, attr_crt_order_flags);
+ }
+ ctx.indent_level--;
+ dump_indent -= COL;
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->datasetblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend);
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->datasetend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_data
+ *
+ * Purpose: Dump attribute or dataset data
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications: pvn, print the matrix indices
+ * Albert Cheng, 2004/11/18
+ * Add --string printing for attributes too.
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_data(hid_t obj_id, int obj_data, struct subset_t *sset, int display_index)
+{
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ int print_dataset = FALSE;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ if(obj_data == DATASET_DATA)
+ print_dataset = TRUE;
+ h5tools_dump_data(rawoutstream, outputformat, &ctx, obj_id, print_dataset, sset, display_index, display_char);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_fcpl
+ *
+ * Purpose: prints file creation property list information
+ *
+ * Return: void
+ *
+ * Programmer: pvn
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_fcpl(hid_t fid)
+{
+ hid_t fcpl; /* file creation property list ID */
+ hsize_t userblock; /* userblock size retrieved from FCPL */
+ size_t off_size; /* size of offsets in the file */
+ size_t len_size; /* size of lengths in the file */
+ H5F_file_space_type_t fs_strategy; /* file space strategy */
+ hsize_t fs_threshold; /* free-space section threshold */
+ H5F_info2_t finfo; /* file information */
+#ifdef SHOW_FILE_DRIVER
+ hid_t fapl; /* file access property list ID */
+ hid_t fdriver; /* file driver */
+ char dname[32]; /* buffer to store driver name */
+#endif
+ unsigned sym_lk; /* symbol table B-tree leaf 'K' value */
+ unsigned sym_ik; /* symbol table B-tree internal 'K' value */
+ unsigned istore_ik; /* indexed storage B-tree internal 'K' value */
+
+ fcpl=H5Fget_create_plist(fid);
+ H5Fget_info2(fid, &finfo);
+ H5Pget_userblock(fcpl,&userblock);
+ H5Pget_sizes(fcpl,&off_size,&len_size);
+ H5Pget_sym_k(fcpl,&sym_ik,&sym_lk);
+ H5Pget_istore_k(fcpl,&istore_ik);
+ H5Pget_file_space(fcpl, &fs_strategy, &fs_threshold);
+ H5Pclose(fcpl);
+#ifdef SHOW_FILE_DRIVER
+ fapl=h5_fileaccess();
+ fdriver=H5Pget_driver(fapl);
+ H5Pclose(fapl);
+#endif
+
+ /*-------------------------------------------------------------------------
+ * SUPER_BLOCK
+ *-------------------------------------------------------------------------
+ */
+ PRINTSTREAM(rawoutstream, "\n%s %s\n",SUPER_BLOCK, BEGIN);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","SUPERBLOCK_VERSION", finfo.super.version);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","FREELIST_VERSION", finfo.free.version);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","SYMBOLTABLE_VERSION", 0); /* Retain this for backward compatibility, for now (QAK) */
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","OBJECTHEADER_VERSION", finfo.sohm.version);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream,"%s %zu\n","OFFSET_SIZE", off_size);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream,"%s %zu\n","LENGTH_SIZE", len_size);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","BTREE_RANK", sym_ik);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %d\n","BTREE_LEAF", sym_lk);
+
+#ifdef SHOW_FILE_DRIVER
+ if(H5FD_CORE==fdriver)
+ HDstrcpy(dname,"H5FD_CORE");
+#ifdef H5_HAVE_DIRECT
+ else if(H5FD_DIRECT==fdriver)
+ HDstrcpy(dname,"H5FD_DIRECT");
+#endif
+ else if(H5FD_FAMILY==fdriver)
+ HDstrcpy(dname,"H5FD_FAMILY");
+ else if(H5FD_LOG==fdriver)
+ HDstrcpy(dname,"H5FD_LOG");
+ else if(H5FD_MPIO==fdriver)
+ HDstrcpy(dname,"H5FD_MPIO");
+ else if(H5FD_MULTI==fdriver)
+ HDstrcpy(dname,"H5FD_MULTI");
+ else if(H5FD_SEC2==fdriver)
+ HDstrcpy(dname,"H5FD_SEC2");
+ else if(H5FD_STDIO==fdriver)
+ HDstrcpy(dname,"H5FD_STDIO");
+ else
+ HDstrcpy(dname,"Unknown driver");
+
+ /* Take out this because the driver used can be different from the
+ * standard output. */
+ /*indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %s\n","FILE_DRIVER", dname);*/
+#endif
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %u\n","ISTORE_K", istore_ik);
+
+ indentation(dump_indent + COL);
+ if(fs_strategy == H5F_FILE_SPACE_ALL_PERSIST) {
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_ALL_PERSIST");
+ } else if(fs_strategy == H5F_FILE_SPACE_ALL) {
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_ALL");
+ } else if(fs_strategy == H5F_FILE_SPACE_AGGR_VFD) {
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_AGGR_VFD");
+ } else if(fs_strategy == H5F_FILE_SPACE_VFD) {
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_VFD");
+ } else
+ PRINTSTREAM(rawoutstream, "%s %s\n", "FILE_SPACE_STRATEGY", "Unknown strategy");
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s %Hu\n","FREE_SPACE_THRESHOLD", fs_threshold);
+
+ /*-------------------------------------------------------------------------
+ * USER_BLOCK
+ *-------------------------------------------------------------------------
+ */
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "USER_BLOCK %s\n",BEGIN);
+ indentation(dump_indent + COL + COL);
+ PRINTSTREAM(rawoutstream,"%s %Hu\n","USERBLOCK_SIZE", userblock);
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s\n",END);
+
+ PRINTSTREAM(rawoutstream, "%s",END);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_fcontents
+ *
+ * Purpose: prints all objects
+ *
+ * Return: void
+ *
+ * Programmer: pvn
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_fcontents(hid_t fid)
+{
+ PRINTSTREAM(rawoutstream, "%s %s\n",FILE_CONTENTS, BEGIN);
+
+ /* special case of unamed types in root group */
+ if (unamedtype) {
+ unsigned u;
+
+ for (u = 0; u < type_table->nobjs; u++) {
+ if (!type_table->objs[u].recorded)
+ PRINTSTREAM(rawoutstream, " %-10s /#"H5_PRINTF_HADDR_FMT"\n", "datatype", type_table->objs[u].objno);
+ }
+ }
+
+ /* print objects in the files */
+ h5trav_print(fid);
+
+ PRINTSTREAM(rawoutstream, " %s\n",END);
+}
+
+static herr_t
+attr_search(hid_t oid, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *ainfo, void *_op_data)
+{
+ herr_t ret = SUCCEED;
+ int j;
+ char *obj_op_name;
+ char *obj_name;
+ trav_attr_udata_t *attr_data = (trav_attr_udata_t*)_op_data;
+ const char *buf = attr_data->path;
+ const char *op_name = attr_data->op_name;
+
+ j = (int)HDstrlen(op_name) - 1;
+ /* find the last / */
+ while(j >= 0) {
+ if(op_name[j] == '/' && (j == 0 || (j > 0 && op_name[j - 1] != '\\')))
+ break;
+ j--;
+ }
+
+ obj_op_name = h5tools_str_replace(op_name + j + 1, "\\/", "/");
+
+ if(obj_op_name == NULL) {
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ if(HDstrcmp(attr_name, obj_op_name)==0) {
+ size_t u, v, w;
+
+ /* object name */
+ u = HDstrlen(buf);
+ v = HDstrlen(op_name);
+ w = u + 1 + v + 1 + 2;
+ obj_name = (char *)HDmalloc(w);
+ if(obj_name == NULL) {
+ h5tools_setstatus(EXIT_FAILURE);
+ ret = FAIL;
+ }
+ else {
+ HDmemset(obj_name, '\0', w);
+ if(op_name[0] != '/') {
+ HDstrncat(obj_name, buf, u + 1);
+ if(buf[u - 1] != '/')
+ HDstrncat(obj_name, "/", (size_t)2);
+ }
+ HDstrncat(obj_name, op_name, v + 1);
+
+ handle_attributes(oid, obj_name, NULL, 0, NULL);
+ HDfree(obj_name);
+ }
+ }
+ HDfree(obj_op_name);
+ }
+ return ret;
+} /* end attr_search() */
+
+static herr_t
+obj_search(const char *path, const H5O_info_t *oi, const char H5_ATTR_UNUSED *already_visited, void *_op_data)
+{
+ trav_handle_udata_t *handle_data = (trav_handle_udata_t*)_op_data;
+ const char *op_name = handle_data->op_name;
+ trav_attr_udata_t attr_data;
+
+ attr_data.path = path;
+ attr_data.op_name = op_name;
+ H5Aiterate_by_name(handle_data->fid, path, H5_INDEX_NAME, H5_ITER_INC, NULL, attr_search, (void*)&attr_data, H5P_DEFAULT);
+
+ if(HDstrcmp(path, op_name) == 0) {
+ switch(oi->type) {
+ case H5O_TYPE_GROUP:
+ handle_groups(handle_data->fid, path, NULL, 0, NULL);
+ break;
+
+ case H5O_TYPE_DATASET:
+ handle_datasets(handle_data->fid, path, NULL, 0, NULL);
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ handle_datatypes(handle_data->fid, path, NULL, 0, NULL);
+ break;
+
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ error_msg("unknown object type value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end switch */
+ }
+
+ return 0;
+} /* end obj_search() */
+
+static herr_t
+lnk_search(const char *path, const H5L_info_t *li, void *_op_data)
+{
+ size_t search_len;
+ size_t k;
+ char *search_name;
+ trav_handle_udata_t *handle_data = (trav_handle_udata_t*)_op_data;
+ const char *op_name = handle_data->op_name;
+
+ search_len = HDstrlen(op_name);
+ if(search_len > 0 && op_name[0] != '/')
+ k = 2;
+ else
+ k = 1;
+ search_name = (char *)HDmalloc(search_len + k);
+ if(search_name == NULL) {
+ error_msg("creating temporary link\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ if (k == 2) {
+ HDstrcpy(search_name, "/");
+ HDstrncat(search_name, op_name, search_len + 1);
+ }
+ else
+ HDstrncpy(search_name, op_name, search_len + 1);
+ search_name[search_len + k - 1] = '\0';
+
+ if(HDstrcmp(path, search_name) == 0) {
+ switch(li->type) {
+ case H5L_TYPE_SOFT:
+ case H5L_TYPE_EXTERNAL:
+ handle_links(handle_data->fid, op_name, NULL, 0, NULL);
+ break;
+
+ case H5L_TYPE_HARD:
+ case H5L_TYPE_MAX:
+ case H5L_TYPE_ERROR:
+ default:
+ error_msg("unknown link type value\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ break;
+ } /* end switch() */
+ }
+ HDfree(search_name);
+ }
+ return 0;
+} /* end lnk_search() */
+
+/*-------------------------------------------------------------------------
+ * Function: handle_paths
+ *
+ * Purpose: Handle objects from the command.
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_paths(hid_t fid, const char *path_name, void H5_ATTR_UNUSED * data, int H5_ATTR_UNUSED pe, const char H5_ATTR_UNUSED *display_name)
+{
+ hid_t gid = -1;
+
+ if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) {
+ error_msg("unable to open root group\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ hid_t gcpl_id;
+ unsigned crt_order_flags;
+ unsigned attr_crt_order_flags;
+ trav_handle_udata_t handle_udata; /* User data for traversal */
+
+ if ((gcpl_id = H5Gget_create_plist(gid)) < 0) {
+ error_msg("error in getting group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties for attributes */
+ if (H5Pget_attr_creation_order(gcpl_id, &attr_crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ /* query the group creation properties */
+ if(H5Pget_link_creation_order(gcpl_id, &crt_order_flags) < 0) {
+ error_msg("error in getting group creation properties\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ if(H5Pclose(gcpl_id) < 0) {
+ error_msg("error in closing group creation property list ID\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ handle_udata.fid = fid;
+ handle_udata.op_name = path_name;
+ if(h5trav_visit(fid, "/", TRUE, TRUE, obj_search, lnk_search, &handle_udata) < 0) {
+ error_msg("error traversing information\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: handle_attributes
+ *
+ * Purpose: Handle the attributes from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications:
+ *
+ * PVN, May 2008
+ * add an extra parameter PE, to allow printing/not printing of error messages
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_attributes(hid_t fid, const char *attr, void H5_ATTR_UNUSED * data, int H5_ATTR_UNUSED pe, const char H5_ATTR_UNUSED *display_name)
+{
+ hid_t oid = -1;
+ hid_t attr_id = -1;
+ char *obj_name = NULL;
+ char *attr_name = NULL;
+ int j;
+ h5tools_str_t buffer; /* string into which to render */
+ h5tools_context_t ctx; /* print context */
+ h5tool_format_t *outputformat = &h5tools_dataformat;
+ h5tool_format_t string_dataformat;
+ hsize_t curr_pos = 0; /* total data element position */
+
+ j = (int)HDstrlen(attr) - 1;
+ obj_name = (char *)HDmalloc((size_t)j + 2);
+ if(obj_name == NULL)
+ goto error;
+
+ /* find the last / */
+ while(j >= 0) {
+ if (attr[j] == '/' && (j==0 || (j>0 && attr[j-1]!='\\')))
+ break;
+ j--;
+ }
+
+ /* object name */
+ if(j == -1)
+ HDstrcpy(obj_name, "/");
+ else {
+ HDstrncpy(obj_name, attr, (size_t)j + 1);
+ obj_name[j + 1] = '\0';
+ } /* end else */
+
+ dump_indent += COL;
+ HDmemset(&ctx, 0, sizeof(ctx));
+ ctx.indent_level = dump_indent / COL;
+ ctx.cur_column = dump_indent;
+
+ string_dataformat = *outputformat;
+
+ if (fp_format) {
+ string_dataformat.fmt_double = fp_format;
+ string_dataformat.fmt_float = fp_format;
+ }
+
+ if (h5tools_nCols == 0) {
+ string_dataformat.line_ncols = 65535;
+ string_dataformat.line_per_line = 1;
+ }
+ else
+ string_dataformat.line_ncols = h5tools_nCols;
+
+ string_dataformat.do_escape = display_escape;
+ outputformat = &string_dataformat;
+
+ attr_name = h5tools_str_replace(attr + j + 1, "\\/", "/");
+
+ /* handle error case: cannot open the object with the attribute */
+ if((oid = H5Oopen(fid, obj_name, H5P_DEFAULT)) < 0) {
+ /* setup */
+ HDmemset(&buffer, 0, sizeof(h5tools_str_t));
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ h5tools_str_append(&buffer, "%s \"%s\" %s",
+ h5tools_dump_header_format->attributebegin, attr,
+ h5tools_dump_header_format->attributeblockbegin);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ error_msg("unable to open object \"%s\"\n", obj_name);
+
+ ctx.need_prefix = TRUE;
+ h5tools_simple_prefix(rawoutstream, outputformat, &ctx, (hsize_t)0, 0);
+ /* Render the element */
+ h5tools_str_reset(&buffer);
+ if(HDstrlen(h5tools_dump_header_format->attributeblockend)) {
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->attributeblockend);
+ if(HDstrlen(h5tools_dump_header_format->attributeend))
+ h5tools_str_append(&buffer, " ");
+ }
+ if(HDstrlen(h5tools_dump_header_format->attributeend))
+ h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->attributeend);
+ h5tools_render_element(rawoutstream, outputformat, &ctx, &buffer, &curr_pos, (size_t)outputformat->line_ncols, (hsize_t)0, (hsize_t)0);
+
+ h5tools_str_close(&buffer);
+
+ goto error;
+ } /* end if */
+
+ attr_id = H5Aopen(oid, attr_name, H5P_DEFAULT);
+ oid_output = display_oid;
+ data_output = display_data;
+ attr_data_output = display_attr_data;
+
+ h5dump_type_table = type_table;
+ h5tools_dump_attribute(rawoutstream, outputformat, &ctx, attr_name, attr_id, display_ai, display_char);
+ h5dump_type_table = NULL;
+
+ if(attr_id < 0) {
+ goto error;
+ }
+
+ /* Close object */
+ if(H5Oclose(oid) < 0) {
+ goto error;
+ } /* end if */
+
+ HDfree(obj_name);
+ HDfree(attr_name);
+ dump_indent -= COL;
+ return;
+
+error:
+ h5tools_setstatus(EXIT_FAILURE);
+ if(obj_name)
+ HDfree(obj_name);
+
+ if (attr_name)
+ HDfree(attr_name);
+
+ H5E_BEGIN_TRY {
+ H5Oclose(oid);
+ H5Aclose(attr_id);
+ } H5E_END_TRY;
+ dump_indent -= COL;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: handle_datasets
+ *
+ * Purpose: Handle the datasets from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications:
+ * Pedro Vicente, Tuesday, January 15, 2008
+ * check for block overlap\
+ *
+ * Pedro Vicente, May 8, 2008
+ * added a flag PE that prints/not prints error messages
+ * added for cases of external links not found, to avoid printing of
+ * objects not found, since external links are dumped on a trial error basis
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_datasets(hid_t fid, const char *dset, void *data, int pe, const char *display_name)
+{
+ H5O_info_t oinfo;
+ hid_t dsetid;
+ hid_t dapl_id = H5P_DEFAULT; /* dataset access property list ID */
+ struct subset_t *sset = (struct subset_t *)data;
+ const char *real_name = display_name ? display_name : dset;
+
+ if(display_data) {
+ if ((dapl_id = H5Pcreate(H5P_DATASET_ACCESS)) < 0) {
+ error_msg("error in creating default access property list ID\n");
+ }
+ if (display_vds_first) {
+ if(H5Pset_virtual_view(dapl_id, H5D_VDS_FIRST_MISSING) < 0)
+ error_msg("error in setting access property list ID, virtual_view\n");
+ }
+ if (vds_gap_size > 0) {
+ if(H5Pset_virtual_printf_gap(dapl_id, (hsize_t)vds_gap_size) < 0)
+ error_msg("error in setting access property list ID, virtual_printf_gap\n");
+ }
+ }
+ if((dsetid = H5Dopen2(fid, dset, dapl_id)) < 0) {
+ if (pe)
+ handle_links(fid, dset, data, pe, display_name);
+ return;
+ } /* end if */
+
+ if(sset) {
+ unsigned int i;
+ unsigned int ndims;
+ hid_t sid = H5Dget_space(dsetid);
+ int ndims_res = H5Sget_simple_extent_ndims(sid);
+
+ H5Sclose(sid);
+ if(ndims_res < 0) {
+ error_msg("H5Sget_simple_extent_ndims failed\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+ ndims = (unsigned)ndims_res;
+
+ if(!sset->start.data || !sset->stride.data || !sset->count.data || !sset->block.data) {
+ /* they didn't specify a ``stride'' or ``block''. default to 1 in all
+ * dimensions */
+ if(!sset->start.data) {
+ /* default to (0, 0, ...) for the start coord */
+ sset->start.data = (hsize_t *)HDcalloc((size_t)ndims, sizeof(hsize_t));
+ sset->start.len = ndims;
+ }
+
+ if(!sset->stride.data) {
+ sset->stride.data = (hsize_t *)HDcalloc((size_t)ndims, sizeof(hsize_t));
+ sset->stride.len = ndims;
+ for (i = 0; i < ndims; i++)
+ sset->stride.data[i] = 1;
+ }
+
+ if(!sset->count.data) {
+ sset->count.data = (hsize_t *)HDcalloc((size_t)ndims, sizeof(hsize_t));
+ sset->count.len = ndims;
+ for (i = 0; i < ndims; i++)
+ sset->count.data[i] = 1;
+ }
+
+ if(!sset->block.data) {
+ sset->block.data = (hsize_t *)HDcalloc((size_t)ndims, sizeof(hsize_t));
+ sset->block.len = ndims;
+ for (i = 0; i < ndims; i++)
+ sset->block.data[i] = 1;
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * check for dimension overflow
+ *-------------------------------------------------------------------------
+ */
+ if(sset->start.len > ndims) {
+ error_msg("number of start dims (%u) exceed dataset dims (%u)\n", sset->start.len, ndims);
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+ if(sset->stride.len > ndims) {
+ error_msg("number of stride dims (%u) exceed dataset dims (%u)\n", sset->stride.len, ndims);
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+ if(sset->count.len > ndims) {
+ error_msg("number of count dims (%u) exceed dataset dims (%u)\n", sset->count.len, ndims);
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+ if(sset->block.len > ndims) {
+ error_msg("number of block dims (%u) exceed dataset dims (%u)\n", sset->block.len, ndims);
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ }
+
+ /*-------------------------------------------------------------------------
+ * check for block overlap
+ *-------------------------------------------------------------------------
+ */
+ for(i = 0; i < ndims; i++) {
+ if(sset->count.data[i] > 1) {
+ if(sset->stride.data[i] < sset->block.data[i]) {
+ error_msg("wrong subset selection; blocks overlap\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ return;
+ } /* end if */
+ } /* end if */
+ } /* end for */
+ } /* end if */
+
+
+ H5Oget_info(dsetid, &oinfo);
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(dset_table, oinfo.addr);
+
+ if(found_obj) {
+ if (found_obj->displayed) {
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(dump_indent);
+ begin_obj(h5tools_dump_header_format->datasetbegin, real_name, h5tools_dump_header_format->datasetblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(dump_indent + COL);
+ PRINTSTREAM(rawoutstream, "%s \"%s\"\n", HARDLINK, found_obj->objname);
+ indentation(dump_indent);
+ end_obj(h5tools_dump_header_format->datasetend, h5tools_dump_header_format->datasetblockend);
+ }
+ else {
+ found_obj->displayed = TRUE;
+ dump_indent += COL;
+ dump_dataset(dsetid, real_name, sset);
+ dump_indent -= COL;
+ }
+ }
+ else
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ dump_indent += COL;
+ dump_dataset(dsetid, real_name, sset);
+ dump_indent -= COL;
+ }
+ if (dapl_id != H5P_DEFAULT)
+ H5Pclose(dapl_id);
+ if(H5Dclose(dsetid) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: handle_groups
+ *
+ * Purpose: Handle the groups from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications: Pedro Vicente, September 26, 2007
+ * handle creation order
+ *
+ * Pedro Vicente, May 8, 2008
+ * added a flag PE that prints/not prints error messages
+ * added for cases of external links not found, to avoid printing of
+ * objects not found, since external links are dumped on a trial error basis
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_groups(hid_t fid, const char *group, void H5_ATTR_UNUSED *data, int pe, const char *display_name)
+{
+ hid_t gid;
+ const char *real_name = display_name ? display_name : group;
+
+ if((gid = H5Gopen2(fid, group, H5P_DEFAULT)) < 0) {
+ if (pe) {
+ PRINTVALSTREAM(rawoutstream, "\n");
+ begin_obj(h5tools_dump_header_format->groupbegin, real_name, h5tools_dump_header_format->groupblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ error_msg("unable to open group \"%s\"\n", real_name);
+ end_obj(h5tools_dump_header_format->groupend, h5tools_dump_header_format->groupblockend);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ }
+ else {
+ size_t new_len = HDstrlen(group) + 1;
+
+ if(prefix_len <= new_len) {
+ prefix_len = new_len;
+ prefix = (char *)HDrealloc(prefix, prefix_len);
+ } /* end if */
+
+ HDstrcpy(prefix, group);
+
+ dump_indent += COL;
+ dump_group(gid, real_name);
+ dump_indent -= COL;
+
+ if(H5Gclose(gid) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+ } /* end else */
+} /* end handle_groups() */
+
+/*-------------------------------------------------------------------------
+ * Function: handle_links
+ *
+ * Purpose: Handle soft or UD links from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_links(hid_t fid, const char *links, void H5_ATTR_UNUSED * data, int H5_ATTR_UNUSED pe, const char H5_ATTR_UNUSED *display_name)
+{
+ H5L_info_t linfo;
+
+ if(H5Lget_info(fid, links, &linfo, H5P_DEFAULT) < 0) {
+ error_msg("unable to get link info from \"%s\"\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else if(linfo.type == H5L_TYPE_HARD) {
+ error_msg("\"%s\" is a hard link\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ else {
+ char *buf = (char *)HDmalloc(linfo.u.val_size);
+ PRINTVALSTREAM(rawoutstream, "\n");
+
+ switch(linfo.type) {
+ case H5L_TYPE_SOFT: /* Soft link */
+ begin_obj(h5tools_dump_header_format->softlinkbegin, links, h5tools_dump_header_format->softlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ if(H5Lget_val(fid, links, buf, linfo.u.val_size, H5P_DEFAULT) >= 0) {
+ PRINTSTREAM(rawoutstream, "LINKTARGET \"%s\"\n", buf);
+ }
+ else {
+ error_msg("h5dump error: unable to get link value for \"%s\"\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ end_obj(h5tools_dump_header_format->softlinkend, h5tools_dump_header_format->softlinkblockend);
+ break;
+
+ case H5L_TYPE_EXTERNAL:
+ begin_obj(h5tools_dump_header_format->udlinkbegin, links, h5tools_dump_header_format->udlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ begin_obj(h5tools_dump_header_format->extlinkbegin, links, h5tools_dump_header_format->extlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ if(H5Lget_val(fid, links, buf, linfo.u.val_size, H5P_DEFAULT) >= 0) {
+ const char *elink_file;
+ const char *elink_path;
+
+ if(H5Lunpack_elink_val(buf, linfo.u.val_size, NULL, &elink_file, &elink_path)>=0) {
+ indentation(COL);
+ PRINTSTREAM(rawoutstream, "LINKCLASS %d\n", linfo.type);
+ indentation(COL);
+ PRINTSTREAM(rawoutstream, "TARGETFILE \"%s\"\n", elink_file);
+ indentation(COL);
+ PRINTSTREAM(rawoutstream, "TARGETPATH \"%s\"\n", elink_path);
+ }
+ else {
+ error_msg("h5dump error: unable to unpack external link value for \"%s\"\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ }
+ else {
+ error_msg("h5dump error: unable to get external link value for \"%s\"\n", links);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ end_obj(h5tools_dump_header_format->extlinkend, h5tools_dump_header_format->extlinkblockend);
+ break;
+
+ case H5L_TYPE_ERROR:
+ case H5L_TYPE_MAX:
+ HDassert(0);
+ /* fall through */
+ case H5L_TYPE_HARD:
+ default:
+ begin_obj(h5tools_dump_header_format->udlinkbegin, links, h5tools_dump_header_format->udlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ begin_obj(h5tools_dump_header_format->udlinkbegin, links, h5tools_dump_header_format->udlinkblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ PRINTSTREAM(rawoutstream, "LINKCLASS %d\n", linfo.type);
+ end_obj(h5tools_dump_header_format->udlinkend, h5tools_dump_header_format->udlinkblockend);
+ break;
+ } /* end switch */
+ HDfree(buf);
+ } /* end else */
+}
+
+/*-------------------------------------------------------------------------
+ * Function: handle_datatypes
+ *
+ * Purpose: Handle the datatypes from the command.
+ *
+ * Return: void
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 9. January 2001
+ *
+ * Modifications:
+ *
+ * Pedro Vicente, May 8, 2008
+ * added a flag PE that prints/not prints error messages
+ * added for cases of external links not found, to avoid printing of
+ * objects not found, since external links are dumped on a trial error basis
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+handle_datatypes(hid_t fid, const char *type, void H5_ATTR_UNUSED * data, int pe, const char *display_name)
+{
+ hid_t type_id;
+ const char *real_name = display_name ? display_name : type;
+
+ if((type_id = H5Topen2(fid, type, H5P_DEFAULT)) < 0) {
+ /* check if type is unamed datatype */
+ unsigned idx = 0;
+
+ while(idx < type_table->nobjs ) {
+ char name[128];
+
+ if(!type_table->objs[idx].recorded) {
+ /* unamed datatype */
+ sprintf(name, "/#"H5_PRINTF_HADDR_FMT, type_table->objs[idx].objno);
+
+ if(!HDstrcmp(name, real_name))
+ break;
+ } /* end if */
+
+ idx++;
+ } /* end while */
+
+ if(idx == type_table->nobjs) {
+ if (pe) {
+ /* unknown type */
+ PRINTVALSTREAM(rawoutstream, "\n");
+ begin_obj(h5tools_dump_header_format->datatypebegin, real_name, h5tools_dump_header_format->datatypeblockbegin);
+ PRINTVALSTREAM(rawoutstream, "\n");
+ indentation(COL);
+ error_msg("unable to open datatype \"%s\"\n", real_name);
+ end_obj(h5tools_dump_header_format->datatypeend, h5tools_dump_header_format->datatypeblockend);
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+ }
+ else {
+ hid_t dsetid = H5Dopen2(fid, type_table->objs[idx].objname, H5P_DEFAULT);
+ type_id = H5Dget_type(dsetid);
+
+ dump_indent += COL;
+ dump_named_datatype(type_id, real_name);
+ dump_indent -= COL;
+
+ H5Tclose(type_id);
+ H5Dclose(dsetid);
+ }
+ }
+ else {
+ dump_indent += COL;
+ dump_named_datatype(type_id, real_name);
+ dump_indent -= COL;
+
+ if(H5Tclose(type_id) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_extlink
+ *
+ * made by: PVN
+ *
+ * Purpose: Dump an external link
+ * Since external links are soft links, they are dumped on a trial error
+ * basis, attempting to dump as a dataset, as a group and as a named datatype
+ * Error messages are supressed
+ *
+ * Modifications:
+ * Neil Fortner
+ * 13 October 2008
+ * Function basically rewritten. No longer directly opens the target file,
+ * now initializes a new set of tables for the external file. No longer
+ * dumps on a trial and error basis, but errors are still suppressed.
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+dump_extlink(hid_t group, const char *linkname, const char *objname)
+{
+ hid_t oid;
+ H5O_info_t oi;
+ table_t *old_group_table = group_table;
+ table_t *old_dset_table = dset_table;
+ table_t *old_type_table = type_table;
+ hbool_t old_hit_elink;
+ ssize_t idx;
+
+ /* Open target object */
+ if ((oid = H5Oopen(group, linkname, H5P_DEFAULT)) < 0)
+ goto fail;
+
+ /* Get object info */
+ if (H5Oget_info(oid, &oi) < 0) {
+ H5Oclose(oid);
+ goto fail;
+ }
+
+ /* Check if we have visited this file already */
+ if ((idx = table_list_visited(oi.fileno)) < 0) {
+ /* We have not visited this file, build object tables */
+ if ((idx = table_list_add(oid, oi.fileno)) < 0) {
+ H5Oclose(oid);
+ goto fail;
+ }
+ }
+
+ /* Do not recurse through an external link into the original file (idx=0) */
+ if (idx) {
+ /* Update table pointers */
+ group_table = table_list.tables[idx].group_table;
+ dset_table = table_list.tables[idx].dset_table;
+ type_table = table_list.tables[idx].type_table;
+
+ /* We will now traverse the external link, set this global to indicate this */
+ old_hit_elink = hit_elink;
+ hit_elink = TRUE;
+
+ /* add some indentation to distinguish that these objects are external */
+ dump_indent += COL;
+
+ /* Recurse into the external file */
+ switch (oi.type) {
+ case H5O_TYPE_GROUP:
+ handle_groups(group, linkname, NULL, 0, objname);
+ break;
+
+ case H5O_TYPE_DATASET:
+ handle_datasets(group, linkname, NULL, 0, objname);
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ handle_datatypes(group, linkname, NULL, 0, objname);
+ break;
+
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ h5tools_setstatus(EXIT_FAILURE);
+ }
+
+ dump_indent -= COL;
+
+ /* Reset table pointers */
+ group_table = old_group_table;
+ dset_table = old_dset_table;
+ type_table = old_type_table;
+
+ /* Reset hit_elink */
+ hit_elink = old_hit_elink;
+ } /* end if */
+
+ if (H5Idec_ref(oid) < 0)
+ h5tools_setstatus(EXIT_FAILURE);
+
+ return SUCCEED;
+
+fail:
+ return FAIL;
+}
+