reals_check/reals_check.ps1 (119 lines of code) (raw):

#Copyright (c) Microsoft. All rights reserved. #Licensed under the MIT license. See LICENSE file in the project root for full license information. function Check-Symbols { param( [string] $lib ) try { [string]$output = cmd.exe /c dumpbin /ALL $lib } catch { Write-Error "Unable to run dumpbin on given lib $lib" return 2 } # The list of public symbols in the dumpbin output is contained between these two symbols: $start_token = "public symbols" $end_token = "Archive member name" try { [int] $start = $output.IndexOf($start_token) [int] $end = $output.IndexOf($end_token, $start) # Isolating symbols from rest of dumpbin output $symbol_text = ($output.Substring($start + $start_token.Length+1, $end-$start-$start_token.Length-1)) # Splitting text by whitespace, alternate tokens are symbols $split_symbols = $symbol_text.Split('',[StringSplitOptions]::RemoveEmptyEntries) } catch { Write-Error "Unable to parse dumpbin output for lib $lib" return 2 } # Detecting if symbol list was not generated by dumpbin if($split_symbols.Length -lt 2) { Write-Error "Unable to parse dumpbin output for lib $lib" return 2 } $real_prefix = "real_" # hashset to store original symbols and real symbols $symbol_table = New-Object -TypeName "System.Collections.Generic.HashSet[string]" # list of symbols that have original and duplicate. $duplicate_symbols = New-Object -TypeName "System.Collections.ArrayList" $return_code = 0 for($i=0; $i -lt $split_symbols.Length; $i++){ # Skip even tokens because only odd tokens have symbols if($i % 2 -ne 0) { if($split_symbols[$i].StartsWith($real_prefix)) { $real_symbol = $split_symbols[$i] $symbol = $split_symbols[$i].Substring($real_prefix.Length) } else { $symbol = $split_symbols[$i] $real_symbol = $real_prefix + $symbol } # Add original symbol and real symbol to hashset if(-not ($symbol_table.Add($symbol) -and $symbol_table.Add($real_symbol))){ # If either of the adds fails, it means symbol was already present in hashset $return_code = 1 [void]$duplicate_symbols.Add($symbol) } } } # Print duplicate symbols (if any) to stderr if($duplicate_symbols.Count -gt 0){ Write-Error ("The following symbols have original and reals:`n"+($duplicate_symbols -join "`n")) } return $return_code } ForEach($lib in $args){ Write-Host "Checking lib $lib" try { $exit_code = Check-Symbols -lib $lib } catch { Write-Error "Unable to check lib $lib." return 2 } if($exit_code -ne 0){ exit $exit_code } } exit 0 <# .SYNOPSIS Checks library for presence of "[symbol]" and "real_[symbol]". .DESCRIPTION Checks library for presence of "[symbol]" and "real_[symbol]". Takes path to library as parameter. .PARAMETER lib Library to be checked. .INPUTS None. .OUTPUTS None. Returns exit code 0 if no ("[symbol]", "real_[symbol]") pairs found in any library. Returns exit code 1 if atleast 1 ("[symbol]", "real_[symbol]") pair found in a library. Prints names of symbols to stderr. Returns exit code 2 if unable to determine for a library. Prints reason to stderror. .EXAMPLE PS> .\reals_check.ps1 lib_to_check_good.lib PS> $lastexitcode 0 .EXAMPLE PS> .\reals_check.ps1 lib_to_check_bad.lib Check-Symbols : The following symbols are duplicate: [ list of duplicate symbols ] At {path_to_script}\reals_check.ps1:57 char:7 + exit (Check-Symbols -lib $args[0]) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Check-Symbols PS> $lastexitcode 1 .EXAMPLE PS> .\reals_check.ps1 lib_to_check_nonexistent.lib Check-Symbols : Unable to parse dumpbin output At {path_to_script}\reals_check.ps1:57 char:7 + exit (Check-Symbols -lib $args[0]) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Check-Symbols PS> $lastexitcode 2 #>