summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5.c220
-rw-r--r--src/H5mpi.c2
-rw-r--r--src/H5private.h70
-rw-r--r--src/H5public.h26
-rw-r--r--src/H5system.c170
5 files changed, 383 insertions, 105 deletions
diff --git a/src/H5.c b/src/H5.c
index 5a07b28..1b7407c 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -63,6 +63,10 @@ hbool_t H5_PKG_INIT_VAR = FALSE;
/* Library Private Variables */
/*****************************/
+/* Library incompatible release versions */
+const unsigned VERS_RELEASE_EXCEPTIONS[] = {0};
+const unsigned VERS_RELEASE_EXCEPTIONS_SIZE = 0;
+
/* statically initialize block for pthread_once call used in initializing */
/* the first global mutex */
#ifdef H5_HAVE_THREADSAFE
@@ -264,13 +268,13 @@ done:
} /* end H5_init_library() */
/*-------------------------------------------------------------------------
- * Function: H5_term_library
+ * Function: H5_term_library
*
- * Purpose: Terminate interfaces in a well-defined order due to
- * dependencies among the interfaces, then terminate
- * library-specific data.
+ * Purpose: Terminate interfaces in a well-defined order due to
+ * dependencies among the interfaces, then terminate
+ * library-specific data.
*
- * Return: void
+ * Return: void
*
*-------------------------------------------------------------------------
*/
@@ -456,22 +460,22 @@ done:
} /* end H5_term_library() */
/*-------------------------------------------------------------------------
- * Function: H5dont_atexit
+ * Function: H5dont_atexit
*
- * Purpose: Indicates that the library is not to clean up after itself
- * when the application exits by calling exit() or returning
- * from main(). This function must be called before any other
- * HDF5 function or constant is used or it will have no effect.
+ * Purpose: Indicates that the library is not to clean up after itself
+ * when the application exits by calling exit() or returning
+ * from main(). This function must be called before any other
+ * HDF5 function or constant is used or it will have no effect.
*
- * If this function is used then certain memory buffers will not
- * be de-allocated nor will open files be flushed automatically.
- * The application may still call H5close() explicitly to
- * accomplish these things.
+ * If this function is used then certain memory buffers will not
+ * be de-allocated nor will open files be flushed automatically.
+ * The application may still call H5close() explicitly to
+ * accomplish these things.
*
- * Return: Success: non-negative
+ * Return: Success: non-negative
*
- * Failure: negative if this function is called more than
- * once or if it is called too late.
+ * Failure: negative if this function is called more than
+ * once or if it is called too late.
*
*-------------------------------------------------------------------------
*/
@@ -492,19 +496,19 @@ H5dont_atexit(void)
} /* end H5dont_atexit() */
/*-------------------------------------------------------------------------
- * Function: H5garbage_collect
+ * Function: H5garbage_collect
*
- * Purpose: Walks through all the garbage collection routines for the
- * library, which are supposed to free any unused memory they have
- * allocated.
+ * Purpose: Walks through all the garbage collection routines for the
+ * library, which are supposed to free any unused memory they have
+ * allocated.
*
* These should probably be registered dynamically in a linked list of
* functions to call, but there aren't that many right now, so we
* hard-wire them...
*
- * Return: Success: non-negative
+ * Return: Success: non-negative
*
- * Failure: negative
+ * Failure: negative
*
*-------------------------------------------------------------------------
*/
@@ -525,9 +529,9 @@ done:
} /* end H5garbage_collect() */
/*-------------------------------------------------------------------------
- * Function: H5set_free_list_limits
+ * Function: H5set_free_list_limits
*
- * Purpose: Sets limits on the different kinds of free lists. Setting a value
+ * Purpose: Sets limits on the different kinds of free lists. Setting a value
* of -1 for a limit means no limit of that type. These limits are global
* for the entire library. Each "global" limit only applies to free lists
* of that type, so if an application sets a limit of 1 MB on each of the
@@ -545,9 +549,9 @@ done:
* int blk_global_lim; IN: The limit on all "block" free list memory used
* int blk_list_lim; IN: The limit on memory used in each "block" free list
*
- * Return: Success: non-negative
+ * Return: Success: non-negative
*
- * Failure: negative
+ * Failure: negative
*
*-------------------------------------------------------------------------
*/
@@ -571,11 +575,11 @@ done:
} /* end H5set_free_list_limits() */
/*-------------------------------------------------------------------------
- * Function: H5get_free_list_sizes
+ * Function: H5get_free_list_sizes
*
- * Purpose: Gets the current size of the different kinds of free lists that
- * the library uses to manage memory. The free list sizes can be set with
- * H5set_free_list_limits and garbage collected with H5garbage_collect.
+ * Purpose: Gets the current size of the different kinds of free lists that
+ * the library uses to manage memory. The free list sizes can be set with
+ * H5set_free_list_limits and garbage collected with H5garbage_collect.
* These lists are global for the entire library.
*
* Parameters:
@@ -584,8 +588,8 @@ done:
* size_t *blk_size; OUT: The current size of all "block" free list memory used
* size_t *fac_size; OUT: The current size of all "factory" free list memory used
*
- * Return: Success: non-negative
- * Failure: negative
+ * Return: Success: non-negative
+ * Failure: negative
*
* Programmer: Quincey Koziol
* Friday, March 6, 2020
@@ -609,23 +613,23 @@ done:
} /* end H5get_free_list_sizes() */
/*-------------------------------------------------------------------------
- * Function: H5get_alloc_stats
+ * Function: H5get_alloc_stats
*
- * Purpose: Gets the memory allocation statistics for the library, if the
- * --enable-memory-alloc-sanity-check option was given when building the
+ * Purpose: Gets the memory allocation statistics for the library, if the
+ * --enable-memory-alloc-sanity-check option was given when building the
* library. Applications can check whether this option was enabled by
- * detecting if the 'H5_MEMORY_ALLOC_SANITY_CHECK' macro is defined. This
- * option is enabled by default for debug builds of the library and
- * disabled by default for non-debug builds. If the option is not enabled,
- * all the values returned with be 0. These statistics are global for the
- * entire library, but don't include allocations from chunked dataset I/O
- * filters or non-native VOL connectors.
+ * detecting if the 'H5_MEMORY_ALLOC_SANITY_CHECK' macro is defined. This
+ * option is enabled by default for debug builds of the library and
+ * disabled by default for non-debug builds. If the option is not enabled,
+ * all the values returned with be 0. These statistics are global for the
+ * entire library, but don't include allocations from chunked dataset I/O
+ * filters or non-native VOL connectors.
*
* Parameters:
* H5_alloc_stats_t *stats; OUT: Memory allocation statistics
*
- * Return: Success: non-negative
- * Failure: negative
+ * Return: Success: non-negative
+ * Failure: negative
*
* Programmer: Quincey Koziol
* Saturday, March 7, 2020
@@ -758,12 +762,12 @@ H5__debug_mask(const char *s)
#ifdef H5_HAVE_PARALLEL
/*-------------------------------------------------------------------------
- * Function: H5__mpi_delete_cb
+ * Function: H5__mpi_delete_cb
*
- * Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5
+ * Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5
* library when the communicator is destroyed, i.e. on MPI_Finalize.
*
- * Return: MPI_SUCCESS
+ * Return: MPI_SUCCESS
*
*-------------------------------------------------------------------------
*/
@@ -777,18 +781,18 @@ H5__mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void
#endif /*H5_HAVE_PARALLEL*/
/*-------------------------------------------------------------------------
- * Function: H5get_libversion
+ * Function: H5get_libversion
*
- * Purpose: Returns the library version numbers through arguments. MAJNUM
- * will be the major revision number of the library, MINNUM the
- * minor revision number, and RELNUM the release revision number.
+ * Purpose: Returns the library version numbers through arguments. MAJNUM
+ * will be the major revision number of the library, MINNUM the
+ * minor revision number, and RELNUM the release revision number.
*
- * Note: When printing an HDF5 version number it should be printed as
+ * Note: When printing an HDF5 version number it should be printed as
*
- * printf("%u.%u.%u", maj, min, rel) or
- * printf("version %u.%u release %u", maj, min, rel)
+ * printf("%u.%u.%u", maj, min, rel) or
+ * printf("version %u.%u release %u", maj, min, rel)
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
*/
@@ -813,17 +817,20 @@ done:
} /* end H5get_libversion() */
/*-------------------------------------------------------------------------
- * Function: H5check_version
+ * Function: H5check_version
*
- * Purpose: Verifies that the arguments match the version numbers
- * compiled into the library. This function is intended to be
- * called from user to verify that the versions of header files
- * compiled into the application match the version of the hdf5
- * library.
+ * Purpose: Verifies that the arguments match the version numbers
+ * compiled into the library. This function is intended to be
+ * called from user to verify that the versions of header files
+ * compiled into the application match the version of the hdf5
+ * library.
+ * Within major.minor.release version, the expectation
+ * is that all release versions are compatible, exceptions to
+ * this rule must be added to the VERS_RELEASE_EXCEPTIONS list.
*
- * Return: Success: SUCCEED
+ * Return: Success: SUCCEED
*
- * Failure: abort()
+ * Failure: abort()
*
*-------------------------------------------------------------------------
*/
@@ -836,6 +843,15 @@ done:
"linked with a different version of static or shared HDF5 library.\n" \
"You should recompile the application or check your shared library related\n" \
"settings such as 'LD_LIBRARY_PATH'.\n"
+#define RELEASE_MISMATCH_WARNING \
+ "Warning! ***HDF5 library release mismatched error***\n" \
+ "The HDF5 header files used to compile this application are not compatible with\n" \
+ "the version used by the HDF5 library to which this application is linked.\n" \
+ "Data corruption or segmentation faults may occur if the application continues.\n" \
+ "This can happen when an application was compiled by one version of HDF5 but\n" \
+ "linked with an incompatible version of static or shared HDF5 library.\n" \
+ "You should recompile the application or check your shared library related\n" \
+ "settings such as 'LD_LIBRARY_PATH'.\n"
herr_t
H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
@@ -864,7 +880,11 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
disable_version_check = (unsigned int)HDstrtol(s, NULL, 0);
}
- if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE != relnum) {
+ /* H5_VERS_MAJOR and H5_VERS_MINOR must match */
+ /* Cast relnum to int to avoid warning for unsigned < 0 comparison
+ * in first release versions */
+ if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > (int)relnum) {
+
switch (disable_version_check) {
case 0:
HDfprintf(stderr, "%s%s", version_mismatch_warning,
@@ -899,7 +919,51 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
break;
} /* end switch */
- } /* end if */
+ } /* end if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > relnum) */
+
+ /* H5_VERS_RELEASE should be compatible, we will only add checks for exceptions */
+ if (H5_VERS_RELEASE != relnum) {
+ for (unsigned i = 0; i < VERS_RELEASE_EXCEPTIONS_SIZE; i++) {
+ /* Check for incompatible headers or incompatible library */
+ if (VERS_RELEASE_EXCEPTIONS[i] == relnum || VERS_RELEASE_EXCEPTIONS[i] == H5_VERS_RELEASE) {
+ switch (disable_version_check) {
+ case 0:
+ HDfprintf(
+ stderr, "%s%s", version_mismatch_warning,
+ "You can, at your own risk, disable this warning by setting the environment\n"
+ "variable 'HDF5_DISABLE_VERSION_CHECK' to a value of '1'.\n"
+ "Setting it to 2 or higher will suppress the warning messages totally.\n");
+ /* Mention the versions we are referring to */
+ HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum,
+ relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR,
+ (unsigned)H5_VERS_RELEASE);
+
+ /* Bail out now. */
+ HDfputs("Bye...\n", stderr);
+ HDabort();
+ case 1:
+ /* continue with a warning */
+ /* Note that the warning message is embedded in the format string.*/
+ HDfprintf(stderr,
+ "%s'HDF5_DISABLE_VERSION_CHECK' "
+ "environment variable is set to %d, application will\n"
+ "continue at your own risk.\n",
+ version_mismatch_warning, disable_version_check);
+ /* Mention the versions we are referring to */
+ HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum,
+ relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR,
+ (unsigned)H5_VERS_RELEASE);
+ break;
+ default:
+ /* 2 or higher: continue silently */
+ break;
+ } /* end switch */
+
+ } /* end if */
+
+ } /* end for */
+
+ } /* end if (H5_VERS_RELEASE != relnum) */
/* Indicate that the version check has been performed */
checked = 1;
@@ -944,7 +1008,7 @@ done:
* is failing inexplicably, then try calling this function
* first.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
*/
@@ -965,9 +1029,9 @@ done:
/*-------------------------------------------------------------------------
* Function: H5close
*
- * Purpose: Terminate the library and release all resources.
+ * Purpose: Terminate the library and release all resources.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
*-------------------------------------------------------------------------
*/
@@ -988,9 +1052,9 @@ H5close(void)
} /* end H5close() */
/*-------------------------------------------------------------------------
- * Function: H5allocate_memory
+ * Function: H5allocate_memory
*
- * Purpose: Allocate a memory buffer with the semantics of malloc().
+ * Purpose: Allocate a memory buffer with the semantics of malloc().
*
* NOTE: This function is intended for use with filter
* plugins so that all allocation and free operations
@@ -1028,9 +1092,9 @@ H5allocate_memory(size_t size, hbool_t clear)
} /* end H5allocate_memory() */
/*-------------------------------------------------------------------------
- * Function: H5resize_memory
+ * Function: H5resize_memory
*
- * Purpose: Resize a memory buffer with the semantics of realloc().
+ * Purpose: Resize a memory buffer with the semantics of realloc().
*
* NOTE: This function is intended for use with filter
* plugins so that all allocation and free operations
@@ -1065,14 +1129,14 @@ H5resize_memory(void *mem, size_t size)
} /* end H5resize_memory() */
/*-------------------------------------------------------------------------
- * Function: H5free_memory
+ * Function: H5free_memory
*
- * Purpose: Frees memory allocated by the library that it is the user's
+ * Purpose: Frees memory allocated by the library that it is the user's
* responsibility to free. Ensures that the same library
* that was used to allocate the memory frees it. Passing
* NULL pointers is allowed.
*
- * Return: SUCCEED/FAIL
+ * Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
@@ -1089,12 +1153,12 @@ H5free_memory(void *mem)
} /* end H5free_memory() */
/*-------------------------------------------------------------------------
- * Function: H5is_library_threadsafe
+ * Function: H5is_library_threadsafe
*
- * Purpose: Checks to see if the library was built with thread-safety
+ * Purpose: Checks to see if the library was built with thread-safety
* enabled.
*
- * Return: SUCCEED/FAIL
+ * Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
diff --git a/src/H5mpi.c b/src/H5mpi.c
index 9749721..4a8aa44 100644
--- a/src/H5mpi.c
+++ b/src/H5mpi.c
@@ -523,7 +523,7 @@ H5_mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, MPI_Datat
MPI_Type_get_extent(old_type, &unused_lb_arg, &old_extent);
}
- /* Set up the arguments for MPI_Type_struct constructor */
+ /* Set up the arguments for MPI_Type_create_struct() */
type[0] = outer_type;
type[1] = leftover_type;
block_len[0] = 1;
diff --git a/src/H5private.h b/src/H5private.h
index 808c2ce..1fd95dc 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -31,19 +31,19 @@
#include <errno.h>
#include <fcntl.h>
#include <float.h>
-#include <limits.h>
#include <math.h>
#include <signal.h>
-#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* POSIX headers */
+#ifdef H5_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
#ifdef H5_HAVE_UNISTD_H
#include <pwd.h>
#include <unistd.h>
-#include <sys/types.h>
#include <sys/wait.h>
#endif
@@ -130,22 +130,21 @@
#define H5_DEFAULT_VOL H5VL_NATIVE
#ifdef H5_HAVE_WIN32_API
+
/* The following two defines must be before any windows headers are included */
#define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
#define NOGDI /* Exclude Graphic Display Interface macros */
-#ifdef H5_HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
+#include <windows.h>
+
+#include <direct.h> /* For _getcwd() */
+#include <io.h> /* POSIX I/O */
+#include <winsock2.h> /* For GetUserName() */
#ifdef H5_HAVE_THREADSAFE
#include <process.h> /* For _beginthread() */
#endif
-#include <windows.h>
-#include <direct.h> /* For _getcwd() */
-#include <io.h> /* POSIX I/O */
-
#endif /*H5_HAVE_WIN32_API*/
#ifndef F_OK
@@ -2524,6 +2523,57 @@ H5_DLL double H5_get_time(void);
H5_DLL herr_t H5_build_extpath(const char *name, char **extpath /*out*/);
H5_DLL herr_t H5_combine_path(const char *path1, const char *path2, char **full_name /*out*/);
+/* getopt(3) equivalent that papers over the lack of long options on BSD
+ * and lack of Windows support.
+ */
+H5_DLLVAR int H5_opterr; /* get_option prints errors if this is on */
+H5_DLLVAR int H5_optind; /* token pointer */
+H5_DLLVAR const char *H5_optarg; /* flag argument (or value) */
+
+enum h5_arg_level {
+ no_arg = 0, /* doesn't take an argument */
+ require_arg, /* requires an argument */
+ optional_arg /* argument is optional */
+};
+
+/*
+ * get_option determines which options are specified on the command line and
+ * returns a pointer to any arguments possibly associated with the option in
+ * the ``H5_optarg'' variable. get_option returns the shortname equivalent of
+ * the option. The long options are specified in the following way:
+ *
+ * struct h5_long_options foo[] = {
+ * { "filename", require_arg, 'f' },
+ * { "append", no_arg, 'a' },
+ * { "width", require_arg, 'w' },
+ * { NULL, 0, 0 }
+ * };
+ *
+ * Long named options can have arguments specified as either:
+ *
+ * ``--param=arg'' or ``--param arg''
+ *
+ * Short named options can have arguments specified as either:
+ *
+ * ``-w80'' or ``-w 80''
+ *
+ * and can have more than one short named option specified at one time:
+ *
+ * -aw80
+ *
+ * in which case those options which expect an argument need to come at the
+ * end.
+ */
+struct h5_long_options {
+ const char * name; /* Name of the long option */
+ enum h5_arg_level has_arg; /* Whether we should look for an arg */
+ char shortval; /* The shortname equivalent of long arg
+ * this gets returned from get_option
+ */
+};
+
+H5_DLL int H5_get_option(int argc, const char **argv, const char *opt, const struct h5_long_options *l_opt);
+
#ifdef H5_HAVE_PARALLEL
/* Generic MPI functions */
H5_DLL hsize_t H5_mpi_set_bigio_count(hsize_t new_count);
diff --git a/src/H5public.h b/src/H5public.h
index 30d297e..495af6f 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -35,22 +35,23 @@
#include <features.h> /* For setting POSIX, BSD, etc. compatibility */
#endif
-#ifdef H5_HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#include <limits.h> /* For H5T_NATIVE_CHAR defn in H5Tpublic.h */
-#include <stdarg.h> /* For variadic functions in H5VLpublic.h */
-
-#include <stdint.h> /* For C9x types */
-
+/* C library header files for things that appear in HDF5 public headers */
#ifdef __cplusplus
#define __STDC_FORMAT_MACROS
#endif
-#include <inttypes.h> /* C99/POSIX.1 header for uint64_t, PRIu64 */
-
-#ifdef H5_HAVE_STDDEF_H
+#include <inttypes.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdbool.h>
#include <stddef.h>
+#include <stdint.h>
+
+/* Unlike most sys/ headers, which are POSIX-only, sys/types.h is avaible
+ * on Windows, though it doesn't necessarily contain all the POSIX types
+ * we need for HDF5 (e.g. ssize_t).
+ */
+#ifdef H5_HAVE_SYS_TYPES_H
+#include <sys/types.h>
#endif
#ifdef H5_HAVE_PARALLEL
@@ -214,7 +215,6 @@ typedef int herr_t;
* }
* \endcode
*/
-#include <stdbool.h>
typedef bool hbool_t;
typedef int htri_t;
diff --git a/src/H5system.c b/src/H5system.c
index 4aae743..56110ea 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -487,7 +487,7 @@ Wsetenv(const char *name, const char *value, int overwrite)
return (int)_putenv_s(name, value);
} /* end Wsetenv() */
-#ifdef H5_HAVE_WINSOCK2_H
+#ifdef H5_HAVE_WIN32_API
#pragma comment(lib, "advapi32.lib")
#endif
@@ -572,12 +572,12 @@ char *
Wgetlogin(void)
{
-#ifdef H5_HAVE_WINSOCK2_H
+#ifdef H5_HAVE_WIN32_API
DWORD bufferCount = WloginBuffer_count;
if (GetUserName(Wlogin_buffer, &bufferCount) != 0)
return (Wlogin_buffer);
else
-#endif /* H5_HAVE_WINSOCK2_H */
+#endif
return NULL;
}
@@ -1058,3 +1058,167 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5_expand_windows_env_vars() */
#endif /* H5_HAVE_WIN32_API */
+
+/* Global variables */
+int H5_opterr = 1; /* Get_option prints errors if this is on */
+int H5_optind = 1; /* Token pointer */
+const char *H5_optarg; /* Flag argument (or value) */
+
+/*-------------------------------------------------------------------------
+ * Function: H5_get_option
+ *
+ * Purpose: Determine the command-line options a user specified. We can
+ * accept both short and long type command-lines.
+ *
+ * Return: Success: The short valued "name" of the command line
+ * parameter or EOF if there are no more
+ * parameters to process.
+ *
+ * Failure: A question mark.
+ *-------------------------------------------------------------------------
+ */
+int
+H5_get_option(int argc, const char **argv, const char *opts, const struct h5_long_options *l_opts)
+{
+ static int sp = 1; /* character index in current token */
+ int optopt = '?'; /* option character passed back to user */
+
+ if (sp == 1) {
+ /* check for more flag-like tokens */
+ if (H5_optind >= argc || argv[H5_optind][0] != '-' || argv[H5_optind][1] == '\0') {
+ return EOF;
+ }
+ else if (HDstrcmp(argv[H5_optind], "--") == 0) {
+ H5_optind++;
+ return EOF;
+ }
+ }
+
+ if (sp == 1 && argv[H5_optind][0] == '-' && argv[H5_optind][1] == '-') {
+ /* long command line option */
+ int i;
+ const char ch = '=';
+ char * arg = HDstrdup(&argv[H5_optind][2]);
+ size_t arg_len = 0;
+
+ H5_optarg = strchr(&argv[H5_optind][2], ch);
+ arg_len = HDstrlen(&argv[H5_optind][2]);
+ if (H5_optarg) {
+ arg_len -= HDstrlen(H5_optarg);
+ H5_optarg++; /* skip the equal sign */
+ }
+ arg[arg_len] = 0;
+
+ for (i = 0; l_opts && l_opts[i].name; i++) {
+ if (HDstrcmp(arg, l_opts[i].name) == 0) {
+ /* we've found a matching long command line flag */
+ optopt = l_opts[i].shortval;
+
+ if (l_opts[i].has_arg != no_arg) {
+ if (H5_optarg == NULL) {
+ if (l_opts[i].has_arg != optional_arg) {
+ if (H5_optind < (argc - 1))
+ if (argv[H5_optind + 1][0] != '-')
+ H5_optarg = argv[++H5_optind];
+ }
+ else if (l_opts[i].has_arg == require_arg) {
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: option required for \"--%s\" flag\n", argv[0], arg);
+
+ optopt = '?';
+ }
+ }
+ }
+ else {
+ if (H5_optarg) {
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: no option required for \"%s\" flag\n", argv[0], arg);
+
+ optopt = '?';
+ }
+ }
+ break;
+ }
+ }
+
+ if (l_opts[i].name == NULL) {
+ /* exhausted all of the l_opts we have and still didn't match */
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: unknown option \"%s\"\n", argv[0], arg);
+
+ optopt = '?';
+ }
+
+ H5_optind++;
+ sp = 1;
+
+ HDfree(arg);
+ }
+ else {
+ register char *cp; /* pointer into current token */
+
+ /* short command line option */
+ optopt = argv[H5_optind][sp];
+
+ if (optopt == ':' || (cp = HDstrchr(opts, optopt)) == 0) {
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: unknown option \"%c\"\n", argv[0], optopt);
+
+ /* if no chars left in this token, move to next token */
+ if (argv[H5_optind][++sp] == '\0') {
+ H5_optind++;
+ sp = 1;
+ }
+ return '?';
+ }
+
+ if (*++cp == ':') {
+ /* if a value is expected, get it */
+ if (argv[H5_optind][sp + 1] != '\0') {
+ /* flag value is rest of current token */
+ H5_optarg = &argv[H5_optind++][sp + 1];
+ }
+ else if (++H5_optind >= argc) {
+ if (H5_opterr)
+ HDfprintf(stderr, "%s: value expected for option \"%c\"\n", argv[0], optopt);
+
+ optopt = '?';
+ }
+ else {
+ /* flag value is next token */
+ H5_optarg = argv[H5_optind++];
+ }
+
+ sp = 1;
+ }
+ /* wildcard argument */
+ else if (*cp == '*') {
+ /* check the next argument */
+ H5_optind++;
+ /* we do have an extra argument, check if not last */
+ if ((H5_optind + 1) < argc) {
+ if (argv[H5_optind][0] != '-') {
+ H5_optarg = argv[H5_optind++];
+ }
+ else {
+ H5_optarg = NULL;
+ }
+ }
+ else {
+ H5_optarg = NULL;
+ }
+ }
+ else {
+ /* set up to look at next char in token, next time */
+ if (argv[H5_optind][++sp] == '\0') {
+ /* no more in current token, so setup next token */
+ H5_optind++;
+ sp = 1;
+ }
+ H5_optarg = NULL;
+ }
+ }
+
+ /* return the current flag character found */
+ return optopt;
+}