diff -r 14dc2103a631 -r ed1c9f64298a trace/tracebuilder/com.nokia.tracebuilder/src/com/nokia/tracebuilder/source/PreprocessorDefinitionParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trace/tracebuilder/com.nokia.tracebuilder/src/com/nokia/tracebuilder/source/PreprocessorDefinitionParser.java Wed Jun 23 14:35:40 2010 +0300 @@ -0,0 +1,278 @@ +/* +* Copyright (c) 2008 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: +* +* Parser for preprocessor definitions and include statements +* +*/ +package com.nokia.tracebuilder.source; + +import java.util.ArrayList; +import java.util.Iterator; + +/** + * Parser for preprocessor definitions and include statements + * + */ +class PreprocessorDefinitionParser { + + /** + * Source parser + */ + private SourceParser parser; + + /** + * List of #define's found from source + */ + protected ArrayList preprocessorDefinitions; + + /** + * List of #include's found from source + */ + protected ArrayList includes; + + /** + * Constructor + * + * @param parser + * the source parser + */ + PreprocessorDefinitionParser(SourceParser parser) { + this.parser = parser; + } + + /** + * Resets all definitions parsed from the source + */ + void reset() { + if (preprocessorDefinitions != null) { + preprocessorDefinitions.clear(); + } + if (includes != null) { + includes.clear(); + } + } + + /** + * Locates the value of a preprocessor definition for given name. + * + * @param name + * the name of the definition + * @return the value or null if not found + * @throws SourceParserException + * if parser fails + */ + String findDefine(String name) throws SourceParserException { + if (preprocessorDefinitions == null + || preprocessorDefinitions.isEmpty()) { + createDefines(); + } + Iterator itr = preprocessorDefinitions + .iterator(); + String retval = null; + while (itr.hasNext() && retval == null) { + SourcePreprocessorDefinition def = itr.next(); + if (def.getName().equals(name)) { + retval = def.getValue(); + } + } + return retval; + } + + /** + * Finds an include definition with given name + * + * @param name + * the include file name + * @return + *
    + *
  • if found, index to start of #include + *
  • if not, -1 - index to end of last #include + *
+ * @throws SourceParserException + * if parser fails + */ + int findInclude(String name) throws SourceParserException { + + createIncludes(); + + Iterator itr = includes.iterator(); + int ret = -1; + while (itr.hasNext()) { + SourceInclude inc = itr.next(); + if (inc.getHeaderName().equalsIgnoreCase(name)) { + ret = inc.getOffset(); + } + } + if (ret == -1 && includes.size() > 0) { + SourceInclude inc = includes.get(includes.size() - 1); + ret = -1 - (inc.getOffset() + inc.getLength()); + } + return ret; + } + + /** + * Creates the list of preprocessor definitions. This only works with simple + * values + * + * @throws SourceParserException + * if parser fails + */ + private void createDefines() throws SourceParserException { + if (preprocessorDefinitions == null) { + preprocessorDefinitions = new ArrayList(); + } else { + preprocessorDefinitions.clear(); + } + Iterator excludedAreas = parser.getExcludedAreas() + .iterator(); + while (excludedAreas.hasNext()) { + createDefineFromExcludedArea(excludedAreas.next()); + } + } + + /** + * Creates the list of include definitions + * + * @throws SourceParserException + * if parser fails + */ + private void createIncludes() throws SourceParserException { + if (includes == null) { + includes = new ArrayList(); + } else { + includes.clear(); + } + Iterator excludedAreas = parser.getExcludedAreas() + .iterator(); + while (excludedAreas.hasNext()) { + createIncludeFromExcludedArea(excludedAreas.next()); + } + } + + /** + * Creates an #define definition from given excluded area + * + * @param area + * the area + * @throws SourceParserException + */ + private void createDefineFromExcludedArea(SourceExcludedArea area) + throws SourceParserException { + if (area.getType() == SourceExcludedArea.PREPROCESSOR_DEFINITION + && area.getLength() > SourceConstants.DEFINE.length()) { + String tag = parser.getSource().get(area.getOffset(), + SourceConstants.DEFINE.length()); + if (tag.equals(SourceConstants.DEFINE)) { + // Cannot use SKIP_ALL here, since it contains SKIP_PREPROCESSOR + SourceIterator itr = parser.createIterator(area.getOffset() + + SourceConstants.DEFINE.length(), + SourceParser.SKIP_WHITE_SPACES + | SourceParser.SKIP_COMMENTS); + if (itr.hasNext()) { + parsePreprocessorDefinition(itr); + } + } + } + } + + /** + * Creates an #include definition from given excluded area + * + * @param area + * the area + * @throws SourceParserException + * if parser fails + */ + private void createIncludeFromExcludedArea(SourceExcludedArea area) + throws SourceParserException { + if (area.getType() == SourceExcludedArea.PREPROCESSOR_DEFINITION + && area.getLength() > SourceConstants.INCLUDE.length()) { + String tag = parser.getSource().get(area.getOffset(), + SourceConstants.INCLUDE.length()); + if (tag.equals(SourceConstants.INCLUDE)) { + // Cannot use SKIP_ALL here, since it contains SKIP_PREPROCESSOR + SourceIterator itr = parser.createIterator(area.getOffset() + + SourceConstants.INCLUDE.length(), + SourceParser.SKIP_WHITE_SPACES + | SourceParser.SKIP_COMMENTS); + if (itr.hasNext()) { + parseInclude(itr); + } + } + } + } + + /** + * Parses a preprocessor definition. This only finds simple values + * + * @param itr + * source iterator, positioned so that next will return the first + * character of the name of the definition + * @throws SourceParserException + * if parser fails + */ + private void parsePreprocessorDefinition(SourceIterator itr) + throws SourceParserException { + int start = itr.nextIndex(); + int defstart = -1; + SourcePreprocessorDefinition def = new SourcePreprocessorDefinition( + parser, start); + while (itr.hasNext() && def != null) { + itr.next(); + if (itr.hasSkipped()) { + if (defstart == -1) { + if ((itr.previousIndex() + 1) > start) { + def.setName(parser.getSource().get(start, + itr.previousIndex() + 1 - start)); + defstart = itr.currentIndex(); + } else { + def = null; + } + } else { + def.setValue(parser.getSource().get(defstart, + itr.previousIndex() + 1 - defstart)); + def.setLength(itr.previousIndex() + 1 - def.getOffset()); + preprocessorDefinitions.add(def); + def = null; + } + } + } + } + + /** + * Parses an include line + * + * @param itr + * source iterator, positioned so that next will return the first + * character of the name of the definition + * @throws SourceParserException + * if parser fails + */ + private void parseInclude(SourceIterator itr) throws SourceParserException { + int start = itr.nextIndex(); + SourceInclude inc = new SourceInclude(parser, start); + while (itr.hasNext() && inc != null) { + itr.next(); + if (itr.hasSkipped() && (itr.previousIndex()) > (start + 1)) { + inc.setHeaderName(parser.getSource().get(start + 1, + itr.previousIndex() - (start + 1))); + inc.setLength(itr.previousIndex() - inc.getOffset() + 1); + includes.add(inc); + inc = null; + } + } + } + +}