perl的数据结构

 不论使用什么语言来设计程序,数据结构都不能忽视,因为数据结构是你整个程序的基础元素。

使用PERL相对与其他的语言而言,数据的定义似乎更加容易。因为PERL里面的数据类型似乎只有3种表现形式:标量,数组,hash.标量不用说,是最简单和基本的形式,数组和hash则相对复杂和强大一些。一般而言,使用数组可以实现类似堆栈、队列、链表之类的数据结构,而hash则可以实现记录、查询表、或者更为复杂的结构。

参考:

(1)perl数据结构:http://blog.sina.com.cn/s/blog_4be5711f01018fgj.html

                                http://nightsailer.com/2008/03/14/225.html#more-225

(2)perl实例精解 11章 子例程与函数:http://www.alexhe.net/post/14.html


1、结构体:(用哈希实现)

#!/usr/bin/perl -w
use strict;
               
use Clone qw/clone/;
use Data::Dumper;
                
my %center_point = 
{
x => undef,
y => undef,
dx => undef,
dy => undef
};
               
my %mycp;
&center_point_init(\%mycp);
print  Dumper %mycp;
               
sub center_point_init
{
my ($param) = @_;
my %cp = %center_point;
$cp{x} = 1;
$cp{y} = 2;
$cp{dx} = 10;
$cp{dy} = 20;
%$param = %cp; #传递哈希的引用,以改变指向哈希的值
#print Dumper %cp;
}


2、复杂数据结构:

二维数组:my @twoArr = ([1,"a"],[2,"b"]);

Hash的数组:my @hashArr =(%hash1,%hash2);

数组的Hash:my %arrHash = {@arr1,@arr2);

Hash的Hash:my %arrHash = {%hash1,%hash2);


#标量、perl数组、hash的几个特点:

#1)长度是动态的,可以任意增加/删除其元素;对超出数组长度的下标的元素赋值,数组的长度就会改变,仅引用则数组长度不变;

#2)perl进行内存管理,不需用户进行内存操作(对不用的变量和元素删除,会减小内存开销);

#3)子程序传递时,数组/hash一般传其引用,开销小且可以改变其值;

#4)hash可作为结构体使用,定义前需约定好变量名称(如%center_point );且最好不要在使用中,对其元素进行增删操作;

#5)Hash的数组复杂的数据结构作为形参传递时,其实本质还是数组;

#6)Hash数组:my @arrHash 的使用:$arrHash[$i]->{key};$arrHash[$i]{key};${$arrHash[$i]}{key}; 三种方式均OK,推荐第一种。

#hash与其引用
my %hash = (
k1=>"v1",
k2=>"v2");
my $phash = \%hash;
               
print $hash{k1},"\n";
print $phash->{k1},"\n";
print ${$phash}{k1},"\n";

#7)(个人理解,不知正确与否)标量没有赋值,可直接作为数组或hash的引用,但使用中必须保持一致,不能既作数组的引用,又作hash的引用。

       所以Hash数组作为形参时,是不需要在前面定义好数组中的每个hash元素的;也不必对某个欲当作Hash引用的标量进行Hash实体赋值。当然,使用前仍需要注意对其初始化。

#标量没有赋值,直接作为数组/hash的引用
my $param;
$param->[8]=200;
#$param->{good} = "ok";
#Hash的数组
use Clone qw/clone/;
my %hashGroup=
(
    name=>undef
);
             
#初始化"Hash的数组"$param_arrHash:元素$param_hash,大小:$param_size。
sub arrHashGroupInit
{
my ($param_arrHash,$param_hash,$param_size) = @_;
    for(my $i=0;$i<$param_size;$i++)
   {
        my  %hash_temp = %hashGroup;
        ${$param_arrHash}[$i] = \%hash_temp;
foreach my $key (keys(%$param_hash))
{
${$param_arrHash}[$i]->{$key} = "init".$i; #初始化hash
}
   }
}
my @arrHashGroup;
arrHashGroupInit(\@arrHashGroup,\%hashGroup,10);
             
print $#arrHashGroup,"\n"; #9
print $arrHashGroup[3]->{name},"\n"; #init3

#8) padre IDE编译perl,有时存在忽略某一代码行(非注释行)的情况,当出现比较怪异的事情时,可能是由此导致的。原因可能是,utf-8的pl文件解析出该行为注释行;此问题容易出现在“#”注释行的下一代码行。


3、perl哈希hash的常见用法介绍:http://www.jb51.net/article/33905.htm

Perl学习之哈希 hash:http://linux.chinaunix.net/techdoc/net/2008/07/06/1015218.shtml

perl中数组初始化:http://blog.163.com/qin_kexin@126/blog/static/7915547820122144582883/

Perl – 打印哈希:http://tech.mclarian.com/a/252

#hash遍历打印
my %ghash=(
    k1 => "v1",
    k2 => "v2",
    );
             
