Alias with setdos no longer works

This alias used to work in previous versions:

for %x in (*.php) do php -l %x | (setdos /x-46 & for %y in (@CON:) do if %@index["%y",No syntax errors detected in] != 1 echo %@replace[^&,^^^&,%y] & setdos /x46)

To demonstrate the problem, we can simplify it to

echo `Foo` | (setdos /x-46 & for %y in (@CON:) do echo %y & setdos /x46)

When I run this, it sits there with the window header showing the stuff after the pipe. If I press the Enter key, then I get the prompt. But, it doesn't echo "Foo". It should echo "Foo" and give me the prompt, like if I do

echo `Foo` | (for %y in (@CON:) do echo %y)

TCC 26.02.41 x64 Windows 10 [Version 10.0.19041.388]
 
May 20, 2008
10,637
82
Syracuse, NY, USA
Thanks for the simplified example. It works in v25 and not in v26.

It has nothing to do with SETDOS or FOR per se. Any command before "for" will do it. For example,

Code:
echo `Foo` | (echo. & for %y in (@CON:) do echo %y)
And the same thing happens using DO instead of FOR.

Code:
echo `Foo` | (echo. & do x in @con: (echo %x))
In fact, this does it too (likewise with FOR).

Code:
echo `Foo` | (& do x in @con: (echo %x))
 
Build 42 works.

I tried to change the FOR to DO in my alias, but it doesn't work. What am I doing wrong?
Code:
C:\Junk>php -l Test.php
PHP error.
Parse error: syntax error, unexpected '&' in Test.php on line 34
Errors parsing Test.php

C:\Junk>alias cho
for %x in (*.php) do php -l %x | (setdos /x-46 & for %y in (@CON:) do if %@index["%y",No syntax errors detected in] != 1 echo %@replace[^&,^^^&,%y] & setdos /x46)

C:\Junk>cho
PHP error.
Parse error: syntax error, unexpected '&' in Test.php on line 34
Errors parsing Test.php

C:\Junk>alias ch
do x in *.php (php -l %x) | (setdos /x-46 & do y in @CON: (if %@index["%y",No syntax errors detected in] != 1 echo %@replace[^&,^^^&,%y]) & setdos /x46)

C:\Junk>ch
TCC: Syntax error "@replace["
TCC: Unknown command "^&"
TCC: Syntax error "@replace["
TCC: Unknown command "^&"
TCC: Unknown command "'"
TCC: Syntax error "@replace["
TCC: Unknown command "^&"

C:\Junk>ver

TCC  26.02.42 x64   Windows 10 [Version 10.0.19041.388]
 
Aug 23, 2010
589
7
I don't see why do you need SETDOS to begin with.

Try

Code:
DO x IN *.php ( php -l "%[x]" 2>&1 > NUL: )
 
May 20, 2008
10,637
82
Syracuse, NY, USA
That will not output anything. The point is to output the errors, but not the "no error" messages.
David, could you explain exactly what this is supposed to do.

What is the output of

Code:
(php -l %x)
and what's this (below) supposed to do to it? I have a feeling that TPIPE might suffice (quite elegantly).

Code:
| (setdos /x-46 & for %y in (@CON:) do if %@index["%y",No syntax errors detected in] != 1 echo %@replace[^&,^^^&,%y] & setdos /x46)
 
"php -l" does a PHP syntax check of the file. However, it writes something even if there are no errors, e.g.,
Code:
C:\TT\RatingsCentral\Code\Web>do x in *.php (php -l %x)
No syntax errors detected in Admin.php
No syntax errors detected in BaseListParameters.php
No syntax errors detected in BooleanStuff.php
No syntax errors detected in ChangePassword.php
No syntax errors detected in ChangePasswordResponse.php
No syntax errors detected in CharacterStuff.php
No syntax errors detected in CheckStuff.php
No syntax errors detected in ClubInfo.php
No syntax errors detected in ClubList.php
I only want it to write something if there is an error. The version with FOR works fine. But, it seems DO is generally preferred to FOR, so I thought I'd change it to use DO. But, the DO version doesn't work, and I'm curious why. I could just stick with the FOR version. If there is an error, then "php -l" outputs the erroneous code, which may have characters that TCC tries to interpret. That's the reason for the setdos and %@replace. For example, here is what happens without the %@replace:

Code:
C:\Junk>php -l Test.php
PHP error.
Parse error: syntax error, unexpected '&' in Test.php on line 34
Errors parsing Test.php

C:\Junk>for %x in (*.php) do php -l %x | (setdos /x-46 & for %y in (@CON:) do if %@index["%y",No syntax errors detected in] != 1 echo %y & setdos /x46)
PHP error.
Parse error: syntax error, unexpected '
TCC: Unknown command "'"
Errors parsing Test.php

