mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-10-06 04:03:30 +03:00
commit ff7a9a34de2fcd78f5d32a1532f3d0e224b20d94 Author: Kimmy Mu <kmu@hdfgroup.org> Date: Wed Jan 29 14:12:18 2020 -0600 Merge pull request #2324 in HDFFV/hdf5 from ~KMU/hdf5:hdf5_1_12 to hdf5_1_12 * commit '781fa57f6ee816e037dd12fff02d37ff7ec9c2b1': pick up missing piece from merge Merge pull request #2311 in HDFFV/hdf5 from ~KMU/hdf5:misc to develop remove redundent definition Merge pull request #2311 in HDFFV/hdf5 from ~KMU/hdf5:misc to develop Merge pull request #2311 in HDFFV/hdf5 from ~KMU/hdf5:misc to develop Merge pull request #2315 in HDFFV/hdf5 from ~KMU/hdf5:develop to develop missing prototype warning prototype issue Merge pull request #2306 in HDFFV/hdf5 from ~KMU/hdf5:develop to develop Merge pull request #2300 in HDFFV/hdf5 from ~KMU/hdf5:squashed_cast to develop Merge pull request #2291 in HDFFV/hdf5 from ~KMU/hdf5:bugfix/uninitialized to develop Merge pull request #2295 in HDFFV/hdf5 from ~KMU/hdf5:bugfix/float to develop Merge pull request #2292 in HDFFV/hdf5 from ~KMU/hdf5:bugfix/prototype to develop Merge pull request #2094 in HDFFV/hdf5 from ~KMU/hdf5:bugfix/unused to develop commit 9f3d808c05d2a3b308f32c958c6671fcac0a432c Author: David Young <dyoung@hdfgroup.org> Date: Wed Jan 29 11:43:55 2020 -0600 testpar/t_2Gio.c: Fix a typo that I think was introduced by a previous warnings PR. An array element was assigned to itself---shape[2]Â =Â shape[2];---instead of being assigned to chunk[2]. fortran/src/H5Pf.c: move conditional compilation controlled by H5_NO_DEPRECATED_SYMBOLS outside of a function for readability. fortran/src/H5match_types.c: put a variable's declaration under the same conditional compilation (H5_FORTRAN_HAVE_C_LONG_DOUBLE) as its use. For now, skip compilation of some unused debug dump routines in the JNI. While I'm in the JNI, delete a set-but-unused variable. src/H5Z.c: condition a variable declaration on H5_NO_DEPRECATED_SYMBOLS so that it's not declared but unused or vice versa. test/cache_common.h: add an #include in to get some symbols we need to avoid implicit declaration warnings. test/dsets.c: use a more conventional conditional-compilation syntax. test/dt_arith.c, test/fillval.c: initialize a bunch of uninitialized variables before use. test/vfd.c: pass the expected type of `void **` to posix_memalign(3) instead of `int **`. testpar/t_bigio.c: explicitly compare with 0 instead of using ! when "equal to 0?" is the question not "is false?" Repair some indentation while I'm here. testpar/testpar.h: repair misaligned line-continuation backslashes in a macro that probably should be a function so that we don't have to fiddle with the line continuation to begin with. tools/src/h5repack/h5repack_main.c: fix some compiler fussing about enums. tools/test/perform/pio_engine.c: the compiler fusses if you cast a function call returning double directly to off_t. It's ok if you cast a variable that's a double to off_t, however. Write and use a new function, sqrto(), to avoid the cast warnings. commit 43a4b80b21c0329fbc1f9a0e2854795189f0bb50 Author: David Young <dyoung@hdfgroup.org> Date: Wed Jan 29 10:47:30 2020 -0600 Reduce casts of HDcalloc()/HDmalloc() that -Wc++-compat required. Reduce gratuitous casts---e.g., (size_t)1. Use the right format string for a pointer. In the H5C sanity checks, change a "size increase" variable from ssize_t (too narrow) to int64_t (wide enough). Parenthesize every appearance of `storage` in the macro `H5D_CHUNK_STORAGE_INDEX_CHK(storage)` so that you can pass in an expression like &sc and it works properly. Disallow re-assignment of the `dset` parameter to H5D__chunk_init() because it helped assure me that it's safe to replace the repeating expression `&dset->shared->layout.storage.u.chunk` with `sc` throughout. Replace lengthy expressions such as `&dset->shared->layout.storage.u.chunk` with `sc` throughout several functions in H5Dchunk.c ISTR that the compiler warned that `sc` was declared but unused in a couple of functions, and then I found that `sc` could be used in many places. Maybe the disused `sc` appeared because a bunch of code was copied and pasted, I don't know. Anyway, it's a lot tighter code now that I use `sc`. In H5D__chunk_update_old_edge_chunks() and H5D__chunk_delete() I actually expand `sc` and another temporary variable, `pline`, because they're used only in !defined(NDEBUG) code. This squashes unused-variable warnings in the defined(NDEBUG) configuration. Don't drop the `volatile` qualification with a cast in tools/src/h5import/h5import.c. commit 035bfa0769a4012881fc659b673bacf44d146537 Author: David Young <dyoung@hdfgroup.org> Date: Tue Jan 28 20:35:28 2020 -0600 Reduce differences between my -Werror branch and `develop`: Rename index -> idx, fileno -> fnumber, fileno -> fno to avoid GCC shadowed declaration warnings about index(3). Convert #pragma GCC diagnostic push/pop/ignored to the HDF5 library's H5_GCC_DIAG_OFF()/H5_GCC_DIAG_ON() macros.
777 lines
25 KiB
C
777 lines
25 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Copyright by The HDF Group. *
|
|
* 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://support.hdfgroup.org/ftp/HDF5/releases. *
|
|
* If you do not have access to either file, you may request a copy from *
|
|
* help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/*
|
|
* Purpose: Code to implement a path table which stores plugin search paths.
|
|
*
|
|
* The path table is implemented as a dynamic, global array which
|
|
* will grow as new paths are inserted. The capacity of the path
|
|
* table never shrinks (though given the low number of paths
|
|
* expected and the low likelihood of paths being removed, this
|
|
* seems unlikely to be a problem). Inserts and removals rework
|
|
* the array so that there are no 'holes' in the in-use part
|
|
* of the array.
|
|
*
|
|
* Note that it's basically up to the user to manage the indexes
|
|
* when a complicated series of insert, overwrite, and, remove
|
|
* operations take place.
|
|
*/
|
|
|
|
/****************/
|
|
/* Module Setup */
|
|
/****************/
|
|
|
|
#include "H5PLmodule.h" /* This source code file is part of the H5PL module */
|
|
|
|
|
|
/***********/
|
|
/* Headers */
|
|
/***********/
|
|
#include "H5private.h" /* Generic Functions */
|
|
#include "H5Eprivate.h" /* Error handling */
|
|
#include "H5MMprivate.h" /* Memory management */
|
|
#include "H5PLpkg.h" /* Plugin */
|
|
|
|
|
|
/****************/
|
|
/* Local Macros */
|
|
/****************/
|
|
|
|
/* Initial capacity of the path table */
|
|
#define H5PL_INITIAL_PATH_CAPACITY 16
|
|
|
|
/* The amount to add to the capacity when the table is full */
|
|
#define H5PL_PATH_CAPACITY_ADD 16
|
|
|
|
|
|
/******************/
|
|
/* Local Typedefs */
|
|
/******************/
|
|
|
|
|
|
/********************/
|
|
/* Local Prototypes */
|
|
/********************/
|
|
|
|
static herr_t H5PL__insert_at(const char *path, unsigned int idx);
|
|
static herr_t H5PL__make_space_at(unsigned int idx);
|
|
static herr_t H5PL__replace_at(const char *path, unsigned int idx);
|
|
static herr_t H5PL__expand_path_table(void);
|
|
static herr_t H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *found, const char *dir, const void **plugin_info);
|
|
|
|
/*********************/
|
|
/* Package Variables */
|
|
/*********************/
|
|
|
|
|
|
/*****************************/
|
|
/* Library Private Variables */
|
|
/*****************************/
|
|
|
|
|
|
/*******************/
|
|
/* Local Variables */
|
|
/*******************/
|
|
|
|
/* Stored plugin paths to search */
|
|
static char **H5PL_paths_g = NULL;
|
|
|
|
/* The number of stored paths */
|
|
static unsigned H5PL_num_paths_g = 0;
|
|
|
|
/* The capacity of the path table */
|
|
static unsigned H5PL_path_capacity_g = H5PL_INITIAL_PATH_CAPACITY;
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__insert_at()
|
|
*
|
|
* Purpose: Insert a path at a particular index in the path table.
|
|
* Does not clobber! Will move existing paths up to make
|
|
* room. Use H5PL__replace_at(index) if you want to clobber.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static herr_t
|
|
H5PL__insert_at(const char *path, unsigned int idx)
|
|
{
|
|
char *path_copy = NULL; /* copy of path string (for storing) */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_STATIC
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(path);
|
|
HDassert(HDstrlen(path));
|
|
|
|
/* Expand the table if it is full */
|
|
if (H5PL_num_paths_g == H5PL_path_capacity_g)
|
|
if (H5PL__expand_path_table() < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't expand path table")
|
|
|
|
/* Copy the path for storage so the caller can dispose of theirs */
|
|
if (NULL == (path_copy = H5MM_strdup(path)))
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't make internal copy of path")
|
|
|
|
#ifdef H5_HAVE_WIN32_API
|
|
/* Clean up Microsoft Windows environment variables in the path string */
|
|
if(H5_expand_windows_env_vars(&path_copy))
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTCONVERT, FAIL, "can't expand environment variable string")
|
|
#endif /* H5_HAVE_WIN32_API */
|
|
|
|
/* If the table entry is in use, make some space */
|
|
if (H5PL_paths_g[idx])
|
|
if (H5PL__make_space_at(idx) < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "unable to make space in the table for the new entry")
|
|
|
|
/* Insert the copy of the search path into the table at the specified index */
|
|
H5PL_paths_g[idx] = path_copy;
|
|
H5PL_num_paths_g++;
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__insert_at() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__make_space_at()
|
|
*
|
|
* Purpose: Free up a slot in the path table, moving existing path
|
|
* entries as necessary.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static herr_t
|
|
H5PL__make_space_at(unsigned int idx)
|
|
{
|
|
unsigned u; /* iterator */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_STATIC_NOERR
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(idx < H5PL_path_capacity_g);
|
|
|
|
/* Copy the paths back to make a space */
|
|
for (u = H5PL_num_paths_g; u > idx; u--)
|
|
H5PL_paths_g[u] = H5PL_paths_g[u-1];
|
|
|
|
H5PL_paths_g[idx] = NULL;
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__make_space_at() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__replace_at()
|
|
*
|
|
* Purpose: Replace a path at a particular index in the path table.
|
|
* The path in the table must exist and will be freed by this
|
|
* function.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static herr_t
|
|
H5PL__replace_at(const char *path, unsigned int idx)
|
|
{
|
|
char *path_copy = NULL; /* copy of path string (for storing) */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_STATIC
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(path);
|
|
HDassert(HDstrlen(path));
|
|
|
|
/* Check that the table entry is in use */
|
|
if (!H5PL_paths_g[idx])
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, FAIL, "path entry at index %u in the table is NULL", idx)
|
|
|
|
/* Copy the path for storage so the caller can dispose of theirs */
|
|
if (NULL == (path_copy = H5MM_strdup(path)))
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't make internal copy of path")
|
|
|
|
#ifdef H5_HAVE_WIN32_API
|
|
/* Clean up Microsoft Windows environment variables in the path string */
|
|
if (H5_expand_windows_env_vars(&path_copy))
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTCONVERT, FAIL, "can't expand environment variable string")
|
|
#endif /* H5_HAVE_WIN32_API */
|
|
|
|
/* Free the existing path entry */
|
|
H5PL_paths_g[idx] = (char *)H5MM_xfree(H5PL_paths_g[idx]);
|
|
|
|
/* Copy the search path into the table at the specified index */
|
|
H5PL_paths_g[idx] = path_copy;
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__replace_at() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__create_path_table
|
|
*
|
|
* Purpose: Create the collection of paths that will be searched
|
|
* when loading plugins.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5PL__create_path_table(void)
|
|
{
|
|
char *env_var= NULL; /* Path string from environment variable */
|
|
char *paths = NULL; /* Delimited paths string. Either from the
|
|
* environment variable or the default.
|
|
*/
|
|
char *next_path = NULL; /* A path tokenized from the paths string */
|
|
char *lasts = NULL; /* Context pointer for strtok_r() call */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_PACKAGE
|
|
|
|
/* Allocate memory for the path table */
|
|
H5PL_num_paths_g = 0;
|
|
H5PL_path_capacity_g = H5PL_INITIAL_PATH_CAPACITY;
|
|
if (NULL == (H5PL_paths_g = (char **)H5MM_calloc((size_t)H5PL_path_capacity_g * sizeof(char *))))
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path table")
|
|
|
|
/* Retrieve paths from HDF5_PLUGIN_PATH if the user sets it
|
|
* or from the default paths if it isn't set.
|
|
*/
|
|
env_var = HDgetenv("HDF5_PLUGIN_PATH");
|
|
if (NULL == env_var)
|
|
paths = H5MM_strdup(H5PL_DEFAULT_PATH);
|
|
else
|
|
paths = H5MM_strdup(env_var);
|
|
|
|
if (NULL == paths)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path copy")
|
|
|
|
/* Separate the paths and store them */
|
|
next_path = HDstrtok_r(paths, H5PL_PATH_SEPARATOR, &lasts);
|
|
while (next_path) {
|
|
|
|
/* Insert the path into the table */
|
|
if (H5PL__append_path(next_path) < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't insert path: %s", next_path)
|
|
|
|
/* Get the next path from the environment string */
|
|
next_path = HDstrtok_r(NULL, H5PL_PATH_SEPARATOR, &lasts);
|
|
} /* end while */
|
|
|
|
done:
|
|
if (paths)
|
|
paths = (char *)H5MM_xfree(paths);
|
|
|
|
/* Try to clean up on errors */
|
|
if (FAIL == ret_value) {
|
|
if (H5PL_paths_g)
|
|
H5PL_paths_g = (char **)H5MM_xfree(H5PL_paths_g);
|
|
H5PL_path_capacity_g = 0;
|
|
}
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__create_path_table() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__close_path_table
|
|
*
|
|
* Purpose: Close the collection of paths that will be searched
|
|
* when loading plugins.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5PL__close_path_table(void)
|
|
{
|
|
unsigned u; /* iterator */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_PACKAGE_NOERR
|
|
|
|
/* Free paths */
|
|
for (u = 0; u < H5PL_num_paths_g; u++)
|
|
if (H5PL_paths_g[u])
|
|
H5PL_paths_g[u] = (char *)H5MM_xfree(H5PL_paths_g[u]);
|
|
|
|
/* Free path table */
|
|
H5PL_paths_g = (char **)H5MM_xfree(H5PL_paths_g);
|
|
|
|
/* Reset values */
|
|
H5PL_num_paths_g = 0;
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
|
|
} /* end H5PL__close_path_table() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__get_num_paths
|
|
*
|
|
* Purpose: Gets the number of plugin paths that have been stored.
|
|
*
|
|
* Return: Success: The number of paths
|
|
* Failture: Can't fail
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
unsigned
|
|
H5PL__get_num_paths(void)
|
|
{
|
|
FUNC_ENTER_PACKAGE_NOERR
|
|
|
|
FUNC_LEAVE_NOAPI(H5PL_num_paths_g)
|
|
|
|
} /* end H5PL__get_num_paths() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__expand_path_table
|
|
*
|
|
* Purpose: Expand the path table when it's full.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
static herr_t
|
|
H5PL__expand_path_table(void)
|
|
{
|
|
herr_t ret_value = SUCCEED;
|
|
|
|
FUNC_ENTER_STATIC
|
|
|
|
/* Update the capacity */
|
|
H5PL_path_capacity_g += H5PL_PATH_CAPACITY_ADD;
|
|
|
|
/* Resize the array */
|
|
if(NULL == (H5PL_paths_g = (char **)H5MM_realloc(H5PL_paths_g, (size_t)H5PL_path_capacity_g * sizeof(char *))))
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "allocating additional memory for path table failed")
|
|
|
|
/* Initialize the new memory */
|
|
HDmemset(H5PL_paths_g + H5PL_num_paths_g, 0, (size_t)H5PL_PATH_CAPACITY_ADD * sizeof(char *));
|
|
|
|
done:
|
|
/* Set the path capacity back if there were problems */
|
|
if (FAIL == ret_value)
|
|
H5PL_path_capacity_g -= H5PL_PATH_CAPACITY_ADD;
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__expand_path_table() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__append_path
|
|
*
|
|
* Purpose: Insert a path at the end of the table.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5PL__append_path(const char *path)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_PACKAGE
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(path);
|
|
HDassert(HDstrlen(path));
|
|
|
|
/* Insert the path at the end of the table */
|
|
if (H5PL__insert_at(path, H5PL_num_paths_g) < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to append search path")
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__append_path() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__prepend_path
|
|
*
|
|
* Purpose: Insert a path at the beginning of the table.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5PL__prepend_path(const char *path)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_PACKAGE
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(path);
|
|
HDassert(HDstrlen(path));
|
|
|
|
/* Insert the path at the beginning of the table */
|
|
if (H5PL__insert_at(path, 0) < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to prepend search path")
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__prepend_path() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__replace_path
|
|
*
|
|
* Purpose: Replace a path at particular index in the table.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5PL__replace_path(const char *path, unsigned int idx)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_PACKAGE
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(path);
|
|
HDassert(HDstrlen(path));
|
|
HDassert(idx < H5PL_path_capacity_g);
|
|
|
|
/* Insert the path at the requested index */
|
|
if (H5PL__replace_at(path, idx) < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to replace search path")
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__replace_path() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__insert_path
|
|
*
|
|
* Purpose: Insert a path at particular index in the table, moving
|
|
* any existing paths back to make space.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5PL__insert_path(const char *path, unsigned int idx)
|
|
{
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_PACKAGE
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(path);
|
|
HDassert(HDstrlen(path));
|
|
HDassert(idx < H5PL_path_capacity_g);
|
|
|
|
/* Insert the path at the requested index */
|
|
if (H5PL__insert_at(path, idx) < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to insert search path")
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__insert_path() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__remove_path
|
|
*
|
|
* Purpose: Remove a path at particular index in the table, freeing
|
|
* the path string and moving the paths down to close the gap.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5PL__remove_path(unsigned int idx)
|
|
{
|
|
unsigned u; /* iterator */
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
FUNC_ENTER_PACKAGE
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(idx < H5PL_path_capacity_g);
|
|
|
|
/* Check if the path at that index is set */
|
|
if (!H5PL_paths_g[idx])
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTDELETE, FAIL, "search path at index %u is NULL", idx)
|
|
|
|
/* Delete the path */
|
|
H5PL_num_paths_g--;
|
|
H5PL_paths_g[idx] = (char *)H5MM_xfree(H5PL_paths_g[idx]);
|
|
|
|
/* Shift the paths down to close the gap */
|
|
for (u = idx; u < H5PL_num_paths_g; u++)
|
|
H5PL_paths_g[u] = H5PL_paths_g[u+1];
|
|
|
|
/* Set the (former) last path to NULL */
|
|
H5PL_paths_g[H5PL_num_paths_g] = NULL;
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__remove_path() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__get_path
|
|
*
|
|
* Purpose: Get a pointer to a path at particular index in the table.
|
|
*
|
|
* Return: Success: A pointer to a path string stored in the table
|
|
* Failure: NULL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
const char *
|
|
H5PL__get_path(unsigned int idx)
|
|
{
|
|
char *ret_value = NULL; /* Return value */
|
|
|
|
FUNC_ENTER_PACKAGE
|
|
|
|
/* Get the path at the requested index */
|
|
if (idx >= H5PL_num_paths_g)
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "path index %u is out of range in table", idx)
|
|
|
|
return H5PL_paths_g[idx];
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__replace_path() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__find_plugin_in_path_table
|
|
*
|
|
* Purpose: Attempts to find a matching plugin in the file system
|
|
* using the paths stored in the path table.
|
|
*.
|
|
* The 'found' parameter will be set appropriately.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
herr_t
|
|
H5PL__find_plugin_in_path_table(const H5PL_search_params_t *search_params, hbool_t *found, const void **plugin_info)
|
|
{
|
|
unsigned int u; /* iterator */
|
|
herr_t ret_value = SUCCEED;
|
|
|
|
FUNC_ENTER_PACKAGE
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(search_params);
|
|
HDassert(found);
|
|
HDassert(plugin_info);
|
|
|
|
/* Initialize output parameters */
|
|
*found = FALSE;
|
|
*plugin_info = NULL;
|
|
|
|
/* Loop over the paths in the table, checking for an appropriate plugin */
|
|
for (u = 0; u < H5PL_num_paths_g; u++) {
|
|
|
|
/* Search for the plugin in this path */
|
|
if (H5PL__find_plugin_in_path(search_params, found, H5PL_paths_g[u], plugin_info) < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in path %s encountered an error", H5PL_paths_g[u])
|
|
|
|
/* Break out if found */
|
|
if (*found) {
|
|
if (!plugin_info)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "plugin info should not be NULL")
|
|
break;
|
|
}
|
|
}
|
|
|
|
done:
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__find_plugin_in_path_table() */
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
* Function: H5PL__find_plugin_in_path
|
|
*
|
|
* Purpose: Given a path, this function opens the directory and envokes
|
|
* another function to go through all files to find the right
|
|
* plugin library. Two function definitions are for Unix and
|
|
* Windows.
|
|
*
|
|
* The found parameter will be set to TRUE and the info
|
|
* parameter will be filled in on success.
|
|
*
|
|
* Return: SUCCEED/FAIL
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef H5_HAVE_WIN32_API
|
|
static herr_t
|
|
H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *found, const char *dir, const void **plugin_info)
|
|
{
|
|
char *path = NULL;
|
|
DIR *dirp = NULL; /* Directory stream */
|
|
struct dirent *dp = NULL; /* Directory entry */
|
|
herr_t ret_value = SUCCEED;
|
|
|
|
FUNC_ENTER_STATIC
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(search_params);
|
|
HDassert(found);
|
|
HDassert(dir);
|
|
HDassert(plugin_info);
|
|
|
|
/* Initialize the found parameter */
|
|
*found = FALSE;
|
|
|
|
/* Open the directory */
|
|
if (!(dirp = HDopendir(dir)))
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory: %s", dir)
|
|
|
|
/* Iterate through all entries in the directory */
|
|
while (NULL != (dp = HDreaddir(dirp))) {
|
|
|
|
/* The library we are looking for should be called libxxx.so... on Unix
|
|
* or libxxx.xxx.dylib on Mac.
|
|
*/
|
|
#ifndef __CYGWIN__
|
|
if (!HDstrncmp(dp->d_name, "lib", (size_t)3) &&
|
|
(HDstrstr(dp->d_name, ".so") || HDstrstr(dp->d_name, ".dylib"))) {
|
|
#else
|
|
if (!HDstrncmp(dp->d_name, "cyg", (size_t)3) &&
|
|
HDstrstr(dp->d_name, ".dll") ) {
|
|
#endif
|
|
|
|
h5_stat_t my_stat;
|
|
size_t len;
|
|
|
|
/* Allocate & initialize the path name */
|
|
len = HDstrlen(dir) + HDstrlen(H5PL_PATH_SEPARATOR) + HDstrlen(dp->d_name) + 1 /*\0*/ + 4; /* Extra "+4" to quiet GCC warning - 2019/07/05, QAK */
|
|
|
|
if (NULL == (path = (char *)H5MM_calloc(len)))
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
|
|
|
|
HDsnprintf(path, len, "%s/%s", dir, dp->d_name);
|
|
|
|
/* Get info for directory entry */
|
|
if (HDstat(path, &my_stat) == -1)
|
|
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't stat file %s -- error was: %s", path, HDstrerror(errno))
|
|
|
|
/* If it is a directory, skip it */
|
|
if (S_ISDIR(my_stat.st_mode))
|
|
continue;
|
|
|
|
/* attempt to open the dynamic library as a filter library */
|
|
if (H5PL__open(path, search_params->type, search_params->key, found, plugin_info) < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed")
|
|
if (*found)
|
|
HGOTO_DONE(SUCCEED)
|
|
|
|
path = (char *)H5MM_xfree(path);
|
|
} /* end if */
|
|
} /* end while */
|
|
|
|
done:
|
|
if (dirp)
|
|
if (HDclosedir(dirp) < 0)
|
|
HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "can't close directory: %s", HDstrerror(errno))
|
|
|
|
path = (char *)H5MM_xfree(path);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__find_plugin_in_path() */
|
|
#else /* H5_HAVE_WIN32_API */
|
|
static herr_t
|
|
H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *found, const char *dir, const void **plugin_info)
|
|
{
|
|
WIN32_FIND_DATAA fdFile;
|
|
HANDLE hFind = INVALID_HANDLE_VALUE;
|
|
char *path = NULL;
|
|
char service[2048];
|
|
herr_t ret_value = SUCCEED;
|
|
|
|
FUNC_ENTER_STATIC
|
|
|
|
/* Check args - Just assert on package functions */
|
|
HDassert(search_params);
|
|
HDassert(found);
|
|
HDassert(dir);
|
|
HDassert(plugin_info);
|
|
|
|
/* Initialize the found parameter */
|
|
*found = FALSE;
|
|
|
|
/* Specify a file mask. *.* = We want everything! */
|
|
HDsprintf(service, "%s\\*.dll", dir);
|
|
if ((hFind = FindFirstFileA(service, &fdFile)) == INVALID_HANDLE_VALUE)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory")
|
|
|
|
/* Loop over all the files */
|
|
do {
|
|
/* Ignore '.' and '..' */
|
|
if (HDstrcmp(fdFile.cFileName, ".") != 0 && HDstrcmp(fdFile.cFileName, "..") != 0) {
|
|
|
|
/* XXX: Probably just continue here and move the code below over one tab */
|
|
|
|
size_t len;
|
|
|
|
/* Allocate & initialize the path name */
|
|
len = HDstrlen(dir) + HDstrlen(H5PL_PATH_SEPARATOR) + HDstrlen(fdFile.cFileName) + 1;
|
|
|
|
if (NULL == (path = (char *)H5MM_calloc(len)))
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
|
|
|
|
HDsnprintf(path, len, "%s\\%s", dir, fdFile.cFileName);
|
|
|
|
/* Ignore directories */
|
|
if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
continue;
|
|
|
|
/* attempt to open the dynamic library as a filter library */
|
|
if (H5PL__open(path, search_params->type, search_params->key, found, plugin_info) < 0)
|
|
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed")
|
|
if (*found)
|
|
HGOTO_DONE(SUCCEED)
|
|
|
|
path = (char *)H5MM_xfree(path);
|
|
}
|
|
} while (FindNextFileA(hFind, &fdFile));
|
|
|
|
done:
|
|
if (hFind != INVALID_HANDLE_VALUE)
|
|
FindClose(hFind);
|
|
if (path)
|
|
path = (char *)H5MM_xfree(path);
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
} /* end H5PL__find_plugin_in_path() */
|
|
#endif /* H5_HAVE_WIN32_API */
|
|
|