#1
print Dumper(\%ghash);
#2。推荐
foreach my$key (keys(%ghash)){
    print "$key = $ghash{$key} \n";
}
#3.使用each有风险
while(my ($key,$value) = each(%ghash))
{
    print "$key = $value \n";
}
#常量
use constant {
        LOG_NULL=>0,
        LOG_ERR=>1,
        LOG_WARNING=>2,
        LOG_DEBUG=>4,
        LOG_INFO=>8
        };

4、ttcn脚本用例转csv用例表:

#!/usr/bin/perl -w
################################################
use strict;
use Clone qw/clone/;
use Data::Dumper;
use Time::HiRes qw(gettimeofday usleep);
################################################
#Description:从TTCN语言的测试用例脚本,根据t2e.cfg中配置规则,生成与脚本对应的excel用例表。
#t2e.cfg与testcase_3mp_file,必须为ANSI编码格式.
#:usage: ttcn2excel.pl [-d] testcase_3mp_file
#:filename 输入用例3mp文件
#-d:调试打印。
#eg: ttcn2excel.pl -d testcase.3mp
################################################
use constant {  NULL_TYPE=>0,
        NOTES_TYPE=>1,
        GROUP_TYPE=>10,
        CASE_TYPE=>11,
        CASE_CODE_TYPE=>12,
        CASE_HEAD_TYPE=>13,
         
        LOG_NULL=>0,
        LOG_ERR=>1,
        LOG_WARNING=>2,
        LOG_DEBUG=>4,
        LOG_INFO=>8
        };
         
my $g_log_level = LOG_ERR; 
#my ($start_sec, $start_usec) = gettimeofday;
 
 
my %g_keys_index = (
    line_num => 10,
    group_id => 1,
    group_level_start => 2, # defined for $group_comment.
    case_id => -1, # 7
    p_case_head_arr => 0 # NoUsed.defined for %case_head:"{testcasename:}=>5";
        );
 
&ttcn2excel();
 
##############################################################
 
 
#单行的属性描述信息
my %lineInfo=
(
    type=>undef,       #TYPE
    note_left_cnt=>undef,  #有效"/*"的个数
    note_right_cnt=>undef,  #“*/”
    scale_left_cnt=>undef,  #有效"{"的个数
    scale_right_cnt=>undef,  #“}”
    pElem=>undef
);
 
my %keyv=
(
    key=>undef,
    value=>undef,
    pos=>undef,
    match=>undef
);
 
my %hashGroup=
(
    id=>undef,
    level=>undef,
    pos_start=>undef,
    pos_end=>undef
);
 
my %hashCase=
(
    id=>undef,
    level=>undef,
    pos_start=>undef,
    pos_end=>undef,
    head=>undef
);
 
#初始化"Hash的数组"$param_arrHash:元素$param_hash,大小:$param_size
sub arrHashGroupInit
{
=pos
    my ($param_arrHash,$param_hash,$param_size) = @_; #(\@out_arr,\%in_hash,\$in_var);
    for(my $i=0;$i<$param_size;$i++)
   {
         my  %hash_temp =  %hashGroup;
        ${$param_arrHash}[$i] = \%hash_temp;
        foreach my $key (keys(%$param_hash))
        {
            ${$param_arrHash}[$i]->{$key} = 0; #初始化hash
        }
             
   }
=cut
}
 
#打印"Hash"
sub arrHashPrint
{
    my ($param_Hash) = @_; #(\%in_hash);
    foreach my $key (keys(%{$param_Hash}))
    {
        print "$key = $param_Hash->{$key}\n";
    }
}
             
