1997-12-11 06:41:56 +08:00
|
|
|
|
/*
|
|
|
|
|
* Copyright (C) 1997 NCSA
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke <matzke@llnl.gov>
|
|
|
|
|
* Tuesday, December 9, 1997
|
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Purpose: Tests the data type interface (H5T)
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*/
|
1998-07-01 05:30:28 +08:00
|
|
|
|
#include <assert.h>
|
1997-12-11 06:41:56 +08:00
|
|
|
|
#include <hdf5.h>
|
1998-07-01 05:30:28 +08:00
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <signal.h>
|
1997-12-11 06:41:56 +08:00
|
|
|
|
#include <stdio.h>
|
1998-06-06 05:03:49 +08:00
|
|
|
|
#include <stdlib.h>
|
1998-07-07 07:02:32 +08:00
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/wait.h>
|
1997-12-11 06:41:56 +08:00
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
1998-07-01 05:30:28 +08:00
|
|
|
|
#define H5T_PACKAGE
|
|
|
|
|
#include <H5Tpkg.h> /*to turn off hardware conversions*/
|
|
|
|
|
|
1998-06-06 05:03:49 +08:00
|
|
|
|
#include <H5config.h>
|
|
|
|
|
#ifndef HAVE_ATTRIBUTE
|
|
|
|
|
# undef __attribute__
|
|
|
|
|
# define __attribute__(X) /*void*/
|
|
|
|
|
# define __unused__ /*void*/
|
|
|
|
|
#else
|
|
|
|
|
# define __unused__ __attribute__((unused))
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-07-01 05:30:28 +08:00
|
|
|
|
#ifndef MAX
|
|
|
|
|
# define MAX(X,Y) ((X)>(Y)?(X):(Y))
|
|
|
|
|
# define MIN(X,Y) ((X)<(Y)?(X):(Y))
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-06-05 11:35:31 +08:00
|
|
|
|
#define FILE_NAME_1 "dtypes1.h5"
|
|
|
|
|
#define FILE_NAME_2 "dtypes2.h5"
|
1997-12-11 06:41:56 +08:00
|
|
|
|
|
1998-01-10 01:49:23 +08:00
|
|
|
|
typedef struct complex_t {
|
1998-01-17 06:23:43 +08:00
|
|
|
|
double re;
|
|
|
|
|
double im;
|
1998-01-10 01:49:23 +08:00
|
|
|
|
} complex_t;
|
1998-06-05 11:35:31 +08:00
|
|
|
|
|
1998-07-01 05:30:28 +08:00
|
|
|
|
/*
|
|
|
|
|
* Count up or down depending on whether the machine is big endian or little
|
|
|
|
|
* endian. If `E' is H5T_ORDER_BE then the result will be I, otherwise the
|
|
|
|
|
* result will be Z-(I+1).
|
|
|
|
|
*/
|
|
|
|
|
#define ENDIAN(E,Z,I) (H5T_ORDER_BE==(E)?(I):(Z)-((I)+1))
|
|
|
|
|
|
|
|
|
|
typedef enum flt_t {
|
|
|
|
|
FLT_FLOAT, FLT_DOUBLE, FLT_LDOUBLE, FLT_OTHER
|
|
|
|
|
} flt_t;
|
|
|
|
|
|
1998-07-08 04:13:31 +08:00
|
|
|
|
/* Count the number of overflows */
|
|
|
|
|
static int noverflows_g = 0;
|
|
|
|
|
|
1998-07-07 07:02:32 +08:00
|
|
|
|
/*
|
|
|
|
|
* Some machines generate SIGFPE on floating point overflows. According to
|
|
|
|
|
* the Posix standard, we cannot assume that we can continue from such a
|
|
|
|
|
* signal. Therefore, if the following constant is defined then tests that
|
|
|
|
|
* might raise SIGFPE are executed in a child process.
|
|
|
|
|
*/
|
1998-07-13 23:35:21 +08:00
|
|
|
|
#if defined(HAVE_FORK) && defined(HAVE_WAITPID)
|
|
|
|
|
# define HANDLE_SIGFPE
|
|
|
|
|
#endif
|
1998-07-07 07:02:32 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: fpe_handler
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Exit with 255
|
|
|
|
|
*
|
|
|
|
|
* Return: void
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Monday, July 6, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
fpe_handler(int __unused__ signo)
|
|
|
|
|
{
|
|
|
|
|
puts(" -SKIP-");
|
|
|
|
|
puts(" Test skipped due to SIGFPE from probable overflow.");
|
1998-07-13 23:35:21 +08:00
|
|
|
|
#ifndef HANDLE_SIGFPE
|
|
|
|
|
puts(" Remaining tests could not be run.");
|
|
|
|
|
puts(" Please turn off SIGFPE on overflows and try again.");
|
|
|
|
|
#endif
|
1998-07-07 07:02:32 +08:00
|
|
|
|
exit(255);
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-08 04:13:31 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: overflow_handler
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Gets called for all data type conversion overflows.
|
|
|
|
|
*
|
|
|
|
|
* Return: Success: 0
|
|
|
|
|
*
|
|
|
|
|
* Failure: -1
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Tuesday, July 7, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static herr_t
|
|
|
|
|
overflow_handler(hid_t __unused__ src_id, hid_t __unused__ dst_id,
|
|
|
|
|
void __unused__ *src_buf, void __unused__ *dst_buf)
|
|
|
|
|
{
|
|
|
|
|
noverflows_g++;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-05 11:35:31 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-06-06 05:03:49 +08:00
|
|
|
|
* Function: cleanup
|
1998-06-05 11:35:31 +08:00
|
|
|
|
*
|
|
|
|
|
* Purpose: Removes test files
|
|
|
|
|
*
|
|
|
|
|
* Return: void
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Thursday, June 4, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static void
|
1998-06-06 05:03:49 +08:00
|
|
|
|
cleanup (void)
|
1998-06-05 11:35:31 +08:00
|
|
|
|
{
|
1998-06-06 05:03:49 +08:00
|
|
|
|
if (!getenv ("HDF5_NOCLEANUP")) {
|
|
|
|
|
remove (FILE_NAME_1);
|
|
|
|
|
remove (FILE_NAME_2);
|
|
|
|
|
}
|
1998-06-05 11:35:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: display_error_cb
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Displays the error stack after printing "*FAILED*".
|
|
|
|
|
*
|
|
|
|
|
* Return: Success: 0
|
|
|
|
|
*
|
|
|
|
|
* Failure: -1
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, March 4, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static herr_t
|
1998-06-06 05:03:49 +08:00
|
|
|
|
display_error_cb (void __unused__ *client_data)
|
1998-06-05 11:35:31 +08:00
|
|
|
|
{
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
H5Eprint (stdout);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1997-12-11 06:41:56 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Function: test_classes
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Purpose: Test type classes
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Return: Success: 0
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Failure: -1
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
1997-12-11 06:41:56 +08:00
|
|
|
|
* Tuesday, December 9, 1997
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
test_classes(void)
|
1997-12-11 06:41:56 +08:00
|
|
|
|
{
|
1998-06-05 11:35:31 +08:00
|
|
|
|
H5T_class_t tcls;
|
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
printf("%-70s", "Testing H5Tget_class()");
|
|
|
|
|
|
1998-06-05 11:35:31 +08:00
|
|
|
|
if ((tcls=H5Tget_class(H5T_NATIVE_INT))<0) goto error;
|
|
|
|
|
if (H5T_INTEGER!=tcls) {
|
1998-01-17 06:23:43 +08:00
|
|
|
|
puts("*FAILED*");
|
1998-06-05 11:35:31 +08:00
|
|
|
|
puts(" Invalid type class for H5T_NATIVE_INT");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
goto error;
|
|
|
|
|
}
|
1998-06-05 11:35:31 +08:00
|
|
|
|
if ((tcls=H5Tget_class(H5T_NATIVE_DOUBLE))<0) goto error;
|
|
|
|
|
if (H5T_FLOAT!=tcls) {
|
1998-01-17 06:23:43 +08:00
|
|
|
|
puts("*FAILED*");
|
1998-06-05 11:35:31 +08:00
|
|
|
|
puts(" Invalid type class for H5T_NATIVE_DOUBLE");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
puts(" PASSED");
|
1998-06-05 11:35:31 +08:00
|
|
|
|
return 0;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
error:
|
1998-06-05 11:35:31 +08:00
|
|
|
|
return -1;
|
1997-12-11 06:41:56 +08:00
|
|
|
|
}
|
1998-06-05 11:35:31 +08:00
|
|
|
|
|
1997-12-11 06:41:56 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Function: test_copy
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Purpose: Are we able to copy a data type?
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Return: Success: 0
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Failure: -1
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
1997-12-11 06:41:56 +08:00
|
|
|
|
* Tuesday, December 9, 1997
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
test_copy(void)
|
1997-12-11 06:41:56 +08:00
|
|
|
|
{
|
1998-03-05 00:20:23 +08:00
|
|
|
|
hid_t a_copy;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
printf("%-70s", "Testing H5Tcopy()");
|
|
|
|
|
|
1998-06-05 11:35:31 +08:00
|
|
|
|
if ((a_copy = H5Tcopy(H5T_NATIVE_SHORT)) < 0) goto error;
|
|
|
|
|
if (H5Tclose(a_copy) < 0) goto error;
|
1998-03-05 00:20:23 +08:00
|
|
|
|
|
1998-06-05 11:35:31 +08:00
|
|
|
|
/* We should not be able to close a built-in byte */
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
if (H5Tclose (H5T_NATIVE_CHAR)>=0) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Should not be able to close a predefined type!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} H5E_END_TRY;
|
1998-03-05 00:20:23 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
puts(" PASSED");
|
1998-06-05 11:35:31 +08:00
|
|
|
|
return 0;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
error:
|
1998-06-05 11:35:31 +08:00
|
|
|
|
return -1;
|
1997-12-11 06:41:56 +08:00
|
|
|
|
}
|
1998-06-05 11:35:31 +08:00
|
|
|
|
|
1998-01-10 01:49:23 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Function: test_compound
|
1998-01-10 01:49:23 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Purpose: Tests various things about compound data types.
|
1998-01-10 01:49:23 +08:00
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Return: Success: 0
|
1998-01-10 01:49:23 +08:00
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Failure: -1
|
1998-01-10 01:49:23 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
1998-01-10 01:49:23 +08:00
|
|
|
|
* Wednesday, January 7, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static herr_t
|
1998-01-17 06:23:43 +08:00
|
|
|
|
test_compound(void)
|
1998-01-10 01:49:23 +08:00
|
|
|
|
{
|
1998-01-17 06:23:43 +08:00
|
|
|
|
complex_t tmp;
|
|
|
|
|
hid_t complex_id;
|
|
|
|
|
|
|
|
|
|
printf("%-70s", "Testing compound data types");
|
|
|
|
|
|
|
|
|
|
/* Create the empty type */
|
1998-06-05 11:35:31 +08:00
|
|
|
|
if ((complex_id = H5Tcreate(H5T_COMPOUND, sizeof tmp))<0) goto error;
|
|
|
|
|
|
1998-03-05 00:20:23 +08:00
|
|
|
|
/* Add a couple fields */
|
1998-06-05 11:35:31 +08:00
|
|
|
|
if (H5Tinsert(complex_id, "real", HOFFSET(complex_t, re),
|
|
|
|
|
H5T_NATIVE_DOUBLE)<0) goto error;
|
|
|
|
|
if (H5Tinsert(complex_id, "imaginary", HOFFSET(complex_t, im),
|
|
|
|
|
H5T_NATIVE_DOUBLE)<0) goto error;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
1998-06-05 11:35:31 +08:00
|
|
|
|
if (H5Tclose (complex_id)<0) goto error;
|
|
|
|
|
puts(" PASSED");
|
|
|
|
|
return 0;
|
1998-01-17 06:23:43 +08:00
|
|
|
|
|
|
|
|
|
error:
|
1998-06-05 11:35:31 +08:00
|
|
|
|
return -1;
|
1998-01-10 01:49:23 +08:00
|
|
|
|
}
|
1998-06-05 06:28:11 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: test_transient
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Tests transient data types.
|
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Return: Success: 0
|
1998-06-05 06:28:11 +08:00
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Failure: -1
|
1998-06-05 06:28:11 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Thursday, June 4, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static herr_t
|
|
|
|
|
test_transient (void)
|
|
|
|
|
{
|
1998-06-06 05:03:49 +08:00
|
|
|
|
static hsize_t ds_size[2] = {10, 20};
|
[svn-r429] Changes since 19980616
----------------------
./html/tracing.html NEW
This entire update is to make it possible for the library to
print the name, arguments, and return value of every API call
without requiring any extra work from developers or app
programmers. This file describes how this all works.
./configure.in
Added the `--enable-tracing' switch. If you use it then the
library will include code to print API function names,
argument names and values, and function return values.
However, you must then turn on the tracing by setting the
HDF5_TRACE environment variable to a file descriptor number.
The default is `--disable-tracing' since enabling it causes a
slight increase in library size and a slowdown resulting from
an extra function call for each API function call (I couldn't
even measure the slowdown :-)
./bin/trace NEW
A perl script that synchronizes the H5TRACE() macro calls in
the *.c files with the function return type and formal
argument names and types. If you use GNU make and gcc then
this will be done automatically, otherwise just invoke this
script with the names of one or more .c files. You could do
it by hand to, but encoding argument types is a little tricky
at first.
./config/commence.in
Added the $(TRACE) macro, which defaults to the no-op.
Added -D_POSIX_SOURCE to the compiler command line.
./src/Makefile.in
Override the default for $(TRACE).
./config/depend.in
Automatically calls $(TRACE) to synchronize the H5TRACE()
macros in any source file that changed. As with makefile
dependencies, one way to force synchronization of all files is
to remove the `.depend' file.
./MANIFEST
Added new files.
./src/H5Eprivate.h
Modified HRETURN_ERROR() and HRETURN() for tracing.
./src/H5.c
./src/H5private.h
This is where the real tracing work really happens, in
H5_trace().
./src/H5A.c
./src/H5D.c
./src/H5G.c
./src/H5P.c
./src/H5S.c
./src/H5Z.c
Added H5TRACE() calls to all API functions. You don't really
need these changes if you don't want to merge your stuff
because they can be generated automatically by going to the
hdf5/src directory and saying ../bin/trace *.c
./src/H5T.c
Added H5TRACE() calls. Other stuff below.
./src/H5E.c
./src/H5Epublic.h
Added H5TRACE() calls. Created a type H5E_auto_t for the
`func' argument of H5Eset_auto() and H5Eget_auto() to make
those arguments easier to parse for tracing. It should also
make it clearer for users that don't know how to read
complicated ANSI data types.
./src/H5F.c
Added H5TRACE() calls. Changed a couple `uintn' argument
types in API functions to `unsigned int' since `uintn' part of
the API. Changed a few "can't" and "cant" error messages to
"unable to".
./src/H5Ipublic.h
Removed H5_DIRECTORY from the H5I_group_t enum. It wasn't
used anywhere.
./src/H5Tconv.c
Removed an unused label.
./src/H5Fistore.c
./src/H5Oattr.c
./src/H5Odtype.c
./src/H5T.c
./test/dsets.c
./test/dtypes.c
Fixed a warning about a variable possibly used before it's
initialized. Added __unused__ to turn off some unused
argument warnings that pop up when debugging is turned off and
optimizations are turned on.
1998-06-18 04:46:29 +08:00
|
|
|
|
hid_t file=-1, type=-1, space=-1, dset=-1, t2=-1;
|
1998-06-05 06:28:11 +08:00
|
|
|
|
|
|
|
|
|
printf ("%-70s", "Testing transient data types");
|
1998-06-05 11:35:31 +08:00
|
|
|
|
if ((file=H5Fcreate (FILE_NAME_1, H5F_ACC_TRUNC|H5F_ACC_DEBUG,
|
1998-06-05 06:28:11 +08:00
|
|
|
|
H5P_DEFAULT, H5P_DEFAULT))<0) goto error;
|
|
|
|
|
space = H5Screate_simple (2, ds_size, ds_size);
|
|
|
|
|
|
|
|
|
|
/* Predefined types cannot be modified or closed */
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
if (H5Tset_precision (H5T_NATIVE_INT, 256)>=0) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Predefined types should not be modifiable!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (H5Tclose (H5T_NATIVE_INT)>=0) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Predefined types should not be closable!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} H5E_END_TRY;
|
|
|
|
|
|
|
|
|
|
/* Copying a predefined type results in a modifiable copy */
|
|
|
|
|
if ((type=H5Tcopy (H5T_NATIVE_INT))<0) goto error;
|
|
|
|
|
if (H5Tset_precision (type, 256)<0) goto error;
|
1998-06-06 05:03:49 +08:00
|
|
|
|
|
|
|
|
|
/* It should not be possible to create an attribute for a transient type */
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
if (H5Acreate (type, "attr1", H5T_NATIVE_INT, space, H5P_DEFAULT)>=0) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Attributes should not be allowed for transient types!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} H5E_END_TRY;
|
1998-06-05 06:28:11 +08:00
|
|
|
|
|
|
|
|
|
/* Create a dataset from a transient data type */
|
1998-06-06 05:03:49 +08:00
|
|
|
|
if (H5Tclose (type)<0) goto error;
|
1998-06-05 06:28:11 +08:00
|
|
|
|
if ((type = H5Tcopy (H5T_NATIVE_INT))<0) goto error;
|
|
|
|
|
if ((dset=H5Dcreate (file, "dset1", type, space, H5P_DEFAULT))<0) {
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The type returned from a dataset should not be modifiable */
|
|
|
|
|
if ((t2 = H5Dget_type (dset))<0) goto error;
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
if (H5Tset_precision (t2, 256)>=0) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Dataset data types should not be modifiable!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} H5E_END_TRY;
|
|
|
|
|
if (H5Tclose (t2)<0) goto error;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Close the dataset and reopen it, testing that it's type is still
|
|
|
|
|
* read-only.
|
|
|
|
|
*/
|
|
|
|
|
if (H5Dclose (dset)<0) goto error;
|
|
|
|
|
if ((dset=H5Dopen (file, "dset1"))<0) goto error;
|
|
|
|
|
if ((t2 = H5Dget_type (dset))<0) goto error;
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
if (H5Tset_precision (t2, 256)>=0) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Dataset data types should not be modifiable!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} H5E_END_TRY;
|
|
|
|
|
if (H5Tclose (t2)<0) goto error;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Get the dataset data type by applying H5Tcopy() to the dataset. The
|
|
|
|
|
* result should be modifiable.
|
|
|
|
|
*/
|
|
|
|
|
if ((t2=H5Tcopy (dset))<0) goto error;
|
|
|
|
|
if (H5Tset_precision (t2, 256)<0) goto error;
|
|
|
|
|
if (H5Tclose (t2)<0) goto error;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
H5Dclose (dset);
|
|
|
|
|
H5Fclose (file);
|
|
|
|
|
H5Tclose (type);
|
|
|
|
|
H5Sclose (space);
|
|
|
|
|
puts (" PASSED");
|
1998-06-05 11:35:31 +08:00
|
|
|
|
return 0;
|
1998-06-05 06:28:11 +08:00
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
H5Tclose (t2);
|
|
|
|
|
H5Tclose (type);
|
|
|
|
|
H5Sclose (space);
|
|
|
|
|
H5Dclose (dset);
|
|
|
|
|
H5Fclose (file);
|
|
|
|
|
} H5E_END_TRY;
|
1998-06-05 11:35:31 +08:00
|
|
|
|
return -1;
|
1998-06-05 06:28:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: test_named
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Tests named data types.
|
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Return: Success: 0
|
1998-06-05 06:28:11 +08:00
|
|
|
|
*
|
1998-06-05 11:35:31 +08:00
|
|
|
|
* Failure: -1
|
1998-06-05 06:28:11 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Monday, June 1, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static herr_t
|
|
|
|
|
test_named (void)
|
|
|
|
|
{
|
[svn-r429] Changes since 19980616
----------------------
./html/tracing.html NEW
This entire update is to make it possible for the library to
print the name, arguments, and return value of every API call
without requiring any extra work from developers or app
programmers. This file describes how this all works.
./configure.in
Added the `--enable-tracing' switch. If you use it then the
library will include code to print API function names,
argument names and values, and function return values.
However, you must then turn on the tracing by setting the
HDF5_TRACE environment variable to a file descriptor number.
The default is `--disable-tracing' since enabling it causes a
slight increase in library size and a slowdown resulting from
an extra function call for each API function call (I couldn't
even measure the slowdown :-)
./bin/trace NEW
A perl script that synchronizes the H5TRACE() macro calls in
the *.c files with the function return type and formal
argument names and types. If you use GNU make and gcc then
this will be done automatically, otherwise just invoke this
script with the names of one or more .c files. You could do
it by hand to, but encoding argument types is a little tricky
at first.
./config/commence.in
Added the $(TRACE) macro, which defaults to the no-op.
Added -D_POSIX_SOURCE to the compiler command line.
./src/Makefile.in
Override the default for $(TRACE).
./config/depend.in
Automatically calls $(TRACE) to synchronize the H5TRACE()
macros in any source file that changed. As with makefile
dependencies, one way to force synchronization of all files is
to remove the `.depend' file.
./MANIFEST
Added new files.
./src/H5Eprivate.h
Modified HRETURN_ERROR() and HRETURN() for tracing.
./src/H5.c
./src/H5private.h
This is where the real tracing work really happens, in
H5_trace().
./src/H5A.c
./src/H5D.c
./src/H5G.c
./src/H5P.c
./src/H5S.c
./src/H5Z.c
Added H5TRACE() calls to all API functions. You don't really
need these changes if you don't want to merge your stuff
because they can be generated automatically by going to the
hdf5/src directory and saying ../bin/trace *.c
./src/H5T.c
Added H5TRACE() calls. Other stuff below.
./src/H5E.c
./src/H5Epublic.h
Added H5TRACE() calls. Created a type H5E_auto_t for the
`func' argument of H5Eset_auto() and H5Eget_auto() to make
those arguments easier to parse for tracing. It should also
make it clearer for users that don't know how to read
complicated ANSI data types.
./src/H5F.c
Added H5TRACE() calls. Changed a couple `uintn' argument
types in API functions to `unsigned int' since `uintn' part of
the API. Changed a few "can't" and "cant" error messages to
"unable to".
./src/H5Ipublic.h
Removed H5_DIRECTORY from the H5I_group_t enum. It wasn't
used anywhere.
./src/H5Tconv.c
Removed an unused label.
./src/H5Fistore.c
./src/H5Oattr.c
./src/H5Odtype.c
./src/H5T.c
./test/dsets.c
./test/dtypes.c
Fixed a warning about a variable possibly used before it's
initialized. Added __unused__ to turn off some unused
argument warnings that pop up when debugging is turned off and
optimizations are turned on.
1998-06-18 04:46:29 +08:00
|
|
|
|
hid_t file=-1, type=-1, space=-1, dset=-1, t2=-1, attr1=-1;
|
1998-06-05 06:28:11 +08:00
|
|
|
|
herr_t status;
|
1998-06-06 05:03:49 +08:00
|
|
|
|
static hsize_t ds_size[2] = {10, 20};
|
1998-06-05 06:28:11 +08:00
|
|
|
|
|
|
|
|
|
printf ("%-70s", "Testing named data types");
|
1998-06-05 11:35:31 +08:00
|
|
|
|
if ((file=H5Fcreate (FILE_NAME_2, H5F_ACC_TRUNC|H5F_ACC_DEBUG,
|
1998-06-05 06:28:11 +08:00
|
|
|
|
H5P_DEFAULT, H5P_DEFAULT))<0) goto error;
|
|
|
|
|
space = H5Screate_simple (2, ds_size, ds_size);
|
|
|
|
|
|
|
|
|
|
/* Predefined types cannot be committed */
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
if (H5Tcommit (file, "test_named_1 (should not exist)",
|
|
|
|
|
H5T_NATIVE_INT)>=0) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Predefined types should not be committable!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} H5E_END_TRY;
|
|
|
|
|
|
|
|
|
|
/* Copy a predefined data type and commit the copy */
|
|
|
|
|
if ((type = H5Tcopy (H5T_NATIVE_INT))<0) goto error;
|
|
|
|
|
if (H5Tcommit (file, "native-int", type)<0) goto error;
|
|
|
|
|
if ((status=H5Tcommitted (type))<0) goto error;
|
|
|
|
|
if (0==status) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" H5Tcommitted() returned false!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We should not be able to modify a type after it has been committed. */
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
if (H5Tset_precision (type, 256)>=0) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Committed type is not constant!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} H5E_END_TRY;
|
|
|
|
|
|
|
|
|
|
/* We should not be able to re-commit a committed type */
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
if (H5Tcommit (file, "test_named_2 (should not exist)", type)>=0) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Committed types should not be recommitted!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
} H5E_END_TRY;
|
|
|
|
|
|
1998-06-06 05:03:49 +08:00
|
|
|
|
/* It should be possible to define an attribute for the named type */
|
|
|
|
|
if ((attr1=H5Acreate (type, "attr1", H5T_NATIVE_INT, space,
|
|
|
|
|
H5P_DEFAULT))<0) goto error;
|
|
|
|
|
if (H5Aclose (attr1)<0) goto error;
|
|
|
|
|
|
1998-06-05 06:28:11 +08:00
|
|
|
|
/*
|
|
|
|
|
* Copying a committed type should result in a transient type which is
|
|
|
|
|
* not locked.
|
|
|
|
|
*/
|
|
|
|
|
if ((t2 = H5Tcopy (type))<0) goto error;
|
|
|
|
|
if ((status=H5Tcommitted (t2))<0) goto error;
|
|
|
|
|
if (status) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Copying a named type should result in a transient type!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (H5Tset_precision (t2, 256)<0) goto error;
|
|
|
|
|
if (H5Tclose (t2)<0) goto error;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Close the committed type and reopen it. It should return a named type.
|
|
|
|
|
*/
|
|
|
|
|
if (H5Tclose (type)<0) goto error;
|
|
|
|
|
if ((type=H5Topen (file, "native-int"))<0) goto error;
|
|
|
|
|
if ((status=H5Tcommitted (type))<0) goto error;
|
|
|
|
|
if (!status) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Opened named types should be named types!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create a dataset that uses the named type */
|
|
|
|
|
if ((dset = H5Dcreate (file, "dset1", type, space, H5P_DEFAULT))<0) {
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the dataset's data type and make sure it's a named type */
|
|
|
|
|
if ((t2 = H5Dget_type (dset))<0) goto error;
|
|
|
|
|
if ((status=H5Tcommitted (t2))<0) goto error;
|
|
|
|
|
if (!status) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Dataset type should be a named type!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Close the dataset, then close its type, then reopen the dataset */
|
|
|
|
|
if (H5Dclose (dset)<0) goto error;
|
|
|
|
|
if (H5Tclose (t2)<0) goto error;
|
|
|
|
|
if ((dset = H5Dopen (file, "dset1"))<0) goto error;
|
|
|
|
|
|
|
|
|
|
/* Get the dataset's type and make sure it's named */
|
|
|
|
|
if ((t2 = H5Dget_type (dset))<0) goto error;
|
|
|
|
|
if ((status=H5Tcommitted (t2))<0) goto error;
|
|
|
|
|
if (!status) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Dataset type should be a named type!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Close the dataset and create another with the type returned from the
|
|
|
|
|
* first dataset.
|
|
|
|
|
*/
|
|
|
|
|
if (H5Dclose (dset)<0) goto error;
|
|
|
|
|
if ((dset=H5Dcreate (file, "dset2", t2, space, H5P_DEFAULT))<0) {
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Reopen the second dataset and make sure the type is shared */
|
|
|
|
|
if (H5Tclose (t2)<0) goto error;
|
|
|
|
|
if (H5Dclose (dset)<0) goto error;
|
|
|
|
|
if ((dset = H5Dopen (file, "dset2"))<0) goto error;
|
|
|
|
|
if ((t2 = H5Dget_type (dset))<0) goto error;
|
|
|
|
|
if ((status=H5Tcommitted (t2))<0) goto error;
|
|
|
|
|
if (!status) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" Dataset type should be a named type!");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (H5Tclose (t2)<0) goto error;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Get the dataset data type by applying H5Tcopy() to the dataset. The
|
|
|
|
|
* result should be modifiable.
|
|
|
|
|
*/
|
|
|
|
|
if ((t2=H5Tcopy (dset))<0) goto error;
|
|
|
|
|
if (H5Tset_precision (t2, 256)<0) goto error;
|
|
|
|
|
if (H5Tclose (t2)<0) goto error;
|
|
|
|
|
|
|
|
|
|
/* Clean up */
|
|
|
|
|
if (H5Dclose (dset)<0) goto error;
|
|
|
|
|
if (H5Tclose (type)<0) goto error;
|
|
|
|
|
if (H5Sclose (space)<0) goto error;
|
|
|
|
|
if (H5Fclose (file)<0) goto error;
|
|
|
|
|
puts (" PASSED");
|
1998-06-05 11:35:31 +08:00
|
|
|
|
return 0;
|
1998-06-05 06:28:11 +08:00
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
H5E_BEGIN_TRY {
|
|
|
|
|
H5Tclose (t2);
|
|
|
|
|
H5Tclose (type);
|
|
|
|
|
H5Sclose (space);
|
|
|
|
|
H5Dclose (dset);
|
|
|
|
|
H5Fclose (file);
|
|
|
|
|
} H5E_END_TRY;
|
1998-06-05 11:35:31 +08:00
|
|
|
|
return -1;
|
1998-06-05 06:28:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
1998-06-13 01:31:06 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-07-01 05:30:28 +08:00
|
|
|
|
* Function: test_conv_int
|
1998-06-13 01:31:06 +08:00
|
|
|
|
*
|
|
|
|
|
* Purpose: Test atomic number conversions.
|
|
|
|
|
*
|
|
|
|
|
* Return: Success:
|
|
|
|
|
*
|
|
|
|
|
* Failure:
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Wednesday, June 10, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static herr_t
|
1998-07-01 05:30:28 +08:00
|
|
|
|
test_conv_int (void)
|
1998-06-13 01:31:06 +08:00
|
|
|
|
{
|
1998-06-17 03:38:26 +08:00
|
|
|
|
const size_t ntests=100;
|
|
|
|
|
const size_t nelmts=2000;
|
1998-06-13 01:31:06 +08:00
|
|
|
|
|
|
|
|
|
size_t i, j;
|
|
|
|
|
void *buf=NULL, *saved=NULL;
|
1998-06-17 03:38:26 +08:00
|
|
|
|
unsigned char byte[4];
|
1998-06-13 01:31:06 +08:00
|
|
|
|
|
1998-06-17 03:38:26 +08:00
|
|
|
|
/*---------------------------------------------------------------------
|
|
|
|
|
* Test some specific overflow/underflow cases.
|
|
|
|
|
*---------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-07-01 05:30:28 +08:00
|
|
|
|
printf ("%-70s", "Testing integer overflow conversions");
|
1998-06-17 03:38:26 +08:00
|
|
|
|
fflush (stdout);
|
|
|
|
|
|
|
|
|
|
/* (unsigned)0x80000000 -> (unsigned)0xffff */
|
|
|
|
|
byte[0] = byte[1] = byte[2] = 0;
|
|
|
|
|
byte[3] = 0x80;
|
1998-06-19 05:03:30 +08:00
|
|
|
|
if (H5Tconvert (H5T_STD_U32LE, H5T_STD_U16LE, 1, byte, NULL)<0) {
|
1998-06-17 03:38:26 +08:00
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (byte[0]!=0xff || byte[1]!=0xff) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" (unsigned)0x80000000 -> (unsigned)0xffff");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* (unsigned)0xffffffff -> (signed)0x7fff */
|
|
|
|
|
byte[0] = byte[1] = byte[2] = byte[3] = 0xff;
|
1998-06-19 05:03:30 +08:00
|
|
|
|
if (H5Tconvert (H5T_STD_U32LE, H5T_STD_I16LE, 1, byte, NULL)<0) {
|
1998-06-17 03:38:26 +08:00
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (byte[0]!=0xff || byte[1]!=0x7f) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" (unsigned)0xffffffff -> (signed)0x7f");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
1998-06-13 01:31:06 +08:00
|
|
|
|
|
1998-06-17 03:38:26 +08:00
|
|
|
|
/* (signed)0xffffffff -> (unsigned)0x0000 */
|
|
|
|
|
byte[0] = byte[1] = byte[2] = byte[3] = 0xff;
|
1998-06-19 05:03:30 +08:00
|
|
|
|
if (H5Tconvert (H5T_STD_I32LE, H5T_STD_U16LE, 1, byte, NULL)<0) {
|
1998-06-17 03:38:26 +08:00
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (byte[0]!=0x00 || byte[1]!=0x00) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" (signed)0xffffffff -> (unsigned)0x00");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* (signed)0x7fffffff -> (unsigned)0xffff */
|
|
|
|
|
byte[0] = byte[1] = byte[2] = 0xff;
|
|
|
|
|
byte[3] = 0x7f;
|
1998-06-19 05:03:30 +08:00
|
|
|
|
if (H5Tconvert (H5T_STD_I32LE, H5T_STD_U16LE, 1, byte, NULL)<0) {
|
1998-06-17 03:38:26 +08:00
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (byte[0]!=0xff || byte[1]!=0xff) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" (signed)0x7fffffff -> (unsigned)0xffff");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* (signed)0x7fffffff -> (signed)0x7fff */
|
|
|
|
|
byte[0] = byte[1] = byte[2] = 0xff;
|
|
|
|
|
byte[3] = 0x7f;
|
1998-06-19 05:03:30 +08:00
|
|
|
|
if (H5Tconvert (H5T_STD_I32LE, H5T_STD_I16LE, 1, byte, NULL)<0) {
|
1998-06-17 03:38:26 +08:00
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (byte[0]!=0xff || byte[1]!=0x7f) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" (signed)0x7fffffff -> (signed)0x7fff");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* (signed)0xbfffffff -> (signed)0x8000 */
|
|
|
|
|
byte[0] = byte[1] = byte[2] = 0xff;
|
|
|
|
|
byte[3] = 0xbf;
|
1998-06-19 05:03:30 +08:00
|
|
|
|
if (H5Tconvert (H5T_STD_I32LE, H5T_STD_I16LE, 1, byte, NULL)<0) {
|
1998-06-17 03:38:26 +08:00
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (byte[0]!=0x00 || byte[1]!=0x80) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
puts (" (signed)0xbfffffff -> (signed)0x8000");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
puts (" PASSED");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-----------------------------------------------------------------------
|
|
|
|
|
* Test random cases.
|
|
|
|
|
*-----------------------------------------------------------------------
|
|
|
|
|
*/
|
1998-07-01 05:30:28 +08:00
|
|
|
|
printf ("%-70s", "Testing random integer conversions");
|
1998-06-17 03:38:26 +08:00
|
|
|
|
fflush (stdout);
|
|
|
|
|
|
1998-06-13 01:31:06 +08:00
|
|
|
|
/* Allocate buffers */
|
|
|
|
|
buf = malloc (nelmts*8);
|
|
|
|
|
saved = malloc (nelmts*8);
|
|
|
|
|
|
|
|
|
|
for (i=0; i<ntests; i++) {
|
|
|
|
|
|
|
|
|
|
/* Start with NATIVE_INT */
|
|
|
|
|
for (j=0; j<nelmts; j++) ((int*)buf)[j] = rand();
|
|
|
|
|
memcpy (saved, buf, nelmts*sizeof(int));
|
|
|
|
|
|
|
|
|
|
/* Convert there and back */
|
1998-06-19 05:03:30 +08:00
|
|
|
|
if (H5Tconvert (H5T_NATIVE_INT, H5T_STD_I64LE, nelmts, buf,
|
1998-06-13 01:31:06 +08:00
|
|
|
|
NULL)<0) goto error;
|
1998-06-19 05:03:30 +08:00
|
|
|
|
if (H5Tconvert (H5T_STD_I64LE, H5T_NATIVE_INT, nelmts, buf,
|
1998-06-13 01:31:06 +08:00
|
|
|
|
NULL)<0) goto error;
|
|
|
|
|
|
|
|
|
|
/* Check results */
|
|
|
|
|
for (j=0; j<nelmts; j++) {
|
|
|
|
|
if (((int*)buf)[j]!=((int*)saved)[j]) {
|
|
|
|
|
puts ("*FAILED*");
|
|
|
|
|
printf (" Test %lu, elmt %lu, got %d instead of %d\n",
|
|
|
|
|
(unsigned long)i, (unsigned long)j,
|
|
|
|
|
((int*)buf)[j], ((int*)saved)[j]);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
puts (" PASSED");
|
|
|
|
|
free (buf);
|
|
|
|
|
free (saved);
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
if (buf) free (buf);
|
|
|
|
|
if (saved) free (saved);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-07 07:02:32 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: my_isnan
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Determines whether VAL points to NaN.
|
|
|
|
|
*
|
|
|
|
|
* Return: TRUE or FALSE
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Monday, July 6, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
my_isnan(flt_t type, void *val)
|
|
|
|
|
{
|
|
|
|
|
int retval;
|
|
|
|
|
char s[256];
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case FLT_FLOAT:
|
|
|
|
|
retval = (*((float*)val)!=*((float*)val));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLT_DOUBLE:
|
|
|
|
|
retval = (*((double*)val)!=*((double*)val));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLT_LDOUBLE:
|
|
|
|
|
retval = (*((long double*)val)!=*((long double*)val));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Sometimes NaN==NaN (e.g., DEC Alpha) so we try to print it and see if
|
|
|
|
|
* the result contains a NaN string.
|
|
|
|
|
*/
|
|
|
|
|
if (!retval) {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case FLT_FLOAT:
|
|
|
|
|
sprintf(s, "%g", *((float*)val));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLT_DOUBLE:
|
|
|
|
|
sprintf(s, "%g", *((double*)val));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case FLT_LDOUBLE:
|
|
|
|
|
sprintf(s, "%Lg", *((long double*)val));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strstr(s, "NaN") || !strstr(s, "NAN") || !strstr(s, "nan")) {
|
|
|
|
|
retval = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-01 05:30:28 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: test_conv_flt_1
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Test conversion of random floating point values from SRC to
|
|
|
|
|
* DST. These types should be H5T_NATIVE_FLOAT,
|
|
|
|
|
* H5T_NATIVE_DOUBLE, or H5T_NATIVE_LDOUBLE.
|
|
|
|
|
*
|
|
|
|
|
* Return: Success: 0
|
|
|
|
|
*
|
|
|
|
|
* Failure: -1
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Robb Matzke
|
|
|
|
|
* Tuesday, June 23, 1998
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
|
|
|
|
|
{
|
|
|
|
|
flt_t src_type, dst_type; /*data types */
|
1998-07-03 09:16:22 +08:00
|
|
|
|
const size_t ntests=5; /*number of tests */
|
1998-07-01 05:30:28 +08:00
|
|
|
|
const size_t nelmts=200000; /*num values per test */
|
|
|
|
|
const size_t max_fails=8; /*max number of failures*/
|
|
|
|
|
size_t fails_all_tests=0; /*number of failures */
|
|
|
|
|
size_t fails_this_test; /*fails for this test */
|
|
|
|
|
const char *src_type_name = NULL; /*source type name */
|
|
|
|
|
const char *dst_type_name = NULL; /*destination type name */
|
|
|
|
|
size_t src_size, dst_size; /*type sizes */
|
|
|
|
|
unsigned char *buf = NULL; /*buffer for conversion */
|
|
|
|
|
unsigned char *saved = NULL; /*original values */
|
|
|
|
|
char str[256]; /*hello string */
|
|
|
|
|
float hw_f; /*hardware-converted */
|
|
|
|
|
double hw_d; /*hardware-converted */
|
|
|
|
|
long double hw_ld; /*hardware-converted */
|
|
|
|
|
unsigned char *hw=NULL; /*ptr to hardware-conv'd*/
|
|
|
|
|
size_t i, j, k; /*counters */
|
|
|
|
|
int endian; /*machine endianess */
|
|
|
|
|
|
1998-07-07 07:02:32 +08:00
|
|
|
|
#ifdef HANDLE_SIGFPE
|
|
|
|
|
pid_t child_pid; /*process ID of child */
|
|
|
|
|
int status; /*child exit status */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Some systems generage SIGFPE during floating point overflow and we
|
|
|
|
|
* cannot assume that we can continue from such a signal. Therefore, we
|
|
|
|
|
* fork here and let the child run the test and return the number of
|
|
|
|
|
* failures with the exit status.
|
|
|
|
|
*/
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
fflush(stderr);
|
|
|
|
|
if ((child_pid=fork())<0) {
|
|
|
|
|
perror("fork");
|
|
|
|
|
return 1;
|
|
|
|
|
} else if (child_pid>0) {
|
|
|
|
|
while (child_pid!=waitpid(child_pid, &status, 0)) /*void*/;
|
|
|
|
|
if (WIFEXITED(status) && 255==WEXITSTATUS(status)) {
|
|
|
|
|
return 0; /*child exit after catching SIGFPE*/
|
|
|
|
|
} else if (WIFEXITED(status)) {
|
|
|
|
|
return WEXITSTATUS(status);
|
|
|
|
|
} else {
|
|
|
|
|
puts(" Child didn't exit normally.");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-07-13 23:35:21 +08:00
|
|
|
|
#endif
|
1998-07-07 07:02:32 +08:00
|
|
|
|
|
|
|
|
|
/*
|
1998-07-13 23:35:21 +08:00
|
|
|
|
* The remainder of this function is executed only by the child if
|
|
|
|
|
* HANDLE_SIGFPE is defined.
|
1998-07-07 07:02:32 +08:00
|
|
|
|
*/
|
|
|
|
|
signal(SIGFPE,fpe_handler);
|
|
|
|
|
|
1998-07-01 05:30:28 +08:00
|
|
|
|
/* What are the names of the source and destination types */
|
|
|
|
|
if (H5Tequal(src, H5T_NATIVE_FLOAT)) {
|
|
|
|
|
src_type_name = "float";
|
|
|
|
|
src_type = FLT_FLOAT;
|
|
|
|
|
} else if (H5Tequal(src, H5T_NATIVE_DOUBLE)) {
|
|
|
|
|
src_type_name = "double";
|
|
|
|
|
src_type = FLT_DOUBLE;
|
|
|
|
|
} else if (H5Tequal(src, H5T_NATIVE_LDOUBLE)) {
|
|
|
|
|
src_type_name = "long double";
|
|
|
|
|
src_type = FLT_LDOUBLE;
|
|
|
|
|
} else {
|
|
|
|
|
src_type_name = "UNKNOWN";
|
|
|
|
|
src_type = FLT_OTHER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (H5Tequal(dst, H5T_NATIVE_FLOAT)) {
|
|
|
|
|
dst_type_name = "float";
|
|
|
|
|
dst_type = FLT_FLOAT;
|
|
|
|
|
} else if (H5Tequal(dst, H5T_NATIVE_DOUBLE)) {
|
|
|
|
|
dst_type_name = "double";
|
|
|
|
|
dst_type = FLT_DOUBLE;
|
|
|
|
|
} else if (H5Tequal(dst, H5T_NATIVE_LDOUBLE)) {
|
|
|
|
|
dst_type_name = "long double";
|
|
|
|
|
dst_type = FLT_LDOUBLE;
|
|
|
|
|
} else {
|
|
|
|
|
dst_type_name = "UNKNOWN";
|
|
|
|
|
dst_type = FLT_OTHER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Sanity checks */
|
|
|
|
|
assert(sizeof(float)!=sizeof(double));
|
|
|
|
|
if (FLT_OTHER==src_type || FLT_OTHER==dst_type) {
|
|
|
|
|
sprintf(str, "Testing random %s %s -> %s conversions",
|
|
|
|
|
name, src_type_name, dst_type_name);
|
|
|
|
|
printf ("%-70s", str);
|
|
|
|
|
puts("*FAILED*");
|
|
|
|
|
puts(" Unknown data type.");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Allocate buffers */
|
|
|
|
|
endian = H5Tget_order(H5T_NATIVE_FLOAT);
|
|
|
|
|
src_size = H5Tget_size(src);
|
|
|
|
|
dst_size = H5Tget_size(dst);
|
|
|
|
|
buf = malloc(nelmts*MAX(src_size, dst_size));
|
|
|
|
|
saved = malloc(nelmts*MAX(src_size, dst_size));
|
1998-07-08 04:13:31 +08:00
|
|
|
|
noverflows_g = 0;
|
1998-07-01 05:30:28 +08:00
|
|
|
|
|
|
|
|
|
for (i=0; i<ntests; i++) {
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If it looks like it might take a long time then print a progress
|
|
|
|
|
* report between each test.
|
|
|
|
|
*/
|
|
|
|
|
sprintf(str, "Testing random %s %s -> %s conversions (test %d/%d)",
|
|
|
|
|
name, src_type_name, dst_type_name, (int)i+1, (int)ntests);
|
|
|
|
|
printf ("%-70s", str);
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
fails_this_test = 0;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Initialize the source buffers to random bits. The `buf' buffer
|
|
|
|
|
* will be used for the conversion while the `saved' buffer will be
|
|
|
|
|
* used for the comparison later.
|
|
|
|
|
*/
|
|
|
|
|
for (j=0; j<nelmts*src_size; j++) buf[j] = saved[j] = rand();
|
|
|
|
|
|
|
|
|
|
/* Perform the conversion in software */
|
|
|
|
|
if (H5Tconvert(src, dst, nelmts, buf, NULL)<0) goto error;
|
|
|
|
|
|
|
|
|
|
/* Check the software results against the hardware */
|
|
|
|
|
for (j=0; j<nelmts; j++) {
|
1998-07-07 07:02:32 +08:00
|
|
|
|
hw_f = 911.0;
|
|
|
|
|
hw_d = 911.0;
|
|
|
|
|
hw_ld = 911.0;
|
1998-07-01 05:30:28 +08:00
|
|
|
|
|
|
|
|
|
/* The hardware conversion */
|
|
|
|
|
if (FLT_FLOAT==src_type) {
|
|
|
|
|
if (FLT_FLOAT==dst_type) {
|
|
|
|
|
hw_f = ((float*)saved)[j];
|
|
|
|
|
hw = (unsigned char*)&hw_f;
|
|
|
|
|
} else if (FLT_DOUBLE==dst_type) {
|
|
|
|
|
hw_d = ((float*)saved)[j];
|
|
|
|
|
hw = (unsigned char*)&hw_d;
|
|
|
|
|
} else {
|
|
|
|
|
hw_ld = ((float*)saved)[j];
|
|
|
|
|
hw = (unsigned char*)&hw_ld;
|
|
|
|
|
}
|
|
|
|
|
} else if (FLT_DOUBLE==src_type) {
|
|
|
|
|
if (FLT_FLOAT==dst_type) {
|
1998-07-07 07:02:32 +08:00
|
|
|
|
hw_f = ((double*)saved)[j];
|
1998-07-01 05:30:28 +08:00
|
|
|
|
hw = (unsigned char*)&hw_f;
|
|
|
|
|
} else if (FLT_DOUBLE==dst_type) {
|
|
|
|
|
hw_d = ((double*)saved)[j];
|
|
|
|
|
hw = (unsigned char*)&hw_d;
|
|
|
|
|
} else {
|
|
|
|
|
hw_ld = ((double*)saved)[j];
|
|
|
|
|
hw = (unsigned char*)&hw_ld;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (FLT_FLOAT==dst_type) {
|
1998-07-07 07:02:32 +08:00
|
|
|
|
hw_f = ((long double*)saved)[j];
|
1998-07-01 05:30:28 +08:00
|
|
|
|
hw = (unsigned char*)&hw_f;
|
|
|
|
|
} else if (FLT_DOUBLE==dst_type) {
|
1998-07-07 07:02:32 +08:00
|
|
|
|
hw_d = ((long double*)saved)[j];
|
1998-07-01 05:30:28 +08:00
|
|
|
|
hw = (unsigned char*)&hw_d;
|
|
|
|
|
} else {
|
|
|
|
|
hw_ld = ((long double*)saved)[j];
|
|
|
|
|
hw = (unsigned char*)&hw_ld;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Are the two results the same? */
|
|
|
|
|
for (k=0; k<dst_size; k++) {
|
|
|
|
|
if (buf[j*dst_size+k]!=hw[k]) break;
|
|
|
|
|
}
|
|
|
|
|
if (k==dst_size) continue; /*no error*/
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
/*
|
|
|
|
|
* Assume same if both results are NaN. There are many NaN bit
|
|
|
|
|
* patterns and the software doesn't attemt to emulate the
|
|
|
|
|
* hardware in this regard. Instead, software uses a single bit
|
|
|
|
|
* pattern for NaN by setting the significand to all ones.
|
|
|
|
|
*/
|
|
|
|
|
if (FLT_FLOAT==dst_type &&
|
1998-07-07 07:02:32 +08:00
|
|
|
|
my_isnan(dst_type, (float*)buf+j) &&
|
|
|
|
|
my_isnan(dst_type, hw)) {
|
1998-07-01 05:30:28 +08:00
|
|
|
|
continue;
|
|
|
|
|
} else if (FLT_DOUBLE==dst_type &&
|
1998-07-07 07:02:32 +08:00
|
|
|
|
my_isnan(dst_type, (double*)buf+j) &&
|
|
|
|
|
my_isnan(dst_type, hw)) {
|
1998-07-01 05:30:28 +08:00
|
|
|
|
continue;
|
|
|
|
|
} else if (FLT_LDOUBLE==dst_type &&
|
1998-07-07 07:02:32 +08:00
|
|
|
|
my_isnan(dst_type, (long double*)buf+j) &&
|
|
|
|
|
my_isnan(dst_type, hw)) {
|
1998-07-01 05:30:28 +08:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
/*
|
|
|
|
|
* Assume same if hardware result is NaN. This is because the
|
|
|
|
|
* hardware conversions on some machines return NaN instead of
|
|
|
|
|
* overflowing to +Inf or -Inf or underflowing to +0 or -0.
|
|
|
|
|
*/
|
1998-07-07 07:02:32 +08:00
|
|
|
|
if (my_isnan(dst_type, hw)) continue;
|
1998-07-01 05:30:28 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
/*
|
|
|
|
|
* Instead of matching down to the bit, just make sure the
|
|
|
|
|
* exponents are the same and the mantissa is the same to a
|
|
|
|
|
* certain precision. This is needed on machines that don't
|
|
|
|
|
* round as expected.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
double check_mant[2];
|
|
|
|
|
int check_expo[2];
|
|
|
|
|
|
|
|
|
|
if (FLT_FLOAT==dst_type) {
|
|
|
|
|
check_mant[0] = frexp(((float*)buf)[j], check_expo+0);
|
|
|
|
|
check_mant[1] = frexp(((float*)hw)[0], check_expo+1);
|
|
|
|
|
} else if (FLT_DOUBLE==dst_type) {
|
|
|
|
|
check_mant[0] = frexp(((double*)buf)[j], check_expo+0);
|
|
|
|
|
check_mant[1] = frexp(((double*)hw)[0], check_expo+1);
|
|
|
|
|
} else {
|
|
|
|
|
check_mant[0] = frexp(((long double*)buf)[j],check_expo+0);
|
|
|
|
|
check_mant[1] = frexp(((long double*)hw)[0],check_expo+1);
|
|
|
|
|
}
|
|
|
|
|
if (check_expo[0]==check_expo[1] &&
|
|
|
|
|
fabs(check_mant[0]-check_mant[1])<0.000001) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (0==fails_this_test++) puts("*FAILED*");
|
|
|
|
|
printf(" test %u, elmt %u\n", (unsigned)i+1, (unsigned)j);
|
|
|
|
|
|
|
|
|
|
printf(" src =");
|
|
|
|
|
for (k=0; k<src_size; k++) {
|
|
|
|
|
printf(" %02x", saved[j*src_size+ENDIAN(endian,src_size,k)]);
|
|
|
|
|
}
|
|
|
|
|
printf("%*s", 3*MAX(0, (ssize_t)dst_size-(ssize_t)src_size), "");
|
|
|
|
|
if (FLT_FLOAT==src_type) {
|
|
|
|
|
printf(" %29.20e\n", ((float*)saved)[j]);
|
|
|
|
|
} else if (FLT_DOUBLE==src_type) {
|
|
|
|
|
printf(" %29.20e\n", ((double*)saved)[j]);
|
|
|
|
|
} else {
|
|
|
|
|
printf(" %29.20Le\n", ((long double*)saved)[j]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf(" dst =");
|
|
|
|
|
for (k=0; k<dst_size; k++) {
|
|
|
|
|
printf(" %02x", buf[j*dst_size+ENDIAN(endian,dst_size,k)]);
|
|
|
|
|
}
|
|
|
|
|
printf("%*s", 3*MAX(0, (ssize_t)src_size-(ssize_t)dst_size), "");
|
|
|
|
|
if (FLT_FLOAT==dst_type) {
|
|
|
|
|
printf(" %29.20e\n", ((float*)buf)[j]);
|
|
|
|
|
} else if (FLT_DOUBLE==dst_type) {
|
|
|
|
|
printf(" %29.20e\n", ((double*)buf)[j]);
|
|
|
|
|
} else {
|
|
|
|
|
printf(" %29.20Le\n", ((long double*)buf)[j]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf(" ans =");
|
|
|
|
|
for (k=0; k<dst_size; k++) {
|
|
|
|
|
printf(" %02x", hw[ENDIAN(endian,dst_size,k)]);
|
|
|
|
|
}
|
|
|
|
|
printf("%*s", 3*MAX(0, (ssize_t)src_size-(ssize_t)dst_size), "");
|
|
|
|
|
if (FLT_FLOAT==dst_type) {
|
|
|
|
|
printf(" %29.20e\n", hw_f);
|
|
|
|
|
} else if (FLT_DOUBLE==dst_type) {
|
|
|
|
|
printf(" %29.20e\n", hw_d);
|
|
|
|
|
} else {
|
|
|
|
|
printf(" %29.20Le\n", hw_ld);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (++fails_all_tests>=max_fails) {
|
|
|
|
|
puts(" maximum failures reached, aborting test...");
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
puts(" PASSED");
|
|
|
|
|
}
|
1998-07-08 04:13:31 +08:00
|
|
|
|
if (noverflows_g>0) {
|
|
|
|
|
printf(" %d overflow%s\n", noverflows_g, 1==noverflows_g?"":"s");
|
|
|
|
|
}
|
1998-07-01 05:30:28 +08:00
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
if (buf) free (buf);
|
|
|
|
|
if (saved) free (saved);
|
1998-07-07 07:02:32 +08:00
|
|
|
|
#ifdef HANDLE_SIGFPE
|
|
|
|
|
exit(MIN((int)fails_all_tests, 254));
|
|
|
|
|
#else
|
1998-07-01 05:30:28 +08:00
|
|
|
|
return (int)fails_all_tests;
|
1998-07-07 07:02:32 +08:00
|
|
|
|
#endif
|
1998-07-01 05:30:28 +08:00
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
if (buf) free (buf);
|
|
|
|
|
if (saved) free (saved);
|
1998-07-07 07:02:32 +08:00
|
|
|
|
#ifdef HANDLE_SIGFPE
|
|
|
|
|
exit(MIN(MAX((int)fails_all_tests, 1), 254));
|
|
|
|
|
#else
|
|
|
|
|
return MAX((int)fails_all_tests, 1);
|
|
|
|
|
#endif
|
1998-07-01 05:30:28 +08:00
|
|
|
|
}
|
1998-06-13 01:31:06 +08:00
|
|
|
|
|
1997-12-11 06:41:56 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Function: main
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Purpose: Test the data type interface.
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Return: Success:
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Failure:
|
1997-12-11 06:41:56 +08:00
|
|
|
|
*
|
1998-01-17 06:23:43 +08:00
|
|
|
|
* Programmer: Robb Matzke
|
1997-12-11 06:41:56 +08:00
|
|
|
|
* Tuesday, December 9, 1997
|
|
|
|
|
*
|
|
|
|
|
* Modifications:
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
int
|
1998-01-17 06:23:43 +08:00
|
|
|
|
main(void)
|
1997-12-11 06:41:56 +08:00
|
|
|
|
{
|
1998-07-01 05:30:28 +08:00
|
|
|
|
unsigned long nerrors = 0;
|
|
|
|
|
|
1998-06-05 11:35:31 +08:00
|
|
|
|
/* Set the error handler */
|
|
|
|
|
H5Eset_auto (display_error_cb, NULL);
|
1998-06-05 06:28:11 +08:00
|
|
|
|
|
1998-07-08 04:13:31 +08:00
|
|
|
|
/* Set the overflow handler */
|
|
|
|
|
H5Tset_overflow(overflow_handler);
|
|
|
|
|
|
1998-06-05 11:35:31 +08:00
|
|
|
|
/* Do the tests */
|
|
|
|
|
nerrors += test_classes()<0 ? 1 : 0;
|
|
|
|
|
nerrors += test_copy()<0 ? 1 : 0;
|
|
|
|
|
nerrors += test_compound()<0 ? 1 : 0;
|
|
|
|
|
nerrors += test_transient ()<0 ? 1 : 0;
|
|
|
|
|
nerrors += test_named ()<0 ? 1 : 0;
|
1998-07-01 05:30:28 +08:00
|
|
|
|
nerrors += test_conv_int ()<0 ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
/* Test degenerate cases */
|
|
|
|
|
nerrors += test_conv_flt_1("noop", H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT);
|
|
|
|
|
nerrors += test_conv_flt_1("noop", H5T_NATIVE_DOUBLE, H5T_NATIVE_DOUBLE);
|
|
|
|
|
|
|
|
|
|
/* Test hardware conversion functions */
|
|
|
|
|
nerrors += test_conv_flt_1("hw", H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE);
|
|
|
|
|
nerrors += test_conv_flt_1("hw", H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT);
|
|
|
|
|
|
|
|
|
|
/* Test software conversion functions */
|
|
|
|
|
H5Tunregister(H5T_conv_float_double);
|
|
|
|
|
H5Tunregister(H5T_conv_double_float);
|
|
|
|
|
nerrors += test_conv_flt_1("sw", H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE);
|
|
|
|
|
nerrors += test_conv_flt_1("sw", H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE);
|
|
|
|
|
nerrors += test_conv_flt_1("sw", H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT);
|
|
|
|
|
nerrors += test_conv_flt_1("sw", H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE);
|
|
|
|
|
nerrors += test_conv_flt_1("sw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT);
|
|
|
|
|
nerrors += test_conv_flt_1("sw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_DOUBLE);
|
1998-06-13 01:31:06 +08:00
|
|
|
|
|
1998-01-17 06:23:43 +08:00
|
|
|
|
if (nerrors) {
|
1998-07-01 05:30:28 +08:00
|
|
|
|
printf("***** %lu FAILURE%s! *****\n",
|
|
|
|
|
nerrors, 1==nerrors?"":"S");
|
1998-01-17 06:23:43 +08:00
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
printf("All data type tests passed.\n");
|
1998-06-06 05:03:49 +08:00
|
|
|
|
cleanup ();
|
1998-02-10 03:37:40 +08:00
|
|
|
|
return 0;
|
1997-12-11 06:41:56 +08:00
|
|
|
|
}
|