'
[edit 31/01/12] fixed variable overflow detectionjeb wrote:But as some of them still are substituted by a three character sequence, you need to split it into three chunks to be absolutly sure.
I mainly return macro's, 99.9% is good enough for me...
I've been happily using the safe return macro for a while now
Code: Select all
%= =%set ^"EndlocalR_=(set ^"$replace=%% ^"^"^" !$cr!!$cr!^"%$n1c%
%= =%)^&for /f "tokens=1-3" %%1 in ("!$replace!") do for %%4 in ("!$lf!") do endlocal^&endlocal^&"
Using the following test string, the practical maximum is somewhere around 8192-2515 characters.
Code: Select all
set "$8kVar=_##^^#"q"ex^!#%%1#_" %= 16 chars initially =%
for /l %%! in ( 1, 1, 11 ) do set "$8kVar=!$8kVar!!$8kVar!"
set "$8kVar=!$8kVar!!$8kVar:~0,-2515!"
I already figured the %%~1 tilde replacement was unnecessary.
I wondered why ben &jeb tripled the quotes, and used the tilde during the %%~2 and %%~3 replacement.
I was baffled to discover again it's unnecessary.
Using this optimization, the practical maximum is somewhere around 8192-1965 characters.
Code: Select all
:: --------------------------------------------------------------------------------------------------------------------------
%Pre_% EndlocalR_
:: --------------------------------------------------------------------------------------------------------------------------
:: last updated : 30/01/2012
:: support : onDelayed
:: style : dBenham's replace
::
:: push over endlocal using replace technique
:: (
%= =%set ^"EndlocalR_=(set ^"$replace=%% ^" !$cr!!$cr!^"%$n1c%
%= =%)^&for /f "tokens=1-3" %%1 in ("!$replace!") do for %%4 in ("!$lf!") do endlocal^&endlocal^&"
:: )
%Post_% EndlocalR_ [ok:loaded]
>> "succes.log" echo.EndlocalR_
::
setlocal enabledelayedexpansion
:: (
setlocal &setlocal &%EndlocalR_% set "$cr=%%3" !
::
%@necho_% $cr failed !$cr! $cr succes
setlocal &setlocal
:: (
echo.
:: )
%EndlocalR_% ( %= skip a line to max return size to 8k =%
::
set "$var=one=%%1_%%~4 two=%%2_" !
)
::
%@necho_% !$var!
:: )
endlocal
:: --------------------------------------------------------------------------------------------------------------------------
::goto :skip "()"
%@endoftest%
:skip ()
Code: Select all
>> EndlocalR_
<< EndlocalR_ [ok:loaded]
$cr succes
one=%_
two="_
endoftestDruk op een toets om door te gaan. . .
The Linefeed is a totally different matter though, I failed in finding a way that didn't require the ~, for /f didn't work
Code: Select all
:: --------------------------------------------------------------------------------------------------------------------------
%Pre_% @macroEnd
:: --------------------------------------------------------------------------------------------------------------------------
:: last updated : 31/01/2012
:: support : naDelayed, $cr, $lf, theoretical max 8192, real max 8192-10, replacer practical max 8192-+-1965
:: style : dBenham's replace
::
:: Prepares $defined to be pushed over endlocal using immediate expansion + replace technique,
:: regardless the outer delayed setting
:: (
%= =%set ^"@macroEnd=(setlocal enableDelayedExpansion%$n1c%
%= =%(echo.^&if defined $NotDelayedFlag (set/p= NotDelayed^<nul) else set/p= Delayed^<nul)^>^&2%$n1c%
%= =%%forQ_% ("!$defines!") do set $=^&set $=!%%~?!^&^&(%$n1c%
%= =%(echo.^&set/p= ^<nul^&set "%%~?")^>^&2%$n1c%
%= =%set $1=!$:~0,4096!^&set $2=!$:~4096!^&%forQ_% (1,2) do if defined $%%~? (%$n1c%
%= =%set $=!$%%~?!^&set $=!$:%%=%%1!^&set ^"$=!$:^"=%%2!^"%= Replace by injection =%%$n1c%
%= =%for %%r in ("!$cr!") do set $=!$:%%~r=%%3!%$n1c%
%= =%for %%r in ("!$lf!") do set $=!$:%%~r=%%~4!%$n1c%
%= =%if not defined $NotDelayedFlag call set "$=%%^$:^!=""^!%%"!^&set "$=!$:^=^^!"^&set "$=!$:""=^!"%$n1c%
%= =%set $%%~?=!$!%$n1c%
%= =%)%$n1c%
%= =%)^|^|call :endSimple "@macroEnd, not defined: '!$defines!'"%$n1c%
%= =%set $=^&set $=set "!$defines!=!$1!!$2!"^!^|^|call :endSimple "@macroEnd, variable overflow: '!$defines!'"%$n1c%
%= =%(echo.^&set/p= !$!^<nul)^>^&2%$n1c%
%= =%echo.!$defines!^>^>"succes.log"%$n1c%
%= =%echo.^&set/p"= ^<^< !$defines! [ok:loaded]"^<nul%$n1c%
%= =%)"
:: )
%Post_% @macroEnd [ok:loaded]
>> "succes.log" echo.@macroEnd
:: (
setlocal enableDelayedExpansion &set "$defines=$8kVar"
:: (
%@n2echo_% testing replacer practical max 8192-+-1965
2>nul ( %macroStart_% enableDelayedExpansion )
:: (
set "$8kVar=_##^^#"q"ex^!#%%1#_" %= 16 chars initially =%
for /l %%! in ( 1, 1, 11 ) do set "$8kVar=!$8kVar!!$8kVar!"
set "$8kVar=!$8kVar!!$8kVar:~0,-1965!"
:: )
%@macroEnd%
%EndlocalR_% (
%= =%%$%
)
%@n2echo_% $8kVar=!$8kVar!_
:: )
endlocal
%@endoftest%
Code: Select all
>> @macroEnd
<< @macroEnd [ok:loaded]
testing replacer practical max 8192-+-1965
>> $8kVar
Delayed
$8kVar=_##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"
...
ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1
set "$8kVar=_##^^#%2q%2ex^!#%11#__##^^#%2q%2ex^!#%11#__##^^#%2q%2ex^!#%11#__##^
...
__##^^#%2q%2ex^!#%11"!
<< $8kVar [ok:loaded]
$8kVar=_##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"
...
ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1#__##^#"q"ex!#%1_
endoftestDruk op een toets om door te gaan. . .
I implemented the code, it works perfectly !
If you believe you can optimize, even if it's just a single char, please let me now...