Замена макроса массива регулярным выражением - PullRequest
0 голосов
/ 10 декабря 2018

Я хотел удалить макрос в одном из проектов, над которым работал, и для этого потребовался скрипт, так как в исходном коде c / cpp есть более 800 вхождений.Обратите внимание, что хотя этот макрос присутствует в файлах cpp, все объявления и типы являются простыми c.

Рассматриваемый макрос выглядит так:

#define ARRAY(data_type, size, array_name) data_type array_name[size]

Когда он используется в источнике, он выглядитвот так:

#define BAR_LEN 2

struct Foo_t
{
   uint16_t example;
   ARRAY(uint8_t, BAR_LEN, Bar);  //<-- This line
   uint8_t target;
};

Теперь я могу перечислить все исходные файлы

find . -regextype egrep -regex '.*/.*\.(h|c|cpp)' -print0

и потенциально передать их в xargs для использования с другой утилитой, такой как awk или sed.Проблема в том, что я не уверен, какое направление выбрать.Используя приведенный выше пример, моя цель - преобразовать:

struct Foo_t
{
   uint16_t example;
   ARRAY(uint8_t, BAR_LEN, Bar); //<-- This line
   uint8_t target;
};

в

struct Foo_t
{
   uint16_t example;
   uint8_t Bar[BAR_LEN];  //<-- This line
   uint8_t target;
};

Однако существует много объявлений, в которых используется этот макрос, которые передают разные параметры для каждого вызова.Кроме того, использование макроса имеет различия в форматировании с точки зрения расстояния.Я немного озадачен на данный момент, любое направление будет с благодарностью.Спасибо!

Обновление:

В целях тестирования я создал файл Test.txt для проверки команд, все, что он содержит, - это следующие 4 строки:

ARRAY( uint8_t, 16, Bar1);
ARRAY(uint8_t,4,Bar2);
ARRAY(uint8_t, 18,Bar3);
ARRAY(uint8_t,2, Bar4);

Фактическое использование можно найти по ссылке ниже:

https://onlinegdb.com/Skpstxn1N

1 Ответ

0 голосов
/ 10 декабря 2018

Скорее всего, вам лучше использовать gcc в режиме препроцессора для расширения ваших макросов, но если вы только (и точно) хотите расширить этот макрос, следующий oneliner может сделать это уже при условии, что вызов макроса всегдав одной строке, а сами типы являются простыми идентификаторами, как в вашем примере.

perl -pi -e 's/\bARRAY\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/$1 $3\[$2\]/g' *.c

Это выводит ваши тестовые данные:

uint8_t Bar1[16];
uint8_t Bar2[4];
uint8_t Bar3[18];
uint8_t Bar4[2];

Другим подходом будет запуск gcc -E, но это также расширит все #include с.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...