📄 boostbuild.py
字号:
# format headers containing an internal timestamp. # (2) Intel's compiler for Linux has the same behaviour. filesets = [d.modified_files, d.touched_files] while filesets: try: glob_remove(filesets[-1], name) break except ValueError: filesets.pop() if not filesets: annotation("failure", "File %s not touched as expected" % name) self.fail_test(1) def ignore_touch(self, wildcard): self.ignore_elements(self.unexpected_difference.touched_files, wildcard) def ignore(self, wildcard): self.ignore_elements(self.unexpected_difference.added_files, wildcard) self.ignore_elements(self.unexpected_difference.removed_files, wildcard) self.ignore_elements(self.unexpected_difference.modified_files, wildcard) self.ignore_elements(self.unexpected_difference.touched_files, wildcard) def expect_nothing(self, names): for name in self.adjust_names(names): if name in self.difference.added_files: annotation("failure", "File %s added, but no action was expected" % name) self.fail_test(1) if name in self.difference.removed_files: annotation("failure", "File %s removed, but no action was expected" % name) self.fail_test(1) pass if name in self.difference.modified_files: annotation("failure", "File %s modified, but no action was expected" % name) self.fail_test(1) if name in self.difference.touched_files: annotation("failure", "File %s touched, but no action was expected" % name) self.fail_test(1) def expect_nothing_more(self): # Not totally sure about this change, but I do not see a good # alternative. if windows: self.ignore('*.ilk') # MSVC incremental linking files. self.ignore('*.pdb') # MSVC program database files. self.ignore('*.rsp') # Response files. self.ignore('*.tds') # Borland debug symbols. self.ignore('*.manifest') # MSVC DLL manifests. # Debug builds of bjam built with gcc produce this profiling data. self.ignore('gmon.out') self.ignore('*/gmon.out') if not self.unexpected_difference.empty(): print 'FAILED' print '------- The following changes were unexpected -------' self.unexpected_difference.pprint() self.fail_test(1) def __expect_line(self, content, expected, expected_to_exist): expected = expected.strip() lines = content.splitlines() found = False for line in lines: line = line.strip() if fnmatch.fnmatch(line, expected): found = True break if expected_to_exist and not found: annotation("failure", "Did not find expected line:\n%s\nin output:\n%s" % (expected, content)) self.fail_test(1) if not expected_to_exist and found: annotation("failure", "Found an unexpected line:\n%s\nin output:\n%s" % (expected, content)) self.fail_test(1) def expect_output_line(self, line, expected_to_exist=True): self.__expect_line(self.stdout(), line, expected_to_exist) def expect_content_line(self, name, line, expected_to_exist=True): content = self.__read_file(name) self.__expect_line(content, line, expected_to_exist) def __read_file(self, name, exact=False): name = self.adjust_names(name)[0] result = "" try: if exact: result = self.read(name) else: result = string.replace(self.read_and_strip(name), "\\", "/") except (IOError, IndexError): print "Note: could not open file", name self.fail_test(1) return result def expect_content(self, name, content, exact=False): actual = self.__read_file(name, exact) content = string.replace(content, "$toolset", self.toolset+"*") matched = False if exact: matched = fnmatch.fnmatch(actual, content) else: def sorted_(x): x.sort() return x actual_ = map(lambda x: sorted_(x.split()), actual.splitlines()) content_ = map(lambda x: sorted_(x.split()), content.splitlines()) if len(actual_) == len(content_): matched = map( lambda x, y: map(lambda n, p: fnmatch.fnmatch(n, p), x, y), actual_, content_) matched = reduce( lambda x, y: x and reduce( lambda a, b: a and b, y), matched) if not matched: print "Expected:\n" print content print "Got:\n" print actual self.fail_test(1) def maybe_do_diff(self, actual, expected): if os.environ.has_key("DO_DIFF") and os.environ["DO_DIFF"] != '': e = tempfile.mktemp("expected") a = tempfile.mktemp("actual") open(e, "w").write(expected) open(a, "w").write(actual) print "DIFFERENCE" if os.system("diff -u " + e + " " + a): print "Unable to compute difference: diff -u %s %s" % (e, a) os.unlink(e) os.unlink(a) else: print "Set environmental variable 'DO_DIFF' to examine difference." # Helpers. def mul(self, *arguments): if len(arguments) == 0: return None here = arguments[0] if type(here) == type(''): here = [here] if len(arguments) > 1: there = apply(self.mul, arguments[1:]) result = [] for i in here: for j in there: result.append(i + j) return result return here # Internal methods. def ignore_elements(self, list, wildcard): """Removes in-place, element of 'list' that match the given wildcard. """ list[:] = filter(lambda x, w=wildcard: not fnmatch.fnmatch(x, w), list) def adjust_lib_name(self, name): global lib_prefix result = name pos = string.rfind(name, ".") if pos != -1: suffix = name[pos:] if suffix == ".lib": (head, tail) = os.path.split(name) if lib_prefix: tail = "lib" + tail result = os.path.join(head, tail) elif suffix == ".dll": (head, tail) = os.path.split(name) if dll_prefix: tail = "lib" + tail result = os.path.join(head, tail) # If we want to use this name in a Jamfile, we better convert \ to /, as # otherwise we would have to quote \. result = string.replace(result, "\\", "/") return result def adjust_suffix(self, name): if not self.translate_suffixes: return name pos = string.rfind(name, ".") if pos != -1: suffix = name[pos:] name = name[:pos] if suffixes.has_key(suffix): suffix = suffixes[suffix] else: suffix = '' return name + suffix # Acceps either a string or a list of strings and returns a list of strings. # Adjusts suffixes on all names. def adjust_names(self, names): if type(names) == types.StringType: names = [names] r = map(self.adjust_lib_name, names) r = map(self.adjust_suffix, r) r = map(lambda x, t=self.toolset: string.replace(x, "$toolset", t+"*"), r) return r def native_file_name(self, name): name = self.adjust_names(name)[0] elements = string.split(name, "/") return os.path.normpath(apply(os.path.join, [self.workdir]+elements)) # Wait while time is no longer equal to the time last "run_build_system" # call finished. Used to avoid subsequent builds treating existing files as # 'current'. def wait_for_time_change_since_last_build(self): while 1: # In fact, I'm not sure why "+ 2" as opposed to "+ 1" is needed but # empirically, "+ 1" sometimes causes 'touch' and other functions # not to bump the file time enough for a rebuild to happen. if math.floor(time.time()) < math.floor(self.last_build_time_finish) + 2: time.sleep(0.1) else: breakclass List: def __init__(self, s=""): elements = [] if isinstance(s, type("")): # Have to handle espaced spaces correctly. s = string.replace(s, "\ ", '\001') elements = string.split(s) else: elements = s; self.l = [] for e in elements: self.l.append(string.replace(e, '\001', ' ')) def __len__(self): return len(self.l) def __getitem__(self, key): return self.l[key] def __setitem__(self, key, value): self.l[key] = value def __delitem__(self, key): del self.l[key] def __str__(self): return str(self.l) def __repr__(self): return (self.__module__ + '.List(' + repr(string.join(self.l, ' ')) + ')') def __mul__(self, other): result = List() if not isinstance(other, List): other = List(other) for f in self: for s in other: result.l.append(f + s) return result def __rmul__(self, other): if not isinstance(other, List): other = List(other) return List.__mul__(other, self) def __add__(self, other): result = List() result.l = self.l[:] + other.l[:] return result# Quickie tests. Should use doctest instead.if __name__ == '__main__': assert str(List("foo bar") * "/baz") == "['foo/baz', 'bar/baz']" assert repr("foo/" * List("bar baz")) == "__main__.List('foo/bar foo/baz')" print 'tests passed'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -