1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

powershellでGreen Hillsコンパイラのログ解析してみた

Posted at

コンパイルログ解析

Green Hills のコンパイラが出力するログを解析し,どのようなエラー/ワーニングが何件発生ているか解析したいと思い立ったので書いてみた。

下記は warning の例です。
:" から次の "までが問題があるソースファイル名を示しています。
また,"warning #"のあとの数値がワーニングの種類を示しています。

> complielog.log:3139:"test.c", line 78: warning #550-D: variable "testram1" was
  complielog.log:3140:          set but never used

これらのワードで各種情報を抽出します。

基本的な処理の流れ

Log 読み込む

ログを読み込む際に "error #"や "warning #" にマッチする行を選択的に読み込む。

$logFile = "complielog.log"
$resE = Select-String -Path $logFile -Pattern "error #" -Context  0, 3 -Encoding default
$resW = Select-String -Path $logFile -Pattern "warning #" -Context  0, 3 -Encoding default

ファイル名を抽出する

エラーログ上の :" から ",までの中身がファイル名となる。

> complielog.log:3139:"test.c", line 78: warning #550-D: variable "fl_testram1" was
  complielog.log:3140:          set but never used
$resEfile = [RegEx]::Matches( $resE, '(?<=(:")).*?(?=(",))')
$resWfile = [RegEx]::Matches( $resW, '(?<=(:")).*?(?=(",))')

エラー No を抽出する

エラーログ上の # から:でまでの中身がエラーNo

$resENo = [RegEx]::Matches( $resE, "(?<=#).*?(?=:)")
$resWNo = [RegEx]::Matches( $resW, "(?<=#).*?(?=:)")

エラー No 毎の件数を計算する

もう少し賢いやり方がありそうだが,連想配列を使ってごりごり処理してみた。

$resEhash = @{}  # 空の連想配列を作成
if ($resENo.Count -gt 0) {
    $resENo.Value | ForEach-Object {
        $val = $_
        if (! $resEhash.ContainsKey($val)) {
            $resEhash.add($val, 1) # if keyがない場合は追加する
        } else {
            $resEhash[$val] = $resEhash[$val] + 1 # else keyがある場合はインクリメントする
        }
    }
}

$resWhash = @{}  # 空の連想配列を作成
if ($resWno.Count -gt 0) {
    $resWNo.Value | ForEach-Object {
        $val = $_
        if(! $resWhash.ContainsKey($val)){
            $resWhash.add($val, 1) # if keyがない場合は追加する
        } else {
            $resWhash[$val] = $resWhash[$val] + 1 # else keyがある場合はインクリメントする
        }
    }
}

エクセルに書き込む

詳細は下記 Script を参照ください。

Script

# compile log の を整理する。

# [使い方]
# PS > .\compilelogGrep2.ps1 -logfile .\aaa.log -outputfile aaaa.xlsx

param (
    # Param1
    [Parameter(Position = 0)]
    [String]
    $logFile = ".\GHS_compile.log",
    # Param2
    [Parameter(Position = 1)]
    [String]
    $outputfile = "compilelog_summary.xlsx"
)

# === Log読込・解析処理  ===========================================================
Write-host "error を抽出"
$resE = Select-String -Path $logFile -Pattern "error #" -Context  0, 3 -Encoding default
if ($debugMode) {
    $outputEFname = "compilelog_summary_error.csv"
    if (test-path -Path $outputEFname) { remove-item $outputEFname }
    $resE | out-file $outputEFname -Append -Encoding default -width 1000
}
write-host "error件数" $resE.count
if ($resE.Count -gt 0) {
    # ファイル名抽出
    $resEfile = [RegEx]::Matches( $resE, '(?<=(:")).*?(?=(",))')
    # エラーNo抽出
    $resENo = [RegEx]::Matches( $resE, "(?<=#).*?(?=:)")
    $resEhash = @{}  # 空の連想配列を作成
    if ($resENo.Count -gt 0) {
        $resENo.Value | ForEach-Object {
            $val = $_
            if (! $resEhash.ContainsKey($val)) {
                $resEhash.add($val, 1) # if keyがない場合は追加する
            } else {
                $resEhash[$val] = $resEhash[$val] + 1 # else keyがある場合はインクリメントする
            }
        }

    }
}

