1 /**************************************************************************
3 * Copyright 2012 VMware, Inc.
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 **************************************************************************/
35 #include <trace_callset.hpp>
37 using namespace trace;
40 // Parser class for call sets
48 CallSetParser(CallSet &_set) :
66 CallNo start = std::numeric_limits<CallNo>::min();
67 CallNo stop = std::numeric_limits<CallNo>::max();
69 CallFlags freq = FREQUENCY_ALL;
71 freq = parseFrequency();
73 if (isOperator('*')) {
76 start = parseCallNo();
77 if (isOperator('-')) {
87 if (isOperator('/')) {
91 freq = parseFrequency();
95 set.addRange(CallRange(start, stop, step, freq));
98 // match and consume an operator
99 bool isOperator(char c) {
100 if (lookahead == c) {
109 CallNo parseCallNo() {
113 CallNo digit = consume() - '0';
114 number = number * 10 + digit;
117 std::cerr << "error: expected digit, found '" << lookahead << "'\n";
124 CallFlags parseFrequency() {
128 freq.push_back(consume());
131 std::cerr << "error: expected frequency, found '" << lookahead << "'\n";
135 if (freq == "frame") {
136 return FREQUENCY_FRAME;
137 } else if (freq == "rendertarget" || freq == "fbo") {
138 return FREQUENCY_RENDERTARGET;
139 } else if (freq == "render" || freq == "draw") {
140 return FREQUENCY_RENDER;
142 std::cerr << "error: expected frequency, found '" << freq << "'\n";
144 return FREQUENCY_NONE;
148 // match lookahead with a digit (does not consume)
149 bool isDigit() const {
150 return lookahead >= '0' && lookahead <= '9';
153 bool isAlpha() const {
154 return lookahead >= 'a' && lookahead <= 'z';
157 void skipWhiteSpace() {
163 bool isSpace() const {
164 return lookahead == ' ' ||
170 virtual char consume() = 0;
174 class StringCallSetParser : public CallSetParser
179 StringCallSetParser(CallSet &_set, const char *_buf) :
197 class FileCallSetParser : public CallSetParser
199 std::ifstream stream;
202 FileCallSetParser(CallSet &_set, const char *filename) :
205 stream.open(filename);
206 if (!stream.is_open()) {
207 std::cerr << "error: failed to open \"" << filename << "\"\n";
211 stream.get(lookahead);
219 stream.get(lookahead);
226 CallSet::CallSet(const char *string): limits(std::numeric_limits<CallNo>::min(), std::numeric_limits<CallNo>::max())
228 if (*string == '@') {
229 FileCallSetParser parser(*this, &string[1]);
232 StringCallSetParser parser(*this, string);
238 CallSet::CallSet(CallFlags freq): limits(std::numeric_limits<CallNo>::min(), std::numeric_limits<CallNo>::max()) {
239 if (freq != FREQUENCY_NONE) {
240 CallNo start = std::numeric_limits<CallNo>::min();
241 CallNo stop = std::numeric_limits<CallNo>::max();
243 addRange(CallRange(start, stop, step, freq));