Add qemu 2.4.0
[kvmfornfv.git] / qemu / scripts / tracetool / backend / __init__.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5 Backend management.
6
7
8 Creating new backends
9 ---------------------
10
11 A new backend named 'foo-bar' corresponds to Python module
12 'tracetool/backend/foo_bar.py'.
13
14 A backend module should provide a docstring, whose first non-empty line will be
15 considered its short description.
16
17 All backends must generate their contents through the 'tracetool.out' routine.
18
19
20 Backend attributes
21 ------------------
22
23 ========= ====================================================================
24 Attribute Description
25 ========= ====================================================================
26 PUBLIC    If exists and is set to 'True', the backend is considered "public".
27 ========= ====================================================================
28
29
30 Backend functions
31 -----------------
32
33 All the following functions are optional, and no output will be generated if
34 they do not exist.
35
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 =============================== ==============================================
46
47 """
48
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"
52
53 __maintainer__ = "Stefan Hajnoczi"
54 __email__      = "stefanha@linux.vnet.ibm.com"
55
56
57 import os
58
59 import tracetool
60
61
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)
71
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]
76
77         public = getattr(module, "PUBLIC", False)
78         if only_public and not public:
79             continue
80
81         doc = module.__doc__
82         if doc is None:
83             doc = ""
84         doc = doc.strip().split("\n")[0]
85
86         name = modname.replace("_", "-")
87         res.append((name, doc))
88     return res
89
90
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]
99
100
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)
108
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)
115
116     def generate_begin(self, events):
117         self._run_function("generate_%s_begin", events)
118
119     def generate(self, event):
120         self._run_function("generate_%s", event)
121
122     def generate_end(self, events):
123         self._run_function("generate_%s_end", events)