В m4, как вы включаете файл, в имени которого есть переменная окружения? - PullRequest
3 голосов
/ 18 марта 2011

Я хочу включить файл, основанный на моем базовом каталоге песочницы, внутри моего текста m4 без использования ключа -I.

Пока я выяснил, как получить переменные окружения с помощью вызова sys:

define(MODEL_ROOT,`syscmd(`printf $MODEL_ROOT')')dnl

Далее я хочу включить файл на основе этой переменной среды:

include(MODEL_ROOT/sw/lib/m4_macros/foreach2.m4)

Всего у меня есть:

define(MODEL_ROOT,`syscmd(`printf $MODEL_ROOT')')

MODEL_ROOT

MODEL_ROOT/sw/lib/m4_macros/foreach2.m4

include(MODEL_ROOT/sw/lib/m4_macros/foreach2.m4)

Какие отпечатки:

/home/ross/sandbox

/home/ross/sandbox/sw/lib/m4_macros/foreach2.m4

/home/ross/sandboxforeach_example.m4:7: m4: Cannot open /sw/lib/m4_macros/foreach2.m4: No such file or directory

Я знаю, что нормальный синтаксис для включений -

include(`file.m4')

Но если я процитирую MODEL_ROOT/sw/lib/m4_macros/foreach2.m4, то m4 вроде:

[...]
include(`MODEL_ROOT/sw/lib/m4_macros/foreach2.m4')

m4 жалуется:

[...]
foreach_example.m4:7: m4: Cannot open MODEL_ROOT/sw/lib/m4_macros/foreach2.m4: No such file or directory

Как включить файл с переменной окружения в свой путь?

Ответы [ 2 ]

2 голосов
/ 18 марта 2011

Я думаю, вам нужно использовать esyscmd вместо syscmd.esyscmd читает выходные данные командной строки.

1 голос
/ 01 августа 2016

Как упоминается в другом ответе, вы должны использовать расширение GNU esyscmd, чтобы иметь возможность получить выходные данные команды.Макрос syscmd просто печатает прямо на стандартный вывод, игнорируя все макросы и divert s.

Именно поэтому он выглядел так, как будто MODEL_ROOT работал везде: это было, но только в очень простых ситуациях, когдаm4 не нужно было иметь дело с его выводом.

Однако, что касается цитаты:

  • include(MODEL_ROOT/sw/lib/m4_macros/foreach2.m4)
  • include(`MODEL_ROOT/sw/lib/m4_macros/foreach2.m4')

Это должно иметь перемещенные кавычки:

include(MODEL_ROOT`/sw/lib/m4_macros/foreach2.m4')

Кавычки предотвращают расширение макроса MODEL_ROOT, поэтому они не должны заключать его здесь (где вы хотите, чтобы он был расширен).«Правильно» заключать в кавычки оставшуюся часть строки, потому что это не то, что вы захотите раскрыть макросами.


В качестве более надежного способа получить переменную среды изshell будет выглядеть примерно так:

define(`HOME', esyscmd(`printf \`\`%s\'\' "$HOME"'))

Это позволит избежать проблем, вызванных именами макросов, процентными знаками, обратными слешами, символами глобуса или пробелами в значении переменной среды.Единственное различие между этим и вашим решением заключается в добавлении \`\`%s\'\' и кавычек вокруг переменной.

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

...