def value_to_jam(value, methods=False): """Makes a token to refer to a Python value inside Jam language code. The token is merely a string that can be passed around in Jam code and eventually passed back. For example, we might want to pass PropertySet instance to a tag function and it might eventually call back to virtual_target.add_suffix_and_prefix, passing the same instance. For values that are classes, we'll also make class methods callable from Jam. Note that this is necessary to make a bit more of existing Jamfiles work. This trick should not be used to much, or else the performance benefits of Python port will be eaten. """ global __value_id r = __python_to_jam.get(value, None) if r: return r exported_name = '###_' + str(__value_id) __value_id = __value_id + 1 __python_to_jam[value] = exported_name __jam_to_python[exported_name] = value if methods and type(value) == types.InstanceType: for field_name in dir(value): field = getattr(value, field_name) if callable(field) and not field_name.startswith("__"): bjam.import_rule("", exported_name + "." + field_name, field) return exported_name
def install(self, scanner, target, vtarget): """ Installs the specified scanner on actual target 'target'. vtarget: virtual target from which 'target' was actualized. """ assert isinstance(scanner, Scanner) assert isinstance(target, basestring) assert isinstance(vtarget, basestring) engine = self.manager_.engine() engine.set_target_variable(target, "HDRSCAN", scanner.pattern()) if scanner not in self.exported_scanners_: exported_name = "scanner_" + str(self.count_) self.count_ = self.count_ + 1 self.exported_scanners_[scanner] = exported_name bjam.import_rule("", exported_name, scanner.process) else: exported_name = self.exported_scanners_[scanner] engine.set_target_variable(target, "HDRRULE", exported_name) # scanner reflects difference in properties affecting # binding of 'target', which will be known when processing # includes for it, will give information on how to # interpret quoted includes. engine.set_target_variable(target, "HDRGRIST", str(id(scanner))) pass
def import_(self, name, names_to_import=None, local_names=None): name = name[0] jamfile_module = self.registry.current().project_module() attributes = self.registry.attributes(jamfile_module) location = attributes.get("location") m = self.registry.load_module(name, [location]) for f in m.__dict__: v = m.__dict__[f] if callable(v): bjam.import_rule(jamfile_module, name + "." + f, v) if names_to_import: if not local_names: local_names = names_to_import if len(names_to_import) != len(local_names): self.registry.manager.errors( )("""The number of names to import and local names do not match.""" ) for n, l in zip(names_to_import, local_names): bjam.import_rule(jamfile_module, l, m.__dict__[n])
def install (self, scanner, target, vtarget): """ Installs the specified scanner on actual target 'target'. vtarget: virtual target from which 'target' was actualized. """ assert isinstance(scanner, Scanner) assert isinstance(target, basestring) assert isinstance(vtarget, basestring) engine = self.manager_.engine() engine.set_target_variable(target, "HDRSCAN", scanner.pattern()) if scanner not in self.exported_scanners_: exported_name = "scanner_" + str(self.count_) self.count_ = self.count_ + 1 self.exported_scanners_[scanner] = exported_name bjam.import_rule("", exported_name, scanner.process) else: exported_name = self.exported_scanners_[scanner] engine.set_target_variable(target, "HDRRULE", exported_name) # scanner reflects difference in properties affecting # binding of 'target', which will be known when processing # includes for it, will give information on how to # interpret quoted includes. engine.set_target_variable(target, "HDRGRIST", str(id(scanner))) pass
def _import_rule(self, bjam_module, name, callable_): assert isinstance(bjam_module, basestring) assert isinstance(name, basestring) assert callable(callable_) if hasattr(callable_, "bjam_signature"): bjam.import_rule(bjam_module, name, self.make_wrapper(callable_), callable_.bjam_signature) else: bjam.import_rule(bjam_module, name, self.make_wrapper(callable_))
def init_project(self, project_module): for n in self.local_names: # Using 'getattr' here gives us a bound method, # while using self.__dict__[r] would give unbound one. v = getattr(self, n) if callable(v): if n == "import_": n = "import" else: n = string.replace(n, "_", "-") bjam.import_rule(project_module, n, self.make_wrapper(v)) for n in self.rules: bjam.import_rule(project_module, n, self.make_wrapper(self.rules[n]))
def import_(self, name, names_to_import=None, local_names=None): name = name[0] jamfile_module = self.registry.current().project_module() attributes = self.registry.attributes(jamfile_module) location = attributes.get("location") m = self.registry.load_module(name, [location]) for f in m.__dict__: v = m.__dict__[f] if callable(v): bjam.import_rule(jamfile_module, name + "." + f, v) if names_to_import: if not local_names: local_names = names_to_import if len(names_to_import) != len(local_names): self.registry.manager.errors()("""The number of names to import and local names do not match.""") for n, l in zip(names_to_import, local_names): bjam.import_rule(jamfile_module, l, m.__dict__[n])
def _import_rule(self, bjam_module, name, callable): if hasattr(callable, "bjam_signature"): bjam.import_rule(bjam_module, name, self.make_wrapper(callable), callable.bjam_signature) else: bjam.import_rule(bjam_module, name, self.make_wrapper(callable))