[Solved] Return ANY string across ENDLOCAL boundry - BUG!
Posted: 22 May 2011 20:11
Noooooooo!
I just discovered a serious bug in the "magic" code that Jeb developed here :chr, :asc, :str2hex, :hex2str
The code is intended to return any string across an ENDLOCAL boundry, whether or not delayed expansion is enabled or disabled. But it doesn't work if the string contains any of the following: %A, %B, %C, %L.
The results are weird, especially for %B. I am mystified why those strings don't work, yet %~A, %~B, %~C and %~L work perfectly.
I have been lovin' the technique and have used it in a number of functions. I hope this doesn't mean the whole house of cards is collapsing
Jeb - do you see a way to fix this
Here is Jeb's original test code, with the failing new test cases appended to the "zero" line.
and the unfortunate results are:
Dave Benham
I just discovered a serious bug in the "magic" code that Jeb developed here :chr, :asc, :str2hex, :hex2str
The code is intended to return any string across an ENDLOCAL boundry, whether or not delayed expansion is enabled or disabled. But it doesn't work if the string contains any of the following: %A, %B, %C, %L.
The results are weird, especially for %B. I am mystified why those strings don't work, yet %~A, %~B, %~C and %~L work perfectly.
I have been lovin' the technique and have used it in a number of functions. I hope this doesn't mean the whole house of cards is collapsing
Jeb - do you see a way to fix this
Here is Jeb's original test code, with the failing new test cases appended to the "zero" line.
Code: Select all
@echo off
setlocal EnableDelayedExpansion
cls
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
set LF=^
rem TWO Empty lines are neccessary
set "original=zero*? %%~A%%~B%%~C%%~L :%%A:%%B:%%C:%%L:!LF!one&line!LF!two with exclam^! !LF!three with "quotes^&"&"!LF!four with ^^^^ ^| ^< ^> ( ) ^& ^^^! ^"!LF!xxxxxwith CR!CR!five !LF!six with ^"^"Q ^"^"L still six "
setlocal DisableDelayedExpansion
call :lfTest result original
setlocal EnableDelayedExpansion
echo The result with disabled delayed expansion is:
if !original! == !result! (echo OK) ELSE echo !result!
call :lfTest result original
echo The result with enabled delayed expansion is:
if !original! == !result! (echo OK) ELSE echo !result!
echo !lf!------------------!lf!original:
echo !original!
goto :eof
::::::::::::::::::::
:lfTest
setlocal
set "NotDelayedFlag=!"
echo(
if defined NotDelayedFlag (echo lfTest was called with Delayed Expansion DISABLED) else echo lfTest was called with Delayed Expansion ENABLED
setlocal EnableDelayedExpansion
set "var=!%~2!"
rem echo the input is:
rem echo !var!
echo(
rem ** Prepare for return
set "var=!var:%%=%%~A!"
set "var=!var:"=%%~B!"
for %%a in ("!LF!") do set "var=!var:%%~a=%%~L!"
for %%a in ("!CR!") do set "var=!var:%%~a=%%~C!"
rem ** It is neccessary to use two IF's else the %var% expansion doesn't work as expected
if not defined NotDelayedFlag set "var=!var:^=^^^^!"
if not defined NotDelayedFlag set "var=%var:!=^^^!%" !
set "replace=%% """ !CR!!CR!"
for %%L in ("!LF!") do (
for /F "tokens=1,2,3" %%A in ("!replace!") DO (
ENDLOCAL
ENDLOCAL
set "%~1=%var%" !
@echo off
goto :eof
)
)
and the unfortunate results are:
Code: Select all
lfTest was called with Delayed Expansion DISABLED
The result with disabled delayed expansion is:
zero*? %~A%~B%~C%~L ::d--------:::
one&line
two with exclam!
three with "quotes&"&"
four with ^ | < > ( ) & ! "
five with CR
six with ""Q ""L still six
lfTest was called with Delayed Expansion ENABLED
The result with enabled delayed expansion is:
zero*? %~A%~B%~C%~L ::d--------:::
one&line
two with exclam!
three with "quotes&"&"
four with ^ | < > ( ) & ! "
five with CR
six with ""Q ""L still six
------------------
original:
zero*? %~A%~B%~C%~L :%A:%B:%C:%L:
one&line
two with exclam!
three with "quotes&"&"
four with ^ | < > ( ) & ! "
five with CR
six with ""Q ""L still six
Dave Benham