From 3a21ee0877ecea5593112b7c8370cb8571a7e627 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 29 Dec 2023 08:42:35 -0600 Subject: [PATCH 1/2] Add 'warning density' computation to the warnhist script (#3910) * Add 'warning density' computation to the warnhist script, along with several cleanups to it. Add "--enable-show-all-warnings" configure (and CMake) option to disable compiler diagnostic suppression (and therefore show all the otherwise suppressed compiler diagnostics), disabled by default. Clean up a buncn of misc. warnings. Signed-off-by: Quincey Koziol --- bin/warnhist | 301 ++++++++++++++++++++++++++--- config/cmake/ConfigureChecks.cmake | 11 ++ config/cmake/H5pubconf.h.in | 3 + configure.ac | 39 ++++ fortran/src/H5config_f.inc.cmake | 4 +- release_docs/INSTALL_CMake.txt | 1 + src/H5Dpkg.h | 2 +- src/H5EApkg.h | 2 +- src/H5ESpkg.h | 2 +- src/H5Idbg.c | 15 +- src/H5Iint.c | 58 ++---- src/H5Ipkg.h | 11 +- src/H5Pprivate.h | 2 +- src/H5Tpkg.h | 2 +- src/H5private.h | 8 + test/event_set.c | 4 +- tools/src/h5import/h5import.c | 84 ++++---- utils/mirror_vfd/mirror_writer.c | 1 - 18 files changed, 414 insertions(+), 136 deletions(-) diff --git a/bin/warnhist b/bin/warnhist index 1e63a550b39..b77202f9504 100755 --- a/bin/warnhist +++ b/bin/warnhist @@ -22,8 +22,13 @@ use warnings; # Perl modules/settings use strict; use Getopt::Std; +use File::Find; +use File::Basename; +use Cwd; +#use Data::Dumper; # Global variables, for accumulating information +my %options=(); my $totalcount = 0; my $notecount = 0; my $dupcount = 0; @@ -54,11 +59,25 @@ my $last_fort_name; my $last_fort_line; my $last_fort_offset; +# Info about source files +my %c_files; +my %c_files_counted; +my %cpp_files; +my %cpp_files_counted; +my %fort_files; +my %fort_files_counted; +my $c_lines = 0; +my $cpp_lines = 0; +my $fort_lines = 0; + # Display usage sub do_help { - print "Usage: 'warnhist [-h, --help] [-t ] [-w ] [-W] [-f ] [-F] [-s ] [-S ] [file]'\n"; - print "\t-h, --help\tDisplay this usage\n"; - print "\t-t \tTrim pathname prefix from filenames, \n"; + print "Usage: 'warnhist [-h, --help] [-t ] [-w ] [-W] [-f ] [-F]\n"; + print "\t[-s ] [-S ] [-d] [-p Trim pathname prefix from filenames, \n"; print "\t-w \tDisplay files for a given warning index list, \n"; print "\t\t can be a single value, a range, or a comma separated list\n"; print "\t\tFor example: '0' or '0,4' or '8-10' or '0,2-4,8-10,13'\n"; @@ -67,10 +86,13 @@ sub do_help { print "\t\t can be a single value, a range, or a comma separated list\n"; print "\t\tFor example: '0' or '0,4' or '8-10' or '0,2-4,8-10,13'\n"; print "\t-F\tDisplay warnings for all files\n"; - print "\t-s \tDisplay files for warnings which contain a string, \n"; + print "\t-s Display files for warnings which contain a\n"; + print "\t\tstring, \n"; print "\t\t is a comma separated list, with no spaces\n"; - print "\t\tFor example: 'Wunused-dummy-argument' or 'Wunused-dummy-argument,Wunused-variable'\n"; - print "\t-S \tDisplay warnings for files which contain a string, \n"; + print "\t\tFor example: 'Wunused-dummy-argument' or\n"; + print "\t\t'Wunused-dummy-argument,Wunused-variable'\n"; + print "\t-S Display warnings for files which contain a\n"; + print "\t\tstring, \n"; print "\t\t is a comma separated list, with no spaces\n"; print "\t\tFor example: 'H5Fint' or 'H5Fint,H5Gnode'\n"; print "\t-l\tDisplay line numbers for file/warning\n"; @@ -78,18 +100,182 @@ sub do_help { print "\t-i \tIgnore named files, \n"; print "\t\t is a comma separated list, with no spaces\n"; print "\t\tFor example: 'H5LTparse' or 'H5LTparse,H5LTanalyze'\n"; + print "\t-d\tCompute warning density for compiled source files. Paths to the\n"; + print "\t\troot of a directory containing source may be provided with the\n"; + print "\t\t'-p ' option. If the path list is given, only those\n"; + print "\t\tdirectories are scanned for source files. If the path list\n"; + print "\t\toption is not given, the current working directory is scanned.\n"; + print "\t-p \tPaths to search for compiled files. Compiled files\n"; + print "\t\tare only used when computing warning density and are not\n"; + print "\t\tnecessary for just analyzing warnings in build output.\n"; + print "\t\t is a comma separated list, with no spaces\n"; + print "\t\tFor example: '/home/koziol/hdf5' or '.,~/dev/hdf5,~/dev/build'\n"; + print "\t-q\tSuppress warning output\n"; print "\tfile\tFilename containing build output\n"; print "\t\tIf no file is given, standard input is used.\n"; exit; } +# Count # of lines in a file +sub line_count { + my ($name) = @_; +#print "name = '$name'\n"; + my $tmp; + my $lines = 0; + + open (FILE, $name) or die "Can't open '$name': $!"; + $lines++ while ($tmp = ); + close FILE; +#print "$lines\n"; + + return $lines; +} + +# Recursively search a directory hierarchy for source files +# Adds results to the global %c_files, %cpp_files, and %fort_files hashes +sub parse_tree { + my ($root_path) = @_; +#print "root_path = $root_path\n"; + + my $path_checker = sub { + my $name = $File::Find::name; + if (-f $name) { + my $bn = basename($name); + + # Check for different kinds of source files + # Use lists here: https://gist.github.com/ppisarczyk/43962d06686722d26d176fad46879d41#file-programming_languages_extensions-json + + # FORTRAN source file + if($bn =~ /.*(\.f90)|(\.f)|(\.f03)|(\.f08)|(\.f77)|(\.f95)|(\.for)|(\.fpp)$/i) { + $bn =~ s/(\.f90)|(\.f)|(\.f03)|(\.f08)|(\.f77)|(\.f95)|(\.for)|(\.fpp)$//ig; + if(!exists $fort_files{$bn}) { + $fort_files{$bn} = [ $name ]; + } else { + push @{ $fort_files{$bn} }, $name; + } + # C++ source file + } elsif($bn =~ /.*(\.cpp)|(\.c\+\+)|(\.cc)|(\.cp)|(\.cxx)$/i) { + $bn =~ s/(\.cpp)|(\.c\+\+)|(\.cc)|(\.cp)|(\.cxx)$//ig; + if(!exists $cpp_files{$bn}) { + $cpp_files{$bn} = [ $name ]; + } else { + push @{ $cpp_files{$bn} }, $name; + } + # C source file + } elsif($bn =~ /.*(\.c)$/i) { + $bn =~ s/(\.c)$//g; + if(!exists $c_files{$bn}) { + $c_files{$bn} = [ $name ]; + } else { + push @{ $c_files{$bn} }, $name; + } + } + } + }; + find($path_checker, $root_path); + +#print Dumper \%c_files; +#print Dumper \%cpp_files; +#print Dumper \%fort_files; +} + +sub count_file_loc { + my ($filename, $typename, $file_paths, $files_counted, $count) = @_; + + # Attempt to detect and handle object file name mangling by Automake + if(!exists $file_paths->{$filename} && $filename =~ /\-/) { + my ($bn) = $filename =~ /\S+\-(\S+)$/x; + if(exists $file_paths->{$bn}) { + if(!exists $options{q}) { + warn "No path for $typename source file '$filename', but '$bn' has path, assuming automake generated object file name"; + } + $filename = $bn; + } + } + + if(exists $file_paths->{$filename}) { + my $filecount = 0; + + # Attempt to count LOC for files with same name + if(scalar(@{$file_paths->{$filename}}) > 1) { + $filecount = $files_counted->{$filename}++; + + # Issue warning about multiple source files with same name + if($filecount == 0 && !exists $options{q}) { + local $" = ', '; # '$"' is documented in https://perldoc.perl.org/perlvar + warn "Multiple paths for $typename source file named '$filename', assuming each is compiled once, paths: [@{$file_paths->{$filename}}]\n"; + } + + # Sanity check for too many compiles of a file + if($filecount >= scalar(@{$file_paths->{$filename}})) { + if(!exists $options{q}) { + local $" = ', '; # '$"' is documented in https://perldoc.perl.org/perlvar + warn "Too many compiles of $typename source file named '$filename' with paths: [@{$file_paths->{$filename}}], disabling warning density calculations\n"; + } + delete $options{d}; + } + } + + # Increment the # of lines of code (if not too many) + if($filecount < scalar(@{$file_paths->{$filename}})) { + ${$count} += line_count($file_paths->{$filename}[$filecount]); + } + } else { + if(!exists $options{q}) { + warn "No path for $typename source file '$filename', e '-p' option to specify, disabling warning density calculations\n"; + } + delete $options{d}; + } +} + +# Compute LOC for compiled source file +sub count_source_loc { + my ($compile_line) = @_; +#print "compile_line = $compile_line\n"; + my $filetype; + my $filename; + + ($filetype, $filename) = $compile_line =~ /^\s+(CC|FC|CXX|PPFC)\s+(\S*)\.l*o$/x; + if($filename =~ /\//) { + $filename = basename($filename); + } +#print "filetype = '$filetype'\n"; +#print "filename = '$filename'\n"; + + if($filetype =~ /FC|PPFC/) { # FORTRAN source file + count_file_loc($filename, "FORTRAN", \%fort_files, \%fort_files_counted, \$fort_lines); + } elsif($filetype =~ /CXX/) { # C++ source file + count_file_loc($filename, "C++", \%cpp_files, \%cpp_files_counted, \$cpp_lines); + } elsif($filetype =~ /CC/) { # C source file + count_file_loc($filename, "C", \%c_files, \%c_files_counted, \$c_lines); + } +} + +sub sanity_check_loc { + my ($typename, $file_paths, $files_counted) = @_; + + if(scalar keys %{$files_counted} > 0) { + for my $x (keys(%{$files_counted})) { +#print "x = $x, # of compiles = ${$files_counted}{$x}, # of paths = ", scalar(@{$file_paths->{$x}}), "\n"; + if($files_counted->{$x} != scalar(@{$file_paths->{$x}})) { + if(!exists $options{q}) { + warn "# of compiles of C source file '$x' ($files_counted->{$x}) != # of paths (", scalar(@{$file_paths->{$x}}), "), disabling warning density calculation\n"; + } + # Don't print warning density, it's not accurate + delete $options{d}; + last; + } + } + } +} + + sub main::HELP_MESSAGE { do_help(); } # declare the Perl command line flags/options we want to allow -my %options=(); -getopts("FWhut:w:f:s:S:i:l", \%options); +getopts("FWhut:w:f:s:S:i:ldp:q", \%options); # Display usage, if requested if($options{h}) { @@ -185,6 +371,20 @@ if($options{u}) { $genericize = 0; } +# Scan source files, if warning density requested +if(exists $options{d}) { + if(exists $options{p}) { + my @pathnames = split /,/, $options{p}; +#print STDERR @pathnames; + for my $path (@pathnames) { + parse_tree($path); + } + } else { + # Scan the current working directory + parse_tree(getcwd); + } +} + PARSE_LINES: while (<>) { my $name; @@ -197,7 +397,7 @@ while (<>) { my $extra2; # Retain last FORTRAN compile line, which comes a few lines before warning - if($_ =~ /.*\.[fF]90:.*/) { + if($_ =~ /.*((\.inc)|(\.f90)|(\.f)|(\.f03)|(\.f08)|(\.f77)|(\.f95)|(\.for)|(\.fpp))\:.*/i) { ($last_fort_name, $last_fort_line, $last_fort_offset) = split /\:/, $_; ($last_fort_line, $toss) = split /\./, $last_fort_line; } @@ -212,17 +412,30 @@ while (<>) { $last_c_name = $_; } + # Compute LOC for compiled source files, if warning density requested + if(exists $options{d}) { + # Check for compilation line + if($_ =~ /^\s+(CC|FC|CXX|PPFC)\s+/) { + count_source_loc($_); + } + } + # Skip lines that don't have the word "warning" next if $_ !~ /[Ww]arning/; # Skip warnings from linker next if $_ =~ /ld: warning:/; + # Skip warnings from make + next if $_ =~ /^Makefile:[\d]*: warning:/; + # Skip warnings from build_py and install_lib next if $_ =~ /warning: (build_py|install_lib)/; - # Skip variables with the word 'warning' in them - next if $_ =~ /_warning_/; + # Skip variables with the word 'warning' (case insensitively) in them + next if $_ =~ /_warning_/i; + next if $_ =~ /_warning/i; + next if $_ =~ /warning_/i; # Skip AMD Optimizing Compiler (aocc) lines "<#> warning(s) generated." next if $_ =~ / warnings? generated\./; @@ -235,13 +448,9 @@ while (<>) { # Check for weird formatting of warning message $line = "??"; $offset = "??"; - if($_ =~ /^cc1: warning:.*/) { + if($_ =~ /^(cc1|): warning:.*/) { $name = $last_c_name; ($toss, $toss, $warning, $extra, $extra2) = split /\:/, $_; - # Check for CMAKE build with warning on first line and no filename - } elsif($_ =~ /^\s*[Ww]arning:.*/) { - $name = $last_c_name; - ($toss, $warning, $extra, $extra2) = split /\:/, $_; # Check for file-scope gcc Fortran warning output } elsif($_ =~ /f\d\d\d: Warning:/) { # These are interspersed with the "compiling a file" output @@ -274,9 +483,9 @@ while (<>) { } elsif($_ =~ /^\".*, line [0-9]+: *[Ww]arning:.*/) { ($name, $toss, $warning, $extra, $extra2) = split /\:/, $_; ($name, $line) = split /\,/, $name; - $name =~ s/^\"//g; - $name =~ s/\"$//g; - $line =~ s/^\s*line\s*//g; + $name =~ s/^\"//g; + $name =~ s/\"$//g; + $line =~ s/^\s*line\s*//g; # Check for Intel icc warning } elsif($_ =~ /.*[A-Za-z0-9_]\.[chC]\(.*[0-9]\):.*#.*/) { ($last_c_name, $toss, $warning) = split /\:/, $last_c_name; @@ -294,19 +503,13 @@ while (<>) { # Check for extra ':' followed by more text in original warning string, # and append the ':' and text back onto the parsed warning - # (Use 'length $extra' idiom to avoid warning when $extra is undefined) - if(length $extra ) { + if(defined $extra) { $warning = join ':', $warning, $extra; } - if(length $extra2 ) { + if(defined $extra2) { $warning = join ':', $warning, $extra2; } - # Restore the C++ '::' symbol now that we've parsed out the parts of the line - while($warning =~ /@@@@/) { - $warning =~ s/@@@@/\:\:/g; - } - # Trim leading '..' paths from filename while($name =~ /^\.\.\//) { $name =~ s/^\.\.\///g; @@ -336,6 +539,11 @@ while (<>) { next } + # Restore the C++ '::' symbol now that we've parsed out the parts of the line + while($warning =~ /@@@@/) { + $warning =~ s/@@@@/\:\:/g; + } + # Get rid of leading & trailing whitespace $warning =~ s/^\s//g; $warning =~ s/\s$//g; @@ -383,8 +591,8 @@ while (<>) { if($warning =~ /'[A-Za-z_0-9\(\)\*\,\[\]\.\<\>\&\:\+\#\-\=]+[A-Za-z_0-9\(\)\*\,\[\]\.\<\>\&\:\+\#\-\=\ ]*'/) { $warning =~ s/'[A-Za-z_0-9\(\)\*\,\[\]\.\<\>\&\:\+\#\-\=]+[A-Za-z_0-9\(\)\*\,\[\]\.\<\>\&\:\+\#\-\=\ ]*'/'-'/g; } - if($warning =~ /'%[\#0\-\ \+]*[,;\:_]?[0-9\*]*\.?[0-9\*]*[hjltzL]*[aAcdeEfFgGinosuxX]'/) { - $warning =~ s/'%[\#0\-\ \+]*[,;\:_]?[0-9\*]*\.?[0-9\*]*[hjltzL]*[aAcdeEfFgGinosuxX]'/'-'/g; + if($warning =~ /'%[\#0\-\ \+]*[,;\:_]?[0-9\*]*\.?[0-9\*]*[hjltzL]*[aAcdeEfFgGinopsuxX]'/) { + $warning =~ s/'%[\#0\-\ \+]*[,;\:_]?[0-9\*]*\.?[0-9\*]*[hjltzL]*[aAcdeEfFgGinopsuxX]'/'-'/g; } # Genericize C/C++ "" warnings into "-" @@ -397,6 +605,11 @@ while (<>) { $warning =~ s/=[A-Za-z_0-9]*\]/=-\]/g; } + # Genericize C/C++ "No such file or directory" warnings into "-" + if($warning =~ /^[A-Za-z_0-9\/]*: No such file or directory/) { + $warning =~ s/^[A-Za-z_0-9\/]*:/'-':/g; + } + # Genericize FORTRAN "at ()" into "at (-)", "REAL()" into "REAL(-)", # and "INTEGER()" into "INTEGER(-)" if($warning =~ /.*at\s\([0-9]+\).*/) { @@ -449,7 +662,31 @@ while (<>) { # print STDERR "warning = \"$warning\"\n"; } -print "Total unique [non-ignored] warnings: $totalcount\n"; +# Sanity check compiled source files with multiple paths when computing +# warning density +# (Check $options{d} each time, because any of the sanity checks could disable +# displaying the warning density) +if(exists $options{d}) { + sanity_check_loc("C", \%c_files, \%c_files_counted); +} +if(exists $options{d}) { + sanity_check_loc("FORTRAN", \%fort_files, \%fort_files_counted); +} +if(exists $options{d}) { + sanity_check_loc("C++", \%cpp_files, \%cpp_files_counted); +} + + +# +# Display results +# + +print "\nTotal unique [non-ignored] warnings: $totalcount\n"; +# Display warning density, if requested +if(exists $options{d}) { + print "Lines of code compiled: (C/C++/FORTRAN): ", ($c_lines + $cpp_lines + $fort_lines), " ($c_lines/$cpp_lines/$fort_lines)\n"; + printf "Warning density (<# of warnings> / <# of LOC compiled>): %10.10f\n", $totalcount / ($c_lines + $cpp_lines + $fort_lines); +} print "Ignored notes / supplemental warning lines [not counted in unique warnings]: $notecount\n"; print "Duplicated warning lines [not counted in unique warnings]: $dupcount\n"; print "Total ignored warnings: $ignorecount\n"; @@ -484,7 +721,7 @@ for my $x (sort {$warn_count{$b} <=> $warn_count{$a}} keys(%warn_count)) { $match = 1; } - if($match) { + if($match || exists $options{W}) { for my $y (sort {$warn_file{$x}{$b} <=> $warn_file{$x}{$a}} keys(%{$warn_file{$x}})) { printf ("\t%4d - %s\n", $warn_file{$x}{$y}, $y); if(exists $options{l}) { @@ -522,7 +759,7 @@ for my $x (sort {$file_count{$b} <=> $file_count{$a}} keys(%file_count)) { $match = 1; } - if($match) { + if($match || exists $options{F}) { for my $y (sort {$file_warn{$x}{$b} <=> $file_warn{$x}{$a}} keys(%{$file_warn{$x}})) { printf ("\t%4d - %s\n", $file_warn{$x}{$y}, $y); if(exists $options{l}) { diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 801336358bf..df28f76bd7d 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -594,6 +594,17 @@ if (HDF5_ENABLE_CODESTACK) endif () MARK_AS_ADVANCED (HDF5_ENABLE_CODESTACK) +# ---------------------------------------------------------------------- +# Check if they would like to show all warnings (not suppressed internally) +#----------------------------------------------------------------------------- +option (HDF5_SHOW_ALL_WARNINGS "Show all warnings (not suppressed internally)." OFF) +mark_as_advanced (HDF5_SHOW_ALL_WARNINGS) +if (HDF5_SHOW_ALL_WARNINGS) + message (STATUS "....All warnings will be displayed") + set (${HDF_PREFIX}_SHOW_ALL_WARNINGS 1) +endif () +MARK_AS_ADVANCED (HDF5_SHOW_ALL_WARNINGS) + # ---------------------------------------------------------------------- # Check if they would like to use file locking by default #----------------------------------------------------------------------------- diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 847c835eaea..2534b8e2542 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -631,6 +631,9 @@ /* Check exception handling functions during data conversions */ #cmakedefine H5_WANT_DCONV_EXCEPTION @H5_WANT_DCONV_EXCEPTION@ +/* Define if showing all compiler warnings are desired (i.e. don't suppress them internally) */ +#cmakedefine H5_SHOW_ALL_WARNINGS @H5_SHOW_ALL_WARNINGS@ + /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if !defined(__APPLE__) diff --git a/configure.ac b/configure.ac index 689ab3d2a42..650ee1ddab4 100644 --- a/configure.ac +++ b/configure.ac @@ -2311,6 +2311,45 @@ case "X-$DEV_WARNINGS" in ;; esac +## ---------------------------------------------------------------------- +## Check if they would like suppessed compiler diagnostics displayed +## (i.e. not suppressed) +## +## NOTE: Compiler diagnostics (i.e. warnings) are suppressed for some +## "noisy" warnings that are harmless (in the opinion of the primary +## HDF5 development team), but this option is provided to allow +## developers to see those warnings. +## +AC_MSG_CHECKING([whether showing all compiler warnings is enabled]) +AC_ARG_ENABLE([show-all-warnings], + [AS_HELP_STRING([--enable-show-all-warnings], + [Enable showing all compiler warnings (for developer debugging). + [default=no] + ])], + [SHOW_ALL_WARNINGS=$enableval]) + +## Set the default level. +if test "X-$SHOW_ALL_WARNINGS" = X- ; then + SHOW_ALL_WARNINGS=no +fi + +## Allow this variable to be substituted in +## other files (src/libhdf5.settings.in, etc.) +AC_SUBST([SHOW_ALL_WARNINGS]) + +case "X-$SHOW_ALL_WARNINGS" in + X-yes) + AC_MSG_RESULT([yes]) + AC_DEFINE([SHOW_ALL_WARNINGS], [1], [Define if showing all warnings is desired (i.e. not suppressed internally with H5_DIAG_OFF)]) + ;; + X-no) + AC_MSG_RESULT([no]) + ;; + *) + AC_MSG_ERROR([Unrecognized value: $SHOW_ALL_WARNINGS]) + ;; +esac + ## ---------------------------------------------------------------------- ## Check if the compiler should use profiling flags/settings ## diff --git a/fortran/src/H5config_f.inc.cmake b/fortran/src/H5config_f.inc.cmake index 665207641ee..433fd3568be 100644 --- a/fortran/src/H5config_f.inc.cmake +++ b/fortran/src/H5config_f.inc.cmake @@ -28,8 +28,8 @@ #endif ! Define if on APPLE -#cmakedefine01 H5_HAVE_DARWIN -#if H5_HAVE_DARWIN == 0 +#cmakedefine01 CMAKE_H5_HAVE_DARWIN +#if CMAKE_H5_HAVE_DARWIN == 0 #undef H5_HAVE_DARWIN #else #define H5_HAVE_DARWIN diff --git a/release_docs/INSTALL_CMake.txt b/release_docs/INSTALL_CMake.txt index 27c185d544c..90e816e4fa4 100644 --- a/release_docs/INSTALL_CMake.txt +++ b/release_docs/INSTALL_CMake.txt @@ -826,6 +826,7 @@ ALLOW_UNSUPPORTED "Allow unsupported combinations of configure opti HDF5_EXTERNAL_LIB_PREFIX "Use prefix for custom library naming." "" HDF5_DISABLE_COMPILER_WARNINGS "Disable compiler warnings" OFF HDF5_ENABLE_ALL_WARNINGS "Enable all warnings" OFF +HDF5_SHOW_ALL_WARNINGS "Show all warnings (i.e. not suppress "noisy" ones internally)" OFF HDF5_ENABLE_CODESTACK "Enable the function stack tracing (for developer debugging)." OFF HDF5_ENABLE_COVERAGE "Enable code coverage for Libraries and Programs" OFF HDF5_ENABLE_DEBUG_APIS "Turn on extra debug output in all packages" OFF diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index a3695ae8544..dc842e8825b 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -727,7 +727,7 @@ H5_DLL herr_t H5D__chunk_allocated(const H5D_t *dset, hsize_t *nbytes); H5_DLL herr_t H5D__chunk_allocate(const H5D_t *dset, bool full_overwrite, const hsize_t old_dim[]); H5_DLL herr_t H5D__chunk_file_alloc(const H5D_chk_idx_info_t *idx_info, const H5F_block_t *old_chunk, H5F_block_t *new_chunk, bool *need_insert, const hsize_t *scaled); -H5_DLL void *H5D__chunk_mem_alloc(size_t size, void *pline); +H5_DLL void *H5D__chunk_mem_alloc(size_t size, void *pline) H5_ATTR_MALLOC; H5_DLL void H5D__chunk_mem_free(void *chk, void *pline); H5_DLL void *H5D__chunk_mem_xfree(void *chk, const void *pline); H5_DLL void *H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline); diff --git a/src/H5EApkg.h b/src/H5EApkg.h index 90ba02a02d8..e8b5a13e8d4 100644 --- a/src/H5EApkg.h +++ b/src/H5EApkg.h @@ -389,7 +389,7 @@ H5_DLL herr_t H5EA__destroy_flush_depend(H5AC_info_t *parent_entry, H5AC_info_t H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f); H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata); H5_DLL haddr_t H5EA__hdr_create(H5F_t *f, const H5EA_create_t *cparam, void *ctx_udata); -H5_DLL void *H5EA__hdr_alloc_elmts(H5EA_hdr_t *hdr, size_t nelmts); +H5_DLL void *H5EA__hdr_alloc_elmts(H5EA_hdr_t *hdr, size_t nelmts) H5_ATTR_MALLOC; H5_DLL herr_t H5EA__hdr_free_elmts(H5EA_hdr_t *hdr, size_t nelmts, void *elmts); H5_DLL herr_t H5EA__hdr_incr(H5EA_hdr_t *hdr); H5_DLL herr_t H5EA__hdr_decr(H5EA_hdr_t *hdr); diff --git a/src/H5ESpkg.h b/src/H5ESpkg.h index f7c70e8f0c7..1da58a68679 100644 --- a/src/H5ESpkg.h +++ b/src/H5ESpkg.h @@ -75,7 +75,7 @@ typedef int (*H5ES_list_iter_func_t)(H5ES_event_t *ev, void *ctx); /******************************/ /* Package Private Prototypes */ /******************************/ -H5_DLL H5ES_t *H5ES__create(void); +H5_DLL H5ES_t *H5ES__create(void) H5_ATTR_MALLOC; H5_DLL herr_t H5ES__insert_request(H5ES_t *es, H5VL_t *connector, void *token); H5_DLL herr_t H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, bool *op_failed); H5_DLL herr_t H5ES__get_requests(H5ES_t *es, H5_iter_order_t order, hid_t *connector_ids, void **requests, diff --git a/src/H5Idbg.c b/src/H5Idbg.c index 4c7d1ec17c5..7910b1ce43d 100644 --- a/src/H5Idbg.c +++ b/src/H5Idbg.c @@ -83,13 +83,13 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) fprintf(stderr, " id = %" PRIdHID "\n", info->id); fprintf(stderr, " count = %u\n", info->count); - fprintf(stderr, " obj = 0x%8p\n", info->object); + fprintf(stderr, " obj = 0x%8p\n", info->u.c_object); fprintf(stderr, " marked = %d\n", info->marked); /* Get the group location, so we get get the name */ switch (type) { case H5I_GROUP: { - const H5VL_object_t *vol_obj = (const H5VL_object_t *)info->object; + const H5VL_object_t *vol_obj = (const H5VL_object_t *)info->u.c_object; object = H5VL_object_data(vol_obj); if (H5_VOL_NATIVE == vol_obj->connector->cls->value) @@ -98,7 +98,7 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) } case H5I_DATASET: { - const H5VL_object_t *vol_obj = (const H5VL_object_t *)info->object; + const H5VL_object_t *vol_obj = (const H5VL_object_t *)info->u.c_object; object = H5VL_object_data(vol_obj); if (H5_VOL_NATIVE == vol_obj->connector->cls->value) @@ -107,13 +107,10 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) } case H5I_DATATYPE: { - const H5T_t *dt = (const H5T_t *)info->object; + H5T_t *dt = info->u.object; - H5_GCC_CLANG_DIAG_OFF("cast-qual") - object = (void *)H5T_get_actual_type((H5T_t *)dt); - H5_GCC_CLANG_DIAG_ON("cast-qual") - - path = H5T_nameof(object); + object = H5T_get_actual_type((H5T_t *)dt); + path = H5T_nameof(object); break; } diff --git a/src/H5Iint.c b/src/H5Iint.c index 7d8b4acd0cc..1c5321461cc 100644 --- a/src/H5Iint.c +++ b/src/H5Iint.c @@ -369,17 +369,16 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) */ if (udata->force || (info->count - (!udata->app_ref * info->app_count)) <= 1) { /* Check if this is an un-realized future object */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") if (info->is_future) { /* Discard the future object */ - if ((info->discard_cb)((void *)info->object) < 0) { + if ((info->discard_cb)(info->u.object) < 0) { if (udata->force) { #ifdef H5I_DEBUG if (H5DEBUG(I)) { fprintf(H5DEBUG(I), "H5I: discard type=%d obj=%p " "failure ignored\n", - (int)udata->type_info->cls->type, info->object); + (int)udata->type_info->cls->type, info->u.c_object); } #endif /* H5I_DEBUG */ @@ -395,14 +394,14 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) else { /* Check for a 'free' function and call it, if it exists */ if (udata->type_info->cls->free_func && - (udata->type_info->cls->free_func)((void *)info->object, H5_REQUEST_NULL) < 0) { + (udata->type_info->cls->free_func)(info->u.object, H5_REQUEST_NULL) < 0) { if (udata->force) { #ifdef H5I_DEBUG if (H5DEBUG(I)) { fprintf(H5DEBUG(I), "H5I: free type=%d obj=%p " "failure ignored\n", - (int)udata->type_info->cls->type, info->object); + (int)udata->type_info->cls->type, info->u.c_object); } #endif /* H5I_DEBUG */ @@ -415,7 +414,6 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) mark = true; } } - H5_GCC_CLANG_DIAG_ON("cast-qual") /* Remove ID if requested */ if (mark) { @@ -524,7 +522,7 @@ H5I__register(H5I_type_t type, const void *object, bool app_ref, H5I_future_real info->id = new_id; info->count = 1; /* initial reference count */ info->app_count = !!app_ref; - info->object = object; + info->u.c_object = object; info->is_future = (NULL != realize_cb); info->realize_cb = realize_cb; info->discard_cb = discard_cb; @@ -633,7 +631,7 @@ H5I_register_using_existing_id(H5I_type_t type, void *object, bool app_ref, hid_ info->id = existing_id; info->count = 1; /* initial reference count*/ info->app_count = !!app_ref; - info->object = object; + info->u.object = object; /* This API call is only used by the native VOL connector, which is * not asynchronous. */ @@ -677,12 +675,10 @@ H5I_subst(hid_t id, const void *new_object) HGOTO_ERROR(H5E_ID, H5E_NOTFOUND, NULL, "can't get ID ref count"); /* Get the old object pointer to return */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - ret_value = (void *)info->object; - H5_GCC_CLANG_DIAG_ON("cast-qual") + ret_value = info->u.object; /* Set the new object pointer for the ID */ - info->object = new_object; + info->u.c_object = new_object; done: FUNC_LEAVE_NOAPI(ret_value) @@ -709,12 +705,9 @@ H5I_object(hid_t id) FUNC_ENTER_NOAPI_NOERR /* General lookup of the ID */ - if (NULL != (info = H5I__find_id(id))) { + if (NULL != (info = H5I__find_id(id))) /* Get the object pointer to return */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - ret_value = (void *)info->object; - H5_GCC_CLANG_DIAG_ON("cast-qual") - } + ret_value = info->u.object; FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_object() */ @@ -742,12 +735,9 @@ H5I_object_verify(hid_t id, H5I_type_t type) assert(type >= 1 && (int)type < H5I_next_type_g); /* Verify that the type of the ID is correct & lookup the ID */ - if (type == H5I_TYPE(id) && NULL != (info = H5I__find_id(id))) { + if (type == H5I_TYPE(id) && NULL != (info = H5I__find_id(id))) /* Get the object pointer to return */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - ret_value = (void *)info->object; - H5_GCC_CLANG_DIAG_ON("cast-qual") - } + ret_value = info->u.object; FUNC_LEAVE_NOAPI(ret_value) } /* H5I_object_verify() */ @@ -898,9 +888,7 @@ H5I__remove_common(H5I_type_info_t *type_info, hid_t id) if (type_info->last_id_info == info) type_info->last_id_info = NULL; - H5_GCC_CLANG_DIAG_OFF("cast-qual") - ret_value = (void *)info->object; - H5_GCC_CLANG_DIAG_ON("cast-qual") + ret_value = info->u.object; if (!H5I_marking_s) info = H5FL_FREE(H5I_id_info_t, info); @@ -1000,8 +988,7 @@ H5I__dec_ref(hid_t id, void **request) /* Get the ID's type */ type_info = H5I_type_info_array_g[H5I_TYPE(id)]; - H5_GCC_CLANG_DIAG_OFF("cast-qual") - if (!type_info->cls->free_func || (type_info->cls->free_func)((void *)info->object, request) >= 0) { + if (!type_info->cls->free_func || (type_info->cls->free_func)(info->u.object, request) >= 0) { /* Remove the node from the type */ if (NULL == H5I__remove_common(type_info, id)) HGOTO_ERROR(H5E_ID, H5E_CANTDELETE, (-1), "can't remove ID node"); @@ -1009,7 +996,6 @@ H5I__dec_ref(hid_t id, void **request) } /* end if */ else ret_value = -1; - H5_GCC_CLANG_DIAG_ON("cast-qual") } /* end if */ else { --(info->count); @@ -1482,9 +1468,7 @@ H5I__iterate_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) /* The stored object pointer might be an H5VL_object_t, in which * case we'll need to get the wrapped object struct (H5F_t *, etc.). */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - object = H5I__unwrap((void *)info->object, type); - H5_GCC_CLANG_DIAG_ON("cast-qual") + object = H5I__unwrap(info->u.object, type); /* Invoke callback function */ cb_ret_val = (*udata->user_func)((void *)object, info->id, udata->user_udata); @@ -1607,14 +1591,13 @@ H5I__find_id(hid_t id) } /* Check if this is a future ID */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") if (id_info && id_info->is_future) { hid_t actual_id = H5I_INVALID_HID; /* ID for actual object */ void *future_object; /* Pointer to the future object */ void *actual_object; /* Pointer to the actual object */ /* Invoke the realize callback, to get the actual object */ - if ((id_info->realize_cb)((void *)id_info->object, &actual_id) < 0) + if ((id_info->realize_cb)(id_info->u.object, &actual_id) < 0) HGOTO_DONE(NULL); /* Verify that we received a valid ID, of the same type */ @@ -1624,10 +1607,10 @@ H5I__find_id(hid_t id) HGOTO_DONE(NULL); /* Swap the actual object in for the future object */ - future_object = (void *)id_info->object; + future_object = id_info->u.object; actual_object = H5I__remove_common(type_info, actual_id); assert(actual_object); - id_info->object = actual_object; + id_info->u.object = actual_object; /* Discard the future object */ if ((id_info->discard_cb)(future_object) < 0) @@ -1639,7 +1622,6 @@ H5I__find_id(hid_t id) id_info->realize_cb = NULL; id_info->discard_cb = NULL; } - H5_GCC_CLANG_DIAG_ON("cast-qual") /* Set return value */ ret_value = id_info; @@ -1674,9 +1656,7 @@ H5I__find_id_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) assert(udata); /* Get a pointer to the VOL connector's data */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - object = H5I__unwrap((void *)info->object, type); - H5_GCC_CLANG_DIAG_ON("cast-qual") + object = H5I__unwrap(info->u.object, type); /* Check for a match */ if (object == udata->object) { diff --git a/src/H5Ipkg.h b/src/H5Ipkg.h index 620796278f4..c42c61d3d1b 100644 --- a/src/H5Ipkg.h +++ b/src/H5Ipkg.h @@ -56,10 +56,13 @@ /* ID information structure used */ typedef struct H5I_id_info_t { - hid_t id; /* ID for this info */ - unsigned count; /* Ref. count for this ID */ - unsigned app_count; /* Ref. count of application visible IDs */ - const void *object; /* Pointer associated with the ID */ + hid_t id; /* ID for this info */ + unsigned count; /* Ref. count for this ID */ + unsigned app_count; /* Ref. count of application visible IDs */ + union { + const void *c_object; /* Const pointer associated with the ID */ + void *object; /* Pointer associated with the ID */ + } u; /* Future ID info */ bool is_future; /* Whether this ID represents a future object */ diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index fa70e386dc3..36c24579959 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -175,7 +175,7 @@ H5_DLL herr_t H5P_insert(H5P_genplist_t *plist, const char *name, size_t size, v H5_DLL herr_t H5P_remove(H5P_genplist_t *plist, const char *name); H5_DLL htri_t H5P_exist_plist(const H5P_genplist_t *plist, const char *name); H5_DLL htri_t H5P_class_isa(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2); -H5_DLL char *H5P_get_class_name(H5P_genclass_t *pclass); +H5_DLL char *H5P_get_class_name(H5P_genclass_t *pclass) H5_ATTR_MALLOC; /* Internal helper routines */ H5_DLL herr_t H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, bool recurse); diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 7a79d449c0f..b9e24be912b 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -870,7 +870,7 @@ H5_DLL herr_t H5T__enum_insert(const H5T_t *dt, const char *name, const void *va H5_DLL herr_t H5T__get_member_value(const H5T_t *dt, unsigned membno, void *value); /* Field functions (for both compound & enumerated types) */ -H5_DLL char *H5T__get_member_name(H5T_t const *dt, unsigned membno); +H5_DLL char *H5T__get_member_name(H5T_t const *dt, unsigned membno) H5_ATTR_MALLOC; H5_DLL herr_t H5T__sort_value(const H5T_t *dt, int *map); H5_DLL herr_t H5T__sort_name(const H5T_t *dt, int *map); diff --git a/src/H5private.h b/src/H5private.h index 3aaa0d52453..5663c00123f 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -497,8 +497,16 @@ #define H5_DIAG_DO_PRAGMA(x) _Pragma(#x) #define H5_DIAG_PRAGMA(x) H5_DIAG_DO_PRAGMA(GCC diagnostic x) +/* Allow suppression of compiler diagnostics unless H5_SHOW_ALL_WARNINGS is + * defined (enabled with '--enable-show-all-warnings' configure option). + */ +#ifndef H5_SHOW_ALL_WARNINGS #define H5_DIAG_OFF(x) H5_DIAG_PRAGMA(push) H5_DIAG_PRAGMA(ignored H5_DIAG_JOINSTR("-W", x)) #define H5_DIAG_ON(x) H5_DIAG_PRAGMA(pop) +#else +#define H5_DIAG_OFF(x) +#define H5_DIAG_ON(x) +#endif /* Macros for enabling/disabling particular GCC-only warnings. * These pragmas are only implemented usefully in gcc 4.6+ diff --git a/test/event_set.c b/test/event_set.c index 52aa6ba5a4b..9e659aada15 100644 --- a/test/event_set.c +++ b/test/event_set.c @@ -22,8 +22,8 @@ static const char *FILENAME[] = {"event_set_1", NULL}; static hid_t connector_ids_g[EVENT_SET_NUM_CONNECTOR_IDS]; -herr_t fake_wait_request_wait(void *req, uint64_t timeout, H5VL_request_status_t *status); -herr_t fake_wait_request_free(void *req); +herr_t fake_wait_request_wait(void *req, uint64_t timeout, H5VL_request_status_t *status); +H5_ATTR_CONST herr_t fake_wait_request_free(void *req); /* A VOL class struct that describes a VOL class with no * functionality, other than a wait that returns success. diff --git a/tools/src/h5import/h5import.c b/tools/src/h5import/h5import.c index 2d3574a2f83..663f68a7479 100644 --- a/tools/src/h5import/h5import.c +++ b/tools/src/h5import/h5import.c @@ -26,48 +26,48 @@ #endif /* Local function declarations */ -static int gtoken(char *s); -static int process(struct Options *opt); -static int processConfigurationFile(char *infile, struct Input *in); -static int mapKeywordToIndex(char *key); -static int parsePathInfo(struct path_info *path, char *strm); -static int parseDimensions(struct Input *in, char *strm); -static int getInputSize(struct Input *in, int ival); -static int getInputClass(struct Input *in, char *strm); -static int getInputClassType(struct Input *in, char *strm); -static int getInputByteOrder(struct Input *in, FILE *strm); -static int InputClassStrToInt(char *temp); -static int getRank(struct Input *in, FILE *strm); -static int getDimensionSizes(struct Input *in, FILE *strm); -static int getOutputSize(struct Input *in, FILE *strm); -static int getOutputClass(struct Input *in, FILE *strm); -static int OutputClassStrToInt(char *temp); -static int getOutputArchitecture(struct Input *in, FILE *strm); -static int OutputArchStrToInt(const char *temp); -static int getOutputByteOrder(struct Input *in, FILE *strm); -static int OutputByteOrderStrToInt(const char *temp); -static int getChunkedDimensionSizes(struct Input *in, FILE *strm); -static int getCompressionType(struct Input *in, FILE *strm); -static int CompressionTypeStrToInt(char *temp); -static int getCompressionParameter(struct Input *in, FILE *strm); -static int getExternalFilename(struct Input *in, FILE *strm); -static int getMaximumDimensionSizes(struct Input *in, FILE *strm); -static int processDataFile(char *infile, struct Input *in, hid_t file_id); -static int readIntegerData(FILE *strm, struct Input *in); -static int readFloatData(FILE *strm, struct Input *in); -static int allocateIntegerStorage(struct Input *in); -static int allocateFloatStorage(struct Input *in); -static int readUIntegerData(FILE *strm, struct Input *in); -static int allocateUIntegerStorage(struct Input *in); -static int validateConfigurationParameters(struct Input *in); -static int processStrData(FILE *strm, struct Input *in, hid_t file_id); -static int processStrHDFData(FILE *strm, struct Input *in, hid_t file_id); -uint16_t swap_uint16(uint16_t val); -int16_t swap_int16(int16_t val); -uint32_t swap_uint32(uint32_t val); -int32_t swap_int32(int32_t val); -int64_t swap_int64(int64_t val); -uint64_t swap_uint64(uint64_t val); +static int gtoken(char *s); +static int process(struct Options *opt); +static int processConfigurationFile(char *infile, struct Input *in); +static int mapKeywordToIndex(char *key); +static int parsePathInfo(struct path_info *path, char *strm); +static int parseDimensions(struct Input *in, char *strm); +static int getInputSize(struct Input *in, int ival); +static int getInputClass(struct Input *in, char *strm); +static int getInputClassType(struct Input *in, char *strm); +static int getInputByteOrder(struct Input *in, FILE *strm); +static int InputClassStrToInt(char *temp); +static int getRank(struct Input *in, FILE *strm); +static int getDimensionSizes(struct Input *in, FILE *strm); +static int getOutputSize(struct Input *in, FILE *strm); +static int getOutputClass(struct Input *in, FILE *strm); +static int OutputClassStrToInt(char *temp); +static int getOutputArchitecture(struct Input *in, FILE *strm); +static int OutputArchStrToInt(const char *temp); +static int getOutputByteOrder(struct Input *in, FILE *strm); +static int OutputByteOrderStrToInt(const char *temp); +static int getChunkedDimensionSizes(struct Input *in, FILE *strm); +static int getCompressionType(struct Input *in, FILE *strm); +static int CompressionTypeStrToInt(char *temp); +static int getCompressionParameter(struct Input *in, FILE *strm); +static int getExternalFilename(struct Input *in, FILE *strm); +static int getMaximumDimensionSizes(struct Input *in, FILE *strm); +static int processDataFile(char *infile, struct Input *in, hid_t file_id); +static int readIntegerData(FILE *strm, struct Input *in); +static int readFloatData(FILE *strm, struct Input *in); +static int allocateIntegerStorage(struct Input *in); +static int allocateFloatStorage(struct Input *in); +static int readUIntegerData(FILE *strm, struct Input *in); +static int allocateUIntegerStorage(struct Input *in); +static int validateConfigurationParameters(struct Input *in); +static int processStrData(FILE *strm, struct Input *in, hid_t file_id); +static int processStrHDFData(FILE *strm, struct Input *in, hid_t file_id); +H5_ATTR_CONST uint16_t swap_uint16(uint16_t val); +H5_ATTR_CONST int16_t swap_int16(int16_t val); +H5_ATTR_CONST uint32_t swap_uint32(uint32_t val); +H5_ATTR_CONST int32_t swap_int32(int32_t val); +H5_ATTR_CONST int64_t swap_int64(int64_t val); +H5_ATTR_CONST uint64_t swap_uint64(uint64_t val); int main(int argc, char *argv[]) diff --git a/utils/mirror_vfd/mirror_writer.c b/utils/mirror_vfd/mirror_writer.c index a5a1d27f90b..f1569657deb 100644 --- a/utils/mirror_vfd/mirror_writer.c +++ b/utils/mirror_vfd/mirror_writer.c @@ -29,7 +29,6 @@ /* in detailed logging */ #define HEXDUMP_WRITEDATA 0 /* Toggle whether to print bytes to write */ /* in detailed logging */ -#define LISTENQ 80 /* max pending Driver requests */ #define MW_SESSION_MAGIC 0x88F36B32u #define MW_SOCK_COMM_MAGIC 0xDF10A157u From 2fc140079b861b6efeede10ca6d796276657a9ff Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Sat, 30 Dec 2023 17:33:31 -0600 Subject: [PATCH 2/2] Added H5Fdelete_f with test (#3912) --- fortran/src/H5Fff.F90 | 43 +++++++++++++++++++++++-- fortran/src/hdf5_fortrandll.def.in | 1 + fortran/test/tH5F.F90 | 51 ++++++++++++++++++++++++------ release_docs/RELEASE.txt | 3 ++ 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/fortran/src/H5Fff.F90 b/fortran/src/H5Fff.F90 index d31117784e5..79aa5a7a34b 100644 --- a/fortran/src/H5Fff.F90 +++ b/fortran/src/H5Fff.F90 @@ -256,6 +256,43 @@ END SUBROUTINE h5fflush_f !> !! \ingroup FH5F !! +!! \brief Deletes an HDF5 file +!! +!! \param name Name of the file to delete +!! \param hdferr \fortran_error +!! \param access_prp File access property list identifier +!! +!! See C API: @ref H5Fdelete() +!! + SUBROUTINE h5fdelete_f(name, hdferr, access_prp) + IMPLICIT NONE + CHARACTER(LEN=*), INTENT(IN) :: name + INTEGER , INTENT(OUT) :: hdferr + INTEGER(HID_T) , INTENT(IN), OPTIONAL :: access_prp + + INTEGER(HID_T) :: access_prp_default + CHARACTER(LEN=LEN_TRIM(name)+1,KIND=C_CHAR) :: c_name + + INTERFACE + INTEGER(C_INT) FUNCTION H5Fdelete(name, access_prp_default) BIND(C,NAME='H5Fdelete') + IMPORT :: C_CHAR, C_INT + IMPORT :: HID_T + CHARACTER(KIND=C_CHAR), DIMENSION(*) :: name + INTEGER(HID_T), VALUE :: access_prp_default + END FUNCTION H5Fdelete + END INTERFACE + + c_name = TRIM(name)//C_NULL_CHAR + + access_prp_default = H5P_DEFAULT_F + IF (PRESENT(access_prp)) access_prp_default = access_prp + + hdferr = INT(H5Fdelete(c_name, access_prp_default)) + + END SUBROUTINE h5fdelete_f +!> +!! \ingroup FH5F +!! !! \brief Asynchronously flushes all buffers associated with a file to disk. !! !! \param object_id Identifier of object used to identify the file. @@ -285,7 +322,7 @@ SUBROUTINE h5fflush_async_f(object_id, scope, es_id, hdferr, file, func, line) INTEGER(KIND=C_INT) :: line_default = 0 INTERFACE - INTEGER FUNCTION H5Fflush_async(file, func, line, object_id, scope, es_id) & + INTEGER(C_INT) FUNCTION H5Fflush_async(file, func, line, object_id, scope, es_id) & BIND(C,NAME='H5Fflush_async') IMPORT :: C_CHAR, C_INT, C_PTR IMPORT :: HID_T @@ -303,8 +340,8 @@ END FUNCTION H5Fflush_async IF(PRESENT(func)) func_default = func IF(PRESENT(line)) line_default = INT(line, C_INT) - hdferr = H5Fflush_async(file_default, func_default, line_default, & - object_id, INT(scope, C_INT), es_id) + hdferr = INT(H5Fflush_async(file_default, func_default, line_default, & + object_id, INT(scope, C_INT), es_id)) END SUBROUTINE h5fflush_async_f !> diff --git a/fortran/src/hdf5_fortrandll.def.in b/fortran/src/hdf5_fortrandll.def.in index 55f4f2b579b..119e140e399 100644 --- a/fortran/src/hdf5_fortrandll.def.in +++ b/fortran/src/hdf5_fortrandll.def.in @@ -121,6 +121,7 @@ H5ES_mp_H5ESGET_ERR_COUNT_F H5ES_mp_H5ESCLOSE_F ; H5F H5F_mp_H5FCREATE_F +H5F_mp_H5FDELETE_F H5F_mp_H5FCREATE_ASYNC_F H5F_mp_H5FFLUSH_F H5F_mp_H5FFLUSH_ASYNC_F diff --git a/fortran/test/tH5F.F90 b/fortran/test/tH5F.F90 index b4d973e6844..7f9490b7d20 100644 --- a/fortran/test/tH5F.F90 +++ b/fortran/test/tH5F.F90 @@ -479,10 +479,11 @@ SUBROUTINE mountingtest(cleanup, total_error) total_error = total_error + 1 ENDIF - if(cleanup) CALL h5_cleanup_f(filename1, H5P_DEFAULT_F, error) + IF(cleanup) CALL h5_cleanup_f(filename1, H5P_DEFAULT_F, error) CALL check("h5_cleanup_f", error, total_error) - if(cleanup) CALL h5_cleanup_f(filename2, H5P_DEFAULT_F, error) + IF(cleanup) CALL h5_cleanup_f(filename2, H5P_DEFAULT_F, error) CALL check("h5_cleanup_f", error, total_error) + RETURN END SUBROUTINE mountingtest @@ -853,7 +854,9 @@ SUBROUTINE plisttest(cleanup, total_error) INTEGER(HID_T) :: access_id ! File Access property list identifier !flag to check operation success - INTEGER :: error + INTEGER :: error + !file status + LOGICAL :: status ! !Create a file1 using default properties. @@ -920,10 +923,37 @@ SUBROUTINE plisttest(cleanup, total_error) CALL h5fclose_f(file2_id, error) CALL check("h5fclose_f",error,total_error) - if(cleanup) CALL h5_cleanup_f(filename1, H5P_DEFAULT_F, error) - CALL check("h5_cleanup_f", error, total_error) - if(cleanup) CALL h5_cleanup_f(filename2, H5P_DEFAULT_F, error) - CALL check("h5_cleanup_f", error, total_error) + ! Test file deletion + CALL h5fis_accessible_f(filename1, status, error) + CALL check("h5fis_accessible_f",error,total_error) + IF ( .NOT. status ) THEN + WRITE(*,*) "ERROR: File ", filename1, " is not accessible as hdf5" + END IF + + CALL h5fdelete_f(filename1, error, H5P_DEFAULT_F) + CALL check("h5fdelete_f", error, total_error) + + INQUIRE(FILE=filename1, EXIST=status) + IF ( status ) THEN + WRITE(*,*) "ERROR: File ", filename1, " was not removed by H5Fdelete_f" + END IF + + CALL h5fis_accessible_f(filename2, status, error) + CALL check("h5fis_accessible_f",error,total_error) + IF ( .NOT. status ) THEN + WRITE(*,*) "ERROR: File ", filename2, " is not accessible as hdf5" + total_error=total_error + 1 + END IF + + CALL h5fdelete_f(filename2, error) + CALL check("h5fdelete_f", error, total_error) + + INQUIRE(FILE=filename2, EXIST=status) + IF ( status ) THEN + WRITE(*,*) "ERROR: File ", filename2, " was not removed by H5Fdelete_f" + total_error=total_error + 1 + END IF + RETURN END SUBROUTINE plisttest @@ -1320,6 +1350,7 @@ SUBROUTINE test_get_file_image(total_error) TYPE(C_PTR) :: f_ptr ! Pointer INTEGER(hid_t) :: fapl ! File access property INTEGER :: error ! Error flag + CHARACTER(LEN=18), PARAMETER :: filename="tget_file_image.h5" ! Create new properties for file access CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl, error) @@ -1330,7 +1361,7 @@ SUBROUTINE test_get_file_image(total_error) CALL check("h5pset_fapl_stdio_f", error, total_error) ! Create the file - CALL h5fcreate_f("tget_file_image.h5", H5F_ACC_TRUNC_F, file_id, error, H5P_DEFAULT_F, fapl) + CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, error, H5P_DEFAULT_F, fapl) CALL check("h5fcreate_f", error, total_error) ! Set up data space for new data set @@ -1357,7 +1388,7 @@ SUBROUTINE test_get_file_image(total_error) CALL check("h5fflush_f",error, total_error) ! Open the test file using standard I/O calls - OPEN(UNIT=10,FILE='tget_file_image.h5', ACCESS='STREAM') + OPEN(UNIT=10,FILE=filename, ACCESS='STREAM') ! Get the size of the test file ! ! Since we use the eoa to calculate the image size, the file size @@ -1406,7 +1437,7 @@ SUBROUTINE test_get_file_image(total_error) ALLOCATE(file_image_ptr(1:image_size)) ! Open the test file using standard I/O calls - OPEN(UNIT=10,FILE='tget_file_image.h5', FORM='UNFORMATTED', ACCESS='STREAM') + OPEN(UNIT=10,FILE=filename, FORM='UNFORMATTED', ACCESS='STREAM') ! Read the test file from disk into the buffer DO i = 1, image_size diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index dda38522fb8..1a40da7ee46 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -388,6 +388,9 @@ New Features Fortran Library: ---------------- + - Added Fortran APIs: + h5fdelete_f + - Added Fortran APIs: h5vlnative_addr_to_token_f and h5vlnative_token_to_address_f