Uten Posted December 3, 2006 Posted December 3, 2006 (edited) Some udf's to compare version numbers. This was written because I wanted to compare version numbers embedded in the filename. Unfortunately it is common to use - as the last increment separator, and even have letters in the version number. So, if this looks overcomplicated to you it probably is. A well formed version number can be compared much easier as @zedna points out in the next post.UDF'sexpandcollapse popupIf not IsDeclared("gDbg") Then Global $gDbg = 0 Func VersionNumIsBigger($ver1, $ver2) ;Returns true or false based on ;$ver1 is bigger than $ver2 Local $a1, $a2, $imax Local $fooArr[1] Local $ret = -1 $a1 = VersionNumToArr($ver1) if @error Then SetError(@error) SetExtended(1) err("ERROR: VersionNumberIsBigger $ver1 is not converted to an array") Return 0 EndIf $a2 = VersionNumToArr($ver2) if @error Then SetError(@error) SetExtended(2) err("ERROR: VersionNumberIsBigger $ver2 is not converted to an array") Return 0 EndIf ; Determine the biggest one $imax = UBound($a1) If $imax > UBound($a2) Then $iMax = UBound($a2) For $i = 0 to $iMax - 1 If NumNumeric($a1[$i]) AND NumNumeric($a2[$i]) Then ;Note "0" returns 0 If number($a1[$i]) > number($a2[$i]) Then if $gdbg Then dbg( $a1[$i] & ">" & $a2[$i]) $ret = 1 ExitLoop ElseIf number($a1[$i]) < number($a2[$i]) Then if $gdbg Then dbg( $a1[$i] & "<" & $a2[$i]) $ret = 0 ExitLoop EndIf Else ;Do a ASCII compare. OBS! 012a <> 12a ;NOTE: This should be done agains localization settings. ;See sample: http://www.autoitscript.com/forum/index.php?showtopic=18823&hl=compare* If $a1[$i] > $a2[$i] Then if $gdbg Then dbg( $a1[$i] & ">" & $a2[$i]) $ret = 1 ExitLoop ElseIf $a1[$i] < $a2[$i] Then if $gdbg Then dbg( $a1[$i] & "<" & $a2[$i]) $ret = 0 ExitLoop EndIf EndIf Next If $ret = -1 And UBound($a1) <> UBound($a2) Then ;At this point comparison has been equal. We have to study the fine print ;NOTE: We consider this the case even if they are equal ; As in 2.1.0.0 compared to 2.1.0 If $gDbg Then dbg("+++Fine picking: ") Local $arrX, $fix if UBound($a1) > UBound($a2) Then $arrX = $a1 $fix = 1 Else $arrX = $a2 $fix = 0 EndIF $i = $iMax For $i = $iMax to NumBiggest(UBound($a1), UBound($a2)) - 1 If $arrX[$i] > 0 then ;0 and "" is the same? $ret = $fix ExitLoop EndIf Next ; If we still don't have a conclusive result we return true If $ret = -1 Then $ret = 1 EndIf Return $ret Return $ret EndFunc Func VersionNumToArr($ver) ;NOTE: Requieres Autoit version 3.2.1.8 or higher (PCRE regexp implementation) Local $a, $fooArr ;NOTE: $a = StringRegExp($ver, "(\d+)", 3) If not IsArray($a) Then ; Could be a single number If IsNumber($ver) Then $fooArr[0] = $ver $a = $fooArr Else SetError(1) EndIf EndIf Return $a EndFunc oÝ÷ Ùµ-XÉû§rبÏÛjëh×6func dbg($msg, $erl=@ScriptLineNumber) ConsoleWrite("(" & $erl & ") := " & $msg & @LF) EndFunc func err($msg, $erl=@ScriptLineNumber) ConsoleWrite("(" & $erl & ") := " & $msg & @LF) EndFunc Func NumBiggest($arg1, $arg2) Local $ret If $arg1 > $arg2 Then $ret = $arg1 Else $ret = $arg2 EndIf Return $ret EndFunc Func NumNumeric($arg) ;PURPOSE: Check if $arg is a number. Return NOT StringRegExp($arg, "[^\d]+") ;Number will return 0=false for 0 EndFunc Func assert($bool, $msg = "NO MSG", $erl=@ScriptLineNumber) if not $bool then ConsoleWrite("(" & $erl & ") := " & $msg & @LF) EndIf EndFunc oÝ÷ Ù´Þ²×(uïÛjëh×6 Func testVersionNumToArr() Local $a $a = VersionNumToArr("1.35.0.1") assert(UBound($a) = 4, "Unexpected array size") assert($a[0] = 1 ) assert($a[1] = 35) assert($a[2] = 0) assert($a[3] = 1) $a = VersionNumToArr("2.35") assert(UBound($a) = 2, "Unexpected array size") assert($a[0] = 2 ) assert($a[1] = 35) $a = VersionNumToArr("3") assert(UBound($a) = 1, "Unexpected array size") assert($a[0] = 3 ) $a = VersionNumToArr("4.35-3") assert(UBound($a) = 3, "Unexpected array size") assert($a[0] = 4 ) assert($a[1] = 35) assert($a[2] = 3) ConsoleWrite("+++DONE: testVersionNumToArr" & @LF) EndFunc Func testVersionNumIsBigger() assert(VersionNumIsBigger("1", "0"), "Unexpected result") assert(NOT VersionNumIsBigger("0", "1"), "Unexpected result") assert(VersionNumIsBigger("1.0", "0.1"), "Unexpected result") assert(VersionNumIsBigger("1.2.3.0", "0.3.3.4"), "Unexpected result") assert(VersionNumIsBigger("1.0-3", "1.0"), "Unexpected result") assert(VersionNumIsBigger("1.1.0.12", "1.1.0.11"), "Unexpected result") assert(VersionNumIsBigger("1.1.0.12", "1.1.0.11"), "Unexpected result") ;NOTE: Testing with the entier file name, diffrent ext. assert(VersionNumIsBigger("file-1.1.0.12.zip", "file-1.1.0.11.zap"), "Unexpected result") ;NOTE: Filename with embeded number assert(VersionNumIsBigger("file2-1.1.0.12.zip", "file1-1.1.0.12.zip"), "Unexpected result") ConsoleWrite("+++DONE: testVersionNumIsBigger" & @LF) EndFunc Func testVersionNumIsBiggerFunnyNumbers() assert(VersionNumIsBigger("0112.1.130.12", "112.1.130.12"), "Unexpected result") assert(VersionNumIsBigger("arc-5.21j-1-bin.zip", "arc-5.21j-bin.zip"), "Unexpected result") assert(NOT VersionNumIsBigger("arc-5.21j-bin.zip", "arc-5.21j-1-bin.zip"), "Unexpected result") assert(VersionNumIsBigger("arc-5.21e.8-1-bin.zip", "arc-5.21e.8-bin.zip")) assert(VersionNumIsBigger("arc-5.21j-1-bin.zip", "arc-5.21j-bin.zip")) ;$gDbg = 1 assert(VersionNumIsBigger("arc-5.21j-1-bin.zip", "arc-5.21e.8-1-bin.zip")) assert(NOT VersionNumIsBigger("arc-5.21e.8-1-bin.zip", "arc-5.21j-1-bin.zip")) ConsoleWrite("+++DONE: testVersionNumIsBiggerFunnyNumbers" & @LF) EndFunc Func testIsNumber() assert(IsNumber(number("012"))) ConsoleWrite("+++DONE: testIsNumber" & @LF) EndFunc testVersionNumToArr() testVersionNumIsBigger() testIsNumber() testVersionNumIsBiggerFunnyNumbers()EDIT: Modified code to handle letters in the version number and numbers starting with 0 ("012").EDIT: Changed NumNumeric as it did not do its work as wanted. Added tests to testVersionNumIsBiggerFunnyNumbers(). Edited December 3, 2006 by Uten Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling
Zedna Posted December 3, 2006 Posted December 3, 2006 (edited) Why so complicated? Func VersionNumIsBigger($ver1, $ver2) ;Returns true or false based on ;$ver1 is bigger than $ver2 $ver1 = StringReplace($ver1,'-','.') $ver2 = StringReplace($ver2,'-','.') ;NOTE: We consider this the case even if they are equal ; As in 2.1.0.0 compared to 2.1.0 If StringLen($ver1) = 5 Then $ver1 &= '.0' If StringLen($ver2) = 5 Then $ver2 &= '.0' If $ver1 > $ver2 Then Return 1 Else Return 0 EndIf EndFuncEDIT: Now I look at yours testVersionNumIsBigger() and your version numbers are too much complicared so my function will not fit for that purpose, but idea stays: first give to both version numbers the same format and then do very simple compare Edited December 3, 2006 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search
Uten Posted December 3, 2006 Author Posted December 3, 2006 (edited) Why so complicated? Because you did not post yours first..EDIT: Spell... Edited December 3, 2006 by Uten Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling
Uten Posted December 3, 2006 Author Posted December 3, 2006 Uhh, we both failed in this case assert(VersionNumIsBigger("0112.1.130.12", "112.1.130.12"), "Unexpected result") And probably in other padded samples to.. Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling
MHz Posted December 3, 2006 Posted December 3, 2006 I use StringSplit to test version of my scripts. _AutoItVersion('3.2.0.0') Func _AutoItVersion($scriptver) Local $au3ver, $expectver, $exitcode If Not @Compiled Then $au3ver = StringSplit(@AutoItVersion, '.') $expectver = StringSplit($scriptver, '.') If @error Then Return ConsoleWrite('_AutoItVersion() error with using StringSplit()' & @CRLF) Exit -2 EndIf For $i = 1 To $expectver[0] If $au3ver[$i] = $expectver[$i] Then ContinueLoop ElseIf $au3ver[$i] > $expectver[$i] Then Return Else MsgBox(0x40010, @ScriptName, 'Need atleast v' & $scriptver & ' to execute this script', 10) $exitcode = StringReplace($scriptver, '.', '') Exit $exitcode EndIf Next EndIf EndFunc Seems to work well. I expect "." then "-" in the read.
Uten Posted December 3, 2006 Author Posted December 3, 2006 I know, it should be simple if we all sticked to the same convention. But we don't. What I really want to do is to download the newest gnu libraries and tools. In my naive state I thought tis is just a few lines of AutoIt code.So take a look at the list. It can drive you nuts.. At least when it comes to version numbers.. I'm only interested in the ones ending with bin.zipI have fixed the code so it works on the gnuwin32 list, except for one case as far as I can see. Sorry @Zedna it is even more complicated. Your solution is brilliant for well formed version numbers.I will update the fist post after posting this with the complicated and messy code.Thanks for the interest, suggestions and participation. Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now