for %1 %%i in (*.*) do [...] not working

Apr 1, 2010
43
0
#1
In CMD, I can place %1 in for statement so that I can control for loop to recursive or not, for example (sizes.bat):
Code:
@echo off

set TOTALSIZE=0
for %1 %%i in (*.*) do call :add %%~zi
echo %TOTALSIZE%
set TOTALSIZE=
goto :EOF


:add
 set /A TOTALSIZE+=%1
but with TCC, it shows usage of for statement no matter %1 is set or not.
 

samintz

Scott Mintz
May 20, 2008
1,271
11
Solon, OH, USA
#2
not working

I haven't tried this but I suspect due to the complex nature of FOR's
syntax, something is getting tripped up.

Change this:
set TOTALSIZE=0
for %1 %%i in (*.*) do call :add %%~zi
echo %TOTALSIZE%

to this:
set TOTALSIZE=0
set foreach=for %1 %%i in (*.*) do call :add %%~zi
%foreach
echo %TOTALSIZE

-Scott

roytam1 <> wrote on 04/15/2010 06:57:16 AM:


> In CMD, I can place %1 in for statement so that I can control for
> loop to recursive or not, for example (sizes.bat):
>
> Code:
> ---------
> @echo off
>
> set TOTALSIZE=0
> for %1 %%i in (*.*) do call :add %%~zi
> echo %TOTALSIZE%
> set TOTALSIZE> goto :EOF
>
>
> :add
> set /A TOTALSIZE+=%1
> ---------
> but with TCC, it shows usage of for statement no matter %1 is set or
not.
 
Apr 1, 2010
43
0
#3
Re: not working

I haven't tried this but I suspect due to the complex nature of FOR's
syntax, something is getting tripped up.

Change this:
set TOTALSIZE=0
for %1 %%i in (*.*) do call :add %%~zi
echo %TOTALSIZE%

to this:
set TOTALSIZE=0
set foreach=for %1 %%i in (*.*) do call :add %%~zi
%foreach
echo %TOTALSIZE

-Scott

roytam1 <> wrote on 04/15/2010 06:57:16 AM:
It doesn't work.

BTW the rewrited script won't work in CMD any longer.
I want to keep CMD compatibility of scripts.
 
#4
not working

I think the problem is the way TCC parses the command line. AFAIK, you can't
use a variable before FOR's loop variable. It's the "%1" that's the problem.
You **can** do that with CMD. Apparently (and again unlike CMD) you also can't
do this:

set command=FOR /L
%command %i in (1,1,2) echo %i

You can, however, use an alias (forget CMD compatibility):

IFF "%1" == "/R"
ALIAS myfor FOR /R
ELSE
ALIAS myfor FOR
ENDIFF
myfor ...

And this, though awkward, works:

v:\> set command=for /l

v:\> %command %%i in (1,1,2) echo %%i
1
2

On Thu, 15 Apr 2010 12:30:10 -0400, samintz <> wrote:

|I haven't tried this but I suspect due to the complex nature of FOR's
|syntax, something is getting tripped up.
|
|Change this:
|set TOTALSIZE=0
|for %1 %%i in (*.*) do call :add %%~zi
|echo %TOTALSIZE%
|
|to this:
|set TOTALSIZE=0
|set foreach=for %1 %%i in (*.*) do call :add %%~zi
|%foreach
|echo %TOTALSIZE
|
|-Scott
|
|roytam1 <> wrote on 04/15/2010 06:57:16 AM:
|
|
|
|---Quote---
|> In CMD, I can place %1 in for statement so that I can control for
|> loop to recursive or not, for example (sizes.bat):
|>
|> Code:
|> ---------
|> @echo off
|>
|> set TOTALSIZE=0
|> for %1 %%i in (*.*) do call :add %%~zi
|> echo %TOTALSIZE%
|> set TOTALSIZE> goto :EOF
|>
|>
|> :add
|> set /A TOTALSIZE+=%1
|> ---------
|> but with TCC, it shows usage of for statement no matter %1 is set or
|---End Quote---
|not.
|
|
|
|
--
- Vince
 

samintz

Scott Mintz
May 20, 2008
1,271
11
Solon, OH, USA
#5
Re: not working

The issue has to do with delayed parsing and FOR's loop variable. When
TCC is parsing the FOR statement it is interpreting %1 as the loop
variable. It has no way of knowing you meant to use %i instead. The
following syntax, while not CMD compatible, does work in TCC. Note both
the use of backticks and double %'s to enable the functionality you're
trying for.

@echo off

set TOTALSIZE=0
set foreach=`for %1 %%i in (*.*) do call :add %%@filesize[%%i]`
echo "%foreach"
%foreach
echo %TOTALSIZE
set TOTALSIZEgoto :EOF


:add
set /A TOTALSIZE+=%1

As an alternative using purely TCC syntax:
echo %@filesize[*.*]

or

echo %@eval[%@execstr[4,dir /s /u2]]

-Scott


roytam1 <> wrote on 04/15/2010 12:37:36 PM:


> ---Quote (Originally by samintz)---
> I haven't tried this but I suspect due to the complex nature of FOR's
> syntax, something is getting tripped up.
>
> Change this:
> set TOTALSIZE=0
> for %1 %%i in (*.*) do call :add %%~zi
> echo %TOTALSIZE%
>
> to this:
> set TOTALSIZE=0
> set foreach=for %1 %%i in (*.*) do call :add %%~zi
> %foreach
> echo %TOTALSIZE
>
> -Scott
>
> roytam1 <> wrote on 04/15/2010 06:57:16 AM:
> ---End Quote---
> It doesn't work.
>
> BTW the rewrited script won't work in CMD any longer.
> I want to keep CMD compatibility of scripts.
>
>
>
>
 

samintz

Scott Mintz
May 20, 2008
1,271
11
Solon, OH, USA
#6
Re: not working

Actually, I left out the recurse option:

echo %@filesize[*]

or

echo %@filesize[/S *]

-Scott

samintz <> wrote on 04/15/2010 04:26:10 PM:


> The issue has to do with delayed parsing and FOR's loop variable. When
> TCC is parsing the FOR statement it is interpreting %1 as the loop
> variable. It has no way of knowing you meant to use %i instead. The
> following syntax, while not CMD compatible, does work in TCC. Note both

> the use of backticks and double %'s to enable the functionality you're
> trying for.
>
> @echo off
>
> set TOTALSIZE=0
> set foreach=`for %1 %%i in (*.*) do call :add %%@filesize[%%i]`
> echo "%foreach"
> %foreach
> echo %TOTALSIZE
> set TOTALSIZEgoto :EOF
>
>
> :add
> set /A TOTALSIZE+=%1
>
> As an alternative using purely TCC syntax:
> echo %@filesize[*.*]
>
> or
>
> echo %@eval[%@execstr[4,dir /s /u2]]
>
> -Scott
>
>
> roytam1 <> wrote on 04/15/2010 12:37:36 PM:
>
>
>
> ---Quote---
> > ---Quote (Originally by samintz)---
> > I haven't tried this but I suspect due to the complex nature of FOR's
> > syntax, something is getting tripped up.
> >
> > Change this:
> > set TOTALSIZE=0
> > for %1 %%i in (*.*) do call :add %%~zi
> > echo %TOTALSIZE%
> >
> > to this:
> > set TOTALSIZE=0
> > set foreach=for %1 %%i in (*.*) do call :add %%~zi
> > %foreach
> > echo %TOTALSIZE
> >
> > -Scott
> >
> > roytam1 <> wrote on 04/15/2010 06:57:16 AM:
> > ---End Quote---
> > It doesn't work.
> >
> > BTW the rewrited script won't work in CMD any longer.
> > I want to keep CMD compatibility of scripts.
> >
> >
> >
> >
> ---End Quote---
>
>
>
 
Apr 1, 2010
43
0
#7
Re: not working

The issue has to do with delayed parsing and FOR's loop variable. When
TCC is parsing the FOR statement it is interpreting %1 as the loop
variable. It has no way of knowing you meant to use %i instead. The
following syntax, while not CMD compatible, does work in TCC. Note both
the use of backticks and double %'s to enable the functionality you're
trying for.

@echo off

set TOTALSIZE=0
set foreach=`for %1 %%i in (*.*) do call :add %%@filesize[%%i]`
echo "%foreach"
%foreach
echo %TOTALSIZE
set TOTALSIZEgoto :EOF


:add
set /A TOTALSIZE+=%1

As an alternative using purely TCC syntax:
echo %@filesize[*.*]

or

echo %@eval[%@execstr[4,dir /s /u2]]

-Scott


roytam1 <> wrote on 04/15/2010 12:37:36 PM:
but allowing %1 ~ %9 and %* for use as FOR variable breaks compatibility with CMD.

and the example is just a minimal test case for reproducing the issue.
my full script look like this:
Code:
@echo off
setlocal EnableDelayedExpansion
set REDUSIZE=0

for %1 %%i in (*.jpeg;*.jpg) do call :optjpeg "%%~i"
echo Done. %REDUSIZE% bytes freed.

rem clean up
set REDUSIZE=
set rpath=
set FSIZE=
SET SIZEDIFF=
GOTO :EOF

rem sub optjpeg(filename)
:optjpeg
SET SIZEDIFF=0
call :rpath "%~1"
jpegtran.exe -optimize "%~1" "%~1.new"
if errorlevel 1 del "%~1.new" & echo %rpath% ... jpegtran internal error. Skipped.
ujpg.exe "%~1.new" > nul 2>&1
call :fsize "%~1.new"
SET /A SIZEDIFF=%~z1-%FSIZE%
if %FSIZE% EQU 0 del "%~1.new" & echo %rpath% ... Zero byte output. Skipped.
if %SIZEDIFF% LSS 0 del "%~1.new" & echo %rpath% ... Output [%FSIZE%] is larger than original [%~z1]. Skipped.
if %SIZEDIFF% EQU 0 del "%~1.new" & echo %rpath% ... Original and output has same size [%~z1]. Skipped.

if exist "%~1.new" call :overwrite "%~1"
GOTO :EOF

rem sub overwrite(filename)
:overwrite
 set /A REDUSIZE+=%SIZEDIFF%
 echo %rpath% ... from %~z1 to %FSIZE% [%SIZEDIFF%].
  touch -r "%~1" "%~1.new"
 move /y "%~1.new" "%~1"
GOTO :EOF

rem sub rpath(filename) OUT: %rpath%
:rpath
 SET rpath=%~1
 set rpath=!rpath:%CD%\=!
GOTO :EOF

rem sub fsize(filename) OUT: %FSIZE%
:fsize
 IF EXIST %1 (
  SET FSIZE=%~z1
 ) ELSE (
  SET FSIZE=0
 )
GOTO :EOF

endlocal
 
Apr 1, 2010
43
0
#8
Re: not working

I think the problem is the way TCC parses the command line. AFAIK, you can't
use a variable before FOR's loop variable. It's the "%1" that's the problem.
You **can** do that with CMD. Apparently (and again unlike CMD) you also can't
do this:

set command=FOR /L
%command %i in (1,1,2) echo %i

You can, however, use an alias (forget CMD compatibility):

IFF "%1" == "/R"
ALIAS myfor FOR /R
ELSE
ALIAS myfor FOR
ENDIFF
myfor ...

And this, though awkward, works:

v:\> set command=for /l

v:\> %command %%i in (1,1,2) echo %%i
1
2

On Thu, 15 Apr 2010 12:30:10 -0400, samintz <> wrote:

|I haven't tried this but I suspect due to the complex nature of FOR's
|syntax, something is getting tripped up.
|
|Change this:
|set TOTALSIZE=0
|for %1 %%i in (*.*) do call :add %%~zi
|echo %TOTALSIZE%
|
|to this:
|set TOTALSIZE=0
|set foreach=for %1 %%i in (*.*) do call :add %%~zi
|%foreach
|echo %TOTALSIZE
|
|-Scott
|
|roytam1 <> wrote on 04/15/2010 06:57:16 AM:
|
|
|
|---Quote---
|> In CMD, I can place %1 in for statement so that I can control for
|> loop to recursive or not, for example (sizes.bat):
|>
|> Code:
|> ---------
|> @echo off
|>
|> set TOTALSIZE=0
|> for %1 %%i in (*.*) do call :add %%~zi
|> echo %TOTALSIZE%
|> set TOTALSIZE> goto :EOF
|>
|>
|> :add
|> set /A TOTALSIZE+=%1
|> ---------
|> but with TCC, it shows usage of for statement no matter %1 is set or
|---End Quote---
|not.
|
|
|
|
--
- Vince
but replace %%~zi with %%@filesize[%%i] works.
TCC kills %%~zi here.
Code:
@echo off

set TOTALSIZE=0
set FORSW=for %1
%FORSW% %%i in (*.*) do call :add %%@filesize[%%i]
echo %TOTALSIZE%
set TOTALSIZE=
goto :EOF


:add
 set /A TOTALSIZE+=%1
 

samintz

Scott Mintz
May 20, 2008
1,271
11
Solon, OH, USA
#9
Re: not working

I have not tested this script, but this is an equivilent TCC script to
what you are attempting to do in CMD:

Code:
@echo off
setlocal
set REDUSIZE=0
do jpg in %1 *.jpeg;*.jpg
        f:\app_re~1\jpegtran.exe -optimize "%jpg" "%jpg.new"
        iff errorlevel 1 then
                del "%jpg.new"
                echo %@filename[%jpg] ... jpegtran internal error. 
Skipped.
                iterate
        endiff
        f:\app_re~1\ujpg.exe "%jpg.new" > nul 2>&1
        set fsize=%@filesize[%jpg.new]
        iff %fsize LE 0 then
                echo %@filename[%jpg] ... Zero byte output. Skipped.
                iterate
        elseiff %fsize GT %@filesize[%jpg] then
                echo %@filename[%jpg] ... Output [%fsize] is larger than 
original [%@filesize[%jpg]]. Skipped.
                iterate
        elseiff %fsize EQ %@filesize[%jpg] then
                echo %@filename[%jpg] ... Original and output have same 
size [%@filesize[%jpg]]. Skipped.
                iterate
        endiff
        set SIZEDIFF=%@eval[%@filesize[%jpg] - %fsize]
        set /A REDUSIZE+=%SIZEDIFF
        echo %@filename[%jpg] ... from %@filesize[%jpg] to %fsize 
[%SIZEDIFF].
        touch /r "%jpg" "%jpg.new"
        move /y "%jpg.new" "%jpg"
enddo
echo Done. %REDUSIZE bytes freed.
endlocal
-Scott

roytam1 <> wrote on 04/15/2010 08:35:45 PM:


> ---Quote (Originally by samintz)---
> The issue has to do with delayed parsing and FOR's loop variable. When
> TCC is parsing the FOR statement it is interpreting %1 as the loop
> variable. It has no way of knowing you meant to use %i instead. The
> following syntax, while not CMD compatible, does work in TCC. Note both

> the use of backticks and double %'s to enable the functionality you're
> trying for.
>
> @echo off
>
> set TOTALSIZE=0
> set foreach=`for %1 %%i in (*.*) do call :add %%@filesize[%%i]`
> echo "%foreach"
> %foreach
> echo %TOTALSIZE
> set TOTALSIZEgoto :EOF
>
>
> :add
> set /A TOTALSIZE+=%1
>
> As an alternative using purely TCC syntax:
> echo %@filesize[*.*]
>
> or
>
> echo %@eval[%@execstr[4,dir /s /u2]]
>
> -Scott
>
>
> roytam1 <> wrote on 04/15/2010 12:37:36 PM:
> ---End Quote---
> but allowing %1 ~ %9 and %* for use as FOR variable breaks
> compatibility with CMD.
>
> and the example is just a minimal test case for reproducing the issue.
> my full script look like this:
>
> Code:
> ---------
> @echo off
> setlocal EnableDelayedExpansion
> set REDUSIZE=0
>
> for %1 %%i in (*.jpeg;*.jpg) do call :optjpeg "%%~i"
> echo Done. %REDUSIZE% bytes freed.
>
> rem clean up
> set REDUSIZE> set rpath> set FSIZE> SET SIZEDIFF> GOTO :EOF
>
> rem sub optjpeg(filename)
> :optjpeg
> SET SIZEDIFF=0
> call :rpath "%~1"
> f:\app_re~1\jpegtran.exe -optimize "%~1" "%~1.new"
> if errorlevel 1 del "%~1.new" & echo %rpath% ... jpegtran internal
> error. Skipped.
> f:\app_re~1\ujpg.exe "%~1.new" > nul 2>&1
> call :fsize "%~1.new"
> SET /A SIZEDIFF=%~z1-%FSIZE%
> if %FSIZE% EQU 0 del "%~1.new" & echo %rpath% ... Zero byte output.
Skipped.

> if %SIZEDIFF% LSS 0 del "%~1.new" & echo %rpath% ... Output [%
> FSIZE%] is larger than original [%~z1]. Skipped.
> if %SIZEDIFF% EQU 0 del "%~1.new" & echo %rpath% ... Original and
> output has same size [%~z1]. Skipped.
>
> if exist "%~1.new" call :overwrite "%~1"
> GOTO :EOF
>
> rem sub overwrite(filename)
> :overwrite
> set /A REDUSIZE+=%SIZEDIFF%
> echo %rpath% ... from %~z1 to %FSIZE% [%SIZEDIFF%].
> f:\app_re~1\touch -r "%~1" "%~1.new"
> move /y "%~1.new" "%~1"
> GOTO :EOF
>
> rem sub rpath(filename) OUT: %rpath%
> :rpath
> SET rpath=%~1
> set rpath=!rpath:%CD%\=!
> GOTO :EOF
>
> rem sub fsize(filename) OUT: %FSIZE%
> :fsize
> IF EXIST %1 (
> SET FSIZE=%~z1
> ) ELSE (
> SET FSIZE=0
> )
> GOTO :EOF
>
> endlocal
> ---------
>
>
>
 
Apr 1, 2010
43
0
#10
Re: not working

I have not tested this script, but this is an equivilent TCC script to
what you are attempting to do in CMD:

Code:
@echo off
setlocal
set REDUSIZE=0
do jpg in %1 *.jpeg;*.jpg
        f:\app_re~1\jpegtran.exe -optimize "%jpg" "%jpg.new"
        iff errorlevel 1 then
                del "%jpg.new"
                echo %@filename[%jpg] ... jpegtran internal error. 
Skipped.
                iterate
        endiff
        f:\app_re~1\ujpg.exe "%jpg.new" > nul 2>&1
        set fsize=%@filesize[%jpg.new]
        iff %fsize LE 0 then
                echo %@filename[%jpg] ... Zero byte output. Skipped.
                iterate
        elseiff %fsize GT %@filesize[%jpg] then
                echo %@filename[%jpg] ... Output [%fsize] is larger than 
original [%@filesize[%jpg]]. Skipped.
                iterate
        elseiff %fsize EQ %@filesize[%jpg] then
                echo %@filename[%jpg] ... Original and output have same 
size [%@filesize[%jpg]]. Skipped.
                iterate
        endiff
        set SIZEDIFF=%@eval[%@filesize[%jpg] - %fsize]
        set /A REDUSIZE+=%SIZEDIFF
        echo %@filename[%jpg] ... from %@filesize[%jpg] to %fsize 
[%SIZEDIFF].
        touch /r "%jpg" "%jpg.new"
        move /y "%jpg.new" "%jpg"
enddo
echo Done. %REDUSIZE bytes freed.
endlocal
-Scott

roytam1 <> wrote on 04/15/2010 08:35:45 PM:






Skipped.
but your script, I can't supply /r in %1 for recursive iteration, and it won't show relative path.

and I wonder why people there always rewrite one's script to BTM even if he/she wants CMD compatibility.
 
#11
Re: not working

| but your script, I can't supply /r in %1 for recursive iteration,
| and it won't show relative path.

You need to use /S as the first (and only) parameter of the posted batch
program so it would iterate through all subdirectories of the starting path.
What do you mean by "relative path"? If %fullpath is the full pathname
of a file, and the file is located in a subdirectory of %ref_path, the value
of the function %@replace[%ref_path,,%fullpath] is the path of the file
relative to directory %ref_path.

| and I wonder why people there always rewrite one's script to BTM
| even if he/she wants CMD compatibility.

Sometimes it is a lot easier to have separate batch files for CMD.EXE
and for TCC.EXE. Many of us (including myself) never learned how to use
CMD.EXE, having "grown up" with the JP Software command processors, we never
downgraded.
--
HTH, Steve
 
Apr 1, 2010
43
0
#12
In website, JP Software claims "Upwardly compatible with CMD.EXE with literally thousands of additions".
But actually it doesn't, and failing in most powerful part in CMD: FOR command:
- wrongly parsing FOR variable with arguments and SET variables.
- killing extended FOR variables(%%~{*} variables, see FOR /? in CMD for details) if using SET variable to store FOR command.
and one offing this topic:
- improper MBCS support.

How JP Software claim "compatible with CMD.EXE" with these incompatibilities?

