Brad King wrote: > On 08/29/2012 09:25 AM, Brad King wrote: >>> I've pushed a generator-expression-refactor branch to my clone. It needs >>> some clean-up, de-duplication etc, but I'm looking for feedback on the >>> approach. >>> >>> In my branch, all parameters must be separated by ','. All commas and >>> colons must appear literally in the expression. This makes escaping >>> not-needed, and multiple-parameter-separators consistent accross all >>> generators. >> >> Great. I'll take a look when I get a chance. > > That looks like a good start. Pre-parsing the entire expression tree > is the right approach. > > While quoting/escaping expanded values is not needed we still need > it for the input, like STREQUAL comparing to "," for example.
The first solution that comes to mind within the current implementation is a <COMMA> or similar. Reading on... > > When we first designed generator expressions it was just for the > basic "$<TARGET_FILE:tgt>"-type expressions. The format for target > names was restricted so we didn't need to think about handling > arbitrary content. The $<0:...> and $<1:...> expressions can > have arbitrary content other than ">" but they always have exactly > one "parameter" so there is no real parsing involved. > > When I mentioned the "$<RANGLE>" expression it was just as an example > of what the current approach can do (a better name might be ANGLE-R). > However, now that you're writing a real lexer/parser we need to think > about how this new mini-language will work syntactically. There should > be no need for $<ANGLE-R> if we have proper quoting rules. Consider > bash syntax like > > echo $(echo 'nested command with )') > > where the quoting protects the close-parenthesis inside $(...) syntax. > In order to allow more readable inputs we could consider allowing > arbitrary whitespace to separate arguments, as in: > > $<STREQUAL "$<TARGET_PROPERTY:TYPE>" > "EXECUTABLE"> > > just like the CMake language itself. If quoting is parsed as part > of the syntax then it can be used for '>' too e.g. > > $<STREQUAL "a" ">"> > > where quoting protects argument contents as in bash. Other examples: $<STREQUAL "a" " "> $<STREQUAL "a" "\""> Which looks like a fairly 'normal' escaping scheme from a c++ point of view. However, the problem is that these generator expressions are in strings already. Which means we'll have this: set_target_properties(foolib PROPERTIES INCLUDE_DIRECTORIES "$<$<STREQUAL \"a b\" \"\\\",\"> \"/bar bat/bag\">" ) because that set_target_properties signature can only take one argument (there are other bug reports about this I think, but I don't recall if it's changable). I don't think it's very readable. In my branch it would be this instead: set_target_properties(foolib PROPERTIES INCLUDE_DIRECTORIES "$<$<STREQUAL:a b,\"$<COMMA>>:/bar bat/bag>" ) which is also not perfect, but is better. In the case of: set_property(TARGET foolib [APPEND] PROPERTY INCLUDE_DIRECTORIES $<$<STREQUAL "a" "\""> "/bar bat/bag"> ) it will create a list of strings. So the const char *input to the generator expression will contain a ';' separated list of strings. > > One way to distinguish expressions with free-form arguments from > those without is whether there is a ':' or whitespace after the > expression name. I don't think that benefits readability. So the options are either: 1) Require the use of $<ANGLE-R> or $<COMMA> inside generator expressions 2) Introduce proper quoting rules. I don't think the current proposal for that is readable enough to be beneficial, but with a different parsing/quoting scheme not based on whitespace and "\"", it might be workable. I think that (1) is cheap and worth it. One unfortunate place where it doesn't fit and where $<COMMA> would have to be broadly used would be this: set_target_properties(foolib PROPERTIES COMPILE_OPTIONS "$<$<CONFIG:Debug>:-Wl$<COMMA>no-undefined>" ) That is fixable if we choose a different parameter separation character (and port $<AND> and $<OR> to it too). Colon is not an option because it makes the language more confusing, and would require a $<COLON>, which would need to be broadly used to escape 'Qt5::Core' etc. Looking at my keyboard, how about '?' '|' '\'' '#' or '*'? $<AND:$<STREQUAL:a*b>*$<TARGET_PROPERTY:TYPE*EXECUTABLE>> $<AND:$<STREQUAL:a|b>|$<TARGET_PROPERTY:TYPE|EXECUTABLE>> $<AND:$<STREQUAL:a'b>'$<TARGET_PROPERTY:TYPE'EXECUTABLE>> $<AND:$<STREQUAL:a#b>#$<TARGET_PROPERTY:TYPE#EXECUTABLE>> $<AND:$<STREQUAL:a?b>?$<TARGET_PROPERTY:TYPE?EXECUTABLE>> I prefer '*' because '?' doesn't stand out enough and :a?b seems wrong. '|' means OR more strongly to me than '*' would mean multiply in this context, and stands out well. '#' might work too, but I think it would be parsed as a comment if the whole expression was not surrounded in quotes? Thanks, Steve. -- Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers