Skip to content

Commit d82f426

Browse files
authored
New test for regular expression match_list.py (#491)
* match_list.py added for testing of regexps using MATCH builtin rule * let match_list.py to work with python3.x * fixed comment in match_list.py
1 parent ce5309a commit d82f426

File tree

4 files changed

+99
-2
lines changed

4 files changed

+99
-2
lines changed

doc/src/history.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Fix jam/{CPP} bind definitions of 4 or more values in a single
77
declared argument not actually adding all the definitions.
88
-- _Paolo Pastori_
9+
* *New*: Added test for regular expressions with MATCH builtin rule.
10+
-- _Paolo Pastori_
911

1012
== Version 5.4.2
1113

test/README.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ time. All the elements in `names` should be relative paths.
311311

312312
. Stores the state of the working directory in `self.previous_tree`.
313313
. Changes to `subdir`, if it is specified. It is relative to the
314-
`original_workdir` or the workdir specified in `__init`.
314+
`original_workdir` or the workdir specified in `+__init__+`.
315315
. Invokes the `b2` executable, passing `extra_args` to it. The binary should be
316316
located under `<test_invocation_dir>/../src/engine`. This is to make sure
317317
tests use the version of `b2` build from source.
@@ -376,7 +376,7 @@ The members are:
376376
* `expect_modification`
377377
* `expect_nothing`
378378

379-
Note that `expect_modification` is used to check that a either file content or
379+
Note that `expect_modification` is used to check if the file contents or
380380
timestamp has changed. The rationale is that some compilers change content even
381381
if sources does not change, and it's easier to have a method which checks for
382382
both content and time changes.

test/match_list.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2026 Paolo Pastori
4+
# Distributed under the Boost Software License, Version 1.0.
5+
# (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
6+
7+
# List of tested regexps. Each tuple contains the pattern,
8+
# the value used for the test, and the expected result (do not use [] here).
9+
# Any test is processed by an instruction such as
10+
#
11+
# ECHO [ MATCH <pattern> : <value> ] ;
12+
#
13+
# fell free to add more test cases...
14+
15+
# remember to use raw strings to avoid surprises with escaping
16+
trials = [
17+
(r'', r'', r''),
18+
# nothing captured (no parentheses in the pattern)
19+
(r'"hello world"', r'"hello world"', r''),
20+
# captures (more than one)
21+
(r'(first(second))(third)', r'firstsecondthird', r'firstsecond second third'),
22+
# ^ matches at start of line
23+
(r'^(world)', r'"hello world"', r''),
24+
(r'(world)', r'"hello world"', r'world'),
25+
# $ matches at end of line
26+
(r'(hello)$', r'"hello world"', r''),
27+
# . matches any single character
28+
(r'(.)', r'x', r'x'),
29+
# literal dot (with escaping looses special meaning)
30+
# NOTE: a \ followed by one of the characters ^.[$()|*+?\
31+
# matches that character taken as an ordinary character,
32+
# while a \ followed by any other character (but <>) does nothing!
33+
# NOTE: because of common escaping by shell/interpreters
34+
# to obtain a final \ you often have to escape itself using
35+
# \\ or enclose it in raw strings (Python r'..', C++ R"...")
36+
(r'(\\.)', r'y', r''),
37+
(r'(\\.)', r'.', r'.'),
38+
# ? matches an optional atom, matches a sequence
39+
# of 0 or 1 matches of the atom
40+
(r'bar(s)?', r'bar', r''),
41+
(r'bar(s)?', r'bars', r's'),
42+
# + matches a sequence of 1 or more matches of the atom
43+
(r'(cin)+', r'cin', r'cin'),
44+
(r'((cin)+)', r'cincin', r'cincin cin'),
45+
# * matches a sequence of 0 or more matches of the atom
46+
(r'(0)*', r'1', r''),
47+
(r'(0)*', r'1000', r''), # NOTE: this does not work as expected
48+
# at the beginning of the pattern
49+
(r'1(0)*', r'1000', r'0'),
50+
(r'1(0)*1$', r'1001', r'0'),
51+
# \< matches at the beginning of a word
52+
(r'\\<(lo)', r'hello', r''),
53+
(r'\\<(lo)', r"she's so lovely", r'lo'),
54+
# \> matches at the end of a word
55+
(r'"\\>( fi)"', r'fidel', r''),
56+
(r'"\\>( fi)"', r'"hi fi"', r' fi'), # NOTE: extra space in result too
57+
# | separate branches, matches anything that matches one of the branches
58+
(r'(left)|(right)', r'left', r'left'),
59+
(r'(left)|(right)', r'right', r' right'), # NOTE: extra space as first group is empty
60+
# [] character class (list of characters enclosed in []), matches
61+
# any single character from the list. If the list begins with ^, it
62+
# matches any single character not from the rest of the list.
63+
# If two characters in the list are separated by -, this is shorthand
64+
# for the full range of characters between those two.
65+
# To include a literal ] in the list, make it the first character
66+
# (following a possible ^). To include a literal -, make it the first
67+
# or last character. Within brackets special characters ^.[$()|*+?
68+
# loose their special meaning.
69+
(r'"([0-9]+)"', r'1980s', r'1980'),
70+
(r'"([^0-9]+)"', r'1980s', r's'),
71+
# some real life cases
72+
(r'"^([0-9]+)\\.([0-9]+)(.*)$"', r'5.4.3beta', r'5 4 .3beta'),
73+
(r'^@(.*)', r'@my-rule', r'my-rule'),
74+
(r'^(!)?(.*)', r'"!bla bla"', r'! bla bla'),
75+
]
76+
77+
# Do not change code below !
78+
79+
testln = []
80+
exptln = []
81+
for n, c in enumerate(trials):
82+
testln.append('ECHO {} [ MATCH {} : {} ] ;'.format(n, c[0], c[1]))
83+
exptln.append('{} {}'.format(n, c[2]) if c[2] else str(n))
84+
testln.append('EXIT : 0 ;\n')
85+
exptln.append('\n')
86+
87+
import BoostBuild
88+
89+
t = BoostBuild.Tester(pass_toolset=False)
90+
t.write('Jamroot', '\n'.join(testln))
91+
t.run_build_system()
92+
t.expect_output_lines('\n'.join(exptln))
93+
t.expect_nothing_more()
94+
t.cleanup()

test/test_all.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ def reorder_tests(tests, first_test):
394394
"load_order",
395395
"loop",
396396
"make_rule",
397+
"match_list",
397398
"message",
398399
"ndebug",
399400
"no_type",

0 commit comments

Comments
 (0)