#打印"Hash的数组"
sub arrHashGroupPrint
{
    my ($param_arrHash) = @_; #(\@out_arr);
    for(my $i=0;$i<$#{$param_arrHash}+1;$i++)
   {        
        arrHashPrint(\%{${$param_arrHash}[$i]});            
   }
}
 
 
# $g_log_level;
#my $PF_LOG_OUT;
sub debug_print
{
    my ($log_level,@param) = @_;
    if($log_level <= $g_log_level)
    {
        print @param;
        print PF_LOG_OUT @param;
    }
}
 
 
#输出csv。
#my $PF_CSV_OUT;
sub print_out_init
{
    my ($FileOut) = @_; # ($FileOutName)
    open(PF_CSV_OUT,">$FileOut") or die "[ERROR].can not open csv_outfile:$FileOut\n";
     
    my $logFileOut = "c:\\ttcn2excel.log";
    open(PF_LOG_OUT,">$logFileOut") or die "[ERROR].can not open log_outfile:$logFileOut\n";
}
sub print_out
{
    my (@param) = @_;
    print PF_CSV_OUT @param;
}
 
sub print_out_terminate
{
    close(PF_CSV_OUT);
    close(PF_LOG_OUT);
}
##############################################################
sub ttcn2excel()
{
    my $FileIn = "test.3mp";
    my $FileOut = "ttcn2excel.csv";
    my $FileStandConf = "t2e.cfg";
     
    my $RegExp = "";
    my $RegMode = 0; 
    my $RegNumId = -1; 
     
    my $params_num = 0;
     
#=pod
    if(@ARGV < 1)
    {
        print "usage: ttcn2excel.exe [-d] testcase_3mp_file\n";
        exit;
    }
     
    for(my $i=0; $i < @ARGV; $i++)
    {
        if("-d" eq $ARGV[$i])
        {
            $g_log_level = LOG_INFO;
            $i++;
        }
        elsif("-o" eq $ARGV[$i])
        {
            #$FileOut = $ARGV[$i];
            #$i++;
        }
        else
        {
            $FileIn = $ARGV[$i];            
        }
    }
 
#=cut
    #open infile and outfile.
    open(PF_IN,"<$FileIn") or die "[ERROR].can not open infile:$FileIn\n";
    open(PF_CONF,"<$FileStandConf") or die "[ERROR].can not open configure file:$FileStandConf\n";
    #open(PF_OUT,">$FileOut") or die "error.can not open outfile:$FileOut\n";
     
    my @arrTtcnIn = <PF_IN>;
    my @arrConf = <PF_CONF>;
    my @Words =("#outtitle","#sys","#head","#body");
    my @kv = ("k=","v=");   
    my $Outtitle="";
    my @arrOuttitle = ();   
    my @arrHashSyskeys = (); #[0]=group and [1]=testcase
    my @arrHashCasehead = ();
    my @arrHashCasebody = ();
    my @arrTtcnLineInfo = ();
     
    close(PF_IN);
    close(PF_CONF);
    #arrHashGroupInit(\@arrHashSyskeys,\%keyv,10);
    #arrHashGroupInit(\@arrHashCasehead,\%keyv,100);    
    #arrHashPrint(\%{$arrHashSyskeys[0]});
     
    #cost time and print_out init.
    my $first_time = time();
    print_out_init($FileOut);   
     
       #read template from $FileStandConf = "t2e.cfg".
        my $p_ref_arrHash;
    my $ConfWords_flag =0;
    my $cnt=0;
    for(my $i=0;$i<@arrConf;$i++)
    {
         chomp $arrConf[$i];
         if($arrConf[$i] =~ /\s*$Words[0]/ and 0 == $ConfWords_flag)  #"#outtitle"
         {
            $i++;
            $Outtitle = $arrConf[$i];
            chomp $Outtitle;
            #$Outtitle =~ s/\s+//g;
            @arrOuttitle = split(",",$Outtitle);
         }
         elsif($arrConf[$i] =~ /\s*$Words[1]/)  #"#sys"
         {
            $ConfWords_flag =1;
            $p_ref_arrHash  = \@arrHashSyskeys;
            $cnt=0;
         }
         elsif($arrConf[$i] =~ /\s*$Words[2]/)  #"#head"
         {
            #"#sys"         
            $ConfWords_flag =2;
            $p_ref_arrHash  = \@arrHashCasehead;
            $cnt=0;
         }
         elsif($arrConf[$i] =~ /\s*$Words[3]/)  #"#body"
         {
            $ConfWords_flag =3;
            $p_ref_arrHash  = \@arrHashCasebody;
            $cnt=0;
         }
         elsif($arrConf[$i] =~ /\s*$kv[0]/ and $ConfWords_flag > 0)  #"k="
         {
             my $key = $arrConf[$i];
             $key =~ s/\s*$kv[0](.*)/$1/; 
             $i++;
             if($arrConf[$i] =~ /\s*$kv[1]/)  #"v="
             {
                my $value = $arrConf[$i];
                chomp($value);
                $value =~ s/\s*$kv[1](.*)/$1/;
                #$p_ref_arrHash->[$cnt]->{$key} = $value; #error. 
                $p_ref_arrHash->[$cnt]->{key} = $key; 
                $p_ref_arrHash->[$cnt]->{value} = $value;         
                $cnt++;             
                #print $key,"=$value\n";
             }
         }       
    }
=pod
    print $#arrHashSyskeys,"\n";    
    print $#arrHashCasehead,"\n";   
    arrHashGroupPrint(\@arrHashSyskeys);
=cut
         
    debug_print  LOG_ERR,"\n******************************************************************************\n";
    debug_print  LOG_ERR,"Input >>\nttcn_file: $FileIn"," LinesNum: ".($#arrTtcnIn+1),"\n\n";
    debug_print  LOG_ERR,"OutTittle >>\n",$Outtitle,"\n\n";
 
    #get the pos of hash_value for arrHashCasehead.
    debug_print  LOG_ERR,"CaseHead >>\n";
    my $match_flag =0;
     for(my $i=0;$i<($#arrHashCasehead+1);$i++) 
     {
        debug_print  LOG_ERR,${$arrHashCasehead[$i]}{key},${$arrHashCasehead[$i]}{value},"\n";
        #debug_print  LOG_ERR,$arrHashCasehead[$i]{key},$arrHashCasehead[$i]{value},"\n";
        #debug_print  LOG_ERR,$arrHashCasehead[$i]->{key},$arrHashCasehead[$i]->{value},"\n";
        $match_flag = 0;
        for(my $j=0;$j<($#arrOuttitle+1);$j++)
        {       
            if( ${$arrHashCasehead[$i]}{value} eq $arrOuttitle[$j])
            {
                ${$arrHashCasehead[$i]}{pos} = $j;
                $match_flag =1;
                last;
            }
        }
        if(1 != $match_flag)
        {
            ${$arrHashCasehead[$i]}{pos} = -1;
            debug_print  LOG_ERR,"[WARNING].This value has no pos in the outtitle","\n";
        }
    }
     
    #get the pos of hash_value for arrHashCasebody.
    debug_print  LOG_ERR,"\nCaseBody >>\n";
     for(my $i=0;$i<($#arrHashCasebody+1);$i++) 
     {
        debug_print  LOG_ERR,$arrHashCasebody[$i]->{key},$arrHashCasebody[$i]->{value},"\n";
        $match_flag = 0;
        for(my $j=0;$j<($#arrOuttitle+1);$j++)
        {       
            if( ${$arrHashCasebody[$i]}{value} eq $arrOuttitle[$j])
            {
                ${$arrHashCasebody[$i]}{pos} = $j;
                $match_flag =1;
                last;
            }
        }
        if(1 != $match_flag)
        {
            ${$arrHashCasebody[$i]}{pos} = -1;
            debug_print  LOG_ERR,"[WARNING].This value has no pos in the outtitle","\n";
        }
    }
     
    #init  %g_keys_index that will be used when outputing.
    $g_keys_index{line_num} = $#arrOuttitle + 1;
    #$g_keys_index{group_id} = ;    
    #$g_keys_index{case_id} = ;
    my $group_match_flag = 0;
    my $testcase_match_flag = 0;    
    for(my $j=0;$j<($#arrOuttitle+1);$j++)
    {       
        if( ${$arrHashSyskeys[0]}{value} eq $arrOuttitle[$j])
        {
            $g_keys_index{group_id} = $j;
            $group_match_flag =1;           
            next;
        }
        elsif( ${$arrHashSyskeys[1]}{value} eq $arrOuttitle[$j])
        {
            $g_keys_index{case_id} = $j;
            $testcase_match_flag =1;            
            next;
        }
    }
     
    if(0 == $group_match_flag)
    {
        debug_print  LOG_ERR,"[ERROR].group of syshead has no pos in the outtitle","\n";
    }   
    if(0 == $testcase_match_flag)
    {
        debug_print  LOG_ERR,"[ERROR].testcase of syshead has no pos in the outtitle","\n";
    }
     
    $g_keys_index{group_level_start} = $g_keys_index{group_id} + 1;
 
    #out csv.
    print_out($Outtitle."\n");
     
    debug_print  LOG_ERR,"\n******************************************************************************\n";
    arrHashGroupInit(\@arrTtcnLineInfo,\%lineInfo,$#arrTtcnIn+1);
    #start to parse.
    findkeyAllLines(\@arrTtcnIn,\@arrTtcnLineInfo,\@arrHashCasehead,\@arrHashCasebody); 
     
     
        #clac cost time
        my $end_time = time() - $first_time;
    debug_print LOG_ERR,"**********************finished.it takes time: $end_time s ****************************\n";
 
    #close filehandle.
    print_out_terminate();  
}
 
##############################################################
#去除某行TTCN语法所有的字符串与注释
sub delLineNotes
{
    my  ($inout_line) =@_; #(\$inout_param)
    #print $in_line;
    $$inout_line =~ s#\".*?\"##g; #去除""
    $$inout_line =~ s#\/\/.*##g; #再去除//
    $$inout_line =~ s#\/\*.*?\*\/##g; #再去除/**/
    $$inout_line =~ s#\/\*.*##g; #再去除/*
    $$inout_line =~ s#.*\*\/##g; #再去除*/
}
 
#识别单行TTCN语法中有效的“/*”、“*/”的个数。
sub findComment
{
    my ($in_line,$p_out_left_cnt,$p_out_right_cnt)=@_; #($in_param1,\$out_param1,\$out_param2);
     
    my $line=$in_line;
    #print $in_line;
    $line =~ s#\".*?\"##g; #去除""
    $line =~ s#\/\/.*##g; #再去除//
     
    $$p_out_left_cnt = 0;
    $$p_out_right_cnt = 0;
     
    my @arr=();
    if(@arr = ($line =~ m#\/\*#g))
    {
        $$p_out_left_cnt = $#arr+1;
    }
     
    if(@arr = ($line =~ m#\*\/#g))
    {
        $$p_out_right_cnt = $#arr+1;
    }
}
 
#识别单行TTCN语法中有效的“{”、“}”的个数。
sub findRangeMark
{
    my ($in_line,$p_out_left_cnt,$p_out_right_cnt)=@_; #($in_param1,\$out_param1,\$out_param2);
     
    my $line=$in_line;
    #print $in_line;
    $line =~ s#\".*?\"##g; #去除""
    $line =~ s#\/\/.*##g; #再去除//
    $line =~ s#\/\*.*?\*\/##g; #再去除/**/
    $line =~ s#\/\*.*##g; #再去除/*
    $line =~ s#.*\*\/##g; #再去除*/
     
    $$p_out_left_cnt = 0;
    $$p_out_right_cnt = 0;
     
    my @arr=();
    if(@arr = ($line =~ /{/g))
    {
        $$p_out_left_cnt = $#arr+1;
    }
     
    if(@arr = ($line =~ /}/g))
    {
        $$p_out_right_cnt = $#arr+1;
    }
}
 
=test findRangeMark
print "{=1 ; }=2 ; {}=3\n";
my $line="dfeaddfae\"{}\"fadd//{}ddddf";
my ($out_flag,$out_flag1) =(18,19);
findRangeMark($line,\$out_flag,\$out_flag1);
print "left: $out_flag right: $out_flag1\n";
=cut
 
#查找某行的testcase_id
sub findLineTestCase
{
    my ($in_line,$out_group_id) = @_; #($in_line,\$out_group_id)
     
    my $line = $in_line;
    delLineNotes(\$line);
     
    $$out_group_id = "";
     
     if(my @arr = ($line =~ m#^\s*testcase\s*(.*?)\s*runs#))
     {
        $$out_group_id = $arr[0];
     }
      
     return $$out_group_id;
}
 
#查找某行的group_id
sub findLineGroup
{
    my ($in_line,$out_group_id) = @_; #($in_line,\$out_group_id)
     
    my $line = $in_line;
    delLineNotes(\$line);
     
    $$out_group_id = "";
     if(my @arr = ($line =~ m#^\s*group\s*(.*?)\s*$#))
     {
        $$out_group_id = $arr[0];
     }
     return $$out_group_id;
}
 
##############################################################
my @g_arr_group_mark;
sub print_group_init
{
    my ($p_arr_group_mark) = @_;
 
    @g_arr_group_mark = @{$p_arr_group_mark};
}
sub str_init
{
    my ($str,$num) = @_;
     
    my $ret = "";
    for(my $i=0;$i<$num;$i++)
    {
        $ret = $ret.$str;
    }
     
    return $ret;
}
#按行输出到csv
sub print_csv
{
    my ($p_in_arr_csv_line) = @_; # (\@ArrCsv)
     
    my $len = $#{$p_in_arr_csv_line}+1;
    my $line="";
    for(my $i=0;$i<$len;$i++)
    {
        my $in_line = ${$p_in_arr_csv_line}[$i];
        $in_line =~ s#"#""#g;  #for the ".
        if(0 ==$i)
        {
            $line = $in_line;
            next;
        }
        $line = $line.','."\"$in_line\""; #add “” for each element of the array.
    }
     
    #add "\n" of the array end.
    $line = $line."\n"; 
     
    #output to csv file.
    print_out $line;
    debug_print LOG_INFO,"[csv_out]:: ",$line,"\n";
}
 
 
#输出Group行   
sub print_csv_group
{
    my ($group_id,$level,$group_comm) = @_; # (\@ArrCsv)    print_cvs_group($group_id,$level,$group_comm);
     
    my  @arrLine;   
    my  %keys_index = %g_keys_index;
    debug_print LOG_INFO,"###print_csv_group ing for ",".... \n";   
    for(my $i=0;$i<$keys_index{line_num};$i++)
    {
        $arrLine[$i] = "";
    }
    $arrLine[0] =  str_init("\.",$level);
    $arrLine[$keys_index{group_id}] = $group_id;
    $arrLine[$keys_index{group_level_start} + $level -1] = $group_comm; 
 
    #output
    print_csv(\@arrLine);   
}
 
#Des:输出用例行
#t2e。cfg与用例中头部关键字描述顺序必须一致。
sub print_csv_case
{
    my ($case_id,$p_in_arr_hash_case_head,$p_in_arr_hash_case_body) = @_;
     
    my  @arrLine;   
    my  %keys_index = %g_keys_index;
    my  $pos_flag = 1;
    debug_print LOG_INFO,"###print_csv_case ing for case_id and ",$#{$p_in_arr_hash_case_head} + 1," keys in case head.... \n";
    for(my $i=0;$i<$keys_index{line_num};$i++)
    {
        $arrLine[$i] = "";  
         
        #查找$i对应的head输出项。
        my $item = -1;
        for(my $j=0;$j<($#{$p_in_arr_hash_case_head} + 1);$j++)
        {
            if($i == $p_in_arr_hash_case_head->[$j]->{pos})
            {
                $item = $j;
                last;
            }
        }       
         
        #找到则输出
        if(-1 != $item)
        {
            $arrLine[$i] = $p_in_arr_hash_case_head->[$item]->{match};
            next;
        }
         
        #查找$i对应的body输出项。
        $item = -1;
        for(my $j=0;$j<($#{$p_in_arr_hash_case_body} + 1);$j++)
        {
            if($i == $p_in_arr_hash_case_body->[$j]->{pos})
            {
                $item = $j;
                last;
            }
        }       
         
        #找到则输出
        if(-1 != $item)
        {
            $arrLine[$i] = $p_in_arr_hash_case_body->[$item]->{match};
            next;
        }
         
    }
     
    $arrLine[0] =  str_init("\.",5);
    if ($keys_index{case_id} >= 0 )
    {
        $arrLine[$keys_index{case_id}] = $case_id;
    }
 
    #output
    print_csv(\@arrLine);   
     
}
 
#Des:在用例对应的头部中,查找关键字的信息
#t2e。cfg与用例中头部关键字描述顺序必须一致。
sub findCaseHead
{
    my ($p_in_arrLines,$p_inout_arrHashCasehead) = @_;  #(\@in_arrLines,\@arrHashCasehead)
     
    my @arrLine = @$p_in_arrLines;
    my @arrHashCaseHead = @$p_inout_arrHashCasehead;
    my @elem_flag; #记录找到的项;
    my $item = -1; #找到的当前项
    my $ret =0;
     
    #init 
    for(my $j = 0;$j<($#arrHashCaseHead+1);$j++)
    {
        $elem_flag[$j] = 0;
        $p_inout_arrHashCasehead->[$j]->{match} = "";
    } 
     
    debug_print LOG_INFO,"###findCaseHead ing for ",$#arrHashCaseHead+1," keys in case head.... \n";                            
    for(my $i=0;$i<($#arrLine+1);$i++)
    {   
        chomp($arrLine[$i]);    
         
        if($arrLine[$i] =~ m#^\s*$#) #空行则跳过。
        {
            next;
        }           
        elsif($arrLine[$i] =~ m#\*/\s*$#) #"*/结束"
        {
            last;
        }
         
        #查找是否为case head中的某key项。找到则输出。   
        my $find_flag = 0;  
        my @arrMatch;
        for(my $j = 0;$j<($#arrHashCaseHead+1);$j++)
        {
            my $expre = $arrHashCaseHead[$j]->{key}."(.*)";          
            if(@arrMatch = ($arrLine[$i] =~ m#$expre#))
            {
                $find_flag = 1;
                $item = $j;
                $elem_flag[$j] = 1;
                $arrMatch[0] =~ s#^\s*##g; #去除前后的空格
                $arrMatch[0] =~ s#\s*$##g;
                $p_inout_arrHashCasehead->[$j]->{match} = $arrMatch[0];
                last;
            }
        }
        if(1 == $find_flag)
        {
            next;
        }       
         
        #续行
        if($item >= 0)
        {
            $arrLine[$i] =~ s#^\s*##g;
            $arrLine[$i] =~ s#\s*$##g;
            $p_inout_arrHashCasehead->[$item]->{match} = $p_inout_arrHashCasehead->[$item]->{match}."\n".$arrLine[$i];          
        }               
    }
     
    for(my $i=0;$i<($#arrHashCaseHead+1);$i++)
    {
        debug_print LOG_INFO,"\[",$p_inout_arrHashCasehead->[$i]->{key},"]>>> ",$p_inout_arrHashCasehead->[$i]->{match},"\n";
    }
     
    for(my $j = 0;$j<($#arrHashCaseHead+1);$j++)
    {
        if(0 == $elem_flag[$j])
        {
            debug_print LOG_ERR, "[ERROR]..can not find: ",$arrHashCaseHead[$j]->{key},"\n";
            $ret = -1;
        }
    }
     
    return $ret;
}
#在整个3mp文件中,查找所有的group、testcase、case_head的信息,并输出到csv。
sub findkeyAllLines
{
    my ($p_in_arr_lines,$p_out_arr_lineInfo,$p_inout_arrHashCasehead,$p_inout_arrHashCaseBody) = @_; #{\@LineArr,\@lineInfo,\@arrHashCasehead,\@arrHashCasebody);
     
    my @arrLines = @{$p_in_arr_lines};
    my $len = $#arrLines + 1;
    my $group_cnt = 0;
    my $group_id = 0;
    my $testcase_cnt = 0;
    my $testcase_id = 0;
     
    my $out_left_cnt;
    my $out_right_cnt;
    my $note_left_sum =0;
    my $note_right_sum =0;
    my $group_range_left_sum =0;
    my $group_range_right_sum =0;
    my $case_range_left_sum =0;
    my $case_range_right_sum =0;
     
    my $testcase_flag = 0;
    my $testcase_output_flag = 0;
    my $group_level = 0;
    my $group_start_range_num = 0;
    my $max_group_level = 0;
    my $group_first_flag = 1;
     
    my %hash_log = (
        last_group_id=>-1,
        last_group_start_line=>-1,
        last_group_end_line=>-1,
        last_testcase_id=>-1,
        last_testcase_start_line=>-1,
        last_testcase_end_line=>-1);
             
    for(my $i=0;$i<$len;$i++)
    {
        chomp $arrLines[$i];
        #debug_print "line:$i  $arrLines[$i]\n";
        $p_out_arr_lineInfo->[$i]->{type} = CASE_CODE_TYPE;   
         
        if($arrLines[$i] =~ m#^\s*//# or $arrLines[$i] =~ m#^\s*$#) #空行或//行
        {
            $p_out_arr_lineInfo->[$i]->{type} = NOTES_TYPE;
            #debug_print "NOTE_1\n";
            next;
        }
        findComment($arrLines[$i],\$out_left_cnt,\$out_right_cnt);
        if($note_left_sum >  $note_right_sum
            and $out_left_cnt > $out_right_cnt)  #for ttcn,filter "/*" betwwen  "/*" and "*/".
        {
            $out_left_cnt = 0;
            $out_right_cnt = 0;
        }
        $note_left_sum += $out_left_cnt;
        $note_right_sum += $out_right_cnt;      
        #TODO:
        if($note_left_sum != $note_right_sum or $out_left_cnt != $out_right_cnt)  #注释行
        {
            $p_out_arr_lineInfo->[$i]->{type} = NOTES_TYPE;
            #debug_print LOG_INFO," $i NOTE_2\n";
            next;
        }       
         
        findRangeMark($arrLines[$i],\$out_left_cnt,\$out_right_cnt);        
         
        if(1 == $testcase_flag )
        {
            $case_range_left_sum += $out_left_cnt;
            $case_range_right_sum += $out_right_cnt;
            if($case_range_left_sum <= $case_range_right_sum)
            {
                $testcase_flag = 0;
                $hash_log{last_testcase_end_line}=$i;
                if(0 == $testcase_output_flag)
                {
                    $p_inout_arrHashCaseBody->[0]->{match} = "";
                    debug_print LOG_ERR,"[ERROR].This case does not set case_body_type.line:$hash_log{last_testcase_start_line} testcase:$hash_log{last_testcase_id}\n";
                }
                print_csv_case($testcase_id,$p_inout_arrHashCasehead,$p_inout_arrHashCaseBody);
                debug_print LOG_INFO,"line:$i case END\n";
                 
                #may be the end of the group.               
                if($case_range_left_sum < $case_range_right_sum) #get the end of group.
                 {
                    my $end_level = ($group_range_left_sum - $group_range_right_sum) - $group_start_range_num;
                    my $end_level2 = $end_level - ($case_range_right_sum - $case_range_left_sum)+1;
                    $hash_log{last_group_end_line}=$i;
                    debug_print LOG_INFO,"\nline:$i the end of group level:\[$end_level - $end_level2]\n";
                 }
                  
                 $group_range_right_sum += ($case_range_right_sum - $case_range_left_sum);
            }
             
            #find case body , output head and body together.
            if(0 == $testcase_output_flag
                and my @arrRet = ($arrLines[$i] =~ m#$p_inout_arrHashCaseBody->[0]->{key}\((.*?),#))
            {
                $p_inout_arrHashCaseBody->[0]->{match} = $arrRet[0];              
                $testcase_output_flag = 1;
            }
                         
#=pos
            #[ERROR].
            my $tmp;
            findLineTestCase($arrLines[$i],\$tmp);
            if("" ne $tmp)
            {
                debug_print LOG_ERR,"[ERROR].line:$i testcase.$testcase_id ";
            }
            findLineGroup($arrLines[$i],\$tmp);
            if("" ne $tmp)
            {
                debug_print LOG_ERR,"[ERROR].line:$i testcase.$testcase_id ";
            }
#=cut
            next;
        }
         
        findLineTestCase($arrLines[$i],\$testcase_id);
        if("" ne $testcase_id)
        {           
            $testcase_cnt++;
            $testcase_flag = 1;
            $testcase_output_flag = 0;
            $case_range_left_sum = $out_left_cnt;
            $case_range_right_sum = $out_right_cnt;
             
            $p_out_arr_lineInfo->[$i]->{type} = CASE_TYPE;                                           
            #$p_out_arr_lineInfo->[$i]->{pElem} = \%{${$p_out_arr_hashCase}[$testcase_cnt]}; #ok
            $p_out_arr_lineInfo->[$i]->{pElem}->{id} = $testcase_id;
            $p_out_arr_lineInfo->[$i]->{pElem}->{pos_start} = $i;
             
            $hash_log{last_testcase_start_line}=$i;
            $hash_log{last_testcase_id}=$testcase_id;
            debug_print LOG_INFO,"\nline:$i testcase:$testcase_id\n";           
             
            #get case_head.
            my $m =$i-1;
            my $n = -1;
            my @arrCaseHeadLines = ();
            for(;$m >= 0;$m--)
            {
                if($arrLines[$m] =~ m#$p_inout_arrHashCasehead->[0]->{key}#i) #找到case_head
                {
                    $n = $m;
                    last;
                }
                elsif($p_out_arr_lineInfo->[$m]->{type} ne NOTES_TYPE)
                {
                    debug_print LOG_ERR,"\n[ERROR].line:$i testcase:$testcase_id.This testcase has no case_head\n";
                    last;
                }               
            }
             
            if(-1 != $n)
            {
                my $len = $i -$n;
                for(my $i_0 = 0;$i_0 < $len;$i_0++)
                {
                    $arrCaseHeadLines[$i_0] = $arrLines[$n+$i_0];
                }   
            }
             
            my $ret = findCaseHead(\@arrCaseHeadLines,$p_inout_arrHashCasehead);
            if(0 != $ret)
            {
                debug_print LOG_ERR,"line:$i testcase:$testcase_id\n";
            }           
             
            #make sure the output of this case even if it has no case_head.
            #print_csv_case($testcase_id,$p_inout_arrHashCasehead);
             
            next;
        }
         
        findLineGroup($arrLines[$i],\$group_id);
        if("" ne $group_id)
        {           
            if(1 == $group_first_flag)
            {
                $group_start_range_num = ($group_range_left_sum - $group_range_right_sum);
                $group_first_flag = 0;
            }
            $group_level = ($group_range_left_sum - $group_range_right_sum) - $group_start_range_num + 1;
            $group_cnt++;           
             
            #get group comment.
            my $group_comm = "";
            my @group_comm0;
            if(@group_comm0 = ($arrLines[$i-1] =~ m#\s*//(.+?)\s*$#))
            {               
                    $group_comm = $group_comm0[0];
            }
            else
            {
                debug_print LOG_ERR,"\n[ERROR].line:$i group:$group_id level:$group_level.This group has no group_comment\n";
            }           
             
            $p_out_arr_lineInfo->[$i]->{type} = GROUP_TYPE;
            #$p_out_arr_lineInfo->[$i]->{pElem} = \${$p_out_arr_hashGroup}[$group_cnt]; #[ERROR].
            $p_out_arr_lineInfo->[$i]->{pElem}->{id} = $group_id;
            $p_out_arr_lineInfo->[$i]->{pElem}->{pos_start} = $i;
            $p_out_arr_lineInfo->[$i]->{pElem}->{level} = $group_level;
             
            $hash_log{last_group_start_line}=$i;
            $hash_log{last_group_id}=$group_id;         
             
            debug_print LOG_INFO,"\nline:$i group:$group_id level:$group_level comment:$group_comm......\n";
            print_csv_group($group_id,$group_level,$group_comm);
        }       
         
         if($out_right_cnt > $out_left_cnt) #get the end of group.
         {
            my $end_level = ($group_range_left_sum - $group_range_right_sum) - $group_start_range_num;
            my $end_level2 = $end_level - ($out_right_cnt - $out_left_cnt)+1;
            $hash_log{last_group_end_line}=$i;
            debug_print LOG_INFO,"\nline:$i the end of group level:[$end_level - $end_level2]\n";
         }       
          
         #freah data stats.
         $group_range_left_sum += $out_left_cnt;
         $group_range_right_sum += $out_right_cnt;      
    }   
     
    debug_print  LOG_ERR,"\n******************************************************************************\n";
    debug_print  LOG_ERR,"last_group: ".$hash_log{last_group_id}." level: $group_level"," line: ".$hash_log{last_group_start_line}.",".$hash_log{last_group_end_line},"\n";
    debug_print  LOG_ERR,"last_testcase: ".$hash_log{last_testcase_id}," line: ".$hash_log{last_testcase_start_line}.",".$hash_log{last_testcase_end_line},"\n";
     
    #
    if($group_range_left_sum != $group_range_right_sum)
    {
        debug_print LOG_ERR,"\@[ERROR].group scacle{} is wrong.\n"; 
    }
     
    debug_print LOG_ERR,"\ngroupTotal: $group_cnt\n";
    debug_print LOG_ERR,"testcaseTotal: $testcase_cnt\n";
     
}


t2e.cfg: >>

#outtitle

序号,group,一级,二级,三级,四级,五级,用例名,自动化类型,步骤,期望,备注


#sys.v must be in the outtitle."group" and "testcase" can not be modified.

k=group

v=一级

k=testcase

v=用例名


#head. keep the right order.defined thd searched item and output position.and it will skip unexisted k-item in the case_heads.

k=@testcase:

v=用例名

k=@teststep:

v=步骤

k=@testexpect:

v=期望


#body. case body.

k=setcaseinfo

v=自动化类型


test.3mp: >>

//COMMENT

group GROUP0 

{

//COMMENT

group GROUP0_1

{

/*

@testcase:CASE0_0

@testste:1、初始化"Init,Control" ;

  2、运行

@testexpect:run ok。

*/

testcase CASE0_0()  runs on

{

    setcaseinfo(true,"");

    {

    }

    // /* */

    /*

    */

} //end of testcase

} // end of group GROUP0_1

} // end of group GROUP0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值