]> git.cworth.org Git - apitrace/blob - cli/cli_pickle.cpp
Python pickle output.
[apitrace] / cli / cli_pickle.cpp
1 /**************************************************************************
2  *
3  * Copyright 2012 Jose Fonseca
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 <string.h>
28
29 #include "pickle.hpp"
30
31 #include "cli.hpp"
32 #include "cli_pager.hpp"
33
34 #include "trace_parser.hpp"
35 #include "trace_model.hpp"
36 #include "trace_callset.hpp"
37
38
39 using namespace trace;
40
41
42 class PickleVisitor : public trace::Visitor
43 {
44 protected:
45     PickleWriter &writer;
46
47 public:
48     PickleVisitor(PickleWriter &_writer) :
49         writer(_writer) {
50     }
51
52     void visit(Null *node) {
53         writer.writeInt(0);
54     }
55
56     void visit(Bool *node) {
57         writer.writeBool(node->value);
58     }
59
60     void visit(SInt *node) {
61         writer.writeInt(node->value);
62     }
63
64     void visit(UInt *node) {
65         writer.writeInt(node->value);
66     }
67
68     void visit(Float *node) {
69         writer.writeFloat(node->value);
70     }
71
72     void visit(Double *node) {
73         writer.writeFloat(node->value);
74     }
75
76     void visit(String *node) {
77         writer.writeString(node->value);
78     }
79
80     void visit(Enum *node) {
81         // TODO: keep symbolic name
82         writer.writeInt(node->value);
83     }
84
85     void visit(Bitmask *node) {
86         // TODO: keep symbolic name
87         writer.writeInt(node->value);
88     }
89
90     void visit(Struct *node) {
91         writer.beginDict();
92         for (unsigned i = 0; i < node->sig->num_members; ++i) {
93             writer.beginItem(node->sig->member_names[i]);
94             _visit(node->members[i]);
95             writer.endItem();
96         }
97         writer.endDict();
98     }
99
100     void visit(Array *node) {
101         writer.beginList();
102         for (std::vector<Value *>::iterator it = node->values.begin(); it != node->values.end(); ++it) {
103             _visit(*it);
104         }
105         writer.endList();
106     }
107
108     void visit(Blob *node) {
109         writer.writeString((const char *)node->buf, node->size);
110     }
111
112     void visit(Pointer *node) {
113         writer.writeInt(node->value);
114     }
115
116     void visit(Call *call) {
117         writer.beginTuple();
118
119         writer.writeInt(call->no);
120
121         writer.writeString(call->name());
122
123         writer.beginList();
124         for (unsigned i = 0; i < call->args.size(); ++i) {
125             if (call->args[i]) {
126                 _visit(call->args[i]);
127             } else {
128                 writer.writeNone();
129             }
130         }
131         writer.endList();
132
133         if (call->ret) {
134             _visit(call->ret);
135         } else {
136             writer.writeNone();
137         }
138
139         writer.endTuple();
140     }
141 };
142
143
144 static trace::CallSet calls(trace::FREQUENCY_ALL);
145
146 static const char *synopsis = "Pickle given trace(s) to standard output.";
147
148 static void
149 usage(void)
150 {
151     std::cout
152         << "usage: apitrace pickle [OPTIONS] <trace-file>...\n"
153         << synopsis << "\n"
154         "\n"
155         "    --calls <CALLSET>   Only pickle specified calls\n"
156     ;
157 }
158
159 static int
160 command(int argc, char *argv[])
161 {
162     int i;
163
164     for (i = 0; i < argc;) {
165         const char *arg = argv[i];
166
167         if (arg[0] != '-') {
168             break;
169         }
170
171         ++i;
172
173         if (!strcmp(arg, "--")) {
174             break;
175         } else if (!strcmp(arg, "--help")) {
176             usage();
177             return 0;
178         } else if (!strcmp(arg, "--calls")) {
179             calls = trace::CallSet(argv[i++]);
180         } else {
181             std::cerr << "error: unknown option " << arg << "\n";
182             usage();
183             return 1;
184         }
185     }
186         
187
188     for (; i < argc; ++i) {
189         trace::Parser parser;
190
191         if (!parser.open(argv[i])) {
192             std::cerr << "error: failed to open " << argv[i] << "\n";
193             return 1;
194         }
195
196         trace::Call *call;
197         while ((call = parser.parse_call())) {
198             if (calls.contains(*call)) {
199                 PickleWriter writer(std::cout);
200                 PickleVisitor visitor(writer);
201                 
202                 visitor.visit(call);
203             }
204             delete call;
205         }
206     }
207
208     return 0;
209 }
210
211 const Command pickle_command = {
212     "pickle",
213     synopsis,
214     usage,
215     command
216 };