mirror of
https://github.com/boostorg/build.git
synced 2026-01-19 04:02:14 +00:00
Added the ability to escape the '$' character before '(' as "$$" which will allow using the "$()" and "$(())" expressions of bash, sh, and other shells. (#467)
The '$' character is now escaped as the "$$" sequence when a non-zero-length "$$" character sequence ends with the "$(" sequence or the '(' character.
This allows the use of SHELL $(...) or $((...)) expressions within bjam expressions such as "actions { ... }" or "[ SHELL ... ]".
---------
Co-authored-by: René Ferdinand Rivera Morell <grafikrobot@gmail.com>
This commit is contained in:
@@ -2363,6 +2363,20 @@ static int32_t try_parse_variable( char const * * s_, char const * * string,
|
||||
VAR_PARSE_GROUP * out )
|
||||
{
|
||||
char const * s = *s_;
|
||||
// escaping '$' with "$$" sequence when it needed (sequence of multiple "$$" before "$(" or '(')
|
||||
if ( s[ 0 ] == '$' && s[ 1 ] == '$' )
|
||||
{
|
||||
// count repeats of "$$" and checks that sequence used before '(' or "$(" (when escaping needed)
|
||||
for(s += 2; s[ 0 ] == '$' && s[ 1 ] == '$'; s += 2);
|
||||
if(s[ 0 ] == '(' || (s[ 0 ] == '$' && s[ 1 ] == '(')) {
|
||||
// save escaped '$'s as half of found "$$" sequence
|
||||
size_t repeats = (s - *s_) / 2;
|
||||
var_parse_group_maybe_add_constant( out, *string, s - repeats );
|
||||
*string = s;
|
||||
}
|
||||
*s_ = s;
|
||||
return 1;
|
||||
}
|
||||
if ( s[ 0 ] == '$' && s[ 1 ] == '(' )
|
||||
{
|
||||
var_parse_group_maybe_add_constant( out, *string, s );
|
||||
|
||||
39
test/escaping_dollar_before_round_bracket.py
Executable file
39
test/escaping_dollar_before_round_bracket.py
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright Ivan Kotov 2025.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE.txt or copy at
|
||||
# https://www.bfgroup.xyz/b2/LICENSE.txt)
|
||||
|
||||
# Regression test. When Jamfile contained "using whatever ; " and the 'whatever'
|
||||
# module declared a project, then all targets in Jamfile were considered to be
|
||||
# declared in the project associated with 'whatever', not with the Jamfile.
|
||||
|
||||
import BoostBuild
|
||||
|
||||
t = BoostBuild.Tester(use_test_config=False)
|
||||
|
||||
t.write("jamroot.jam", """\
|
||||
|
||||
rule test {
|
||||
value = zero ;
|
||||
echo $(value) ;
|
||||
echo $$(value) ;
|
||||
echo $$$(value) ;
|
||||
echo $$$$(value) ;
|
||||
echo $$$$ ;
|
||||
}
|
||||
|
||||
test a.test ;
|
||||
|
||||
""")
|
||||
|
||||
t.run_build_system(stdout="""zero
|
||||
$(value)
|
||||
$zero
|
||||
$$(value)
|
||||
$$$$
|
||||
...found 1 target...
|
||||
""")
|
||||
|
||||
t.cleanup()
|
||||
@@ -293,6 +293,7 @@ tests = ["abs_workdir",
|
||||
"dll_path",
|
||||
"double_loading",
|
||||
"duplicate",
|
||||
"escaping_dollar_before_round_bracket",
|
||||
"example_libraries",
|
||||
"example_make",
|
||||
"exit_status",
|
||||
|
||||
Reference in New Issue
Block a user