我有一个如下所示的函数调用:
Send(0x39,((rLoss>>8)&0xFF),(rLoss&0xFF) );
我想将此函数转换为指针传递。我写了两个像
的宏BYTE0(var) ((uint8_t *)&var)
BYTE1(var) ((uint8_t)&var)+1)
我希望结果是
Send(0x39,BYTE1(rLoss),BYTE0(rLoss) );
你能帮我在perl做这件事吗...谢谢....
答案 0 :(得分:1)
我认为调用的第一个参数是总是一个十六进制数,不需要检查或转换。我还假设args 2和3总是与0xFF进行AND运算。最后,我假设被调用的函数和被移位的参数是简单的单词 - 即匹配\w+
。有了这些假设,以下似乎可以做你想做的事情;
use v5.12;
while (<>) {
chomp ;
if (/ ^ (\w+) \( .* \) \s* ; $ /x) {
my $call = $1 ; # function name being called
s/ ^ \w+ \( //x ; # Strip off fn call and open paren
s/ \) \s* ; \s* $ //x ; # Strip off close paren and semicolon
my ($arg1 , $arg2 , $arg3) = split ',' ; # split into arguements of the call
my $new_args = join("," , $arg1 , transform($arg2) , transform($arg3)) ;
say "$call($new_args );" ;
}
else {
say $_ ;
}
}
sub transform {
$_ = shift ;
my $replacement ;
s/ ^ \s* \( //x; # Strip off opening paren
s/ \) \s* $ //x; # Strip off closing paren
s/ & 0xFF $ //x ; # Strip off ANDing all ones
if (/^ \w+ $/x) { # Simple var name left?
$replacement = "BYTE0(" . $_ . ")" ;
}
elsif (/ ^ \( (\w+) >> (\d+) \) $ /x) { # var name shifted some number of bits
my $var_name = $1 ;
my $shift_size = $2 ;
my $byte_num = $shift_size / 8 ;
$replacement = "BYTE" . $byte_num . "(" . $var_name . ")" ;
}
else {
warn "Dont understand '$_' on line $.\n";
$replacement = $_ ;
}
return $replacement
}
其unix过滤器样式 - 在STDIN上输入,在STDOUT上转换输出。当我喂它时,这就组成了数据;
hello
Send(0x39,((rLoss>>8)&0xFF),(rLoss&0xFF) );
world
Receive(0x12,(rWin&0xFF),((rWin>>16)&0xFF) );
bye
吐出来
hello
Send(0x39,BYTE1(rLoss),BYTE0(rLoss) );
world
Receive(0x12,BYTE0(rWin),BYTE2(rWin) );
bye
希望内联注释解释代码。关于是否尝试改变线路或不管它的决定仅仅基于第一个正则表达式 - 一个单词(fn调用)后跟括号中的内容 - 这可能是也可能不是你想要的。也许你知道它总是调用“发送”,在这种情况下你可以把它放在正则表达式中。
你可能不熟悉的另一件事是整数除法运算符'/'。这用于转换被移位到BYTE num宏调用的位数。