Commandline parsing problem

General FreeBASIC programming questions.
fzabkar
Posts: 154
Joined: Sep 29, 2018 2:52
Location: Australia

Re: Commandline parsing problem

Post by fzabkar »

fxm wrote:In order to update the COMMAND documentation page:
Is this behavior specific to Windows or general (same behavior with Linux)?
I don't have a Linux box to test this. Sorry.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Commandline parsing problem

Post by jj2007 »

For Windows, my tests showed 'escaping' behaviour for CommandLineToArgvW but 'straight' results for GetCommandLine (both A and W).
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Commandline parsing problem

Post by badidea »

Ubuntu mate 18.04, 64-bit, mate terminal 1.20.0:

Code: Select all

for i as ulong = 0 to 3
	print command(i),
next
print

Code: Select all

$ ./test "abc" d e
./test        abc           d             e             

$ ./test a\\b d"e f"g h
./test        a\b           de fg         h             

$ ./test a\\\"b c d
./test        a\"b          c             d             

$ ./test a\\\\"b c" d e
./test        a\\b c        d             e             
Second entry only 1 "\" instead of 2

Code: Select all

$ ./test "a b c" d e
./test        a b c         d             e             

$ ./test "ab\"c" "\\" d
./test        ab"c          \             d             

$ ./test a\\\b d"e f"g h
./test        a\b           de fg         h             

$ ./test a\\\"b c d
./test        a\"b          c             d             

$ ./test a\\\\"b c" d e
./test        a\\b c        d             e             
Third entry only 1 "\" instead of 3

There must be some logic behind it, but too confusing for me.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Commandline parsing problem

Post by fxm »

So I added a warning sentence without specifying the details on page 'COMMAND' of the documentation:
KeyPgCommand → fxm [added warning sentence on backslash(es) usage]
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Commandline parsing problem

Post by marcov »

badidea wrote:Ubuntu mate 18.04, 64-bit, mate terminal 1.20.0:
On *nix it depends on the shell how parameters are expanded. IOW the escapes are processed before the parameters are passed to the program.

The argv/argc generating API functions are probably meant to imitate this. But that is *nix emulation, and IMHO this should be fixed in the RTS.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Commandline parsing problem

Post by coderJeff »

It's consistent, sort-of.

For windows, in my opinion, it will be common behaviour for many windows programs to have \" => " escape translation. FB follows theses rules. Actually, FB doesn't do anything special. It just uses same behaviour as any other 'gcc' or 'vs' compiled program would, what follows MSDN rules.

For *nix and also bash or sh shells running on dos / windows, the shell has many options for controlling how arguments are passed to the called program. FB doesn't control that; it would be weird to have shell options to control how arguments are expanded and then have the FB program ignore the user's selected shell options.

Therefore, in general, when calling an FB program, refer to the shell's (bash/sh/csh/gitbash/cmd.exe, etc) for rules on argument passing.


However, of interest will be EXEC, CHAIN, SHELL, RUN:
- when caller is a freebasic program and callee is also a freebasic program, argument handling *should* be consistent.
- dos and *nix use fb_hParseArgs() which follows the same \" escaping rules as windows before calling spawn* or exec* system functions.
- for windows, the command line in source code is passed as-is to CreateProcess() so default handling should also follow the \" escaping rules.

Reason for escaping \": I would expect how else to let a program know that you are actually passing a double quote (") as part of the argument.

Ultimately, I don't think is a bug. If you really want to implement your own rules on windows, then use "GetCommandLineA()" or "GetCommandLineW()" as suggested by jj2007 and do whatever you want. But if really think is a bug, then, what's the new rules? Would be nice if there is come consistency across platforms, thanks. FB programs work fine using forward slash '/' as a path separator for FB built-ins. Personally, my preference is to always use '/' for path separators, and then only convert (and/or escape) as needed for system calls. Obviously, others may have other preferences.
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Commandline parsing problem

Post by marcov »

Afaik VIsual Studio does not do this, so I doublechecked. Yes, MSDN has old functions for it (NT4 POSIX system?), but VS is not using them, running e.g.

Code: Select all

int main(int argc, char *argv[])
{	
	printf("%s %d\n", argv[1],strlen(argv[1]));
	return 0;
}
in e.g. VS 2015 with \t as commandline param (no quotes) returns

\t 2

mingw is still Unix centric due to its msys emulation environment.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Commandline parsing problem

Post by coderJeff »

marcov wrote:Afaik VIsual Studio does not do this
Doesn't do what? I must be missing something important, because freebasic does same.

Straight FB using COMMAND() from cmd.exe shell: 'cmd-line1 \t'

Code: Select all

/' OUTPUT: 
arg 0 : 'cmd-line1', len=9
arg 1 : '\t', len=2
'/

dim i as integer = 0
while command( i ) > ""
	print "arg " & i & " : " & "'" & command( i ) & "', len=" & len(command( i ))
	i += 1
wend
Straight FB using __FB_ARGC__ & __FB_ARGV__ from cmd.exe shell: 'cmd-line2 \t'

Code: Select all

/' OUTPUT: 
arg 0 : 'cmd-line2', len=9
arg 1 : '\t', len=2
'/

'' implicit main
for i as integer = 0 to __FB_ARGC__ - 1
	print "arg " & i & " : '" & *(__FB_ARGV__[i]) & "', len=" & len(*(__FB_ARGV__[i]))
next 

This next one is a little trickier, just because how fbc handles implicit main and 'main' module.
Need to name the source file something different than the target exe name: e.g. 'fbc -m cmd-line3 cmd-line3-source.bas'
from cmd.exe shell: 'cmd-line3 \t'

Code: Select all

/' OUTPUT:
arg 0 : 'cmd-line3', len=9
arg 1 : '\t', len=2
'/

'' explicit main
function main cdecl alias "main" _
	( _
		byval argc as integer, _
		byval argv as zstring ptr ptr, _
		byval envp as zstring ptr ptr _
	) as integer 

	for i as integer = 0 to argc - 1
		print "arg " & i & " : '" & *(argv[i]) & "', len=" & len(*(argv[i]))
	next 

    return 0

end function
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Commandline parsing problem

Post by marcov »

I reread the thread in more detail (and better separating old from new posts), and indeed vs does interpret quotes.

testprogram "C:\Documents and Settings\Zippy\"

prints trailing "

Ugh
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Commandline parsing problem

Post by jj2007 »

Which can be interpreted in three ways:
1. ugly but correct - it's a Windows "feature"
2. ugly and incorrect - as a coder, I want to decide myself what to do with the commandline
3. ugly but irrelevant - you can't produce such a commandline by dragging a file over the exe

My preference would be 2 but I use GetCommandLine anyway, and that one doesn't tamper the commandline ;-)
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Commandline parsing problem

Post by marcov »

jj2007 wrote:Which can be interpreted in three ways:
1. ugly but correct - it's a Windows "feature"
Definitely not, it is a feature of the MSVCRT runtime, not necessarily windows (kernel32/user32)
2. ugly and incorrect - as a coder, I want to decide myself what to do with the commandline
3. ugly but irrelevant - you can't produce such a commandline by dragging a file over the exe

My preference would be 2 but I use GetCommandLine anyway, and that one doesn't tamper the commandline ;-)
[/quote]

IMHO I'd still fix the RTS for it. Partial interpretation of commandlines is pointless.
Post Reply