Sanitization of carets/exclamation marks inside a macro
The crux of the following code is L91-97:
Code: Select all
set "prefix=%~2" & if "" equ "%~2" if "" equ "%2" (set "prefix=0x")
if defined prefix (set "prefix=%prefix:^=^^^^^^^^%")
if defined prefix (set "prefix=%prefix:!=^^^^^^^!%")
set "suffix=%~3" & if "" equ "%~3" if "" equ "%3" (set "suffix=")
if defined suffix (set "suffix=%suffix:^=^^^^^^^^%")
if defined suffix (set "suffix=%suffix:!=^^^^^^^!%")
The code in its entirety:
Code: Select all
@if not "Windows_NT" == "%OS%" >&2 (
echo This program isn't compatible with the current operating system.
goto :EOF
) else (set ^"^") >nul 2>&1 || >&2 (
echo This program requires Command Extensions to be available to run.
goto :EOF
)
@echo off && (if defined CMD_DEBUG echo on) & goto :main
:main
setlocal DisableDelayedExpansion EnableExtensions
call :init
set result=
call :define_strhex $strhex
%$strhex% result -1
%$stdout% "null: %result%"
call :define_strhex $strhex "^^"
%$strhex% result -1
%$stdout% ""^^": %result%"
call :define_strhex $strhex ^^
%$strhex% result -1
%$stdout% " ^^ : %result%"
call :define_strhex $strhex "!!"
%$strhex% result -1
%$stdout% ""!!": %result%"
call :define_strhex $strhex !!
%$strhex% result -1
%$stdout% " !! : %result%"
exit /b 0
:init ()
if not defined \n set ^"\n=^^^
%= These lines are supposed to be undented and empty; =%
%= removing them will result in hard-to-debug errors! =%
if not defined \p if "%=^%=" == "%=%=" (
set ^"\p=%%<nul"
) else (
set ^"\p=^%<nul"
)
for /f "tokens=1 delims== " %\p%! in (
"!=! ^^^!"
) do for /f %\p%^^ in (
"^ ^^^^%\p%!=%\p%!"
) do set ^"$define=break ^& for %\p%$ in (1) do^
@for /f "tokens=1 delims== " %\p%%\p%! in ("%\p%!=%\p%! %\p%^%\p%^%\p%^%\p%!") do^
@for /f %\p%%\p%^^%\p%^^ in ("%\p%^ %\p%^%\p%^%\p%^%\p%^%\p%^%\p%!=%\p%^%\p%!") do @set"
%$define% ^"$for=%\p%%\p%~$=_Always_prefix_macros_with_'$'_during_their_definition._=:$param"
for %$for:param=s% in (stdout stderr) do (call :define_stream $%$for:param=s% %$for:param=s%)
goto :EOF
:define_stream (name: string, stream: File = stdout)
setlocal
::: https://learn.microsoft.com/en-us/windows/console/console-handles
set "stream=" & if not "" == "%~2" if /i not "%~2" equ "stdout" if /i "%~2" equ "stdin" (
set "stream=^>^&0"
) else if /i "%~2" equ "stderr" (
set "stream=^>^&2"
) else (
set "stream=^>%~2"
)
endlocal & %$define% ^"%~1=for %$for:param='% in (1 2) do if %$for:param='% equ 2 (%\n%
setlocal EnableDelayedExpansion%\n%
for /f "tokens=1,* delims= " %$for:param=0% in (": %\p%!args%\p%!") do (%\n%
endlocal ^& endlocal ^& (echo(%$for:param=~1%) ^& (call )%\n%
)%\n%
) %stream% else setlocal DisableDelayedExpansion ^& set args= "
goto :EOF
:define_strhex (name: string, prefix: string = "0x", suffix: string = "")
setlocal
set "prefix=%~2" & if "" equ "%~2" if "" equ "%2" (set "prefix=0x")
if defined prefix (set "prefix=%prefix:^=^^^^^^^^%")
if defined prefix (set "prefix=%prefix:!=^^^^^^^!%")
set "suffix=%~3" & if "" equ "%~3" if "" equ "%3" (set "suffix=")
if defined suffix (set "suffix=%suffix:^=^^^^^^^^%")
if defined suffix (set "suffix=%suffix:!=^^^^^^^!%")
endlocal & %$define% ^"%~1=for %$for:param='% in (1 2) do if %$for:param='% equ 2 (%\n%
for /f "tokens=1,2,* delims== " %$for:param=0% in (": %\p%!args%\p%!") do (%\n%
endlocal ^& if not "%$for:param=~1%" equ "" (%\n%
set /a "number=%$for:param=~2% + 0" ^>nul 2^>^&1%\n%
set "map=0123456789abcdef"%\n%
set "digit="%\n%
set "result="%\n%
for /l %$for:param=_% in (1, 1, 8) do (%\n%
set /a "digit=number & 15, number>>=4"%\n%
for %$for:param=d% in (%\p%!digit%\p%!) do (%\n%
set "result=%\p%!map:~%$for:param=d%,1%\p%!%\p%!result%\p%!"%\n%
)%\n%
)%\n%
for %$for:param=v% in (%prefix%%\p%!result%\p%!%suffix%) do (%\n%
endlocal ^& set "%$for:param=~1%=%$for:param=v%" %\n%
)%\n%
)%\n%
)%\n%
) else setlocal EnableDelayedExpansion ^& setlocal ^& set args= "
goto :EOF
:EOF
@call
Code: Select all
null: 0xffffffff
"^": ^^^^ffffffff ::: Doubled?
^^ : ^ffffffff ::: Halved?
"!!": !!ffffffff
!! : !!ffffffff