# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and # distribute this software is granted provided this copyright notice appears in # all copies. This software is provided "as is" without express or implied # warranty, and with no claim as to its suitability for any purpose. # # Returns a list of the following substrings: # 1) from beginning till the first occurence of 'separator' or till the end, # 2) between each occurence of 'separator' and the next occurence, # 3) from the last occurence of 'separator' till the end. # If no separator is present, the result will contain only one element. # rule split ( string separator ) { local result ; local s = $(string) ; # Break pieaces off 's' until it has no separators left. local match = 1 ; while $(match) { match = [ MATCH ^(.*)($(separator))(.*) : $(s) ] ; if $(match) { match += "" ; # in case 3rd item was empty - works around MATCH bug result = $(match[3]) $(result) ; s = $(match[1]) ; } } # Combine the remaining part at the beginning, which does not have # separators, with the pieces broken off. # Note that rule's signature does not allow initial s to be empty. return $(s) $(result) ; } # Match string against pattern, and return the elements indicated by # indices. rule match ( pattern : string : indices * ) { indices ?= 1 2 3 4 5 6 7 8 9 ; local x = [ MATCH $(pattern) : $(string) ] ; return $(x[$(indices)]) ; } rule __test__ ( ) { import assert ; assert.result a b c : split "a/b/c" / ; assert.result "" a b c : split "/a/b/c" / ; assert.result "" "" a b c : split "//a/b/c" / ; assert.result "" a "" b c : split "/a//b/c" / ; assert.result "" a "" b c "" : split "/a//b/c/" / ; assert.result "" a "" b c "" "" : split "/a//b/c//" / ; assert.result a c b d : match (.)(.)(.)(.) : abcd : 1 3 2 4 ; assert.result a b c d : match (.)(.)(.)(.) : abcd ; assert.result ababab cddc : match ((ab)*)([cd]+) : abababcddc : 1 3 ; }