2020年8月24日月曜日

[SpyGlass]解析結果のマージスクリプト

[SpyGlass]解析結果のマージスクリプト

SpyGlassのレポートと解析結果をマージするPerlスクリプト

実行環境

  • SpyGlassのレポート(moresimple.rpt)
  • SpyGlassの解析結果レポート(Tab区切り)
    ※SpyGlassのレポートに判定と根拠を追加したファイル
  • Cygwin
  • Perl(5.36.3)

使い方

  1. 置換リスト($rep)を環境に合わせて変更
    ※例ではファイルパスを削除している
  2. SpyGlassのレポートと解析レポートを同じフォルダに保存
  3. Cygwin上でコマンドを実行
    $perl ./merge_report.pl <SpyGlassのレポート> <解析レポート>
  4. 2種類のファイルが生成されていることを確認
    ①template.rpt
    ②merge_report.rpt

①SpyGlassの解析レポート
前回のSpyGlassの解析レポート+新たな結果を追記した内容

②SpyGlassの解析内容をマージしたレポート
SpyGlassのレポートと解析レポートを比較し内容が一致した場合のみ解析レポートから判定と根拠をマージした内容

スクリプト名:merge_report.pl

#! /bin/perl
use strict;
use warnings;
use utf8;
use Class::Struct;
use Encode 'decode';
use Encode 'encode';

  struct replace => {
    s => '$', # サーチ
    r => '$', # リプレイス
  };
  
  our @rep      = replace->new();
  our $dummy    = "--dummy_data--";
  our $join_msg = "";

  # +-------------------------------------------------------+
  # | 置換リスト                                            |
  # +-------------------------------------------------------+
  $rep[0] = replace->new();
  $rep[0]->s('  +');
  $rep[0]->r("");
  
  $rep[1] = replace->new();
  $rep[1]->s("../2020-08-01/RTL/");
  $rep[1]->r("");

  $rep[2] = replace->new();
  $rep[2]->s("../2020-08-02/RTL/");
  $rep[2]->r("");

  # +-------------------------------------------------------+
  # | main                                                  |
  # +-------------------------------------------------------+
  struct column => {
    I => '$', # ID
    R => '$', # Rule
    A => '$', # Alias
    S => '$', # Severity
    F => '$', # File
    L => '$', # Line
    W => '$', # Wt
    M => '$', # Message
    J => '$', # 判定
    G => '$', # 根拠
    C => '$', # 比較結果
    O => '$', # Other
    N => '$', # レポートファイル名
  };
  struct posi => {
    s => '$', # 開始ポジション
    e => '$', # 終了ポジション
  };
  
  struct list => {
    RASFLWM => '$', # perfect matching
    RASFLW_ => '$', # unmatch(Message)
    RASF_WM => '$', # unmatch(Line:?)
    RASF_W_ => '$', # unmatch(Message, Line:?)
    RAS____ => '$', #unmatch(File)
    LINE    => '$', # unsigned int
  };
  struct summary => {
    PM  => '$', # perfect matching
    UM  => '$', # unmatch(Message)
    UL  => '$', # unmatch(Line:?)
    UML => '$', # unmatch(Message, Line:?)
    UF  => '$', # unmatch(File)
    NM  => '$', # nomatch
  };
  
  my $new_file; # SpyGlass report
  my $old_file; #Analysis report
  my $text_ref; # テキスト
  
  if(@ARGV != 2) {
    print "Argments Error.\n";
    exit(1);
  }
  if(-e $ARGV[0]) {
    $new_file = $ARGV[0];
  }
  else {
    print "New file not found.\n";
    exit(1);
  }

  if(-e $ARGV[1]) {
    $old_file = $ARGV[1];
  }
  else {
    print "Old file not found.\n";
    exit(1);
  }
  
  # Step 1.レポートをロードし要素毎にデータを整理
     $text_ref    = fetch($new_file);
  my $new_ele_ref = get_spyglass($text_ref, $new_file);
  
  # Step 2.解析資料をロードし要素毎にデータを整理
     $text_ref    = fetch($old_file);