I'm really not trying to criticizing TCC or JP Software, both Take Command(/LE) and TCC(/LE) are still excellent products. But I feel disappointed for JP Software not responding my questions and shifting off problem to "no in-house wide char developers" but not providing ANSI version again as a workaround. 4NT/TCC switched to Unicode only version, but not taking extra care to ANSI-Unicode/Unicode-ANSI conversion and brings trouble to users.
 

rconn

Administrator
Staff member
May 14, 2008
10,551
97
#13
not working

> In website, JP Software claims "Upwardly compatible with CMD.EXE with
> literally thousands of additions".
> But actually it doesn't, and failing in most powerful part in CMD: FOR
> command:
> - wrongly parsing FOR variable with arguments and SET variables.
Well, no -- IMHO this is *not* an issue. You're apparently upset that FOR
will recognize something other than a single alphabetic character as a FOR
variable; most users consider this a feature. If you don't duplicate your
variable names, it will not be a problem.


> - improper MBCS support.
As I said, we do not support DBCS environments. When we *did* (in older
ANSI versions of 4NT), our Asian sales never amounted to more than 0.1% of
the total. Given this, it makes no financial sense for us to divert limited
resources to support imaginary non-paying customers.


> How JP Software claim "compatible with CMD.EXE" with these
> incompatibilities?
We never claimed 100% compatibility -- an obvious impossibility, given that
(1) different versions of CMD.EXE are incompatible, and (2) it's impossible
to add features without introducing some level of incompatibility. Given
the choice of supporting undocumented CMD.EXE bugs (like the FOR or IF
termination in batch files) or providing additional features (like the batch
debugger and ON ERROR), we'll go with the features.

Rex Conn
JP Software
 
Apr 1, 2010
43
0
#14
Re: not working

Well, no -- IMHO this is *not* an issue. You're apparently upset that FOR
will recognize something other than a single alphabetic character as a FOR
variable; most users consider this a feature. If you don't duplicate your
variable names, it will not be a problem.
I didn't. But instead, I'm pleased that I can use other than single letter as FOR variable.

But in other side, FOR it trying to use command line arguments(%1 ~ %9, %*) and variable that should evaluated first (%var%) as FOR variable, but not evaluate things(arguments, %var%) first and then execute the FOR statement. Does it make sense?


As I said, we do not support DBCS environments. When we *did* (in older
ANSI versions of 4NT), our Asian sales never amounted to more than 0.1% of
the total. Given this, it makes no financial sense for us to divert limited
resources to support imaginary non-paying customers.
then the internal CHCP is nothing other than a joke.
PLEASE NOTE the >127 part(for example: ¼ Ê Á ð Æ à æ Ì ñ Ç á È ò â ¶ Ö) in ANSI codepages (CP 437/850/etc.) will use 2 bytes to store when using UTF-8(CP 65001).

without proper support, even UTF-8 support is broken too.

As I said in that thread, you just not taking care of wchar_t/char count of MultiByteToWideChar and WideCharToMultiByte(IF you use WinAPI to deal with Unicode-ANSI/ANSI-Unicode conversion), which is trivial to fix.

We never claimed 100% compatibility -- an obvious impossibility, given that
(1) different versions of CMD.EXE are incompatible, and (2) it's impossible
to add features without introducing some level of incompatibility. Given
the choice of supporting undocumented CMD.EXE bugs (like the FOR or IF
termination in batch files) or providing additional features (like the batch
debugger and ON ERROR), we'll go with the features.

Rex Conn
JP Software
for unknown undocumented features/bugs, YES we can live without it.
but for documented behavior or well known behavior, you should make it work BECAUSE you claim the compatibility with CMD.

But BTW I don't think Microsoft will change the behavior (both documented and undocumented) in CMD in the future because Microsoft is trying to push their PowerShell to users.
 

rconn

Administrator
Staff member
May 14, 2008
10,551
97
#15
Re: not working

> But in other side, FOR it trying to use command line arguments(%1 ~ %9,
> %*) and variable that should evaluated first (%var%) as FOR variable,
> but not evaluate things(arguments, %var%) first and then execute the
> FOR statement. Does it make sense?
FOR supports all variable types, *except* as the first variable following
the FOR, where FOR expects only a FOR variable. This is necessary due to
the much more complex nature of TCC's FOR than CMD's simplistic FOR. TCC
also doesn't expand the entire line before it's even recognized as a FOR (as
does CMD), so you don't need the doubled %%'s to prevent premature
expansion.

Rex Conn
JP Software
 

rconn

Administrator
Staff member
May 14, 2008
10,551
97
#16
Re: not working

> ---Quote (Originally by rconn)---
> As I said, we do not support DBCS environments. When we *did* (in
> older ANSI versions of 4NT), our Asian sales never amounted to more
> than 0.1% of the total. Given this, it makes no financial sense for
> us to divert limited resources to support imaginary non-paying customers.
> ---End Quote---

> then the internal CHCP is nothing other than a joke.
Well, OK, if you're ignoring the vast majority of code pages which are *not*
DBCS.


> PLEASE NOTE the >127 part(for example: ¼ Ê Á ð Æ à æ Ì ñ Ç á È ò â ¶ Ö)
> in ANSI codepages (CP 437/850/etc.) will use 2 bytes to store when
> using UTF-8(CP 65001).
>
> without proper support, even UTF-8 support is broken too.
There is no UTF-8 support in Windows. A few Windows apps have some custom
support for UTF-8, but Windows itself is all UTF-16.

Rex Conn
JP Software
 

samintz

Scott Mintz
May 20, 2008
1,271
11
Solon, OH, USA
#17
Re: not working

DO uses /S for recursing into subdirectories. And there is no real
benefit to bending over backwards to make sure your script works in CMD
and TCC. If this is a shared script then either make it TCC/LE compatible
or get licenses for everyone that uses it.

Ultimately, if you need CMD to run your script from TCC you can always do
CMD /C cmdscript.bat

Relative paths are on the suggestion list (at least I know I've made that
suggestion in the past). Nonetheless, it is still possible to create
relative paths easily.

set slen=%@len[%_CWD]
do jpg in %1 *.jpg;*.jpeg
echo jpg = "%jpg"
echo name = %@filename[%jpg]
echo rel path = .%@right[-%slen,%@full[%jpg]]
enddo

-Scott

roytam1 <> wrote on 04/16/2010 09:13:53 PM:


> but your script, I can't supply /r in %1 for recursive iteration,
> and it won't show relative path.
>
> and I wonder why people there always rewrite one's script to BTM
> even if he/she wants CMD compatibility.
>
>
>
>
 
Apr 1, 2010
43
0
#18
Re: not working

DO uses /S for recursing into subdirectories. And there is no real
benefit to bending over backwards to make sure your script works in CMD
and TCC. If this is a shared script then either make it TCC/LE compatible
or get licenses for everyone that uses it.

Ultimately, if you need CMD to run your script from TCC you can always do
CMD /C cmdscript.bat

Relative paths are on the suggestion list (at least I know I've made that
suggestion in the past). Nonetheless, it is still possible to create
relative paths easily.

set slen=%@len[%_CWD]
do jpg in %1 *.jpg;*.jpeg
echo jpg = "%jpg"
echo name = %@filename[%jpg]
echo rel path = .%@right[-%slen,%@full[%jpg]]
enddo

-Scott

roytam1 <> wrote on 04/16/2010 09:13:53 PM:
These are real test cases to checking TCC's CMD compatibility.

By the way, about the full script I posted in this thread, I found that "setlocal EnableDelayedExpansion" cannot be use for temporarily enabling Delayed Variable Expansion function.

I know that there is an option for enable it permanently (requires restart) but I want to use it temporarily inside setlocal/endlocal scope.

and the Delayed Variable string substitution (!var:from=[to(can be empty)]!) is not working (even if I enabled it in option and restarted).
 

samintz

Scott Mintz
May 20, 2008
1,271
11
Solon, OH, USA
#20
Re: not working

Again if 100% compatibility is necessary then just use CMD to run the
script.

CMD /c script.bat

-Scott

roytam1 <> wrote on 04/19/2010 12:57:52 PM:


> ---Quote (Originally by samintz)---
> DO uses /S for recursing into subdirectories. And there is no real
> benefit to bending over backwards to make sure your script works in CMD
> and TCC. If this is a shared script then either make it TCC/LE
compatible

> or get licenses for everyone that uses it.
>
> Ultimately, if you need CMD to run your script from TCC you can always
do

> CMD /C cmdscript.bat
>
> Relative paths are on the suggestion list (at least I know I've made
that

> suggestion in the past). Nonetheless, it is still possible to create
> relative paths easily.
>
> set slen=%@len[%_CWD]
> do jpg in %1 *.jpg;*.jpeg
> echo jpg = "%jpg"
> echo name = %@filename[%jpg]
> echo rel path = .%@right[-%slen,%@full[%jpg]]
> enddo
>
> -Scott
>
> roytam1 <> wrote on 04/16/2010 09:13:53 PM:
> ---End Quote---
> These are real test cases to checking TCC's CMD compatibility.
>
> By the way, about the full script I posted in this thread, I found
> that "setlocal EnableDelayedExpansion" cannot be use for temporarily
> enabling Delayed Variable Expansion function.
>
> I know that there is an option for enable it permanently (requires
> restart) but I want to use it temporarily inside setlocal/endlocal
scope.

>
> and the Delayed Variable string substitution (!var:from=[to(can be
> empty)]!) is not working (even if I enabled it in option and restarted).
>
>
>
>
 

rconn

Administrator
Staff member
May 14, 2008
10,551
97
#21
Re: not working

> By the way, about the full script I posted in this thread, I found that
> "setlocal EnableDelayedExpansion" cannot be use for temporarily
> enabling Delayed Variable Expansion function.
SETLOCAL in TCC *does* support ENABLEDELAYEDEXPANSION (in batch files, not
from the command line). Can you post an example of what is failing for you?


> I know that there is an option for enable it permanently (requires
> restart) but I want to use it temporarily inside setlocal/endlocal
> scope.
>
> and the Delayed Variable string substitution (!var:from=[to(can be
> empty)]!) is not working (even if I enabled it in option and
> restarted).
Again, can you post an example?

Rex Conn
JP Software
 

rconn

Administrator
Staff member
May 14, 2008
10,551
97
#22
not working

> P.S.: the complete examples of setlocal is here:
> http://ss64.com/nt/setlocal.html
TCC already supports all of those arguments (and DisableDelayedExpansion,
which CMD does not).

Note that TCC always supports delayed expansion (and always has), unless
it's explicitly disabled.

Rex Conn
JP Software
 
Apr 1, 2010
43
0
#23
Re: not working

SETLOCAL in TCC *does* support ENABLEDELAYEDEXPANSION (in batch files, not
from the command line). Can you post an example of what is failing for you?




Again, can you post an example?

