summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5.c1
-rw-r--r--src/H5Edefin.h3
-rw-r--r--src/H5Einit.h7
-rw-r--r--src/H5Epubgen.h4
-rw-r--r--src/H5Eterm.h3
-rw-r--r--src/H5PL.c401
-rw-r--r--src/H5PLpkg.h59
-rw-r--r--src/H5PLprivate.h59
-rw-r--r--src/H5PLpublic.h45
-rw-r--r--src/H5Pocpl.c91
-rw-r--r--src/H5Pprivate.h2
-rw-r--r--src/H5Z.c62
-rw-r--r--src/H5Zprivate.h1
-rw-r--r--src/H5Zpublic.h6
-rw-r--r--src/H5config.h.in3
-rw-r--r--src/H5err.txt2
-rw-r--r--src/H5private.h1
-rw-r--r--src/Makefile.am4
-rw-r--r--src/Makefile.in7
-rw-r--r--src/hdf5.h1
20 files changed, 747 insertions, 15 deletions
diff --git a/src/H5.c b/src/H5.c
index 14ec7ca..25525a4 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -271,6 +271,7 @@ H5_term_library(void)
pending += DOWN(Z);
pending += DOWN(FD);
pending += DOWN(P);
+ pending += DOWN(PL);
/* Don't shut down the error code until other APIs which use it are shut down */
if(pending == 0)
pending += DOWN(E);
diff --git a/src/H5Edefin.h b/src/H5Edefin.h
index 2ae79e5..8557f13 100644
--- a/src/H5Edefin.h
+++ b/src/H5Edefin.h
@@ -25,6 +25,7 @@ hid_t H5E_FUNC_g = FAIL; /* Function entry/exit */
hid_t H5E_FILE_g = FAIL; /* File accessibilty */
hid_t H5E_SOHM_g = FAIL; /* Shared Object Header Messages */
hid_t H5E_SYM_g = FAIL; /* Symbol table */
+hid_t H5E_PLUGIN_g = FAIL; /* Plugin for dynamically loaded library */
hid_t H5E_VFL_g = FAIL; /* Virtual File Layer */
hid_t H5E_INTERNAL_g = FAIL; /* Internal error (too specific to document in detail) */
hid_t H5E_BTREE_g = FAIL; /* B-Tree node */
@@ -131,6 +132,8 @@ hid_t H5E_PATH_g = FAIL; /* Problem with path to object */
/* No error */
hid_t H5E_NONE_MINOR_g = FAIL; /* No error */
+/* Plugin errors */
+
/* File accessibilty errors */
hid_t H5E_FILEEXISTS_g = FAIL; /* File already exists */
hid_t H5E_FILEOPEN_g = FAIL; /* File already open */
diff --git a/src/H5Einit.h b/src/H5Einit.h
index a2eb02f..edd9bf5 100644
--- a/src/H5Einit.h
+++ b/src/H5Einit.h
@@ -44,6 +44,11 @@ if((msg = H5E_create_msg(cls, H5E_MAJOR, "Symbol table"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_SYM_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_PLUGIN_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Plugin for dynamically loaded library"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_PLUGIN_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_VFL_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Virtual File Layer"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
@@ -477,6 +482,8 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "No error"))==NULL)
if((H5E_NONE_MINOR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+/* Plugin errors */
+
/* File accessibilty errors */
assert(H5E_FILEEXISTS_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "File already exists"))==NULL)
diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h
index ddfb1d3..3df7d7e 100644
--- a/src/H5Epubgen.h
+++ b/src/H5Epubgen.h
@@ -28,6 +28,7 @@
#define H5E_FILE (H5OPEN H5E_FILE_g)
#define H5E_SOHM (H5OPEN H5E_SOHM_g)
#define H5E_SYM (H5OPEN H5E_SYM_g)
+#define H5E_PLUGIN (H5OPEN H5E_PLUGIN_g)
#define H5E_VFL (H5OPEN H5E_VFL_g)
#define H5E_INTERNAL (H5OPEN H5E_INTERNAL_g)
#define H5E_BTREE (H5OPEN H5E_BTREE_g)
@@ -60,6 +61,7 @@ H5_DLLVAR hid_t H5E_FUNC_g; /* Function entry/exit */
H5_DLLVAR hid_t H5E_FILE_g; /* File accessibilty */
H5_DLLVAR hid_t H5E_SOHM_g; /* Shared Object Header Messages */
H5_DLLVAR hid_t H5E_SYM_g; /* Symbol table */
+H5_DLLVAR hid_t H5E_PLUGIN_g; /* Plugin for dynamically loaded library */
H5_DLLVAR hid_t H5E_VFL_g; /* Virtual File Layer */
H5_DLLVAR hid_t H5E_INTERNAL_g; /* Internal error (too specific to document in detail) */
H5_DLLVAR hid_t H5E_BTREE_g; /* B-Tree node */
@@ -221,6 +223,8 @@ H5_DLLVAR hid_t H5E_PATH_g; /* Problem with path to object */
#define H5E_NONE_MINOR (H5OPEN H5E_NONE_MINOR_g)
H5_DLLVAR hid_t H5E_NONE_MINOR_g; /* No error */
+/* Plugin errors */
+
/* File accessibilty errors */
#define H5E_FILEEXISTS (H5OPEN H5E_FILEEXISTS_g)
#define H5E_FILEOPEN (H5OPEN H5E_FILEOPEN_g)
diff --git a/src/H5Eterm.h b/src/H5Eterm.h
index 6c621bc..f782db5 100644
--- a/src/H5Eterm.h
+++ b/src/H5Eterm.h
@@ -26,6 +26,7 @@ H5E_FUNC_g=
H5E_FILE_g=
H5E_SOHM_g=
H5E_SYM_g=
+H5E_PLUGIN_g=
H5E_VFL_g=
H5E_INTERNAL_g=
H5E_BTREE_g=
@@ -133,6 +134,8 @@ H5E_PATH_g=
/* No error */
H5E_NONE_MINOR_g=
+/* Plugin errors */
+
/* File accessibilty errors */
H5E_FILEEXISTS_g=
H5E_FILEOPEN_g=
diff --git a/src/H5PL.c b/src/H5PL.c
new file mode 100644
index 0000000..4bf059c
--- /dev/null
+++ b/src/H5PL.c
@@ -0,0 +1,401 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define H5PL_PACKAGE /*suppress error about including H5PLpkg */
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5PL_init_interface
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Dataset functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspace functions */
+#include "H5Zprivate.h" /* Filter pipeline */
+#include "H5PLpkg.h" /* Plugin */
+
+#define H5PL_DEFAULT_PATH "/usr:/usr/lib:/usr/local"
+#define H5PL_PATH_SEPERATOR ":"
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5PL_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5PL_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5PL_init_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5PL_init_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL_term_interface
+ *
+ * Purpose: Terminate the H5I interface: release all memory, reset all
+ * global variables to initial values. This only happens if all
+ * types have been destroyed from other interfaces.
+ *
+ * Return: Success: Positive if any action was taken that might
+ * affect some other interface; zero otherwise.
+ *
+ * Failure: Negative.
+ *
+ * Programmer: Raymond Lu
+ * 20 February 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5PL_term_interface(void)
+{
+ void *handle = NULL;
+ size_t i = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(H5_interface_initialize_g) {
+ /* Free the table of dynamic libraries */
+ for(i=0; i<H5PL_table_used_g; i++) {
+ handle = (H5PL_table_g[i]).handle;
+/*fprintf(stderr, "%s: handle=%p\n", FUNC, handle);*/
+ H5PL_close(handle);
+ }
+
+ H5PL_table_g = (H5PL_table_t *)H5MM_xfree(H5PL_table_g);
+ H5PL_table_used_g = H5PL_table_alloc_g = 0;
+
+ for(i = 0; i < num_paths; i++) {
+ if(path_table[i])
+ path_table[i] = H5MM_xfree(path_table[i]);
+ }
+ num_paths = 0;
+ path_found = FALSE;
+
+ H5_interface_initialize_g = 0;
+ i = 1;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(i)
+} /* end H5PL_term_interface() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL_load
+ *
+ * Purpose:
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 13 February 2013
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5PL_load(H5PL_type_t type, int id)
+{
+ char *dl_path = NULL;
+ char *origin_dl_path = NULL;
+ char *pathname = NULL;
+ size_t len = 0;
+ char *dir = NULL;
+ DIR *dirp = NULL;
+ int i;
+ void *handle = NULL;
+ htri_t found_in_table = FALSE;
+ htri_t found_in_path = FALSE;
+ H5Z_class2_t* (*PL_get_plugin_info)(void) = NULL;
+ H5Z_class2_t *plugin_info = NULL;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* Search in the table of already loaded plugin libraries */
+ if((found_in_table = H5PL_search_table(type, id, &plugin_info)) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in table failed")
+
+ /* Finish the function if found */
+ if(found_in_table && plugin_info) {
+ ret_value = (void *)plugin_info;
+ HGOTO_DONE(ret_value)
+ }
+
+ if(FALSE == path_found) {
+ origin_dl_path = HDgetenv("HDF5_PLUGIN_PATH");
+ if(origin_dl_path == NULL) {
+ len = HDstrlen(H5PL_DEFAULT_PATH) + 1;
+ dl_path = (char *)H5MM_malloc(len*sizeof(char));
+ HDstrncpy(dl_path, H5PL_DEFAULT_PATH, len-1);
+ dl_path[len-1] = '\0';
+ } else {
+ len = HDstrlen(origin_dl_path) + 1;
+ dl_path = (char *)H5MM_malloc(len*sizeof(char));
+ HDstrncpy(dl_path, origin_dl_path, len);
+ }
+
+ dir = HDstrtok(dl_path, H5PL_PATH_SEPERATOR);
+ while(dir) {
+ path_table[num_paths] = (char *)HDmalloc(HDstrlen(dir) + 1);
+ path_table[num_paths][0] = '\0';
+ HDstrcat(path_table[num_paths], dir);
+ num_paths++;
+ dir = HDstrtok(NULL, H5PL_PATH_SEPERATOR);
+ }
+
+ path_found = TRUE;
+ }
+
+#ifndef TMP
+ for(i=0; i<num_paths; i++) {
+ /*fprintf(stderr, "path[%d]=%s\n", i, path_table[i]);*/
+ if((found_in_path = H5PL_find(type, id, path_table[i], &plugin_info)) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in paths failed")
+
+ /* Finish the function if found */
+ if(found_in_path && plugin_info) {
+ ret_value = (void *)plugin_info;
+ HGOTO_DONE(ret_value)
+ }
+ }
+#endif
+
+done:
+ if(dl_path)
+ dl_path = (char *)H5MM_xfree(dl_path);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL_find
+ *
+ * Purpose: Given a path, this function opens the directory and iterates
+ * through all files to find the right plugin library. It
+ * loads the dynamic plugin library and keeps it on the list
+ * of loaded libraries.
+ *
+ * Return: TRUE on success,
+ * FALSE on not found,
+ * negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 13 February 2013
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5PL_find(H5PL_type_t plugin_type, int type_id, char *dir, void **info)
+{
+ char *dl_path = NULL;
+ char *pathname = NULL;
+ DIR *dirp = NULL;
+ int i;
+ void *handle = NULL;
+ htri_t found_in_table = FALSE;
+ hbool_t free_path = FALSE;
+ H5Z_class2_t* (*H5PL_get_plugin_info)(void) = NULL;
+ H5Z_class2_t *plugin_info = NULL;
+ htri_t ret_value = FALSE;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+
+ if(dirp = HDopendir(dir)) {
+ struct dirent *dp = NULL;
+ struct stat my_stat;
+ while ((dp = HDreaddir(dirp)) != NULL) {
+ if(!HDstrncmp(dp->d_name, "lib", 3) && HDstrstr(dp->d_name, ".so")) {
+ pathname = (char *)H5MM_malloc(strlen(dir) + strlen(dp->d_name) + 2);
+ HDstrncpy(pathname, dir, strlen(dir)+1);
+ HDstrcat(pathname, "/");
+ HDstrcat(pathname, dp->d_name);
+
+ /*fprintf(stderr, "dp->d_name=%s, pathname=%s. ", dp->d_name, pathname);
+ fprintf(stderr, "\n");*/
+
+ if(HDstat(pathname, &my_stat) == -1)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't stat file: %s", strerror(errno))
+
+ if(!S_ISDIR(my_stat.st_mode)) { /* if directory, skip it */
+ if(NULL == (handle = dlopen(pathname, RTLD_NOW|RTLD_LAZY))) {
+ /*fprintf(stderr, "not open dl library: %s", dlerror());*/
+ if(!HDstrcmp(dp->d_name, "libbogus2.so"))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't open dl library: %s", dlerror())
+ else
+ continue;
+ }
+
+ dlerror(); /*clear error*/
+ if(NULL == (H5PL_get_plugin_info = dlsym(handle, "H5PL_get_plugin_info"))) {
+ if(H5PL_close(handle) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library")
+ }
+
+ if(H5PL_get_plugin_info) {
+ if(NULL == (plugin_info = (*H5PL_get_plugin_info)())) {
+ if(H5PL_close(handle) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get plugin info")
+ }
+
+ if(plugin_info->id == type_id) {
+ (H5PL_table_g[H5PL_table_used_g]).handle = handle;
+ (H5PL_table_g[H5PL_table_used_g]).pl_type = plugin_type;
+ (H5PL_table_g[H5PL_table_used_g]).pl_id = plugin_info->id;
+/*fprintf(stderr, "%s: H5PL_table_used_g=%d, id=%d, id 2=%d\n", FUNC, H5PL_table_used_g, (H5PL_table_g[H5PL_table_used_g]).pl_id, plugin_info->id);*/
+ H5PL_table_used_g++;
+
+ *info = (void *)plugin_info;
+ ret_value = TRUE;
+
+ HGOTO_DONE(ret_value)
+ } else if(H5PL_close(handle) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library")
+ }
+ }
+
+ if(pathname)
+ pathname = (char *)H5MM_xfree(pathname);
+ }
+ }
+
+ if(HDclosedir(dirp) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "can't close directory: %s", strerror(errno))
+ dirp = NULL;
+ }
+
+
+done:
+ if(pathname)
+ pathname = (char *)H5MM_xfree(pathname);
+ if(dirp)
+ HDclosedir(dirp);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL_search_table
+ *
+ * Purpose:
+ *
+ * Return: TRUE on success,
+ * FALSE on not found,
+ * negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 13 February 2013
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5PL_search_table(H5PL_type_t plugin_type, int type_id, void **info)
+{
+ htri_t found = FALSE;
+ H5Z_class2_t* (*H5PL_get_plugin_info)(void) = NULL;
+ H5Z_class2_t *plugin_info = NULL;
+ int i;
+ htri_t ret_value = FALSE;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+/*if(0 < H5PL_table_used_g)
+fprintf(stderr, "%s: H5PL_table_used_g=%d, id=%d\n", FUNC, H5PL_table_used_g, (H5PL_table_g[H5PL_table_used_g-1]).pl_id);*/
+
+ /* Search in the table of already opened dynamic libraries */
+ if(0 < H5PL_table_used_g) {
+ for(i=0; i<H5PL_table_used_g; i++) {
+ if((plugin_type == (H5PL_table_g[i]).pl_type) && (type_id == (H5PL_table_g[i]).pl_id)) {
+ if(NULL == (H5PL_get_plugin_info = dlsym((H5PL_table_g[i]).handle, "H5PL_get_plugin_info")))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get function: %s", dlerror())
+
+ if(NULL == (plugin_info = (*H5PL_get_plugin_info)()))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get plugin info")
+
+ /*fprintf(stderr, "%s: handle=%p, H5PL_get_plugin_info=%p, plugin_info=%p, id=%d\n", FUNC, (H5PL_table_g[i]).handle, H5PL_get_plugin_info, plugin_info, plugin_info->id);*/
+
+ *info = (void *)plugin_info;
+ ret_value = TRUE;
+ }
+ }
+ }
+
+ /* Expand the table if it is small */
+ if(H5PL_table_used_g >= H5PL_table_alloc_g) {
+ size_t n = MAX(H5Z_MAX_NFILTERS, 2*H5PL_table_alloc_g);
+ H5PL_table_t *table = (H5PL_table_t *)H5MM_realloc(H5PL_table_g, n * sizeof(H5PL_table_t));
+
+ if(!table)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend dynamic library table")
+
+ H5PL_table_g = table;
+ H5PL_table_alloc_g = n;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL_close
+ *
+ * Purpose:
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 13 February 2013
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL_close(void *handle)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+/*fprintf(stderr, "%s: closing. handle=%p\n", FUNC, handle);*/
+ dlclose(handle);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
diff --git a/src/H5PLpkg.h b/src/H5PLpkg.h
new file mode 100644
index 0000000..adbe38a
--- /dev/null
+++ b/src/H5PLpkg.h
@@ -0,0 +1,59 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef H5PL_PACKAGE
+#error "Do not include this file outside the H5PL package!"
+#endif
+
+#ifndef _H5PLpkg_H
+#define _H5PLpkg_H
+
+/* Include private header file */
+#include "H5PLprivate.h"
+
+#define MAX_PATH_NUM 16
+
+/****************************/
+/* Local typedefs */
+/****************************/
+
+typedef struct H5PL_table_t {
+ H5PL_type_t pl_type; /* plugin type */
+ int pl_id; /* ID for the plugin */
+ void *handle; /* plugin handle */
+} H5PL_table_t;
+
+/****************************/
+/* Local variables */
+/****************************/
+
+static size_t H5PL_table_alloc_g = 0;
+static size_t H5PL_table_used_g = 0;
+static H5PL_table_t *H5PL_table_g = NULL;
+
+static char *path_table[MAX_PATH_NUM];
+static size_t num_paths = 0;
+static htri_t path_found = FALSE;
+
+/******************************/
+/* Package Private Prototypes */
+/******************************/
+
+/* Function prototypes for H5PL package scope */
+htri_t H5PL_find(H5PL_type_t plugin_type, int type_id, char *dir, void **info);
+htri_t H5PL_search_table(H5PL_type_t plugin_type, int type_id, void **info);
+
+#endif /* _H5PLpkg_H */
+
diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h
new file mode 100644
index 0000000..0a79249
--- /dev/null
+++ b/src/H5PLprivate.h
@@ -0,0 +1,59 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Programmer: Raymond Lu <songyulu@hdfgroup.org>
+ * 13 February 2013
+ */
+
+#ifndef _H5PLprivate_H
+#define _H5PLprivate_H
+
+/* Include package's public header */
+#include "H5PLpublic.h"
+
+/* Private headers needed by this file */
+#include "H5private.h" /* Generic Functions */
+
+#ifdef H5_HAVE_DLFCN_H
+ #include <dlfcn.h>
+#endif
+
+#include <dirent.h>
+/*#include <sys/dirent.h>*/
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+
+/*****************************/
+/* Library-private Variables */
+/*****************************/
+
+
+/***************************************/
+/* Library-private Function Prototypes */
+/***************************************/
+
+/* Internal API routines */
+H5_DLL void* H5PL_load(H5PL_type_t plugin_type, int type_id);
+H5_DLL herr_t H5PL_close(void *handle);
+
+#endif
diff --git a/src/H5PLpublic.h b/src/H5PLpublic.h
new file mode 100644
index 0000000..1f21f88
--- /dev/null
+++ b/src/H5PLpublic.h
@@ -0,0 +1,45 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Raymond Lu <songyulu@hdfgroup.org>
+ * 13 February 2013
+ */
+#ifndef _H5PLpublic_H
+#define _H5PLpublic_H
+
+/* Public headers needed by this file */
+#include "H5public.h"
+
+/****************************/
+/* Library Public Typedefs */
+/****************************/
+
+typedef enum H5PL_type_t {
+ H5PL_TYPE_ERROR = -1, /*error */
+ H5PL_TYPE_FILTER = 0, /*filter */
+ H5PL_TYPE_VFD = 1, /*virtual file driver */
+ H5PL_TYPE_NONE = 2 /*this must be last! */
+} H5PL_type_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c
index d8ddfee..032162a 100644
--- a/src/H5Pocpl.c
+++ b/src/H5Pocpl.c
@@ -38,6 +38,8 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
+#include "H5PLprivate.h" /* Dynamic plugin */
+#include "H5Zprivate.h" /* Filter pipeline */
#include "H5Opkg.h" /* Object headers */
#include "H5Ppkg.h" /* Property lists */
@@ -746,9 +748,9 @@ herr_t
H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags,
size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/])
{
- H5P_genplist_t *plist; /* Property list */
- H5O_pline_t pline; /* Filter pipeline */
- herr_t ret_value=SUCCEED; /* return value */
+ H5P_genplist_t *plist; /* Property list */
+ H5O_pline_t pline; /* Filter pipeline */
+ herr_t ret_value=SUCCEED; /* return value */
FUNC_ENTER_API(FAIL)
H5TRACE5("e", "iZfIuz*[a3]Iu", plist_id, filter, flags, cd_nelmts, cd_values);
@@ -765,6 +767,84 @@ H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags,
if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE)))
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ /* Call the private function */
+ if(H5P_set_filter(plist, filter, flags, cd_nelmts, cd_values) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "failed to call private function")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_filter() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P_set_filter
+ *
+ * Purpose: Adds the specified FILTER and corresponding properties to the
+ * end of the data or link output filter pipeline
+ * depending on whether PLIST is a dataset creation or group
+ * creation property list. The FLAGS argument specifies certain
+ * general properties of the filter and is documented below.
+ * The CD_VALUES is an array of CD_NELMTS integers which are
+ * auxiliary data for the filter. The integer vlues will be
+ * stored in the dataset object header as part of the filter
+ * information.
+ *
+ * The FLAGS argument is a bit vector of the following fields:
+ *
+ * H5Z_FLAG_OPTIONAL(0x0001)
+ * If this bit is set then the filter is optional. If the
+ * filter fails during an H5Dwrite() operation then the filter
+ * is just excluded from the pipeline for the chunk for which it
+ * failed; the filter will not participate in the pipeline
+ * during an H5Dread() of the chunk. If this bit is clear and
+ * the filter fails then the entire I/O operation fails.
+ * If this bit is set but encoding is disabled for a filter,
+ * attempting to write will generate an error.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, April 15, 1998
+ *
+ * Modifications:
+ *
+ * Raymond Lu
+ * Tuesday, October 2, 2001
+ * Changed the way to check parameter and set property for
+ * generic property list.
+ *
+ * Neil Fortner
+ * Wednesday, May 20, 2009
+ * Overloaded to accept gcpl's as well as dcpl's and moved to
+ * H5Pocpl.c
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P_set_filter(H5P_genplist_t *plist, H5Z_filter_t filter, unsigned int flags,
+ size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/])
+{
+ H5O_pline_t pline; /* Filter pipeline */
+ H5Z_class2_t *filter_info = NULL;
+ htri_t filter_avail = FALSE; /* Filter availability */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ if((filter_avail = H5Z_filter_avail(filter)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't check filter availability")
+
+ if(!filter_avail) {
+ if((filter_info = (H5Z_class2_t *)H5PL_load(H5PL_TYPE_FILTER, (int)filter)) == NULL)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, FAIL, "failed to load dynamically loaded plugin")
+/*if(filter_info)
+fprintf(stderr, "%s: filter_info=%p, filter_info->id=%d\n", FUNC, filter_info, filter_info->id);*/
+ if (H5Z_register (filter_info)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register filter")
+
+ }
+
+#ifndef TMP
/* Get the pipeline property to append to */
if(H5P_get(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
@@ -776,10 +856,11 @@ H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags,
/* Put the I/O pipeline information back into the property list */
if(H5P_set(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set pipeline")
+#endif
done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Pset_filter() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P_set_filter() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h
index 6560064..2006ced 100644
--- a/src/H5Pprivate.h
+++ b/src/H5Pprivate.h
@@ -108,6 +108,8 @@ H5_DLL herr_t H5P_modify_filter(H5P_genplist_t *plist, H5Z_filter_t filter,
H5_DLL herr_t H5P_get_filter_by_id(H5P_genplist_t *plist, H5Z_filter_t id,
unsigned int *flags, size_t *cd_nelmts, unsigned cd_values[],
size_t namelen, char name[], unsigned *filter_config);
+H5_DLL herr_t H5P_set_filter(H5P_genplist_t *plist, H5Z_filter_t filter,
+ unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]);
/* *SPECIAL* Don't make more of these! -QAK */
H5_DLL htri_t H5P_isa_class(hid_t plist_id, hid_t pclass_id);
diff --git a/src/H5Z.c b/src/H5Z.c
index 3bb3a44..8e8d80c 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -26,6 +26,7 @@
#include "H5MMprivate.h" /* Memory management */
#include "H5Oprivate.h" /* Object headers */
#include "H5Pprivate.h" /* Property lists */
+#include "H5PLprivate.h" /* Plugins */
#include "H5Sprivate.h" /* Dataspace functions */
#include "H5Zpkg.h" /* Data filters */
@@ -303,6 +304,8 @@ H5Z_register (const H5Z_class2_t *cls)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
+/*if(cls)
+fprintf(stderr, "cls=%p, cls->id=%d\n", cls, cls->id);*/
HDassert(cls);
HDassert(cls->id >= 0 && cls->id <= H5Z_FILTER_MAX);
@@ -450,7 +453,6 @@ done:
htri_t
H5Zfilter_avail(H5Z_filter_t id)
{
- size_t i; /* Local index variable */
htri_t ret_value=FALSE; /* Return value */
FUNC_ENTER_API(FAIL)
@@ -459,6 +461,36 @@ H5Zfilter_avail(H5Z_filter_t id)
/* Check args */
if(id<0 || id>H5Z_FILTER_MAX)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identification number")
+
+ if((ret_value = H5Z_filter_avail(id)) < 0)
+ HGOTO_ERROR (H5E_PLINE, H5E_NOTFOUND, FAIL, "unable to check the availability of the filter")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Zfilter_avail() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_filter_avail
+ *
+ * Purpose: Private function to check if a filter is available
+ *
+ * Return: Non-negative (TRUE/FALSE) on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 13 February 2013
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5Z_filter_avail(H5Z_filter_t id)
+{
+ size_t i; /* Local index variable */
+ htri_t ret_value=FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
/* Is the filter already registered? */
for(i=0; i<H5Z_table_used_g; i++)
@@ -468,8 +500,8 @@ H5Zfilter_avail(H5Z_filter_t id)
} /* end if */
done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Zfilter_avail() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_filter_avail() */
/*-------------------------------------------------------------------------
@@ -1088,16 +1120,36 @@ H5Z_pipeline(const H5O_pline_t *pline, unsigned flags,
failed |= (unsigned)1 << idx;
continue;/*filter excluded*/
}
+
+ /* If the filter isn't registered, try to load it dynamically and register it. Otherwise, return failure */
+ if ((fclass_idx=H5Z_find_idx(pline->filter[idx].id))<0) {
+ H5Z_class2_t *filter_info = NULL;
+
+ if((filter_info = (H5Z_class2_t *)H5PL_load(H5PL_TYPE_FILTER, (int)(pline->filter[idx].id))) != NULL) {
+ if (H5Z_register(filter_info)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register filter")
+ } else {
+ /* Print out the filter name to give more info. But the name is optional for
+ * the filter */
+ if(pline->filter[idx].name)
+ HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter '%s' is not registered",
+ pline->filter[idx].name)
+ else
+ HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter (name unavailable) is not registered")
+ }
+ }
+
+ /* Search in the table of registered filters again to find the dynamic filter just loaded and registered */
if ((fclass_idx=H5Z_find_idx(pline->filter[idx].id))<0) {
/* Print out the filter name to give more info. But the name is optional for
* the filter */
if(pline->filter[idx].name)
HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter '%s' is not registered",
- pline->filter[idx].name)
+ pline->filter[idx].name)
else
HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter (name unavailable) is not registered")
-
}
+
fclass=&H5Z_table_g[fclass_idx];
#ifdef H5Z_DEBUG
fstats=&H5Z_stat_table_g[fclass_idx];
diff --git a/src/H5Zprivate.h b/src/H5Zprivate.h
index c1528b3..f53b50c 100644
--- a/src/H5Zprivate.h
+++ b/src/H5Zprivate.h
@@ -92,6 +92,7 @@ H5_DLL herr_t H5Z_set_local_direct(const struct H5O_pline_t *pline);
H5_DLL H5Z_filter_info_t *H5Z_filter_info(const struct H5O_pline_t *pline,
H5Z_filter_t filter);
H5_DLL htri_t H5Z_all_filters_avail(const struct H5O_pline_t *pline);
+H5_DLL htri_t H5Z_filter_avail(H5Z_filter_t id);
H5_DLL herr_t H5Z_delete(struct H5O_pline_t *pline, H5Z_filter_t filter);
/* Data Transform Functions */
diff --git a/src/H5Zpublic.h b/src/H5Zpublic.h
index 5d9b5ed..b5ac475 100644
--- a/src/H5Zpublic.h
+++ b/src/H5Zpublic.h
@@ -42,6 +42,12 @@ typedef int H5Z_filter_t;
#define H5Z_FILTER_NBIT 5 /*nbit compression */
#define H5Z_FILTER_SCALEOFFSET 6 /*scale+offset compression */
#define H5Z_FILTER_RESERVED 256 /*filter ids below this value are reserved for library use */
+
+#define H5Z_FILTER_DYNLIB1 257
+#define H5Z_FILTER_DYNLIB2 258
+
+#define H5Z_FILTER_BZIP2 300
+
#define H5Z_FILTER_MAX 65535 /*maximum filter id */
/* General macros */
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 0308b38..c1cee13 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -187,6 +187,9 @@
/* Define to 1 if you have the <io.h> header file. */
#undef HAVE_IO_H
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
/* Define to 1 if you have the `dmalloc' library (-ldmalloc). */
#undef HAVE_LIBDMALLOC
diff --git a/src/H5err.txt b/src/H5err.txt
index ab3277f..282afd8 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -76,6 +76,7 @@ MAJOR, H5E_FSPACE, Free Space Manager
MAJOR, H5E_SOHM, Shared Object Header Messages
MAJOR, H5E_EARRAY, Extensible Array
MAJOR, H5E_FARRAY, Fixed Array
+MAJOR, H5E_PLUGIN, Plugin for dynamically loaded library
MAJOR, H5E_NONE_MAJOR, No error
# Sections (for grouping minor errors)
@@ -98,6 +99,7 @@ SECTION, HEAP, Heap errors
SECTION, FSPACE, Free space errors
SECTION, PIPELINE, I/O pipeline errors
SECTION, SYSTEM, System level errors
+SECTION, PLUGIN, Plugin errors
SECTION, NONE, No error
# Minor errors
diff --git a/src/H5private.h b/src/H5private.h
index bff4e59..3bc8722 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -2350,6 +2350,7 @@ H5_DLL int H5G_term_interface(void);
H5_DLL int H5I_term_interface(void);
H5_DLL int H5L_term_interface(void);
H5_DLL int H5P_term_interface(void);
+H5_DLL int H5PL_term_interface(void);
H5_DLL int H5R_term_interface(void);
H5_DLL int H5S_term_interface(void);
H5_DLL int H5T_term_interface(void);
diff --git a/src/Makefile.am b/src/Makefile.am
index 2669bdd..262bdc7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -88,7 +88,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5P.c H5Pacpl.c H5Pdapl.c H5Pdcpl.c \
H5Pdeprec.c H5Pdxpl.c H5Pencdec.c \
H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \
- H5Pgcpl.c H5Pint.c \
+ H5Pgcpl.c H5Pint.c H5PL.c \
H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \
H5R.c H5Rdeprec.c \
H5RC.c \
@@ -117,7 +117,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers
H5FDfamily.h H5FDlog.h H5FDmpi.h H5FDmpio.h H5FDmpiposix.h \
H5FDmulti.h H5FDsec2.h H5FDstdio.h \
H5Gpublic.h H5Ipublic.h H5Lpublic.h \
- H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \
+ H5MMpublic.h H5Opublic.h H5PLpublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \
H5Tpublic.h H5Zpublic.h
# install libhdf5.settings in lib directory
diff --git a/src/Makefile.in b/src/Makefile.in
index d9dca2d..f7fe1d8 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -158,7 +158,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5Orefcount.lo H5Osdspace.lo H5Oshared.lo H5Ostab.lo \
H5Oshmesg.lo H5Otest.lo H5Ounknown.lo H5P.lo H5Pacpl.lo \
H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo H5Pencdec.lo \
- H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo \
+ H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo H5PL.lo \
H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo \
H5Ptest.lo H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo \
H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \
@@ -585,7 +585,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5P.c H5Pacpl.c H5Pdapl.c H5Pdcpl.c \
H5Pdeprec.c H5Pdxpl.c H5Pencdec.c \
H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \
- H5Pgcpl.c H5Pint.c \
+ H5Pgcpl.c H5Pint.c H5PL.c \
H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \
H5R.c H5Rdeprec.c \
H5RC.c \
@@ -614,7 +614,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers
H5FDfamily.h H5FDlog.h H5FDmpi.h H5FDmpio.h H5FDmpiposix.h \
H5FDmulti.h H5FDsec2.h H5FDstdio.h \
H5Gpublic.h H5Ipublic.h H5Lpublic.h \
- H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \
+ H5MMpublic.h H5Opublic.h H5PLpublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \
H5Tpublic.h H5Zpublic.h
@@ -935,6 +935,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Otest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ounknown.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5P.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5PL.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pacpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdapl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pdcpl.Plo@am__quote@
diff --git a/src/hdf5.h b/src/hdf5.h
index a37329d..c2e4866 100644
--- a/src/hdf5.h
+++ b/src/hdf5.h
@@ -34,6 +34,7 @@
#include "H5MMpublic.h" /* Memory management */
#include "H5Opublic.h" /* Object headers */
#include "H5Ppublic.h" /* Property lists */
+#include "H5PLpublic.h" /* Plugin */
#include "H5Rpublic.h" /* References */
#include "H5Spublic.h" /* Dataspaces */
#include "H5Tpublic.h" /* Datatypes */