[cmake-developers] Branches on next

Ben Boeckel ben.boeckel at kitware.com
Tue Feb 11 23:03:50 EST 2014


On Tue, Feb 11, 2014 at 19:16:49 -0500, Matthew Woehlke wrote:
> On 2014-02-11 17:54, Ben Boeckel wrote:
> >Parsing in CMake is split into separate sections: the part which parses
> >the lines into CMake's command calls and the part which expands
> >variables (which is why "${cmd}(${args})" isn't allowed).
> 
> Right; I'd figured that much out on my own, and my own parser AFAICT
> operates in a similar manner to CMake itself... it doesn't try to
> tokenize variable substitutions (I didn't need that, and it would
> have made the API non-trivially more complex), although it does choke
> if it seems things like '${foo\n'. From what I can tell, the CMake
> command parsing pass does also?

Probably worth a test. The new parser will see:

    ${foo
    }

and happily lookup the "foo\n" variable. The old parser may have choked.
FWIW, variables named as such can still come in through CMakeCache.txt
and probably the command line as well, so maybe there's some value here.
If it's wanted, I can tighten up the new implementation (it's also the
perfect release version to start rejecting junk like ';' or ' ' in
variable names, but it is probably too late in the release cycle at this
point).

> >ExpandVariablesInString is the part which takes a string which may have
> >variables in it and dereferences them.
> 
> Yes, that's why your changes are probably not all that helpful to
> understanding CMake's parsing... one must first understand the
> initial parse pass, which I assume is still in lex (unless you
> rewrote it too and forgot to mention it ;-), which I doubt).

That code isn't even on the radar for expensive code. It probably could
be replaced with smaller code other than lex/yacc, but it's not worth
the time if performance is the goal (removing lines, however…). Anything
other than comments and blank lines is always in the form:

    <command> "(" <argstring> ")" <newline>

which is pretty fast (the parser is also set up once per file; the EVIS
lex/yacc parser was set up and torn down for *each* expansion which is
generally per-line which contains any of "@$\\").

> >Corner cases I hit while developing the new parser:
> >
> >   - in "\@var@", 'var' is expanded;
> 
> Is '@var@' actually expanded in plain CMake script? (OMG... it is...)
> 
> I wonder how many people are even aware of this. At any rate, at
> least kate doesn't highlight it. (vim doesn't either, but vim also
> doesn't highlight '${var}', so no surprise it doesn't.)
> 
> Alas, my parser does not accept these at present.

It was news to me as well. In any case, it's only expanded if 'var' is
defined (and it must occur all on one line). For the
configure_file(@ONLY) command, it will expand @var@ to empty strings
however. It's a backwards compat thing; see bug 2722.

> >  - '\;' is always literal (don't ask why, but if you don't keep the
> >    slash around, things fail);
> 
> Oh, ick... right now I'm not handling ';' as special but as literal
> text of an argument. If anyone is using that instead of whitespace as
> an argument specifier, then too bad :-). (For now at least, since
> fixing it will require some odd fiddling with the API. Or possibly
> declaring that ';' now counts as whitespace :P.)
> 
> AFAICT, \; is only an escape when it *isn't* quoted. In quotes it's
> just two normal characters. (This appears to be the only escape that
> behaves differently quoted versus not.)

Yeah, I think if the string is quoted, the 'noEscapes' is false which is
where it acts…weird. I think it has to do with nested lists breaking if
the semicolon disappears or something (ExpandListArguments deals with
escaped semicolons and nothing else).

--Ben



More information about the cmake-developers mailing list