A probably stupid question about .btm file argument parsing...

#1
As it says in the title, this is probably a stupid question about a very simple subject: Argument parsing by .btm files. Specifically, the following very short and simple .btm file (named "Sample.btm"):
Code:
@Echo Off
SetLocal
Set I=0
   Do While "%[%I]" != ""
      @Echo I:   %I  Value: %[%I]
      Set I=%@Inc[%I]
   EndDo 
EndLocal
Quit 0
When fed the following arguments:
Code:
Sample A = B C
produces the following output:
Code:
I: 0   Value: Sample
I: 1   Value: A
Obviously, the "=" and everything after it is missing. What obvious thing am I missing here?
 
#2
I think '=' is a separator, but that doesn't explain the missing args. If you
throw in

Code:
echo number of args: %#
it gets more interesting:

Code:
v:\> batargs a = b c
number of args: 4
I:   0  Value: batargs
I:   1  Value: a
It works better if '=' is immediately preceded by something:

Code:
v:\> batargs a= b c
number of args: 3
I:   0  Value: batargs
I:   1  Value: a
I:   2  Value: b
I:   3  Value: c
I think your loop is terminating at the empty ("") arg just before the '='.

I think it's undesirable behavior (and seem to recall its being discussed in the
past with no change).

On Thu, 15 Sep 2011 22:35:48 -0400, mathewsdw <> wrote:

|As it says in the title, this is probably a stupid question about a very simple subject: Argument parsing by .btm files. Specifically, the following very short and simple .btm file (named "Sample.btm"):
|
|Code:
|---------
|@Echo Off
|SetLocal
|Set I=0
| Do While "%[%I]" != ""
| @Echo I: %I Value: %[%I]
| Set I=%@Inc[%I]
| EndDo
|EndLocal
|Quit 0
|---------
|When fed the following arguments:
|
|Code:
|---------
|Sample A = B C
|---------
|produces the following output:
|
|Code:
|---------
|I: 0 Value: Sample
|I: 1 Value: A
|---------
|Obviously, the "=" and everything after it is missing. What obvious thing am I *missing* here?
 
#3
If it's for CMD-compatibility, it doesn't quite get there:

Code:
v:\> type cmdargs.bat
@echo off
echo arg0 is %0
echo arg1 is %1
echo arg2 is %2
echo arg3 is %3
echo arg4 is %4

CMD:

v:\> cmd /c cmdargs.bat a = b c
arg0 is cmdargs.bat
arg1 is a
arg2 is b
arg3 is c
arg4 is

TCC:

v:\> cmdargs.bat a = b c
arg0 is cmdargs.bat
arg1 is a
arg2 is
arg3 is b
arg4 is c
 
#4
I think '=' is a separator, but that doesn't explain the missing args. If you
throw in

Code:
echo number of args: %#
it gets more interesting:

Code:
v:\> batargs a = b c
number of args: 4
I:   0  Value: batargs
I:   1  Value: a
It works better if '=' is immediately preceded by something:

Code:
v:\> batargs a= b c
number of args: 3
I:   0  Value: batargs
I:   1  Value: a
I:   2  Value: b
I:   3  Value: c
I think your loop is terminating at the empty ("") arg just before the '='.