write-host "warning を抽出"
$resW = Select-String -Path $logFile -Pattern "warning #" -Context  0, 3 -Encoding default
if ($debugMode) {
    $outputWFname = "compilelog_summary_warning.csv"
    if (test-path -Path $outputWFname) { remove-item $outputWFname }
    $resW | out-file $outputWFname -Append -Encoding default -width 1000
}
write-host "warning件数" $resW.count
$resWfile = @()
$resWNo = @()
if ($resW.Count -gt 0){
    # ファイル名抽出
    $resWfile = [RegEx]::Matches( $resW, '(?<=(:")).*?(?=(",))')
    # ワーニングNo抽出
    $resWNo = [RegEx]::Matches( $resW, "(?<=#).*?(?=:)")
    $resWhash = @{}  # 空の連想配列を作成
    if ($resWno.Count -gt 0) {
        $resWNo.Value | ForEach-Object {
            $val = $_
            if (! $resWhash.ContainsKey($val)) {
                $resWhash.add($val, 1)  # if keyがない場合は追加する
            } else {
                $resWhash[$val] = $resWhash[$val] + 1 # else keyがある場合はインクリメントする
            }
        }
    }
}


# === 出力処理 ==================================================================
# Excelに出力する
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true          # 画面上に表示させない
$excel.DisplayAlerts = $true    # 警告メッセージは表示する

# # 対象の Excel ファイル名
$currentPath = (Convert-Path .)
$outputfile = join-path $currentPath $outputfile
if (Test-Path $outputfile) { Remove-Item $outputfile }      # 存在する場合は事前に削除しておく

$book = $excel.Workbooks.Add()
$SheetE = $book.Worksheets.Item(1)
$SheetE.Name = "error"
$SheetW = $book.Worksheets.Add([System.Reflection.Missing]::Value, $SheetE)
$SheetW.Name = "warning"
$SheetS = $book.Worksheets.Add($SheetE)
$SheetS.Name = "Summary"

# ---------- summary sheet -----------------
$SheetS.Columns("A").ColumnWidth = 5
$SheetS.Columns("B:C").ColumnWidth = 15

$SheetS.Range("A1") = "コンパイル結果"
$SheetS.Range("A1").Font.Bold = $true
$SheetS.Range("A1").interior.ColorIndex = 6

$SheetS.Range("B4") = "mk32 log"
$SheetS.Range("C4") = $logFile
$SheetS.Range("B5") = "Log Date"
$SheetS.Range("C5") = $(Get-ItemProperty $logFile).LastWriteTime.ToString('yyyy/MM/dd')
$SheetS.Range("B6") = "Log Time"
$SheetS.Range("C6") = $(Get-ItemProperty $logFile).LastWriteTime.ToString('HH:mm:ss')

$lop = 9
$strRange = ("C" + $lop)
$SheetS.Range($strRange) = "Error"
$SheetS.Range($strRange).Font.Bold = $true
$SheetS.Range($strRange).interior.ColorIndex = 6
$lop++
$SheetS.Range("B" + $lop) = "件数"
$SheetS.Range("C" + $lop) = $resE.count
if ($resE.Count -gt 0) {
    $lop = $lop + 2
    $SheetS.Range("B" + $lop) = "内訳"
    $SheetS.Range("C" + $lop) = "Error No"
    $SheetS.Range("D" + $lop) = "Count"
    $lop++
    foreach ($key in $resEhash.Keys) {
        $SheetS.Range("C" + $lop) = $key
        $SheetS.Range("D" + $lop) = $resEhash[$key]
        $lop++
    }
}
$lop = $lop + 3

