'Calling a multi-line macro by using a dynamic name?
I'm back here for another question, this time about macros.
I'd want to call a multi-line macro by using !..! (if possible) in order to use dynamic macro names like in the following call for a single-line macro:
setlocal disabledelayedexpansion
:: Simple single-line macros for testing purpose.
set "_testA=echo A" & set "_testB=echo B"
setlocal enabledelayedexpansion
:: Choose macro _testA or _testB.
set /p char="Type A or B:"
:: Execute the chosen macro.
!_test%char%!
endlocal
endlocal
For example,
setlocal disabledelayedexpansion
:: Line feed character.
(set CHR10=^
%=Do not remove this line, or you will be turned into a frog=%
)
:: End of line in a macro code.
set ^"\nmac=^^^%CHR10%%CHR10%^%CHR10%%CHR10%^^"
:: Simple multi-line macro for testing purpose, it could be replace with one receiving parameters obviously.
set _test=(echo A%\nmac%
echo B%\nmac%
echo C)
setlocal enabledelayedexpansion
:: Works as expected, displays A then B then C.
%_test%
:: Doesn't work... as expected also, displays `(echo Is Not Recognized as an Internal or External Command, Operable Program or Batch File.`
!_test!
endlocal
endlocal
The problem seems to comes from the definition of CHR10 when using with !..! (using %_test% works, obviously).
Any idea to solve this ? A solution could help me to refactor some code.
Thanks in advance for your answer.
Solution 1:[1]
The solution is easy, you always need percent expansion for the execution of a batch macro. Obviously you can't make the variable name dynamic for a percent expansion, but you can make the content dynamic.
@echo off
(set ^"$\n=^^^
%= Do not remove this line=%
)
set macro1=(echo #1 Line1 %$\n%
echo #1 Line2)
set macro2=(echo #2 Line1 %$\n%
echo #2 Line2)
setlocal EnableDelayedExpansion
%macro1%
%macro2%
set /p "macroNum=Select 1 or 2: "
set "macroName=macro%macroNum%"
REM *** Copy the content of the 'dynamic macro' to indirectMacro
set "indirectMacro=!%macroName%!"
%indirectMacro%
Btw. Your definition and use of \nmac
is superfluous, because a single linefeed
(with a single caret) is enough in batch macros, when they are enclosed in parenthesis.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |