[prob. user error] JuceApplication::initialise() breaks arguments with spaces

Hi JUCE team,

just a heads up:
If you call an app with arguments, the arguments are properly handed over in the argc / argv parameters. Using JUCEApplicationBase::getCommandLineParameterArray() works just find.

However JUCEApplicationBase::initialise (const String& commandLine) has all strings joined, hence putting that in a StringArray::parseFromTokens() leads to trouble.

The best what one can do is ignoreUnused (commandLine) and work with the static JUCEApplicationBase::getCommandLineParameterArray(), rendering the initialise parameter misleading and obsolete.

I don’t know what is best, maybe to change the API, which will lead to little applause from many, or letting people search for solutions how to get arguments with whitespaces correctly processed…

Cheers,
Daniel

1 Like

What kind of trouble?:thinking: The joined arguments are whitespace-separated, so parsing it into a string array with whitespaces as separators works. At least I did that for some apps without any trouble. Or did I get you wrong?

Sorry, I realised I made it complicated:

$> myApp "path with whitespaces/yeah.wav"

JUCEApplicationBase::getCommandLineParameterArray() removes the myApp and shows one string in the array, because it is quoted.
However, StringArray args = StringArray::fromTokens( commandLine); will show “path”, “with”, "whitespaces/yeah.wav"
This is because fromTokens has no idea, if it should take care of quotes, backslashes etc. vs. argc and argv hand them over as correct tokens, as said before.

Hope that makes it clearer…

The documentation of JUCEApplicationBase::initialise() contains the following:

        @param commandLineParameters    the line passed in does not include the name of
                                        the executable, just the parameter list. To get the
                                        parameters as an array, you can call
                                        JUCEApplication::getCommandLineParameters()

So I guess using JUCEApplicationBase::getCommandLineParameterArray() is intended.

The problem is not, that the application name is removed, that is perfectly fine.

The problem is, that if you split the arguments from the commandLine parameter yourself, you end up splitting arguments, that were by quoting perfectly parsed in the first place, because the shell took care of it.

I guess To get the parameters as an array, you can call JUCEApplication::getCommandLineParameters() should be rephrased to To get the parameters as an array, you should call JUCEApplication::getCommandLineParameters().

I know that JUCEApplicationBase::getCommandLineParameterArray() solves the problem. I wrote that in the original post.

But I also know, that the API as it stands suggests to use commandLine, since it is there. And it let me search 1-2 hours why filenames with whitespaces don’t work, even though they are perfectly quoted.

The API should lead me to use the Array in the first place, since that is the correct version.
You should never use the argument list concatenated to a String at all, there is no point in doing so.

I totally agree with you. But what you are asking for is a big API breaking change. Not sure the JUCE team will agree to do it.

You took the words right out of my mouth… (hope I use that phrase right, never got the meaning of that song :wink: )

1 Like

Can you provide an example of what’s going wrong? I have an app where this is working as expected. With

void MyApp::initialise (const String& commandLine)
{
    DBG (commandLine);
    for (auto& s : StringArray::fromTokens (commandLine, true))
        DBG (s);
}

I get

$ ./MyApp "path with whitespaces/yeah.wav" aaa bbb
JUCE v5.2.1
"path with whitespaces/yeah.wav" aaa bbb
"path with whitespaces/yeah.wav"
aaa
bbb

That got me sweating…
But I checked in source control, this is really the code I used.
I am using iTerm (running zsh), maybe I got somehow the arguments double-quoted?
The problem was first reported by my colleague, he is running ubuntu (same project). Strange coincident, that it failed only for both of us.

However, reading into the source of addTokens doesn’t support that hypothesis.

Ok, another try, maybe the result from addTokens came out quoted, and stuffing that into the File constructor screwed up…
That would mean, calling argument.unquoted() in the File constructor would have helped as well.

Well in any case, it is probably a user error, it works now and is only an internal tool, so I leave it and you can ignore the thread…

Sorry for all the noise.