Утилита для удаления из текста C++ блоков #if с подходящими условиями
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 07.07.23 17:34
Оценка: -1 :)
Много лет назад уже задавал этот вопрос
Автор: Евгений Музыченко
Дата: 29.01.09
. Тогда посоветовали cpp-partial, но он не подошел — понимает только #ifdef/#ifndef, а у меня все условия на #if, чтобы не нарываться на проблемы из-за ошибок в написании имен.

Тогда я обошелся вынесением заказчикозависимого кода в отдельные файлы, но это довольно неудобно — и код не сразу виден, и для многих мест достаточно лишь пары-тройки строк.

Может, с тех пор появилось что-то подходящее?
Re: Просто используй С++, а на С с классами
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 07.07.23 21:20
Оценка: -1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Может, с тех пор появилось что-то подходящее?

Концепты и policy-based подход к реализации подобных вещей. Просто переделай это и всё будет нормально работать, хотя куда тебе, ты знатный ретроград.
Вот хорошее видео
  Видео
.
Sic luceat lux!
Re[2]: Просто используй С++, а на С с классами
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 07.07.23 21:31
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Концепты и policy-based подход к реализации подобных вещей.


Очень рад за них — особенно при том, что они не имеют ни малейшего отношения к заданному вопросу. Может, Вам стоило хотя бы прочитать его?
Re: Утилита для удаления из текста C++ блоков #if с подходящими условиями
От: vsb Казахстан  
Дата: 07.07.23 21:33
Оценка: +2
А в чём проблема написать самому? Я может что-то не понимаю, но вроде задача на час от силы. Или там какие-то сверх-сложные условия в if, которые самописным парсером не разобрать?
Re[2]: Утилита для удаления из текста C++ блоков #if с подхо
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 07.07.23 21:35
Оценка: :)
Здравствуйте, vsb, Вы писали:

vsb>вроде задача на час от силы.


На час она тому, кто регулярно пишет парсеры/интерпретаторы выражений, или знаком с готовыми библиотеками. Я такого вообще ни разу не писал — если возьмусь делать наскоро, то получится жутко уродливый код, меня такой раздражает, придется дорабатывать и вылизывать, в итоге растянется на несколько дней.

vsb>Или там какие-то сверх-сложные условия в if, которые самописным парсером не разобрать?


Да не особо — только числовая/битовая арифметика, да логические связки.
Отредактировано 07.07.2023 21:39 Евгений Музыченко . Предыдущая версия .
Re: Утилита для удаления из текста C++ блоков #if с подходящими условиями
От: ononim  
Дата: 08.07.23 07:23
Оценка: -1
ЕМ>Много лет назад уже задавал этот вопрос
Автор: Евгений Музыченко
Дата: 29.01.09
. Тогда посоветовали cpp-partial, но он не подошел — понимает только #ifdef/#ifndef, а у меня все условия на #if, чтобы не нарываться на проблемы из-за ошибок в написании имен.

ЕМ>Тогда я обошелся вынесением заказчикозависимого кода в отдельные файлы, но это довольно неудобно — и код не сразу виден, и для многих мест достаточно лишь пары-тройки строк.
ЕМ>Может, с тех пор появилось что-то подходящее?
gcc -E?

-E Stop after the preprocessing stage; do not run the compiler
proper. The output is in the form of preprocessed source
code, which is sent to the standard output.

Как много веселых ребят, и все делают велосипед...
Re[3]: Утилита для удаления из текста C++ блоков #if с подхо
От: rg45 СССР  
Дата: 08.07.23 07:43
Оценка: :)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>На час она тому, кто регулярно пишет парсеры/интерпретаторы выражений, или знаком с готовыми библиотеками. Я такого вообще ни разу не писал — если возьмусь делать наскоро, то получится жутко уродливый код, меня такой раздражает, придется дорабатывать и вылизывать, в итоге растянется на несколько дней.


Да ты 14 лет уже ищешь.

