caret removes the first command after opening parenthesis if its concat'd to the first token of command without space

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
lockedscope
Posts: 31
Joined: 12 Jun 2020 10:38

caret removes the first command after opening parenthesis if its concat'd to the first token of command without space

#1 Post by lockedscope » 21 Jun 2020 06:32

- Following works because there is space after the first token of command

Code: Select all

(
dir ^
t*.cmd
)
- Following removes the first command because of caret is in first token and echo works

Code: Select all

(
di^
r t*.cmd
echo abc
)
'r' is not recognized as an internal or external command,
operable program or batch file.
abc
- Following works, caret is in second token

Code: Select all

(
dir t^
*.cmd
)
- Following does not work, caret is concatenated to the first token

Code: Select all

(
dir^
t*.cmd
)
't*.cmd' is not recognized as an internal or external command, operable program or batch file.
- When there is a space, it is treated as a command and error raised and dir works fine.

Code: Select all

(
^<space> 
dir ^
t*.cmd
)

' ' is not recognized as an internal or external command,
operable program or batch file.
<DIR RESULT>
- And weirdly

Code: Select all

(
^
<space> 
dir ^
t*.cmd
)
The syntax of the command is incorrect.
So, what causes it, is it a bug, are there any rules covering it?
Last edited by lockedscope on 25 Jun 2020 10:59, edited 1 time in total.

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: caret removes the first command after opening parenthesis if its concat'd to the first token of command without spac

#2 Post by jeb » 22 Jun 2020 00:20

Hi lockedscope,

nice finding :!:
I didn't knew that and never tested it.


The rule seems to be:
- In paremthesis:
- If a caret+line feed splits the command token (usually the first token), then only the part after the last LF is used
- This rule is true for any position in the parenthsis, not only the first line

Simple exsample

Code: Select all

(
ec^
ho FAILS
)

More complex examples

Code: Select all

@echo on
cls
(
echo Start
^echo #1: Works
^
echo #2: Works

ec^HO #3: Fails
ec^
HO #4: Fails

<nul echo #5: Works
<n^
ul echo #6: Works

<nul ec^
ho #7: FAILS
<n^
ul ec^
ho #8: FAILS

^<nul echo #9: WORKS
)

echo End
Test 5-8 shows that the rule only applies for a command token, but not for first redirection!

Test 9 shows the (already known, Bug/Mystery in the phase parsing rules 1.5 and 2 CR vs redirect) strange behaviour, that the "nul" token is removed and the "echo" is used for the redirection.
Really strange, because there shouldn't no redirection at all, as the redirection character was escaped


jeb

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: caret removes the first command after opening parenthesis if its concat'd to the first token of command without spac

#3 Post by jeb » 22 Jun 2020 00:43

Btw. the @ has also sme impact.

Code: Select all

@echo on
cls
(
echo Start

@ ec^
ho #1: Works
@ec^
ho #2: Fails

@@^
@@ ec^
ho #3: Works

xyz@@^
@@ ec^
ho #4: Works
)

echo End

lockedscope
Posts: 31
Joined: 12 Jun 2020 10:38

Re: caret removes the first command after opening parenthesis if its concat'd to the first token of command without spac

#4 Post by lockedscope » 22 Jun 2020 10:06

As a workaround, following works with a label operator(: colon) before the line wherever `commands first token splitting caret` usage appears

Code: Select all

(:
di^
r t*.cmd
echo b)
The rule applies at any line so we need to fix it before every line such a weird caret usage appears

Code: Select all

(:
di^
r t*.cmd
echo a
:
di^
r t*.cmd
echo b)

lockedscope
Posts: 31
Joined: 12 Jun 2020 10:38

Re: caret removes the first command after opening parenthesis if its concat'd to the first token of command without spac

#5 Post by lockedscope » 25 Jun 2020 14:34

Another workaround is to redefine parenthesis :) ;
- opening parenthesis with the escaped (!& and
- a command delimiter - with the escaped !&

Rules:
- First command could be on the same line as opening parenthesis or on the next line without any space between.
- It works when there is a space between command delimeter and command but fails when command is on the next line.

Code: Select all

setlocal EnableDelayedExpansion
set t=before
set "(=^(^!^&^^"
set "-=^!^&"
set )=^)

%(%di^
r te^
mp*.cmd
%-%di^
r m^
*.cmd
set t=4
echo percent: %t%
echo delayed: !t!
echo b
%)%

echo after parenthesis - percent: %t%
(echo ^
  Other parenthesis work fine )
 endlocal

Post Reply