I'm using eclipse on Windows to build a C-project.
I create a preprocessor define containing git status summary git status -s.
This is my define symbol:
GIT_STATUS="$(shell git status -s)"
This works, but if changed files contain spaces those paths are surrounded by un-escaped quotes.
example:
git status -s
M file1.c
M "file 2.c"
expected output:
'-DGIT_STATUS="M file1.c \"file 2.c\""'
In the command-line I can use sed to escape these quotes:
git status -s | sed 's/"/\\"/g'
or
git status -s | sed 's/\x22/\\"/g'
This works. But if I use this in define symbol it doesn't work.
I can replace characters such as a and b:
GIT_STATUS="$(shell git status -s | sed "s/a/b/g")"
But if I add a double quote it won't work. Even if I escape it once or twice or three times.
I either get sed: bad option in substitution expression or an empty string as value for the define.
So now I use a separate file as a workaround:
GIT_STATUS="$(shell git status -s | sed -f ../replace_quotes.sed)"
containing:
s/"/\\\"/g
This works, but I'm looking for a way to do it in one line without an extra file.

I don't know how to debug the intermediate outputs of this process so I don't know what escaped characters are eaten at each step.
sed accepts the backslash (\) as an escape character in regular expressions and in s-command replacement strings. You need to double it to represent a literal backslash, so if you want to replace " with \" then sed needs to see:
s/"/\\"/g
(Alternatively, the s/"/\\\"/g you report using in an external file is equivalent.)
Supposing that your $(shell ...) works as you seem to intend it to do*, your command will be evaluated by a shell, which, in a typical make-hosting environment, would be a Bourne-family shell. Such shells also accept the backslash as an escape character, except inside a single quotes. Also, you need the shell to treat the " characters as literals, not quote characters. So, the shell needs to see:
sed 's/"/\\"/g'
... or an equivalent.
make has idiosyncratic rules about escaping. The backslash is significant as an escape character only in a small number of narrow contexts, so you get a break here. (GNU) make needs to see:
$(shell sed 's/"/\\"/g')
That your starting command works indicates that Eclipse is not running make via a shell, so you don't need another level of escaping for the shell, but apparently Eclipse does perform its own escape processing. This is somewhat to be expected, because it definitely does (Eclipse) variable interpolation. That means it needs to provide a way to escape literal values that look like Eclipse variable references and literal values that look like escapes. I'm having trouble finding documentation of the details, but I'm fairly that means sure you need to double the backslashes again to escape them for Eclipse. That is, I think Eclipse needs to see:
$(shell sed 's/"/\\\\"/g')
Update: but apparently not. Eclipse is doing something strange and possibly buggy here.
*It's unclear to what extent you can or should rely on $(shell ...), because that's a GNU make feature, and tunneling it from Eclipse into make to be expanded there requires a combination of factors to align.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With