Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @Echo off & Setlocal EnableExtensions & CLS
- REM Author: T3RR0R, aka T3RRY. 10/02/2024
- REM Discuss with author at https://discord.gg/HCSEC829F9
- REM
- REM - A template for the creation of macros with arguments
- REM Macros may be defined in either Delayed enabled or disabled environments, but will require
- REM Delayed expansion to be enabled in order for them to be expanded.
- REM
- REM EXPLAINER
- REM - Macro's offer superior performance to CALLed :functions, however involve an
- REM increased degree of complexity in their definition and use.
- REM This template aims to reduce the learning curve required and make macro's more accessible
- REM As such, no processing of the Arguments provided to the Macro is performed
- REM
- REM Any Macro specific processing is to be defined by You, the user, where the template notes
- REM to insert such processing.
- REM
- REM The DEFAULT behavior is to split the arguments into an Array defined to $Return[#], where
- REM # is the current index of the Array (1 indexed).
- REM The size of the Array is returned in $Return[i]
- REM $Return may be substituted using Substring Modification with a custom variable name at the
- REM time of expansion.
- REM
- REM Use the search and replace tool of your script editor to replace $Macro.Template with the
- REM intended name of your Macro
- REM Recommended Learning resources:
- REM [1] https://www.dostips.com/forum/viewtopic.php?t=9265#p60294
- REM [2] https://www.dostips.com/forum/viewtopic.php?f=3&t=10983&sid=f6937e02068d93bc5a97ef63d4e5319e
- REM - Macros with arguments:
- REM [3] https://www.dostips.com/forum/viewtopic.php?f=3&t=1827
- REM - CMD parsing behaviour:
- REM [4] https://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts
- REM String length method is a modified version originally produced by JEB
- REM See link at resource [2] above.
- (Set $\n=^^^
- %= DO NOT MODIFY $\n newline variable for multi-line macro definition =%)
- REM - Each internal line of multiline macro's must be terminated with the escaped linefeed variable:
- REM %$\n%
- Set ^"$DQ=""
- REM - EnableDelayedExpansion Aka EDE required to %expand% macro/s
- REM May be placed before or after Macro definiton.
- Setlocal EnableDelayedExpansion
- For /f %%! in ("! ^! ^^^!") Do %= This outer loop allows DDE or EDE environment independant definition =%^
- Set $Macro.Template=For %%n in (1 2)Do if %%n == 2 ( %$\n: IMPORTANT - No whitespace permitted at Start of this Line =%
- If "%%!%%!" == "" ( %$\n: DDE or EDE test. If enableDE; enact macro =%
- If not "%%!$Macro.Template.Args%%!" == "" ( %!! Args do arg processing =%
- If "%%!$Macro.Template.Args:~0,1%%!" == " " Set "$Macro.Template.Args=%%!$Macro.Template.Args:~1%%!" %$\n%
- For /f "delims=" %%Q In ("%%!$DQ%%!")Do ( %$\n%
- Set "$Macro.Template.Args=%%!$Macro.Template.Args: %%Q=,%%Q%%!" %$\n%
- Set "$Macro.Template.Args=%%!$Macro.Template.Args:%%Q =%%Q,%%!" %$\n%
- ) %$\n%
- If not "%%!$Macro.Template.Switch[Defined]%%!" == "" ( %$\n%
- For /f "tokens=1 Delims==" %%G in ('Set "$Macro.Template.Switch"')Do Set "%%G=" %$\n%
- ) %$\n%
- Set "$Macro.Template.Arg[i]=0" %$\n%
- Set "$Macro.Template.Args=%%!$Macro.Template.Args: /=,/%%!" %$\n%
- For /l %%i in (1 1 750)Do If defined $Macro.Template.Args ( %$\n%
- For /f "tokens=1 Delims=," %%? in ("%%!$Macro.Template.Args%%!")Do If not %%? == "" ( %$\n%
- Set "$Macro.Template.ThisArg=%%~?" %$\n%
- (Set^^ "$_=%%~?") %$\n%
- If Defined $_ ( %$\n%
- Set "$Len=1" %$\n%
- For %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1)Do ( %$\n%
- If "%%!$_:~%%P,1%%!" NEQ "" ( %$\n%
- Set /a "$Len+=%%P" %$\n%
- Set "$_=%%!$_:~%%P%%!" %$\n%
- ) %$\n%
- ) %$\n%
- )Else set "$Len=0" %$\n%
- Set "$Macro.Template.Switch=" %$\n%
- Set /A "$Len.OG=%%!$Len%%!","$Macro.Template.Argcull=3" %$\n%
- If "%%?" == "%%~?" ( %$\n%
- Set "$Macro.Template.Argcull=1" %$\n%
- ) %$\n%
- If "%%!$Macro.Template.Argcull%%!" == "1" ( %$\n%
- IF "%%!$Macro.Template.ThisArg:~0,1%%!" == "/" ( %$\n%
- Set "$Macro.Template.Switch=true" %$\n%
- Set "$Macro.Template.Switch[Defined]=true" %$\n%
- Set "$Macro.Template.Switch[%%!$Macro.Template.ThisArg:~1,1%%!]=true" %$\n%
- If %%!$Len%%! GTR 2 ( %$\n%
- Set "$Macro.Template.Switch[%%!$Macro.Template.ThisArg:~1,1%%!]=%%!$Macro.Template.ThisArg:~3%%!" %$\n%
- %$\n:_____________________________________________________ TOGGLE SWITCH OFF /[A-Z]- ______________________________________________________=%
- IF "%%!$Macro.Template.ThisArg:~3%%!" == "-" Set "$Macro.Template.Switch[%%!$Macro.Template.ThisArg:~1,1%%!]=" %$\n%
- )%$\n%
- Set /a "$Len+=$Macro.Template.Argcull" %$\n%
- For /F "delims=" %%i in ("%%!$Len%%!")Do ( %$\n%
- Set "$Macro.Template.Args=%%!$Macro.Template.Args:~%%i%%!" %$\n:Shift Arg =%
- ) %$\n%
- ) %$\n%
- ) %$\n%
- If "%%!$Macro.Template.Switch%%!" == "" ( %$\n: Is Arg =%
- Set /A "$Macro.Template.Arg[i]+=1"%$\n%
- %$\n:________ IF THE ARGUMENTS STRING LENGTH IS REQUIRED FOR YOUR MACRO FUNCTION USE IT BEFORE NEXT LINE. EXPAND WITH A FOR LOOP __________=%
- Set /a "$Len+=$Macro.Template.Argcull" %$\n%
- For /F "delims=" %%i in ("%%!$Len%%!")Do ( %$\n%
- Set "$Macro.Template.Args=%%!$Macro.Template.Args:~%%i%%!" %$\n: Shift Arg =%
- ) %$\n%
- %$\n:______________________________________________ EXAMPLES OF BASIC SWITCH IMPLEMENTATION _______________________________________________=%
- %= /o - output =% If not "%%!$Macro.Template.Switch[o]%%!" == "" (Echo(%%!$Macro.Template.ThisArg%%!) %$\n%
- %= /L - Return Length =% If not "%%!$Macro.Template.Switch[L]%%!" == "" ( %$\n%%
- Set "$Return[%%!$Macro.Template.Arg[i]%%!].Len=%%!$Len.OG%%!" %$\n%
- ) %$\n%
- %!!%
- Set "$Return[%%!$Macro.Template.Arg[i]%%!]=%%!$Macro.Template.ThisArg%%!" %$\n%
- Set "$Return[i]=%%!$Macro.Template.Arg[i]%%!" %$\n%
- ) %$\n%
- ) %$\n%
- ) %$\n%
- )Else ( %!!%
- ^>"%~f0:$Macro.Template.help" ( %$\n%
- Echo( %$\n%
- Echo(Usage: Expand macro with double quoted arguments: %$\n%
- Echo( %%$Macro.Template%% [[/{A-Z}]:[{-}/{SwitchArg}]] "arg string" "arg string" %$\n%
- Echo( - Or - %$\n%
- Echo( %%$Macro.Template%% [[/{A-Z}]:[{-}/{SwitchArg}]] "arg string","arg string" %$\n%
- Echo( %$\n%
- Echo( %%$Macro.Template:$Return=ReturnName%% "arg string","arg string","arg String" %$\n%
- Echo( Use Substitution to provide a custom return variable name by replacing $Return %$\n%
- Echo( %$\n%
- Echo( - Arguments must be double quoted: "argument" %$\n%
- Echo( - Arguments must not contain ',' characters. %$\n%
- Echo( Comma: ',' is used internally to seperate arguments. %$\n%
- Echo( - Arguments may be seperated by either whitespace: " " or Comma: "," %$\n%
- Echo( %$\n%
- Echo( * Switch states will be the currently set state for each subsequent Arg * %$\n%
- Echo( Use conditional testing within the macro to implement switch behavours. %$\n%
- Echo( - Where 'SwitchChar' is a single character. IE [A-Z]: %$\n%
- Echo( /SwitchChar = Set state "$Macro.Template.Switch[SwitchChar]=true" %$\n%
- Echo( /SwitchChar:- = Set state "$Macro.Template.Switch[SwitchChar]=" %$\n%
- Echo( /SwitchChar:value = Set state "$Macro.Template.Switch[SwitchChar]=value" %$\n%
- Echo( %$\n%
- Echo( Switch usage example %$\n%
- Echo( %%$Macro.Template%% "arg 1" "arg 2" /o "Arg 3" %$\n%
- Echo( would output only the 3rd argument and beyond %$\n%
- %!!%
- Echo( %$\n%
- ) %$\n%
- (MORE /C ^<"%~f0:$Macro.Template.help") %$\n%
- ) %$\n%
- )Else ( %$\n: NO EDE - Notify Environment Req. =%
- Echo( %$\n%
- Echo( %%! Delayed Expansion is currently Disabled. %$\n%
- Echo( To successfully expand %%$Macro.Template%%, the command: %$\n%
- Echo( %$\n%
- Echo(Setlocal EnableDelayedExpansion %$\n%
- Echo( %$\n%
- Echo( is required *before* this macro command. %$\n%
- Echo( %$\n%
- ) %$\n%
- )Else Set $Macro.Template.Args=%= Capture macro Args =%
- REM Strip TABS from macro definition if in an EDE environment to conserve environment space.
- If "!!" == "" Set "$Macro.Template=!$macro.Template: =!"
- Echo(Example:
- Echo( %%$Macro.Template:$Return=My Array%% "Arg one" "Arg two" "<a=b>" "this=?" /c SwitchArg "and*" /o /l "Hello World^^^!" /o:- "." un quoted, /l:-,non switch UQ arg
- Echo(
- %$Macro.Template:$Return=My Array% "Arg one" "Arg two" "<a=b>" "this=?" /c SwitchArg "and*" /o /l "Hello World^^^!" /o:- "." un quoted,non switch UQ arg
- Echo(
- Set "My Array"
- Set "$Macro.Template.Switch"
- Echo(
- PAUSE & 1> nul TIMEOUT /T 1 /NOBREAK
- REM Usage displayed if expanded with no args
- %$Macro.Template%
- Setlocal DisableDelayedExpansion
- %$Macro.Template% "Demo Macro Error output in Environment Without EnableDelayedExpansion"
- (
- Endlocal & Endlocal & Endlocal
- Pause
- )
Advertisement
Comments
-
- Template updated 12/02/2024 to include switch processing and example switch handling.
- Switches allow complex processing behavior to be applied to selected arguments within the same expansion of the macro function.
- Switch states are defined whe the switch as used IE: /S and can be disabled via the argument '-' IE: /S:-
- Switches may also be provided unquoted argument values to be used to apply processing to subsequent arguments until or unless the switch state is again disabled - ensure supplied switch arguments are escaped if needed.
Add Comment
Please, Sign In to add comment
Advertisement