]> git.cworth.org Git - apitrace/blob - trace_model.cpp
Add a benchmark mode.
[apitrace] / trace_model.cpp
1 /**************************************************************************
2  *
3  * Copyright 2010 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26
27 #include "formatter.hpp"
28 #include "trace_model.hpp"
29
30
31 namespace Trace {
32
33
34 void Null::visit(Visitor &visitor) { visitor.visit(this); }
35 void Bool::visit(Visitor &visitor) { visitor.visit(this); } 
36 void SInt::visit(Visitor &visitor) { visitor.visit(this); } 
37 void UInt::visit(Visitor &visitor) { visitor.visit(this); } 
38 void Float::visit(Visitor &visitor) { visitor.visit(this); } 
39 void String::visit(Visitor &visitor) { visitor.visit(this); } 
40 void Enum::visit(Visitor &visitor) { visitor.visit(this); } 
41 void Bitmask::visit(Visitor &visitor) { visitor.visit(this); } 
42 void Struct::visit(Visitor &visitor) { visitor.visit(this); } 
43 void Array::visit(Visitor &visitor) { visitor.visit(this); } 
44 void Blob::visit(Visitor &visitor) { visitor.visit(this); } 
45 void Pointer::visit(Visitor &visitor) { visitor.visit(this); }
46
47 class Dumper : public Visitor
48 {
49 protected:
50     std::ostream &os;
51     Formatter::Formatter *formatter;
52     Formatter::Attribute *normal;
53     Formatter::Attribute *bold;
54     Formatter::Attribute *italic;
55     Formatter::Attribute *red;
56     Formatter::Attribute *pointer;
57     Formatter::Attribute *literal;
58
59 public:
60     Dumper(std::ostream &_os) : os(_os) {
61         formatter = Formatter::defaultFormatter();
62         normal = formatter->normal();
63         bold = formatter->bold();
64         italic = formatter->italic();
65         red = formatter->color(Formatter::RED);
66         pointer = formatter->color(Formatter::GREEN);
67         literal = formatter->color(Formatter::BLUE);
68     }
69
70     ~Dumper() {
71         delete normal;
72         delete bold;
73         delete italic;
74         delete red;
75         delete pointer;
76         delete literal;
77         delete formatter;
78     }
79
80     void visit(Null *) {
81         os << "NULL";
82     }
83
84     void visit(Bool *node) {
85         os << literal << (node->value ? "true" : "false") << normal;
86     }
87
88     void visit(SInt *node) {
89         os << literal << node->value << normal;
90     }
91
92     void visit(UInt *node) {
93         os << literal << node->value << normal;
94     }
95
96     void visit(Float *node) {
97         os << literal << node->value << normal;
98     }
99
100     void visit(String *node) {
101         os << literal << '"' << node->value << '"' << normal;
102     }
103
104     void visit(Enum *node) {
105         os << literal << node->name << normal;
106     }
107
108     void visit(Bitmask *bitmask) {
109         unsigned long long value = bitmask->value;
110         const Bitmask::Signature *sig = bitmask->sig;
111         bool first = true;
112         for (Bitmask::Signature::const_iterator it = sig->begin(); value != 0 && it != sig->end(); ++it) {
113             assert(it->second);
114             if ((value & it->second) == it->second) {
115                 if (!first) {
116                     os << " | ";
117                 }
118                 os << literal << it->first << normal;
119                 value &= ~it->second;
120                 first = false;
121             }
122         }
123         if (value || first) {
124             if (!first) {
125                 os << " | ";
126             }
127             os << literal << "0x" << std::hex << value << std::dec << normal;
128         }
129     }
130
131     void visit(Struct *s) {
132         const char *sep = "";
133         os << "{";
134         for (unsigned i = 0; i < s->members.size(); ++i) {
135             os << sep << italic << s->sig->member_names[i] << normal << " = ";
136             _visit(s->members[i]);
137             sep = ", ";
138         }
139         os << "}";
140     }
141
142     void visit(Array *array) {
143         if (array->values.size() == 1) {
144             os << "&";
145             _visit(array->values[0]);
146         }
147         else {
148             const char *sep = "";
149             os << "{";
150             for (std::vector<Value *>::iterator it = array->values.begin(); it != array->values.end(); ++it) {
151                 os << sep;
152                 _visit(*it);
153                 sep = ", ";
154             }
155             os << "}";
156         }
157     }
158
159     void visit(Blob *blob) {
160         os << pointer << "blob(" << blob->size << ")" << normal;
161     }
162
163     void visit(Pointer *p) {
164         os << pointer << "0x" << std::hex << p->value << std::dec << normal;
165     }
166
167     void visit(Call *call) {
168         const char *sep = "";
169         os << bold << call->sig->name << normal << "(";
170         for (unsigned i = 0; i < call->args.size(); ++i) {
171             os << sep << italic << call->sig->arg_names[i] << normal << " = ";
172             _visit(call->args[i]);
173             sep = ", ";
174         }
175         os << ")";
176         if (call->ret) {
177             os << " = ";
178             _visit(call->ret);
179         }
180         os << "\n";
181     }
182 };
183
184
185 std::ostream & operator <<(std::ostream &os, Value *value) {
186     Dumper d(os);
187     if (value) {
188         value->visit(d);
189     }
190     return os;
191 }
192
193
194 static inline const Value *unwrap(const Value *node) {
195     const Enum *c = dynamic_cast<const Enum *>(node);
196     if (c)
197         return c->value;
198     return node;
199 }
200
201
202 Value::operator bool(void) const {
203     const Bool *b = dynamic_cast<const Bool *>(unwrap(this));
204     if (b)
205         return b->value;
206     assert(0);
207     return false;
208 }
209
210 Value::operator signed long long(void) const {
211     const SInt *sint = dynamic_cast<const SInt *>(unwrap(this));
212     if (sint)
213         return sint->value;
214     const UInt *uint = dynamic_cast<const UInt *>(unwrap(this));
215     if (uint)
216         return uint->value;
217     assert(0);
218     return 0;
219 }
220
221 Value::operator unsigned long long(void) const {
222     const UInt *uint = dynamic_cast<const UInt *>(unwrap(this));
223     if (uint)
224         return uint->value;
225     assert(0);
226     return 0;
227 }
228
229
230 Value::operator double(void) const {
231     const Float *fl = dynamic_cast<const Float *>(unwrap(this));
232     assert(fl);
233     return fl->value;
234 }
235
236 static Null null;
237
238 const Value & Value::operator[](size_t index) const {
239     const Array *array = dynamic_cast<const Array *>(unwrap(this));
240     if (array) {
241         if (index < array->values.size()) {
242             return *array->values[index];
243         }
244     }
245     return null;
246 }
247
248 void * Value::blob(void) const {
249     const Blob *blob = dynamic_cast<const Blob *>(unwrap(this));
250     if (blob)
251         return blob->buf;
252     const Null *null = dynamic_cast<const Null *>(unwrap(this));
253     if (null)
254         return NULL;
255     assert(0);
256     return NULL;
257 }
258
259 const char * Value::string(void) const {
260     const String *string = dynamic_cast<const String *>(unwrap(this));
261     if (string)
262         return string->value.c_str();
263     const Null *null = dynamic_cast<const Null *>(unwrap(this));
264     if (null)
265         return NULL;
266     assert(0);
267     return NULL;
268 }
269
270 std::ostream & operator <<(std::ostream &os, Call &call) {
271     Dumper d(os);
272     d.visit(&call);
273     return os;
274 }
275
276
277 } /* namespace Trace */