]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/plr/tools/tsar/tsar_rules.py
bfaa179fcd71a5d82f07796b7e0b8eb5dd9a1cd1
[l4.git] / l4 / pkg / plr / tools / tsar / tsar_rules.py
1 #!/usr/bin/python
2
3 """TSAR Event rewrite rule support"""
4
5 import os
6 import tempfile
7 import re
8 import sys
9
10 #pylint: disable=C0103,R0903
11
12
13 class Condition:
14     """Represents a condition to check"""
15     def __init__(self, cond):
16         """Condition has the format: <attribute>:<value>
17            where value can be an integer or a string (if surrounded
18            with quotation marks."""
19         (self.attrib, v) = cond.split(":")
20         if v[0] == '"':
21             self.value = v[1:-1]
22             self.isint = False
23             self.isstring = True
24         else:
25             self.value = int(v, 0)
26             self.isint = True
27             self.isstring = False
28
29         #print self.attrib, " -- ", self.value
30
31     def apply(self, obj):
32         """Apply the condition to a given object.
33
34         Checks if the object matches the (attribute,value)
35         pair specified by this condition.
36         """
37         return getattr(obj, self.attrib) == self.value
38
39     def __repr__(self):
40         if self.isstring:
41             return "Cond(%s == %s)" % (self.attrib, self.value)
42         else:
43             return "Cond(%s == 0x%x)" % (self.attrib, self.value)
44
45
46 class ProcessorRule:
47     """Representation of a single rewrite rule.
48
49     Rules come from a file and consist of a list of (conjunctive)
50     conditions and a rewrite target.
51         * Conditions are a list of <attr> : <val> pairs, separated
52           by commas.
53         * The rewrite target is a <attr> : <val> pair
54         * Values can be integer values (any base encoding is
55           supported) or strings (using quotation marks).
56         * Conditions and rewrite target a separated using an arrow: ->
57     """
58     def __init__(self, _input):
59         self.conditions = []
60         #print _input
61         #print "Conditions: "
62         for cond in _input[0].split(","):
63             self.conditions += [Condition(cond)]
64
65         (self.dest, val) = _input[1].split(":")
66         self.deststring = (val[0] == "\"")
67         if self.deststring:
68             self.destval = val[1:-1]
69         else:
70             self.destval = int(val, 0)
71
72     def apply(self, event):
73         """Apply the rewrite rule to a given event object.
74
75         If the event matches all conditions of this rule,
76         the event's target attribute is rewritten.
77         """
78         for c in self.conditions:
79             #print event
80             #print c
81             if not c.apply(event):
82                 #print "Cond did not hold"
83                 return
84
85         #print "Rewriting: %s -> %s" % (self.dest, self.destval)
86         setattr(event, self.dest, self.destval)
87
88
89 class EventPreprocessor:
90     """Event Preprocessor
91
92     Takes a list of rewrite rules from a configuration file.
93     These rewrite rules can then be applied to an event using
94     the process() function.
95
96     The configuration file is searched either under the name
97     "tsar.rules" in the local directory or by using the
98     TSAR_RULEFILE environment variable if it is set.
99     """
100
101     def tryLocalRuleFile(self):
102         """Try to use local tsar.rules rule file."""
103         try:
104             self.rulefile = file("tsar.rules", "r")
105         except IOError:
106             self.rulefile = None
107
108     def tryEnvRuleFile(self):
109         """Try to find rule file using TSAR_RULEFILE
110            environment variable.
111         """
112         try:
113             envrule = os.getenv("TSAR_RULEFILE")
114             if envrule == "":
115                 self.rulefile = tempfile.NamedTemporaryFile(mode="r")
116             else:
117                 self.rulefile = file(envrule, "r")
118         except IOError:
119             self.rulefile = None
120
121     def parseRules(self):
122         """Read rules from the rule file found."""
123         rules = []
124         for l in self.rulefile.readlines():
125
126             # skip comments
127             if l.strip().startswith("#"):
128                 continue
129
130             l = l.replace(" ", "")
131             m = re.match("(.*)->(.*)", l.strip())
132             if m:
133                 rules += [ProcessorRule(m.groups())]
134         return rules
135
136     def __init__(self):
137         self.rulefile = None
138         self.tryLocalRuleFile()
139         if self.rulefile is None:
140             self.tryEnvRuleFile()
141         if self.rulefile is None:
142             sys.stderr.write("No rule file found. "
143                              "Use TSAR_FULEFILE='' to use none.\n")
144             sys.exit(1)
145
146         self.rules = self.parseRules()
147
148     def process(self, event):
149         """Apply the rewrite rules to the given event."""
150         for r in self.rules:
151             r.apply(event)
152         return event