diff --git a/src/engine/function.cpp b/src/engine/function.cpp index 3a8e91de6..0e78c979f 100644 --- a/src/engine/function.cpp +++ b/src/engine/function.cpp @@ -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 ); diff --git a/test/escaping_dollar_before_round_bracket.py b/test/escaping_dollar_before_round_bracket.py new file mode 100755 index 000000000..1ad451246 --- /dev/null +++ b/test/escaping_dollar_before_round_bracket.py @@ -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() diff --git a/test/test_all.py b/test/test_all.py index 8542efacb..65a2aa330 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -293,6 +293,7 @@ tests = ["abs_workdir", "dll_path", "double_loading", "duplicate", + "escaping_dollar_before_round_bracket", "example_libraries", "example_make", "exit_status",