Sign in to follow this  
Followers 0
Uten

VersionNumToArr and VersionNumIsBigger

6 posts in this topic

#1 ·  Posted (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's

If 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 by Uten

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Why so complicated? :lmao:

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
EndFunc

EDIT: 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 by Zedna

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Why so complicated? ;)

Because you did not post yours first..:lmao:

EDIT: Spell...

Edited by Uten

Share this post


Link to post
Share on other sites

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..;)

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.zip

I 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.:lmao:

I will update the fist post after posting this with the complicated and messy code.

Thanks for the interest, suggestions and participation.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0