Если 30 лет опыта разработки на С++ недостаточно для решения такой сложной задачи, можно воспользоваться более приятными языками
Автор: Shmj
Дата: 03.05.23
— Java, C#, Python . . .
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 08.07.2023 8:15 rg45 . Предыдущая версия . Еще …
Отредактировано 08.07.2023 8:11 rg45 . Предыдущая версия .
Отредактировано 08.07.2023 8:10 rg45 . Предыдущая версия .
Отредактировано 08.07.2023 8:10 rg45 . Предыдущая версия .
Отредактировано 08.07.2023 8:07 rg45 . Предыдущая версия .
Re: Утилита для удаления из текста C++ блоков #if с подходящими условиями
От: vopl Россия  
Дата: 08.07.23 09:23
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Много лет назад уже задавал этот вопрос
Автор: Евгений Музыченко
Дата: 29.01.09
. Тогда посоветовали cpp-partial, но он не подошел — понимает только #ifdef/#ifndef, а у меня все условия на #if, чтобы не нарываться на проблемы из-за ошибок в написании имен.


ЕМ>Тогда я обошелся вынесением заказчикозависимого кода в отдельные файлы, но это довольно неудобно — и код не сразу виден, и для многих мест достаточно лишь пары-тройки строк.


ЕМ>Может, с тех пор появилось что-то подходящее?


Мне в свое время понравился boost wave, посмотри его примеры, в особенности некий "The advanced_hooks sample", выглядит довольно близко к тому что тебе надо.
Re[2]: Утилита для удаления из текста C++ блоков #if с подходящими условиями
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.07.23 11:26
Оценка:
Здравствуйте, ononim, Вы писали:

O>gcc -E?


Ну это ж совсем не то.
Re[4]: Утилита для удаления из текста C++ блоков #if с подхо
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.07.23 11:27
Оценка:
Здравствуйте, rg45, Вы писали:

R>Да ты 14 лет уже ищешь.


Да, и Вам это еще 15 лет не даст покоя.
Re[5]: Утилита для удаления из текста C++ блоков #if с подхо
От: rg45 СССР  
Дата: 08.07.23 11:39
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Да, и Вам это еще 15 лет не даст покоя.


Звучит как угроза.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[6]: Утилита для удаления из текста C++ блоков #if с подхо
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.07.23 12:59
Оценка:
Здравствуйте, rg45, Вы писали:

R>Звучит как угроза.


Вы и без угроз справитесь. "Свинья везде грязь найдет".
Re[7]: Утилита для удаления из текста C++ блоков #if с подхо
От: rg45 СССР  
Дата: 08.07.23 13:11
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Вы и без угроз справитесь. "Свинья везде грязь найдет".


Какая ясновидящая грязь попалась.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Утилита для удаления из текста C++ блоков #if с подходящими условиями
От: Quebecois Канада https://www.canada.ca/
Дата: 08.07.23 16:27
Оценка: -1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Ну это ж совсем не то.

То, если распарсить результат, посмотреть, какие блоки выкинулись/остались, и на основании этого пропатчить оригиналы.
Re[4]: Утилита для удаления из текста C++ блоков #if с подходящими условиями
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.07.23 16:43
Оценка:
Здравствуйте, Quebecois, Вы писали:

Q>То, если распарсить результат, посмотреть, какие блоки выкинулись/остались, и на основании этого пропатчить оригиналы.


Осталось вспомнить, что есть такая штука, как макросы, и соотнесение блоков в том виде, в каком их выдаст препроцессор, будет задачей куда менее тривиальной, чем сделать интерпретатор выражений, допустимых для #if.
Re[5]: Утилита для удаления из текста C++ блоков #if с подхо
От: Quebecois Канада https://www.canada.ca/
Дата: 08.07.23 16:56
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Осталось вспомнить, что есть такая штука, как макросы, и соотнесение блоков в том виде, в каком их выдаст препроцессор, будет задачей куда менее тривиальной, чем сделать интерпретатор выражений, допустимых для #if.

Вы результат работы gcc -E вживую видели? Или, хотя бы, задумывались, как cc1, работающий после препроцессор, умудряется записать правильные номера строк в debug info, не выполняя "нетривиальное соотнесение блоков"?

По факту, задача элементарная, потому что препроцессор нашпигует свою выдачу #line-ами.
Отредактировано 08.07.2023 16:57 Quebecois . Предыдущая версия .
Re[6]: Утилита для удаления из текста C++ блоков #if с подхо
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 08.07.23 20:24
Оценка:
Здравствуйте, Quebecois, Вы писали:

Q>Вы результат работы gcc -E вживую видели?


