crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/SourceParser/Parsers/ParserSrcMethod.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/SourceParser/Parsers/ParserSrcMethod.cs Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,234 @@
+/*
+* Copyright (c) 2009 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:
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SymbianUtils.SourceParser.Objects;
+using SymbianUtils.SourceParser.Parsers;
+
+namespace SymbianUtils.SourceParser.Parsers
+{
+ public class ParserSrcMethod
+ {
+ #region Constructors
+ public ParserSrcMethod()
+ {
+ }
+ #endregion
+
+ #region API
+ public SrcMethod Parse( ref string aText )
+ {
+ SrcMethod ret = null;
+ //
+ if ( aText.Length > 0 )
+ {
+ string parameters = string.Empty;
+ //
+ if ( ContainsParameters( aText ) )
+ {
+ // This leaves modifiers intact
+ parameters = ExtractParameters( ref aText );
+ }
+
+ // Look for the class separator. If we find that, then everything after
+ // it is the method name.
+ //
+ // If no class separator exists, then we treat the whole thing as the method
+ // name.
+ int pos = aText.IndexOf( SrcClass.KClassSeparator );
+
+ // By default, treat the whole text as the class name
+ string methodText = aText;
+ if ( pos >= 0 )
+ {
+ methodText = aText.Substring( pos + SrcClass.KClassSeparator.Length );
+ aText = aText.Substring( 0, pos + SrcClass.KClassSeparator.Length );
+ }
+ else
+ {
+ // Everything was consumed...
+ aText = string.Empty;
+ }
+
+ // Make a new method. Work out if the method text
+ // actually has any parameters
+ ret = new SrcMethod();
+
+ // Try to parse the modifiers. We extract that first
+ // to leave us with just the method name and the parameters.
+ bool hasModifier = ContainsModifier( methodText );
+ if ( hasModifier )
+ {
+ ParserSrcMethodModifier parser = new ParserSrcMethodModifier();
+ SrcMethodModifier modifier = parser.Parse( ref methodText );
+ if ( modifier != null )
+ {
+ ret.Modifier = modifier;
+ }
+ }
+
+ // Try to parse the parameters. We can also use this
+ // to calculate the exact method name.
+ if ( parameters.Length > 0 )
+ {
+ ParserSrcMethodParameter parser = new ParserSrcMethodParameter();
+ parser.Parse( ref parameters, ret );
+ }
+
+ // What's left should be the method name followed by "()" if the
+ // 'method' wasn't a label.
+ if ( ContainsParameters( methodText ) )
+ {
+ // Discard "()";
+ pos = methodText.LastIndexOf( "(" );
+ methodText = methodText.Substring( 0, pos );
+ }
+
+ ret.Name = methodText;
+ }
+ //
+ return ret;
+ }
+ #endregion
+
+ #region Properties
+ #endregion
+
+ #region Internal methods
+ private static bool ContainsParameters( string aText )
+ {
+ // Search initiall for '(' - if that is found, then
+ // we should also find a closing bracket.
+ bool parameters = false;
+ int openingBracketPos = aText.IndexOf( "(" );
+ //
+ if ( openingBracketPos > 0 )
+ {
+ // Should also be a closing bracket and it should
+ // appear after the opening bracket
+ int closingBracketPos = aText.LastIndexOf( ")" );
+ parameters = ( closingBracketPos > openingBracketPos );
+ }
+ //
+ return parameters;
+ }
+
+ private static bool ContainsModifier( string aText )
+ {
+ bool modifiers = false;
+
+ int openingBracketPos = aText.IndexOf( "(" );
+ if ( openingBracketPos >= 0 )
+ {
+ int closingBracketPos = openingBracketPos;
+ SymbianUtils.Strings.StringParsingUtils.SkipToEndOfSection( ref aText, ref closingBracketPos, '(', ')' );
+
+ if ( closingBracketPos > openingBracketPos )
+ {
+ // everything here on is the modifier text;
+ string modifierText = aText.Substring( closingBracketPos + 1 );
+ modifiers = ( modifierText.Trim().Length > 0 );
+ }
+ }
+ //
+ return modifiers;
+ }
+
+ private static string ExtractParameters( ref string aText )
+ {
+ const string KOperatorChevronText = "operator <<";
+
+ // DoAppendFormatList<TDes16, (int)2>(T1&, const T3&, std::__va_list, T2*)
+ // DoAppendFormatList<TDes16, (int)2>(T1&, TBuf<(int)256>, std::__va_list, T2*)
+ // Method<TDes16>::Wibble( something )
+ // Method::Wibble( RPointerArray<HBufC> )
+ // RTest::operator ()(int, int, const unsigned short*)
+ // TDesC16::Left(int) const
+ // CObjectCon::AtL(int) const
+ // User::Panic(const TDesC16&, int)
+ // operator <<(RWriteStream&, const unsigned char&)
+
+ // Handle special case of "operator <<" confusing matters
+ string workingText = aText;
+ int operatorOpeningChevronPos = aText.IndexOf( KOperatorChevronText );
+ if ( operatorOpeningChevronPos >= 0 )
+ {
+ aText = aText.Substring( 0, operatorOpeningChevronPos + KOperatorChevronText.Length );
+ workingText = workingText.Substring( operatorOpeningChevronPos + KOperatorChevronText.Length );
+ }
+ else
+ {
+ aText = string.Empty;
+ }
+
+ string ret = string.Empty;
+ //
+ int closingPos = 0;
+ int openingPos = 0;
+ int templatePos = 0;
+ //
+ while ( openingPos >= 0 )
+ {
+ if ( templatePos >= 0 )
+ templatePos = workingText.IndexOf( "<", templatePos );
+ openingPos = workingText.IndexOf( "(", openingPos );
+
+ if ( templatePos >= 0 && templatePos < openingPos )
+ {
+ // Template region appears before the next bracket. Skip
+ // over all characters until we hit the end of the template
+ // section
+ int endingPos = templatePos;
+ SymbianUtils.Strings.StringParsingUtils.SkipToEndOfSection( ref workingText, ref endingPos, '<', '>' );
+
+ if ( endingPos < 0 )
+ {
+ // Matching closing brace was never found - dealing with operator << ?
+ templatePos = -1;
+ }
+ else
+ {
+ // Something like DoAppendFormatList<TDes16, (int)2>(T1&, const T3&, std::__va_list, T2*) ???
+ templatePos = endingPos;
+ openingPos = endingPos;
+ }
+ }
+ else if ( openingPos >= 0 )
+ {
+ // Skipped over any template nonsense. Work backward from the end
+ // in order to locate start of parameters.
+ closingPos = workingText.LastIndexOf( ')' );
+ openingPos = closingPos;
+ SymbianUtils.Strings.StringParsingUtils.SkipToBeginningOfSection( ref workingText, ref openingPos, '(', ')' );
+
+ string parameters = workingText.Substring( openingPos + 1, ( closingPos - openingPos ) - 1 ).Trim();
+ ret = parameters;
+ workingText = workingText.Substring( 0, openingPos + 1 ) + workingText.Substring( closingPos );
+ aText = aText + workingText;
+ break;
+ }
+ }
+ //
+ return ret;
+ }
+ #endregion
+
+ #region Data members
+ #endregion
+ }
+}