qemu/scripts/tracetool/backend/__init__.py

130 lines
3.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# -*- 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
-----------------
======== =======================================================================
Function Description
======== =======================================================================
<format> Called to generate the format- and backend-specific code for each of
the specified events. If the function does not exist, the backend is
considered not compatible with the given format.
======== =======================================================================
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "stefanha@linux.vnet.ibm.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 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]
def compatible(backend, format):
"""Whether a backend is compatible with the given format."""
if not exists(backend):
raise ValueError("unknown backend: %s" % backend)
backend = backend.replace("-", "_")
format = format.replace("-", "_")
if backend == "nop":
return True
else:
func = tracetool.try_import("tracetool.backend." + backend,
format, None)[1]
return func is not None
def _empty(events):
pass
def generate(backend, format, events):
"""Generate the per-event output for the given (backend, format) pair."""
if not compatible(backend, format):
raise ValueError("backend '%s' not compatible with format '%s'" %
(backend, format))
backend = backend.replace("-", "_")
format = format.replace("-", "_")
if backend == "nop":
func = tracetool.try_import("tracetool.format." + format,
"nop", _empty)[1]
else:
func = tracetool.try_import("tracetool.backend." + backend,
format, None)[1]
func(events)