56
|
1 |
/*
|
|
2 |
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
|
3 |
* All rights reserved.
|
|
4 |
* This component and the accompanying materials are made available
|
|
5 |
* under the terms of "Eclipse Public License v1.0"
|
|
6 |
* which accompanies this distribution, and is available
|
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
8 |
*
|
|
9 |
* Initial Contributors:
|
|
10 |
* Nokia Corporation - initial contribution.
|
|
11 |
*
|
|
12 |
* Contributors:
|
|
13 |
*
|
|
14 |
* Description:
|
|
15 |
*
|
|
16 |
* OST trace parser rule
|
|
17 |
*
|
|
18 |
*/
|
|
19 |
package com.nokia.tracecompiler.engine.rules.osttrace;
|
|
20 |
|
|
21 |
import java.util.ArrayList;
|
|
22 |
import java.util.List;
|
|
23 |
|
|
24 |
import com.nokia.tracecompiler.engine.TraceLocation;
|
|
25 |
import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode;
|
|
26 |
import com.nokia.tracecompiler.engine.rules.AutoAddFunctionParametersRule;
|
|
27 |
import com.nokia.tracecompiler.engine.rules.AutoAddReturnParameterRule;
|
|
28 |
import com.nokia.tracecompiler.engine.rules.AutoAddThisPtrRule;
|
|
29 |
import com.nokia.tracecompiler.engine.rules.AutoAddValueRule;
|
|
30 |
import com.nokia.tracecompiler.engine.rules.AutomaticTraceTextRule;
|
|
31 |
import com.nokia.tracecompiler.engine.rules.ComplexHeaderRuleImpl;
|
|
32 |
import com.nokia.tracecompiler.engine.rules.EntryTraceRule;
|
|
33 |
import com.nokia.tracecompiler.engine.rules.ExitTraceRule;
|
|
34 |
import com.nokia.tracecompiler.engine.rules.PerformanceEventStartRule;
|
|
35 |
import com.nokia.tracecompiler.engine.rules.PerformanceEventStopRule;
|
|
36 |
import com.nokia.tracecompiler.engine.rules.ReadOnlyObjectRuleImpl;
|
|
37 |
import com.nokia.tracecompiler.engine.rules.SourceParserRuleBase;
|
|
38 |
import com.nokia.tracecompiler.engine.rules.StateTraceRule;
|
|
39 |
import com.nokia.tracecompiler.engine.source.SourceParserResult;
|
|
40 |
import com.nokia.tracecompiler.model.TraceCompilerException;
|
|
41 |
import com.nokia.tracecompiler.model.TraceModelExtension;
|
|
42 |
import com.nokia.tracecompiler.model.TraceParameter;
|
|
43 |
import com.nokia.tracecompiler.source.FormatMapping;
|
|
44 |
import com.nokia.tracecompiler.source.SourceContext;
|
|
45 |
import com.nokia.tracecompiler.source.SourceParser;
|
|
46 |
|
|
47 |
/**
|
|
48 |
* OST trace parser rule
|
|
49 |
*
|
|
50 |
*/
|
|
51 |
public final class OstTraceParserRule extends SourceParserRuleBase {
|
|
52 |
|
|
53 |
/**
|
|
54 |
* PERFORMANCE group name
|
|
55 |
*/
|
|
56 |
private static final String PERFORMANCE_GROUP_NAME = "TRACE_PERFORMANCE"; //$NON-NLS-1$
|
|
57 |
|
|
58 |
/**
|
|
59 |
* STATE group name
|
|
60 |
*/
|
|
61 |
private static final String STATE_GROUP_NAME = "TRACE_STATE"; //$NON-NLS-1$
|
|
62 |
|
|
63 |
/**
|
|
64 |
* FLOW group name
|
|
65 |
*/
|
|
66 |
private static final String FLOW_GROUP_NAME = "TRACE_FLOW"; //$NON-NLS-1$
|
|
67 |
|
|
68 |
/**
|
|
69 |
* Data trace parameter count
|
|
70 |
*/
|
|
71 |
private static final int DATA_PARAMETER_COUNT = 2; // CodForChk_Dis_Magic
|
|
72 |
|
|
73 |
/**
|
|
74 |
* Entry Ext trace parameter count
|
|
75 |
*/
|
|
76 |
private static final int ENTRY_EXT_PARAMETER_COUNT = 1; // CodForChk_Dis_Magic
|
|
77 |
|
|
78 |
/**
|
|
79 |
* Exit Ext trace parameter count
|
|
80 |
*/
|
|
81 |
private static final int EXIT_EXT_PARAMETER_COUNT = 2; // CodForChk_Dis_Magic
|
|
82 |
|
|
83 |
/**
|
|
84 |
* Trace parameter index list
|
|
85 |
*/
|
|
86 |
class TraceParameterIndexList {
|
|
87 |
|
|
88 |
/**
|
|
89 |
* Minimum number of parameters needed to decode traces
|
|
90 |
*/
|
|
91 |
int minParamCount;
|
|
92 |
|
|
93 |
/**
|
|
94 |
* Preprocessor level index
|
|
95 |
*/
|
|
96 |
int levelIndex;
|
|
97 |
|
|
98 |
/**
|
|
99 |
* Trace name index
|
|
100 |
*/
|
|
101 |
int nameIndex;
|
|
102 |
|
|
103 |
/**
|
|
104 |
* Trace text index
|
|
105 |
*/
|
|
106 |
int textIndex;
|
|
107 |
|
|
108 |
/**
|
|
109 |
* Trace group index in case group name is free-form
|
|
110 |
*/
|
|
111 |
int groupIndex;
|
|
112 |
|
|
113 |
/**
|
|
114 |
* Trace group name in case group name is pre-determined by rules
|
|
115 |
*/
|
|
116 |
String groupName;
|
|
117 |
}
|
|
118 |
|
|
119 |
/**
|
|
120 |
* List of flags related to OST API macro
|
|
121 |
*/
|
|
122 |
class TraceParameterFlagList {
|
|
123 |
|
|
124 |
/**
|
|
125 |
* Data tag
|
|
126 |
*/
|
|
127 |
boolean hasDataTag;
|
|
128 |
|
|
129 |
/**
|
|
130 |
* State tag
|
|
131 |
*/
|
|
132 |
boolean hasStateTag;
|
|
133 |
|
|
134 |
/**
|
|
135 |
* Ext tag
|
|
136 |
*/
|
|
137 |
boolean hasExtTag;
|
|
138 |
|
|
139 |
/**
|
|
140 |
* Event start tag
|
|
141 |
*/
|
|
142 |
boolean hasEventStartTag;
|
|
143 |
|
|
144 |
/**
|
|
145 |
* Event stop
|
|
146 |
*/
|
|
147 |
boolean hasEventStopTag;
|
|
148 |
|
|
149 |
/**
|
|
150 |
* Function entry
|
|
151 |
*/
|
|
152 |
boolean hasFunctionEntryTag;
|
|
153 |
|
|
154 |
/**
|
|
155 |
* Function exit
|
|
156 |
*/
|
|
157 |
boolean hasFunctionExitTag;
|
|
158 |
|
|
159 |
/**
|
|
160 |
* Constructor
|
|
161 |
*
|
|
162 |
* @param tag
|
|
163 |
* the trace tag
|
|
164 |
*/
|
|
165 |
TraceParameterFlagList(String tag) {
|
|
166 |
hasDataTag = tag.indexOf(OstConstants.DATA_TRACE_TAG) > 0;
|
|
167 |
hasStateTag = tag.indexOf(OstConstants.STATE_TRACE_TAG) > 0;
|
|
168 |
hasExtTag = tag.indexOf(OstConstants.EXTENSION_TRACE_TAG) > 0;
|
|
169 |
hasEventStartTag = tag
|
|
170 |
.indexOf(OstConstants.PERFORMANCE_EVENT_START_TAG) > 0;
|
|
171 |
hasEventStopTag = tag
|
|
172 |
.indexOf(OstConstants.PERFORMANCE_EVENT_STOP_TAG) > 0;
|
|
173 |
hasFunctionEntryTag = tag.indexOf(OstConstants.FUNCTION_ENTRY_TAG) > 0;
|
|
174 |
hasFunctionExitTag = tag.indexOf(OstConstants.FUNCTION_EXIT_TAG) > 0;
|
|
175 |
}
|
|
176 |
|
|
177 |
/**
|
|
178 |
* Checks if any of the flags is set
|
|
179 |
*
|
|
180 |
* @return true if flag is set
|
|
181 |
*/
|
|
182 |
boolean hasFlags() {
|
|
183 |
return hasDataTag || hasStateTag || hasExtTag || hasEventStartTag
|
|
184 |
|| hasEventStopTag || hasFunctionEntryTag
|
|
185 |
|| hasFunctionExitTag;
|
|
186 |
}
|
|
187 |
|
|
188 |
}
|
|
189 |
|
|
190 |
/**
|
|
191 |
* Offset to preprocessor level
|
|
192 |
*/
|
|
193 |
private static final int PREPROCESSOR_LEVEL_OFFSET = 0; // CodForChk_Dis_Magic
|
|
194 |
|
|
195 |
/**
|
|
196 |
* Offset to group name if preprocessor level is not in use
|
|
197 |
*/
|
|
198 |
private static final int GROUP_NAME_OFFSET = 0; // CodForChk_Dis_Magic
|
|
199 |
|
|
200 |
/**
|
|
201 |
* Offset to trace name if preprocessor level is not in use
|
|
202 |
*/
|
|
203 |
private static final int TRACE_NAME_OFFSET = 1; // CodForChk_Dis_Magic
|
|
204 |
|
|
205 |
/**
|
|
206 |
* Offset to trace text if preprocessor level is not in use
|
|
207 |
*/
|
|
208 |
private static final int TRACE_TEXT_OFFSET = 2; // CodForChk_Dis_Magic
|
|
209 |
|
|
210 |
/**
|
|
211 |
* Minimum number of parameters if preprocessor level is not in use
|
|
212 |
*/
|
|
213 |
private static final int MIN_PARAMETER_COUNT = 3; // CodForChk_Dis_Magic
|
|
214 |
|
|
215 |
/**
|
|
216 |
* Parser tag
|
|
217 |
*/
|
|
218 |
private static final String OST_TRACE_PARSER_TAG = "OstTrace"; //$NON-NLS-1$
|
|
219 |
|
|
220 |
/**
|
|
221 |
* OstTrace parser formats
|
|
222 |
*/
|
|
223 |
private final static String[] OST_TRACE_PARSER_FORMATS = { "0", //$NON-NLS-1$
|
|
224 |
"1", //$NON-NLS-1$
|
|
225 |
"Data", //$NON-NLS-1$
|
|
226 |
"Ext?", //$NON-NLS-1$
|
|
227 |
"FunctionEntry0", //$NON-NLS-1$
|
|
228 |
"FunctionEntry1", //$NON-NLS-1$
|
|
229 |
"FunctionEntryExt", //$NON-NLS-1$
|
|
230 |
"FunctionExit0", //$NON-NLS-1$
|
|
231 |
"FunctionExit1", //$NON-NLS-1$
|
|
232 |
"FunctionExitExt", //$NON-NLS-1$
|
|
233 |
"EventStart0", //$NON-NLS-1$
|
|
234 |
"EventStart1", //$NON-NLS-1$
|
|
235 |
"EventStop", //$NON-NLS-1$
|
|
236 |
"Def0", //$NON-NLS-1$
|
|
237 |
"Def1", //$NON-NLS-1$
|
|
238 |
"DefData", //$NON-NLS-1$
|
|
239 |
"DefExt?", //$NON-NLS-1$
|
|
240 |
"State0", //$NON-NLS-1$
|
|
241 |
"State1" //$NON-NLS-1$
|
|
242 |
};
|
|
243 |
|
|
244 |
/**
|
|
245 |
* Creates a new OstTrace parser rule
|
|
246 |
*/
|
|
247 |
public OstTraceParserRule() {
|
|
248 |
super(OST_TRACE_PARSER_TAG, OST_TRACE_PARSER_FORMATS);
|
|
249 |
}
|
|
250 |
|
|
251 |
/*
|
|
252 |
* (non-Javadoc)
|
|
253 |
*
|
|
254 |
* @see com.nokia.tracecompiler.engine.source.SourceParserRule#getName()
|
|
255 |
*/
|
|
256 |
@Override
|
|
257 |
public String getName() {
|
|
258 |
return OstTraceFormatRule.STORAGE_NAME;
|
|
259 |
}
|
|
260 |
|
|
261 |
/* (non-Javadoc)
|
|
262 |
* @see com.nokia.tracecompiler.engine.rules.SourceParserRuleBase#parseParameters(java.lang.String, java.util.List)
|
|
263 |
*/
|
|
264 |
@Override
|
|
265 |
public SourceParserResult parseParameters(String tag, List<String> list)
|
|
266 |
throws TraceCompilerException {
|
|
267 |
SourceParserResult result = new SourceParserResult();
|
|
268 |
TraceParameterIndexList indexList = getIndexList(tag);
|
|
269 |
if (list.size() >= indexList.minParamCount) {
|
|
270 |
// Name must exist
|
|
271 |
result.originalName = list.get(indexList.nameIndex);
|
|
272 |
result.convertedName = result.originalName;
|
|
273 |
// Text is optional
|
|
274 |
if (indexList.textIndex >= 0) {
|
|
275 |
result.traceText = trimTraceText(list.get(indexList.textIndex));
|
|
276 |
} else {
|
|
277 |
result.traceText = ""; //$NON-NLS-1$
|
|
278 |
}
|
|
279 |
// Group ID and preprocessor level are stored into the
|
|
280 |
// parser-specific data
|
|
281 |
result.parserData = new ArrayList<String>();
|
|
282 |
if (indexList.levelIndex >= 0) {
|
|
283 |
result.parserData.add(list.get(indexList.levelIndex));
|
|
284 |
}
|
|
285 |
if (indexList.groupIndex >= 0) {
|
|
286 |
result.parserData.add(list.get(indexList.groupIndex));
|
|
287 |
} else if (indexList.groupName != null) {
|
|
288 |
result.parserData.add(indexList.groupName);
|
|
289 |
}
|
|
290 |
|
|
291 |
// Extra parameters are converted to trace parameters
|
|
292 |
result.parameters = new ArrayList<String>();
|
|
293 |
for (int i = indexList.minParamCount; i < list.size(); i++) {
|
|
294 |
result.parameters.add(list.get(i));
|
|
295 |
}
|
|
296 |
} else {
|
|
297 |
throw new TraceCompilerException(
|
|
298 |
TraceCompilerErrorCode.NOT_ENOUGH_PARAMETERS);
|
|
299 |
}
|
|
300 |
return result;
|
|
301 |
}
|
|
302 |
|
|
303 |
/**
|
|
304 |
* Gets the parameter index list based on trace tag
|
|
305 |
*
|
|
306 |
* @param tag
|
|
307 |
* the trace tag
|
|
308 |
* @return the index list
|
|
309 |
*/
|
|
310 |
private TraceParameterIndexList getIndexList(String tag) {
|
|
311 |
TraceParameterIndexList indexes = new TraceParameterIndexList();
|
|
312 |
indexes.levelIndex = -1;
|
|
313 |
if (tag.indexOf(OstConstants.FUNCTION_ENTRY_TAG) > 0
|
|
314 |
|| tag.indexOf(OstConstants.FUNCTION_EXIT_TAG) > 0) {
|
|
315 |
indexes.minParamCount = 1; // Name is mandatory
|
|
316 |
indexes.textIndex = -1; // No trace text
|
|
317 |
indexes.nameIndex = 0; // Trace name at index 0
|
|
318 |
indexes.groupIndex = -1; // Group is fixed to TRACE_FLOW
|
|
319 |
indexes.groupName = FLOW_GROUP_NAME;
|
|
320 |
} else if (tag.indexOf(OstConstants.STATE_TRACE_TAG) > 0) {
|
|
321 |
indexes.minParamCount = 1; // Name is mandatory
|
|
322 |
indexes.textIndex = -1; // No trace text
|
|
323 |
indexes.nameIndex = 0; // Trace name at index 0
|
|
324 |
indexes.groupIndex = -1; // Group is fixed to TRACE_STATE
|
|
325 |
indexes.groupName = STATE_GROUP_NAME;
|
|
326 |
} else if (tag.indexOf(OstConstants.PERFORMANCE_EVENT_START_TAG) > 0) {
|
|
327 |
// Name and event name are mandatory
|
|
328 |
indexes.minParamCount = 2; // CodForChk_Dis_Magic
|
|
329 |
indexes.textIndex = 1; // Trace text at index 1
|
|
330 |
indexes.nameIndex = 0; // Trace name at index 0
|
|
331 |
indexes.groupIndex = -1; // Group is fixed to TRACE_PERFORMANCE
|
|
332 |
indexes.groupName = PERFORMANCE_GROUP_NAME;
|
|
333 |
} else if (tag.indexOf(OstConstants.PERFORMANCE_EVENT_STOP_TAG) > 0) {
|
|
334 |
// Name and event name are mandatory
|
|
335 |
indexes.minParamCount = 2; // CodForChk_Dis_Magic
|
|
336 |
indexes.textIndex = 1; // Trace text at index 1
|
|
337 |
indexes.nameIndex = 0; // Trace name at index 0
|
|
338 |
indexes.groupIndex = -1; // Group is fixed to TRACE_PERFORMANCE
|
|
339 |
indexes.groupName = PERFORMANCE_GROUP_NAME;
|
|
340 |
} else {
|
|
341 |
indexes.minParamCount = MIN_PARAMETER_COUNT;
|
|
342 |
indexes.textIndex = TRACE_TEXT_OFFSET;
|
|
343 |
indexes.nameIndex = TRACE_NAME_OFFSET;
|
|
344 |
indexes.groupIndex = GROUP_NAME_OFFSET;
|
|
345 |
}
|
|
346 |
// If the trace macro contains preprocessor level, the offsets are
|
|
347 |
// incremented by one
|
|
348 |
if (tag.indexOf(OstConstants.PREPROCESSOR_LEVEL_TAG) > 0) {
|
|
349 |
indexes.minParamCount++;
|
|
350 |
if (indexes.textIndex >= 0) {
|
|
351 |
indexes.textIndex++;
|
|
352 |
}
|
|
353 |
if (indexes.nameIndex >= 0) {
|
|
354 |
indexes.nameIndex++;
|
|
355 |
}
|
|
356 |
if (indexes.groupIndex >= 0) {
|
|
357 |
indexes.groupIndex++;
|
|
358 |
}
|
|
359 |
indexes.levelIndex = PREPROCESSOR_LEVEL_OFFSET;
|
|
360 |
}
|
|
361 |
return indexes;
|
|
362 |
}
|
|
363 |
|
|
364 |
/*
|
|
365 |
* (non-Javadoc)
|
|
366 |
*
|
|
367 |
* @see com.nokia.tracecompiler.engine.source.SourceParserRule#
|
|
368 |
* convertLocation(com.nokia.tracecompiler.engine.TraceLocation)
|
|
369 |
*/
|
|
370 |
@Override
|
|
371 |
public TraceConversionResult convertLocation(TraceLocation location)
|
|
372 |
throws TraceCompilerException { // CodForChk_Dis_ComplexFunc
|
|
373 |
TraceParameterFlagList flags = checkParameterCount(location);
|
|
374 |
|
|
375 |
// Data tag does not have parameters
|
|
376 |
boolean checkParameters = !flags.hasDataTag;
|
|
377 |
|
|
378 |
List<FormatMapping> typeList;
|
|
379 |
if (flags.hasExtTag
|
|
380 |
&& (flags.hasFunctionEntryTag || flags.hasFunctionExitTag)) {
|
|
381 |
// Parameters are generated by AutoAdd rules
|
|
382 |
typeList = new ArrayList<FormatMapping>();
|
|
383 |
checkParameters = false;
|
|
384 |
} else if (!flags.hasFlags() || flags.hasDataTag || flags.hasExtTag) {
|
|
385 |
// If the Ext, Data or EventStart tag is present, all formats
|
|
386 |
// are supported. If no flags is set, only 32-bit formats are
|
|
387 |
// supported.
|
|
388 |
typeList = buildParameterTypeList(location.getTraceText(),
|
|
389 |
!flags.hasDataTag && !flags.hasExtTag);
|
|
390 |
} else if (flags.hasEventStartTag) {
|
|
391 |
// In case of Start1 tag value parameter is supported
|
|
392 |
typeList = new ArrayList<FormatMapping>();
|
|
393 |
// Check that does optional value exist
|
|
394 |
if (location.getParameterCount() == 1) {
|
|
395 |
FormatMapping mapping = new FormatMapping(TraceParameter.SDEC32);
|
|
396 |
mapping.isSimple = true;
|
|
397 |
typeList.add(mapping);
|
|
398 |
}
|
|
399 |
checkParameters = false;
|
|
400 |
} else if (flags.hasEventStopTag) {
|
|
401 |
// If the Event stop tag is presented, start event trace
|
|
402 |
// id parameter is supported
|
|
403 |
typeList = new ArrayList<FormatMapping>();
|
|
404 |
FormatMapping mapping = new FormatMapping(TraceParameter.UDEC32);
|
|
405 |
mapping.isSimple = true;
|
|
406 |
typeList.add(mapping);
|
|
407 |
checkParameters = false;
|
|
408 |
|
|
409 |
} else if (flags.hasStateTag) {
|
|
410 |
// If the State tag is presented, two ascii parameters are supported
|
|
411 |
// in case of State0 tag (parameter count = 2). In case of State1
|
|
412 |
// tag (parameter count = 3) two ascii and one 32-bit hex parameters
|
|
413 |
// are supported
|
|
414 |
typeList = new ArrayList<FormatMapping>();
|
|
415 |
FormatMapping mapping = new FormatMapping(TraceParameter.ASCII);
|
|
416 |
mapping.isSimple = true;
|
|
417 |
typeList.add(mapping);
|
|
418 |
mapping = new FormatMapping(TraceParameter.ASCII);
|
|
419 |
mapping.isSimple = true;
|
|
420 |
typeList.add(mapping);
|
|
421 |
|
|
422 |
// Check that does optional instance identifier exist
|
|
423 |
if (location.getParameterCount() == 3) { // CodForChk_Dis_Magic
|
|
424 |
mapping = new FormatMapping(TraceParameter.HEX32);
|
|
425 |
mapping.isSimple = true;
|
|
426 |
typeList.add(mapping);
|
|
427 |
}
|
|
428 |
checkParameters = false;
|
|
429 |
} else {
|
|
430 |
// If some other flag than Data, State, Ext or EventStart is set,
|
|
431 |
// only one 32-bit hex parameter is supported
|
|
432 |
typeList = new ArrayList<FormatMapping>();
|
|
433 |
if (location.getParameterCount() == 1) {
|
|
434 |
FormatMapping mapping = new FormatMapping(TraceParameter.HEX32);
|
|
435 |
mapping.isSimple = true;
|
|
436 |
typeList.add(mapping);
|
|
437 |
}
|
|
438 |
}
|
|
439 |
// If no flags or Ext flag is present, the parameter count needs to be
|
|
440 |
// verified
|
|
441 |
TraceConversionResult result = super.convertLocation(location,
|
|
442 |
checkParameters, typeList);
|
|
443 |
// If the extension or state tag is present, zero parameters or a single
|
|
444 |
// 32-bit parameter is not accepted because they do not need to generate
|
|
445 |
// a function into the header
|
|
446 |
if (((flags.hasExtTag && !flags.hasFunctionExitTag && !flags.hasFunctionEntryTag) || (flags.hasStateTag))
|
|
447 |
&& (typeList.size() == 0 || (typeList.size() == 1 && typeList
|
|
448 |
.get(0).isSimple))) {
|
|
449 |
throw new TraceCompilerException(
|
|
450 |
TraceCompilerErrorCode.PARAMETER_FORMAT_UNNECESSARY_EXT_MACRO);
|
|
451 |
}
|
|
452 |
// Ext-macros are tagged with the complex header rule, so the header
|
|
453 |
// gets written when traces are exported. Data-macros are tagged with
|
|
454 |
// read-only rule, so they are not updated via UI. Other special cases
|
|
455 |
// are flagged with corresponding rule.
|
|
456 |
// If trace text does not exist, it is created based on context
|
|
457 |
AutomaticTraceTextRule rule = null;
|
|
458 |
if (flags.hasDataTag) {
|
|
459 |
addRule(result, new ReadOnlyObjectRuleImpl());
|
|
460 |
} else if (flags.hasStateTag) {
|
|
461 |
addRule(result, new StateTraceRule());
|
|
462 |
addRule(result, new ComplexHeaderRuleImpl());
|
|
463 |
} else if (flags.hasEventStartTag) {
|
|
464 |
addRule(result, new PerformanceEventStartRule());
|
|
465 |
// If event value is not defined then event value 1 is automatically
|
|
466 |
// added to event start macros
|
|
467 |
if (location.getParameterCount() == 0) {
|
|
468 |
addRule(result, new AutoAddValueRule());
|
|
469 |
}
|
|
470 |
} else if (flags.hasEventStopTag) {
|
|
471 |
addRule(result, new PerformanceEventStopRule());
|
|
472 |
addRule(result, new ComplexHeaderRuleImpl());
|
|
473 |
// Event value 0 is automatically added to event stop macros
|
|
474 |
addRule(result, new AutoAddValueRule());
|
|
475 |
} else if (flags.hasFunctionEntryTag) {
|
|
476 |
if (flags.hasExtTag) {
|
|
477 |
// Entry trace may contain Ext tag. In that case the trace
|
|
478 |
// parameters are an instance variable and function parameters
|
|
479 |
// parsed from source. It is also flagged as complex, so the
|
|
480 |
// function gets generated to the trace header
|
|
481 |
addRule(result, new ComplexHeaderRuleImpl());
|
|
482 |
addRule(result, new AutoAddFunctionParametersRule());
|
|
483 |
addRule(result, new AutoAddThisPtrRule());
|
|
484 |
}
|
|
485 |
rule = new EntryTraceRule();
|
|
486 |
addRule(result, rule);
|
|
487 |
} else if (flags.hasFunctionExitTag) {
|
|
488 |
if (flags.hasExtTag) {
|
|
489 |
// Exit trace may contain Ext tag. In that case the trace has
|
|
490 |
// two parameters: instance variable and return statement
|
|
491 |
// It is also flagged as complex, so the function gets generated
|
|
492 |
// to the trace header
|
|
493 |
addRule(result, new ComplexHeaderRuleImpl());
|
|
494 |
addRule(result, new AutoAddThisPtrRule());
|
|
495 |
addRule(result, new AutoAddReturnParameterRule());
|
|
496 |
}
|
|
497 |
rule = new ExitTraceRule();
|
|
498 |
addRule(result, rule);
|
|
499 |
} else if (flags.hasExtTag) {
|
|
500 |
addRule(result, new ComplexHeaderRuleImpl());
|
|
501 |
}
|
|
502 |
if (rule != null) {
|
|
503 |
setAutoTextToTrace(location, result, rule);
|
|
504 |
}
|
|
505 |
List<String> parserData = location.getParserData();
|
|
506 |
result.group = parserData.get(parserData.size() - 1);
|
|
507 |
// The convert flag is reset to prevent further conversions
|
|
508 |
location.locationConverted();
|
|
509 |
return result;
|
|
510 |
}
|
|
511 |
|
|
512 |
/**
|
|
513 |
* Uses the auto-text rule to create trace text
|
|
514 |
*
|
|
515 |
* @param location
|
|
516 |
* the location
|
|
517 |
* @param result
|
|
518 |
* the conversion result
|
|
519 |
* @param rule
|
|
520 |
* the auto-text rule
|
|
521 |
* @throws TraceCompilerException
|
|
522 |
* if update fails
|
|
523 |
*/
|
|
524 |
private void setAutoTextToTrace(TraceLocation location,
|
|
525 |
TraceConversionResult result, AutomaticTraceTextRule rule)
|
|
526 |
throws TraceCompilerException {
|
|
527 |
// The trace text comes from the auto-text rule
|
|
528 |
SourceParser parser = location.getParser();
|
|
529 |
SourceContext context = parser.getContext(location.getOffset());
|
|
530 |
if (context != null) {
|
|
531 |
result.text = rule.formatTrace(context);
|
|
532 |
} else {
|
|
533 |
throw new TraceCompilerException(
|
|
534 |
TraceCompilerErrorCode.NO_CONTEXT_FOR_LOCATION);
|
|
535 |
}
|
|
536 |
}
|
|
537 |
|
|
538 |
/**
|
|
539 |
* Checks parameter count
|
|
540 |
*
|
|
541 |
* @param location
|
|
542 |
* the location
|
|
543 |
* @return the location tag flags
|
|
544 |
* @throws TraceCompilerException
|
|
545 |
* if parameter count is not valid
|
|
546 |
*/
|
|
547 |
private TraceParameterFlagList checkParameterCount(TraceLocation location)
|
|
548 |
throws TraceCompilerException {
|
|
549 |
TraceParameterFlagList flags = new TraceParameterFlagList(location
|
|
550 |
.getTag());
|
|
551 |
|
|
552 |
// If the trace has some tag, the parameter count is fixed
|
|
553 |
// Data has 2 parameters
|
|
554 |
// State has 2 or 3 parameters
|
|
555 |
// Function entry-exit has 0 or 1 parameters
|
|
556 |
// Event start has 0 or 1 parameters
|
|
557 |
// Event stop has 1 parameters
|
|
558 |
int parameterCount = location.getParameterCount();
|
|
559 |
|
|
560 |
// Entry trace may have zero or one parameter
|
|
561 |
// In case of Ext, it must have one parameter
|
|
562 |
if (flags.hasFunctionEntryTag
|
|
563 |
&& ((parameterCount > 1) || (flags.hasExtTag && (parameterCount != ENTRY_EXT_PARAMETER_COUNT)))) {
|
|
564 |
throw new TraceCompilerException(
|
|
565 |
TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
|
|
566 |
}
|
|
567 |
|
|
568 |
// Exit trace may have zero or one parameter
|
|
569 |
// In case of Ext, it must have two parameters
|
|
570 |
if (flags.hasFunctionExitTag
|
|
571 |
&& ((!flags.hasExtTag && (parameterCount > 1)) || (flags.hasExtTag && parameterCount != EXIT_EXT_PARAMETER_COUNT))) { // CodForChk_Dis_LengthyLine
|
|
572 |
throw new TraceCompilerException(
|
|
573 |
TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
|
|
574 |
}
|
|
575 |
|
|
576 |
// Event start may have zero or one parameter
|
|
577 |
if (flags.hasEventStartTag && (parameterCount > 1)) {
|
|
578 |
throw new TraceCompilerException(
|
|
579 |
TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
|
|
580 |
}
|
|
581 |
|
|
582 |
// Event stop have one parameters
|
|
583 |
if (flags.hasEventStopTag && (parameterCount != 1)) {
|
|
584 |
throw new TraceCompilerException(
|
|
585 |
TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
|
|
586 |
}
|
|
587 |
|
|
588 |
// Data trace has two parameters
|
|
589 |
if ((flags.hasDataTag && (parameterCount != DATA_PARAMETER_COUNT))) {
|
|
590 |
throw new TraceCompilerException(
|
|
591 |
TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
|
|
592 |
}
|
|
593 |
|
|
594 |
// State trace may have two or three parameter
|
|
595 |
if (flags.hasStateTag && (parameterCount < 2 || parameterCount > 3)) { // CodForChk_Dis_Magic
|
|
596 |
throw new TraceCompilerException(
|
|
597 |
TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
|
|
598 |
}
|
|
599 |
|
|
600 |
return flags;
|
|
601 |
}
|
|
602 |
|
|
603 |
/**
|
|
604 |
* Adds a rule to result
|
|
605 |
*
|
|
606 |
* @param result
|
|
607 |
* the result
|
|
608 |
* @param rule
|
|
609 |
* the rule
|
|
610 |
*/
|
|
611 |
private void addRule(TraceConversionResult result, TraceModelExtension rule) {
|
|
612 |
if (result.extensions == null) {
|
|
613 |
result.extensions = new ArrayList<TraceModelExtension>();
|
|
614 |
}
|
|
615 |
result.extensions.add(rule);
|
|
616 |
}
|
|
617 |
|
|
618 |
/*
|
|
619 |
* (non-Javadoc)
|
|
620 |
*
|
|
621 |
* @see com.nokia.tracecompiler.engine.rules.SourceParserRuleBase#
|
|
622 |
* isLocationConverted(com.nokia.tracecompiler.engine.TraceLocation)
|
|
623 |
*/
|
|
624 |
@Override
|
|
625 |
public boolean isLocationConverted(TraceLocation location) {
|
|
626 |
boolean retval = location.hasChangedAfterConvert();
|
|
627 |
if (!retval) {
|
|
628 |
// Duplicate-location conversions need to be retried in case the
|
|
629 |
// location is no longer a duplicate
|
|
630 |
retval = (location.getValidityCode() == TraceCompilerErrorCode.TRACE_HAS_MULTIPLE_LOCATIONS);
|
|
631 |
}
|
|
632 |
return retval;
|
|
633 |
}
|
|
634 |
|
|
635 |
/*
|
|
636 |
* (non-Javadoc)
|
|
637 |
*
|
|
638 |
* @seecom.nokia.tracecompiler.engine.rules.printf.PrintfTraceParserRule#
|
|
639 |
* getLocationGroup()
|
|
640 |
*/
|
|
641 |
@Override
|
|
642 |
public String getLocationGroup() {
|
|
643 |
return null;
|
|
644 |
}
|
|
645 |
}
|