$strRange = ("C" + $lop)
$SheetS.Range($strRange) = "Warning"
$SheetS.Range($strRange).Font.Bold = $true
$SheetS.Range($strRange).interior.ColorIndex = 6
$lop++
$SheetS.Range("B" + $lop) = "件数"
$SheetS.Range("C" + $lop) = $resW.count
if ($resW.Count -gt 0) {
    $lop = $lop + 2
    $SheetS.Range("B" + $lop) = "内訳"
    $SheetS.Range("C" + $lop) = "Warning No"
    $SheetS.Range("D" + $lop) = "Count"
    $lop++
    foreach ($key in $resWhash.Keys) {
        $SheetS.Range("C" + $lop) = $key
        $SheetS.Range("D" + $lop) = $resWhash[$key]
        $lop++
    }
} else {
$lop++
}
$SheetS.Range("A" + $lop) = "[EOL]"




# ---------- error sheet -----------------
$SheetE.Range("A1") = "処置"
$SheetE.Columns("A").ColumnWidth = 25
$SheetE.Range("B1") = "担当"
$SheetE.Range("C1") = "処置結果"
$SheetE.Columns("C").ColumnWidth = 25
$SheetE.Range("D1") = "No"
$SheetE.Columns("D").ColumnWidth = 15
$SheetE.Range("E1") = "filename"
$SheetE.Columns("E").ColumnWidth = 25
$SheetE.Range("F1") = "ログ"
$SheetE.Columns("F").ColumnWidth = 150
$SheetE.Range("A1:F1").Font.Bold = $true
$SheetE.Range("A1:F1").interior.ColorIndex = 6

if ($resE.Count -gt 0) {
    $lop = 2
    $resE | ForEach-Object {
        $strRange = ("F" + $lop)
        $SheetE.Range($strRange) = $_.ToString()
        $lop++
    }
    $lop = 2
    $resEfile.Value | ForEach-Object {
        $strRange = ("E" + $lop)
        $SheetE.Range($strRange) = $_
        $lop++
    }

    $lop = 2
    $resENo.Value | ForEach-Object {
        $strRange = ("D" + $lop)
        $SheetE.Range($strRange) = $_
        $lop++
    }
    $SheetE.Range("A" + $lop+":F"+ $lop) = "[EOL]"
    # オートフィルタを設定する
    $SheetE.Range("A:F").autofilter(1) | out-null
}


# ---------- warning sheet -----------------
$SheetW.Range("A1") = "処置"
$SheetW.Columns("A").ColumnWidth = 25
$SheetW.Range("B1") = "担当"
$SheetW.Range("C1") = "処置結果"
$SheetW.Columns("C").ColumnWidth = 25
$SheetW.Range("D1") = "No"
$SheetW.Columns("D").ColumnWidth = 15
$SheetW.Range("E1") = "Filename"
$SheetW.Columns("E").ColumnWidth = 25
$SheetW.Range("F1") = "ログ"
$SheetW.Columns("F").ColumnWidth = 150
$SheetW.Range("A1:F1").Font.Bold = $true
$SheetW.Range("A1:F1").interior.ColorIndex = 6

if ($resW.Count -gt 0) {
    $lop = 2
    $resW | ForEach-Object {
        $strRange = ("F" + $lop)
        $SheetW.Range($strRange) = $_.ToString()
        $lop++
    }
    $lop = 2
    $resWfile.Value | ForEach-Object {
        $strRange = ("E" + $lop)
        $SheetW.Range($strRange) = $_
        $lop++
    }
    $lop = 2
    $resWNo.Value | ForEach-Object {
        $strRange = ("D" + $lop)
        $SheetW.Range($strRange) = $_
        $lop++
    }
    $SheetW.Range("A" + $lop+":F"+ $lop) = "[EOL]"
    # オートフィルタを設定する
    $SheetW.Range("A:F").autofilter(1) | out-null
}

# 上書き保存
$book.SaveAs($outputfile)
# ブックを閉じる
$excel.Workbooks.Close()
$excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($book) | out-null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | out-null

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?