Rex Conn
JP Software
Posted before in this thread:
http://www.jpsoft.com/forums/showpost.php?p=9449&postcount=7

the :rpath subroutine doesn't replace.
When it echo %rpath% it print !rpath:[...]\=! directly, such replacement works in CMD.

a simplified test case here:
Code:
@echo off
setlocal enabledelayedexpansion
for /R %%i in (.) do (
 call :rpath %%~i
 echo %rpath%
)
endlocal
GOTO :EOF

rem sub rpath(filename) OUT: %rpath%
:rpath
 rem debug print %1 here
 echo (rpath: %1)

 SET rpath=%~1
 set rpath=!rpath:%CD%\=!
GOTO :EOF
CMD result:
Code:
F:\app_related\TCCLE>rpath
(rpath: F:\app_related\TCCLE\.)
.
(rpath: F:\app_related\TCCLE\abd\.)
abd\.
(rpath: F:\app_related\TCCLE\dfe\.)
dfe\.

F:\app_related\TCCLE>
TCC result:
Code:
[F:\app_re~1\TCCLE]rpath
(rpath: F:\app_re~1\TCCLE\.)
!rpath:F:\app_re~1\TCCLE\=!
(rpath: F:\app_re~1\TCCLE\abd\.)
!rpath:F:\app_re~1\TCCLE\abd\=!
(rpath: F:\app_re~1\TCCLE\dfe\.)
!rpath:F:\app_re~1\TCCLE\dfe\=!

[F:\app_re~1\TCCLE]
and another type of delayed expansion fails. example from http://ss64.com/nt/syntax-replace.html :
Code:
:: To remove characters from the right hand side of a string is 
:: a two step process and requires the use of a CALL statement
:: e.g.

   SET _test=The quick brown fox jumps over the lazy dog

   :: To delete everything after the string 'brown'  
   :: first delete 'brown' and everything before it
   SET _endbit=%_test:*brown=%
   Echo We dont want: [%_endbit%]

   ::Now remove this from the original string
   CALL SET _result=%%_test:%_endbit%=%%
   echo %_result%
in CMD:
We dont want: [ fox jumps over the lazy dog]
The quick brown

in TCC:
We dont want: [ fox jumps over the lazy dog]
The quick brown fox jumps over the lazy dog: fox jumps over the lazy dog
TCC already supports all of those arguments (and DisableDelayedExpansion,
which CMD does not).

Note that TCC always supports delayed expansion (and always has), unless
it's explicitly disabled.

Rex Conn
JP Software
always enabling delayed expansion even on %var% might not be good on all scripts.

Quote from http://blogs.msdn.com/oldnewthing/archive/2006/08/23/714650.aspx :
That's because the command interpreter expanded the environment variables at the time the line was read (not at the time the line is executed), yielding

set VAR=after & echo before

As a result, the old value of VAR is echoed. Some people treat this as a feature, allowing them to "restore" a variable without having to save it anywhere:

set VAR=newvalue & call helper.cmd & set VAR=%VAR%


a simple test case using this 'feature':
Code:
@echo off
set varx=abc
set varx=def& call :gsub & set varx=%varx%

:gsub
 echo (gsub: %varx%)
in CMD:
(gsub: def)
(gsub: abc)

in TCC:
(gsub: def)
(gsub: def)