I think it's undesirable behavior (and seem to recall its being discussed in the past with no change).
Vince, thank you, you are obviously correct. But first, I do not remember the "=" sign being used as a separator (separator for what and when? Could be my bad memory again...), so if I change the loop terminating condition to
Code:
Do While %I LE %#
every thing works almost as I would have expected, except that, as you indicate, the argument that is an equals sign is replaced by a null argument (truthfully. probably based on my C++ experience(s), I didn't know that "null" arguments were even possible. It makes me wonder how many programs I have written that test for a null argument rather than using the "argc" variable (I tend to write code like that because it is simpler; even if I used "argc" as a loop counter I would still have to iterate the "argument" pointer anyway (two operations instead of one), and not only that but I would still have to test for a "null" argument anyway or the C++ program would crash (checking for the "contents" of memory address "0" is not allowed) and whether I should go systematically through all of them and change them!!!) (Breaking news!!! I just a wrote a quick and dirty C++ program to test that and it worked just fine! The "=" sign is there just as every other argument that is not an "=" sign is there. It would appear that the "=" sign is "eaten" strictly by the argument parser for batch files in TCC. Phew!!!!)
 
Jul 1, 2008
81
0
71
Montreal
#5
You're not missing anything. There has long been a discrepancy between the output of different ways of reading batch file arguments. Consider this:
Code:
echo ==================
echo method 1   do arg in /l %%*
set cnt=0
do arg in /l %*
  set cnt=%@inc[%cnt]
  echo arg %cnt == %arg
enddo
echo ==================
echo method 2   do cnt = 0 to %%#
do cnt = 0 to %#
  echo arg %cnt == %[%cnt]
enddo
echo ==================
echo method 3   do while "%%[%%i]" != ""
set i=0
do while "%[%i]" != ""
  echo i:   %i  value: %[%i]
  set i=%@inc[%i]
enddo
produces this output:
Code:
==================
method 1   do arg in /l %*
arg 1 == 1
arg 2 == 2
arg 3 == =
arg 4 == 4
==================
method 2   do cnt = 0 to %#
arg 0 == test
arg 1 == 1
arg 2 == 2
arg 3 ==
arg 4 == 4
==================
method 3   do while "%[%i]" != ""
i:   0  value: test
i:   1  value: 1
i:   2  value: 2
Your take, method 3, kicks out of the loop as instructed, i.e. when %3 returns an empty string. I can't offer an explanation for the differences. There are also quirks interpreting batch file arguments in double quotes. I have found the most reliable approach is method 2 above.
--
Peter

As it says in the title, this is probably a stupid question about a very simple subject: Argument parsing by .btm files... What obvious thing am I missing here?
 

samintz

Scott Mintz
May 20, 2008
1,294
11
Solon, OH, USA
#6
Method 1 is kinda nifty. You get
these results with a command line of "a b=c":

Code:
=================method 1   do arg in /l %*
arg 1 == a
arg 2 == b=c
=================method 2   do cnt = 0 to %#
arg 0 == "foo"
arg 1 == "a"
arg 2 == "b"
arg 3 == "c"
=================method 3   do while "%[%i]"
!= ""
i:   0  value: foo
i:   1  value: a
i:   2  value: b
i:   3  value: c
-Scott

Peter Bratton <> wrote
on 09/16/2011 09:35:45 AM:


> You're not missing anything. There has long been a discrepancy
> between the output of different ways of reading batch file
> arguments. Consider this:
> Code:
> echo =================> echo method 1 do arg in /l %%*
> set cnt=0
> do arg in /l %*
> set cnt=%@inc[%cnt]
> echo arg %cnt == %arg
> enddo
> echo =================> echo method 2 do cnt = 0 to %%#
> do cnt = 0 to %#
> echo arg %cnt == %[%cnt]
> enddo
> echo =================> echo method 3 do while "%%[%%i]" != ""
> set i=0
> do while "%[%i]" != ""
> echo i: %i value: %[%i]
> set i=%@inc[%i]
> enddo
> produces this output:
> Code:
> =================> method 1 do arg in /l %*
> arg 1 == 1
> arg 2 == 2
> arg 3 == > arg 4 == 4
> =================> method 2 do cnt = 0 to %#
> arg 0 == test
> arg 1 == 1
> arg 2 == 2
> arg 3 => arg 4 == 4
> =================> method 3 do while "%[%i]" != ""
> i: 0 value: test
> i: 1 value: 1
> i: 2 value: 2
> Your take, method 3, kicks out of the loop as
instructed, i.e. when

> %3 returns an empty string. I can't offer an explanation for the
> differences. There are also quirks interpreting batch file arguments
> in double quotes. I have found the most reliable approach is method
2 above.

> --
> Peter

> Quote:
>
> Originally Posted by mathewsdw [image removed]
> As it says in the title, this is probably a stupid
question about a

> very simple subject: Argument parsing by .btm files... What obvious

> thing am I missing here?
>
>
>
 
#7
On Fri, 16 Sep 2011 09:35:46 -0400, Peter Bratton <> wrote:

|You're not missing anything. There has long been a discrepancy between the output of different ways of reading batch file arguments. Consider this:
|
|Code:
|---------
|echo =================|echo method 1 do arg in /l %%*
|set cnt=0
|do arg in /l %*
| set cnt=%@inc[%cnt]
| echo arg %cnt == %arg
|enddo
|echo =================|echo method 2 do cnt = 0 to %%#
|do cnt = 0 to %#
| echo arg %cnt == %[%cnt]
|enddo
|echo =================|echo method 3 do while "%%[%%i]" != ""
|set i=0
|do while "%[%i]" != ""
| echo i: %i value: %[%i]
| set i=%@inc[%i]
|enddo
|---------
|produces this output:
|
|Code:
|---------
|=================|method 1 do arg in /l %*
|arg 1 == 1
|arg 2 == 2
|arg 3 == |arg 4 == 4
|=================|method 2 do cnt = 0 to %#
|arg 0 == test
|arg 1 == 1
|arg 2 == 2
|arg 3 =|arg 4 == 4
|=================|method 3 do while "%[%i]" != ""
|i: 0 value: test
|i: 1 value: 1
|i: 2 value: 2
|---------
|Your take, method 3, kicks out of the loop as instructed, i.e. when %3 returns an empty string. I can't offer an explanation for the differences. There are also quirks interpreting batch file arguments in double quotes. I have found the most reliable approach is method 2 above.

The difference between methods 1 and 3 is expected. In method 1 DO doesn't know
the string (%*) is a collection of batch file args; it's just a string, and it
contains 4 tokens.