]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | # Copyright 2001, 2002 Dave Abrahams |
2 | # Copyright 2003 Douglas Gregor | |
3 | # Copyright 2003 Rene Rivera | |
4 | # Copyright 2002, 2003, 2004, 2005 Vladimir Prus | |
5 | # Distributed under the Boost Software License, Version 1.0. | |
1e59de90 TL |
6 | # (See accompanying file LICENSE.txt or copy at |
7 | # https://www.bfgroup.xyz/b2/LICENSE.txt) | |
7c673cae FG |
8 | |
9 | # | |
10 | # Returns a list of the following substrings: | |
11 | # 1) from beginning till the first occurrence of 'separator' or till the end, | |
12 | # 2) between each occurrence of 'separator' and the next occurrence, | |
13 | # 3) from the last occurrence of 'separator' till the end. | |
14 | # If no separator is present, the result will contain only one element. | |
15 | # | |
16 | ||
17 | rule split ( string separator ) | |
18 | { | |
19 | local result ; | |
20 | local s = $(string) ; | |
21 | ||
22 | # Break pieaces off 's' until it has no separators left. | |
23 | local match = 1 ; | |
24 | while $(match) | |
25 | { | |
26 | match = [ MATCH ^(.*)($(separator))(.*) : $(s) ] ; | |
27 | if $(match) | |
28 | { | |
29 | match += "" ; # in case 3rd item was empty - works around MATCH bug | |
30 | result = $(match[3]) $(result) ; | |
31 | s = $(match[1]) ; | |
32 | } | |
33 | } | |
34 | # Combine the remaining part at the beginning, which does not have | |
35 | # separators, with the pieces broken off. Note that the rule's signature | |
36 | # does not allow the initial s to be empty. | |
37 | return $(s) $(result) ; | |
38 | } | |
39 | ||
40 | if [ HAS_NATIVE_RULE regex : split : 1 ] | |
41 | { | |
42 | NATIVE_RULE regex : split ; | |
43 | } | |
44 | ||
45 | # Returns the concatenated results of Applying regex.split to every element of | |
46 | # the list using the separator pattern. | |
47 | # | |
48 | rule split-list ( list * : separator ) | |
49 | { | |
50 | local result ; | |
51 | for s in $(list) | |
52 | { | |
53 | result += [ split $(s) $(separator) ] ; | |
54 | } | |
55 | return $(result) ; | |
56 | } | |
57 | ||
58 | ||
59 | # Match string against pattern, and return the elements indicated by indices. | |
60 | # | |
61 | rule match ( pattern : string : indices * ) | |
62 | { | |
63 | indices ?= 1 2 3 4 5 6 7 8 9 ; | |
64 | local x = [ MATCH $(pattern) : $(string) ] ; | |
65 | return $(x[$(indices)]) ; | |
66 | } | |
67 | ||
68 | ||
92f5a8d4 | 69 | # Matches all elements of 'list' against the 'pattern' and returns a list of |
7c673cae FG |
70 | # elements indicated by indices of all successful matches. If 'indices' is |
71 | # omitted returns a list of first parenthesised groups of all successful | |
72 | # matches. | |
73 | # | |
74 | rule transform ( list * : pattern : indices * ) | |
75 | { | |
76 | indices ?= 1 ; | |
77 | local result ; | |
78 | for local e in $(list) | |
79 | { | |
80 | local m = [ MATCH $(pattern) : $(e) ] ; | |
81 | if $(m) | |
82 | { | |
83 | result += $(m[$(indices)]) ; | |
84 | } | |
85 | } | |
86 | return $(result) ; | |
87 | } | |
88 | ||
89 | NATIVE_RULE regex : transform ; | |
90 | ||
91 | ||
92 | # Escapes all of the characters in symbols using the escape symbol escape-symbol | |
93 | # for the given string, and returns the escaped string. | |
94 | # | |
95 | rule escape ( string : symbols : escape-symbol ) | |
96 | { | |
97 | local result = "" ; | |
98 | local m = 1 ; | |
99 | while $(m) | |
100 | { | |
11fdf7f2 | 101 | m = [ MATCH "^([^$(symbols)]*)([$(symbols)])(.*)" : $(string) ] ; |
7c673cae FG |
102 | if $(m) |
103 | { | |
104 | m += "" ; # Supposedly a bug fix; borrowed from regex.split | |
105 | result = "$(result)$(m[1])$(escape-symbol)$(m[2])" ; | |
106 | string = $(m[3]) ; | |
107 | } | |
108 | } | |
109 | string ?= "" ; | |
110 | result = "$(result)$(string)" ; | |
111 | return $(result) ; | |
112 | } | |
113 | ||
114 | ||
115 | # Replaces occurrences of a match string in a given string and returns the new | |
116 | # string. The match string can be a regex expression. | |
117 | # | |
118 | rule replace ( | |
119 | string # The string to modify. | |
120 | match # The characters to replace. | |
121 | replacement # The string to replace with. | |
122 | ) | |
123 | { | |
124 | local result = "" ; | |
125 | local parts = 1 ; | |
126 | while $(parts) | |
127 | { | |
128 | parts = [ MATCH ^(.*)($(match))(.*) : $(string) ] ; | |
129 | if $(parts) | |
130 | { | |
131 | parts += "" ; | |
132 | result = "$(replacement)$(parts[3])$(result)" ; | |
133 | string = $(parts[1]) ; | |
134 | } | |
135 | } | |
136 | string ?= "" ; | |
137 | result = "$(string)$(result)" ; | |
138 | return $(result) ; | |
139 | } | |
140 | ||
141 | if [ HAS_NATIVE_RULE regex : replace : 1 ] | |
142 | { | |
143 | NATIVE_RULE regex : replace ; | |
144 | } | |
145 | ||
146 | ||
147 | # Replaces occurrences of a match string in a given list of strings and returns | |
148 | # a list of new strings. The match string can be a regex expression. | |
149 | # | |
150 | # list - the list of strings to modify. | |
151 | # match - the search expression. | |
152 | # replacement - the string to replace with. | |
153 | # | |
154 | rule replace-list ( list * : match : replacement ) | |
155 | { | |
156 | local result ; | |
157 | for local e in $(list) | |
158 | { | |
159 | result += [ replace $(e) $(match) $(replacement) ] ; | |
160 | } | |
161 | return $(result) ; | |
162 | } | |
163 | ||
164 | ||
165 | rule __test__ ( ) | |
166 | { | |
167 | import assert ; | |
168 | ||
169 | assert.result a b c : split "a/b/c" / ; | |
170 | assert.result "" a b c : split "/a/b/c" / ; | |
171 | assert.result "" "" a b c : split "//a/b/c" / ; | |
172 | assert.result "" a "" b c : split "/a//b/c" / ; | |
173 | assert.result "" a "" b c "" : split "/a//b/c/" / ; | |
174 | assert.result "" a "" b c "" "" : split "/a//b/c//" / ; | |
92f5a8d4 TL |
175 | assert.result "" a b c "" : split "abc" "" ; |
176 | assert.result "" "" : split "" "" ; | |
7c673cae FG |
177 | |
178 | assert.result a c b d | |
179 | : match (.)(.)(.)(.) : abcd : 1 3 2 4 ; | |
180 | ||
181 | assert.result a b c d | |
182 | : match (.)(.)(.)(.) : abcd ; | |
183 | ||
184 | assert.result ababab cddc | |
11fdf7f2 | 185 | : match "((ab)*)([cd]+)" : abababcddc : 1 3 ; |
7c673cae FG |
186 | |
187 | assert.result a.h c.h | |
188 | : transform <a.h> \"b.h\" <c.h> : <(.*)> ; | |
189 | ||
190 | assert.result a.h b.h c.h | |
11fdf7f2 | 191 | : transform <a.h> \"b.h\" <c.h> : "<([^>]*)>|\"([^\"]*)\"" : 1 2 ; |
7c673cae FG |
192 | |
193 | assert.result "^<?xml version=\"1.0\"^>" | |
194 | : escape "<?xml version=\"1.0\">" : "&|()<>^" : "^" ; | |
195 | ||
196 | assert.result "<?xml version=\\\"1.0\\\">" | |
197 | : escape "<?xml version=\"1.0\">" : "\\\"" : "\\" ; | |
198 | ||
199 | assert.result "string string " : replace "string string " " " " " ; | |
200 | assert.result " string string" : replace " string string" " " " " ; | |
201 | assert.result "string string" : replace "string string" " " " " ; | |
202 | assert.result "-" : replace "&" "&" "-" ; | |
92f5a8d4 TL |
203 | assert.result "x" : replace "" "" "x" ; |
204 | assert.result "xax" : replace "a" "" "x" ; | |
205 | assert.result "xaxbx" : replace "ab" "" "x" ; | |
7c673cae FG |
206 | |
207 | assert.result "-" "a-b" : replace-list "&" "a&b" : "&" : "-" ; | |
208 | } |