Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

"Functions" in cmd.exe batch files

Aug
1,916
68
This (test.cmd) works in cmd.exe
Code:
@echo off
ver
where cmd.exe
set "TwoParams(x,y)= x=x,y , y=(x,y)"
set /A "test=%TwoParams(x,y):x,y=123,456%"
echo x=%x%, y=%y%

...returns...
Code:
c:\utils>test.cmd

Microsoft Windows [Version 6.1.7601]
C:\Windows\System32\cmd.exe
x=123, y=456

When I run it under CMDebug using CMD Syntax, it returns;
Code:
TCC-RT  23.00.17 x64   Windows 7 [Version 6.1.7601]
x=123456, y=456

...which is not what I get with cmd.exe

When I run it under CMDebug using TCC Syntax, it returns;
Code:
TCC-RT  23.00.17 x64   Windows 7 [Version 6.1.7601]
C:\Windows\System32\cmd.exe
x=123456, y=456

When I run test.cmd from TCC, it returns;
Code:
c:\users\jlc\utils>test.cmd

TCC  23.00.23 x64   Windows 7 [Version 6.1.7601]
C:\Windows\System32\cmd.exe
TCC: C:\Users\jlc\utils\test.cmd [5]  Unbalanced parentheses "(x"
x=, y=

Joe
 
Joe, can you explain what CMD is doing.

At the CMD command line, I get this.
Code:
V:\> set "TwoParams(x,y)= x=x,y , y=(x,y)"

V:\> set /A "test=%TwoParams(x,y):x,y=123,456%"
456
V:\> echo %test%
123

If the "final value of the expression" were 456 (as auto-echoed by SET /A) why was 123 assigned to the variable "test"?
 
A better example;
Code:
@echo off
setlocal EnableDelayedExpansion
ver
where cmd.exe
set "Max(x,y)=( x=x,y, y=(x,y), c=(x-y>>31)+1, c*x+^^^!c*y )"
set "Min(x,y)=!Max(x,y):x-y=y-x!"

echo/
set numbers=123 456
set /A "n1=%numbers: =,n2=%, max=%Max(x,y):x,y=n1,n2%, min=%Min(x,y):x,y=n1,n2%"
echo Max = %max%,  Min = %min%
echo x=%x%, y=%y%

Joe
 
I can sort of grasp the string substitution when invoking a function. But the way the function itself works is voodoo. Can you explain what exactly the MAX function is doing?
Code:
it looks like when the set /A is executed, you get:
set /A "n1=123,n2=456, max=( x=123,456, y=(123,456), c=(123-456>>31)+1, 0*123+^^^!0*456 )"

It looks like SET /A var=x,y sets var to x. And SET /A var=(x,y), sets var to y. And it looks like the expression is evaluated from left to right.
But what do the 3 ^^^'s do?
 
The 3 ^^^'s escape the ! (boolean NOT) as delayed expansion is enabled.

Joe
 
The first issue here is that due to the use of invalid characters in the variable name, you have to set CMDVariables=Yes in your TCMD.INI for TCC to accept the variable name in "test=%TwoParams(x,y):x,y=123,456%". TCC then, like CMD, simply accepts anything between the two %'s.

The second issue is that TCC sees "x=123,456" and interprets the comma as a thousands separator, not an argument delimiter. (TCC works fine with the equally silly undocumented CMD syntax "set /a x=1,y=2,z=3" because the comma isn't embedded in a numeric string.)

The third issue is the undocumented CMD behavior when you give it multiple arguments. For example:

set /a test=123,456

echos "456" (at the command prompt, but not in a batch file), and sets test to 123. That's a little odd, but not as odd as issue four:

set /a test=(123,456)

which sets test to 456.

Now, I can support issue #2 by disallowing thousands separators (not a big issue, because only CMD batch files would be using this grotesque syntax anyway).

Regarding #3 and #4 -- I'm unconvinced that the CMD authors intended this behavior (and if they did, someone should slap them upside the head). But if someone wants to post it in the Suggestions Forum (with a convincing explanation of why this is a good idea), I'll consider it for a future version.
 

Similar threads

Replies
0
Views
1K
Back
Top