From a179e17833e8a88aeb91f63a46ae64e63b8f2006 Mon Sep 17 00:00:00 2001 From: jhendersonHDF Date: Thu, 31 Oct 2024 15:54:25 -0500 Subject: [PATCH] Implement support for complex number datatypes (#4630) * Implement support for complex number datatypes Adds the new datatype class H5T_COMPLEX Adds the new API function H5Tcomplex_create which creates a complex number datatype from an ID of a base floating-point datatype Adds the new feature check macros H5_HAVE_COMPLEX_NUMBERS and H5_HAVE_C99_COMPLEX_NUMBERS Adds the new datatype size macros H5_SIZEOF_FLOAT_COMPLEX, H5_SIZEOF_DOUBLE_COMPLEX and H5_SIZEOF_LONG_DOUBLE_COMPLEX Adds the new datatype ID macros H5T_NATIVE_FLOAT_COMPLEX, H5T_NATIVE_DOUBLE_COMPLEX, H5T_NATIVE_LDOUBLE_COMPLEX, H5T_CPLX_IEEE_F16LE, H5T_CPLX_IEEE_F16BE, H5T_CPLX_IEEE_F32LE, H5T_CPLX_IEEE_F32BE, H5T_CPLX_IEEE_F64LE and H5T_CPLX_IEEE_F64BE Adds hard and soft datatype conversion paths between complex number datatypes and all the integer and floating-point datatypes, as well as between other complex number datatypes Adds a special conversion path between complex number datatypes and array or compound datatypes where the in-memory layout of data is the same between the datatypes and data can be converted directly Adds support for complex number datatypes to the h5dump, h5ls and h5diff/ph5diff tools. Allows h5dump '-m' option to change floating-point printing format for float complex and double complex datatypes, as well as long double complex if it has the same size as double complex Adds minimal support to the h5watch and h5import tools Adds support for the predefined complex number datatypes and H5Tcomplex_create function to the Java wrappers. Also adds initial, untested support to the JNI for future use with HDFView Adds support for just the H5T_COMPLEX datatype class to the Fortran wrappers Adds support for the predefined complex number datatypes and H5Tcomplex_create function to the high level library H5LT interface for use with the H5LTtext_to_dtype and H5LTdtype_to_text functions Changes some usages of "complex" in the library since it conflicts with the "complex" keyword from the complex.h header. Also changes various usages of the word "complex" throughout the library to distinguish compound datatypes from complex datatypes. --- HDF5Examples/C/H5T/200/h5ex_t_complex.c | 12 +- .../C/H5T/200/h5ex_t_complex_custom.c | 12 +- HDF5Examples/C/H5T/200/h5ex_t_complex_msvc.c | 12 +- hl/tools/h5watch/h5watch.c | 34 +-- release_docs/RELEASE.txt | 194 ++++++++++++++++++ src/H5T.c | 2 +- tools/lib/h5tools.h | 9 +- tools/lib/h5tools_dump.c | 31 +-- tools/src/h5dump/h5dump.c | 6 - tools/src/h5dump/h5dump.h | 15 +- tools/src/h5dump/h5dump_ddl.c | 28 +++ tools/src/h5dump/h5dump_extern.h | 1 + tools/src/h5dump/h5dump_xml.c | 87 ++++++-- tools/src/h5ls/h5ls.c | 43 ++-- 14 files changed, 393 insertions(+), 93 deletions(-) diff --git a/HDF5Examples/C/H5T/200/h5ex_t_complex.c b/HDF5Examples/C/H5T/200/h5ex_t_complex.c index 543c5086f42..4e59f0a6efc 100644 --- a/HDF5Examples/C/H5T/200/h5ex_t_complex.c +++ b/HDF5Examples/C/H5T/200/h5ex_t_complex.c @@ -16,10 +16,10 @@ #include #include -#define FILENAME "h5ex_t_complex.h5" -#define DATASET "DS1" -#define DIM0 4 -#define DIM1 7 +#define FILE "h5ex_t_complex.h5" +#define DATASET "DS1" +#define DIM0 4 +#define DIM1 7 int main(void) @@ -45,7 +45,7 @@ main(void) /* * Create a new file using the default properties. */ - file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); /* * Create dataspace. Setting maximum size to NULL sets the maximum @@ -80,7 +80,7 @@ main(void) /* * Open file and dataset. */ - file = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT); + file = H5Fopen(FILE, H5F_ACC_RDONLY, H5P_DEFAULT); dset = H5Dopen(file, DATASET, H5P_DEFAULT); /* diff --git a/HDF5Examples/C/H5T/200/h5ex_t_complex_custom.c b/HDF5Examples/C/H5T/200/h5ex_t_complex_custom.c index 1acba0da423..6c36a2578d8 100644 --- a/HDF5Examples/C/H5T/200/h5ex_t_complex_custom.c +++ b/HDF5Examples/C/H5T/200/h5ex_t_complex_custom.c @@ -16,10 +16,10 @@ #include #include -#define FILENAME "h5ex_t_complex_custom.h5" -#define DATASET "DS1" -#define DIM0 4 -#define DIM1 7 +#define FILE "h5ex_t_complex_custom.h5" +#define DATASET "DS1" +#define DIM0 4 +#define DIM1 7 int main(void) @@ -45,7 +45,7 @@ main(void) /* * Create a new file using the default properties. */ - file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); /* * Create dataspace. Setting maximum size to NULL sets the maximum @@ -87,7 +87,7 @@ main(void) /* * Open file and dataset. */ - file = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT); + file = H5Fopen(FILE, H5F_ACC_RDONLY, H5P_DEFAULT); dset = H5Dopen(file, DATASET, H5P_DEFAULT); /* diff --git a/HDF5Examples/C/H5T/200/h5ex_t_complex_msvc.c b/HDF5Examples/C/H5T/200/h5ex_t_complex_msvc.c index 55a7e207a74..2059380a76b 100644 --- a/HDF5Examples/C/H5T/200/h5ex_t_complex_msvc.c +++ b/HDF5Examples/C/H5T/200/h5ex_t_complex_msvc.c @@ -17,10 +17,10 @@ #include #include -#define FILENAME "h5ex_t_complex_msvc.h5" -#define DATASET "DS1" -#define DIM0 4 -#define DIM1 7 +#define FILE "h5ex_t_complex_msvc.h5" +#define DATASET "DS1" +#define DIM0 4 +#define DIM1 7 int main(void) @@ -46,7 +46,7 @@ main(void) /* * Create a new file using the default properties. */ - file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + file = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); /* * Create dataspace. Setting maximum size to NULL sets the maximum @@ -81,7 +81,7 @@ main(void) /* * Open file and dataset. */ - file = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT); + file = H5Fopen(FILE, H5F_ACC_RDONLY, H5P_DEFAULT); dset = H5Dopen(file, DATASET, H5P_DEFAULT); /* diff --git a/hl/tools/h5watch/h5watch.c b/hl/tools/h5watch/h5watch.c index cfa6bae857d..594e8cbbcf7 100644 --- a/hl/tools/h5watch/h5watch.c +++ b/hl/tools/h5watch/h5watch.c @@ -94,17 +94,21 @@ static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"hel", static herr_t doprint(hid_t did, const hsize_t *start, const hsize_t *block, int rank) { - h5tools_context_t ctx; /* print context */ - h5tool_format_t info; /* Format info for the tools library */ - static char fmt_ldouble[16]; /* Format info */ - static char fmt_double[16], fmt_float[16]; /* Format info */ - struct subset_t subset; /* Subsetting info */ - hsize_t ss_start[H5S_MAX_RANK]; /* Info for hyperslab */ - hsize_t ss_stride[H5S_MAX_RANK]; /* Info for hyperslab */ - hsize_t ss_block[H5S_MAX_RANK]; /* Info for hyperslab */ - hsize_t ss_count[H5S_MAX_RANK]; /* Info for hyperslab */ - int i; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + h5tools_context_t ctx; /* print context */ + h5tool_format_t info; /* Format info for the tools library */ + static char fmt_ldouble[16]; /* Format info */ + static char fmt_double[16]; /* Format info */ + static char fmt_float[16]; /* Format info */ + static char fmt_ldouble_complex[32]; /* Format info */ + static char fmt_double_complex[32]; /* Format info */ + static char fmt_float_complex[16]; /* Format info */ + struct subset_t subset; /* Subsetting info */ + hsize_t ss_start[H5S_MAX_RANK]; /* Info for hyperslab */ + hsize_t ss_stride[H5S_MAX_RANK]; /* Info for hyperslab */ + hsize_t ss_block[H5S_MAX_RANK]; /* Info for hyperslab */ + hsize_t ss_count[H5S_MAX_RANK]; /* Info for hyperslab */ + int i; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ /* Subsetting information for the tools library printing routines */ subset.start.data = ss_start; @@ -176,8 +180,14 @@ doprint(hid_t did, const hsize_t *start, const hsize_t *block, int rank) info.fmt_float = fmt_float; snprintf(fmt_double, sizeof(fmt_double), "%%1.%dg", DBL_DIG); info.fmt_double = fmt_double; - snprintf(fmt_ldouble, sizeof(fmt_ldouble), "%%1.%dLg", DBL_DIG); + snprintf(fmt_ldouble, sizeof(fmt_ldouble), "%%1.%dLg", LDBL_DIG); info.fmt_ldouble = fmt_ldouble; + snprintf(fmt_float_complex, sizeof(fmt_float_complex), "%%1.%dg%%+1.%dgi", FLT_DIG, FLT_DIG); + info.fmt_float_complex = fmt_float_complex; + snprintf(fmt_double_complex, sizeof(fmt_double_complex), "%%1.%dg%%+1.%dgi", DBL_DIG, DBL_DIG); + info.fmt_double_complex = fmt_double_complex; + snprintf(fmt_ldouble_complex, sizeof(fmt_ldouble_complex), "%%1.%dLg%%+1.%dLgi", LDBL_DIG, LDBL_DIG); + info.fmt_ldouble_complex = fmt_ldouble_complex; info.dset_format = "DSET-%s "; info.dset_hidefileno = 0; diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 5f8321daae9..86f894d3bea 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -151,6 +151,200 @@ New Features Library: -------- + - Added support for complex number datatypes + + Support for the C99 "float _Complex", "double _Complex" and "long double _Complex" + (with MSVC, "_Fcomplex", "_Dcomplex" and "_Lcomplex") types has been added for + platforms/compilers that support them. These types have been implemented with a + new datatype class, H5T_COMPLEX. Note that any datatypes of class H5T_COMPLEX + will not be readable with previous versions of HDF5. If a file is accessed with + a library version bounds "high" setting less than H5F_LIBVER_V200, an error will + occur if the application tries to create an object with a complex number datatype. + If compatibility with previous versions of HDF5 is desired, applications should + instead consider adopting one of the existing conventions at + https://nc-complex.readthedocs.io/en/latest/#conventions-used-in-applications. + + The following new macros have been added: + + - H5_HAVE_COMPLEX_NUMBERS + + This macro is defined in H5pubconf.h and will have the value 1 if native + support for complex numbers is available. It will not be defined otherwise. + + - H5_HAVE_C99_COMPLEX_NUMBERS + + This macro is defined in H5pubconf.h and will have the value 1 if native + support for C99 complex numbers is available. It will not be defined otherwise. + If this macro is not defined but H5_HAVE_COMPLEX_NUMBERS is defined, the + complex number types supported are the MSVC types. + + - H5_SIZEOF_FLOAT_COMPLEX + + This macro is defined in H5pubconf.h and will have a value corresponding + to the size of the native float complex datatype, as computed by sizeof(). + If C99 complex number support is available, this will be the size of the + "float _Complex" type. Otherwise, it will be the size of the "_Fcomplex" + type. It will have the value 0 if support for a native float complex datatype + is not available. + + - H5_SIZEOF_DOUBLE_COMPLEX + + This macro is defined in H5pubconf.h and will have a value corresponding + to the size of the native double complex datatype, as computed by sizeof(). + If C99 complex number support is available, this will be the size of the + "double _Complex" type. Otherwise, it will be the size of the "_Dcomplex" + type. It will have the value 0 if support for a native double complex datatype + is not available. + + - H5_SIZEOF_LONG_DOUBLE_COMPLEX + + This macro is defined in H5pubconf.h and will have a value corresponding + to the size of the native long double complex datatype, as computed by sizeof(). + If C99 complex number support is available, this will be the size of the + "long double _Complex" type. Otherwise, it will be the size of the "_Lcomplex" + type. It will have the value 0 if support for a native long double complex + datatype is not available. + + - H5T_NATIVE_FLOAT_COMPLEX + + This macro maps to the ID of an HDF5 datatype representing the native C + float complex datatype (either "float _Complex" or "_Fcomplex") for the + platform. If support for a native float complex datatype is not available + (H5_HAVE_COMPLEX_NUMBERS is not defined), the macro will map to + H5I_INVALID_HID and should not be used. + + - H5T_NATIVE_DOUBLE_COMPLEX + + This macro maps to the ID of an HDF5 datatype representing the native C + double complex datatype (either "double _Complex" or "_Dcomplex") for the + platform. If support for a native double complex datatype is not available + (H5_HAVE_COMPLEX_NUMBERS is not defined), the macro will map to + H5I_INVALID_HID and should not be used. + + - H5T_NATIVE_LDOUBLE_COMPLEX + + This macro maps to the ID of an HDF5 datatype representing the native C + long double complex datatype (either "long double _Complex" or "_Lcomplex") + for the platform. If support for a native long double complex datatype is + not available (H5_HAVE_COMPLEX_NUMBERS is not defined), the macro will map + to H5I_INVALID_HID and should not be used. + + - H5T_COMPLEX_IEEE_F16LE / H5T_COMPLEX_IEEE_F16BE + + These macros map to IDs of HDF5 datatypes representing a complex number of + two parts, each of which is an IEEE 754 16-bit floating-point datatype in + little- or big-endian order. These datatypes are available regardless of + whether complex number support is available or not. + + - H5T_COMPLEX_IEEE_F32LE / H5T_COMPLEX_IEEE_F32BE + + These macros map to IDs of HDF5 datatypes representing a complex number of + two parts, each of which is an IEEE 754 32-bit floating-point datatype in + little- or big-endian order. These datatypes are available regardless of + whether complex number support is available or not. + + - H5T_COMPLEX_IEEE_F64LE / H5T_COMPLEX_IEEE_F64BE + + These macros map to IDs of HDF5 datatypes representing a complex number of + two parts, each of which is an IEEE 754 64-bit floating-point datatype in + little- or big-endian order. These datatypes are available regardless of + whether complex number support is available or not. + + The following new API function has been added: + + hid_t H5Tcomplex_create(hid_t base_type_id); + + Creates a new complex number datatype from the base datatype specified + by the given HDF5 ID `base_type_id`. The base datatype must be a + floating-point datatype. + + The following new hard datatype conversion paths have been added, but + will only be used when complex number support is available: + + H5T_NATIVE_SCHAR <-> H5T_NATIVE_FLOAT_COMPLEX | H5T_NATIVE_UCHAR <-> H5T_NATIVE_FLOAT_COMPLEX + H5T_NATIVE_SHORT <-> H5T_NATIVE_FLOAT_COMPLEX | H5T_NATIVE_USHORT <-> H5T_NATIVE_FLOAT_COMPLEX + H5T_NATIVE_INT <-> H5T_NATIVE_FLOAT_COMPLEX | H5T_NATIVE_UINT <-> H5T_NATIVE_FLOAT_COMPLEX + H5T_NATIVE_LONG <-> H5T_NATIVE_FLOAT_COMPLEX | H5T_NATIVE_ULONG <-> H5T_NATIVE_FLOAT_COMPLEX + H5T_NATIVE_LLONG <-> H5T_NATIVE_FLOAT_COMPLEX | H5T_NATIVE_ULLONG <-> H5T_NATIVE_FLOAT_COMPLEX + H5T_NATIVE_FLOAT16 <-> H5T_NATIVE_FLOAT_COMPLEX | H5T_NATIVE_FLOAT <-> H5T_NATIVE_FLOAT_COMPLEX + H5T_NATIVE_DOUBLE <-> H5T_NATIVE_FLOAT_COMPLEX | H5T_NATIVE_LDOUBLE <-> H5T_NATIVE_FLOAT_COMPLEX + + H5T_NATIVE_SCHAR <-> H5T_NATIVE_DOUBLE_COMPLEX | H5T_NATIVE_UCHAR <-> H5T_NATIVE_DOUBLE_COMPLEX + H5T_NATIVE_SHORT <-> H5T_NATIVE_DOUBLE_COMPLEX | H5T_NATIVE_USHORT <-> H5T_NATIVE_DOUBLE_COMPLEX + H5T_NATIVE_INT <-> H5T_NATIVE_DOUBLE_COMPLEX | H5T_NATIVE_UINT <-> H5T_NATIVE_DOUBLE_COMPLEX + H5T_NATIVE_LONG <-> H5T_NATIVE_DOUBLE_COMPLEX | H5T_NATIVE_ULONG <-> H5T_NATIVE_DOUBLE_COMPLEX + H5T_NATIVE_LLONG <-> H5T_NATIVE_DOUBLE_COMPLEX | H5T_NATIVE_ULLONG <-> H5T_NATIVE_DOUBLE_COMPLEX + H5T_NATIVE_FLOAT16 <-> H5T_NATIVE_DOUBLE_COMPLEX | H5T_NATIVE_FLOAT <-> H5T_NATIVE_DOUBLE_COMPLEX + H5T_NATIVE_DOUBLE <-> H5T_NATIVE_DOUBLE_COMPLEX | H5T_NATIVE_LDOUBLE <-> H5T_NATIVE_DOUBLE_COMPLEX + + H5T_NATIVE_SCHAR <-> H5T_NATIVE_LDOUBLE_COMPLEX | H5T_NATIVE_UCHAR <-> H5T_NATIVE_LDOUBLE_COMPLEX + H5T_NATIVE_SHORT <-> H5T_NATIVE_LDOUBLE_COMPLEX | H5T_NATIVE_USHORT <-> H5T_NATIVE_LDOUBLE_COMPLEX + H5T_NATIVE_INT <-> H5T_NATIVE_LDOUBLE_COMPLEX | H5T_NATIVE_UINT <-> H5T_NATIVE_LDOUBLE_COMPLEX + H5T_NATIVE_LONG <-> H5T_NATIVE_LDOUBLE_COMPLEX | H5T_NATIVE_ULONG <-> H5T_NATIVE_LDOUBLE_COMPLEX + H5T_NATIVE_LLONG <-> H5T_NATIVE_LDOUBLE_COMPLEX | H5T_NATIVE_ULLONG <-> H5T_NATIVE_LDOUBLE_COMPLEX + H5T_NATIVE_FLOAT16 <-> H5T_NATIVE_LDOUBLE_COMPLEX | H5T_NATIVE_FLOAT <-> H5T_NATIVE_LDOUBLE_COMPLEX + H5T_NATIVE_DOUBLE <-> H5T_NATIVE_LDOUBLE_COMPLEX | H5T_NATIVE_LDOUBLE <-> H5T_NATIVE_LDOUBLE_COMPLEX + + H5T_NATIVE_FLOAT_COMPLEX <-> H5T_NATIVE_DOUBLE_COMPLEX + H5T_NATIVE_FLOAT_COMPLEX <-> H5T_NATIVE_LDOUBLE_COMPLEX + H5T_NATIVE_DOUBLE_COMPLEX <-> H5T_NATIVE_LDOUBLE_COMPLEX + + Alternative software implementation conversion paths have been added for all of + the above for use when native complex number support is not available. All of these + conversion paths follow the behavior outlined in the C standard for conversions of + complex number values. + + Additionally, a special datatype conversion path has been added between complex number + datatypes and array or compound datatypes where the in-memory layout of data is the + same between the datatypes and data can be directly converted. This conversion path + is subject to the following rules: + + - An array datatype must consist of exactly two elements where each element is of + the same floating-point datatype as the complex number datatype's base floating-point + datatype. + + - A compound datatype must consist of exactly two fields where each field is of the + same floating-point datatype as the complex number datatype's base floating-point + datatype. The compound datatype must not have any leading or trailing structure + padding or any padding between its two fields. The fields must also have compatible + names, must have compatible offsets within the datatype and must be in the order + of "real" part -> "imaginary" part, such that the compound datatype matches the + following representation: + + H5T_COMPOUND { + "r(e)(a)(l)"; OFFSET 0 + "i(m)(a)(g)(i)(n)(a)(r)(y)"; OFFSET SIZEOF("r(e)(a)(l)") + } + + where "r(e)(a)(l)" means the field may be named any substring of "real", such as + "r", or "re" and "i(m)(a)(g)(i)(n)(a)(r)(y)" means the field may be named any + substring of "imaginary", such as "im" or "imag". + + Support for complex numbers has been added to the h5dump, h5ls and h5diff/ph5diff + tools. The h5dump command-line option '-m' can be used to change the floating-point + printing format for the float complex and double complex datatypes, as well as + the long double complex datatype if it has the same size as a double complex + datatype. + + Support for the predefined complex number datatypes and the H5Tcomplex_create + function has been added to the Java wrappers. However, Java does not have + official types for complex numbers, so an application must be sure that + data is in an appropriate format in-memory when using these datatypes. + + Support for the Fortran wrappers has not yet been added. + + Support for the predefined complex number datatypes and the H5Tcomplex_create + function has been added to the high level library, allowing them to work + with the H5LTtext_to_dtype and H5LTdtype_to_text functions. + + Simple example programs showing how to use complex number datatypes have + been added in the following files: + + - HDF5Examples/C/H5T/200/h5ex_t_complex.c (Uses C99 complex number types) + - HDF5Examples/C/H5T/200/h5ex_t_complex_msvc.c (Uses MSVC complex number types) + - HDF5Examples/C/H5T/200/h5ex_t_complex_custom.c (Uses H5Tcomplex_create to create + a custom complex number type) + - The H5VLstart_lib_state / H5VLfinish_lib_state API routines for pass- through connector authors now require a parameter that can be used to store the library's context. diff --git a/src/H5T.c b/src/H5T.c index 29f76fc772e..234e29d22c4 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -636,7 +636,7 @@ const unsigned H5O_dtype_ver_bounds[] = { H5O_DTYPE_VERSION_3, /* H5F_LIBVER_V110 */ H5O_DTYPE_VERSION_4, /* H5F_LIBVER_V112 */ H5O_DTYPE_VERSION_4, /* H5F_LIBVER_V114 */ - H5O_DTYPE_VERSION_4, /* H5F_LIBVER_V200 */ + H5O_DTYPE_VERSION_5, /* H5F_LIBVER_V200 */ H5O_DTYPE_VERSION_LATEST /* H5F_LIBVER_LATEST */ }; diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h index acce12fbdf0..78b07a6fcc4 100644 --- a/tools/lib/h5tools.h +++ b/tools/lib/h5tools.h @@ -269,11 +269,8 @@ typedef struct h5tool_format_t { * typed `unsigned long long'. The default depends on what * printf() format is available to print this datatype. * - * fmt_ldouble: The printf() format to use when rendering data which is - * typed `long double'. The default is `%Lg'. - * - * fmt_double: The printf() format to use when rendering data which is - * typed `double'. The default is `%g'. + * fmt_float: The printf() format to use when rendering data which is + * typed `float'. The default is `%g'. * * fmt_double: The printf() format to use when rendering data which is * typed `double'. The default is `%g'. @@ -323,8 +320,6 @@ typedef struct h5tool_format_t { const char *fmt_ulong; const char *fmt_llong; const char *fmt_ullong; - const char *fmt_ldouble; - const char *fmt_double; const char *fmt_float; const char *fmt_double; const char *fmt_ldouble; diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c index 11b0bda8bf7..6c9a1cfd0ef 100644 --- a/tools/lib/h5tools_dump.c +++ b/tools/lib/h5tools_dump.c @@ -24,20 +24,23 @@ h5tool_format_t h5tools_dataformat = { 0, /*raw */ - "", /*fmt_raw */ - "%d", /*fmt_int */ - "%u", /*fmt_uint */ - "%hhd", /*fmt_schar */ - "%u", /*fmt_uchar */ - "%d", /*fmt_short */ - "%u", /*fmt_ushort */ - "%ld", /*fmt_long */ - "%lu", /*fmt_ulong */ - NULL, /*fmt_llong */ - NULL, /*fmt_ullong */ - "%Lg", /*fmt_ldouble */ - "%g", /*fmt_double */ - "%g", /*fmt_float */ + "", /*fmt_raw */ + "%hhd", /*fmt_schar */ + "%u", /*fmt_uchar */ + "%d", /*fmt_short */ + "%u", /*fmt_ushort */ + "%d", /*fmt_int */ + "%u", /*fmt_uint */ + "%ld", /*fmt_long */ + "%lu", /*fmt_ulong */ + NULL, /*fmt_llong */ + NULL, /*fmt_ullong */ + "%g", /*fmt_float */ + "%g", /*fmt_double */ + "%Lg", /*fmt_ldouble */ + "%g%+gi", /*fmt_float_complex */ + "%g%+gi", /*fmt_double_complex */ + "%Lg%+Lgi", /*fmt_ldouble_complex */ 0, /*ascii */ 0, /*str_locale */ diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c index f5bf8bbbd51..2d1c3a005c3 100644 --- a/tools/src/h5dump/h5dump.c +++ b/tools/src/h5dump/h5dump.c @@ -1093,12 +1093,6 @@ parse_command_line(int argc, const char *const *argv) break; } - case 'L': - /* specify alternative floating point long double printing format */ - fp_lformat = H5_optarg; - h5tools_nCols = 0; - break; - case 'L': /* specify alternative floating point long double printing format */ fp_lformat = H5_optarg; diff --git a/tools/src/h5dump/h5dump.h b/tools/src/h5dump/h5dump.h index 98c17538631..00a2055478e 100644 --- a/tools/src/h5dump/h5dump.h +++ b/tools/src/h5dump/h5dump.h @@ -235,13 +235,14 @@ typedef struct h5dump_table_list_t { h5dump_table_list_t table_list = {0, 0, NULL}; table_t *group_table = NULL, *dset_table = NULL, *type_table = NULL; -unsigned dump_indent = 0; /* how far in to indent the line */ -int unamedtype = 0; /* shared datatype with no name */ -bool hit_elink = false; /* whether we have traversed an external link */ -size_t prefix_len = 1024; -char *prefix = NULL; -const char *fp_format = NULL; -const char *fp_lformat = NULL; +unsigned dump_indent = 0; /* how far in to indent the line */ +int unamedtype = 0; /* shared datatype with no name */ +bool hit_elink = false; /* whether we have traversed an external link */ +size_t prefix_len = 1024; +char *prefix = NULL; +const char *fp_format = NULL; +const char *fp_lformat = NULL; +const char *complex_format = NULL; /* format for printing complex numbers */ /* things to display or which are set via command line parameters */ typedef struct { diff --git a/tools/src/h5dump/h5dump_ddl.c b/tools/src/h5dump/h5dump_ddl.c index 1fe7f1787a1..f86a0c75ea5 100644 --- a/tools/src/h5dump/h5dump_ddl.c +++ b/tools/src/h5dump/h5dump_ddl.c @@ -119,6 +119,10 @@ dump_attr_cb(hid_t oid, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED * if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -181,6 +185,10 @@ dump_all_cb(hid_t group, const char *name, const H5L_info2_t *linfo, void H5_ATT if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -655,6 +663,10 @@ dump_named_datatype(hid_t tid, const char *name) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -814,6 +826,10 @@ dump_group(hid_t gid, const char *name) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -943,6 +959,10 @@ dump_dataset(hid_t did, const char *name, struct subset_t *sset) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -1117,6 +1137,10 @@ dump_data(hid_t obj_id, int obj_data, struct subset_t *sset, int display_index) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -1585,6 +1609,10 @@ handle_attributes(hid_t fid, const char *attr, void H5_ATTR_UNUSED *data, int H5 if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; diff --git a/tools/src/h5dump/h5dump_extern.h b/tools/src/h5dump/h5dump_extern.h index ba8692dd2f9..c38e09d9c79 100644 --- a/tools/src/h5dump/h5dump_extern.h +++ b/tools/src/h5dump/h5dump_extern.h @@ -57,6 +57,7 @@ extern size_t prefix_len; extern char *prefix; extern const char *fp_format; extern const char *fp_lformat; +extern const char *complex_format; /* format for complex number */ /* things to display or which are set via command line parameters */ typedef struct { diff --git a/tools/src/h5dump/h5dump_xml.c b/tools/src/h5dump/h5dump_xml.c index 13633cd211a..61b37650869 100644 --- a/tools/src/h5dump/h5dump_xml.c +++ b/tools/src/h5dump/h5dump_xml.c @@ -36,20 +36,23 @@ const char *xmlnsprefix = "hdf5:"; static h5tool_format_t xml_dataformat = { 0, /*raw */ - "", /*fmt_raw */ - "%d", /*fmt_int */ - "%u", /*fmt_uint */ - "%hhd", /*fmt_schar */ - "%u", /*fmt_uchar */ - "%d", /*fmt_short */ - "%u", /*fmt_ushort */ - "%ld", /*fmt_long */ - "%lu", /*fmt_ulong */ - NULL, /*fmt_llong */ - NULL, /*fmt_ullong */ - "%Lg", /*fmt_ldouble */ - "%g", /*fmt_double */ - "%g", /*fmt_float */ + "", /*fmt_raw */ + "%hhd", /*fmt_schar */ + "%u", /*fmt_uchar */ + "%d", /*fmt_short */ + "%u", /*fmt_ushort */ + "%d", /*fmt_int */ + "%u", /*fmt_uint */ + "%ld", /*fmt_long */ + "%lu", /*fmt_ulong */ + NULL, /*fmt_llong */ + NULL, /*fmt_ullong */ + "%g", /*fmt_float */ + "%g", /*fmt_double */ + "%Lg", /*fmt_ldouble */ + "%g%+gi", /*fmt_float_complex */ + "%g%+gi", /*fmt_double_complex */ + "%Lg%+Lgi", /*fmt_ldouble_complex */ 0, /*ascii */ 0, /*str_locale */ @@ -156,6 +159,10 @@ xml_dump_all_cb(hid_t group, const char *name, const H5L_info2_t *linfo, void H5 if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -892,6 +899,10 @@ xml_print_datatype(hid_t type, unsigned in_group) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -1642,6 +1653,10 @@ xml_dump_datatype(hid_t type) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -1779,6 +1794,10 @@ xml_dump_dataspace(hid_t space) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -1954,6 +1973,10 @@ xml_dump_data(hid_t obj_id, int obj_data, struct subset_t H5_ATTR_UNUSED *sset, if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -2123,6 +2146,10 @@ xml_dump_attr(hid_t attr, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -2458,6 +2485,10 @@ xml_dump_named_datatype(hid_t type, const char *name) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -2680,6 +2711,10 @@ xml_dump_group(hid_t gid, const char *name) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -3087,6 +3122,10 @@ xml_print_refs(hid_t did, int source) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -3246,6 +3285,10 @@ xml_print_strs(hid_t did, int source) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -3364,6 +3407,10 @@ check_filters(hid_t dcpl) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -3509,6 +3556,10 @@ xml_dump_fill_value(hid_t dcpl, hid_t type) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -4004,6 +4055,10 @@ xml_dump_dataset(hid_t did, const char *name, struct subset_t H5_ATTR_UNUSED *ss if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; @@ -4595,6 +4650,10 @@ xml_print_enum(hid_t type) if (fp_lformat) { string_dataformat.fmt_ldouble = fp_lformat; } + if (complex_format) { + string_dataformat.fmt_double_complex = complex_format; + string_dataformat.fmt_float_complex = complex_format; + } if (h5tools_nCols == 0) { string_dataformat.line_ncols = 65535; diff --git a/tools/src/h5ls/h5ls.c b/tools/src/h5ls/h5ls.c index c5aedba45c8..992d412f368 100644 --- a/tools/src/h5ls/h5ls.c +++ b/tools/src/h5ls/h5ls.c @@ -34,20 +34,23 @@ static h5tool_format_t ls_dataformat = { 0, /*raw */ - "", /*fmt_raw */ - "%d", /*fmt_int */ - "%u", /*fmt_uint */ - "%hhd", /*fmt_schar */ - "%u", /*fmt_uchar */ - "%d", /*fmt_short */ - "%u", /*fmt_ushort */ - "%ld", /*fmt_long */ - "%lu", /*fmt_ulong */ - NULL, /*fmt_llong */ - NULL, /*fmt_ullong */ - "%Lg", /*fmt_ldouble */ - "%g", /*fmt_double */ - "%g", /*fmt_float */ + "", /*fmt_raw */ + "%hhd", /*fmt_schar */ + "%u", /*fmt_uchar */ + "%d", /*fmt_short */ + "%u", /*fmt_ushort */ + "%d", /*fmt_int */ + "%u", /*fmt_uint */ + "%ld", /*fmt_long */ + "%lu", /*fmt_ulong */ + NULL, /*fmt_llong */ + NULL, /*fmt_ullong */ + "%g", /*fmt_float */ + "%g", /*fmt_double */ + "%Lg", /*fmt_ldouble */ + "%g%+gi", /*fmt_float_complex */ + "%g%+gi", /*fmt_double_complex */ + "%Lg%+Lgi", /*fmt_ldouble_complex */ 0, /*ascii */ 0, /*str_locale */ @@ -1444,6 +1447,12 @@ dump_dataset_values(hid_t dset) outputformat.fmt_double = fmt_double; snprintf(fmt_ldouble, sizeof(fmt_ldouble), "%%1.%dLg", LDBL_DIG); outputformat.fmt_ldouble = fmt_ldouble; + snprintf(fmt_float_complex, sizeof(fmt_float_complex), "%%1.%dg%%+1.%dgi", FLT_DIG, FLT_DIG); + outputformat.fmt_float_complex = fmt_float_complex; + snprintf(fmt_double_complex, sizeof(fmt_double_complex), "%%1.%dg%%+1.%dgi", DBL_DIG, DBL_DIG); + outputformat.fmt_double_complex = fmt_double_complex; + snprintf(fmt_ldouble_complex, sizeof(fmt_ldouble_complex), "%%1.%dLg%%+1.%dLgi", LDBL_DIG, LDBL_DIG); + outputformat.fmt_ldouble_complex = fmt_ldouble_complex; if (hexdump_g) { /* Print all data in hexadecimal format if the `-x' or `--hexdump' @@ -1620,6 +1629,12 @@ dump_attribute_values(hid_t attr) outputformat.fmt_double = fmt_double; snprintf(fmt_ldouble, sizeof(fmt_ldouble), "%%1.%dLg", LDBL_DIG); outputformat.fmt_ldouble = fmt_ldouble; + snprintf(fmt_float_complex, sizeof(fmt_float_complex), "%%1.%dg%%+1.%dgi", FLT_DIG, FLT_DIG); + outputformat.fmt_float_complex = fmt_float_complex; + snprintf(fmt_double_complex, sizeof(fmt_double_complex), "%%1.%dg%%+1.%dgi", DBL_DIG, DBL_DIG); + outputformat.fmt_double_complex = fmt_double_complex; + snprintf(fmt_ldouble_complex, sizeof(fmt_ldouble_complex), "%%1.%dLg%%+1.%dLgi", LDBL_DIG, LDBL_DIG); + outputformat.fmt_ldouble_complex = fmt_ldouble_complex; if (hexdump_g) { /* Print all data in hexadecimal format if the `-x' or `--hexdump'