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