Loading core/product_config.rbc +42 −5 Original line number Diff line number Diff line Loading @@ -463,6 +463,28 @@ def _mkinfo(file, message = ""): print(message) def __mkparse_pattern(pattern): """Parses Make's patsubst pattern.""" in_escape = False res = [] acc = "" for c in pattern.elems(): if in_escape: in_escape = False acc += c elif c == '\\': in_escape = True elif c == '%' and not res: res.append(acc) acc = '' else: acc += c if in_escape: acc += '\\' res.append(acc) return res def __mkpatsubst_word(parsed_pattern,parsed_subst, word): (before, after) = parsed_pattern if not word.startswith(before): Loading @@ -480,16 +502,14 @@ def _mkpatsubst(pattern, replacement, s): Tokenizes `s` (unless it is already a list), and then performs a simple wildcard substitution (in other words, `foo%bar` pattern is equivalent to the regular expression `^foo(.*)bar$, and the first `%` in replacement is $1 in regex terms). Escaping % is not supported $1 in regex terms). """ if pattern.find("\\") >= 0: fail("'\\' in pattern is not allowed") parsed_pattern = pattern.split("%", 1) parsed_pattern = __mkparse_pattern(pattern) words = s if type(s) == "list" else _mkstrip(s).split(" ") if len(parsed_pattern) == 1: out_words = [ replacement if x == pattern else x for x in words] else: parsed_replacement = replacement.split("%", 1) parsed_replacement = __mkparse_pattern(replacement) out_words = [__mkpatsubst_word(parsed_pattern, parsed_replacement, x) for x in words] return out_words if type(s) == "list" else " ".join(out_words) Loading Loading @@ -522,6 +542,22 @@ def _mksubst(old, new, s): return s.replace(old, new) def _product_copy_files_by_pattern(src, dest, s): """Creates a copy list. For each item in a given list, create <from>:<to> pair, where <from> and <to> are the results of applying Make-style patsubst of <src> and <dest> respectively. E.g. the result of calling this function with ("foo/%", "bar/%", ["a", "b"]) will be ["foo/a:bar/a", "foo/b:bar/b"]. """ parsed_src = __mkparse_pattern(src) parsed_dest = __mkparse_pattern(dest) parsed_percent = ["", ""] words = s if type(s) == "list" else _mkstrip(s).split(" ") return [ __mkpatsubst_word(parsed_percent, parsed_src, x) + ":" + __mkpatsubst_word(parsed_percent, parsed_dest, x) for x in words] def __get_options(): """Returns struct containing runtime global settings.""" settings = dict( Loading Loading @@ -577,6 +613,7 @@ rblf = struct( mksubst = _mksubst, printvars = _printvars, product_configuration = _product_configuration, product_copy_files_by_pattern = _product_copy_files_by_pattern, require_artifacts_in_path = _require_artifacts_in_path, require_artifacts_in_path_relaxed = _require_artifacts_in_path_relaxed, setdefault = _setdefault, Loading tests/run.rbc +3 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ assert_eq("abcZ", rblf.mkpatsubst("%z", "%Z", "abcz")) assert_eq("azx b", rblf.mkpatsubst("az", "AZ", "azx b")) assert_eq(["azx", "b"], rblf.mkpatsubst("az", "AZ", ["azx", "b"])) assert_eq("ABC", rblf.mkpatsubst("abc", "ABC", "abc")) assert_eq(["%/foo"], rblf.mkpatsubst("%", "\\%/%", ["foo"])) assert_eq(["foo/%"], rblf.mkpatsubst("%", "%/%", ["foo"])) assert_eq(["from/a:to/a", "from/b:to/b"], rblf.product_copy_files_by_pattern("from/%", "to/%", "a b")) globals, config = rblf.product_configuration("test/device", init) assert_eq( Loading Loading
core/product_config.rbc +42 −5 Original line number Diff line number Diff line Loading @@ -463,6 +463,28 @@ def _mkinfo(file, message = ""): print(message) def __mkparse_pattern(pattern): """Parses Make's patsubst pattern.""" in_escape = False res = [] acc = "" for c in pattern.elems(): if in_escape: in_escape = False acc += c elif c == '\\': in_escape = True elif c == '%' and not res: res.append(acc) acc = '' else: acc += c if in_escape: acc += '\\' res.append(acc) return res def __mkpatsubst_word(parsed_pattern,parsed_subst, word): (before, after) = parsed_pattern if not word.startswith(before): Loading @@ -480,16 +502,14 @@ def _mkpatsubst(pattern, replacement, s): Tokenizes `s` (unless it is already a list), and then performs a simple wildcard substitution (in other words, `foo%bar` pattern is equivalent to the regular expression `^foo(.*)bar$, and the first `%` in replacement is $1 in regex terms). Escaping % is not supported $1 in regex terms). """ if pattern.find("\\") >= 0: fail("'\\' in pattern is not allowed") parsed_pattern = pattern.split("%", 1) parsed_pattern = __mkparse_pattern(pattern) words = s if type(s) == "list" else _mkstrip(s).split(" ") if len(parsed_pattern) == 1: out_words = [ replacement if x == pattern else x for x in words] else: parsed_replacement = replacement.split("%", 1) parsed_replacement = __mkparse_pattern(replacement) out_words = [__mkpatsubst_word(parsed_pattern, parsed_replacement, x) for x in words] return out_words if type(s) == "list" else " ".join(out_words) Loading Loading @@ -522,6 +542,22 @@ def _mksubst(old, new, s): return s.replace(old, new) def _product_copy_files_by_pattern(src, dest, s): """Creates a copy list. For each item in a given list, create <from>:<to> pair, where <from> and <to> are the results of applying Make-style patsubst of <src> and <dest> respectively. E.g. the result of calling this function with ("foo/%", "bar/%", ["a", "b"]) will be ["foo/a:bar/a", "foo/b:bar/b"]. """ parsed_src = __mkparse_pattern(src) parsed_dest = __mkparse_pattern(dest) parsed_percent = ["", ""] words = s if type(s) == "list" else _mkstrip(s).split(" ") return [ __mkpatsubst_word(parsed_percent, parsed_src, x) + ":" + __mkpatsubst_word(parsed_percent, parsed_dest, x) for x in words] def __get_options(): """Returns struct containing runtime global settings.""" settings = dict( Loading Loading @@ -577,6 +613,7 @@ rblf = struct( mksubst = _mksubst, printvars = _printvars, product_configuration = _product_configuration, product_copy_files_by_pattern = _product_copy_files_by_pattern, require_artifacts_in_path = _require_artifacts_in_path, require_artifacts_in_path_relaxed = _require_artifacts_in_path_relaxed, setdefault = _setdefault, Loading
tests/run.rbc +3 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,9 @@ assert_eq("abcZ", rblf.mkpatsubst("%z", "%Z", "abcz")) assert_eq("azx b", rblf.mkpatsubst("az", "AZ", "azx b")) assert_eq(["azx", "b"], rblf.mkpatsubst("az", "AZ", ["azx", "b"])) assert_eq("ABC", rblf.mkpatsubst("abc", "ABC", "abc")) assert_eq(["%/foo"], rblf.mkpatsubst("%", "\\%/%", ["foo"])) assert_eq(["foo/%"], rblf.mkpatsubst("%", "%/%", ["foo"])) assert_eq(["from/a:to/a", "from/b:to/b"], rblf.product_copy_files_by_pattern("from/%", "to/%", "a b")) globals, config = rblf.product_configuration("test/device", init) assert_eq( Loading