Files
hdf5/tools/lib/h5tools_ref.c
Larry Knox b42635ad88 Hdf5 merge issue 458 v110 (#465)
* close #195. (#196)

* Update HDF5PluginMacros.cmake

* Update HDF5PluginMacros.cmake

* Modify temporary rpath for testing in java example scripts. (#230)

* Fix undefined left shifting of negative numbers (#338)

Undefined Bahavior Sanitizer errored here about left shifting negative numbers.

* Update license url (#332)

* Modify temporary rpath for testing in java example scripts.

* Update URL in source file Copyright headers for web copy of COPYING
file - src and test directories.

* Applied clang-tidy readability-non-const-parameter warning fixes auto… (#429)

* Automatically applied clang-tidy readability-avoid-const-params-in-decls fixes

Removes useless const declarations.

* Fixed most readability-non-const-parameter warnings

These changes were made automatically by clang-tidy, but I manually reverted the changes related to the H5Z_func_t signature.

* Reformat source with clang v10.0.1.

Co-authored-by: Larry Knox <lrknox@hdfgroup.org>

* Added C++11 override keyword where appropriate (#433)

Added H5_OVERRIDE macro for compatibility with both C++11 and older.

* Various clang tidy warning fixes (#448)

* Fixed clang-tidy bugprone-reserved-identifier warnings

* Fixed clang-tidy bugprone-assert-side-effect warnings

* Fixed clang-tidy bugprone-copy-constructor-init warning

* Fixed clang-tidy readability-redundant-preprocessor warning

For error_test.c the removed code was already dead, because it was in the else of an `#if H5_USE_16_API` block.

Based on H5Location.h, I think p_get_ref_obj_type was meant to be in `#ifndef DOXYGEN_SHOULD_SKIP_THIS` and an `#endif` was missing.  Similarly, in the header, getObjTypeByIdx is only in H5_NO_DEPRECATED_SYMBOLS, not DOXYGEN_SHOULD_SKIP_THIS.

* Fixed clang-tidy readability-redundant-string-init warnings

* Fixed some clang-tidy performance-type-promotion-in-math-fn warnings

* Fixed clang-tidy performance-unnecessary-value-param warnings

* Reformat source with clang v10.0.1.

Co-authored-by: Larry Knox <lrknox@hdfgroup.org>

* Removed checks/workarounds for pre-C++89 compatibility (#449)

After 30+ years, just assume that the following exist:
- extension-less includes
- namespaces
- std::
- static_cast
- bool

* Fixed all clang-tidy bugprone-suspicious-string-compare warnings (#451)

* Fixed all clang-tidy bugprone-suspicious-string-compare warnings

This change was generated entirely by clang-tidy itself.

* Reformat code with clang v10.0.1.

Co-authored-by: Larry Knox <lrknox@hdfgroup.org>

* Fix clang-tidy suspicious string compare in H5A.c missed in merge.

Co-authored-by: H. Joe Lee <hyoklee@hdfgroup.org>
Co-authored-by: Sean McBride <sean@rogue-research.com>
2021-03-12 11:58:10 -06:00

333 lines
9.2 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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 COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "h5tools_ref.h"
#include "H5private.h"
#include "H5SLprivate.h"
#include "h5tools.h"
#include "h5tools_utils.h"
#include "h5trav.h"
/*
* Table to look up a path name for an object
* reference.
*
* This table stores mappings of reference -> path
* for all objects in the file that may be the target of
* an object reference.
*
* The 'path' is an absolute path by which the object
* can be accessed. When an object has > 1 such path,
* only one will be used in the table, with no particular
* method of selecting which one.
*/
typedef struct {
haddr_t objno; /* Object ID (i.e. address) */
char * path; /* Object path */
} ref_path_node_t;
static H5SL_t *ref_path_table = NULL; /* the "table" (implemented with a skip list) */
static hid_t thefile = (-1);
static int ref_path_table_put(const char *, haddr_t objno);
/*-------------------------------------------------------------------------
* Function: free_ref_path_info
*
* Purpose: Free the key for a reference path table node
*
* Return: Non-negative on success, negative on failure
*
* Programmer: Quincey Koziol
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
free_ref_path_info(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *operator_data /*in,out*/)
{
ref_path_node_t *node = (ref_path_node_t *)item;
HDfree(node->path);
HDfree(node);
return (0);
}
/*-------------------------------------------------------------------------
* Function: init_ref_path_cb
*
* Purpose: Called by interator to create references for
* all objects and enter them in the table.
*
* Return: Error status.
*
* Programmer: REMcG
*
*-------------------------------------------------------------------------
*/
static herr_t
init_ref_path_cb(const char *obj_name, const H5O_info_t *oinfo, const char *already_seen,
void H5_ATTR_UNUSED *_udata)
{
/* Check if the object is already in the path table */
if (NULL == already_seen) {
/* Insert the object into the path table */
ref_path_table_put(obj_name, oinfo->addr);
} /* end if */
return 0;
}
/*-------------------------------------------------------------------------
* Function: init_ref_path_table
*
* Purpose: Initalize the reference path table
*
* Return: Non-negative on success, negative on failure
*
* Programmer: Quincey Koziol
*
*-------------------------------------------------------------------------
*/
static int
init_ref_path_table(void)
{
/* Sanity check */
if (thefile > 0) {
/* Create skip list to store reference path information */
if ((ref_path_table = H5SL_create(H5SL_TYPE_HADDR, NULL)) == NULL)
return (-1);
/* Iterate over objects in this file */
if (h5trav_visit(thefile, "/", TRUE, TRUE, init_ref_path_cb, NULL, NULL, H5O_INFO_BASIC) < 0) {
error_msg("unable to construct reference path table\n");
h5tools_setstatus(EXIT_FAILURE);
} /* end if */
return (0);
}
else
return (-1);
}
/*-------------------------------------------------------------------------
* Function: term_ref_path_table
*
* Purpose: Terminate the reference path table
*
* Return: Non-negative on success, negative on failure
*
* Programmer: Quincey Koziol
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
int
term_ref_path_table(void)
{
/* Destroy reference path table, freeing all memory */
if (ref_path_table)
H5SL_destroy(ref_path_table, free_ref_path_info, NULL);
return (0);
}
/*-------------------------------------------------------------------------
* Function: ref_path_table_lookup
*
* Purpose: Looks up a table entry given a path name.
* Used during construction of the table.
*
* Return: The table entre (pte) or NULL if not in the
* table.
*
* Programmer: REMcG
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
haddr_t
ref_path_table_lookup(const char *thepath)
{
H5O_info_t oi;
if ((thepath == NULL) || (HDstrlen(thepath) == 0))
return HADDR_UNDEF;
/* Allow lookups on the root group, even though it doesn't have any link info */
if (HDstrcmp(thepath, "/") != 0) {
H5L_info_t li;
/* Check for external link first, so we don't return the OID of an object in another file */
if (H5Lget_info(thefile, thepath, &li, H5P_DEFAULT) < 0)
return HADDR_UNDEF;
/* UD links can't be followed, so they always "dangle" like soft links. */
if (li.type >= H5L_TYPE_UD_MIN)
return HADDR_UNDEF;
} /* end if */
/* Get the object info now */
/* (returns failure for dangling soft links) */
if (H5Oget_info_by_name2(thefile, thepath, &oi, H5O_INFO_BASIC, H5P_DEFAULT) < 0)
return HADDR_UNDEF;
/* Return OID */
return (oi.addr);
}
/*-------------------------------------------------------------------------
* Function: ref_path_table_put
*
* Purpose: Enter the 'obj' with 'path' in the table (assumes its not
* already there)
*
* Create an object reference, pte, and store them
* in the table.
*
* NOTE: Takes ownership of the path name string passed in!
*
* Return: Non-negative on success, negative on failure
*
* Programmer: REMcG
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
ref_path_table_put(const char *path, haddr_t objno)
{
ref_path_node_t *new_node;
if (ref_path_table && path) {
if ((new_node = (ref_path_node_t *)HDmalloc(sizeof(ref_path_node_t))) == NULL)
return (-1);
new_node->objno = objno;
new_node->path = HDstrdup(path);
return (H5SL_insert(ref_path_table, new_node, &(new_node->objno)));
}
else
return (-1);
}
/*
* counter used to disambiguate multiple instances of same object.
*/
int xid = 1;
int
get_next_xid(void)
{
return xid++;
}
/*
* This counter is used to create fake object ID's
* The idea is to set it to the largest possible offest, which
* minimizes the chance of collision with a real object id.
*
*/
haddr_t fake_xid = HADDR_MAX;
haddr_t
get_fake_xid(void)
{
return (fake_xid--);
}
/*
* for an object that does not have an object id (e.g., soft link),
* create a table entry with a fake object id as the key.
*
* Assumes 'path' is for an object that is not in the table.
*
*/
haddr_t
ref_path_table_gen_fake(const char *path)
{
haddr_t fake_objno;
/* Generate fake ID for string */
fake_objno = get_fake_xid();
/* Create ref path table, if it hasn't already been created */
if (ref_path_table == NULL)
init_ref_path_table();
/* Insert "fake" object into table */
ref_path_table_put(path, fake_objno);
return (fake_objno);
}
/*-------------------------------------------------------------------------
* Function: lookup_ref_path
*
* Purpose: Lookup the path to the object with refernce 'ref'.
*
* Return: Return a path to the object, or NULL if not found.
*
* Programmer: REMcG
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
const char *
lookup_ref_path(haddr_t ref)
{
ref_path_node_t *node;
/* Be safer for h5ls */
if (thefile < 0)
return (NULL);
/* Create ref path table, if it hasn't already been created */
if (ref_path_table == NULL)
init_ref_path_table();
node = (ref_path_node_t *)H5SL_search(ref_path_table, &ref);
return (node ? node->path : NULL);
}
/*-------------------------------------------------------------------------
* Function: fill_ref_path_table
*
* Purpose: Called by interator to create references for
* all objects and enter them in the table.
*
* Return: Error status.
*
* Programmer: REMcG
*
*-------------------------------------------------------------------------
*/
herr_t
fill_ref_path_table(hid_t fid)
{
/* Set file ID for later queries (XXX: this should be fixed) */
thefile = fid;
/* Defer creating the ref path table until it's needed */
return 0;
}