diff --git a/src/tools/types/asm.py b/src/tools/types/asm.py index b4e1c30e7..a4b4aee61 100644 --- a/src/tools/types/asm.py +++ b/src/tools/types/asm.py @@ -4,10 +4,30 @@ # Distributed under the Boost # Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +from b2.build import type as type_ +from b2.manager import get_manager +from b2.tools.cast import cast +from b2.util import bjam_signature -from b2.build import type -def register(): - type.register_type('ASM', ['s', 'S', 'asm']) +MANAGER = get_manager() +PROJECT_REGISTRY = MANAGER.projects() -register() +# maps project.name() + type to type +_project_types = {} + +type_.register_type('ASM', ['s', 'S', 'asm']) + + +@bjam_signature((['type_'], ['sources', '*'], ['name', '?'])) +def set_asm_type(type_, sources, name=''): + project = PROJECT_REGISTRY.current() + _project_types[project.name() + type_] = _project_types.get( + project.name() + type_, type_) + '_' + + name = name if name else _project_types[project.name() + type_] + type_ += '.asm' + cast(name, type_.upper(), sources, [], [], []) + + +PROJECT_REGISTRY.add_rule("set-asm-type", set_asm_type) diff --git a/src/util/path.py b/src/util/path.py index 222b96bfe..011be7370 100644 --- a/src/util/path.py +++ b/src/util/path.py @@ -193,7 +193,35 @@ def is_rooted (path): # return [ sequence.join $(tokens2) : "/" ] ; # } # } -# +def reverse(path): + """Returns path2 such that `os.path.join(path, path2) == '.'`. + `path` may not contain '..' or be rooted. + + Args: + path (str): the path to reverse + + Returns: + the string of the reversed path + + Example: + + >>> p1 = 'path/to/somewhere' + >>> p2 = reverse('path/to/somewhere') + >>> p2 + '../../..' + >>> os.path.normpath(os.path.join(p1, p2)) + '.' + """ + if is_rooted(path) or '..' in path: + from b2.manager import get_manager + get_manager().errors()( + 'reverse(path): path is either rooted or contains ".." in the path') + if path == '.': + return path + path = os.path.normpath(path) + # os.sep.join() is being used over os.path.join() due + # to an extra '..' that is created by os.path.join() + return os.sep.join('..' for t in path.split(os.sep)) # # # # Auxillary rule: does all the semantic of 'join', except for error cheching. # # The error checking is separated because this rule is recursive, and I don't diff --git a/src/util/regex.py b/src/util/regex.py index 29e26ecf4..6348c6fb1 100644 --- a/src/util/regex.py +++ b/src/util/regex.py @@ -5,9 +5,12 @@ import re +from b2.util import bjam_signature + + def transform (list, pattern, indices = [1]): - """ Matches all elements of 'list' agains the 'pattern' - and returns a list of the elements indicated by indices of + """ Matches all elements of 'list' agains the 'pattern' + and returns a list of the elements indicated by indices of all successfull matches. If 'indices' is omitted returns a list of first paranthethised groups of all successfull matches. @@ -23,3 +26,29 @@ def transform (list, pattern, indices = [1]): return result + +@bjam_signature([['s', 'pattern', 'replacement']]) +def replace(s, pattern, replacement): + """Replaces occurrences of a match string in a given + string and returns the new string. The match string + can be a regex expression. + + Args: + s (str): the string to modify + pattern (str): the search expression + replacement (str): the string to replace each match with + """ + return re.sub(pattern, replacement, s) + + +@bjam_signature((['items', '*'], ['match'], ['replacement'])) +def replace_list(items, match, replacement): + """Replaces occurrences of a match string in a given list of strings and returns + a list of new strings. The match string can be a regex expression. + + Args: + items (list): the list of strings to modify. + match (str): the search expression. + replacement (str): the string to replace with. + """ + return [replace(item, match, replacement) for item in items]