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 } |
|