Code: Select all
[see third post for updated code]

Moderator: DosItHelp
Code: Select all
[see third post for updated code]
Sponge Belly wrote:Could someone please explain why I had to suppress the first 5 chars of rev? The cmd inside the in (…) clause behaves as if it’s receiving input from the command line. The rev var is initialised to nothing, or so I thought. On inspection, it had the value “!rev!”![]()
Code: Select all
set "rev=!rev!!chr!"
Code: Select all
Z:\>set "rev="
Z:\>cmd /V:ON
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
Z:\>set "char=a"
Z:\>set "rev=!rev!!char!"
Z:\>set rev
rev=!rev!a
Code: Select all
echo("!rev!"
Code: Select all
@echo off & setLocal enableExtensions disableDelayedExpansion
(call;) %= sets errorLevel to 0 =%
(set lf=^
%= BLANK LINE REQUIRED =%
)
set "cr=" & if not defined cr for /f "skip=1" %%C in (
'echo(^|replace ? . /w /u'
) do set "cr=%%C"
set ^"orig=^<!-- !^^!^^^^! %%etad%% ^| ^"^^^&^^ --^>^"
call :reverseStr res1 orig || goto end
setLocal enableDelayedExpansion
call :reverseStr res2 orig || (endLocal & goto end)
echo(orig: [!orig!]
echo(res1: [!res1!]
echo(res2: [!res2!]
endLocal
:end - exit program with appropriate errorLevel
endLocal & goto :EOF
:reverseStr result= original=
:: reverses a string
setLocal
set "ddx=!" %= is delayed expansion enabled or disabled? =%
setLocal disableDelayedExpansion
setLocal enableDelayedExpansion
set "die=" & if not defined %2 (
>&2 echo( ERROR: var "%2" not defined & set "die=1"
) else set "str=!%2!" %= if =%
if not defined die for %%L in ("!lf!") ^
do if "!str!" neq "!str:%%~L=!" (
>&2 echo( ERROR: var "%2" contains linefeeds & set "die=1"
) %= if =%
if not defined die for %%C in ("!cr!") ^
do if "!str!" neq "!str:%%~C=!" (
>&2 echo( ERROR: var "%2" contains carriage returns
set "die=1"
) %= if =%
if defined die (
endLocal & endLocal & endLocal & set "%1=" & exit /b 1
) %= if =%
endLocal
:: reverse string
for /f delims^=^ eol^= %%R in ('
cmd /von /q /c set "rev=!%2:~-1!" ^^^& ^
set "str=!%2:~0,-1!" ^^^& for /l %%I in (^) do ^
if defined str (set "rev=!rev!!str:~-1!" ^^^& ^
set "str=!str:~0,-1!"^) else (echo(^!rev^!^^^& exit 0^)
') do set "str=%%R"
setLocal enableDelayedExpansion
:: double carets if returning to enabled delayed expansion
if not defined ddx set "str=!str:^=^^^^!"
:: double quotes
set "str=!str:"=""!"
:: escape exclaims if returning to enabled delayed expansion
if not defined ddx set "str=%str:!=^^^!%" !
:: restore quotes
set "str=!str:""="!"
:: use for /f to pass string back over endLocal boundary
for /f delims^=^ eol^= %%A in ("!str!") do (
endLocal & endLocal & endLocal & set "%1=%%A" !
) %= for /f =%
exit /b 0 %= reverseStr =%
Code: Select all
:reverse [%1 - string to reverse ; %2 - if defined will store the result in variable with same name]
@echo off
setlocal disableDelayedExpansion
set "str=%~1"
set LF=^
rem ** Two empty lines are required
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
set $strLen=for /L %%n in (1 1 2) do if %%n==2 (%\n%
for /F "tokens=1,2 delims=, " %%1 in ("!argv!") do (%\n%
set "str=A!%%~2!"%\n%
set "len=0"%\n%
for /l %%A in (12,-1,0) do (%\n%
set /a "len|=1<<%%A"%\n%
for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"%\n%
)%\n%
for %%v in (!len!) do endlocal^&if "%%~b" neq "" (set "%%~1=%%v") else echo %%v%\n%
) %\n%
) ELSE setlocal enableDelayedExpansion ^& set argv=,
%$strLen% len,str
setlocal enableDelayedExpansion
set /a half=len/2
set "res=!str:~%half%,-%half%!"
for /L %%C in (%half%,-1,0) do (
set /a len=%len%-1-%%C
if %%C neq %half% (
for %%c in (!len!) do (
set "res=!str:~%%c,1!!res!!str:~%%C,1!"
)
)
)
endlocal & endlocal & if "%~2" NEQ "" (set %~2=%res%) else echo %res%
Code: Select all
@echo off
setlocal disableDelayedExpansion
if NOT defined stringVar set "stringVar=%~1"
if NOT defined stringVar echo no stringVar defined! & exit /b
call :setAllMacros
setlocal enabledelayedexpansion
%strLen(var):var=!stringVar!%
set /a loop=3
if %len% gtr 150 set /a loop=len/10
if %len% gtr 600 set /a loop=len/25
if %len% gtr 1500 set /a loop=len/90
endlocal & set /a loop=%loop%, len=%len%
rem Reverse var
set "rev=!R:X,1!"
set "revers="
set "reverStr="
setlocal enabledelayedexpansion
for /l %%L in (1 1 %loop%) do set "revers=!Rev:X=~%%L!!revers!"
for /l %%L in (0 %loop% %len%) do (
set "R= !stringVar:~%%L!"
set "ReverStr=%revers%!ReverStr!"
)
if "%~2" equ "" echo !ReverStr!
for /f delims^=^ eol^= %%i in ("!ReverStr!") do (
endlocal
endlocal
if "%~2" neq "" set "%~2=%%i"
)
exit /b
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:setAllMacros
:: define LF as a Line Feed (newline) character
set ^"LF=^
^" Above empty line is required - do not remove
:: define a newline with line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:strLen.var
:: create a macro with reduced For loops
:: Parenthesis are included
:: usage: %strLen(var):var=!stringVar!%
::
@for %%T in ("%temp%\%~n0.tmp.cmd") do @(
@ >%%T (
echo( @set strLen(var^)=(%%\n%%
echo( set "str=Avar"%%\n%%
echo( set "len=0"%%\n%%
for /l %%i in (12 -1 0) do @(
echo( set /a "len|=1<<%%i"%%\n%%
echo( for %%%%# in (!len!^) do if .!str:~%%%%#^^^^^^,1!==. set /a "len&=~1<<%%i"%%\n%%
)
echo(^)
)
call %%T
del %%T
)
set "LF="
set "\n="
exit /B
Code: Select all
@echo off
setlocal disableDelayedExpansion
if NOT defined stringVar set "stringVar=%~1"
if NOT defined stringVar echo no stringVar defined! & exit /b
set "rev=!R:~X,1!"
set "revMax="
set "revers="
set "reverStr="
set ^"LF=^
^" Above empty line is required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
set forI= set /a "len|=1<<FORi"%\n%
for %%# in (!len!^) do if .!str:~%%#^^^,1!==. ( set /a "len&=~1<<FORi"%\n%
^) else if not defined revMax set /a "revMax=(FORi-3)*(FORi-3)+10"
@set strLen(var^)=(%\n%
set "str=Avar"%\n%
set "len=0"
setlocal enabledelayedexpansion
for /l %%i in (12 -1 0) do @ set "strLen(var)=!strLen(var)!!lf!!forI:FORi=%%i!"
set strLen(var)=!strLen(var)!!lf!)
%strLen(var):var=!stringVar!%
set /a L=loop=1
for /l %%L in (1 1 %revMax%) do if !L! lss %len% ( set /a L=%%L*%%L, loop=%%L
set "revers=!Rev:X=%%L!!revers!"
)
if not defined revers ( set "ReverStr=!stringVar!"
) else for /l %%L in (0 %loop% %len%) do ( set "R= !stringVar:~%%L!"
set "ReverStr=%revers%!ReverStr!"
)
if "%~2" equ "" echo !ReverStr!
for /f delims^=^ eol^= %%i in ("!ReverStr!") do (
endlocal
endlocal
if "%~2" neq "" set "%~2=%%i"
)
exit /b