Переименование заголовка C++ с perl - многострочные проблемы

Я пытаюсь заключить пространство имен библиотеки C++ только для заголовков в собственное пространство имен, чтобы избежать конфликтов имен символов с кодом клиента.

Вот сценарий Perl, который я написал. Он должен заключать пространство имен def в пространство имен abc.

#!/usr/bin/perl

while (<>) { 
    s/namespace\s+def\s*
    ( # group 1 - braced string with balanced number of lbraces and rbraces
        \{
        ( # group 2 - String without braces or recursion to group 1
            [^\{\}]* # some string that does not contain braces
            | (?1) # recursion of group1
        )*
        \}
    )
    /namespace abc {\nnamespace def \1\n}/gcsx;
    print;
}

и вот тестовый файл, который я использую:

namespace def {}
namespace def { abc }
namespace def { { } }
namespace def { { abcd } }
namespace def {
    abc
}
namespace def { // some comment
    do_something();
}
namespace def {
    do_something();
    while (still_not_crashed()) {
        do_even_more();
    }
}

Однако выполнение сценария в файле дает только

namespace abc {
namespace def {}
}
namespace abc {
namespace def { abc }
}
namespace abc {
namespace def { { } }
}
namespace abc {
namespace def { { abcd } }
}
namespace def {
    abc
}
namespace def { // some comment
    do_something();
}
namespace def {
    do_something();
    while (still_not_crashed()) {
        do_even_more();
    }
}

Пространство имен в одну строку прекрасно работает, но как только шаблон, который должен быть сопоставлен, содержит новую строку, он перестает работать, хотя я добавил модификатор s в свое регулярное выражение.

Что я делаю неправильно?

1 ответ

Решение

Вы должны прочитать весь файл в строке, а затем выполнить подстановку в этой строке:

#!/usr/bin/perl
use Modern::Perl;

undef$/;
$_ = <DATA>;
    s/namespace\s+def\s*
    ( # group 1 - braced string with balanced number of lbraces and rbraces
        \{
        ( # group 2 - String without braces or recursion to group 1
            [^\{\}]* # some string that does not contain braces
            | (?1) # recursion of group1
        )*
        \}
    )
    /namespace abc {\nnamespace def $1\n}/gsx;
    print;


__DATA__
namespace def {}
namespace def { abc }
namespace def { { } }
namespace def { { abcd } }
namespace def {
    abc
}
namespace def { // some comment
    do_something();
}
namespace def {
    do_something();
    while (still_not_crashed()) {
        do_even_more();
    }
}

Выход:

namespace abc {
namespace def {}
}
namespace abc {
namespace def { abc }
}
namespace abc {
namespace def { { } }
}
namespace abc {
namespace def { { abcd } }
}
namespace abc {
namespace def {
    abc
}
}
namespace abc {
namespace def { // some comment
    do_something();
}
}
namespace abc {
namespace def {
    do_something();
    while (still_not_crashed()) {
        do_even_more();
    }
}
Другие вопросы по тегам