# my $old_ele_ref = get_spyglass($text_ref, $old_file); # SpyGlass report間のチェック
  my $old_ele_ref = get_analysis($text_ref);            # Analysis reportとSpyGlass report間のマージ

  # メモリ解放
  $text_ref = undef;
  undef $text_ref  ;
  
  # Step 3.比較リストの生成
  my $new_list_ref = make_list($new_ele_ref);
  my $old_list_ref = make_list($old_ele_ref);
  
  # Step 4.マージファイルの生成 
  my ($template_ref, $tmp_sum) = merge_template($new_list_ref, $old_list_ref, $new_ele_ref, $old_ele_ref);
  make_report($template_ref, "template.rpt");
  
  # Step 5.解析資料の生成
  my $mrg_sum = merge_result($new_list_ref, $old_list_ref, $new_ele_ref, $old_ele_ref);
  make_report($new_ele_ref , "merge_report.rpt");

  # Step 6.サマリの表示
  disp_summary($mrg_sum);

  # +-------------------------------------------------------+
  # | Sub                                                   |
  # +-------------------------------------------------------+
  # サマリの表示
  sub disp_summary {
    my ($summary_ref) = @_;
    print "\nMerge Summary\n";
    print "+------------------------------------------------+\n";
    print "perfect matching        :".$$summary_ref->PM."\n";
    print "unmatch(Message)        :".$$summary_ref->UM."\n";
    print "unmatch(Line:?)         :".$$summary_ref->UL."\n";
    print "unmatch(Message, Line:?):".$$summary_ref->UM."\n";
    print "unmatch(File)           :".$$summary_ref->UF."\n";
    print "noematch                :".$$summary_ref->NM."\n";
    print "+------------------------------------------------+\n";
  }
  
  # レポート出力関数
  sub make_report {
    my ($rpt_ref, $file_name) = @_;
    open(my $fd, ">$file_name"); 
    
    print $fd encode('utf-8', "ID\t"              );
    print $fd encode('utf-8', "Rule\t"            );
    print $fd encode('utf-8', "Alias\t"           );
    print $fd encode('utf-8', "Severity\t"        );
    print $fd encode('utf-8', "File\t"            );
    print $fd encode('utf-8', "Line\t"            );
    print $fd encode('utf-8', "Wt\t"              );
    print $fd encode('utf-8', "Message\t"         );
    print $fd encode('utf-8', "判定\t"            );
    print $fd encode('utf-8', "根拠\t"            );
    print $fd encode('utf-8', "マージ結果\t"      );
    print $fd encode('utf-8', "マージ元ファイル\n");
    
    foreach(@$rpt_ref){
      my $I = $_->I; $I =~ s/  +//g; $I =~ s/$dummy//g; print $fd encode('utf-8', $I."\t");
      my $R = $_->R; $R =~ s/  +//g; $R =~ s/$dummy//g; print $fd encode('utf-8', $R."\t");
      my $A = $_->A; $A =~ s/  +//g; $A =~ s/$dummy//g; print $fd encode('utf-8', $A."\t");
      my $S = $_->S; $S =~ s/  +//g; $S =~ s/$dummy//g; print $fd encode('utf-8', $S."\t");
      my $F = $_->F; $F =~ s/  +//g; $F =~ s/$dummy//g; print $fd encode('utf-8', $F."\t");
      my $L = $_->L; $L =~ s/  +//g; $L =~ s/$dummy//g; print $fd encode('utf-8', $L."\t");
      my $W = $_->W; $W =~ s/  +//g; $W =~ s/$dummy//g; print $fd encode('utf-8', $W."\t");
      my $M = $_->M; $M =~ s/  +//g; $M =~ s/$dummy//g; print $fd encode('utf-8', $M."\t");
      my $J = $_->J; $J =~ s/  +//g; $J =~ s/$dummy//g; print $fd encode('utf-8', $J."\t");
      my $G = $_->G; $G =~ s/  +//g; $G =~ s/$dummy//g; print $fd encode('utf-8', $G."\t");
      my $C = $_->C; $C =~ s/  +//g; $C =~ s/$dummy//g; print $fd encode('utf-8', $C."\t");
      my $N = $_->N; $N =~ s/  +//g; $N =~ s/$dummy//g; print $fd encode('utf-8', $N."\t");
      my $O = $_->O;
      if(defined $O){
         $O =~ s/  +//g; $O =~ s/$dummy//g; print $fd encode('utf-8', $O."\t");
      }
      print $fd encode('utf-8', "\r\n");
    }
    
    close($fd);
  }

  # マージファイルの生成
  sub merge_template{
    my ($new_list_ref, $old_list_ref, $new_ele_ref, $old_ele_ref) = @_;
    my @template = column->new();
    my $t=0; my $n=0; my $o=0;
    my $sum = summary->new();
    $sum->PM (0);
    $sum->UM (0);
    $sum->UL (0);
    $sum->UML(0);
    $sum->UF (0);
    $sum->NM (0);
    
    # Analysis reportのマージ
    for($t=0; $t<@$old_ele_ref; $t++){
      $template[$t] = column->new();
      $template[$t] = @$old_ele_ref[$t];
    }
    
    # perfect match
    # --------------------------------------------------
    for($n=0; $n<@$new_list_ref; $n++){
      my $msg;
      my $new_LINE    = @$new_list_ref[$n]->LINE   ;
      my $new_RASFLWM = @$new_list_ref[$n]->RASFLWM;
      my $new_RASFLW_ = @$new_list_ref[$n]->RASFLW_;
      my $new_RASF_WM = @$new_list_ref[$n]->RASF_WM;
      my $new_RASF_W_ = @$new_list_ref[$n]->RASF_W_;
      my $new_RAS____ = @$new_list_ref[$n]->RAS____;
      my $match       = 0;
      
      for(my $o=0; $o<@$old_list_ref;$o++){
        my $old_RASFLWM =  @$old_list_ref[$o]->RASFLWM;
           $old_RASFLWM =~ s/$dummy//g;
        if($new_RASFLWM eq $old_RASFLWM){
          $match = 1;
          $sum->PM ($sum->PM + 1);
          last;
        }
      }
      
      # unmatch(Line:?)
      # --------------------------------------------------
      if($match == 0){
        for (my $o=0; $o<@$old_list_ref; $o++){
          my $old_LINE    =  @$old_list_ref[$o]->LINE;
          my $old_RASF_WM =  @$old_list_ref[$o]->RASF_WM;
          my $old_RASFLW_ =  @$old_list_ref[$o]->RASFLW_;
             $old_LINE    =~ s/$dummy//g;
             $old_RASF_WM =~ s/$dummy//g;
             $old_RASFLW_ =~ s/$dummy//g;
          
          if(($new_RASF_WM eq $old_RASF_WM) && ($new_RASFLW_ ne $old_RASFLW_)){
            $match = 1;
            $sum->UL($sum->UL + 1);
            last;
          }
        }
      }
      
      # unmatch(Message)
      # --------------------------------------------------
      if($match == 0){
        for($o=0; $o<@$old_list_ref; $o++){
          my $old_RASF_WM =  @$old_list_ref[$o]->RASF_WM;
          my $old_RASFLW_ =  @$old_list_ref[$o]->RASFLW_;
             $old_RASF_WM =~ s/$dummy//g;
             $old_RASFLW_ =~ s/$dummy//g;
          
          if(($new_RASF_WM ne $old_RASF_WM) && ($new_RASFLW_ eq $old_RASFLW_)){
            $template[$t] = column->new();
            $template[$t] = @$new_ele_ref[$n];
            $template[$t]->J(@$old_ele_ref[$o]->J);
            $template[$t]->G(@$old_ele_ref[$o]->G);
            $template[$t]->O(@$old_ele_ref[$o]->O);
            $template[$t]->C("unmatch(Message)"  );
            $match = 1;
            $t++;
            $sum->UM($sum->UM + 1);
            last;
          }
        }
      }
      
      # unmatch(Message, Line:?)
      # --------------------------------------------------
      if($match == 0){
        my @old_row = ();
        for (my $o=0; $o<@$old_list_ref; $o++){
          my $old_LINE    =  @$old_list_ref[$o]->LINE   ;
          my $old_RASF_W_ =  @$old_list_ref[$o]->RASF_W_;
             $old_LINE    =~ s/$dummy//g;
             $old_RASF_W_ =~ s/$dummy//g;

          if($new_RASF_W_ eq $old_RASF_W_){
            push(@old_row, $o);
            $match = 1;
          }
        }
        if($match == 1){
          my $num      = pickup_unmatch_line(@$new_list_ref[$n], $old_list_ref, $old_ele_ref, \@old_row);
          my $old_LINE = @$old_list_ref[$num]->LINE;
             $template[$t] = column->new();
             $template[$t] = @$new_ele_ref[$n];
             $template[$t]->J(@$old_ele_ref[$num]->J);
             $template[$t]->G(@$old_ele_ref[$num]->G);
             $template[$t]->O(@$old_ele_ref[$num]->O);
             $template[$t]->C("unmatch(Message, Line;". abs($new_LINE - $old_LINE).")");
             $t++;
             $sum->UML ($sum->UML + 1);
        }
      }
       
      # unmatch(File)
      # --------------------------------------------------
      if($match == 0){
        for(my $o=0; $o<@$old_list_ref; $o++){
          my $old_RAS____ =  @$old_list_ref[$o]->RAS____;
             $old_RAS____ =~ s/$dummy//g;
        
          if($new_RAS____ eq $old_RAS____ ){
            $template[$t] = column->new();
            $template[$t] = @$new_ele_ref[$n];
            $template[$t]->J("");
            $template[$t]->G("");
            $template[$t]->O("");
            $template[$t]->C("unmatch(File)");
            $t++;
            $match = 1;
            $sum->UF($sum->UF + 1);
            last;
          }
        }
      }

      # No match
      # --------------------------------------------------
      if($match == 0){
        $template[$t] = column->new();
        $template[$t] = @$new_ele_ref[$n];
        $template[$t]->J("");
        $template[$t]->G("");
        $template[$t]->O("");
        $template[$t]->C("No match");
        $t++;
        $match = 1;
        $sum->NM($sum->NM + 1);
      }
    }
    return (\@template, \$sum); 
  }
  
  # レポート間の比較とマージ
  sub merge_result{
    my ($new_list_ref, $old_list_ref, $new_ele_ref, $old_ele_ref) = @_;
    my $sum = summary->new();
    $sum->PM (0);
    $sum->UM (0);
    $sum->UL (0);
    $sum->UML(0);
    $sum->UF (0);
    $sum->NM (0);
    
    for (my $n=0; $n<@$new_list_ref; $n++){
      my $msg;
      my $new_LINE    = @$new_list_ref[$n]->LINE   ;
      my $new_RASFLWM = @$new_list_ref[$n]->RASFLWM;
      my $new_RASFLW_ = @$new_list_ref[$n]->RASFLW_;
      my $new_RASF_WM = @$new_list_ref[$n]->RASF_WM;
      my $new_RASF_W_ = @$new_list_ref[$n]->RASF_W_;
      my $new_RAS____ = @$new_list_ref[$n]->RAS____;
      my $match       = 0;
      
      # perfect_match
      # --------------------------------------------------
      for (my $o=0; $o<@$old_list_ref; $o++){
        my $old_RASFLWM =  @$old_list_ref[$o]->RASFLWM;
           $old_RASFLWM =~ s/$dummy//g;
        
        if($new_RASFLWM eq $old_RASFLWM){
          @$new_ele_ref[$n]->J(@$old_ele_ref[$o]->J);
          @$new_ele_ref[$n]->G(@$old_ele_ref[$o]->G);
          @$new_ele_ref[$n]->O(@$old_ele_ref[$o]->O);
          @$new_ele_ref[$n]->N(@$old_ele_ref[$o]->N);
          @$new_ele_ref[$n]->C("perfect matching"  );
          $match = 1;
          $sum->PM($sum->PM + 1);
          last;
        }
      }

      # unmatch(Line:?)
      # --------------------------------------------------
      if($match == 0){
        my @old_row = ();
        for (my $o=0; $o<@$old_list_ref; $o++){
          my $old_LINE    =  @$old_list_ref[$o]->LINE   ;
          my $old_RASF_WM =  @$old_list_ref[$o]->RASF_WM;
          my $old_RASFLW_ =  @$old_list_ref[$o]->RASFLW_;
             $old_LINE    =~ s/$dummy//g;
             $old_RASF_WM =~ s/$dummy//g;
             $old_RASFLW_ =~ s/$dummy//g;
        
          if(($new_RASF_WM eq $old_RASF_WM) && ($new_RASFLW_ ne $old_RASFLW_)){
            push(@old_row, $o);
            $match = 1;
          }
        }
        if($match == 1){
          my $num      = pickup_unmatch_line(@$new_list_ref[$n], $old_list_ref, $old_ele_ref, \@old_row);
          my $old_LINE = @$old_list_ref[$num]->LINE;
             @$new_ele_ref[$n]->J(@$old_ele_ref[$num]->J);
             @$new_ele_ref[$n]->G(@$old_ele_ref[$num]->G);
             @$new_ele_ref[$n]->O(@$old_ele_ref[$num]->O);
             @$new_ele_ref[$n]->N(@$old_ele_ref[$num]->N);
             @$new_ele_ref[$n]->C("unmatch(Line:". abs($new_LINE - $old_LINE) .")");
             $sum->UL ($sum->UL + 1);
        }
      }

      # unmatch(Message)
      # --------------------------------------------------
      if($match == 0){
        for (my $o=0; $o<@$old_list_ref; $o++){
          my $old_RASF_WM =  @$old_list_ref[$o]->RASF_WM;
          my $old_RASFLW_ =  @$old_list_ref[$o]->RASFLW_;
             $old_RASF_WM =~ s/$dummy//g;
             $old_RASFLW_ =~ s/$dummy//g;
          
          if(($new_RASF_WM ne $old_RASF_WM) && ($new_RASFLW_ eq $old_RASFLW_)){
            @$new_ele_ref[$n]->J(@$old_ele_ref[$o]->J);
            @$new_ele_ref[$n]->G(@$old_ele_ref[$o]->G);
            @$new_ele_ref[$n]->O(@$old_ele_ref[$o]->O);
            @$new_ele_ref[$n]->N(@$old_ele_ref[$o]->N);
            @$new_ele_ref[$n]->C("unmatch(Message)"  );
            $match = 1;
            $sum->UM($sum->UM + 1);
            last;
          }
        }
      }
      
      #unmatch(Message. Line:?)
      # --------------------------------------------------
      if($match == 0){
        my @old_row = ();
        for (my $o=0; $o<@$old_list_ref; $o++){
          my $old_LINE    =  @$old_list_ref[$o]->LINE   ;
          my $old_RASF_W_ =  @$old_list_ref[$o]->RASF_W_;
             $old_LINE    =~ s/$dummy//g;
             $old_RASF_W_ =~ s/$dummy//g;
          
          if($new_RASF_W_ eq $old_RASF_W_){
            push(@old_row, $o);
            $match = 1;
          }
        }
        if($match == 1){
          my $num      = pickup_unmatch_line(@$new_list_ref[$n], $old_list_ref, $old_ele_ref, \@old_row);
          my $old_LINE = @$old_list_ref[$num]->LINE;
          @$new_ele_ref[$n]->J(@$old_ele_ref[$num]->J);
          @$new_ele_ref[$n]->G(@$old_ele_ref[$num]->G);
          @$new_ele_ref[$n]->O(@$old_ele_ref[$num]->O);
          @$new_ele_ref[$n]->N(@$old_ele_ref[$num]->N);
          @$new_ele_ref[$n]->C("unmatch(Message. Line;". abs($new_LINE - $old_LINE).")");
          $sum->UML($sum->UML + 1);
        }
      }
      
      # unmatch(File)
      # --------------------------------------------------
      if($match == 0){
        for (my $o=0; $o<@$$old_list_ref; $o++){
          my $old_RAS____ =  @$old_list_ref[$o]->RAS____;
             $old_RAS____ =~ s/$dummy//g;
          if($new_RAS____ eq $old_RAS____ ){
            @$new_ele_ref[$n]->J("");
            @$new_ele_ref[$n]->G("");
            @$new_ele_ref[$n]->C("unmatch(File)");
            $match = 1;
            $sum->UF($sum->UF + 1);
            last;
          }
        }
      }
      # nomatch
      # --------------------------------------------------
      if($match == 0){
            @$new_ele_ref[$n]->J("");
            @$new_ele_ref[$n]->G("");
            @$new_ele_ref[$n]->C("No match");
            $match = 1;
            $sum->NM($sum->NM + 1);
      }
    }
      return \$sum; 
  }
  
  # 候補(old_list)と比較対象(new_list)のDiffをとりライン番号の差が少ない要素番号を出力する。
  # 連想配列$dif_line)の構成 ハッシュKey=要素番号(old_row_ref) / ハッシュData=ライン番号のDiff結果
  sub pickup_unmatch_line{
    my ($new_list, $old_list_ref, $old_ele_ref, $old_row_ref) = @_;
    my %diff_line = ();
    
    foreach(@$old_row_ref){
      $diff_line{$_} = abs($new_list->LINE - @$old_list_ref[$_]->LINE);
    }
    # ハッシュDataを昇順(0,1, 2.. -)にソートしハッシュKeyを配列@row) に格納
    # ⇒配列 (@row) の先頭がライン番号の差が最も少ない要素番号
    # (注意)ライン番号の差分結果(ハッシュData) が同じ場合、要素番号の順は不明
    #       ⇒仕様から順不同になる結果は起こりえないと思われる。
    my @row = sort {$diff_line{$a} <=> $diff_line{$b}} keys %diff_line;
    
    return $row[0];
  }
  
  # 比較用ワード生成
  sub make_list{
    my ($ele_ref) = @_;
    my @list = list->new();
    
    for(my $r=0; $r<@$ele_ref; $r++){
      my $R = @$ele_ref[$r]->R;
      my $A = @$ele_ref[$r]->A;
      my $S = @$ele_ref[$r]->S;
      my $F = @$ele_ref[$r]->F;
      my $L = @$ele_ref[$r]->L;
      my $W = @$ele_ref[$r]->W;
      my $M = @$ele_ref[$r]->M;
      
      foreach(@rep){
        my $rs = $_->s; # 検索ワード
        my $rr = $_->r; # 置換ワード
        $R =~ s/$rs/$rr/g;
        $A =~ s/$rs/$rr/g;
        $S =~ s/$rs/$rr/g;
        $F =~ s/$rs/$rr/g;
        $L =~ s/$rs/$rr/g;
        $W =~ s/$rs/$rr/g;
        $M =~ s/$rs/$rr/g;
      }
      # 例外処理用置換
        $L =~ s/[^0-9]+/0/g;
      
      $list[$r] = list->new();
      $list[$r]->LINE   ($L                  );
      $list[$r]->RASFLWM($R.$A.$S.$F.$L.$W.$M); # perfect matching
      $list[$r]->RASFLW_($R.$A.$S.$F.$L.$W   ); # unmatch(Message)
      $list[$r]->RASF_WM($R.$A.$S.$F.$W.$M   ); # unmatch(Line:?)
      $list[$r]->RASF_W_($R.$A.$S.$F.$W      ); # unmatch(Message, Line:?)
      $list[$r]->RAS____($R.$A.$S            ); # unmatch(File)
    }
      return \@list;
  }

  # レポートの読み込み
  sub fetch{
    my($file_name) = @_;
    my @fetch_data = ();
    open(my $fd, "< $file_name");
    foreach(<$fd>){
      push(@fetch_data, decode( 'UTF-8', $_));
    }
    close($fd);
    return \@fetch_data;
  }
  
  # Analysis reportを整形し要素毎に整理
  sub get_analysis{
    my ($report_ref) = @_;
    my @ele      = column->new();
    my @join_row = ();
    my $row      = 0;
    my $head     = 0;
    my $col      = 0;
    my $next_flg = 0;
    
    foreach(@$report_ref){
      $_ =~ s/\r\n|\r|\n//g;
      $_ =~ s/\t\t/\t$dummy\t/g; # 列合わせ
      my @split_row = split(/\t/, $_);

      # セル内改行の除去
      $next_flg = join_excel_line(\@split_row, \@join_row, $next_flg);
      if( $next_flg == 1){ next; }
      
      # Title Search(行 + 列)
      # --------------------------------------------------
      if($head == 0){
        $col = 0;
        foreach(@join_row){
          if($_ =~ /^ID$/){ $head = 1; last; }
          else            { $col++;          }
        }
      }
      # get report
      # --------------------------------------------------
      else{
        # 未定義(値が無い) 場合、次行を取
        unless(defined $join_row[$col+ 0]){ next; }
        
        # 空行の場合、次行を取得
        if($join_row[$col+ 0] !~ /^\[/){ next; }
        
        my $ele_num = @join_row;
        $ele[$row] = column->new();
        if(defined $join_row[$col+ 0]){ $ele[$row]->I($join_row[$col+ 0]); }
        else                          { $ele[$row]->I("");                 }
        
        if(defined $join_row[$col+ 1]){ $ele[$row]->R($join_row[$col+ 1]); }
        else                          { $ele[$row]->R("");                 }
        
        if(defined $join_row[$col+ 2]){ $ele[$row]->A($join_row[$col+ 2]); }
        else                          { $ele[$row]->A("");                 }
        
        if(defined $join_row[$col+ 3]){ $ele[$row]->S($join_row[$col+ 3]); }
        else                          { $ele[$row]->S("");                 }
        
        if(defined $join_row[$col+ 4]){ $ele[$row]->F($join_row[$col+ 4]); }
        else                          { $ele[$row]->F("");                 }
        
        if(defined $join_row[$col+ 5]){ $ele[$row]->L($join_row[$col+ 5]); }
        else                          { $ele[$row]->L("");                 }
        
        if(defined $join_row[$col+ 6]){ $ele[$row]->W($join_row[$col+ 6]); }
        else                          { $ele[$row]->W("");                 }
        
        if(defined $join_row[$col+ 7]){ $ele[$row]->M($join_row[$col+ 7]); }
        else                          { $ele[$row]->M("");                 }
        
        if(defined $join_row[$col+ 8]){ $ele[$row]->J($join_row[$col+ 8]); }
        else                          { $ele[$row]->J("");                 }
        
        if(defined $join_row[$col+ 9]){ $ele[$row]->G($join_row[$col+ 9]); }
        else                          { $ele[$row]->G("");                 }
        
        if(defined $join_row[$col+10]){ $ele[$row]->C($join_row[$col+10]); }
        else                          { $ele[$row]->C("");                 }
        
        if(defined $join_row[$col+11]){ $ele[$row]->N($join_row[$col+11]); }
        else                          { $ele[$row]->N("");                 }
        
        if(defined $join_row[$col+12]){
          my @split_ary = splice @join_row, $col+12, $ele_num+12;
          $ele[$row]->O(join "\t", @split_ary);
        }
        else {
          $ele[$row]->O("");
        }
        $row++;
      }
    @join_row = (); # クリア
    }
    return \@ele;
  }

  # セル内改行を除去flg有効時に次の行をロード)
  sub join_excel_line{
    my ($row_ref, $join_ref, $flg) = @_;
    
    foreach(@$row_ref){
      if   ($_ =~ /".*"/ ){ $flg = 0; } # セル内でCloseしている"~"は例外
      elsif($_ =~ /^".*$/){ $flg = 1; } # セル内改行開始
      elsif($_ =~ /"$/   ){ $flg = 0; } # セル内改行終了
      
      $_ =~ s/\r\n|\r|\n//g;             # 改行コード削除
      $join_msg = $join_msg . $_;        # セル内文字列結合
      
      if($flg == 0){
        push (@$join_ref, $join_msg);
        $join_msg ="";
      }
    }
    return $flg;
  }
  
  # SpyGlass reportを整形し要素毎に整理
  sub get_spyglass{
    my ($report_ref, $file_name) =@_;
    my @p   = posi->new();
    my @ele = column->new();
    my $row = 0;
    
    foreach(@$report_ref){
      if($_ =~ /^\[|^ID/){
        if($_ =~ /^ID/){
          $p[0] = posi->new(); $p[0]->s(index($_, "ID"      , 0));
          $p[1] = posi->new(); $p[1]->s(index($_, "Rule"    , 0));
          $p[2] = posi->new(); $p[2]->s(index($_, "Alias"   , 0));
          $p[3] = posi->new(); $p[3]->s(index($_, "Severity", 0));
          $p[4] = posi->new(); $p[4]->s(index($_, "File"    , 0));
          $p[5] = posi->new(); $p[5]->s(index($_, "Line"    , 0));
          $p[6] = posi->new(); $p[6]->s(index($_, "Wt"      , 0));
          $p[7] = posi->new(); $p[7]->s(index($_, "Message" , 0));
          
          $p[0]->e($p[1]->s - $p[0]->s - 1);
          $p[1]->e($p[2]->s - $p[1]->s - 1);
          $p[2]->e($p[3]->s - $p[2]->s - 1);
          $p[3]->e($p[4]->s - $p[3]->s - 1);
          $p[4]->e($p[5]->s - $p[4]->s - 1);
          $p[5]->e($p[6]->s - $p[5]->s - 1);
          $p[6]->e($p[7]->s - $p[6]->s - 1);
          $p[7]->e(1000);
        }
        else{
          $_ =~ s/\r|\n//g;
          $ele[$row] = column->new();
          $ele[$row]->I(substr($_, $p[0]->s, $p[0]->e));
          $ele[$row]->R(substr($_, $p[1]->s, $p[1]->e));
          $ele[$row]->A(substr($_, $p[2]->s, $p[2]->e));
          $ele[$row]->S(substr($_, $p[3]->s, $p[3]->e));
          $ele[$row]->F(substr($_, $p[4]->s, $p[4]->e));
          $ele[$row]->L(substr($_, $p[5]->s, $p[5]->e));
          $ele[$row]->W(substr($_, $p[6]->s, $p[6]->e));
          $ele[$row]->M(substr($_, $p[7]->s, $p[7]->e));
          $ele[$row]->J("");
          $ele[$row]->G("");
          $ele[$row]->C("");
          $ele[$row]->N($file_name);
          $row++;
        }
      }
    }
    @p = (); #メモリ開放
    return \@ele;
  }

  # エラー発生個所の特定
  sub error_hundle{
    my $call_func_name = (caller 1)[3];
    print "[Error] Target Funetion->". $call_func_name."\n";
    exit (1);
  }

Written with StackEdit.

0 件のコメント: