--- a/tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/rules/osttrace/OstTraceParserRule.java Wed Sep 29 17:45:35 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,645 +0,0 @@
-/*
- * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
- * All rights reserved.
- * This component and the accompanying materials are made available
- * under the terms of "Eclipse Public License v1.0"
- * which accompanies this distribution, and is available
- * at the URL "http://www.eclipse.org/legal/epl-v10.html".
- *
- * Initial Contributors:
- * Nokia Corporation - initial contribution.
- *
- * Contributors:
- *
- * Description:
- *
- * OST trace parser rule
- *
- */
-package com.nokia.tracecompiler.engine.rules.osttrace;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.nokia.tracecompiler.engine.TraceLocation;
-import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode;
-import com.nokia.tracecompiler.engine.rules.AutoAddFunctionParametersRule;
-import com.nokia.tracecompiler.engine.rules.AutoAddReturnParameterRule;
-import com.nokia.tracecompiler.engine.rules.AutoAddThisPtrRule;
-import com.nokia.tracecompiler.engine.rules.AutoAddValueRule;
-import com.nokia.tracecompiler.engine.rules.AutomaticTraceTextRule;
-import com.nokia.tracecompiler.engine.rules.ComplexHeaderRuleImpl;
-import com.nokia.tracecompiler.engine.rules.EntryTraceRule;
-import com.nokia.tracecompiler.engine.rules.ExitTraceRule;
-import com.nokia.tracecompiler.engine.rules.PerformanceEventStartRule;
-import com.nokia.tracecompiler.engine.rules.PerformanceEventStopRule;
-import com.nokia.tracecompiler.engine.rules.ReadOnlyObjectRuleImpl;
-import com.nokia.tracecompiler.engine.rules.SourceParserRuleBase;
-import com.nokia.tracecompiler.engine.rules.StateTraceRule;
-import com.nokia.tracecompiler.engine.source.SourceParserResult;
-import com.nokia.tracecompiler.model.TraceCompilerException;
-import com.nokia.tracecompiler.model.TraceModelExtension;
-import com.nokia.tracecompiler.model.TraceParameter;
-import com.nokia.tracecompiler.source.FormatMapping;
-import com.nokia.tracecompiler.source.SourceContext;
-import com.nokia.tracecompiler.source.SourceParser;
-
-/**
- * OST trace parser rule
- *
- */
-public final class OstTraceParserRule extends SourceParserRuleBase {
-
- /**
- * PERFORMANCE group name
- */
- private static final String PERFORMANCE_GROUP_NAME = "TRACE_PERFORMANCE"; //$NON-NLS-1$
-
- /**
- * STATE group name
- */
- private static final String STATE_GROUP_NAME = "TRACE_STATE"; //$NON-NLS-1$
-
- /**
- * FLOW group name
- */
- private static final String FLOW_GROUP_NAME = "TRACE_FLOW"; //$NON-NLS-1$
-
- /**
- * Data trace parameter count
- */
- private static final int DATA_PARAMETER_COUNT = 2; // CodForChk_Dis_Magic
-
- /**
- * Entry Ext trace parameter count
- */
- private static final int ENTRY_EXT_PARAMETER_COUNT = 1; // CodForChk_Dis_Magic
-
- /**
- * Exit Ext trace parameter count
- */
- private static final int EXIT_EXT_PARAMETER_COUNT = 2; // CodForChk_Dis_Magic
-
- /**
- * Trace parameter index list
- */
- class TraceParameterIndexList {
-
- /**
- * Minimum number of parameters needed to decode traces
- */
- int minParamCount;
-
- /**
- * Preprocessor level index
- */
- int levelIndex;
-
- /**
- * Trace name index
- */
- int nameIndex;
-
- /**
- * Trace text index
- */
- int textIndex;
-
- /**
- * Trace group index in case group name is free-form
- */
- int groupIndex;
-
- /**
- * Trace group name in case group name is pre-determined by rules
- */
- String groupName;
- }
-
- /**
- * List of flags related to OST API macro
- */
- class TraceParameterFlagList {
-
- /**
- * Data tag
- */
- boolean hasDataTag;
-
- /**
- * State tag
- */
- boolean hasStateTag;
-
- /**
- * Ext tag
- */
- boolean hasExtTag;
-
- /**
- * Event start tag
- */
- boolean hasEventStartTag;
-
- /**
- * Event stop
- */
- boolean hasEventStopTag;
-
- /**
- * Function entry
- */
- boolean hasFunctionEntryTag;
-
- /**
- * Function exit
- */
- boolean hasFunctionExitTag;
-
- /**
- * Constructor
- *
- * @param tag
- * the trace tag
- */
- TraceParameterFlagList(String tag) {
- hasDataTag = tag.indexOf(OstConstants.DATA_TRACE_TAG) > 0;
- hasStateTag = tag.indexOf(OstConstants.STATE_TRACE_TAG) > 0;
- hasExtTag = tag.indexOf(OstConstants.EXTENSION_TRACE_TAG) > 0;
- hasEventStartTag = tag
- .indexOf(OstConstants.PERFORMANCE_EVENT_START_TAG) > 0;
- hasEventStopTag = tag
- .indexOf(OstConstants.PERFORMANCE_EVENT_STOP_TAG) > 0;
- hasFunctionEntryTag = tag.indexOf(OstConstants.FUNCTION_ENTRY_TAG) > 0;
- hasFunctionExitTag = tag.indexOf(OstConstants.FUNCTION_EXIT_TAG) > 0;
- }
-
- /**
- * Checks if any of the flags is set
- *
- * @return true if flag is set
- */
- boolean hasFlags() {
- return hasDataTag || hasStateTag || hasExtTag || hasEventStartTag
- || hasEventStopTag || hasFunctionEntryTag
- || hasFunctionExitTag;
- }
-
- }
-
- /**
- * Offset to preprocessor level
- */
- private static final int PREPROCESSOR_LEVEL_OFFSET = 0; // CodForChk_Dis_Magic
-
- /**
- * Offset to group name if preprocessor level is not in use
- */
- private static final int GROUP_NAME_OFFSET = 0; // CodForChk_Dis_Magic
-
- /**
- * Offset to trace name if preprocessor level is not in use
- */
- private static final int TRACE_NAME_OFFSET = 1; // CodForChk_Dis_Magic
-
- /**
- * Offset to trace text if preprocessor level is not in use
- */
- private static final int TRACE_TEXT_OFFSET = 2; // CodForChk_Dis_Magic
-
- /**
- * Minimum number of parameters if preprocessor level is not in use
- */
- private static final int MIN_PARAMETER_COUNT = 3; // CodForChk_Dis_Magic
-
- /**
- * Parser tag
- */
- private static final String OST_TRACE_PARSER_TAG = "OstTrace"; //$NON-NLS-1$
-
- /**
- * OstTrace parser formats
- */
- private final static String[] OST_TRACE_PARSER_FORMATS = { "0", //$NON-NLS-1$
- "1", //$NON-NLS-1$
- "Data", //$NON-NLS-1$
- "Ext?", //$NON-NLS-1$
- "FunctionEntry0", //$NON-NLS-1$
- "FunctionEntry1", //$NON-NLS-1$
- "FunctionEntryExt", //$NON-NLS-1$
- "FunctionExit0", //$NON-NLS-1$
- "FunctionExit1", //$NON-NLS-1$
- "FunctionExitExt", //$NON-NLS-1$
- "EventStart0", //$NON-NLS-1$
- "EventStart1", //$NON-NLS-1$
- "EventStop", //$NON-NLS-1$
- "Def0", //$NON-NLS-1$
- "Def1", //$NON-NLS-1$
- "DefData", //$NON-NLS-1$
- "DefExt?", //$NON-NLS-1$
- "State0", //$NON-NLS-1$
- "State1" //$NON-NLS-1$
- };
-
- /**
- * Creates a new OstTrace parser rule
- */
- public OstTraceParserRule() {
- super(OST_TRACE_PARSER_TAG, OST_TRACE_PARSER_FORMATS);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.nokia.tracecompiler.engine.source.SourceParserRule#getName()
- */
- @Override
- public String getName() {
- return OstTraceFormatRule.STORAGE_NAME;
- }
-
- /* (non-Javadoc)
- * @see com.nokia.tracecompiler.engine.rules.SourceParserRuleBase#parseParameters(java.lang.String, java.util.List)
- */
- @Override
- public SourceParserResult parseParameters(String tag, List<String> list)
- throws TraceCompilerException {
- SourceParserResult result = new SourceParserResult();
- TraceParameterIndexList indexList = getIndexList(tag);
- if (list.size() >= indexList.minParamCount) {
- // Name must exist
- result.originalName = list.get(indexList.nameIndex);
- result.convertedName = result.originalName;
- // Text is optional
- if (indexList.textIndex >= 0) {
- result.traceText = trimTraceText(list.get(indexList.textIndex));
- } else {
- result.traceText = ""; //$NON-NLS-1$
- }
- // Group ID and preprocessor level are stored into the
- // parser-specific data
- result.parserData = new ArrayList<String>();
- if (indexList.levelIndex >= 0) {
- result.parserData.add(list.get(indexList.levelIndex));
- }
- if (indexList.groupIndex >= 0) {
- result.parserData.add(list.get(indexList.groupIndex));
- } else if (indexList.groupName != null) {
- result.parserData.add(indexList.groupName);
- }
-
- // Extra parameters are converted to trace parameters
- result.parameters = new ArrayList<String>();
- for (int i = indexList.minParamCount; i < list.size(); i++) {
- result.parameters.add(list.get(i));
- }
- } else {
- throw new TraceCompilerException(
- TraceCompilerErrorCode.NOT_ENOUGH_PARAMETERS);
- }
- return result;
- }
-
- /**
- * Gets the parameter index list based on trace tag
- *
- * @param tag
- * the trace tag
- * @return the index list
- */
- private TraceParameterIndexList getIndexList(String tag) {
- TraceParameterIndexList indexes = new TraceParameterIndexList();
- indexes.levelIndex = -1;
- if (tag.indexOf(OstConstants.FUNCTION_ENTRY_TAG) > 0
- || tag.indexOf(OstConstants.FUNCTION_EXIT_TAG) > 0) {
- indexes.minParamCount = 1; // Name is mandatory
- indexes.textIndex = -1; // No trace text
- indexes.nameIndex = 0; // Trace name at index 0
- indexes.groupIndex = -1; // Group is fixed to TRACE_FLOW
- indexes.groupName = FLOW_GROUP_NAME;
- } else if (tag.indexOf(OstConstants.STATE_TRACE_TAG) > 0) {
- indexes.minParamCount = 1; // Name is mandatory
- indexes.textIndex = -1; // No trace text
- indexes.nameIndex = 0; // Trace name at index 0
- indexes.groupIndex = -1; // Group is fixed to TRACE_STATE
- indexes.groupName = STATE_GROUP_NAME;
- } else if (tag.indexOf(OstConstants.PERFORMANCE_EVENT_START_TAG) > 0) {
- // Name and event name are mandatory
- indexes.minParamCount = 2; // CodForChk_Dis_Magic
- indexes.textIndex = 1; // Trace text at index 1
- indexes.nameIndex = 0; // Trace name at index 0
- indexes.groupIndex = -1; // Group is fixed to TRACE_PERFORMANCE
- indexes.groupName = PERFORMANCE_GROUP_NAME;
- } else if (tag.indexOf(OstConstants.PERFORMANCE_EVENT_STOP_TAG) > 0) {
- // Name and event name are mandatory
- indexes.minParamCount = 2; // CodForChk_Dis_Magic
- indexes.textIndex = 1; // Trace text at index 1
- indexes.nameIndex = 0; // Trace name at index 0
- indexes.groupIndex = -1; // Group is fixed to TRACE_PERFORMANCE
- indexes.groupName = PERFORMANCE_GROUP_NAME;
- } else {
- indexes.minParamCount = MIN_PARAMETER_COUNT;
- indexes.textIndex = TRACE_TEXT_OFFSET;
- indexes.nameIndex = TRACE_NAME_OFFSET;
- indexes.groupIndex = GROUP_NAME_OFFSET;
- }
- // If the trace macro contains preprocessor level, the offsets are
- // incremented by one
- if (tag.indexOf(OstConstants.PREPROCESSOR_LEVEL_TAG) > 0) {
- indexes.minParamCount++;
- if (indexes.textIndex >= 0) {
- indexes.textIndex++;
- }
- if (indexes.nameIndex >= 0) {
- indexes.nameIndex++;
- }
- if (indexes.groupIndex >= 0) {
- indexes.groupIndex++;
- }
- indexes.levelIndex = PREPROCESSOR_LEVEL_OFFSET;
- }
- return indexes;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.nokia.tracecompiler.engine.source.SourceParserRule#
- * convertLocation(com.nokia.tracecompiler.engine.TraceLocation)
- */
- @Override
- public TraceConversionResult convertLocation(TraceLocation location)
- throws TraceCompilerException { // CodForChk_Dis_ComplexFunc
- TraceParameterFlagList flags = checkParameterCount(location);
-
- // Data tag does not have parameters
- boolean checkParameters = !flags.hasDataTag;
-
- List<FormatMapping> typeList;
- if (flags.hasExtTag
- && (flags.hasFunctionEntryTag || flags.hasFunctionExitTag)) {
- // Parameters are generated by AutoAdd rules
- typeList = new ArrayList<FormatMapping>();
- checkParameters = false;
- } else if (!flags.hasFlags() || flags.hasDataTag || flags.hasExtTag) {
- // If the Ext, Data or EventStart tag is present, all formats
- // are supported. If no flags is set, only 32-bit formats are
- // supported.
- typeList = buildParameterTypeList(location.getTraceText(),
- !flags.hasDataTag && !flags.hasExtTag);
- } else if (flags.hasEventStartTag) {
- // In case of Start1 tag value parameter is supported
- typeList = new ArrayList<FormatMapping>();
- // Check that does optional value exist
- if (location.getParameterCount() == 1) {
- FormatMapping mapping = new FormatMapping(TraceParameter.SDEC32);
- mapping.isSimple = true;
- typeList.add(mapping);
- }
- checkParameters = false;
- } else if (flags.hasEventStopTag) {
- // If the Event stop tag is presented, start event trace
- // id parameter is supported
- typeList = new ArrayList<FormatMapping>();
- FormatMapping mapping = new FormatMapping(TraceParameter.UDEC32);
- mapping.isSimple = true;
- typeList.add(mapping);
- checkParameters = false;
-
- } else if (flags.hasStateTag) {
- // If the State tag is presented, two ascii parameters are supported
- // in case of State0 tag (parameter count = 2). In case of State1
- // tag (parameter count = 3) two ascii and one 32-bit hex parameters
- // are supported
- typeList = new ArrayList<FormatMapping>();
- FormatMapping mapping = new FormatMapping(TraceParameter.ASCII);
- mapping.isSimple = true;
- typeList.add(mapping);
- mapping = new FormatMapping(TraceParameter.ASCII);
- mapping.isSimple = true;
- typeList.add(mapping);
-
- // Check that does optional instance identifier exist
- if (location.getParameterCount() == 3) { // CodForChk_Dis_Magic
- mapping = new FormatMapping(TraceParameter.HEX32);
- mapping.isSimple = true;
- typeList.add(mapping);
- }
- checkParameters = false;
- } else {
- // If some other flag than Data, State, Ext or EventStart is set,
- // only one 32-bit hex parameter is supported
- typeList = new ArrayList<FormatMapping>();
- if (location.getParameterCount() == 1) {
- FormatMapping mapping = new FormatMapping(TraceParameter.HEX32);
- mapping.isSimple = true;
- typeList.add(mapping);
- }
- }
- // If no flags or Ext flag is present, the parameter count needs to be
- // verified
- TraceConversionResult result = super.convertLocation(location,
- checkParameters, typeList);
- // If the extension or state tag is present, zero parameters or a single
- // 32-bit parameter is not accepted because they do not need to generate
- // a function into the header
- if (((flags.hasExtTag && !flags.hasFunctionExitTag && !flags.hasFunctionEntryTag) || (flags.hasStateTag))
- && (typeList.size() == 0 || (typeList.size() == 1 && typeList
- .get(0).isSimple))) {
- throw new TraceCompilerException(
- TraceCompilerErrorCode.PARAMETER_FORMAT_UNNECESSARY_EXT_MACRO);
- }
- // Ext-macros are tagged with the complex header rule, so the header
- // gets written when traces are exported. Data-macros are tagged with
- // read-only rule, so they are not updated via UI. Other special cases
- // are flagged with corresponding rule.
- // If trace text does not exist, it is created based on context
- AutomaticTraceTextRule rule = null;
- if (flags.hasDataTag) {
- addRule(result, new ReadOnlyObjectRuleImpl());
- } else if (flags.hasStateTag) {
- addRule(result, new StateTraceRule());
- addRule(result, new ComplexHeaderRuleImpl());
- } else if (flags.hasEventStartTag) {
- addRule(result, new PerformanceEventStartRule());
- // If event value is not defined then event value 1 is automatically
- // added to event start macros
- if (location.getParameterCount() == 0) {
- addRule(result, new AutoAddValueRule());
- }
- } else if (flags.hasEventStopTag) {
- addRule(result, new PerformanceEventStopRule());
- addRule(result, new ComplexHeaderRuleImpl());
- // Event value 0 is automatically added to event stop macros
- addRule(result, new AutoAddValueRule());
- } else if (flags.hasFunctionEntryTag) {
- if (flags.hasExtTag) {
- // Entry trace may contain Ext tag. In that case the trace
- // parameters are an instance variable and function parameters
- // parsed from source. It is also flagged as complex, so the
- // function gets generated to the trace header
- addRule(result, new ComplexHeaderRuleImpl());
- addRule(result, new AutoAddFunctionParametersRule());
- addRule(result, new AutoAddThisPtrRule());
- }
- rule = new EntryTraceRule();
- addRule(result, rule);
- } else if (flags.hasFunctionExitTag) {
- if (flags.hasExtTag) {
- // Exit trace may contain Ext tag. In that case the trace has
- // two parameters: instance variable and return statement
- // It is also flagged as complex, so the function gets generated
- // to the trace header
- addRule(result, new ComplexHeaderRuleImpl());
- addRule(result, new AutoAddThisPtrRule());
- addRule(result, new AutoAddReturnParameterRule());
- }
- rule = new ExitTraceRule();
- addRule(result, rule);
- } else if (flags.hasExtTag) {
- addRule(result, new ComplexHeaderRuleImpl());
- }
- if (rule != null) {
- setAutoTextToTrace(location, result, rule);
- }
- List<String> parserData = location.getParserData();
- result.group = parserData.get(parserData.size() - 1);
- // The convert flag is reset to prevent further conversions
- location.locationConverted();
- return result;
- }
-
- /**
- * Uses the auto-text rule to create trace text
- *
- * @param location
- * the location
- * @param result
- * the conversion result
- * @param rule
- * the auto-text rule
- * @throws TraceCompilerException
- * if update fails
- */
- private void setAutoTextToTrace(TraceLocation location,
- TraceConversionResult result, AutomaticTraceTextRule rule)
- throws TraceCompilerException {
- // The trace text comes from the auto-text rule
- SourceParser parser = location.getParser();
- SourceContext context = parser.getContext(location.getOffset());
- if (context != null) {
- result.text = rule.formatTrace(context);
- } else {
- throw new TraceCompilerException(
- TraceCompilerErrorCode.NO_CONTEXT_FOR_LOCATION);
- }
- }
-
- /**
- * Checks parameter count
- *
- * @param location
- * the location
- * @return the location tag flags
- * @throws TraceCompilerException
- * if parameter count is not valid
- */
- private TraceParameterFlagList checkParameterCount(TraceLocation location)
- throws TraceCompilerException {
- TraceParameterFlagList flags = new TraceParameterFlagList(location
- .getTag());
-
- // If the trace has some tag, the parameter count is fixed
- // Data has 2 parameters
- // State has 2 or 3 parameters
- // Function entry-exit has 0 or 1 parameters
- // Event start has 0 or 1 parameters
- // Event stop has 1 parameters
- int parameterCount = location.getParameterCount();
-
- // Entry trace may have zero or one parameter
- // In case of Ext, it must have one parameter
- if (flags.hasFunctionEntryTag
- && ((parameterCount > 1) || (flags.hasExtTag && (parameterCount != ENTRY_EXT_PARAMETER_COUNT)))) {
- throw new TraceCompilerException(
- TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
- }
-
- // Exit trace may have zero or one parameter
- // In case of Ext, it must have two parameters
- if (flags.hasFunctionExitTag
- && ((!flags.hasExtTag && (parameterCount > 1)) || (flags.hasExtTag && parameterCount != EXIT_EXT_PARAMETER_COUNT))) { // CodForChk_Dis_LengthyLine
- throw new TraceCompilerException(
- TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
- }
-
- // Event start may have zero or one parameter
- if (flags.hasEventStartTag && (parameterCount > 1)) {
- throw new TraceCompilerException(
- TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
- }
-
- // Event stop have one parameters
- if (flags.hasEventStopTag && (parameterCount != 1)) {
- throw new TraceCompilerException(
- TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
- }
-
- // Data trace has two parameters
- if ((flags.hasDataTag && (parameterCount != DATA_PARAMETER_COUNT))) {
- throw new TraceCompilerException(
- TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
- }
-
- // State trace may have two or three parameter
- if (flags.hasStateTag && (parameterCount < 2 || parameterCount > 3)) { // CodForChk_Dis_Magic
- throw new TraceCompilerException(
- TraceCompilerErrorCode.PARAMETER_COUNT_DOES_NOT_MATCH_API);
- }
-
- return flags;
- }
-
- /**
- * Adds a rule to result
- *
- * @param result
- * the result
- * @param rule
- * the rule
- */
- private void addRule(TraceConversionResult result, TraceModelExtension rule) {
- if (result.extensions == null) {
- result.extensions = new ArrayList<TraceModelExtension>();
- }
- result.extensions.add(rule);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.nokia.tracecompiler.engine.rules.SourceParserRuleBase#
- * isLocationConverted(com.nokia.tracecompiler.engine.TraceLocation)
- */
- @Override
- public boolean isLocationConverted(TraceLocation location) {
- boolean retval = location.hasChangedAfterConvert();
- if (!retval) {
- // Duplicate-location conversions need to be retried in case the
- // location is no longer a duplicate
- retval = (location.getValidityCode() == TraceCompilerErrorCode.TRACE_HAS_MULTIPLE_LOCATIONS);
- }
- return retval;
- }
-
- /*
- * (non-Javadoc)
- *
- * @seecom.nokia.tracecompiler.engine.rules.printf.PrintfTraceParserRule#
- * getLocationGroup()
- */
- @Override
- public String getLocationGroup() {
- return null;
- }
-}