be43472f7bd9f6d2e115842a430aff19e6a73edb
[sdk/emulator/qemu.git] / 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 functions
21 -----------------
22
23 ======== =======================================================================
24 Function Description
25 ======== =======================================================================
26 <format> Called to generate the format- and backend-specific code for each of
27          the specified events. If the function does not exist, the backend is
28          considered not compatible with the given format.
29 ======== =======================================================================
30 """
31
32 __author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
33 __copyright__  = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
34 __license__    = "GPL version 2 or (at your option) any later version"
35
36 __maintainer__ = "Stefan Hajnoczi"
37 __email__      = "stefanha@linux.vnet.ibm.com"
38
39
40 import os
41
42 import tracetool
43
44
45 def get_list():
46     """Get a list of (name, description) pairs."""
47     res = [("nop", "Tracing disabled.")]
48     modnames = []
49     for filename in os.listdir(tracetool.backend.__path__[0]):
50         if filename.endswith('.py') and filename != '__init__.py':
51             modnames.append(filename.rsplit('.', 1)[0])
52     for modname in modnames:
53         module = tracetool.try_import("tracetool.backend." + modname)
54
55         # just in case; should never fail unless non-module files are put there
56         if not module[0]:
57             continue
58         module = module[1]
59
60         doc = module.__doc__
61         if doc is None:
62             doc = ""
63         doc = doc.strip().split("\n")[0]
64
65         name = modname.replace("_", "-")
66         res.append((name, doc))
67     return res
68
69
70 def exists(name):
71     """Return whether the given backend exists."""
72     if len(name) == 0:
73         return False
74     if name == "nop":
75         return True
76     name = name.replace("-", "_")
77     return tracetool.try_import("tracetool.backend." + name)[1]
78
79
80 def compatible(backend, format):
81     """Whether a backend is compatible with the given format."""
82     if not exists(backend):
83         raise ValueError("unknown backend: %s" % backend)
84
85     backend = backend.replace("-", "_")
86     format = format.replace("-", "_")
87
88     if backend == "nop":
89         return True
90     else:
91         func = tracetool.try_import("tracetool.backend." + backend,
92                                     format, None)[1]
93         return func is not None
94
95
96 def _empty(events):
97     pass
98
99 def generate(backend, format, events):
100     """Generate the per-event output for the given (backend, format) pair."""
101     if not compatible(backend, format):
102         raise ValueError("backend '%s' not compatible with format '%s'" %
103                          (backend, format))
104
105     backend = backend.replace("-", "_")
106     format = format.replace("-", "_")
107
108     if backend == "nop":
109         func = tracetool.try_import("tracetool.format." + format,
110                                     "nop", _empty)[1]
111     else:
112         func = tracetool.try_import("tracetool.backend." + backend,
113                                     format, None)[1]
114
115     func(events)