Видел.

Q>По факту, задача элементарная


Она лишь просто выполнимой станет только после того, как препроцессор будет обеспечен правильной конфигурацией как путей include, так и значениями всех макросов, которые могут встретиться в выражениях. В общем случае все это доступно только внутри цикла сборки под соответствующую среду (VS, WDK и т.п. — ну не требовалось мне никогда именно *make), так что надо будет вытаскивать конфигурацию и поддерживать ее отдельно. Самое-то смешное, что по логике задачи всего этого не требуется.

Q>препроцессор нашпигует свою выдачу #line-ами.


Нашпигует, а толку? В #if может быть не только одинокий макрос вида "_BUILD_FOR_CUSTOMER_XXX", но и более сложное выражение. Как понять, по какой именно части условия препроцессор выкинул или оставил такой блок?
Re[7]: Утилита для удаления из текста C++ блоков #if с подхо
От: Chorkov Россия  
Дата: 10.07.23 09:55
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Нашпигует, а толку? В #if может быть не только одинокий макрос вида "_BUILD_FOR_CUSTOMER_XXX", но и более сложное выражение. Как понять, по какой именно части условия препроцессор выкинул или оставил такой блок?


А в общем виде, без учета значения других макросов, задача не решается.
Например:
// #define Y 1 || 1
#if defined(USER_C) && Y
int Foo=4; // Этот кусок кода оставлять, для пользователя A ?
#endif

https://godbolt.org/z/Pcsv8rK69

Тут нужно учесть, что значение Y могло "приехать" и из настроек скрипта сборки и его значение неизвестно...

Остается только переписать код, так чтобы defined(_BUILD_FOR_CUSTOMER_XXX) не встречались в сложных условиях, т.е. заменить на #ifdef/#ifndef соотвественно.
Тогда подход cpp-partial сработает.
Re[8]: Утилита для удаления из текста C++ блоков #if с подхо
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 10.07.23 10:40
Оценка:
Здравствуйте, Chorkov, Вы писали:

C>А в общем виде, без учета значения других макросов, задача не решается.


Через стандартный препроцессор — конечно, нет. В идеале надо бы просто упрощать сложные условия, исключая из них макросы с известными значениями.

C>Остается только переписать код, так чтобы defined(_BUILD_FOR_CUSTOMER_XXX) не встречались в сложных условиях, т.е. заменить на #ifdef/#ifndef соотвественно.


Я не использую ни defined (), ни #ifdef/#ifndef — это неслабый источник труднообнаруживаемых глюков. Только #if. Если какие-то стандартные макросы поступают в виде "определено / не определено", они переделываются в локальные со значениями 0/1.
Re: Утилита для удаления из текста C++ блоков #if с подходящими условиями
От: SaZ  
Дата: 10.07.23 13:30
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Много лет назад уже задавал этот вопрос
Автор: Евгений Музыченко
Дата: 29.01.09
. Тогда посоветовали cpp-partial, но он не подошел — понимает только #ifdef/#ifndef, а у меня все условия на #if, чтобы не нарываться на проблемы из-за ошибок в написании имен.


ЕМ>Тогда я обошелся вынесением заказчикозависимого кода в отдельные файлы, но это довольно неудобно — и код не сразу виден, и для многих мест достаточно лишь пары-тройки строк.


ЕМ>Может, с тех пор появилось что-то подходящее?


Нормальная архитектура с заказчикозависимым кодом в отдельном классе. Можно через pimpl подсовывать нужные реализации, а решать уже включать ту или иную имплементацию — на усмотрение билд системы. Если нужно отдавать исходник не заказчику — отдаём только заглушку.

// main.h
class A;

class I
{
public:
    I(A& a) : _a{a}()
    void foo(int a); // not virtual
private:
    A& _a;
};

class A
{
friend class I;
public:
    A() : _impl{*this}()

    void foo(int a)
    {
        // Shared logic
        _impl.foo(a); // Customer-specific or shared logic
        std::cout << _last;
    }

private:
    I _impl;
    std::string _last;
};

// common.cpp или заглушка
void I::foo(int a)
{
  _a._last = "called from shared code";
}

// customer_specific.cpp
void I::foo(int a)
{
  _a._last = "called from customer-specific code";
}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.