2007-01-28 Marek Sieradzki <marek.sieradzki@gmail.com>
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / ConditionTokenizer.cs
index f121e11233ddbabfbaeb9d03c88326aa50c75b08..86136b104de8b0eb3b70fe9f306873def63e38bf 100644 (file)
 
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.Text;
 
 namespace Microsoft.Build.BuildEngine {
 
        internal sealed class ConditionTokenizer {
+       
                string  inputString = null;
                int     position = 0;
                int     tokenPosition = 0;
                
                Token   token;
                
-               bool    ignoreWhiteSpace = true;
+//             bool    ignoreWhiteSpace = true;
                
                static TokenType[] charIndexToTokenType = new TokenType[128];
-               static Hashtable keywordToTokenType = CollectionsUtil.CreateCaseInsensitiveHashtable ();
+               static Dictionary <string, TokenType> keywords = new Dictionary <string, TokenType> (StringComparer.InvariantCultureIgnoreCase);
 
                static ConditionTokenizer ()
                {
@@ -56,11 +58,13 @@ namespace Microsoft.Build.BuildEngine {
                        foreach (CharToTokenType cht in charToTokenType)
                                charIndexToTokenType [(int) cht.ch] = cht.tokenType;
                        
+                       keywords.Add ("and", TokenType.And);
+                       keywords.Add ("or", TokenType.Or);
                }
                
                public ConditionTokenizer ()
                {
-                       this.ignoreWhiteSpace = true;
+//                     this.ignoreWhiteSpace = true;
                }
                
                public void Tokenize (string s)
@@ -75,7 +79,7 @@ namespace Microsoft.Build.BuildEngine {
                        GetNextToken ();
                }
                
-               private void SkipWhiteSpace ()
+               void SkipWhiteSpace ()
                {
                        int ch;
                        
@@ -86,7 +90,7 @@ namespace Microsoft.Build.BuildEngine {
                        }
                }
                
-               private int PeekChar ()
+               int PeekChar ()
                {
                        if (position < inputString.Length)
                                return (int) inputString [position];
@@ -94,7 +98,7 @@ namespace Microsoft.Build.BuildEngine {
                                return -1;
                }
                
-               private int ReadChar ()
+               int ReadChar ()
                {
                        if (position < inputString.Length)
                                return (int) inputString [position++];
@@ -137,12 +141,12 @@ namespace Microsoft.Build.BuildEngine {
                        if (token.Type == TokenType.EOF)
                                throw new ExpressionParseException ("Cannot read past the end of stream.");
                        
-                       if (IgnoreWhiteSpace)
-                               SkipWhiteSpace ();
+                       SkipWhiteSpace ();
                        
                        tokenPosition = position;
                        
-                       int i = PeekChar ();
+//                     int i = PeekChar ();
+                       int i = ReadChar ();
                        
                        if (i == -1) {
                                token = new Token (null, TokenType.EOF);
@@ -150,28 +154,14 @@ namespace Microsoft.Build.BuildEngine {
                        }
                        
                        char ch = (char) i;
-                       
-                       if (IgnoreWhiteSpace == false && Char.IsWhiteSpace (ch)) {
-                               StringBuilder sb = new StringBuilder ();
-                               int ch2;
 
-                               while ((ch2 = PeekChar ()) != -1)  {
-                                       if (!Char.IsWhiteSpace ((char) ch2))
-                                               break;
-
-                                       sb.Append ((char)ch2);
-                                       ReadChar();
-                               }
-                               
-                               token = new Token (sb.ToString (), TokenType.WhiteSpace);
-                               return;
-                       }
                        
-                       if (Char.IsDigit (ch)) {
+                       // FIXME: looks like a hack: if '-' is here '->' won't be tokenized
+                       // maybe we should treat item reference as a token
+                       if (Char.IsDigit (ch) || ch == '-') {
                                StringBuilder sb = new StringBuilder ();
                                
                                sb.Append (ch);
-                               ReadChar ();
                                
                                while ((i = PeekChar ()) != -1) {
                                        ch = (char) i;
@@ -183,15 +173,11 @@ namespace Microsoft.Build.BuildEngine {
                                }
                                
                                token = new Token (sb.ToString (), TokenType.Number);
-                               return;
-                       }
-                       
-                       if (ch == '\'') {
+                       } else if (ch == '\'') {
                                StringBuilder sb = new StringBuilder ();
                                string temp;
                                
                                sb.Append (ch);
-                               ReadChar ();
                                
                                while ((i = PeekChar ()) != -1) {
                                        ch = (char) i;
@@ -204,17 +190,12 @@ namespace Microsoft.Build.BuildEngine {
                                
                                temp = sb.ToString ();
                                
-                               // FIXME: test extreme cases
                                token = new Token (temp.Substring (1, temp.Length - 2), TokenType.String);
                                
-                               return;
-                       }
-                       
-                       if (ch == '_' || Char.IsLetter (ch)) {
+                       } else  if (ch == '_' || Char.IsLetter (ch)) {
                                StringBuilder sb = new StringBuilder ();
                                
                                sb.Append ((char) ch);
-                               ReadChar ();
                                
                                while ((i = PeekChar ()) != -1) {
                                        if ((char) i == '_' || Char.IsLetterOrDigit ((char) i))
@@ -225,56 +206,31 @@ namespace Microsoft.Build.BuildEngine {
                                
                                string temp = sb.ToString ();
                                
-                               if (temp.ToLower () == "and")
-                                       token = new Token (temp, TokenType.And);
-                               else if (temp.ToLower () == "or")
-                                       token = new Token (temp, TokenType.Or);
+                               if (keywords.ContainsKey (temp))
+                                       token = new Token (temp, keywords [temp]);
                                else
-                                       token = new Token (sb.ToString (), TokenType.String);
-                               return;
-                       }
-                       
-                       ReadChar ();
-                       
-                       if (ch == '!' && PeekChar () == (int) '=') {
+                                       token = new Token (temp, TokenType.String);
+                                       
+                       } else if (ch == '!' && PeekChar () == (int) '=') {
                                token = new Token ("!=", TokenType.NotEqual);
                                ReadChar ();
-                               return;
-                       }
-                       
-                       if (ch == '<' && PeekChar () == (int) '=') {
+                       } else if (ch == '<' && PeekChar () == (int) '=') {
                                token = new Token ("<=", TokenType.LessOrEqual);
                                ReadChar ();
-                               return;
-                       }
-                       
-                       if (ch == '>' && PeekChar () == (int) '=') {
+                       } else if (ch == '>' && PeekChar () == (int) '=') {
                                token = new Token (">=", TokenType.GreaterOrEqual);
                                ReadChar ();
-                               return;
-                       }
-                       
-                       if (ch == '=' && PeekChar () == (int) '=') {
+                       } else if (ch == '=' && PeekChar () == (int) '=') {
                                token = new Token ("==", TokenType.Equal);
                                ReadChar ();
-                               return;
-                       }
-                       
-                       if (ch == '-' && PeekChar () == (int) '>') {
-                               token = new Token ("->", TokenType.Transform);
-                               ReadChar ();
-                               return;
-                       }
-                       
-                       if (ch >= 32 && ch < 128) {
+                       } else if (ch >= 32 && ch < 128) {
                                if (charIndexToTokenType [ch] != TokenType.Invalid) {
                                        token = new Token (new String (ch, 1), charIndexToTokenType [ch]);
                                        return;
                                } else
                                        throw new ExpressionParseException (String.Format ("Invalid punctuation: {0}", ch));
-                       }
-                       
-                       throw new ExpressionParseException (String.Format ("Invalid token: {0}", ch));
+                       } else
+                               throw new ExpressionParseException (String.Format ("Invalid token: {0}", ch));
                }
                
                public int TokenPosition {
@@ -285,10 +241,12 @@ namespace Microsoft.Build.BuildEngine {
                        get { return token; }
                }
                
+/*
                public bool IgnoreWhiteSpace {
                        get { return ignoreWhiteSpace; }
                        set { ignoreWhiteSpace = value; }
                }
+*/
                
                struct CharToTokenType {
                        public char ch;