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