C:\Junk>
 
May 20, 2008
10,637
82
Syracuse, NY, USA
"Do x in @con:" is not your friend if there may be sensitive stuff in con:

If you want everything but the "no error" messages, how about something as simple as

Code:
do x in *.php (php -l %x | findstr /v "no errors detected")
Or, if you want a TCC-only solution,

Code:
do x in *.php (php -l %x | tpipe /grep=4,0,0,0,0,0,0,0,"no errors detected")
 
May 20, 2008
10,637
82
Syracuse, NY, USA
These are certainly simpler. The tpipe one is very slow: 1 minute 36 seconds. The findstr one takes 18 seconds. My original with FOR takes 5 seconds, which is the same time it takes for just "do x in *.php (php -l %x)".
Oops! my fault. I was starting FINDSTR/TPIPE for every file. Try it like this.

Code:
(do x in *.php (php -l %x)) | findstr /v "no errors detected"
or

Code:
(do x in *.php (php -l %x)) | tpipe /grep=4,0,0,0,0,0,0,0,"no errors detected"
 
May 20, 2008
10,637
82
Syracuse, NY, USA
What is the difference between tpipe grep type 4 and type 5? I get the same result with both of them.
Beats me!

Much better. The tpipe one is a fraction of a second slower than the FOR one. The findstr one is about 1.5 seconds slower. I think tpipe is the way to go.
TPIPE is only slow to get going. It calls an external, TPIPE.EXE, which needs to load an 18MB dll. But if you're going to do several operations you can do them all with one instance of TPIPE and it will outperform a string of externals.

In this case, I'd expect FINDSTR to outperform TPIPE by a small, fixed amount (below about 0.3 sec regardless of the job size).

Code:
v:\> timer /q & (do i=1 to 10000 (echo foo)) | findstr foo > nul & timer
Timer 1 off: 11:30:42  Elapsed: 0:00:01.896

v:\> timer /q & (do i=1 to 10000 (echo foo)) | tpipe /grep=4,0,0,0,0,0,0,0,foo > nul & timer
Timer 1 off: 11:30:53  Elapsed: 0:00:02.135

v:\> timer /q & (do i=1 to 100000 (echo foo)) | findstr foo > nul & timer
Timer 1 off: 11:31:24  Elapsed: 0:00:17.938

v:\> timer /q & (do i=1 to 100000 (echo foo)) | tpipe /grep=4,0,0,0,0,0,0,0,foo > nul & timer
Timer 1 off: 11:31:50  Elapsed: 0:00:18.252
 
Aug 23, 2010
589
7
No. It writes parsing errors to STDERR and other messages to STDOUT.

Without redirection:
Code:
No syntax errors detected in autoparser.php
PHP Deprecated:  Methods with the same name as their class will not be constructors in a future version of PHP; ExpressionParser h
as a deprecated constructor in exparser.php on line 3
No syntax errors detected in exparser.php
With redirection:
Code:
PHP Deprecated:  Methods with the same name as their class will not be constructors in a future version of PHP; ExpressionParser h
as a deprecated constructor in exparser.php on line 3
 
Code:
C:\TT\RatingsCentral\Code\Web>php -l Test.php
PHP error.
Parse error: syntax error, unexpected '&' in Test.php on line 35
Errors parsing Test.php

C:\TT\RatingsCentral\Code\Web>php -l Test.php >&> nul:
PHP error.
Parse error: syntax error, unexpected '&' in Test.php on line 35
Errors parsing Test.php

C:\TT\RatingsCentral\Code\Web>php -l Test.php > nul:

C:\TT\RatingsCentral\Code\Web>php -l Test2.php
No syntax errors detected in Test2.php

C:\TT\RatingsCentral\Code\Web>php -l Test2.php >&> nul:
No syntax errors detected in Test2.php

C:\TT\RatingsCentral\Code\Web>php -l Test2.php > nul:

C:\TT\RatingsCentral\Code\Web>php -l Test2.php 2>&1 > NUL:

C:\TT\RatingsCentral\Code\Web>php -l Test.php 2>&1 > NUL:

C:\TT\RatingsCentral\Code\Web>which php
php is an alias : "c:\Apps\PHP\php.exe"

C:\TT\RatingsCentral\Code\Web>php -v
PHP 7.3.21 (cli) (built: Aug  4 2020 11:21:15) ( NTS MSVC15 (Visual C++ 2017) x64 )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.21, Copyright (c) 1998-2018 Zend Technologies

C:\TT\RatingsCentral\Code\Web>