#!/usr/bin/env perl require 5.003; $indent=4; use warnings; # # Copyright by The HDF Group. # All rights reserved. # # This file is part of HDF5. The full HDF5 copyright notice, including # terms governing use, modification, and redistribution, is contained in # the LICENSE file, which can be found at the root of the source code # distribution tree, or in https://www.hdfgroup.org/licenses. # If you do not have access to either file, you may request a copy from # help@hdfgroup.org. # # Create error headers # # Read in the error description text file and create the appropriate headers # needed by the library. # ############################################################################## # Print the copyright into an open file # sub print_copyright ($) { my $fh = shift; print $fh "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"; print $fh " * Copyright by The HDF Group. *\n"; print $fh " * All rights reserved. *\n"; print $fh " * *\n"; print $fh " * This file is part of HDF5. The full HDF5 copyright notice, including *\n"; print $fh " * terms governing use, modification, and redistribution, is contained in *\n"; print $fh " * the LICENSE file, which can be found at the root of the source code *\n"; print $fh " * distribution tree, or in https://www.hdfgroup.org/licenses. *\n"; print $fh " * If you do not have access to either file, you may request a copy from *\n"; print $fh " * help\@hdfgroup.org. *\n"; print $fh " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n"; } ############################################################################## # Print the "do not change this file" warning # sub print_warning ($) { my $fh = shift; print $fh "\n/* Generated automatically by bin/make_err -- do not edit */\n"; print $fh "/* Add new errors to H5err.txt file */\n"; } ############################################################################## # Print start of ifdef's to prevent a file from being re-included # sub print_startprotect ($$) { my ($fh, $file) = @_; # Clip off the ".h" part of the name $file =~ s/(\w*)\.h/$1/; # Print the ifdef info print $fh "\n#ifndef ${file}_H\n"; print $fh "#define ${file}_H\n"; } ############################################################################## # Print end of ifdef's to prevent a file from being re-included # sub print_endprotect ($$) { my ($fh, $file) = @_; # Clip off the ".h" part of the name $file =~ s/(\w*)\.h/$1/; # Print the endif info print $fh "\n#endif /* ${file}_H */\n"; } ############################################################################## # Parse a meaningful line (not a comment or blank line) into the appropriate # data structure # sub parse_line ($) { my $line = shift; # Get the line to parse my $name; # The name of the error message my $desc; # The description of the error message # Parse major error lines #print "line=$line\n"; if($line =~ /^\s*MAJOR,/) { # Get the major error's name & description ($name, $desc) = ($line =~ /^\s*MAJOR,\s*(\w*),\s*(.*)\n/); #print "MAJOR: name=$name, desc=$desc\n"; # Check if the name already exists as a major or minor error message if(exists($major{$name}) || exists($minor{$name})) { die "duplicated name: $name"; } # Store the major errors in a hash table, indexed by the name $major{$name}=$desc; } # Parse minor error lines elsif($line =~ /^\s*MINOR,/) { my $min_section; # Minor errors have a section they belong to also # Get the minor error's section, name & description ($min_section, $name, $desc) = ($line =~ /^\s*MINOR,\s*(\w*),\s*(\w*),\s*(.*)\n/); #print "MINOR: min_section=$min_section, name=$name, desc=$desc\n"; # Check for valid section if(!exists($section{$min_section})) { die "unknown section: $min_section"; } # Check if the name already exists as a major or minor error message if(exists($major{$name}) || exists($minor{$name})) { die "duplicated name: $name"; } # Store the minor errors in a hash table, indexed by the name $minor{$name}=$desc; # Add the minor error to the list for the section push @{$section_list{$min_section}}, $name; } # Parse section lines elsif($line =~ /^\s*SECTION,/) { # Get the section's name & description ($name, $desc) = ($line =~ /^\s*SECTION,\s*(\w*),\s*(.*)\n/); #print "SECTION: name=$name, desc=$desc\n"; # Check if the section has already been defined if(exists($section{$name})) { die "duplicated name: $name"; } # Store the section in a hash table, indexed by the name $section{$name}=$desc; } # Unknown keyword else { die "unknown keyword: $line"; } } ############################################################################## # Create the generated portion of the public header file # sub create_public ($) { my $prefix = shift; # Get the prefix for the generated file my $file = "H5Epubgen.h"; # Name of file to generate my $name; # Name of error message my $desc; # Description of error message my $sect_name; # Section of minor error messages my $sect_desc; # Description of section # Rename previous file # rename "${prefix}${file}", "${prefix}${file}~" or die "unable to make backup"; # Open new header file open HEADER, ">${prefix}${file}" or die "unable to modify source"; # Create file contents print_copyright(*HEADER); print_warning(*HEADER); print_startprotect(*HEADER, $file); # Begin extern C block print HEADER "\n"; print HEADER "#ifdef __cplusplus\n"; print HEADER "extern \"C\" {\n"; print HEADER "#endif\n"; # Iterate over all the major errors print HEADER "\n/*********************/\n"; print HEADER "/* Major error codes */\n"; print HEADER "/*********************/\n\n"; foreach $name (sort keys %major) { printf HEADER "#define %-20s (H5OPEN %s_g)\n",$name,$name; } foreach $name (sort keys %major) { printf HEADER "H5_DLLVAR hid_t %-20s /* %s */\n","${name}_g;",$major{$name}; } # Iterate over all the minor error sections print HEADER "\n/*********************/\n"; print HEADER "/* Minor error codes */\n"; print HEADER "/*********************/\n"; foreach $sect_name (sort keys %section) { print HEADER "\n/* $section{$sect_name} */\n"; # Iterate over all the minor errors in each section for $name (sort @{$section_list{$sect_name}}) { printf HEADER "#define %-20s (H5OPEN %s_g)\n",$name,$name; } for $name (sort @{$section_list{$sect_name}}) { printf HEADER "H5_DLLVAR hid_t %-20s /* %s */\n","${name}_g;",$minor{$name}; } } # End extern C block print HEADER "\n"; print HEADER "#ifdef __cplusplus\n"; print HEADER "}\n"; print HEADER "#endif\n"; print_endprotect(*HEADER, $file); # Close header file close HEADER; } ############################################################################## # Create the generated portion of the H5E major message definition code # sub create_majdef ($) { my $prefix = shift; # Get the prefix for the generated file my $file = "H5Emajdef.h"; # Name of file to generate my $name; # Name of error message # Rename previous file # rename "${prefix}${file}", "${prefix}${file}~" or die "unable to make backup"; # Open new header file open HEADER, ">${prefix}${file}" or die "unable to modify source"; # Create file contents print_copyright(*HEADER); print_warning(*HEADER); print_startprotect(*HEADER, $file); # Iterate over all the major errors print HEADER "\n/***********************************/\n"; print HEADER "/* Major error message definitions */\n"; print HEADER "/***********************************/\n\n"; print HEADER "/* clang-format off */\n"; foreach $name (sort keys %major) { printf HEADER "static const H5E_msg_t ${name}_msg_s = {false, \"${major{$name}}\", H5E_MAJOR, &H5E_err_cls_s};\n"; } print HEADER "/* clang-format on */\n"; print_endprotect(*HEADER, $file); # Close header file close HEADER; } ############################################################################## # Create the generated portion of the H5E minor message definition code # sub create_mindef ($) { my $prefix = shift; # Get the prefix for the generated file my $file = "H5Emindef.h"; # Name of file to generate my $name; # Name of error message my $sect_name; # Section of minor error messages # Rename previous file # rename "${prefix}${file}", "${prefix}${file}~" or die "unable to make backup"; # Open new header file open HEADER, ">${prefix}${file}" or die "unable to modify source"; # Create file contents print_copyright(*HEADER); print_warning(*HEADER); print_startprotect(*HEADER, $file); # Iterate over all the minor error sections print HEADER "\n/***********************************/\n"; print HEADER "/* Minor error message definitions */\n"; print HEADER "/***********************************/\n\n"; print HEADER "/* clang-format off */\n"; foreach $sect_name (sort keys %section) { print HEADER "\n/* $sect_name: $section{$sect_name} */\n"; # Iterate over all the minor errors in each section for $name (sort @{$section_list{$sect_name}}) { printf HEADER "static const H5E_msg_t ${name}_msg_s = {false, \"${minor{$name}}\", H5E_MINOR, &H5E_err_cls_s};\n"; } } print HEADER "/* clang-format on */\n"; print_endprotect(*HEADER, $file); # Close header file close HEADER; } ############################################################################## # Create the generated portion of the H5E initialization code # sub create_init ($) { my $prefix = shift; # Get the prefix for the generated file my $file = "H5Einit.h"; # Name of file to generate my $name; # Name of error message my $last_name; # Name of previous error message my $desc; # Description of error message my $sect_name; # Section of minor error messages my $sect_desc; # Description of section my $first_major = 0; # Whether the first major error code was saved my $first_minor = 0; # Whether the first minor error code was saved # Rename previous file # rename "${prefix}${file}", "${prefix}${file}~" or die "unable to make backup"; # Open new header file open HEADER, ">${prefix}${file}" or die "unable to modify source"; # Create file contents print_copyright(*HEADER); print_warning(*HEADER); print_startprotect(*HEADER, $file); # Iterate over all the major errors print HEADER "\n/*********************/\n"; print HEADER "/* Major error codes */\n"; print HEADER "/*********************/\n\n"; foreach $name (sort keys %major) { print HEADER "/* $name */\n"; print HEADER " "x(0*$indent),"assert(H5I_INVALID_HID == ${name}_g);\n"; print HEADER " "x(0*$indent),"if((${name}_g = H5I_register(H5I_ERROR_MSG, &${name}_msg_s, false)) < 0)\n"; print HEADER " "x(1*$indent),"HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, \"can't register error message\");\n"; if ($first_major == 0) { print HEADER " "x(0*$indent),"\n/* Remember first major error code ID */\n"; print HEADER " "x(0*$indent),"assert(H5E_first_maj_id_g==H5I_INVALID_HID);\n"; print HEADER " "x(0*$indent),"H5E_first_maj_id_g = ${name}_g;\n\n"; $first_major = 1; } $last_name = $name; } print HEADER " "x(0*$indent),"\n/* Remember last major error code ID */\n"; print HEADER " "x(0*$indent),"assert(H5E_last_maj_id_g==H5I_INVALID_HID);\n"; print HEADER " "x(0*$indent),"H5E_last_maj_id_g = ${last_name}_g;\n\n"; # Iterate over all the minor error sections print HEADER "\n/*********************/\n"; print HEADER "/* Minor error codes */\n"; print HEADER "/*********************/\n\n"; foreach $sect_name (sort keys %section) { print HEADER "\n/* $section{$sect_name} */\n"; # Iterate over all the minor errors in each section for $name (sort @{$section_list{$sect_name}}) { print HEADER "/* $name */\n"; print HEADER " "x(0*$indent),"assert(H5I_INVALID_HID == ${name}_g);\n"; print HEADER " "x(0*$indent),"if((${name}_g = H5I_register(H5I_ERROR_MSG, &${name}_msg_s, false)) < 0)\n"; print HEADER " "x(1*$indent),"HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, \"can't register error message\");\n"; if ($first_minor == 0) { print HEADER " "x(0*$indent),"\n/* Remember first minor error code ID */\n"; print HEADER " "x(0*$indent),"assert(H5E_first_min_id_g==H5I_INVALID_HID);\n"; print HEADER " "x(0*$indent),"H5E_first_min_id_g = ${name}_g;\n\n"; $first_minor = 1; } $last_name = $name; } } print HEADER " "x(0*$indent),"\n/* Remember last minor error code ID */\n"; print HEADER " "x(0*$indent),"assert(H5E_last_min_id_g==H5I_INVALID_HID);\n"; print HEADER " "x(0*$indent),"H5E_last_min_id_g = ${last_name}_g;\n"; print_endprotect(*HEADER, $file); # Close header file close HEADER; } ############################################################################## # Create the generated portion of the H5E termination code # sub create_term ($) { my $prefix = shift; # Get the prefix for the generated file my $file = "H5Eterm.h"; # Name of file to generate my $name; # Name of error message my $desc; # Description of error message my $sect_name; # Section of minor error messages my $sect_desc; # Description of section # Rename previous file # rename "${prefix}${file}", "${prefix}${file}~" or die "unable to make backup"; # Open new header file open HEADER, ">${prefix}${file}" or die "unable to modify source"; # Create file contents print_copyright(*HEADER); print_warning(*HEADER); print_startprotect(*HEADER, $file); # Iterate over all the major errors print HEADER "\n/* Reset major error IDs */\n"; foreach $name (sort keys %major) { print HEADER " "x($indent),"${name}_g =\n"; } print HEADER " "x(2*$indent),"H5I_INVALID_HID;\n"; print HEADER "\n"," "x(0*$indent),"H5E_first_maj_id_g = H5I_INVALID_HID;\n"; print HEADER " "x(0*$indent),"H5E_last_maj_id_g = H5I_INVALID_HID;\n\n"; # Iterate over all the minor error sections print HEADER "\n/* Reset minor error IDs */\n"; foreach $sect_name (sort keys %section) { print HEADER "\n/* $sect_name: $section{$sect_name} */\n"; # Iterate over all the minor errors in each section for $name (sort @{$section_list{$sect_name}}) { print HEADER " "x($indent),"${name}_g =\n"; } } print HEADER " "x(2*$indent),"H5I_INVALID_HID;\n"; print HEADER "\n"," "x(0*$indent),"H5E_first_min_id_g = H5I_INVALID_HID;\n"; print HEADER " "x(0*$indent),"H5E_last_min_id_g = H5I_INVALID_HID;\n\n"; print_endprotect(*HEADER, $file); # Close header file close HEADER; } ############################################################################## # Create the generated portion of the error code definitions # sub create_define ($) { my $prefix = shift; # Get the prefix for the generated file my $file = "H5Edefin.h"; # Name of file to generate my $name; # Name of error message my $desc; # Description of error message my $sect_name; # Section of minor error messages my $sect_desc; # Description of section my $num_msg; # Number of messages # Rename previous file # rename "${prefix}${file}", "${prefix}${file}~" or die "unable to make backup"; # Open new header file open HEADER, ">${prefix}${file}" or die "unable to modify source"; # Create file contents print_copyright(*HEADER); print_warning(*HEADER); print_startprotect(*HEADER, $file); # Iterate over all the major errors $num_msg = 0; print HEADER "\n/* Major error IDs */\n"; foreach $name (sort keys %major) { printf HEADER "hid_t %-20s = H5I_INVALID_HID; /* %s */\n","${name}_g",$major{$name}; $num_msg++; } print HEADER "\n/* Number of major error messages */\n"; printf HEADER "#define H5E_NUM_MAJ_ERRORS %d\n", $num_msg; # Iterate over all the minor error sections $num_msg = 0; print HEADER "\n/* Minor error IDs */\n"; foreach $sect_name (sort keys %section) { print HEADER "\n/* $sect_name: $section{$sect_name} */\n"; # Iterate over all the minor errors in each section for $name (sort @{$section_list{$sect_name}}) { printf HEADER "hid_t %-20s = H5I_INVALID_HID; /* %s */\n","${name}_g",$minor{$name}; $num_msg++; } } print HEADER "\n/* Number of minor error messages */\n"; printf HEADER "#define H5E_NUM_MIN_ERRORS %d\n", $num_msg; print_endprotect(*HEADER, $file); # Close header file close HEADER; } ############################################################################## # Read error file (given as command-line argument) in and process it into # internal data structures, then create error header files. # for $file (@ARGV) { my $prefix; # Local prefix for generated files ($prefix) = ($file =~ /(^.*\/)/); # Read in the entire file open SOURCE, $file or die "$file: $!\n"; while ( defined ($line=) ) { if(!($line =~ /(^\s*#.*$)|(^\s*$)/)) { # Construct data structures for later printing parse_line($line); } } close SOURCE; # Create header files print "Generating 'H5Epubgen.h'\n"; create_public($prefix); print "Generating 'H5Emajdef.h'\n"; create_majdef($prefix); print "Generating 'H5Emindef.h'\n"; create_mindef($prefix); print "Generating 'H5Einit.h'\n"; create_init($prefix); print "Generating 'H5Eterm.h'\n"; create_term($prefix); print "Generating 'H5Edefin.h'\n"; create_define($prefix); }