[Geany-Devel] Placeholder replacement in (build) commands

Dimitar Zhekov dimitar.zhekov at xxxxx
Thu Apr 2 18:07:23 UTC 2015

On 02.4.2015 г. 03:40, Lex Trotman wrote:
>>>> On 31.3.2015 г. 03:16, Lex Trotman wrote:
>>>> - In all default Geany commands, the placeholders are unquoted, meaning
>>>> that
>>>> any file name with space(s) currently breaks. Shame on us. :)
>>> Well some of the default commands are double quoted, but not all IIRC
>>> (filetypes.c uses all double quotes for eg).
>> Really... with double quotes, very nice for Windows. :)
> Are you sure they don't?  see
> http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
> Says they work, no better than they work on sh though :)

To find proper quoting for Windows, you'll need to look no further than 
spawn_append_argument() in the new spawn. :)

The only thing I'm not sure about are \n \v ... - the official VS 2013 
msdn [1] says "arguments are delimited by white space, which is either a 
space or a tab", but the correct(?) solution in this blog includes \n 
and \v without any explanation. And it may slightly different under the 
various C RTL-s for Win32.

I was aware of this problem, and that's why, even in the oldest spawn 
versions, the blank characters in a Windows command line are #define-d, 
and may be easily changed.

>> I should have clarified: if the original command, before any placeholder
>> expansion, does not contain any quotes. If there is at least a single quote,
>> we assume the user knows what (s)he is doing.
> Well, its a simple rule, but on win, paths ending in backslash will
> break because you get prog "c:\dir with spaces\" and the closing quote
> is escaped.  So its no improvement on the current situation.

What I did not consider is that our placeholders may end in directory 
separator (pretty obvious actually, \ is the root Win~1 directory).
In that case, spawn_append_argument() will do the job.

> Note that the quotes on the C filetype build commands may be because
> of the system() hack, since it passes stuff through cmd before
> creating the process and cmd has *another* set of quotes, see the link
> above.

I know, and have no intention to support the cmd rules, neither in spawn 
nor anywhere else.

> Also if I read the win rules right, quoting %d would prevent you doing
> "%d\filename with spaces" or "%d\%f" to get absolute paths, since it
> doesn't do the catenation of separately quoted parts that sh does (as
> I read it).  On sh you would do %d'\filename with spaces' or %d\\%f.

spawn execute
command line: showargs "foo""b a r""qux"
argv[0] = showargs
argv[1] = foob a rqux

The command line is passed 1:1.

> For Posix sh you simply can't put single quotes inside single quotes
> because backslash is not an escape inside single quotes.  You have to
> end the single quotes just before the single quote, double quote the
> single quote and then single quote the rest. eg cmd 'no $ \ ` special
> chars here except '"'"' or here'

I know... :) We have working natively quoting and escaping and breaking 
and whatever else is required for native quotation functions for Unix 
(g_shell_quote) and Windows (spawn_append_argument), so maybe we can 
stop discussing these details?

>> It'll be a good thing to do IMHO, but won't help in this case. We split the
>> non-shell commands under Unix with glib's g_shell_parse_argv(), which uses
>> the shell syntax. So quoting with 'name' and escaping ' is always right.
> Not under sh, see above.  But if we threw away sh and did our own
> thing then maybe.

Under Unix, we either spawn the command with /bin/sh, which uses the 
shell syntax, or break it into argv with g_shell_parse_argv, which uses 
the shell syntax (without subshells, but let's be realistic).
There is no difference.

So, in my understanding, you want to drop the shell syntax, and that is 
why you want to drop /bin/sh. But what stops "our own thing" from 
producing command line suitable for g_shell_parse_argv, and thus /bin/sh?

>> '$amounts'. Our current double-quoted placeholders make it "$amounts", so
>> the users users of Geany can have fun.
> As the shell substitutes whatever amounts is defined to be :) But
> maybe I *want* to substitute $CFLAGS into the command.

File and directory placeholders.

Now, if you *want* a file or directory placeholder to result in $CFLAGS, 
and then $CFLAGS to be expanded as a shell variable, the current 
double-quoted Geany build commands should be perfect for you, because 
they do exactly that. :)

> So I still think we should either do nothing, or get it RIGHT.
> Adding lots of code to just swap the current issues for a different
> set doesn't sound sensible, but I'm not sure we have quite hit on
> "right" yet.

It's not "lots", the proper quoting functions already exist. Remember 
that we must rewrite the placeholders replacement to *at least* do all 
replacements at once, and maybe add %% for literal % (though it may be 
currently escaped as \% under Unix and quoted with "%" under Windows).

> For me right means:
> - that it "just works" most of the time,
> - there are no situations where the user is screwed totally and can't
> get what they want, and
> - existing quoting either still works or crashes loudly, it never
> silently does something different.

A reasonable minimum.

Personally I wanted to:

- considerably improve the current situation
- with something simple (and it's simple, see "lots" above)
- without breaking anything, even if that means not fixing something

But my idea was no good.

First, the default Geany commands are improperly double quoted, so we 
can expect their user-modified derivatives to retain the double quotes, 
which makes the idea less useful, because of the "no auto quoting if the 
original command line contains at least one quote of any kind".
And it probably does. Gee.

Second, if we unquote the placeholders in all default commands, they 
will be auto quoted, but only until the user adds a probably unrelated 
quote, and then they'll break, which is unacceptable.

So I need some more time to think.

> And there is still those commands that are not run in the shell to
> consider, how are they quoted so they split up right.

Once again, they are run shell-like, see above.

> And windows.

And bash under Windows (part of MSYS), if we want to be complete.

> Sigh!


[1] https://msdn.microsoft.com/en-us/library/17w5ykft.aspx

E-gards: Jimmy

More information about the Devel mailing list