Default versioned API functions to earliest version for older API settings (#6280)

When a global API version is set (e.g., H5_USE_16_API), functions
introduced after that version now default to their earliest version
(version 1) instead of the latest. This prevents breakage when an
application uses an older API setting but calls functions that were
later versioned.
This commit is contained in:
Scot Breitenfeld
2026-04-07 11:06:32 -05:00
committed by GitHub
parent 00499095d6
commit cbff0315f3
6 changed files with 699 additions and 0 deletions
+169
View File
@@ -433,6 +433,19 @@ sub parse_line ($) {
$curr_sym_number++; $curr_sym_number++;
} }
# For API versions earlier than the function's introduction,
# default to the earliest version (version 1) for maximum compatibility
my $intro_vers = $vers_list[0];
foreach my $hash_vers (@versions) {
if ($hash_vers < $intro_vers) {
if ($line_type == 1) {
$api_vers_to_function_vers{$hash_vers}{$name} = 1;
} else {
$api_vers_to_type_vers{$hash_vers}{$name} = 1;
}
}
}
# Store the number of symbol versions in a hash table, indexed by the name # Store the number of symbol versions in a hash table, indexed by the name
if ($line_type == 1) { if ($line_type == 1) {
$functions{$name} = $#vers_list + 1; $functions{$name} = $#vers_list + 1;
@@ -519,6 +532,160 @@ sub create_doxygen_cmake ($) {
close CMAKE; close CMAKE;
} }
##############################################################################
# Create the generated test file for verifying API version defaulting
#
sub create_test ($) {
my $prefix = shift; # Get the prefix for the source file (e.g., "src/")
my $file = "tapi_version_default.c";
# Output to test directory (relative to src/)
my $test_dir = $prefix;
$test_dir =~ s/src\/?$/test\//;
# Validate the substitution succeeded
if ($test_dir eq $prefix && $prefix ne "") {
die "create_test: prefix '$prefix' does not end in 'src/' -- cannot derive test directory";
}
# Create test directory if it doesn't exist
if ($test_dir ne "" && ! -d $test_dir) {
mkdir $test_dir or die "unable to create directory: $test_dir";
}
# Open new test file
open TEST, ">${test_dir}${file}" or die "unable to create test file: ${test_dir}${file}";
# Print copyright and warning
print_copyright(*TEST);
print_warning(*TEST);
# Print test description
print TEST "/*\n";
print TEST " * Purpose: Tests that versioned API function macros default to the earliest\n";
print TEST " * version for functions introduced after the configured global API\n";
print TEST " * version. For example, with H5_USE_16_API, H5Sencode (introduced\n";
print TEST " * in v1.8) should map to H5Sencode1, not H5Sencode2.\n";
print TEST " *\n";
print TEST " * This test is compiled multiple times with different\n";
print TEST " * -DH5_USE_*_API and -DTEST_API_VERSION=* flags to verify each\n";
print TEST " * API version level.\n";
print TEST " */\n";
# Emit preamble that clears all global API version defaults.
# When the project is configured with a default API version (e.g.,
# HDF5_DEFAULT_API_VERSION=v16), H5pubconf.h defines H5_USE_16_API_DEFAULT,
# which causes H5version.h to activate H5_USE_16_API. If the test also
# defines -DH5_USE_200_API, both blocks would be active and the earliest
# one wins (setting everything to version 1). To isolate each test to
# exactly one API version, we include H5pubconf.h first (setting its
# include guard), then #undef all API version macros, and re-establish
# only the version under test before including the rest of the headers.
print TEST "/* Include config header first to set its include guard */\n";
print TEST "#include \"H5pubconf.h\"\n\n";
print TEST "/* Clear all API version macros that may have been set by the\n";
print TEST " * global default configuration, so only the version under test\n";
print TEST " * is active when H5version.h is processed.\n";
print TEST " */\n";
foreach my $api_vers (@versions) {
print TEST "#undef H5_USE_${api_vers}_API_DEFAULT\n";
print TEST "#undef H5_USE_${api_vers}_API\n";
}
print TEST "\n";
print TEST "/* Re-establish only the API version under test */\n";
my $first_preamble = 1;
foreach my $api_vers (@versions) {
if ($first_preamble) {
print TEST "#if TEST_API_VERSION == $api_vers\n";
$first_preamble = 0;
}
else {
print TEST "#elif TEST_API_VERSION == $api_vers\n";
}
print TEST " #define H5_USE_${api_vers}_API 1\n";
}
print TEST "#else\n";
print TEST " #error \"TEST_API_VERSION not set to a valid value\"\n";
print TEST "#endif\n\n";
print TEST "#include \"h5test.h\"\n\n";
# Print CHECK_VERS macro for functions
print TEST "/*\n";
print TEST " * Helper macro: check that a _vers macro equals an expected value.\n";
print TEST " */\n";
print TEST "#define CHECK_VERS(func_name, expected) \\\n";
print TEST " do { \\\n";
print TEST " if (func_name##_vers != (expected)) { \\\n";
print TEST " fprintf(stderr, \"FAIL: %s_vers = %d, expected %d\\n\", \\\n";
print TEST " #func_name, func_name##_vers, (expected)); \\\n";
print TEST " nerrors++; \\\n";
print TEST " } \\\n";
print TEST " } while (0)\n\n";
# Print CHECK_VERS_T macro for typedefs
print TEST "#define CHECK_VERS_T(type_name, expected) \\\n";
print TEST " do { \\\n";
print TEST " if (type_name##_t_vers != (expected)) { \\\n";
print TEST " fprintf(stderr, \"FAIL: %s_t_vers = %d, expected %d\\n\", \\\n";
print TEST " #type_name, type_name##_t_vers, (expected)); \\\n";
print TEST " nerrors++; \\\n";
print TEST " } \\\n";
print TEST " } while (0)\n\n";
# Print main function
print TEST "int\n";
print TEST "main(void)\n";
print TEST "{\n";
print TEST " int nerrors = 0;\n\n";
print TEST " TESTING(\"API version defaulting for versioned functions\");\n\n";
# Generate test sections for each API version
my $first = 1;
foreach my $api_vers (@versions) {
if ($first) {
print TEST "#if TEST_API_VERSION == $api_vers\n";
$first = 0;
}
else {
print TEST "#elif TEST_API_VERSION == $api_vers\n";
}
print TEST " printf(\"Configured with H5_USE_${api_vers}_API\\n\");\n\n";
# Print checks for all functions at this API version
for my $name (sort keys %{$api_vers_to_function_vers{$api_vers}}) {
my $expected = $api_vers_to_function_vers{$api_vers}{$name};
print TEST " CHECK_VERS($name, $expected);\n";
}
print TEST "\n";
# Print checks for all typedefs at this API version
for my $name (sort keys %{$api_vers_to_type_vers{$api_vers}}) {
my $expected = $api_vers_to_type_vers{$api_vers}{$name};
print TEST " CHECK_VERS_T($name, $expected);\n";
}
print TEST "\n";
}
# Close the #if/#elif chain
print TEST "#else\n";
print TEST "#error \"TEST_API_VERSION not set to a valid value\"\n";
print TEST "#endif\n\n";
# Print result checking and return
print TEST " if (nerrors) {\n";
print TEST " H5_FAILED();\n";
print TEST " fprintf(stderr, \" %d version check%s failed\\n\", nerrors, nerrors > 1 ? \"s\" : \"\");\n";
print TEST " return 1;\n";
print TEST " }\n\n";
print TEST " PASSED();\n";
print TEST " return 0;\n";
print TEST "}\n";
# Close test file
close TEST;
}
############################################################################## ##############################################################################
# Read symbol version file (given as command-line argument) in and process it # Read symbol version file (given as command-line argument) in and process it
# into internal data structures, then create header files. # into internal data structures, then create header files.
@@ -551,5 +718,7 @@ for $file (@ARGV) {
create_public($prefix); create_public($prefix);
print "Generating 'docs/doxygen/H5version_doxygen.cmake'\n"; print "Generating 'docs/doxygen/H5version_doxygen.cmake'\n";
create_doxygen_cmake($prefix); create_doxygen_cmake($prefix);
print "Generating 'test/tapi_version_default.c'\n";
create_test($prefix);
} }
+4
View File
@@ -99,6 +99,10 @@ We would like to thank the many HDF5 community members who contributed to this r
`H5Ovisit()` would previously internally traverse each object's path name from the iteration root group in order to retrieve information about that object, causing severe performance degradation with a deeply nested group structure. Modified the algorithm to instead retrieve information directly from the object. To get this benefit, users should use `H5Ovisit3()`, or use `H5Ovisit2()` with neither `H5O_INFO_HDR` nor `H5O_INFO_META_SIZE` selected in the `fields` parameter. Performance of `H5Ocopy()`, `H5Iget_name()`, and external links with a callback set should also improve in similar situations. `H5Ovisit()` would previously internally traverse each object's path name from the iteration root group in order to retrieve information about that object, causing severe performance degradation with a deeply nested group structure. Modified the algorithm to instead retrieve information directly from the object. To get this benefit, users should use `H5Ovisit3()`, or use `H5Ovisit2()` with neither `H5O_INFO_HDR` nor `H5O_INFO_META_SIZE` selected in the `fields` parameter. Performance of `H5Ocopy()`, `H5Iget_name()`, and external links with a callback set should also improve in similar situations.
### Versioned API functions now default to earliest version for older API settings
When a global API compatibility version is set (e.g., `H5_USE_16_API`), functions introduced after that version previously defaulted to their latest version, which could break applications. For example, an application using `H5_USE_16_API` that called `H5Sencode()` (introduced in 1.8, versioned in 1.12) would get `H5Sencode2()` instead of `H5Sencode1()`, potentially causing compilation or runtime failures. Versioned functions now default to their earliest (version 1) variant when the configured API level predates the function's introduction, providing maximum compatibility. See issue [#6278](https://github.com/HDFGroup/hdf5/issues/6278).
## Parallel Library ## Parallel Library
## Fortran Library ## Fortran Library
+84
View File
@@ -84,6 +84,10 @@
#define H5Dopen_vers 1 #define H5Dopen_vers 1
#endif /* !defined(H5Dopen_vers) */ #endif /* !defined(H5Dopen_vers) */
#if !defined(H5Dread_chunk_vers)
#define H5Dread_chunk_vers 1
#endif /* !defined(H5Dread_chunk_vers) */
#if !defined(H5Eclear_vers) #if !defined(H5Eclear_vers)
#define H5Eclear_vers 1 #define H5Eclear_vers 1
#endif /* !defined(H5Eclear_vers) */ #endif /* !defined(H5Eclear_vers) */
@@ -108,6 +112,10 @@
#define H5Ewalk_vers 1 #define H5Ewalk_vers 1
#endif /* !defined(H5Ewalk_vers) */ #endif /* !defined(H5Ewalk_vers) */
#if !defined(H5Fget_info_vers)
#define H5Fget_info_vers 1
#endif /* !defined(H5Fget_info_vers) */
#if !defined(H5Gcreate_vers) #if !defined(H5Gcreate_vers)
#define H5Gcreate_vers 1 #define H5Gcreate_vers 1
#endif /* !defined(H5Gcreate_vers) */ #endif /* !defined(H5Gcreate_vers) */
@@ -116,6 +124,58 @@
#define H5Gopen_vers 1 #define H5Gopen_vers 1
#endif /* !defined(H5Gopen_vers) */ #endif /* !defined(H5Gopen_vers) */
#if !defined(H5Iregister_type_vers)
#define H5Iregister_type_vers 1
#endif /* !defined(H5Iregister_type_vers) */
#if !defined(H5Lget_info_vers)
#define H5Lget_info_vers 1
#endif /* !defined(H5Lget_info_vers) */
#if !defined(H5Lget_info_by_idx_vers)
#define H5Lget_info_by_idx_vers 1
#endif /* !defined(H5Lget_info_by_idx_vers) */
#if !defined(H5Literate_vers)
#define H5Literate_vers 1
#endif /* !defined(H5Literate_vers) */
#if !defined(H5Literate_by_name_vers)
#define H5Literate_by_name_vers 1
#endif /* !defined(H5Literate_by_name_vers) */
#if !defined(H5Lvisit_vers)
#define H5Lvisit_vers 1
#endif /* !defined(H5Lvisit_vers) */
#if !defined(H5Lvisit_by_name_vers)
#define H5Lvisit_by_name_vers 1
#endif /* !defined(H5Lvisit_by_name_vers) */
#if !defined(H5Oget_info_vers)
#define H5Oget_info_vers 1
#endif /* !defined(H5Oget_info_vers) */
#if !defined(H5Oget_info_by_idx_vers)
#define H5Oget_info_by_idx_vers 1
#endif /* !defined(H5Oget_info_by_idx_vers) */
#if !defined(H5Oget_info_by_name_vers)
#define H5Oget_info_by_name_vers 1
#endif /* !defined(H5Oget_info_by_name_vers) */
#if !defined(H5Ovisit_vers)
#define H5Ovisit_vers 1
#endif /* !defined(H5Ovisit_vers) */
#if !defined(H5Ovisit_by_name_vers)
#define H5Ovisit_by_name_vers 1
#endif /* !defined(H5Ovisit_by_name_vers) */
#if !defined(H5Pencode_vers)
#define H5Pencode_vers 1
#endif /* !defined(H5Pencode_vers) */
#if !defined(H5Pget_filter_vers) #if !defined(H5Pget_filter_vers)
#define H5Pget_filter_vers 1 #define H5Pget_filter_vers 1
#endif /* !defined(H5Pget_filter_vers) */ #endif /* !defined(H5Pget_filter_vers) */
@@ -140,6 +200,10 @@
#define H5Rget_obj_type_vers 1 #define H5Rget_obj_type_vers 1
#endif /* !defined(H5Rget_obj_type_vers) */ #endif /* !defined(H5Rget_obj_type_vers) */
#if !defined(H5Sencode_vers)
#define H5Sencode_vers 1
#endif /* !defined(H5Sencode_vers) */
#if !defined(H5Tarray_create_vers) #if !defined(H5Tarray_create_vers)
#define H5Tarray_create_vers 1 #define H5Tarray_create_vers 1
#endif /* !defined(H5Tarray_create_vers) */ #endif /* !defined(H5Tarray_create_vers) */
@@ -148,6 +212,10 @@
#define H5Tcommit_vers 1 #define H5Tcommit_vers 1
#endif /* !defined(H5Tcommit_vers) */ #endif /* !defined(H5Tcommit_vers) */
#if !defined(H5Tdecode_vers)
#define H5Tdecode_vers 1
#endif /* !defined(H5Tdecode_vers) */
#if !defined(H5Tget_array_dims_vers) #if !defined(H5Tget_array_dims_vers)
#define H5Tget_array_dims_vers 1 #define H5Tget_array_dims_vers 1
#endif /* !defined(H5Tget_array_dims_vers) */ #endif /* !defined(H5Tget_array_dims_vers) */
@@ -164,6 +232,14 @@
#define H5E_auto_t_vers 1 #define H5E_auto_t_vers 1
#endif /* !defined(H5E_auto_t_vers) */ #endif /* !defined(H5E_auto_t_vers) */
#if !defined(H5O_info_t_vers)
#define H5O_info_t_vers 1
#endif /* !defined(H5O_info_t_vers) */
#if !defined(H5O_iterate_t_vers)
#define H5O_iterate_t_vers 1
#endif /* !defined(H5O_iterate_t_vers) */
#if !defined(H5Z_class_t_vers) #if !defined(H5Z_class_t_vers)
#define H5Z_class_t_vers 1 #define H5Z_class_t_vers 1
#endif /* !defined(H5Z_class_t_vers) */ #endif /* !defined(H5Z_class_t_vers) */
@@ -192,6 +268,10 @@
#define H5Dopen_vers 2 #define H5Dopen_vers 2
#endif /* !defined(H5Dopen_vers) */ #endif /* !defined(H5Dopen_vers) */
#if !defined(H5Dread_chunk_vers)
#define H5Dread_chunk_vers 1
#endif /* !defined(H5Dread_chunk_vers) */
#if !defined(H5Eclear_vers) #if !defined(H5Eclear_vers)
#define H5Eclear_vers 2 #define H5Eclear_vers 2
#endif /* !defined(H5Eclear_vers) */ #endif /* !defined(H5Eclear_vers) */
@@ -276,6 +356,10 @@
#define H5Ovisit_by_name_vers 1 #define H5Ovisit_by_name_vers 1
#endif /* !defined(H5Ovisit_by_name_vers) */ #endif /* !defined(H5Ovisit_by_name_vers) */
#if !defined(H5Pencode_vers)
#define H5Pencode_vers 1
#endif /* !defined(H5Pencode_vers) */
#if !defined(H5Pget_filter_vers) #if !defined(H5Pget_filter_vers)
#define H5Pget_filter_vers 2 #define H5Pget_filter_vers 2
#endif /* !defined(H5Pget_filter_vers) */ #endif /* !defined(H5Pget_filter_vers) */
+36
View File
@@ -655,6 +655,42 @@ foreach (h5_test ${H5_CHECK_TESTS})
ADD_H5_EXE(${h5_test}) ADD_H5_EXE(${h5_test})
endforeach () endforeach ()
#-- Adding test executables for API version defaulting
# Each is compiled with a different -DH5_USE_*_API and -DTEST_API_VERSION=*
# to verify that functions introduced after the configured API version
# default to their earliest version.
# The test source is auto-generated by bin/make_vers from H5vers.txt.
# Older API versions (v16-v114) require deprecated symbols to be enabled.
# NOTE: Cannot use ADD_H5_EXE here because multiple targets share one source
# file (tapi_version_default.c) with different compile definitions.
if (HDF5_ENABLE_DEPRECATED_SYMBOLS)
set (API_VERSION_TEST_NUMBERS 16 18 110 112 114 200)
else ()
set (API_VERSION_TEST_NUMBERS 200)
endif ()
foreach (api_num IN LISTS API_VERSION_TEST_NUMBERS)
set (test_name tapi_version_default_v${api_num})
add_executable (${test_name} ${HDF5_TEST_SOURCE_DIR}/tapi_version_default.c)
target_include_directories (${test_name} PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};${HDF5_TEST_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
target_compile_options(${test_name} PRIVATE ${HDF5_CMAKE_C_FLAGS})
target_compile_definitions(${test_name} PRIVATE
${HDF5_TEST_COMPILE_DEFS_PRIVATE}
H5_USE_${api_num}_API
TEST_API_VERSION=${api_num}
)
if (NOT BUILD_SHARED_LIBS)
TARGET_C_PROPERTIES (${test_name} STATIC)
target_link_libraries (${test_name} PRIVATE ${HDF5_TEST_LIB_TARGET})
else ()
TARGET_C_PROPERTIES (${test_name} SHARED)
target_link_libraries (${test_name} PRIVATE ${HDF5_TEST_LIBSH_TARGET})
endif ()
set_target_properties (${test_name} PROPERTIES FOLDER test)
if (HDF5_ENABLE_FORMATTERS)
clang_format (HDF5_TEST_${test_name}_FORMAT ${test_name})
endif ()
endforeach ()
#-- Adding test for libinfo #-- Adding test for libinfo
set (GREP_RUNNER ${PROJECT_BINARY_DIR}/GrepRunner.cmake) set (GREP_RUNNER ${PROJECT_BINARY_DIR}/GrepRunner.cmake)
file (WRITE ${GREP_RUNNER} "file (STRINGS \${TEST_PROGRAM} TEST_RESULT REGEX \"SUMMARY OF THE HDF5 CONFIGURATION\") file (WRITE ${GREP_RUNNER} "file (STRINGS \${TEST_PROGRAM} TEST_RESULT REGEX \"SUMMARY OF THE HDF5 CONFIGURATION\")
+14
View File
@@ -915,6 +915,20 @@ if ("H5TEST-error_test" MATCHES "${HDF5_DISABLE_TESTS_REGEX}")
set_tests_properties (H5TEST-error_test PROPERTIES DISABLED true) set_tests_properties (H5TEST-error_test PROPERTIES DISABLED true)
endif () endif ()
#-- Adding tests for API version defaulting
# API_VERSION_TEST_NUMBERS is defined in CMakeLists.txt and already in scope
foreach (api_num IN LISTS API_VERSION_TEST_NUMBERS)
add_test (NAME H5TEST-tapi_version_default_v${api_num}
COMMAND $<TARGET_FILE:tapi_version_default_v${api_num}>
)
set_tests_properties (H5TEST-tapi_version_default_v${api_num} PROPERTIES
WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST
)
if ("H5TEST-tapi_version_default_v${api_num}" MATCHES "${HDF5_DISABLE_TESTS_REGEX}")
set_tests_properties (H5TEST-tapi_version_default_v${api_num} PROPERTIES DISABLED true)
endif ()
endforeach ()
#-- Adding test for links_env #-- Adding test for links_env
add_test (NAME H5TEST-links_env-clear-objects add_test (NAME H5TEST-links_env-clear-objects
COMMAND ${CMAKE_COMMAND} -E remove COMMAND ${CMAKE_COMMAND} -E remove
+392
View File
@@ -0,0 +1,392 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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 LICENSE 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Generated automatically by bin/make_vers -- do not edit */
/* Add new versioned symbols to H5vers.txt file */
/*
* Purpose: Tests that versioned API function macros default to the earliest
* version for functions introduced after the configured global API
* version. For example, with H5_USE_16_API, H5Sencode (introduced
* in v1.8) should map to H5Sencode1, not H5Sencode2.
*
* This test is compiled multiple times with different
* -DH5_USE_*_API and -DTEST_API_VERSION=* flags to verify each
* API version level.
*/
/* Include config header first to set its include guard */
#include "H5pubconf.h"
/* Clear all API version macros that may have been set by the
* global default configuration, so only the version under test
* is active when H5version.h is processed.
*/
#undef H5_USE_16_API_DEFAULT
#undef H5_USE_16_API
#undef H5_USE_18_API_DEFAULT
#undef H5_USE_18_API
#undef H5_USE_110_API_DEFAULT
#undef H5_USE_110_API
#undef H5_USE_112_API_DEFAULT
#undef H5_USE_112_API
#undef H5_USE_114_API_DEFAULT
#undef H5_USE_114_API
#undef H5_USE_200_API_DEFAULT
#undef H5_USE_200_API
/* Re-establish only the API version under test */
#if TEST_API_VERSION == 16
#define H5_USE_16_API 1
#elif TEST_API_VERSION == 18
#define H5_USE_18_API 1
#elif TEST_API_VERSION == 110
#define H5_USE_110_API 1
#elif TEST_API_VERSION == 112
#define H5_USE_112_API 1
#elif TEST_API_VERSION == 114
#define H5_USE_114_API 1
#elif TEST_API_VERSION == 200
#define H5_USE_200_API 1
#else
#error "TEST_API_VERSION not set to a valid value"
#endif
#include "h5test.h"
/*
* Helper macro: check that a _vers macro equals an expected value.
*/
#define CHECK_VERS(func_name, expected) \
do { \
if (func_name##_vers != (expected)) { \
fprintf(stderr, "FAIL: %s_vers = %d, expected %d\n", #func_name, func_name##_vers, (expected)); \
nerrors++; \
} \
} while (0)
#define CHECK_VERS_T(type_name, expected) \
do { \
if (type_name##_t_vers != (expected)) { \
fprintf(stderr, "FAIL: %s_t_vers = %d, expected %d\n", #type_name, type_name##_t_vers, \
(expected)); \
nerrors++; \
} \
} while (0)
int
main(void)
{
int nerrors = 0;
TESTING("API version defaulting for versioned functions");
#if TEST_API_VERSION == 16
printf("Configured with H5_USE_16_API\n");
CHECK_VERS(H5Acreate, 1);
CHECK_VERS(H5Aiterate, 1);
CHECK_VERS(H5Dcreate, 1);
CHECK_VERS(H5Dopen, 1);
CHECK_VERS(H5Dread_chunk, 1);
CHECK_VERS(H5Eclear, 1);
CHECK_VERS(H5Eget_auto, 1);
CHECK_VERS(H5Eprint, 1);
CHECK_VERS(H5Epush, 1);
CHECK_VERS(H5Eset_auto, 1);
CHECK_VERS(H5Ewalk, 1);
CHECK_VERS(H5Fget_info, 1);
CHECK_VERS(H5Gcreate, 1);
CHECK_VERS(H5Gopen, 1);
CHECK_VERS(H5Iregister_type, 1);
CHECK_VERS(H5Lget_info, 1);
CHECK_VERS(H5Lget_info_by_idx, 1);
CHECK_VERS(H5Literate, 1);
CHECK_VERS(H5Literate_by_name, 1);
CHECK_VERS(H5Lvisit, 1);
CHECK_VERS(H5Lvisit_by_name, 1);
CHECK_VERS(H5Oget_info, 1);
CHECK_VERS(H5Oget_info_by_idx, 1);
CHECK_VERS(H5Oget_info_by_name, 1);
CHECK_VERS(H5Ovisit, 1);
CHECK_VERS(H5Ovisit_by_name, 1);
CHECK_VERS(H5Pencode, 1);
CHECK_VERS(H5Pget_filter, 1);
CHECK_VERS(H5Pget_filter_by_id, 1);
CHECK_VERS(H5Pinsert, 1);
CHECK_VERS(H5Pregister, 1);
CHECK_VERS(H5Rdereference, 1);
CHECK_VERS(H5Rget_obj_type, 1);
CHECK_VERS(H5Sencode, 1);
CHECK_VERS(H5Tarray_create, 1);
CHECK_VERS(H5Tcommit, 1);
CHECK_VERS(H5Tdecode, 1);
CHECK_VERS(H5Tget_array_dims, 1);
CHECK_VERS(H5Topen, 1);
CHECK_VERS_T(H5E_auto, 1);
CHECK_VERS_T(H5O_info, 1);
CHECK_VERS_T(H5O_iterate, 1);
CHECK_VERS_T(H5Z_class, 1);
#elif TEST_API_VERSION == 18
printf("Configured with H5_USE_18_API\n");
CHECK_VERS(H5Acreate, 2);
CHECK_VERS(H5Aiterate, 2);
CHECK_VERS(H5Dcreate, 2);
CHECK_VERS(H5Dopen, 2);
CHECK_VERS(H5Dread_chunk, 1);
CHECK_VERS(H5Eclear, 2);
CHECK_VERS(H5Eget_auto, 2);
CHECK_VERS(H5Eprint, 2);
CHECK_VERS(H5Epush, 2);
CHECK_VERS(H5Eset_auto, 2);
CHECK_VERS(H5Ewalk, 2);
CHECK_VERS(H5Fget_info, 1);
CHECK_VERS(H5Gcreate, 2);
CHECK_VERS(H5Gopen, 2);
CHECK_VERS(H5Iregister_type, 1);
CHECK_VERS(H5Lget_info, 1);
CHECK_VERS(H5Lget_info_by_idx, 1);
CHECK_VERS(H5Literate, 1);
CHECK_VERS(H5Literate_by_name, 1);
CHECK_VERS(H5Lvisit, 1);
CHECK_VERS(H5Lvisit_by_name, 1);
CHECK_VERS(H5Oget_info, 1);
CHECK_VERS(H5Oget_info_by_idx, 1);
CHECK_VERS(H5Oget_info_by_name, 1);
CHECK_VERS(H5Ovisit, 1);
CHECK_VERS(H5Ovisit_by_name, 1);
CHECK_VERS(H5Pencode, 1);
CHECK_VERS(H5Pget_filter, 2);
CHECK_VERS(H5Pget_filter_by_id, 2);
CHECK_VERS(H5Pinsert, 2);
CHECK_VERS(H5Pregister, 2);
CHECK_VERS(H5Rdereference, 1);
CHECK_VERS(H5Rget_obj_type, 2);
CHECK_VERS(H5Sencode, 1);
CHECK_VERS(H5Tarray_create, 2);
CHECK_VERS(H5Tcommit, 2);
CHECK_VERS(H5Tdecode, 1);
CHECK_VERS(H5Tget_array_dims, 2);
CHECK_VERS(H5Topen, 2);
CHECK_VERS_T(H5E_auto, 2);
CHECK_VERS_T(H5O_info, 1);
CHECK_VERS_T(H5O_iterate, 1);
CHECK_VERS_T(H5Z_class, 2);
#elif TEST_API_VERSION == 110
printf("Configured with H5_USE_110_API\n");
CHECK_VERS(H5Acreate, 2);
CHECK_VERS(H5Aiterate, 2);
CHECK_VERS(H5Dcreate, 2);
CHECK_VERS(H5Dopen, 2);
CHECK_VERS(H5Dread_chunk, 1);
CHECK_VERS(H5Eclear, 2);
CHECK_VERS(H5Eget_auto, 2);
CHECK_VERS(H5Eprint, 2);
CHECK_VERS(H5Epush, 2);
CHECK_VERS(H5Eset_auto, 2);
CHECK_VERS(H5Ewalk, 2);
CHECK_VERS(H5Fget_info, 2);
CHECK_VERS(H5Gcreate, 2);
CHECK_VERS(H5Gopen, 2);
CHECK_VERS(H5Iregister_type, 1);
CHECK_VERS(H5Lget_info, 1);
CHECK_VERS(H5Lget_info_by_idx, 1);
CHECK_VERS(H5Literate, 1);
CHECK_VERS(H5Literate_by_name, 1);
CHECK_VERS(H5Lvisit, 1);
CHECK_VERS(H5Lvisit_by_name, 1);
CHECK_VERS(H5Oget_info, 1);
CHECK_VERS(H5Oget_info_by_idx, 1);
CHECK_VERS(H5Oget_info_by_name, 1);
CHECK_VERS(H5Ovisit, 1);
CHECK_VERS(H5Ovisit_by_name, 1);
CHECK_VERS(H5Pencode, 1);
CHECK_VERS(H5Pget_filter, 2);
CHECK_VERS(H5Pget_filter_by_id, 2);
CHECK_VERS(H5Pinsert, 2);
CHECK_VERS(H5Pregister, 2);
CHECK_VERS(H5Rdereference, 2);
CHECK_VERS(H5Rget_obj_type, 2);
CHECK_VERS(H5Sencode, 1);
CHECK_VERS(H5Tarray_create, 2);
CHECK_VERS(H5Tcommit, 2);
CHECK_VERS(H5Tdecode, 1);
CHECK_VERS(H5Tget_array_dims, 2);
CHECK_VERS(H5Topen, 2);
CHECK_VERS_T(H5E_auto, 2);
CHECK_VERS_T(H5O_info, 1);
CHECK_VERS_T(H5O_iterate, 1);
CHECK_VERS_T(H5Z_class, 2);
#elif TEST_API_VERSION == 112
printf("Configured with H5_USE_112_API\n");
CHECK_VERS(H5Acreate, 2);
CHECK_VERS(H5Aiterate, 2);
CHECK_VERS(H5Dcreate, 2);
CHECK_VERS(H5Dopen, 2);
CHECK_VERS(H5Dread_chunk, 1);
CHECK_VERS(H5Eclear, 2);
CHECK_VERS(H5Eget_auto, 2);
CHECK_VERS(H5Eprint, 2);
CHECK_VERS(H5Epush, 2);
CHECK_VERS(H5Eset_auto, 2);
CHECK_VERS(H5Ewalk, 2);
CHECK_VERS(H5Fget_info, 2);
CHECK_VERS(H5Gcreate, 2);
CHECK_VERS(H5Gopen, 2);
CHECK_VERS(H5Iregister_type, 1);
CHECK_VERS(H5Lget_info, 2);
CHECK_VERS(H5Lget_info_by_idx, 2);
CHECK_VERS(H5Literate, 2);
CHECK_VERS(H5Literate_by_name, 2);
CHECK_VERS(H5Lvisit, 2);
CHECK_VERS(H5Lvisit_by_name, 2);
CHECK_VERS(H5Oget_info, 3);
CHECK_VERS(H5Oget_info_by_idx, 3);
CHECK_VERS(H5Oget_info_by_name, 3);
CHECK_VERS(H5Ovisit, 3);
CHECK_VERS(H5Ovisit_by_name, 3);
CHECK_VERS(H5Pencode, 2);
CHECK_VERS(H5Pget_filter, 2);
CHECK_VERS(H5Pget_filter_by_id, 2);
CHECK_VERS(H5Pinsert, 2);
CHECK_VERS(H5Pregister, 2);
CHECK_VERS(H5Rdereference, 2);
CHECK_VERS(H5Rget_obj_type, 2);
CHECK_VERS(H5Sencode, 2);
CHECK_VERS(H5Tarray_create, 2);
CHECK_VERS(H5Tcommit, 2);
CHECK_VERS(H5Tdecode, 1);
CHECK_VERS(H5Tget_array_dims, 2);
CHECK_VERS(H5Topen, 2);
CHECK_VERS_T(H5E_auto, 2);
CHECK_VERS_T(H5O_info, 2);
CHECK_VERS_T(H5O_iterate, 2);
CHECK_VERS_T(H5Z_class, 2);
#elif TEST_API_VERSION == 114
printf("Configured with H5_USE_114_API\n");
CHECK_VERS(H5Acreate, 2);
CHECK_VERS(H5Aiterate, 2);
CHECK_VERS(H5Dcreate, 2);
CHECK_VERS(H5Dopen, 2);
CHECK_VERS(H5Dread_chunk, 1);
CHECK_VERS(H5Eclear, 2);
CHECK_VERS(H5Eget_auto, 2);
CHECK_VERS(H5Eprint, 2);
CHECK_VERS(H5Epush, 2);
CHECK_VERS(H5Eset_auto, 2);
CHECK_VERS(H5Ewalk, 2);
CHECK_VERS(H5Fget_info, 2);
CHECK_VERS(H5Gcreate, 2);
CHECK_VERS(H5Gopen, 2);
CHECK_VERS(H5Iregister_type, 1);
CHECK_VERS(H5Lget_info, 2);
CHECK_VERS(H5Lget_info_by_idx, 2);
CHECK_VERS(H5Literate, 2);
CHECK_VERS(H5Literate_by_name, 2);
CHECK_VERS(H5Lvisit, 2);
CHECK_VERS(H5Lvisit_by_name, 2);
CHECK_VERS(H5Oget_info, 3);
CHECK_VERS(H5Oget_info_by_idx, 3);
CHECK_VERS(H5Oget_info_by_name, 3);
CHECK_VERS(H5Ovisit, 3);
CHECK_VERS(H5Ovisit_by_name, 3);
CHECK_VERS(H5Pencode, 2);
CHECK_VERS(H5Pget_filter, 2);
CHECK_VERS(H5Pget_filter_by_id, 2);
CHECK_VERS(H5Pinsert, 2);
CHECK_VERS(H5Pregister, 2);
CHECK_VERS(H5Rdereference, 2);
CHECK_VERS(H5Rget_obj_type, 2);
CHECK_VERS(H5Sencode, 2);
CHECK_VERS(H5Tarray_create, 2);
CHECK_VERS(H5Tcommit, 2);
CHECK_VERS(H5Tdecode, 1);
CHECK_VERS(H5Tget_array_dims, 2);
CHECK_VERS(H5Topen, 2);
CHECK_VERS_T(H5E_auto, 2);
CHECK_VERS_T(H5O_info, 2);
CHECK_VERS_T(H5O_iterate, 2);
CHECK_VERS_T(H5Z_class, 2);
#elif TEST_API_VERSION == 200
printf("Configured with H5_USE_200_API\n");
CHECK_VERS(H5Acreate, 2);
CHECK_VERS(H5Aiterate, 2);
CHECK_VERS(H5Dcreate, 2);
CHECK_VERS(H5Dopen, 2);
CHECK_VERS(H5Dread_chunk, 2);
CHECK_VERS(H5Eclear, 2);
CHECK_VERS(H5Eget_auto, 2);
CHECK_VERS(H5Eprint, 2);
CHECK_VERS(H5Epush, 2);
CHECK_VERS(H5Eset_auto, 2);
CHECK_VERS(H5Ewalk, 2);
CHECK_VERS(H5Fget_info, 2);
CHECK_VERS(H5Gcreate, 2);
CHECK_VERS(H5Gopen, 2);
CHECK_VERS(H5Iregister_type, 2);
CHECK_VERS(H5Lget_info, 2);
CHECK_VERS(H5Lget_info_by_idx, 2);
CHECK_VERS(H5Literate, 2);
CHECK_VERS(H5Literate_by_name, 2);
CHECK_VERS(H5Lvisit, 2);
CHECK_VERS(H5Lvisit_by_name, 2);
CHECK_VERS(H5Oget_info, 3);
CHECK_VERS(H5Oget_info_by_idx, 3);
CHECK_VERS(H5Oget_info_by_name, 3);
CHECK_VERS(H5Ovisit, 3);
CHECK_VERS(H5Ovisit_by_name, 3);
CHECK_VERS(H5Pencode, 2);
CHECK_VERS(H5Pget_filter, 2);
CHECK_VERS(H5Pget_filter_by_id, 2);
CHECK_VERS(H5Pinsert, 2);
CHECK_VERS(H5Pregister, 2);
CHECK_VERS(H5Rdereference, 2);
CHECK_VERS(H5Rget_obj_type, 2);
CHECK_VERS(H5Sencode, 2);
CHECK_VERS(H5Tarray_create, 2);
CHECK_VERS(H5Tcommit, 2);
CHECK_VERS(H5Tdecode, 2);
CHECK_VERS(H5Tget_array_dims, 2);
CHECK_VERS(H5Topen, 2);
CHECK_VERS_T(H5E_auto, 2);
CHECK_VERS_T(H5O_info, 2);
CHECK_VERS_T(H5O_iterate, 2);
CHECK_VERS_T(H5Z_class, 2);
#else
#error "TEST_API_VERSION not set to a valid value"
#endif
if (nerrors) {
H5_FAILED();
fprintf(stderr, " %d version check%s failed\n", nerrors, nerrors > 1 ? "s" : "");
return 1;
}
PASSED();
return 0;
}