通过指针-perl代码传递值

时间:2017-02-10 03:45:40

标签: perl

我有一个如下所示的函数调用:

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做这件事吗...谢谢....

1 个答案:

答案 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宏调用的位数。