|  | # -*- coding: utf-8 -*- | 
|  |  | 
|  | """ | 
|  | Backend management. | 
|  |  | 
|  |  | 
|  | Creating new backends | 
|  | --------------------- | 
|  |  | 
|  | A new backend named 'foo-bar' corresponds to Python module | 
|  | 'tracetool/backend/foo_bar.py'. | 
|  |  | 
|  | A backend module should provide a docstring, whose first non-empty line will be | 
|  | considered its short description. | 
|  |  | 
|  | All backends must generate their contents through the 'tracetool.out' routine. | 
|  |  | 
|  |  | 
|  | Backend attributes | 
|  | ------------------ | 
|  |  | 
|  | ========= ==================================================================== | 
|  | Attribute Description | 
|  | ========= ==================================================================== | 
|  | PUBLIC    If exists and is set to 'True', the backend is considered "public". | 
|  | ========= ==================================================================== | 
|  |  | 
|  |  | 
|  | Backend functions | 
|  | ----------------- | 
|  |  | 
|  | All the following functions are optional, and no output will be generated if | 
|  | they do not exist. | 
|  |  | 
|  | =============================== ============================================== | 
|  | Function                        Description | 
|  | =============================== ============================================== | 
|  | generate_<format>_begin(events) Generate backend- and format-specific file | 
|  | header contents. | 
|  | generate_<format>_end(events)   Generate backend- and format-specific file | 
|  | footer contents. | 
|  | generate_<format>(event)        Generate backend- and format-specific contents | 
|  | for the given event. | 
|  | =============================== ============================================== | 
|  |  | 
|  | """ | 
|  |  | 
|  | __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>" | 
|  | __copyright__  = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" | 
|  | __license__    = "GPL version 2 or (at your option) any later version" | 
|  |  | 
|  | __maintainer__ = "Stefan Hajnoczi" | 
|  | __email__      = "stefanha@redhat.com" | 
|  |  | 
|  |  | 
|  | import os | 
|  |  | 
|  | import tracetool | 
|  |  | 
|  |  | 
|  | def get_list(only_public = False): | 
|  | """Get a list of (name, description) pairs.""" | 
|  | res = [("nop", "Tracing disabled.")] | 
|  | modnames = [] | 
|  | for filename in os.listdir(tracetool.backend.__path__[0]): | 
|  | if filename.endswith('.py') and filename != '__init__.py': | 
|  | modnames.append(filename.rsplit('.', 1)[0]) | 
|  | for modname in sorted(modnames): | 
|  | module = tracetool.try_import("tracetool.backend." + modname) | 
|  |  | 
|  | # just in case; should never fail unless non-module files are put there | 
|  | if not module[0]: | 
|  | continue | 
|  | module = module[1] | 
|  |  | 
|  | public = getattr(module, "PUBLIC", False) | 
|  | if only_public and not public: | 
|  | continue | 
|  |  | 
|  | doc = module.__doc__ | 
|  | if doc is None: | 
|  | doc = "" | 
|  | doc = doc.strip().split("\n")[0] | 
|  |  | 
|  | name = modname.replace("_", "-") | 
|  | res.append((name, doc)) | 
|  | return res | 
|  |  | 
|  |  | 
|  | def exists(name): | 
|  | """Return whether the given backend exists.""" | 
|  | if len(name) == 0: | 
|  | return False | 
|  | if name == "nop": | 
|  | return True | 
|  | name = name.replace("-", "_") | 
|  | return tracetool.try_import("tracetool.backend." + name)[1] | 
|  |  | 
|  |  | 
|  | class Wrapper: | 
|  | def __init__(self, backends, format): | 
|  | self._backends = [backend.replace("-", "_") for backend in backends] | 
|  | self._format = format.replace("-", "_") | 
|  | for backend in self._backends: | 
|  | assert exists(backend) | 
|  | assert tracetool.format.exists(self._format) | 
|  |  | 
|  | def _run_function(self, name, *args, **kwargs): | 
|  | for backend in self._backends: | 
|  | func = tracetool.try_import("tracetool.backend." + backend, | 
|  | name % self._format, None)[1] | 
|  | if func is not None: | 
|  | func(*args, **kwargs) | 
|  |  | 
|  | def generate_begin(self, events, group): | 
|  | self._run_function("generate_%s_begin", events, group) | 
|  |  | 
|  | def generate(self, event, group): | 
|  | self._run_function("generate_%s", event, group) | 
|  |  | 
|  | def generate_backend_dstate(self, event, group): | 
|  | self._run_function("generate_%s_backend_dstate", event, group) | 
|  |  | 
|  | def generate_end(self, events, group): | 
|  | self._run_function("generate_%s_end", events, group) |