动态替换和删除C代码(使用Perl)

时间:2017-07-03 10:47:55

标签: regex perl dynamic replace

我带着我的问题来找你:动态替换/删除C代码的最佳方法是什么?我已经使用正则表达式在Perl中做了一些事情,并从配置文件中读取了要替换/删除的内容,但我无法使其动态化。

代码:

#autoflush output so it will not interfere with calling application
local $| = 1;
##

#libraries
use warnings;
use strict;
use Switch;
use Cwd;
use File::Find;
##

#global variables
my @config;
my $file;
my $directory;
my $result;
##

if(@ARGV < 1)
{
    $directory = cwd();
}
else
{
    $directory = $ARGV[0];
}
$result = $directory . "\\result";

if(! -d $result)
{
    mkdir ($result);
}

open LOG, ">", $result . "\\log.log";

sub start
{
    my $configFile = $_[0];
    open CONFIG, $configFile;
    local $/;
    my $conf = <CONFIG>;
    close CONFIG;

    foreach my $line (split(/\n\*/, $conf))
    {
        if(index($line, "*") == 0)
        {
            $line = substr($line, 1);
        }
        setConfig($line);
    }
    processFiles();
}

sub setConfig
{
    my $line = $_[0];
    my $count = () = $line =~ /\s*==>\s*/;
    switch($count)
    {
        case 0
        {
            remove($line);
        }
        case 1
        {
            replace($line);
        }
    }
}

sub addSlashes
{
    $_[0] =~ s/([\.\\\/\+\*\?\[\^\]\(\)\{\}\=\!\<\>\|\:\-])/\\$1/xg;
    if($_[1] == 1)
    {
        $_[0] =~ s/([\$])/\\$1/xg;
    }
    return;
}

sub remove
{
    my $line = $_[0];
    addSlashes($line, 1);
    $line =~ s/(\\\$){3}/\.\+/g;
    $config[@config][0] = qr/$line/;
    $config[@config - 1][1] = q("");
    $line = "\\(" . $line . "\\(";
    $config[@config - 1][2] = qr/$line/;
}

sub replace
{
    my $line = $_[0];
    my @split = split(/\s*==>\s*/, $line);
    my $original = $split[0];
    my $replace = $split[1];
    my $regex;
    addSlashes($original, 1);
    addSlashes($replace, 0);

    my $counter = 1;
    while($original =~ /\\\$([\d]{1,3})\\\$/g)
    {
        if($1 <= $counter && $1 > 0)
        {
            $counter++;
        }
        else
        {
            print "Invalid format\n";
            return;
        }
    }

    if($counter == 1)
    {
        $config[@config][0] = qr/$original/;
        $config[@config - 1][1] = q(") . $replace . q(");
        $original = "\\(" . $original . "\\(";
        $config[@config - 1][2] = qr/$original/;
        return;
    }

    while($replace =~ /\$([\d]{1,3})\$/g)
    {
        if($1 <= 0 && $1 >= $counter)
        {
            print "Invalid format\n";
            return;
        }
    }

    $original =~ s/\\\$\d{1,3}\\\$/\(\.\+\?\)/xg;
    $original =~ s/\?\)$/\)/xg;

    $replace =~ s/\$(\d{1,3})\$/\$$1/xg;

    $config[@config][0] = qr/$original/;
    $config[@config - 1][1] = q(") . $replace . q(");

    $original = "\\(" . $original . "\\(";
    $config[@config - 1][2] = qr/$original/;
}

sub processFiles
{
    my @files = grep { ! -d } glob "$directory\\*";
    foreach my $file (@files)
    {
        if($file =~ /\.(h|c)$/)
        {
            process($file);
        }
    }
}

sub process
{
    my $file = $_[0];
    open READ, $file;
    local $/;
    my $text = <READ>;
    close READ;
    print LOG "\n--> $file <--\n";
    for(my $i = 0; $i < @config; $i++)
    {
        my $original = $config[$i][0];
        my $replace = $config[$i][1];
        my $log = $config[$i][2];

        while($text =~ /$log/g)
        {
            print LOG $log . " ----> " . $1 . "\n";
        }

        $text =~ s/$original/$replace/eeg;
        print LOG "\n";
    }

    $file = $result . substr($file, rindex($file, "\\"));

    open WRITE, ">", $file;
    print WRITE $text;
    close WRITE;
}

start("qm2asil.cfg");

close LOG;

配置文件内容:

*static 
*GET_$1$() ==> $1$
*GET_$1$($2$) ==> $1$[$2$]
*SET_$1$($2$,$3$); ==> $1$[$2$] = $3$;
*SET_$1$($2$); ==> $1$ = $2$;

我们的想法是,已经有一些规则可以替换/删除,但它们可以运行,但可以存在我无法管理的更复杂的规则。

示例:

SET_VAR1((i),(u8)(((s32)(((s32)GET_VAR2 ((i))) != 0)) && ((s32)((u8)(((s32) (((s32)VAR3[i]) != 0)) ^ ((s32)(((s32) VAR4[i]) != 0)))))));

我想删除SET函数并将其赋值给变量(VAR1 [i] = ...)。这是需要删除/替换的许多变体之一。

你建议我做什么?我可以使用Perl和regex使其工作,或者我应该重新定位到另一种方法和/或编程语言?

编辑:我已经根据配置文件创建了正则表达式,但我遇到了与未知表达式匹配的问题(目前我使用。+)。主要想法是我希望保持配置尽可能简单。

regexes

0 个答案:

没有答案