@@ -41,12 +41,12 @@ public static TheVersion Parse(string version)
4141 return default ( TheVersion ) . Initialize ( version ) ;
4242 }
4343
44- private TheVersion Initialize ( string version )
44+ private TheVersion Initialize ( string theVersion )
4545 {
4646 if ( initialized )
4747 return this ;
4848
49- this . Version = version ? . Trim ( ) ?? String . Empty ;
49+ this . Version = theVersion ? . Trim ( ) ?? String . Empty ;
5050
5151 isAlpha = false ;
5252 isBeta = false ;
@@ -57,7 +57,7 @@ private TheVersion Initialize(string version)
5757 special = null ;
5858 parts = 0 ;
5959
60- if ( String . IsNullOrEmpty ( version ) )
60+ if ( String . IsNullOrEmpty ( theVersion ) )
6161 return this ;
6262
6363 intParts = new int [ PART_COUNT ] ;
@@ -66,15 +66,16 @@ private TheVersion Initialize(string version)
6666 for ( var i = 0 ; i < PART_COUNT ; i ++ )
6767 stringParts [ i ] = intParts [ i ] . ToString ( ) ;
6868
69- var match = regex . Match ( version ) ;
69+ var match = regex . Match ( theVersion ) ;
7070 if ( ! match . Success )
7171 {
72- LogHelper . Error ( new ArgumentException ( "Invalid version: " + version , "version " ) ) ;
72+ LogHelper . Error ( new ArgumentException ( "Invalid version: " + theVersion , "theVersion " ) ) ;
7373 return this ;
7474 }
7575
7676 major = int . Parse ( match . Groups [ "major" ] . Value ) ;
77- intParts [ 0 ] = major ;
77+ intParts [ parts ] = major ;
78+ stringParts [ parts ] = major . ToString ( ) ;
7879 parts = 1 ;
7980
8081 var minorMatch = match . Groups [ "minor" ] ;
@@ -83,39 +84,42 @@ private TheVersion Initialize(string version)
8384
8485 if ( minorMatch . Success )
8586 {
86- parts ++ ;
8787 if ( ! int . TryParse ( minorMatch . Value , out minor ) )
8888 {
8989 special = minorMatch . Value . TrimEnd ( ) ;
90- stringParts [ parts - 1 ] = special ;
90+ stringParts [ parts ] = special ?? "0" ;
9191 }
9292 else
9393 {
94- intParts [ parts - 1 ] = minor ;
94+ intParts [ parts ] = minor ;
95+ stringParts [ parts ] = minor . ToString ( ) ;
96+ parts ++ ;
9597
9698 if ( patchMatch . Success )
9799 {
98- parts ++ ;
99100 if ( ! int . TryParse ( patchMatch . Value , out patch ) )
100101 {
101102 special = patchMatch . Value . TrimEnd ( ) ;
102- stringParts [ parts - 1 ] = special ;
103+ stringParts [ parts ] = special ?? "0" ;
103104 }
104105 else
105106 {
106- intParts [ parts - 1 ] = patch ;
107+ intParts [ parts ] = patch ;
108+ stringParts [ parts ] = patch . ToString ( ) ;
109+ parts ++ ;
107110
108111 if ( buildMatch . Success )
109112 {
110- parts ++ ;
111113 if ( ! int . TryParse ( buildMatch . Value , out build ) )
112114 {
113115 special = buildMatch . Value . TrimEnd ( ) ;
114- stringParts [ parts - 1 ] = special ;
116+ stringParts [ parts ] = special ?? "0" ;
115117 }
116118 else
117119 {
118- intParts [ parts - 1 ] = build ;
120+ intParts [ parts ] = build ;
121+ stringParts [ parts ] = build . ToString ( ) ;
122+ parts ++ ;
119123 }
120124 }
121125 }
@@ -196,19 +200,19 @@ public bool Equals(TheVersion other)
196200 if ( String . IsNullOrEmpty ( rhs . Version ) )
197201 return true ;
198202
199- for ( var i = 0 ; i < PART_COUNT ; i ++ )
203+ for ( var i = 0 ; i < lhs . parts && i < rhs . parts ; i ++ )
200204 {
201205 if ( lhs . intParts [ i ] != rhs . intParts [ i ] )
202206 return lhs . intParts [ i ] > rhs . intParts [ i ] ;
203207 }
204208
205209 for ( var i = 1 ; i < PART_COUNT ; i ++ )
206210 {
207- if ( lhs . stringParts [ i ] != rhs . stringParts [ i ] )
208- {
209- return GreaterThan ( lhs . stringParts [ i ] , rhs . stringParts [ i ] ) ;
210- }
211+ var ret = CompareVersionStrings ( lhs . stringParts [ i ] , rhs . stringParts [ i ] ) ;
212+ if ( ret != 0 )
213+ return ret > 0 ;
211214 }
215+
212216 return false ;
213217 }
214218
@@ -227,35 +231,42 @@ public bool Equals(TheVersion other)
227231 return lhs < rhs || lhs == rhs ;
228232 }
229233
230- private static bool GreaterThan ( string lhs , string rhs )
234+ private static int CompareVersionStrings ( string lhs , string rhs )
231235 {
232- var lhsNonDigitPos = IndexOfFirstNonDigit ( lhs ) ;
233- var rhsNonDigitPos = IndexOfFirstNonDigit ( rhs ) ;
236+ int lhsNonDigitPos ;
237+ var lhsNumber = GetNumberFromVersionString ( lhs , out lhsNonDigitPos ) ;
234238
235- var lhsNumber = - 1 ;
236- if ( lhsNonDigitPos > - 1 )
237- {
238- int . TryParse ( lhs . Substring ( 0 , lhsNonDigitPos ) , out lhsNumber ) ;
239- }
240- else
241- {
242- int . TryParse ( lhs , out lhsNumber ) ;
243- }
239+ int rhsNonDigitPos ;
240+ var rhsNumber = GetNumberFromVersionString ( rhs , out rhsNonDigitPos ) ;
241+
242+ if ( lhsNumber != rhsNumber )
243+ return lhsNumber . CompareTo ( rhsNumber ) ;
244+
245+ if ( lhsNonDigitPos < 0 && rhsNonDigitPos < 0 )
246+ return 0 ;
247+
248+ // versions with alphanumeric characters are always lower than ones without
249+ // i.e. 1.1alpha is lower than 1.1
250+ if ( lhsNonDigitPos < 0 )
251+ return 1 ;
252+ if ( rhsNonDigitPos < 0 )
253+ return - 1 ;
254+ return lhs . Substring ( lhsNonDigitPos ) . CompareTo ( rhs . Substring ( rhsNonDigitPos ) ) ;
255+ }
244256
245- var rhsNumber = - 1 ;
246- if ( rhsNonDigitPos > - 1 )
257+ private static int GetNumberFromVersionString ( string lhs , out int nonDigitPos )
258+ {
259+ nonDigitPos = IndexOfFirstNonDigit ( lhs ) ;
260+ var number = - 1 ;
261+ if ( nonDigitPos > - 1 )
247262 {
248- int . TryParse ( rhs . Substring ( 0 , rhsNonDigitPos ) , out rhsNumber ) ;
263+ int . TryParse ( lhs . Substring ( 0 , nonDigitPos ) , out number ) ;
249264 }
250265 else
251266 {
252- int . TryParse ( rhs , out rhsNumber ) ;
267+ int . TryParse ( lhs , out number ) ;
253268 }
254-
255- if ( lhsNumber != rhsNumber )
256- return lhsNumber > rhsNumber ;
257-
258- return lhs . Substring ( lhsNonDigitPos > - 1 ? lhsNonDigitPos : 0 ) . CompareTo ( rhs . Substring ( rhsNonDigitPos > - 1 ? rhsNonDigitPos : 0 ) ) > 0 ;
269+ return number ;
259270 }
260271
261272 private static int IndexOfFirstNonDigit ( string str )
0 commit comments