diff options
author | Andrey Ponomarenko <andrewponomarenko@yandex.ru> | 2016-09-07 19:09:50 +0300 |
---|---|---|
committer | Andrey Ponomarenko <andrewponomarenko@yandex.ru> | 2016-09-07 19:09:50 +0300 |
commit | 991da688af27e8e62a8ebbabf238bdb6b0e1582b (patch) | |
tree | 0b9f33ace7d04b26fdbfeee7ffa611e8f30de8ae | |
parent | 19b61de40594e427b6dda2c63243ad6a7aee2d25 (diff) | |
download | abi-compliance-checker-991da688af27e8e62a8ebbabf238bdb6b0e1582b.tar.gz |
Improved a module to compare operating systems. Added -mingw-compatible and -skip-unidentified options. Improved support for C++ keywords in C code. The -cpp-compatible option is now enabled by default. Improved support for Windows. Improved support for MinGW.
-rw-r--r-- | abi-compliance-checker.pl | 155 | ||||
-rw-r--r-- | modules/Internals/RegTests.pm | 2 | ||||
-rw-r--r-- | modules/Internals/Styles/CmpSystems.css | 71 | ||||
-rw-r--r-- | modules/Internals/Styles/HeadersDiff.css | 49 | ||||
-rw-r--r-- | modules/Internals/Styles/SymbolsList.css | 6 | ||||
-rw-r--r-- | modules/Internals/SysCheck.pm | 526 |
6 files changed, 411 insertions, 398 deletions
diff --git a/abi-compliance-checker.pl b/abi-compliance-checker.pl index 14b83a7..0dece16 100644 --- a/abi-compliance-checker.pl +++ b/abi-compliance-checker.pl @@ -85,14 +85,14 @@ $AppPath, $StrictCompat, $DumpVersion, $ParamNamesPath, $OutputReportPath, $OutputDumpPath, $ShowRetVal, $SystemRoot_Opt, $DumpSystem, $CmpSystems, $TargetLibsPath, $Debug, $CrossPrefix, $UseStaticLibs, $NoStdInc, $TargetComponent_Opt, $TargetSysInfo, $TargetHeader, $ExtendedCheck, $Quiet, -$SkipHeadersPath, $CppCompat, $LogMode, $StdOut, $ListAffected, $ReportFormat, +$SkipHeadersPath, $CxxCompat, $LogMode, $StdOut, $ListAffected, $ReportFormat, $UserLang, $TargetHeadersPath, $BinaryOnly, $SourceOnly, $BinaryReportPath, $SourceReportPath, $UseXML, $SortDump, $DumpFormat, $ExtraInfo, $ExtraDump, $Force, $Tolerance, $Tolerant, $SkipSymbolsListPath, -$CheckInfo, $Quick, $AffectLimit, $AllAffected, $CppIncompat, +$CheckInfo, $Quick, $AffectLimit, $AllAffected, $CxxIncompat, $SkipInternalSymbols, $SkipInternalTypes, $TargetArch, $GccOptions, $TypesListPath, $SkipTypesListPath, $CheckPrivateABI, $CountSymbols, $OldStyle, -$DisableQuickEmptyReport, $SkipTypedefUncover); +$DisableQuickEmptyReport, $SkipTypedefUncover, $MinGWCompat, $SkipUnidentified); my $CmdName = get_filename($0); my %OS_LibExt = ( @@ -228,8 +228,9 @@ GetOptions("h|help!" => \$Help, "test!" => \$TestTool, "test-dump!" => \$TestDump, "debug!" => \$Debug, - "cpp-compatible!" => \$CppCompat, - "cpp-incompatible!" => \$CppIncompat, + "cpp-compatible!" => \$CxxCompat, + "cxx-incompatible|cpp-incompatible!" => \$CxxIncompat, + "mingw-compatible!" => \$MinGWCompat, "p|params=s" => \$ParamNamesPath, "relpath1|relpath=s" => \$RelativeDirectory{1}, "relpath2=s" => \$RelativeDirectory{2}, @@ -250,6 +251,7 @@ GetOptions("h|help!" => \$Help, "force!" => \$Force, "tolerance=s" => \$Tolerance, "tolerant!" => \$Tolerant, + "skip-unidentified!" => \$SkipUnidentified, "check!" => \$CheckInfo, "quick!" => \$Quick, "disable-quick-empty-report!" => \$DisableQuickEmptyReport, @@ -550,9 +552,11 @@ EXTRA OPTIONS: ABI of operating systems and configure the dumping process. -cmp-systems -d1 sys_dumps/NAME1/ARCH -d2 sys_dumps/NAME2/ARCH - Compare two system ABI dumps. Create compatibility reports for each - library and the common HTML report including the summary of test - results for all checked libraries. Report will be generated to: + Compare two ABI dumps of a system. Create compatibility reports for + each system library and the common HTML report including the summary + of test results for all checked libraries. + + Summary report will be generated to: sys_compat_reports/NAME1_to_NAME2/ARCH -libs-list PATH @@ -631,7 +635,7 @@ OTHER OPTIONS: -test-dump Test ability to create, read and compare ABI dumps. - + -debug Debugging mode. Print debug info on the screen. Save intermediate analysis stages in the debug directory: @@ -640,12 +644,16 @@ OTHER OPTIONS: Also consider using --dump option for debugging the tool. -cpp-compatible - If your header files are written in C language and can be compiled - by the G++ compiler (i.e. don't use C++ keywords), then you can tell - the tool about this and speedup the analysis. - - -cpp-incompatible - Set this option if input C header files use C++ keywords. + Do nothing. + + -cxx-incompatible + Set this option if input C header files use C++ keywords. The tool + will try to replace such keywords at preprocessor stage and replace + them back in the final TU dump. + + -mingw-compatible + If input header files are compatible with the MinGW GCC compiler, + then you can tell the tool about this and speedup the analysis . -p|-params PATH Path to file with the function parameter names. It can be used @@ -659,7 +667,7 @@ OTHER OPTIONS: -relpath PATH Replace {RELPATH} macros to PATH in the XML-descriptor used for dumping the library ABI (see -dump option). - + -relpath1 PATH Replace {RELPATH} macros to PATH in the 1st XML-descriptor (-d1). @@ -737,7 +745,8 @@ OTHER OPTIONS: from the translation unit. -force - Try to use this option if the tool doesn't work. + Try to enable this option if the tool checked zero + types and symbols in header files. -tolerance LEVEL Apply a set of heuristics to successfully compile input @@ -751,7 +760,12 @@ OTHER OPTIONS: -tolerant Enable highest tolerance level [1234]. - + + -skip-unidentified + Skip header files in 'headers' and 'include_preamble' sections + of the XML descriptor that cannot be found. This is useful if + you are trying to use the same descriptor for different targets. + -check Check completeness of the ABI dump. @@ -1372,6 +1386,7 @@ my %WeakSymbols; my %Library_Needed= ( "1"=>{}, "2"=>{} ); +my $DisabledMSVCUnmangling = undef; # Extra Info my %UndefinedSymbols; @@ -6492,7 +6507,7 @@ sub searchForHeaders($) $Registered_Headers{$LibVersion}{$Path}{"Pos"} = $Position++; } } - else { + elsif(not defined $SkipUnidentified) { exitStatus("Access_Error", "can't identify \'$Dest\' as a header file"); } } @@ -6520,7 +6535,7 @@ sub searchForHeaders($) next if(skipHeader($Header_Path, $LibVersion)); push_U($Include_Preamble{$LibVersion}, $Header_Path); } - else { + elsif($SkipUnidentified) { exitStatus("Access_Error", "can't identify \'$Header\' as a header file"); } } @@ -7343,9 +7358,21 @@ sub unmangleArray(@) { if($_[0]=~/\A\?/) { # MSVC mangling + if(defined $DisabledMSVCUnmangling) { + return @_; + } my $UndNameCmd = get_CmdPath("undname"); - if(not $UndNameCmd) { - exitStatus("Not_Found", "can't find \"undname\""); + if(not $UndNameCmd) + { + if($OSgroup eq "windows") { + exitStatus("Not_Found", "can't find \"undname\""); + } + elsif(not defined $DisabledMSVCUnmangling) + { + printMsg("WARNING", "can't find \"undname\", disable MSVC unmangling"); + $DisabledMSVCUnmangling = 1; + return @_; + } } writeFile("$TMP_DIR/unmangle", join("\n", @_)); return split(/\n/, `$UndNameCmd 0x8386 \"$TMP_DIR/unmangle\"`); @@ -7887,6 +7914,7 @@ sub platformSpecs($) "-D__possibly_notnullterminated=\" \"", "-D__nullterminated=\" \"", "-D__nullnullterminated=\" \"", + "-D__assume=\" \"", "-D__w64=\" \"", "-D__ptr32=\" \"", "-D__ptr64=\" \"", @@ -7918,17 +7946,21 @@ sub platformSpecs($) "-DSORTPP_PASS"); if($Arch eq "x86") { + $MinGW_Opts{"-D_X86_=300"}=1; $MinGW_Opts{"-D_M_IX86=300"}=1; } elsif($Arch eq "x86_64") { + $MinGW_Opts{"-D_AMD64_=300"}=1; $MinGW_Opts{"-D_M_AMD64=300"}=1; $MinGW_Opts{"-D_M_X64=300"}=1; } - elsif($Arch eq "ia64") { + elsif($Arch eq "ia64") + { + $MinGW_Opts{"-D_IA64_=300"}=1; $MinGW_Opts{"-D_M_IA64=300"}=1; } - return join(" ", keys(%MinGW_Opts)); + return join(" ", sort keys(%MinGW_Opts)); } return ""; } @@ -8189,7 +8221,7 @@ sub preChange($$) my $PreprocessCmd = getCompileCmd($HeaderPath, "-E", $IncStr); my $Content = undef; - if($OStarget eq "windows" + if(not defined $MinGWCompat and $OStarget eq "windows" and get_dumpmachine($GCC_PATH)=~/mingw/i and $MinGWMode{$Version}!=-1) { # modify headers to compile by MinGW @@ -8215,29 +8247,48 @@ sub preChange($$) } } - if(($COMMON_LANGUAGE{$Version} eq "C" or $CheckHeadersOnly) - and $CppMode{$Version}!=-1 and not $CppCompat and not $CPP_HEADERS) + if(defined $CxxIncompat and ($COMMON_LANGUAGE{$Version} eq "C" or $CheckHeadersOnly) + and $CppMode{$Version}!=-1 and not $CPP_HEADERS) { # rename C++ keywords in C code - # disable this code by -cpp-compatible option + printMsg("INFO", "Checking the code for C++ keywords"); if(not $Content) { # preprocessing $Content = `$PreprocessCmd 2>\"$TMP_DIR/null\"`; } + my $RegExp_C = join("|", keys(%CppKeywords_C)); my $RegExp_F = join("|", keys(%CppKeywords_F)); my $RegExp_O = join("|", keys(%CppKeywords_O)); my $Detected = undef; + my $Sentence_O = undef; + my $Sentence_N = undef; + my $Regex = undef; - while($Content=~s/(\A|\n[^\#\/\n][^\n]*?|\n)(\*\s*|\s+|\@|\,|\()($RegExp_C|$RegExp_F)(\s*([\,\)\;\.\[]|\-\>|\:\s*\d))/$1$2c99_$3$4/g) + $Regex = qr/(\A|\n[^\#\/\n][^\n]*?|\n)(\*\s*|\s+|\@|\,|\()($RegExp_C|$RegExp_F)(\s*([\,\)\;\.\[]|\-\>|\:\s*\d))/; + while($Content=~/$Regex/) { # MATCH: # int foo(int new, int class, int (*new)(int)); # int foo(char template[], char*); # unsigned private: 8; # DO NOT MATCH: # #pragma GCC visibility push(default) - $CppMode{$Version} = 1; - $Detected = "$1$2$3$4" if(not defined $Detected); + $Sentence_O = "$1$2$3$4"; + $Sentence_N = "$1$2c99_$3$4"; + + if($Sentence_O=~/\s+decltype\(/) + { # C++ + # decltype(nullptr) + last; + } + else + { + $Content=~s/$Regex/$Sentence_N/g; + $CppMode{$Version} = 1; + if(not defined $Detected) { + $Detected = $Sentence_O; + } + } } if($Content=~s/([^\w\s]|\w\s+)(?<!operator )(delete)(\s*\()/$1c99_$2$3/g) { # MATCH: @@ -8331,6 +8382,9 @@ sub preChange($$) if($CppMode{$Version}==1) { printMsg("INFO", "Using C++ compatibility mode"); } + else { + printMsg("INFO", "C++ keywords in the C code are not found"); + } } if($CppMode{$Version}==1 @@ -8546,24 +8600,8 @@ sub getDump() { # failed to compile, but the TU dump still can be created if($Errors = readFile($TMP_DIR."/tu_errors")) { # try to recompile - # FIXME: handle other errors and try to recompile - if($CppMode{$Version}==1 - and index($Errors, "c99_")!=-1 - and not defined $CppIncompat) - { # disable c99 mode and try again - $CppMode{$Version}=-1; - - if($Debug) - { - # printMsg("INFO", $Errors); - } - - printMsg("INFO", "Disabling C++ compatibility mode"); - resetLogging($Version); - $TMP_DIR = tempdir(CLEANUP=>1); - return getDump(); - } - elsif($AutoPreambleMode{$Version}!=-1 + # FIXME: handle errors and try to recompile + if($AutoPreambleMode{$Version}!=-1 and my $AddHeaders = detectPreamble($Errors, $Version)) { # add auto preamble headers and try again $AutoPreambleMode{$Version}=-1; @@ -8595,17 +8633,17 @@ sub getDump() return getDump(); } else { - printMsg("WARNING", "Probably c++0x construction detected"); + printMsg("WARNING", "Probably c++0x element detected"); } } - elsif($MinGWMode{$Version}==1) - { # disable MinGW mode and try again - $MinGWMode{$Version}=-1; - resetLogging($Version); - $TMP_DIR = tempdir(CLEANUP=>1); - return getDump(); - } + #elsif($MinGWMode{$Version}==1) + #{ # disable MinGW mode and try again + # $MinGWMode{$Version}=-1; + # resetLogging($Version); + # $TMP_DIR = tempdir(CLEANUP=>1); + # return getDump(); + #} writeLog($Version, $Errors); } else { @@ -22825,7 +22863,8 @@ sub getSysOpts() "CrossGcc"=>$CrossGcc, "UseStaticLibs"=>$UseStaticLibs, "NoStdInc"=>$NoStdInc, - "CppCompat"=>$CppCompat, + "CxxIncompat"=>$CxxIncompat, + "SkipUnidentified"=>$SkipUnidentified, "BinaryOnly" => $BinaryOnly, "SourceOnly" => $SourceOnly diff --git a/modules/Internals/RegTests.pm b/modules/Internals/RegTests.pm index 47ee256..ab3fc1c 100644 --- a/modules/Internals/RegTests.pm +++ b/modules/Internals/RegTests.pm @@ -4849,7 +4849,7 @@ sub runTests($$$$$$$$) exitStatus("Error", "can't compile $LibName v.2: \'$Path_v2/build-log.txt\'"); } # running the tool - my @Cmd = ("perl", $0, "-l", $LibName, "-d1", "$LibName/v1.xml", "-d2", "$LibName/v2.xml"); + my @Cmd = ("perl", $0, "-l", $LibName, "-d1", "$LibName/v1.xml", "-d2", "$LibName/v2.xml", "-cxx-incompatible"); if($TestDump) { @Cmd = (@Cmd, "-use-dumps"); diff --git a/modules/Internals/Styles/CmpSystems.css b/modules/Internals/Styles/CmpSystems.css index 07342e8..a499ccc 100644 --- a/modules/Internals/Styles/CmpSystems.css +++ b/modules/Internals/Styles/CmpSystems.css @@ -1,5 +1,5 @@ body { - font-family:Arial, sans-serif; + font-family:Arial; background-color:White; color:Black; } @@ -14,47 +14,40 @@ h1 { padding-bottom:0px; font-size:1.625em; } -h2 { - margin-bottom:0px; - padding-bottom:0px; - font-size:1.25em; - white-space:nowrap; -} -table.summary, table.wikitable { +table.summary, table.legend { + font-family:"DejaVu Sans Mono", "Monaco", monospace; + font-size:0.94em; border-collapse:collapse; - border:1px outset black; + table-layout:fixed; } -table.summary td, table.summary th { - border:1px inset gray; - padding: 3px 5px 3px 5px; - white-space:nowrap; +table.summary tr, table.summary td, table.summary th, table.legend td +{ + border:1px solid #777777; + border-collapse:collapse; + padding:0.2em; + padding-left:7px; + padding-right:7px; + text-align:center; } table.summary th { - background-color:#EEEEEE; - font-weight:100; - text-align:left; - padding: 3px; - font-size:0.94em; + background:#f2f2f2; + white-space:nowrap; } table.summary td { - text-align:right; - padding-left:10px; - padding: 3px 5px 3px 10px; -} -table.wikitable td, table.wikitable th { - border:1px inset gray; - text-align:center; - padding: 3px; + padding-top:20px; + padding-bottom:20px; white-space:nowrap; } -table.wikitable th { - background-color:#EEEEEE; - font-size:0.94em; -} -table.wikitable td.left { +table.summary td.object { text-align:left; - padding-left:5px; - background-color:#F9F9F9; + max-width:10em; + white-space:normal; + word-wrap:break-word; +} +table.summary td.ver { + max-width:10em; + white-space:normal; + word-wrap:break-word; } td.passed { background-color:#CCFFCC; @@ -68,6 +61,15 @@ td.failed { td.new { background-color:#C6DEFF; } +.compatible { + background-color:#CCFFCC; +} +.almost_compatible { + background-color:#FFDAA3; +} +.incompatible { + background-color:#FFCCCC; +} a.default { color:#336699; } @@ -77,3 +79,6 @@ th.severity { sup { font-size:0.625em; } +.footer { + font-size:0.75em; +}
\ No newline at end of file diff --git a/modules/Internals/Styles/HeadersDiff.css b/modules/Internals/Styles/HeadersDiff.css new file mode 100644 index 0000000..a0426cb --- /dev/null +++ b/modules/Internals/Styles/HeadersDiff.css @@ -0,0 +1,49 @@ +body { + font-family:Arial; + background-color:White; + color:Black; +} +hr { + color:Black; + background-color:Black; + height:1px; + border:0; +} +h1 { + margin-bottom:0px; + padding-bottom:0px; + font-size:1.625em; +} + +.diff_tbl tr { } +.diff_tbl td { + white-space: pre; + font-family: "DejaVu Sans Mono", "Droid Sans Mono", Monaco, Monospace; + vertical-align: top; + font-size: 14px; +} + +.diff_tbl th { + font-size: 16px; +} + +.small { font-size: 0.6em; font-style: italic; font-family: Verdana, Helvetica, sans-serif; } +.left { background-color: #EEE; } +.right { background-color: #FFF; } +.diff { background-color: #CCF; } +.lblock { background-color: #BFB; } +.rblock { background-color: #FF8; } +.insert { background-color: #8FF; } +.delete { background-color: #ACF; } +.void { background-color: #FFB; } +.cont { background-color: #EEE; } +.linebr { background-color: #AAA; } +.lineno { color: red; background-color: #FFF; font-size: 0.7em; text-align: right; padding: 0 2px; } +.elipsis{ background-color: #AAA; } +.left .cont { background-color: #DDD; } +.right .cont { background-color: #EEE; } +.lblock .cont { background-color: #9D9; } +.rblock .cont { background-color: #DD6; } +.insert .cont { background-color: #0DD; } +.delete .cont { background-color: #8AD; } +.stats, .stats td, .stats th { background-color: #EEE; padding: 2px 0; } diff --git a/modules/Internals/Styles/SymbolsList.css b/modules/Internals/Styles/SymbolsList.css index d288aa7..eaf12de 100644 --- a/modules/Internals/Styles/SymbolsList.css +++ b/modules/Internals/Styles/SymbolsList.css @@ -71,3 +71,9 @@ span.param { span.nowrap { white-space:nowrap; } +.top_ref { + font-size:0.69em; +} +.footer { + font-size:0.75em; +}
\ No newline at end of file diff --git a/modules/Internals/SysCheck.pm b/modules/Internals/SysCheck.pm index 550c4f4..96065c7 100644 --- a/modules/Internals/SysCheck.pm +++ b/modules/Internals/SysCheck.pm @@ -28,7 +28,7 @@ use Fcntl; my ($Debug, $Quiet, $LogMode, $CheckHeadersOnly, $SystemRoot, $GCC_PATH, $CrossPrefix, $TargetSysInfo, $TargetLibraryName, $CrossGcc, $UseStaticLibs, -$NoStdInc, $CppCompat, $OStarget, $BinaryOnly, $SourceOnly); +$NoStdInc, $CxxIncompat, $SkipUnidentified, $OStarget, $BinaryOnly, $SourceOnly); my $OSgroup = get_OSgroup(); my $TMP_DIR = tempdir(CLEANUP=>1); @@ -403,6 +403,117 @@ sub cmpSystems($$$) $TestResults{$LName}{"v1"} = $LV1; $TestResults{$LName}{"v2"} = $LV2; } + + my $HP1 = $SPath1."/headers/".$LName; + my $HP2 = $SPath2."/headers/".$LName; + + if(-d $HP1 + and -d $HP2 + and my $RfcDiff = get_CmdPath("rfcdiff")) + { + my @Headers1 = cmd_find($HP1,"f"); + my @Headers2 = cmd_find($HP2,"f"); + + my (%Files1, %Files2) = (); + + foreach my $P (@Headers1) { + $Files1{get_filename($P)} = $P; + } + + foreach my $P (@Headers2) { + $Files2{get_filename($P)} = $P; + } + + my $Diff = ""; + foreach my $N (sort {lc($a) cmp lc($b)} keys(%Files1)) + { + my $Path1 = $Files1{$N}; + my $Path2 = undef; + + if(defined $Files2{$N}) { + $Path2 = $Files2{$N}; + } + else { + next; + } + + if(-s $Path1 == -s $Path2) + { + if(readFile($Path1) eq readFile($Path2)) { + next; + } + } + + my $DiffOut = $TMP_DIR."/rfcdiff"; + + if(-e $DiffOut) { + unlink($DiffOut); + } + + my $Cmd_R = $RfcDiff." --width 75 --stdout \"$Path1\" \"$Path2\" >$DiffOut 2>/dev/null"; + qx/$Cmd_R/; # execute + + if(-s $DiffOut) + { + my $Content = readFile($DiffOut); + if(length($Content)<3500 and $Content=~/The files are identical|No changes|Failed to create/i) { + next; + } + + $Content=~s/<\!--(.|\n)+?-->\s*//g; + $Content=~s/\A((.|\n)+<body\s*>)((.|\n)+)(<\/body>(.|\n)+)\Z/$3/; + $Content=~s/(<td colspan=\"5\"[^>]*>)(.+)(<\/td>)/$1$3/; + $Content=~s/(<table) /$1 class='diff_tbl' /g; + + $Content=~s/(\Q$N\E)( )/$1 ($LV1-$SystemName1)$2/; + $Content=~s/(\Q$N\E)( )/$1 ($LV2-$SystemName2)$2/; + + if($Diff) { + $Diff .= "<br/><br/>\n"; + } + $Diff .= $Content; + } + } + + my $Title = $LName.": headers diff between $LV1-$SystemName1 and $LV2-$SystemName2 versions"; + my $Keywords = $LName.", header, diff"; + my $Description = "Diff for header files between $LV1-$SystemName1 and $LV2-$SystemName2 versions of $LName"; + my $Styles = readModule("Styles", "HeadersDiff.css"); + + my $Link = "This html diff was produced by <a href='http://tools.ietf.org/tools/rfcdiff/'>rfcdiff</a> 1.41."; + + $Diff .= "<br/>"; + $Diff .= "<div style='width:100%;' align='left'>$Link</div>\n"; + + $Diff = "<h1>Headers diff for <span style='color:Blue;'>$LName</span> between <span style='color:Red;'>$LV1-$SystemName1</span> and <span style='color:Red;'>$LV2-$SystemName2</span> versions</h1><br/><br/>".$Diff; + + $Diff = "<table width='100%' cellpadding='0' cellspacing='0'><tr><td>$Diff</td></tr></table>"; + + $Diff = composeHTML_Head($Title, $Keywords, $Description, $Styles, "")."\n<body>\n$Diff\n</body>\n</html>\n"; + + my $Output = $SYS_REPORT_PATH."/headers_diff/$LName"; + writeFile($Output."/diff.html", $Diff); + } + } + + my %TOTAL = (); + foreach my $LName (keys(%TestResults)) + { + if($SONAME_Changed{$LName}) { + next; + } + foreach my $Comp ("Binary", "Source") + { + if(not defined $TestResults{$LName}{$Comp}) { + next; + } + foreach my $Kind (keys(%{$TestResults{$LName}{$Comp}})) + { + if($Kind=~/_problems_(high|medium|low)/) { + $TOTAL{$LName}{$Comp} += $TestResults{$LName}{$Comp}{$Kind}; + } + } + } } my %META_DATA = (); @@ -495,204 +606,56 @@ sub cmpSystems($$$) $SYS_REPORT .= " on <span style='color:Blue;'>".showArch($ArchName)."</span>\n"; $SYS_REPORT .= "</h1>"; + $SYS_REPORT .= "<br/>\n"; # legend - my $LEGEND = "<table cellspacing='2' cellpadding='3'><tr>\n"; - $LEGEND .= "<td class='new' width='70px' style='text-align:left'>Added</td>\n"; - $LEGEND .= "<td class='passed' width='70px' style='text-align:left'>Compatible</td>\n"; + my $LEGEND = "<table class='legend'><tr>\n"; + $LEGEND .= "<td class='new' width='70px' style='text-align:left'>ADDED</td>\n"; + $LEGEND .= "<td class='passed' width='70px' style='text-align:left'>COMPATIBLE</td>\n"; $LEGEND .= "</tr><tr>\n"; - $LEGEND .= "<td class='warning' style='text-align:left'>Warning</td>\n"; - $LEGEND .= "<td class='failed' style='text-align:left'>Incompatible</td>\n"; + $LEGEND .= "<td class='warning' style='text-align:left'>WARNING</td>\n"; + $LEGEND .= "<td class='failed' style='text-align:left'>INCOMPATIBLE</td>\n"; $LEGEND .= "</tr></table>\n"; $SYS_REPORT .= $LEGEND; + $SYS_REPORT .= "<br/>\n"; - # test info - my $TEST_INFO = "<h2>Test Info</h2><hr/>\n"; - $TEST_INFO .= "<table class='summary'>\n"; - $TEST_INFO .= "<tr><th>System #1</th><td>$SystemName1</td></tr>\n"; - $TEST_INFO .= "<tr><th>System #2</th><td>$SystemName2</td></tr>\n"; - $TEST_INFO .= "<tr><th>CPU Type</th><td>".showArch($ArchName)."</td></tr>\n"; - $TEST_INFO .= "</table>\n"; - - # $SYS_REPORT .= $TEST_INFO; + my $Columns = 2; my $Total = (keys(%TestResults) + keys(%Added) + keys(%Removed) - keys(%SONAME_Changed)); + my $HDiff = $SYS_REPORT_PATH."/headers_diff"; - # test results - my $TEST_RES = "<h2>Test Results</h2><hr/>\n"; - $TEST_RES .= "<table class='summary'>\n"; - $TEST_RES .= "<tr><th>Total Libraries</th><td><a href='#Report'>$Total</a></td></tr>\n"; - if($BinaryOnly and $SourceOnly) - { - if(my $Affected = $STAT{"Binary"}{"affected"}) { - $TEST_RES .= "<tr><th>Binary Compatibility</th><td class='failed'>".cut_off_number(100 - $Affected, 3, 1)."%</td></tr>\n"; - } - else { - $TEST_RES .= "<tr><th>Binary Compatibility</th><td class='passed'>100%</td></tr>\n"; - } - if(my $Affected = $STAT{"Source"}{"affected"}) { - $TEST_RES .= "<tr><th>Source Compatibility</th><td class='failed'>".cut_off_number(100 - $Affected, 3, 1)."%</td></tr>\n"; - } - else { - $TEST_RES .= "<tr><th>Source Compatibility</th><td class='passed'>100%</td></tr>\n"; - } - } - elsif($BinaryOnly) - { - if(my $Affected = $STAT{"Binary"}{"affected"}) { - $TEST_RES .= "<tr><th>Compatibility</th><td class='failed'>".cut_off_number(100 - $Affected, 3, 1)."%</td></tr>\n"; - } - else { - $TEST_RES .= "<tr><th>Compatibility</th><td class='passed'>100%</td></tr>\n"; - } - } - elsif($SourceOnly) - { - if(my $Affected = $STAT{"Source"}{"affected"}) { - $TEST_RES .= "<tr><th>Compatibility</th><td class='failed'>".cut_off_number(100 - $Affected, 3, 1)."%</td></tr>\n"; - } - else { - $TEST_RES .= "<tr><th>Compatibility</th><td class='passed'>100%</td></tr>\n"; - } - } - $TEST_RES .= "</table>\n"; - - $SYS_REPORT .= $TEST_RES; - - # problem summary - foreach my $Comp ("Binary", "Source") - { - my $PSUMMARY = "<h2>Problem Summary"; - if(not $BinaryOnly or not $SourceOnly) - { - next if($BinaryOnly and $Comp eq "Source"); - next if($SourceOnly and $Comp eq "Binary"); - } - else { - $PSUMMARY .= " ($Comp Compatibility)\n"; - } - $PSUMMARY .= "</h2><hr/>\n"; - - $PSUMMARY .= "<table class='summary'>\n"; - $PSUMMARY .= "<tr><th></th><th style='text-align:center;font-weight:bold;'>Severity</th><th style='text-align:center;font-weight:bold;'>Count</th></tr>\n"; - if(my $Added = $STAT{$Comp}{"added_interfaces"}) { - $PSUMMARY .= "<tr><th>Added Symbols</th><td>-</td><td class='new'>$Added</td></tr>\n"; - } - else { - $PSUMMARY .= "<tr><th>Added Symbols</th><td>-</td><td>0</td></tr>\n"; - } - if(my $Removed = $STAT{$Comp}{"removed_interfaces"}) { - $PSUMMARY .= "<tr><th>Removed Symbols</th><td>High</td><td class='failed'>$Removed</td></tr>\n"; - } - else { - $PSUMMARY .= "<tr><th>Removed Symbols</th><td>High</td><td>0</td></tr>\n"; - } - $PSUMMARY .= "<tr>"; - - if($BinaryOnly and $SourceOnly) { - $PSUMMARY .= "<th rowspan='3'>$Comp Compatibility<br/>Problems</th>"; - } - else { - $PSUMMARY .= "<th rowspan='3'>Compatibility<br/>Problems</th>"; - } - if(my $High = $STAT{$Comp}{"interface_problems_high"}+$STAT{$Comp}{"type_problems_high"}) { - $PSUMMARY .= "<td>High</td><td class='failed'>$High</td>\n"; - } - else { - $PSUMMARY .= "<td>High</td><td>0</td>\n"; - } - $PSUMMARY .= "</tr>"; - $PSUMMARY .= "<tr>"; - if(my $Medium = $STAT{$Comp}{"interface_problems_medium"}+$STAT{$Comp}{"type_problems_medium"}) { - $PSUMMARY .= "<td>Medium</td><td class='failed'>$Medium</td>\n"; - } - else { - $PSUMMARY .= "<td>Medium</td><td>0</td>\n"; - } - $PSUMMARY .= "</tr>"; - $PSUMMARY .= "<tr>"; - if(my $Low = $STAT{$Comp}{"interface_problems_low"}+$STAT{$Comp}{"type_problems_low"}+$STAT{$Comp}{"changed_constants"}) { - $PSUMMARY .= "<td>Low</td><td class='warning'>$Low</td>\n"; - } - else { - $PSUMMARY .= "<td>Low</td><td>0</td>\n"; - } - $PSUMMARY .= "</tr>"; - $PSUMMARY .= "</table>\n"; - - $SYS_REPORT .= $PSUMMARY; - } - - # added/removed libraries - my $LIB_PROBLEMS = "<h2>Added/Removed Libraries</h2><hr/>\n"; - $LIB_PROBLEMS .= "<table class='summary'>\n"; - $LIB_PROBLEMS .= "<tr><th></th><th style='text-align:center;font-weight:bold;'>Severity</th><th style='text-align:center;font-weight:bold;'>Count</th></tr>\n"; - if(my $Added = keys(%Added)) { - $LIB_PROBLEMS .= "<tr><th>Added</th><td>-</td><td class='new'>$Added</td></tr>\n"; - } - else { - $LIB_PROBLEMS .= "<tr><th>Added</th><td>-</td><td>0</td></tr>\n"; - } - if(my $Removed = keys(%Removed)) { - $LIB_PROBLEMS .= "<tr><th>Removed</th><td>High</td><td class='failed'>$Removed</td></tr>\n"; - } - else { - $LIB_PROBLEMS .= "<tr><th>Removed</th><td>High</td><td>0</td></tr>\n"; - } - $LIB_PROBLEMS .= "</table>\n"; - $SYS_REPORT .= $LIB_PROBLEMS; - - # report table - $SYS_REPORT .= "<a name='Report'></a>\n"; - $SYS_REPORT .= "<h2>Report</h2><hr/>\n"; - - # $SYS_REPORT .= "<br/>"; - - $SYS_REPORT .= "<table class='wikitable'>"; - - $SYS_REPORT .= "<tr>"; - $SYS_REPORT .= "<th rowspan='2'>$SONAME_Title<sup>$Total</sup></th>"; + $SYS_REPORT .= "<table class='summary'>\n"; + $SYS_REPORT .= "<tr>\n"; + $SYS_REPORT .= "<th rowspan='2'>$SONAME_Title<sup>$Total</sup></th>\n"; if(not $GroupByHeaders) { - $SYS_REPORT .= "<th colspan='2'>Version</th>"; + $SYS_REPORT .= "<th colspan='2'>Version</th>\n"; } if($BinaryOnly and $SourceOnly) { - $SYS_REPORT .= "<th colspan='2'>Compatible</th>"; + $SYS_REPORT .= "<th colspan='2'>Compatibility</th>\n"; } else { - $SYS_REPORT .= "<th rowspan='2'>Compatible</th>"; + $SYS_REPORT .= "<th rowspan='2'>Compatibility</th>\n"; } - $SYS_REPORT .= "<th rowspan='2'>Added<br/>Symbols</th><th rowspan='2'>Removed<br/>Symbols</th>"; - if($BinaryOnly and $SourceOnly) + $SYS_REPORT .= "<th rowspan='2'>Added<br/>Symbols</th>\n"; + $SYS_REPORT .= "<th rowspan='2'>Removed<br/>Symbols</th>\n"; + if(-d $HDiff) { - $SYS_REPORT .= "<th colspan='3' style='white-space:nowrap;'>API Changes / Binary Compatibility</th>"; - $SYS_REPORT .= "<th colspan='3' style='white-space:nowrap;'>API Changes / Source Compatibility</th>"; + $SYS_REPORT .= "<th rowspan='2'>Headers<br/>Diff</th>\n"; + $Columns += 1; } - else { - $SYS_REPORT .= "<th colspan='3' style='white-space:nowrap;'>API Changes / Compatibility</th>"; - } - $SYS_REPORT .= "</tr>"; + $SYS_REPORT .= "</tr>\n"; - $SYS_REPORT .= "<tr>"; + $SYS_REPORT .= "<tr>\n"; if(not $GroupByHeaders) { - $SYS_REPORT .= "<th>$SystemName1</th><th>$SystemName2</th>"; + $SYS_REPORT .= "<th>$SystemName1</th><th>$SystemName2</th>\n"; } if($BinaryOnly and $SourceOnly) { - $SYS_REPORT .= "<th>Binary</th><th>Source</th>"; + $SYS_REPORT .= "<th>Binary</th><th>Source</th>\n"; } - $SYS_REPORT .= "<th class='severity'>High</th><th class='severity'>Medium</th><th class='severity'>Low</th>\n" if($BinaryOnly); - $SYS_REPORT .= "<th class='severity'>High</th><th class='severity'>Medium</th><th class='severity'>Low</th>\n" if($SourceOnly); - $SYS_REPORT .= "</tr>"; + $SYS_REPORT .= "</tr>\n"; my %RegisteredPairs = (); - my $Columns = 2; - if($BinaryOnly) { - $Columns += 3; - } - if($SourceOnly) { - $Columns += 3; - } - foreach my $LName (sort {lc($a) cmp lc($b)} (keys(%TestResults), keys(%Added), keys(%Removed))) { next if($SONAME_Changed{$LName}); @@ -700,18 +663,20 @@ sub cmpSystems($$$) my $Anchor = $LName; $Anchor=~s/\+/p/g; # anchor for libFLAC++ is libFLACpp $Anchor=~s/\~/-/g; # libqttracker.so.1~6 - $SYS_REPORT .= "<tr>\n<td class='left'>$LName<a name=\'$Anchor\'></a></td>\n"; + + $SYS_REPORT .= "<tr>\n"; + $SYS_REPORT .= "<td class='object'>$LName<a name=\'$Anchor\'></a></td>\n"; if(defined $Removed{$LName}) { - $SYS_REPORT .= "<td class='failed'>".printVer($Removed{$LName}{"version"})."</td>\n"; + $SYS_REPORT .= "<td class='failed ver'>".printVer($Removed{$LName}{"version"})."</td>\n"; } elsif(defined $Added{$LName}) { $SYS_REPORT .= "<td class='new'><a href='".$Added{$LName}{"list"}."'>added</a></td>\n"; } elsif(not $GroupByHeaders) { - $SYS_REPORT .= "<td>".printVer($TestResults{$LName}{"v1"})."</td>\n"; + $SYS_REPORT .= "<td class='ver'>".printVer($TestResults{$LName}{"v1"})."</td>\n"; } - my $SONAME_report = "<td colspan=\'$Columns\' rowspan='2'>"; + my $SONAME_report = "<td colspan=\'$Columns\' rowspan='2'>\n"; if($BinaryOnly and $SourceOnly) { $SONAME_report .= "SONAME has been changed (see <a href='".$TestResults{$LName_Short}{"Binary"}{"path"}."'>binary</a> and <a href='".$TestResults{$LName_Short}{"Source"}{"path"}."'>source</a> compatibility reports)\n"; } @@ -721,11 +686,11 @@ sub cmpSystems($$$) elsif($SourceOnly) { $SONAME_report .= "SONAME has been <a href='".$TestResults{$LName_Short}{"Source"}{"path"}."'>changed</a>\n"; } - $SONAME_report .= "</td>"; + $SONAME_report .= "</td>\n"; if(defined $Added{$LName}) { # added library - $SYS_REPORT .= "<td class='new'>".printVer($Added{$LName}{"version"})."</td>\n"; + $SYS_REPORT .= "<td class='new ver'>".printVer($Added{$LName}{"version"})."</td>\n"; $SYS_REPORT .= "<td class='passed'>100%</td>\n" if($BinaryOnly); $SYS_REPORT .= "<td class='passed'>100%</td>\n" if($SourceOnly); if($RegisteredPairs{$LName}) { @@ -739,7 +704,7 @@ sub cmpSystems($$$) else { foreach (1 .. $Columns) { - $SYS_REPORT .= "<td>n/a</td>\n"; # colspan='5' + $SYS_REPORT .= "<td>N/A</td>\n"; # colspan='5' } } $SYS_REPORT .= "</tr>\n"; @@ -761,7 +726,7 @@ sub cmpSystems($$$) else { foreach (1 .. $Columns) { - $SYS_REPORT .= "<td>n/a</td>\n"; # colspan='5' + $SYS_REPORT .= "<td>N/A</td>\n"; # colspan='5' } } $SYS_REPORT .= "</tr>\n"; @@ -769,7 +734,7 @@ sub cmpSystems($$$) } elsif(defined $ChangedSoname{$LName}) { # added library - $SYS_REPORT .= "<td>".printVer($TestResults{$LName}{"v2"})."</td>\n"; + $SYS_REPORT .= "<td class='ver'>".printVer($TestResults{$LName}{"v2"})."</td>\n"; $SYS_REPORT .= "<td class='passed'>100%</td>\n" if($BinaryOnly); $SYS_REPORT .= "<td class='passed'>100%</td>\n" if($SourceOnly); if($RegisteredPairs{$LName}) { @@ -783,7 +748,7 @@ sub cmpSystems($$$) else { foreach (1 .. $Columns) { - $SYS_REPORT .= "<td>n/a</td>\n"; # colspan='5' + $SYS_REPORT .= "<td>N/A</td>\n"; # colspan='5' } } $SYS_REPORT .= "</tr>\n"; @@ -791,7 +756,7 @@ sub cmpSystems($$$) } elsif(not $GroupByHeaders) { - $SYS_REPORT .= "<td>".printVer($TestResults{$LName}{"v2"})."</td>\n"; + $SYS_REPORT .= "<td class='ver'>".printVer($TestResults{$LName}{"v2"})."</td>\n"; } my $BinCompatReport = $TestResults{$LName}{"Binary"}{"path"}; @@ -799,24 +764,48 @@ sub cmpSystems($$$) if($BinaryOnly) { - if($TestResults{$LName}{"Binary"}{"verdict"} eq "compatible") { - $SYS_REPORT .= "<td class='passed'><a href=\'$BinCompatReport\'>100%</a></td>\n"; + if($TestResults{$LName}{"Binary"}{"verdict"} eq "compatible") + { + my $Cl = "passed"; + if($TOTAL{$LName}{"Binary"}) { + $Cl = "warning"; + } + $SYS_REPORT .= "<td class=\'$Cl\'><a href=\'$BinCompatReport\'>100%</a></td>\n"; } else { my $Compatible = 100 - $TestResults{$LName}{"Binary"}{"affected"}; - $SYS_REPORT .= "<td class='failed'><a href=\'$BinCompatReport\'>$Compatible%</a></td>\n"; + my $Cl = "incompatible"; + if($Compatible>=90) { + $Cl = "warning"; + } + elsif($Compatible>=80) { + $Cl = "almost_compatible"; + } + $SYS_REPORT .= "<td class=\'$Cl\'><a href=\'$BinCompatReport\'>$Compatible%</a></td>\n"; } } if($SourceOnly) { - if($TestResults{$LName}{"Source"}{"verdict"} eq "compatible") { - $SYS_REPORT .= "<td class='passed'><a href=\'$SrcCompatReport\'>100%</a></td>\n"; + if($TestResults{$LName}{"Source"}{"verdict"} eq "compatible") + { + my $Cl = "passed"; + if($TOTAL{$LName}{"Source"}) { + $Cl = "warning"; + } + $SYS_REPORT .= "<td class=\'$Cl\'><a href=\'$SrcCompatReport\'>100%</a></td>\n"; } else { my $Compatible = 100 - $TestResults{$LName}{"Source"}{"affected"}; - $SYS_REPORT .= "<td class='failed'><a href=\'$SrcCompatReport\'>$Compatible%</a></td>\n"; + my $Cl = "incompatible"; + if($Compatible>=90) { + $Cl = "warning"; + } + elsif($Compatible>=80) { + $Cl = "almost_compatible"; + } + $SYS_REPORT .= "<td class=\'$Cl\'><a href=\'$SrcCompatReport\'>$Compatible%</a></td>\n"; } } if($BinaryOnly) @@ -827,20 +816,20 @@ sub cmpSystems($$$) $AddedSym="<a href='$BinCompatReport\#Added'>$Count new</a>"; } if($AddedSym) { - $SYS_REPORT.="<td class='new'>$AddedSym</td>"; + $SYS_REPORT.="<td class='new'>$AddedSym</td>\n"; } else { - $SYS_REPORT.="<td class='passed'>0</td>"; + $SYS_REPORT.="<td class='passed'>0</td>\n"; } my $RemovedSym=""; if(my $Count = $TestResults{$LName}{"Binary"}{"removed"}) { $RemovedSym="<a href='$BinCompatReport\#Removed'>$Count removed</a>"; } if($RemovedSym) { - $SYS_REPORT.="<td class='failed'>$RemovedSym</td>"; + $SYS_REPORT.="<td class='failed'>$RemovedSym</td>\n"; } else { - $SYS_REPORT.="<td class='passed'>0</td>"; + $SYS_REPORT.="<td class='passed'>0</td>\n"; } } elsif($SourceOnly) @@ -850,137 +839,42 @@ sub cmpSystems($$$) $AddedSym="<a href='$SrcCompatReport\#Added'>$Count new</a>"; } if($AddedSym) { - $SYS_REPORT.="<td class='new'>$AddedSym</td>"; + $SYS_REPORT.="<td class='new'>$AddedSym</td>\n"; } else { - $SYS_REPORT.="<td class='passed'>0</td>"; + $SYS_REPORT.="<td class='passed'>0</td>\n"; } my $RemovedSym=""; if(my $Count = $TestResults{$LName}{"Source"}{"removed"}) { $RemovedSym="<a href='$SrcCompatReport\#Removed'>$Count removed</a>"; } if($RemovedSym) { - $SYS_REPORT.="<td class='failed'>$RemovedSym</td>"; + $SYS_REPORT.="<td class='failed'>$RemovedSym</td>\n"; } else { - $SYS_REPORT.="<td class='passed'>0</td>"; + $SYS_REPORT.="<td class='passed'>0</td>\n"; } } - if($BinaryOnly) - { - my $High=""; - if(my $Count = $TestResults{$LName}{"Binary"}{"type_problems_high"}+$TestResults{$LName}{"Binary"}{"interface_problems_high"}) { - $High="<a href='$BinCompatReport\#High_Risk_Problems'>".problem_title($Count)."</a>"; - } - if($High) { - $SYS_REPORT.="<td class='failed'>$High</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } - my $Medium=""; - if(my $Count = $TestResults{$LName}{"Binary"}{"type_problems_medium"}+$TestResults{$LName}{"Binary"}{"interface_problems_medium"}) { - $Medium="<a href='$BinCompatReport\#Medium_Risk_Problems'>".problem_title($Count)."</a>"; - } - if($Medium) { - $SYS_REPORT.="<td class='failed'>$Medium</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } - my $Low=""; - if(my $Count = $TestResults{$LName}{"Binary"}{"type_problems_low"}+$TestResults{$LName}{"Binary"}{"interface_problems_low"}+$TestResults{$LName}{"Binary"}{"changed_constants"}) { - $Low="<a href='$BinCompatReport\#Low_Risk_Problems'>".warning_title($Count)."</a>"; - } - if($Low) { - $SYS_REPORT.="<td class='warning'>$Low</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } + if(-d $HDiff."/".$LName) { + $SYS_REPORT .= "<td><a href=\'headers_diff/$LName/diff.html\'>diff</a></td>\n"; } - - if($SourceOnly) - { - my $High=""; - if(my $Count = $TestResults{$LName}{"Source"}{"type_problems_high"}+$TestResults{$LName}{"Source"}{"interface_problems_high"}) { - $High="<a href='$SrcCompatReport\#High_Risk_Problems'>".problem_title($Count)."</a>"; - } - if($High) { - $SYS_REPORT.="<td class='failed'>$High</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } - my $Medium=""; - if(my $Count = $TestResults{$LName}{"Source"}{"type_problems_medium"}+$TestResults{$LName}{"Source"}{"interface_problems_medium"}) { - $Medium="<a href='$SrcCompatReport\#Medium_Risk_Problems'>".problem_title($Count)."</a>"; - } - if($Medium) { - $SYS_REPORT.="<td class='failed'>$Medium</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } - my $Low=""; - if(my $Count = $TestResults{$LName}{"Source"}{"type_problems_low"}+$TestResults{$LName}{"Source"}{"interface_problems_low"}+$TestResults{$LName}{"Source"}{"changed_constants"}) { - $Low="<a href='$SrcCompatReport\#Low_Risk_Problems'>".warning_title($Count)."</a>"; - } - if($Low) { - $SYS_REPORT.="<td class='warning'>$Low</td>"; - } - else { - $SYS_REPORT.="<td class='passed'>0</td>"; - } + else { + $SYS_REPORT .= "<td>N/A</td>\n"; } $SYS_REPORT .= "</tr>\n"; } - # bottom header - $SYS_REPORT .= "<tr>"; - $SYS_REPORT .= "<th rowspan='2'>$SONAME_Title</th>"; - if(not $GroupByHeaders) { - $SYS_REPORT .= "<th>$SystemName1</th><th>$SystemName2</th>"; - } - if($BinaryOnly and $SourceOnly) { - $SYS_REPORT .= "<th>Binary</th><th>Source</th>"; - } - else { - $SYS_REPORT .= "<th rowspan='2'>Compatible</th>"; - } - $SYS_REPORT .= "<th rowspan='2'>Added<br/>Symbols</th><th rowspan='2'>Removed<br/>Symbols</th>"; - $SYS_REPORT .= "<th class='severity'>High</th><th class='severity'>Medium</th><th class='severity'>Low</th>" if($BinaryOnly); - $SYS_REPORT .= "<th class='severity'>High</th><th class='severity'>Medium</th><th class='severity'>Low</th>" if($SourceOnly); - $SYS_REPORT .= "</tr>"; - - $SYS_REPORT .= "<tr>"; - if(not $GroupByHeaders) { - $SYS_REPORT .= "<th colspan='2'>Version</th>"; - } - - if($BinaryOnly and $SourceOnly) { - $SYS_REPORT .= "<th colspan='2'>Compatible</th>"; - } - if($BinaryOnly and $SourceOnly) - { - $SYS_REPORT .= "<th colspan='3' style='white-space:nowrap;'>API Changes / Binary Compatibility</th>"; - $SYS_REPORT .= "<th colspan='3' style='white-space:nowrap;'>API Changes / Source Compatibility</th>"; - } - else { - $SYS_REPORT .= "<th colspan='3' style='white-space:nowrap;'>API Changes / Compatibility</th>"; - } - $SYS_REPORT .= "</tr>"; $SYS_REPORT .= "</table>"; - my $Title = "$SystemName1 to $SystemName2 compatibility report"; + my $Title = "$SystemName1 vs $SystemName2 compatibility report"; my $Keywords = "compatibility, $SystemName1, $SystemName2, API, changes"; my $Description = "API compatibility report between $SystemName1 and $SystemName2 on ".showArch($ArchName); my $Styles = readModule("Styles", "CmpSystems.css"); $SYS_REPORT = composeHTML_Head($Title, $Keywords, $Description, $Styles, "")."\n<body>\n<div>".$SYS_REPORT."</div>\n"; - $SYS_REPORT .= "<br/><br/><br/>\n"; + $SYS_REPORT .= "<br/><br/>\n"; $SYS_REPORT .= getReportFooter(); $SYS_REPORT .= "</body></html>\n"; @@ -1001,7 +895,7 @@ sub cmpSystems($$$) $REPORT_PATH .= "src_compat_report.html"; } writeFile($REPORT_PATH, $SYS_REPORT); - printMsg("INFO", "see detailed report:\n $REPORT_PATH"); + printMsg("INFO", "\nSee detailed report:\n $REPORT_PATH"); } sub printVer($) @@ -1143,7 +1037,8 @@ sub initModule($) $CrossGcc = $S->{"CrossGcc"}; $UseStaticLibs = $S->{"UseStaticLibs"}; $NoStdInc = $S->{"NoStdInc"}; - $CppCompat = $S->{"CppCompat"}; + $CxxIncompat = $S->{"CxxIncompat"}; + $SkipUnidentified = $S->{"SkipUnidentified"}; $BinaryOnly = $S->{"BinaryOnly"}; $SourceOnly = $S->{"SourceOnly"}; @@ -1215,7 +1110,8 @@ sub readSysDescriptor($) "skip_types" => "m", "ignore_symbols" => "h", "non_prefix" => "h", - "defines" => "s" + "defines" => "s", + "cxx_incompatible" => "s" ); my %DInfo = (); foreach my $Tag (keys(%Tags)) @@ -2237,6 +2133,7 @@ sub dumpSystem($) } printMsg("INFO", "Generating XML descriptors ..."); my %Generated = (); + my %CxxIncompat_L = (); foreach my $LRelPath (keys(%SysLib_SysHeaders)) { my $LName = get_filename($LRelPath); @@ -2456,6 +2353,9 @@ sub dumpSystem($) if(my $List = $SysInfo->{$_}{"defines"}) { push(@Defines, $List); } + if($SysInfo->{$_}{"cxx_incompatible"}) { + $CxxIncompat_L{$LName} = 1; + } } # common other @@ -2500,7 +2400,18 @@ sub dumpSystem($) } writeFile($DPath, join("\n\n", @Content)); - $Generated{$LRelPath}=1; + $Generated{$LRelPath} = 1; + + # save header files to create visual diff later + my $HSDir = $SYS_DUMP_PATH."/headers/".$LName; + rmtree($HSDir); + mkpath($HSDir); + foreach my $H_P (@IncHeaders) + { + if(-f $H_P) { + copy($H_P, $HSDir); + } + } } } printMsg("INFO", "Created descriptors: ".keys(%Generated)." ($SYS_DUMP_PATH/descriptors/)\n"); @@ -2567,8 +2478,11 @@ sub dumpSystem($) # 3. symbian/GCC $ACC_dump .= " -nostdinc"; } - if($CppCompat) { - $ACC_dump .= " -cpp-compatible"; + if($CxxIncompat or $CxxIncompat_L{$LName}) { + $ACC_dump .= " -cxx-incompatible"; + } + if($SkipUnidentified) { + $ACC_dump .= " -skip-unidentified"; } if($Quiet) { # quiet mode |