1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4""" 5Backend management. 6 7 8Creating new backends 9--------------------- 10 11A new backend named 'foo-bar' corresponds to Python module 12'tracetool/backend/foo_bar.py'. 13 14A backend module should provide a docstring, whose first non-empty line will be 15considered its short description. 16 17All backends must generate their contents through the 'tracetool.out' routine. 18 19 20Backend functions 21----------------- 22 23======== ======================================================================= 24Function 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 40import os 41 42import tracetool 43 44 45def 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 70def 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 80def 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 96def _empty(events): 97 pass 98 99def 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) 116