Merge remote-tracking branch 'remotes/ehabkost/tags/python-next-pull-request' into...
[qemu.git] / scripts / tracetool / backend / __init__.py
blob259c6a6531c6ae25df4a86f57b5ab21d6b5be76f
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 """
5 Backend management.
8 Creating new backends
9 ---------------------
11 A new backend named 'foo-bar' corresponds to Python module
12 'tracetool/backend/foo_bar.py'.
14 A backend module should provide a docstring, whose first non-empty line will be
15 considered its short description.
17 All backends must generate their contents through the 'tracetool.out' routine.
20 Backend attributes
21 ------------------
23 ========= ====================================================================
24 Attribute Description
25 ========= ====================================================================
26 PUBLIC If exists and is set to 'True', the backend is considered "public".
27 ========= ====================================================================
30 Backend functions
31 -----------------
33 All the following functions are optional, and no output will be generated if
34 they do not exist.
36 =============================== ==============================================
37 Function Description
38 =============================== ==============================================
39 generate_<format>_begin(events) Generate backend- and format-specific file
40 header contents.
41 generate_<format>_end(events) Generate backend- and format-specific file
42 footer contents.
43 generate_<format>(event) Generate backend- and format-specific contents
44 for the given event.
45 =============================== ==============================================
47 """
49 __author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
50 __copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
51 __license__ = "GPL version 2 or (at your option) any later version"
53 __maintainer__ = "Stefan Hajnoczi"
54 __email__ = "stefanha@linux.vnet.ibm.com"
57 import os
59 import tracetool
62 def get_list(only_public = False):
63 """Get a list of (name, description) pairs."""
64 res = [("nop", "Tracing disabled.")]
65 modnames = []
66 for filename in os.listdir(tracetool.backend.__path__[0]):
67 if filename.endswith('.py') and filename != '__init__.py':
68 modnames.append(filename.rsplit('.', 1)[0])
69 for modname in sorted(modnames):
70 module = tracetool.try_import("tracetool.backend." + modname)
72 # just in case; should never fail unless non-module files are put there
73 if not module[0]:
74 continue
75 module = module[1]
77 public = getattr(module, "PUBLIC", False)
78 if only_public and not public:
79 continue
81 doc = module.__doc__
82 if doc is None:
83 doc = ""
84 doc = doc.strip().split("\n")[0]
86 name = modname.replace("_", "-")
87 res.append((name, doc))
88 return res
91 def exists(name):
92 """Return whether the given backend exists."""
93 if len(name) == 0:
94 return False
95 if name == "nop":
96 return True
97 name = name.replace("-", "_")
98 return tracetool.try_import("tracetool.backend." + name)[1]
101 class Wrapper:
102 def __init__(self, backends, format):
103 self._backends = [backend.replace("-", "_") for backend in backends]
104 self._format = format.replace("-", "_")
105 for backend in self._backends:
106 assert exists(backend)
107 assert tracetool.format.exists(self._format)
109 def _run_function(self, name, *args, **kwargs):
110 for backend in self._backends:
111 func = tracetool.try_import("tracetool.backend." + backend,
112 name % self._format, None)[1]
113 if func is not None:
114 func(*args, **kwargs)
116 def generate_begin(self, events, group):
117 self._run_function("generate_%s_begin", events, group)
119 def generate(self, event, group):
120 self._run_function("generate_%s", event, group)
122 def generate_backend_dstate(self, event, group):
123 self._run_function("generate_%s_backend_dstate", event, group)
125 def generate_end(self, events, group):
126 self._run_function("generate_%s_end", events, group)