Welcome!

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

SignUp Now!

Unable to pass batch file arguments unaltered

Aug
713
10
I have this script as a wrapper for Cygwin processes:

Code:
@SET PROMPT=@$S$P$_
@ECHO OFF
ON BREAK REM

CALL "%~dp0fix-path.btm"

SET ENV=%@PATH[%@FULL["%~0"]]env.exe
SET CMDNAME=%@EXECSTR[cygpath.exe -u "%~1"]
SHIFT

SET LANG=%@EXECSTR[locale -uU]
"%[ENV]" -- "%[CMDNAME]" "%$"
QUIT %?

Now, the problem is that it chokes when I pass it arguments enclosed in braces,
like your typical
Code:
git for-each-ref --format %(refname) %(objectname) --sort -committerdate
passage.

Is there a way to send arguments unaltered to the child process?
 
Is the problem the %(objectname) et. al.?
One option is to disable environment variable expansion using SETDOS /X. Another is to double up the %'s.
 
Yes, it is. Even with %@, the %(...) is executed before the program is called.
And the resulting command line contains
Code:
git for-each-ref --format 2 2 --sort -committerdate
where "2" looks like your usual "not found" return code. I appreciate the ability, but is it documented?
 
`SETDOS /X-4` doesn't work for the purpose.
TCC: Unknown command "refname"
TCC: Unknown command "objectname"
`SETDOS /X-3` breaks the script completely.
TCC: …\bin\cygwrap.btm [16] Unknown command "%[ENV]"

How to replace % with %% in an arbitrary string, if that string is evaluated long before I can make substitution?
 
I would think setdos /x-4 is what you want. However, I'm not clear on how what you posted gets called and when.

If your command is
Code:
git for-each-ref --format %(refname) %(objectname) --sort -committerdate
Then just double the %'s right there.
Code:
git for-each-ref --format %%(refname) %%(objectname) --sort -committerdate
 
My command is `git-wrapper.sh whatever arguments the caller decide to add`.
The association for ".sh" files is
Code:
$ assoc .sh
.sh=unixshell.script

$ ftype unixshell.script
unixshell.script="C:\Program Files\JPSoft\TCC-RT\TCC.EXE" /B /C "C:\Cygwin64\bin\cygwrap.btm" "%1" %*
 
I am not sure how you are invoking your scripts. I wrote a test framework:
Code:
assoc .foo=test.script
ftype test.script=c:\tc25\tcc.exe /b /c c:\tc25\echotest.btm %%*
I created echotest.btm:
Code:
@ECHO ON
setlocal
SET PROMPT=@$S$P$_
ON BREAK REM

rem CALL "%~dp0fix-path.btm"

SET ENV=%@PATH[%@FULL["%~0"]]env.exe
SET CMDNAME=%@EXECSTR[cygpath.exe -u "%~1"]
SHIFT

SET LANG=%@EXECSTR[locale -uU]
setdos /x-4
echo "%[ENV]" -- "%[CMDNAME]" "%$"
setdos /x0
QUIT %?
And then created test.foo which is basically empty. And invoked it:
Code:
test.foo git for-each-ref --format %%%%(refname) %%%%(objectname) --sort -committerdate
And got this output:
Code:
setlocal
SET PROMPT=@$S$P$_
ON BREAK REM
rem CALL "%~dp0fix-path.btm"
SET ENV=C:\tc25\env.exe
SET CMDNAME=test.foo
"C:\tc25\env.exe" -- "test.foo" "git for-each-ref --format %(refname) %(objectname) --sort -committerdate"
 
I think the arguments pass through the parser 2 or 3 times, and each time a % gets removed. Which is why I had to specify 4 %'s.

It might be easier to do a replace of some other symbol with %'s. e.g. #(refname) --> %(refname)
 
You had to write them 4 times because you passed the arguments from one command interpreter to another.
The fold before passing arguments to script was expected, the second, however, was not.
 
What quoting, can you please provide an example?
Just, before you do, I want to once again stress the fact I have no control over invocation of the script itself.
I can only work with what was passed to it.
 
What quoting, can you please provide an example?
Just, before you do, I want to once again stress the fact I have no control over invocation of the script itself.
I can only work with what was passed to it.

You didn't specify previously that you don't have control over invocation of the script.

SETDOS /X-4 won't help, as it only affects nested variables -- and you're not using nested variables.

To clarify, somebody else is passing a command (like "git for-each-ref --format %(refname) %(objectname) --sort -committerdate") to your script, and you need to pass the %(var) variables as-is?

If you have control over the command line, you'd just back quote the line to prevent all variable expansion.

If you don't, and you're trying to handle a command that's already been parsed *before* it's passed to the batch file -- that's more complicated. There are several issues:

1) The parentheses are not valid variable name characters;
2) So you need to turn off variable expansion, but if you do,
3) you'll disable the variable function expansion.

You could try turning on CMD-style variables (i.e., %var%) when you're parsing the input; then TCC won't think that "%(refname)" should be processed as a variable.
 

Similar threads

Back
Top