m4, используя переменное количество вкладок для выравнивания столбца

Это макрос, который у меня есть до сих пор:

define(`debug_macro', ` #ifndef $1_DEBUG #define $1_DEBUG'forloop(`i',`1',eval(5-(len($1)/4+ifelse(eval(len($1)%4 == 0)), `0', `1')),` ')dnl`0 #endif ') 

Цель состоит в том, чтобы установить правильное количество вкладок между символами _DEBUG и 0 чтобы они _DEBUG в очередь. Там могут отсутствовать парсеры или цитаты, но, надеюсь, вы получите представление о том, куда я иду.

Я использую Xcode и имею свои вкладки в 4. Вот изменения, которые я сделал для этого:

 divert(`-1') # forloop(var, from, to, stmt) define(`forloop', `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')') define(`_forloop', `$4`'ifelse($1, `$3', , `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')') divert`'dnl changecom()dnl define(`debug_macro', ` #ifndef $1_DEBUG #define $1_DEBUG`'forloop(`i', `1', ifelse(eval(len($1) >= 16), 1, 1, eval(5-(len($1)/4+ifelse(eval(len($1)%4 > 1), 0, `0', `1')))),` ')0 #endif ') changecom()dnl 

Поскольку я не мог найти «forloop.m4» в своей системе, я просто включил его. Разделение на 4 раунда, поэтому я добавил проверку, когда остаток больше 1. Я также изменяю пробел для одного символа табуляции.

Для заинтересованного я использую этот макрос для определения констант, которые я использую для включения отладки различных областей моего приложения. Этот файл проверяется на git. Тогда есть файл, который является личным и не проверяется, что выглядит примерно так:

 //#define NETWORK_DEBUG 1 

Файл включен в файл myapp.pch, прежде чем включать вышеуказанный файл. Таким образом, каждый программист может включать и выключать собственные области отладки.

One Solution collect form web for “m4, используя переменное количество вкладок для выравнивания столбца”

Самый простой способ отступов – использовать пробелы, а не вкладки. Особенно не закладок с нестандартной шириной (поскольку стандартная ширина для вкладок составляет 8).

Второй- unexpand простой способ отступов что-то с вкладками состоит в том, чтобы сгенерировать файл с пробелами и вызвать unexpand чтобы заменить пробелы на вкладки.

Это, как говорится, вы можете сделать это в m4, но вам нужно будет больше узнать об этом. Постройте свои выражения поэтапно: получите часть работы, затем переходите к следующей.

forloop не является стандартным макросом m4. Я думаю, вы имеете в forloop макрос forloop представленный в руководстве GNU m4 . Это пример кода, который поставляется с GNU m4 (руководство не делает это очень ясным); чтобы использовать его в своем коде, вам нужно включить его явно. Распространение может или не может отправить его, поэтому вам лучше распространить его с помощью вашего кода.

В коде есть несколько синтаксических проблем.

  • Вы оставили вызов forloop вне каких-либо кавычек, поэтому он оценивается в момент, когда define , а не во время оценки debug_macro .
  • Макрос ifelse не выбирается на основе значения только первого аргумента, сравнивает его первые два аргумента – это скорее макрос case: вызов должен быть ifelse(…, 0, 0, 1) или ifelse(… == 0, 1, 0, 1) .
  • # начинает комментарий. M4 игнорирует все после комментария. Измените разделитель комментариев, когда вы определяете макрос debug_macro .

Следующий код работает до тех пор, пока аргумент не слишком длинный:

 include(`/usr/share/doc/m4/examples/forloop.m4')dnl changecom()dnl define(`debug_macro', ` #ifndef $1_DEBUG #define $1_DEBUG`'forloop(`i',`1',eval(5-(len($1)/4+ifelse(eval(len($1)%4), 0, `0', `1'))),` ')0 #endif ')dnl changecom('#')dnl в include(`/usr/share/doc/m4/examples/forloop.m4')dnl changecom()dnl define(`debug_macro', ` #ifndef $1_DEBUG #define $1_DEBUG`'forloop(`i',`1',eval(5-(len($1)/4+ifelse(eval(len($1)%4), 0, `0', `1'))),` ')0 #endif ')dnl changecom('#')dnl 

С аргументом, который приводит к тому, что максимальный индекс цикла становится равным 0 или меньше, цикл выполняется примерно 2 32 раза (m4 использует 32-битную по модулю арифметику). В этом случае вам потребуется дополнительное испытание. Вот код, который вставляет одну вкладку, когда аргумент слишком длинный.

 include(`/usr/share/doc/m4/examples/forloop.m4')dnl changecom()dnl define(`debug_macro', ` #ifndef $1_DEBUG #define $1_DEBUG`'forloop(`i', `1', ifelse(eval(len($1) >= 16), 1, 1, eval(5-(len($1)/4+ifelse(eval(len($1)%4), 0, `0', `1')))),` ')0 #endif ')dnl changecom('#')dnl в include(`/usr/share/doc/m4/examples/forloop.m4')dnl changecom()dnl define(`debug_macro', ` #ifndef $1_DEBUG #define $1_DEBUG`'forloop(`i', `1', ifelse(eval(len($1) >= 16), 1, 1, eval(5-(len($1)/4+ifelse(eval(len($1)%4), 0, `0', `1')))),` ')0 #endif ')dnl changecom('#')dnl 
Linux и Unix - лучшая ОС в мире.