diff -r a151135b0cf9 -r aa2539c91954 tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/rules/osttrace/OstTraceParserRule.java --- 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 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(); - 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(); - 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 typeList; - if (flags.hasExtTag - && (flags.hasFunctionEntryTag || flags.hasFunctionExitTag)) { - // Parameters are generated by AutoAdd rules - typeList = new ArrayList(); - 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(); - // 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 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 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(); - 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 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(); - } - 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; - } -}