diff options
Diffstat (limited to 'tools/h5dump/h5dump_ddl.c')
-rw-r--r-- | tools/h5dump/h5dump_ddl.c | 1931 |
1 files changed, 1931 insertions, 0 deletions
diff --git a/tools/h5dump/h5dump_ddl.c b/tools/h5dump/h5dump_ddl.c new file mode 100644 index 0000000..48f1396 --- /dev/null +++ b/tools/h5dump/h5dump_ddl.c @@ -0,0 +1,1931 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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" + +/*------------------------------------------------------------------------- + * 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(stdout, 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(stdout, 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 UNUSED *info, void 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(stdout, outputformat, &ctx, oid, 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 + * + *------------------------------------------------------------------------- + */ +herr_t +dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void UNUSED *op_data) +{ + hid_t obj; + 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)); + + memset(&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((obj = H5Dopen2(group, name, H5P_DEFAULT)) >= 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(stdout, outputformat, &ctx, 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + + /* Render the element */ + h5tools_str_reset(&buffer); + if(strlen(h5tools_dump_header_format->datasetblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend); + if(strlen(h5tools_dump_header_format->datasetend)) + h5tools_str_append(&buffer, " "); + } + if(strlen(h5tools_dump_header_format->datasetend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + ctx.indent_level--; + + h5tools_setstatus(EXIT_FAILURE); + ret = FAIL; + H5Dclose(obj); + goto done; + } + else if(found_obj->displayed) { + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + ctx.indent_level--; + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + + /* Render the element */ + h5tools_str_reset(&buffer); + if(strlen(h5tools_dump_header_format->datasetblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend); + if(strlen(h5tools_dump_header_format->datasetend)) + h5tools_str_append(&buffer, " "); + } + if(strlen(h5tools_dump_header_format->datasetend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + H5Dclose(obj); + goto done; + } + else { + found_obj->displayed = TRUE; + } + } /* end if */ + + dump_function_table->dump_dataset_function(obj, name, NULL); + H5Dclose(obj); + } + else { + 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; + + 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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(stdout, outputformat, &ctx, 0, 0); + + /* Render the element */ + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "LINKTARGET \"%s\"", targbuf); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + } + + ctx.indent_level--; + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + + /* Render the element */ + h5tools_str_reset(&buffer); + if(strlen(h5tools_dump_header_format->softlinkblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->softlinkblockend); + if(strlen(h5tools_dump_header_format->softlinkend)) + h5tools_str_append(&buffer, " "); + } + if(strlen(h5tools_dump_header_format->softlinkend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->softlinkend); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + HDfree(targbuf); + break; + + case H5L_TYPE_EXTERNAL: + targbuf = (char *)HDmalloc(linfo->u.val_size); + HDassert(targbuf); + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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(stdout, outputformat, &ctx, 0, 0); + + /* Render the element */ + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "TARGETFILE \"%s\"", filename); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + + /* Render the element */ + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "TARGETPATH \"%s\"", targname); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + /* dump the external link */ + dump_extlink(group, name, targname); + ctx.indent_level--; + } /* end else */ + } /* end else */ + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + + /* Render the element */ + h5tools_str_reset(&buffer); + if(strlen(h5tools_dump_header_format->extlinkblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->extlinkblockend); + if(strlen(h5tools_dump_header_format->extlinkend)) + h5tools_str_append(&buffer, " "); + } + if(strlen(h5tools_dump_header_format->extlinkend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->extlinkend); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + HDfree(targbuf); + break; + + default: + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + ctx.indent_level++; + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + /* Render the element */ + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "LINKCLASS %d", linfo->type); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + ctx.indent_level--; + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + /* Render the element */ + h5tools_str_reset(&buffer); + if(strlen(h5tools_dump_header_format->udlinkblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->udlinkblockend); + if(strlen(h5tools_dump_header_format->udlinkend)) + h5tools_str_append(&buffer, " "); + } + if(strlen(h5tools_dump_header_format->udlinkend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->udlinkend); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + break; + } /* end switch */ + } /* end else */ + +done: + + h5tools_str_close(&buffer); + + if(obj_path) + HDfree(obj_path); + return ret; +} + +/*------------------------------------------------------------------------- + * 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)); + + memset(&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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + goto done; + } + else + found_obj->displayed = TRUE; + } /* end if */ + + /* Render the element */ + h5tools_str_reset(&buffer); + h5tools_print_datatype(stdout, &buffer, outputformat, &ctx, tid, FALSE); + + if(H5Tget_class(tid) != H5T_COMPOUND) { + h5tools_str_append(&buffer, ";"); + } + + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + /* print attributes */ + dump_indent += COL; + + /* attribute iteration: if there is a request to do H5_INDEX_CRT_ORDER and tracking order is set + in the datatype's create property list for attributes, then, sort by creation order, otherwise by name */ + + if((sort_by == H5_INDEX_CRT_ORDER) && (attr_crt_order_flags & H5P_CRT_ORDER_TRACKED)) { + if(H5Aiterate2(tid, 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(tid, 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 */ + + dump_indent -= COL; + +done: + /* Render the element */ + h5tools_str_reset(&buffer); + if(strlen(h5tools_dump_header_format->datatypeblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datatypeblockend); + if(strlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(&buffer, " "); + } + if(strlen(h5tools_dump_header_format->datatypeend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datatypeend); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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)); + + memset(&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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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(stdout, outputformat, &ctx, gid); + } + + h5tools_dump_comment(stdout, 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + } + else { + found_obj->displayed = TRUE; + /* 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((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 */ + + /* 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); + } + } + else { + /* 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((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 */ + + /* 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); + } + + dump_indent -= COL; + ctx.indent_level--; + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + + /* Render the element */ + h5tools_str_reset(&buffer); + if(strlen(h5tools_dump_header_format->groupblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->groupblockend); + if(strlen(h5tools_dump_header_format->groupend)) + h5tools_str_append(&buffer, " "); + } + if(strlen(h5tools_dump_header_format->groupend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->groupend); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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(stdout, outputformat, &ctx, 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + h5tools_dump_comment(stdout, outputformat, &ctx, did); + + dump_indent += COL; + ctx.indent_level++; + + type = H5Dget_type(did); + h5dump_type_table = type_table; + h5tools_dump_datatype(stdout, outputformat, &ctx, type); + h5dump_type_table = NULL; + + space = H5Dget_space(did); + h5tools_dump_dataspace(stdout, outputformat, &ctx, space); + H5Sclose(space); + + if(display_oid) { + h5tools_dump_oid(stdout, outputformat, &ctx, did); + } + + if(display_dcpl) { + h5dump_type_table = type_table; + h5tools_dump_dcpl(stdout, outputformat, &ctx, dcpl_id, type, did); + h5dump_type_table = NULL; + } + H5Pclose(dcpl_id); + + if(display_data) { + int data_loop = 1; + int i; + if(display_packed_bits) + data_loop = packed_bits_num; + for(i=0; i<data_loop; i++) { + if(display_packed_bits) { + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + /* Render the element */ + h5tools_str_reset(&buffer); + packed_data_mask = packed_mask[i]; + packed_data_offset = packed_offset[i]; + packed_data_length = packed_length[i]; + h5tools_print_packed_bits(&buffer, type); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + } + switch(H5Tget_class(type)) { + case H5T_TIME: + ctx.indent_level++; + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + /* Render the element */ + h5tools_str_reset(&buffer); + h5tools_str_append(&buffer, "DATA{ not yet implemented.}"); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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(stdout, outputformat, &ctx, did, TRUE, sset, display_ai, display_char); + } + break; + + default: + break; + } /* end switch */ + } /* for(i=0;i<data_loop;i++) */ + } + H5Tclose(type); + + if (!bin_output) { + /* 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((sort_by == H5_INDEX_CRT_ORDER) && (attr_crt_order_flags & H5P_CRT_ORDER_TRACKED)) { + if(H5Aiterate2(did, 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(did, 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 */ + } + ctx.indent_level--; + dump_indent -= COL; + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + + /* Render the element */ + h5tools_str_reset(&buffer); + if(strlen(h5tools_dump_header_format->datasetblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetblockend); + if(strlen(h5tools_dump_header_format->datasetend)) + h5tools_str_append(&buffer, " "); + } + if(strlen(h5tools_dump_header_format->datasetend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->datasetend); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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(stdout, 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 */ +#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 */ + H5F_file_space_type_t fs_strategy; /* file space strategy */ + hsize_t fs_threshold; /* free-space section threshold */ + H5F_info2_t finfo; /* file information */ + + 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 + *------------------------------------------------------------------------- + */ + HDfprintf(stdout, "\n%s %s\n",SUPER_BLOCK, BEGIN); + indentation(dump_indent + COL); + HDfprintf(stdout, "%s %u\n","SUPERBLOCK_VERSION", finfo.super.version); + indentation(dump_indent + COL); + HDfprintf(stdout, "%s %u\n","FREELIST_VERSION", finfo.free.version); + indentation(dump_indent + COL); + HDfprintf(stdout, "%s %u\n","SYMBOLTABLE_VERSION", 0); /* Retain this for backward compatibility, for now (QAK) */ + indentation(dump_indent + COL); + HDfprintf(stdout, "%s %u\n","OBJECTHEADER_VERSION", finfo.sohm.version); + indentation(dump_indent + COL); + HDfprintf(stdout,"%s %Hd\n","OFFSET_SIZE", (long long)off_size); + indentation(dump_indent + COL); + HDfprintf(stdout,"%s %Hd\n","LENGTH_SIZE", (long long)len_size); + indentation(dump_indent + COL); + HDfprintf(stdout, "%s %u\n","BTREE_RANK", sym_ik); + indentation(dump_indent + COL); + HDfprintf(stdout, "%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"); +#ifdef H5_HAVE_STREAM + else if (H5FD_STREAM==fdriver) + HDstrcpy(dname,"H5FD_STREAM"); +#endif + else + HDstrcpy(dname,"Unknown driver"); + + /* Take out this because the driver used can be different from the + * standard output. */ + /*indentation(dump_indent + COL); + HDfprintf(stdout, "%s %s\n","FILE_DRIVER", dname);*/ +#endif + indentation(dump_indent + COL); + HDfprintf(stdout, "%s %u\n","ISTORE_K", istore_ik); + + indentation(dump_indent + COL); + if(fs_strategy == H5F_FILE_SPACE_ALL_PERSIST) + HDfprintf(stdout, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_ALL_PERSIST"); + else if(fs_strategy == H5F_FILE_SPACE_ALL) + HDfprintf(stdout, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_ALL"); + else if(fs_strategy == H5F_FILE_SPACE_AGGR_VFD) + HDfprintf(stdout, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_AGGR_VFD"); + else if(fs_strategy == H5F_FILE_SPACE_VFD) + HDfprintf(stdout, "%s %s\n", "FILE_SPACE_STRATEGY", "H5F_FILE_SPACE_VFD"); + else + HDfprintf(stdout, "%s %s\n", "FILE_SPACE_STRATEGY", "Unknown strategy"); + indentation(dump_indent + COL); + HDfprintf(stdout, "%s %Hu\n","FREE_SPACE_THRESHOLD", fs_threshold); + + /*------------------------------------------------------------------------- + * USER_BLOCK + *------------------------------------------------------------------------- + */ + indentation(dump_indent + COL); + HDfprintf(stdout, "USER_BLOCK %s\n",BEGIN); + indentation(dump_indent + COL + COL); + HDfprintf(stdout,"%s %Hu\n","USERBLOCK_SIZE", userblock); + indentation(dump_indent + COL); + HDfprintf(stdout, "%s\n",END); + + HDfprintf(stdout, "%s",END); +} + +/*------------------------------------------------------------------------- + * Function: dump_fcontents + * + * Purpose: prints all objects + * + * Return: void + * + * Programmer: pvn + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +dump_fcontents(hid_t fid) +{ + HDfprintf(stdout, "%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) + HDfprintf(stdout, " %-10s /#"H5_PRINTF_HADDR_FMT"\n", "datatype", type_table->objs[u].objno); + } + } + + /* print objects in the files */ + h5trav_print(fid); + + HDfprintf(stdout, " %s\n",END); +} + +/*------------------------------------------------------------------------- + * 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 UNUSED * data, int UNUSED pe, const char UNUSED *display_name) +{ + hid_t oid = -1; + hid_t attr_id = -1; + char *obj_name; + const char *attr_name; + 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] == '/') + 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; + memset(&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 = attr + j + 1; + + /* 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(stdout, outputformat, &ctx, 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(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 0); + + error_msg("unable to open object \"%s\"\n", obj_name); + + ctx.need_prefix = TRUE; + h5tools_simple_prefix(stdout, outputformat, &ctx, 0, 0); + /* Render the element */ + h5tools_str_reset(&buffer); + if(strlen(h5tools_dump_header_format->attributeblockend)) { + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->attributeblockend); + if(strlen(h5tools_dump_header_format->attributeend)) + h5tools_str_append(&buffer, " "); + } + if(strlen(h5tools_dump_header_format->attributeend)) + h5tools_str_append(&buffer, "%s", h5tools_dump_header_format->attributeend); + h5tools_render_element(stdout, outputformat, &ctx, &buffer, &curr_pos, outputformat->line_ncols, 0, 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(stdout, outputformat, &ctx, oid, attr, 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); + dump_indent -= COL; + return; + +error: + h5tools_setstatus(EXIT_FAILURE); + if(obj_name) + HDfree(obj_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; + struct subset_t *sset = (struct subset_t *)data; + const char *real_name = display_name ? display_name : dset; + + if((dsetid = H5Dopen2(fid, dset, H5P_DEFAULT)) < 0) { + if (pe) { + HDfprintf(stdout, "\n"); + begin_obj(h5tools_dump_header_format->datasetbegin, real_name, h5tools_dump_header_format->datasetblockbegin); + HDfprintf(stdout, "\n"); + indentation(COL); + error_msg("unable to open dataset \"%s\"\n", real_name); + end_obj(h5tools_dump_header_format->datasetend, h5tools_dump_header_format->datasetblockend); + h5tools_setstatus(EXIT_FAILURE); + } + return; + } /* end if */ + + if(sset) { + unsigned int i; + hid_t sid = H5Dget_space(dsetid); + int ndims = H5Sget_simple_extent_ndims(sid); + + H5Sclose(sid); + if(ndims < 0) { + error_msg("H5Sget_simple_extent_ndims failed\n"); + h5tools_setstatus(EXIT_FAILURE); + return; + } + + 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 *)calloc((size_t)ndims, sizeof(hsize_t)); + sset->start.len = ndims; + } + + if(!sset->stride.data) { + sset->stride.data = (hsize_t *)calloc((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 *)calloc((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 *)calloc((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) { + HDfprintf(stdout, "\n"); + indentation(dump_indent); + begin_obj(h5tools_dump_header_format->datasetbegin, real_name, h5tools_dump_header_format->datasetblockbegin); + HDfprintf(stdout, "\n"); + indentation(dump_indent + COL); + HDfprintf(stdout, "%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(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 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) { + HDfprintf(stdout, "\n"); + begin_obj(h5tools_dump_header_format->groupbegin, real_name, h5tools_dump_header_format->groupblockbegin); + HDfprintf(stdout, "\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 UNUSED * data, int UNUSED pe, const char 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); + HDfprintf(stdout, "\n"); + + switch(linfo.type) { + case H5L_TYPE_SOFT: /* Soft link */ + begin_obj(h5tools_dump_header_format->softlinkbegin, links, h5tools_dump_header_format->softlinkblockbegin); + HDfprintf(stdout, "\n"); + indentation(COL); + if(H5Lget_val(fid, links, buf, linfo.u.val_size, H5P_DEFAULT) >= 0) + HDfprintf(stdout, "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); + HDfprintf(stdout, "\n"); + indentation(COL); + begin_obj(h5tools_dump_header_format->extlinkbegin, links, h5tools_dump_header_format->extlinkblockbegin); + HDfprintf(stdout, "\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); + HDfprintf(stdout, "LINKCLASS %d\n", linfo.type); + indentation(COL); + HDfprintf(stdout, "TARGETFILE \"%s\"\n", elink_file); + indentation(COL); + HDfprintf(stdout, "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; + + default: + begin_obj(h5tools_dump_header_format->udlinkbegin, links, h5tools_dump_header_format->udlinkblockbegin); + HDfprintf(stdout, "\n"); + indentation(COL); + begin_obj(h5tools_dump_header_format->udlinkbegin, links, h5tools_dump_header_format->udlinkblockbegin); + HDfprintf(stdout, "\n"); + indentation(COL); + HDfprintf(stdout, "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 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 */ + HDfprintf(stdout, "\n"); + begin_obj(h5tools_dump_header_format->datatypebegin, real_name, h5tools_dump_header_format->datatypeblockbegin); + HDfprintf(stdout, "\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; + 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; +} + |