Code: Select all
%SET/S% variable:~start,size=substring to insert
Code: Select all
@echo off
::SET/S - Macro that replace a substring in a variable
::Antonio Perez Ayala - Dec/26/2011
setlocal DisableDelayedExpansion
set LF=^
::Above 2 blank lines are required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
:SET/S variable:~start[,size]=substring
set set/s=for %%n in (1 2) do if %%n==2 (%\n%
for /F "tokens=1* delims==" %%1 in ("!argv!") do (%\n%
set argv=%%1%\n%
set substring=%%2%\n%
)%\n%
for /F "tokens=1-3 delims=:~, " %%1 in ("!argv!") do (%\n%
set "value=!%%1!"%\n%
if not defined value set "value= "%\n%
set size=%%3%\n%
if not defined size (%\n%
if "%%2" == "-0" (%\n%
set "result=!value!!substring!"%\n%
) else (%\n%
if "!value:~%%2,1!" == "" (%\n%
for /L %%A in (1,1,%%2) do set "value=!value! "%\n%
set "result=!value:~0,%%2!!substring!"%\n%
) else (%\n%
set "result=!value:~0,%%2!!substring!!value:~%%2!"%\n%
)%\n%
)%\n%
) else (%\n%
if "%%2" == "-0" (%\n%
set "result=!value!!substring!"%\n%
) else if "!value:~%%2,1!" == "" (%\n%
for /L %%A in (1,1,%%2) do set "value=!value! "%\n%
set "result=!value:~0,%%2!!substring!"%\n%
) else if not "!size:~0,1!" == "-" (%\n%
set /A restart=%%2+%%3%\n%
for %%r in (!restart!) do set "result=!value:~0,%%2!!substring!!value:~%%r!"%\n%
) else (%\n%
set "result=!value:~0,%%2!!substring!"%\n%
if not "%%3" == "-0" set "result=!result!!value:~%%3!"%\n%
)%\n%
)%\n%
for %%v in ("!result!") do endlocal ^& set "%%1=%%~v"%\n%
)%\n%
) else setlocal enableDelayedExpansion ^& set argv=
for /F "skip=4 delims=pR tokens=1,2" %%a in (
'reg query hkcu\environment /v temp' ) do set TAB=%%b
setlocal EnableDelayedExpansion
cls
echo/
echo SET STRING=0123456789
echo/
for %%a in (0 4 -3 -0 13) do (
set string=0123456789
%set/s% string:~%%~a=abc
echo %%SET/S%% STRING:~%%~a=abc!TAB!!TAB!!string!
)
echo/
for %%a in ("0,3" "4,4") do (
set string=0123456789
%set/s% string:~%%~a=abc
echo %%SET/S%% STRING:~%%~a=abc!TAB!!TAB!!string!
)
for %%a in ("-3,1" "-0,2" "13,4") do (
set string=0123456789
%set/s% string:~%%~a=abc
echo %%SET/S%% STRING:~%%~a=abc!TAB!!string!
)
echo/
for %%a in ("0,-3" "4,-4" "-3,-1" "-0,-2" "13,-4") do (
set string=0123456789
%set/s% string:~%%~a=abc
echo %%SET/S%% STRING:~%%~a=abc!TAB!!string!
)
echo/
for %%a in ("0,-0" "4,-0" "-3,-0" "-0,-0" "13,-0") do (
set string=0123456789
%set/s% string:~%%~a=abc
echo %%SET/S%% STRING:~%%~a=abc!TAB!!string!
)
echo/
Code: Select all
SET STRING=0123456789
%SET/S% STRING:~0=abc abc0123456789
%SET/S% STRING:~4=abc 0123abc456789
%SET/S% STRING:~-3=abc 0123456abc789
%SET/S% STRING:~-0=abc 0123456789abc
%SET/S% STRING:~13=abc 0123456789 abc
%SET/S% STRING:~0,3=abc abc3456789
%SET/S% STRING:~4,4=abc 0123abc89
%SET/S% STRING:~-3,1=abc 0123456abc89
%SET/S% STRING:~-0,2=abc 0123456789abc
%SET/S% STRING:~13,4=abc 0123456789 abc
%SET/S% STRING:~0,-3=abc abc789
%SET/S% STRING:~4,-4=abc 0123abc6789
%SET/S% STRING:~-3,-1=abc 0123456abc9
%SET/S% STRING:~-0,-2=abc 0123456789abc
%SET/S% STRING:~13,-4=abc 0123456789 abc
%SET/S% STRING:~0,-0=abc abc
%SET/S% STRING:~4,-0=abc 0123abc
%SET/S% STRING:~-3,-0=abc 0123456abc
%SET/S% STRING:~-0,-0=abc 0123456789abc
%SET/S% STRING:~13,-0=abc 0123456789 abc
Code: Select all
%SET/A% variable=Func2(Param1,Param2)+var*Func1(Param)+234-Func0()
Code: Select all
:Func2 Param1 Param2 Result=
setlocal EnableDelayedExpansion
rem Do some calculation on Param1 and Param2, and get Result
rem . . .
endlocal & set %3=%result%
exit /B
Code: Select all
set /A "Param1=%~1"
set /A "Param2=%~2"
Code: Select all
%SET/A% variable=Func2(var3*var4,3*var5+6)+var*Func1(var1*2)+234-Func0()
This is SET/A macro:
Code: Select all
@echo off
::SET/A - Macro that expand function results in arithmetic expressions
::Antonio Perez Ayala
::Dec/26/2011 - v1.0 Parse functions, replace their return values, execute SET /A
setlocal DisableDelayedExpansion
set LF=^
::Above 2 blank lines are required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
set set/a=for %%n in (1 2) do if %%n==2 (%\n%
rem 1- Store functions start and size in setA.F# array %\n%
for %%v in (N opPos exprLen) do set setA.%%v=0%\n%
for /L %%p in (12,-1,0) do (%\n%
set /A "setA.exprLen|=1<<%%p"%\n%
for %%l in (!setA.exprLen!) do if "!setA.expr:~%%l,1!"=="" set /A "setA.exprLen&=~1<<%%p"%\n%
)%\n%
set "setA.copyExpr=!setA.expr!"%\n%
for %%o in (+ - / %%%% ^^! ^^^> ^^^< ^^^& ^^^|) do set "setA.copyExpr=!setA.copyExpr:%%o=*!"%\n%
for %%v in (parenLevel namePos funcLevel) do set setA.%%v=%\n%
for /L %%c in (0,1,!setA.exprLen!) do (%\n%
set setA.char=!setA.copyExpr:~%%c,1!%\n%
if defined setA.funcLevel (%\n%
if "!setA.char!" == ")" (%\n%
set /A setA.funcLevel-=1%\n%
if !setA.funcLevel! == 0 (%\n%
set /A setA.N+=1, setA.funcLevel=%%c-setA.namePos%\n%
for %%n in (!setA.N!) do (%\n%
set "setA.F%%n=!setA.namePos! !setA.funcLevel!"%\n%
)%\n%
for %%v in (namePos funcLevel) do set setA.%%v=%\n%
rem noelse%\n%
)%\n%
) else if "!setA.char!" == "(" (%\n%
set /A setA.funcLevel+=1%\n%
)%\n%
) else if defined setA.namePos (%\n%
if "!setA.char!" == "(" (%\n%
set setA.funcLevel=1%\n%
) else (%\n%
if "!setA.char!" == "=" set setA.opPos=%%c^& set setA.namePos=%\n%
if "!setA.char!" == "*" set setA.opPos=%%c^& set setA.namePos=%\n%
if "!setA.char!" == "~" set setA.opPos=%%c^& set setA.namePos=%\n%
)%\n%
) else if defined setA.parenLevel (%\n%
if "!setA.char!" == ")" (%\n%
set /A setA.parenLevel-=1%\n%
if !setA.parenLevel! == 0 set setA.parenLevel=%\n%
) else if "!setA.char!" == "(" (%\n%
set /A setA.parenLevel+=1%\n%
)%\n%
) else if defined setA.opPos (%\n%
if "!setA.char!" == "(" (%\n%
set setA.parenLevel=1%\n%
set setA.opPos=%\n%
) else if not "!setA.char!" == " " (%\n%
set setA.namePos=%%c%\n%
set setA.opPos=%\n%
)%\n%
) else (%\n%
if "!setA.char!" == "=" set setA.opPos=%%c%\n%
if "!setA.char!" == "*" set setA.opPos=%%c%\n%
if "!setA.char!" == "~" set setA.opPos=%%c%\n%
)%\n%
)%\n%
rem 2- Call setA.F# functions and replace they by their return values %\n%
set setA.copyExpr=%\n%
set setA.lastStartCopy=0%\n%
for /L %%i in (1,1,!setA.N!) do (%\n%
for /F "tokens=1,2" %%a in ("!setA.F%%i!") do (%\n%
set setA.func=!setA.expr:~%%a,%%b!%\n%
set /A setA.lastSizeCopy=%%a-setA.lastStartCopy%\n%
set /A setA.newStartCopy=%%a+%%b+1%\n%
)%\n%
for /F "tokens=1* delims=(" %%a in ("!setA.func!") do call %%a %%b setA.R=%\n%
for /F "tokens=1,2" %%a in ("!setA.lastStartCopy! !setA.lastSizeCopy!") do (%\n%
set "setA.copyExpr=!setA.copyExpr!!setA.expr:~%%a,%%b!!setA.R!"%\n%
)%\n%
set setA.lastStartCopy=!setA.newStartCopy!%\n%
)%\n%
set /A setA.lastSizeCopy=setA.exprLen-setA.lastStartCopy+1%\n%
for /F "tokens=1,2" %%a in ("!setA.lastStartCopy! !setA.lastSizeCopy!") do (%\n%
set "setA.copyExpr=!setA.copyExpr!!setA.expr:~%%a,%%b!"%\n%
)%\n%
rem 3- Execute SET /A command on final expression %\n%
set /A !setA.copyExpr!%\n%
) else set setA.expr=
setlocal EnableDelayedExpansion
set "string=this has a length of 23"
%set/a% length=:StrLen(string)
echo The result is: %length%
%set/a% sum=:StrLen(string) + :StrLen("And this have 16")
echo The sum of two lengths is: %sum%
%set/a% result=:StrLen(String)*1000 / sum
echo The first lenght times 1000 divided by the previous sum is: %result%
goto :EOF
:StrLen string [result=[adjust]]
setlocal enableDelayedExpansion
set str=%1
set str=!str:"= !
if "!str:~0,1!" == " " (
set "str=0%~1"
) else (
set "str=0!%1!"
)
set len=0
for /L %%A in (12,-1,0) do (
set /A "len|=1<<%%A"
for %%B in (!len!) do if "!str:~%%B,1!" == "" set /A "len&=~1<<%%A"
)
for %%v in (!len!) do endlocal&if not "%2" == "" (set /A "%2=%%v%3") else echo %%v
exit /B
You must be aware that SET/A macro does NOT include the usual SETLOCAL/ENDLOCAL commands.Output wrote: The result is: 23
The sum of two lengths is: 39
The first lenght times 1000 divided by the previous sum is: 589
The original SET /A command may assign values to several variables in the same expression:
Code: Select all
SET /A var1=1*2+3, var2=123*456/321, var3=var1+var2
To avoid modification of local variables, all variable names used in SET/A macro have the "setA." prefix. However, if %set/a% macro would be used in a nested way, the function that create the nesting MUST include a SETLOCAL/ENDLOCAL pair, as described below.
EDIT: I slightly modified StrLen function so it can get the string both as variable name or "constant" in quotes.
Antonio