2010-03-19 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / corlib / System / TimeSpan.cs
index b7c74d1cdac11ced08114afa5b9ae872b5fa98ad..a0a84906cda92e0c42a41693881c17dd6d407334 100644 (file)
@@ -544,14 +544,19 @@ namespace System
                        return t;
                }
 
+               enum ParseError {
+                       None,
+                       Format,
+                       Overflow
+               }
+
                // Class Parser implements parser for TimeSpan.Parse
                private class Parser
                {
                        private string _src;
                        private int _cur = 0;
                        private int _length;
-                       private bool formatError;
-                       private bool overflowError;
+                       ParseError parse_error;
 
                        public Parser (string src)
                        {
@@ -633,7 +638,7 @@ namespace System
                                while (!AtEnd && Char.IsDigit (_src, _cur)) {
                                        res = res * 10 + _src[_cur] - '0';
                                        if (res > Int32.MaxValue) {
-                                               overflowError = true;
+                                               SetParseError (ParseError.Overflow);
                                                break;
                                        }
                                        _cur++;
@@ -641,7 +646,7 @@ namespace System
                                }
 
                                if (!optional && (count == 0))
-                                       formatError = true;
+                                       SetParseError (ParseError.Format);
 
                                return (int)res;
                        }
@@ -688,7 +693,7 @@ namespace System
                                        if (_src[_cur] == ':')
                                                _cur++;
                                        else if (!optional)
-                                               formatError = true;
+                                               SetParseError (ParseError.Format);
                                }
                        }
 
@@ -707,11 +712,51 @@ namespace System
                                }
 
                                if (!digitseen)
-                                       formatError = true;
+                                       SetParseError (ParseError.Format);
 
                                return res;
                        }
 
+                       void SetParseError (ParseError error)
+                       {
+                               // We preserve the very first error.
+                               if (parse_error != ParseError.None)
+                                       return;
+
+                               parse_error = error;
+                       }
+
+                       bool CheckParseSuccess (int hours, int minutes, int seconds, bool tryParse)
+                       {
+                               // FormatException has precedence over OverflowException starting with 4.0
+                               // so put the block before/after properly.
+#if NET_4_0
+                               if (parse_error == ParseError.Format) {
+                                       if (tryParse)
+                                               return false;
+                                       throw new FormatException (
+                                               Locale.GetText ("Invalid format for TimeSpan.Parse."));
+                               }
+#endif
+                               if (parse_error == ParseError.Overflow || hours > 23 || minutes > 59 || seconds > 59) {
+                                       if (tryParse)
+                                               return false;
+                                       throw new OverflowException (
+                                               Locale.GetText ("Invalid time data."));
+                               }
+#if !NET_4_0
+                               // Respect the Overflow precedence for 2.0, putting the format check last.
+                               if (parse_error == ParseError.Format) {
+                                       if (tryParse)
+                                               return false;
+                                       throw new FormatException (
+                                               Locale.GetText ("Invalid format for TimeSpan.Parse."));
+                               }
+#endif
+
+                               return true;
+                       }
+
                        public bool Execute (bool tryParse, out TimeSpan result)
                        {
                                bool sign;
@@ -762,21 +807,10 @@ namespace System
                                ParseWhiteSpace ();
        
                                if (!AtEnd)
-                                       formatError = true;
+                                       SetParseError (ParseError.Format);
 
-                               // Overflow has presceance over FormatException
-                               if (overflowError || hours > 23 || minutes > 59 || seconds > 59) {
-                                       if (tryParse)
-                                               return false;
-                                       throw new OverflowException (
-                                               Locale.GetText ("Invalid time data."));
-                               }
-                               else if (formatError) {
-                                       if (tryParse)
-                                               return false;
-                                       throw new FormatException (
-                                               Locale.GetText ("Invalid format for TimeSpan.Parse."));
-                               }
+                               if (!CheckParseSuccess (hours, minutes, seconds, tryParse))
+                                       return false;
 
                                long t;
                                if (!TimeSpan.CalculateTicks (days, hours, minutes, seconds, 0, false, out t))