#!/usr/bin/perl # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # $Source: src/usr/hwpf/fapi/fapiParseErrorInfo.pl $ # # IBM CONFIDENTIAL # # COPYRIGHT International Business Machines Corp. 2011 # # p1 # # Object Code Only (OCO) source materials # Licensed Internal Code Source Materials # IBM HostBoot Licensed Internal Code # # The source code for this program is not published or other- # wise divested of its trade secrets, irrespective of what has # been deposited with the U.S. Copyright Office. # # Origin: 30 # # IBM_PROLOG_END # # Purpose: This perl script will parse HWP Error XML files and create required # FAPI code. The FAPI files created are: # # 1/ fapiHwpReturnCodes.H - HwpReturnCode enumeration # 2/ fapiHwpErrorInfo.H - Error Information macros # # Author: CamVan Nguyen and Mike Jones # # Change Log ********************************************************** # # Flag Track# Userid Date Description # ---- -------- -------- -------- ----------- # camvanng 06/03/11 Created # mjjones 06/06/11 Minor updates for integration # mjjones 06/10/11 Added "use strict;" # mjjones 07/05/11 Take output dir as parameter # mjjones 08/08/11 Large update to create more code # mjjones 08/24/11 Parse GARD info # mjjones 09/22/11 New Error Info Design # camvanng 10/20/11 Fix bug # # End Change Log ****************************************************** # # Usage: # fapiParseErrorInfo.pl ... use strict; #------------------------------------------------------------------------------ # Subroutine that checks if an entry exists in an array. If it doesn't exist # then it is added. The index of the entry within the array is returned #------------------------------------------------------------------------------ sub addEntryToArray { my ($arrayref, $entry ) = @_; my $match = 0; my $index = 0; foreach my $element (@$arrayref) { if ($element eq $entry) { $match = 1; last; } else { $index++; } } if (!($match)) { push(@$arrayref, $entry); } return $index; } #------------------------------------------------------------------------------ # Print Command Line Help #------------------------------------------------------------------------------ my $numArgs = $#ARGV + 1; if ($numArgs < 2) { print ("Usage: fapiParseErrorInfo.pl ...\n"); print (" This perl script will parse HWP Error XML files and create\n"); print (" required FAPI code\n"); exit(1); } #------------------------------------------------------------------------------ # Specify perl modules to use #------------------------------------------------------------------------------ use XML::Simple; my $xml = new XML::Simple (KeyAttr=>[]); # Uncomment to enable debug output #use Data::Dumper; #------------------------------------------------------------------------------ # Open output files for writing #------------------------------------------------------------------------------ my $rcFile = $ARGV[0]; $rcFile .= "/"; $rcFile .= "fapiHwpReturnCodes.H"; open(RCFILE, ">", $rcFile); my $eiFile = $ARGV[0]; $eiFile .= "/"; $eiFile .= "fapiHwpErrorInfo.H"; open(EIFILE, ">", $eiFile); #------------------------------------------------------------------------------ # Print start of file information to fapiHwpReturnCodes.H #------------------------------------------------------------------------------ print RCFILE "// fapiHwpReturnCodes.H\n"; print RCFILE "// This file is generated by perl script fapiParseErrorInfo.pl\n\n"; print RCFILE "#ifndef FAPIHWPRETURNCODES_H_\n"; print RCFILE "#define FAPIHWPRETURNCODES_H_\n\n"; print RCFILE "namespace fapi\n"; print RCFILE "{\n\n"; print RCFILE "/**\n"; print RCFILE " * \@brief Enumeration of HWP return codes\n"; print RCFILE " *\/\n"; print RCFILE "enum HwpReturnCode\n"; print RCFILE "{\n"; print RCFILE " RC_SUCCESS,\n"; #------------------------------------------------------------------------------ # Print start of file information to fapiHwpErrorInfo.H #------------------------------------------------------------------------------ print EIFILE "// fapiHwpErrorInfo.H\n"; print EIFILE "// This file is generated by perl script fapiParseErrorInfo.pl\n\n"; print EIFILE "#ifndef FAPIHWPERRORINFO_H_\n"; print EIFILE "#define FAPIHWPERRORINFO_H_\n\n"; print EIFILE "/**\n"; print EIFILE " * \@brief Error Information macros\n"; print EIFILE " *\/\n"; #------------------------------------------------------------------------------ # Element names #------------------------------------------------------------------------------ my $collectFfdc = 'collectFfdc'; my $ffdc = 'ffdc'; my $callout = 'callout'; my $deconfigure = 'deconfigure'; my $gard = 'gard'; #------------------------------------------------------------------------------ # For each XML file #------------------------------------------------------------------------------ foreach my $argnum (1 .. $#ARGV) { my $infile = $ARGV[$argnum]; my $count = 0; #-------------------------------------------------------------------------- # Read XML file. Note that there may be multiple collectFfdc/ffdc/callout/ # deconfigure/gard elements so use the ForceArray option with these to # ensure that XML::Simple creates an array even for single elements of # these types #-------------------------------------------------------------------------- # read XML file my $errors = $xml->XMLin($infile, ForceArray => [$collectFfdc, $ffdc, $callout, $deconfigure, $gard]); # Uncomment to get debug output of all errors #print "\nFile: ", $infile, "\n", Dumper($errors), "\n"; #-------------------------------------------------------------------------- # For each Error #-------------------------------------------------------------------------- foreach my $err (@{$errors->{hwpError}}) { #---------------------------------------------------------------------- # Check that expected fields are present #---------------------------------------------------------------------- if (! exists $err->{rc}) { print ("fapiParseErrorInfo.pl ERROR. rc missing\n"); exit(1); } if (! exists $err->{description}) { print ("fapiParseErrorInfo.pl ERROR. description missing\n"); exit(1); } #---------------------------------------------------------------------- # Print the return code to fapiHwpReturnCodes.H #---------------------------------------------------------------------- print RCFILE " $err->{rc},\n"; #---------------------------------------------------------------------- # Print the CALL_FUNC_TO_ANALYZE_ERROR macro to fapiHwpErrorInfo.H #---------------------------------------------------------------------- print EIFILE "#define $err->{rc}_CALL_FUNC_TO_ANALYZE_ERROR(RC) "; if (exists $err->{callFunc}) { print EIFILE "FAPI_EXEC_HWP(RC, $err->{callFunc})\n"; } else { print EIFILE "\n"; } #---------------------------------------------------------------------- # Print the CALL_FUNCS_TO_COLLECT_FFDC macro to fapiHwpErrorInfo.H #---------------------------------------------------------------------- print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_FFDC(RC) "; $count = 0; foreach my $collectFfdc (@{$err->{collectFfdc}}) { if ($count == 0) { print EIFILE "{ fapi::ReturnCode l_tempRc; "; } $count++; print EIFILE "FAPI_EXEC_HWP(l_tempRc, $collectFfdc, RC); "; } if ($count > 0) { print EIFILE "}"; } print EIFILE "\n"; #---------------------------------------------------------------------- # Print the ADD_ERROR_INFO macro to fapiHwpErrorInfo.H #---------------------------------------------------------------------- print EIFILE "#define $err->{rc}_ADD_ERROR_INFO(RC) "; # Array of EI Objects my @eiObjects; my $eiObjectStr = "const void * l_objects[] = {"; my $eiEntryStr = "fapi::ReturnCode::ErrorInfoEntry l_entries[] = {"; my $eiEntryCount = 0; # Local FFDC foreach my $ffdc (@{$err->{ffdc}}) { # Add the FFDC data to the EI Object array if it doesn't already exist my $objNum = addEntryToArray(\@eiObjects, $ffdc); # Add an EI entry to eiEntryStr. if ($eiEntryCount > 0) { $eiEntryStr .= ", "; } $eiEntryStr .= "{fapi::ReturnCode::EI_TYPE_FFDC, $objNum, fapi::ReturnCodeFfdc::getErrorInfoFfdcSize($ffdc)}"; $eiEntryCount++; } # Target callouts foreach my $callout (@{$err->{callout}}) { if (! exists $callout->{target}) { print ("fapiParseErrorInfo.pl ERROR. Callout target missing\n"); exit(1); } if (! exists $callout->{priority}) { print ("fapiParseErrorInfo.pl ERROR. Callout priority missing\n"); exit(1); } # Check the type print EIFILE "fapi::fapiCheckType(&$callout->{target}); "; # Add the Target to the objectlist if it doesn't already exist my $objNum = addEntryToArray(\@eiObjects, $callout->{target}); # Add an EI entry to eiEntryStr if ($eiEntryCount > 0) { $eiEntryStr .= ", "; } $eiEntryStr .= "{fapi::ReturnCode::EI_TYPE_CALLOUT, $objNum, fapi::PRI_$callout->{priority}}"; $eiEntryCount++; } # Target deconfigures foreach my $deconfigure (@{$err->{deconfigure}}) { if (! exists $deconfigure->{target}) { print ("fapiParseErrorInfo.pl ERROR. Deconfigure target missing\n"); exit(1); } # Check the type print EIFILE "fapi::fapiCheckType(&$deconfigure->{target}); "; # Add the Target to the objectlist if it doesn't already exist my $objNum = addEntryToArray(\@eiObjects, $deconfigure->{target}); # Add an EI entry to eiEntryStr if ($eiEntryCount > 0) { $eiEntryStr .= ", "; } $eiEntryStr .= "{fapi::ReturnCode::EI_TYPE_DECONF, $objNum}"; $eiEntryCount++; } # Target Gards foreach my $gard (@{$err->{gard}}) { if (! exists $gard->{target}) { print ("fapiParseErrorInfo.pl ERROR. Gard target missing\n"); exit(1); } # Check the type print EIFILE "fapi::fapiCheckType(&$gard->{target}); "; # Add the Target to the objectlist if it doesn't already exist my $objNum = addEntryToArray(\@eiObjects, $gard->{target}); # Add an EI entry to eiEntryStr if ($eiEntryCount > 0) { $eiEntryStr .= ", "; } $eiEntryStr .= "{fapi::ReturnCode::EI_TYPE_GARD, $objNum}"; $eiEntryCount++; } # Complete $eiEntryStr $eiEntryStr .= "};"; # Add all objects to $eiObjectStr my $objCount = 0; foreach my $eiObject (@eiObjects) { if ($objCount > 0) { $eiObjectStr .= ", "; } $eiObjectStr .= "&$eiObject"; $objCount++; } $eiObjectStr .= "};"; # Print info to file if ($eiEntryCount > 0) { print EIFILE "{$eiObjectStr $eiEntryStr "; print EIFILE "RC.addErrorInfo(l_objects, l_entries, $eiEntryCount);}"; } print EIFILE "\n\n"; } } #------------------------------------------------------------------------------ # Print end of file information to fapiHwpReturnCodes.H #------------------------------------------------------------------------------ print RCFILE "};\n\n"; print RCFILE "}\n\n"; print RCFILE "#endif\n"; #------------------------------------------------------------------------------ # Print end of file information to fapiHwpErrorInfo.H #------------------------------------------------------------------------------ print EIFILE "\n\n#endif\n"; #------------------------------------------------------------------------------ # Close output files #------------------------------------------------------------------------------ close(RCFILE); close(EIFILE);