Also CMD style escape char fails in delayed variables (hellohtml.bat).
[ script content and results were pasted in pastebin.ca ( http://pastebin.ca/1868846 ) because forum kills html tags. ]
 

rconn

Administrator
Staff member
May 14, 2008
10,551
97
#24
Re: not working

> ---Quote (Originally by rconn)---
> TCC already supports all of those arguments (and
> DisableDelayedExpansion, which CMD does not).
>
> Note that TCC always supports delayed expansion (and always has),
> unless it's explicitly disabled.
>
> ---End Quote---
> always enabling delayed expansion even on %var% might not be good on
> all scripts.
4NT / TCC has supported delayed expansion for 15 years, LONG before CMD
implemented it. Changing it now would break a zillion batch files and
infuriate all the existing TCC users; it's not going to happen.

Rex Conn
JP Software
 
Apr 1, 2010
43
0
#25
Re: not working

4NT / TCC has supported delayed expansion for 15 years, LONG before CMD
implemented it. Changing it now would break a zillion batch files and
infuriate all the existing TCC users; it's not going to happen.

Rex Conn
JP Software
That's why I said 'might' here.
I'll also think TCC implementation is better. I just pointed out the difference between CMD and TCC of that.
 
Apr 1, 2010
43
0
#26
Re: not working

That's why I said 'might' here.
I'll also think TCC implementation is better. I just pointed out the difference between CMD and TCC of that.
Because it is very minor and easily fixed for both CMD and TCC in script, mention this behavior somewhere in documentation is enough.

and another minor different, if I use variable to store FOR command, the FOR extended variable will be killed.

Code:
[F:\app_related\TCCLE]set FORSW=for

[F:\app_related\TCCLE]%FORSW% %%i in (*.exe) do echo %%i
tcc.exe

[F:\app_related\TCCLE]%FORSW% %%i in (*.exe) do echo %%~si
ECHO is OFF
Just let you know this.
 

rconn

Administrator
Staff member
May 14, 2008
10,551
97
#27
Re: not working

> Because it is very minor and easily fixed for both CMD and TCC in
> script, mention this behavior somewhere in documentation is enough.
It's well documented and always has been. TCC always does the expansion at
execution time; this is considered a feature!


> and another minor different, if I use variable to store FOR command,
> the FOR extended variable will be killed.
>
>
> Code:
> ---------
> [F:\app_related\TCCLE]set FORSW=for
>
> [F:\app_related\TCCLE]%FORSW% %%i in (*.exe) do echo %%i
> tcc.exe
>
> [F:\app_related\TCCLE]%FORSW% %%i in (*.exe) do echo %%~si
> ECHO is OFF
> ---------
I can conceive of no possible reason to be doing this ...

Rex Conn
JP Software
 

rconn

Administrator
Staff member
May 14, 2008
10,551
97
#28
Re: not working

> and another type of delayed expansion fails. example from
> http://ss64.com/nt/syntax-replace.html :
Leaving aside the horror of this strangled syntax (which would be a one-line
statement in TCC), this has nothing to do with delayed expansion (which
isn't even in use in this example).


> Code:
> ---------
> :: To remove characters from the right hand side of a string is
> :: a two step process and requires the use of a CALL statement
> :: e.g.
>
> SET _test=The quick brown fox jumps over the lazy dog
>
> :: To delete everything after the string 'brown'
> :: first delete 'brown' and everything before it
> SET _endbit=%_test:*brown=%
> Echo We dont want: [%_endbit%]
>
> ::Now remove this from the original string
> CALL SET _result=%%_test:%_endbit%=%%
> echo %_result%
> ---------
The problem here is that the intermediate expansion is:

CALL SET _result=%_test: fox jumps over the lazy dog=%

TCC is breaking on the space following the :, and deciding the variable name
is _test. CMD requires two %'s to enclose the name, but since TCC only
requires one, it cannot simply go hunting on the remainder of the line
looking for another %. (And no, this cannot be changed, even as an option,
without breaking every TCC alias and batch file in existence.) If there is
no intermediate whitespace (as in the first "SET _endbit=..." command), then
TCC will detect the trailing % and interpret the command in the same way as
CMD.

Rex Conn
JP Software
 

samintz

Scott Mintz
May 20, 2008
1,271
11
Solon, OH, USA
#29
Re: not working

As I keep saying, if 100% compatibility is desired then just run the .BAT
script using CMD. You can enable PathExt and remove .BAT from the PATHEXT
environment variable and then add an executable extension to run CMD.

PATHEXT=.COM;.EXE;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.PY
set .bat=cmd /c

Rex - there is an odd behavior I noticed doing this. If I have a file
named FOO.BAT and I type FOO, then the script is launched with CMD.
However, if I type FOO.BAT then TCC executes the script. Is this an
ASSOC/FTYPE issue?

-Scott

rconn <> wrote on 04/20/2010 09:36:39 AM:


> ---Quote---
> > and another type of delayed expansion fails. example from
> > http://ss64.com/nt/syntax-replace.html :
> ---End Quote---
> Leaving aside the horror of this strangled syntax (which would be a
one-line

> statement in TCC), this has nothing to do with delayed expansion (which
> isn't even in use in this example).
>
>
>
> ---Quote---
> > Code:
> > ---------
> > :: To remove characters from the right hand side of a string is
> > :: a two step process and requires the use of a CALL statement
> > :: e.g.
> >
> > SET _test=The quick brown fox jumps over the lazy dog
> >
> > :: To delete everything after the string 'brown'
> > :: first delete 'brown' and everything before it
> > SET _endbit=%_test:*brown=%
> > Echo We dont want: [%_endbit%]
> >
> > ::Now remove this from the original string
> > CALL SET _result=%%_test:%_endbit%=%%
> > echo %_result%
> > ---------
> ---End Quote---
> The problem here is that the intermediate expansion is:
>
> CALL SET _result=%_test: fox jumps over the lazy dog=%
>
> TCC is breaking on the space following the :, and deciding the variable
name

> is _test. CMD requires two %'s to enclose the name, but since TCC only
> requires one, it cannot simply go hunting on the remainder of the line
> looking for another %. (And no, this cannot be changed, even as an
option,

> without breaking every TCC alias and batch file in existence.) If there
is

> no intermediate whitespace (as in the first "SET _endbit=..." command),
then

> TCC will detect the trailing % and interpret the command in the same way
as

> CMD.
>
> Rex Conn
> JP Software
>
>
>
>
 

rconn

Administrator
Staff member
May 14, 2008
10,551
97
#30
Re: not working

> the :rpath subroutine doesn't replace.
> When it echo %rpath% it print !rpath:[...]\=! directly, such
> replacement works in CMD.
>
> a simplified test case here:
>
> Code:
> ---------
> @echo off
> setlocal enabledelayedexpansion
> for /R %%i in (.) do (
> call :rpath %%~i
> echo %rpath%
> )
> endlocal
> GOTO :EOF
>
> rem sub rpath(filename) OUT: %rpath%
> :rpath
> rem debug print %1 here
> echo (rpath: %1)
>
> SET rpath=%~1
> set rpath=!rpath:%CD%\=!
> GOTO :EOF
> ---------
This fails in CMD -- what is "SET rpath=%~1" supposed to do? In CMD on my
system (Server 2008), it removes RPATH from the environment, as %~1 AFAIK
doesn't have any meaning. So the subsequent "set rpath=!rpath:%CD%\=!" does
nothing, and "rpath" is empty when it returns to the FOR loop. All I get is
a lot of "echo is off" messages from the FOR loop.

Rex Conn
JP Software