2

Can anyone help me in comparing two alphanumeric values in tcl.

If say I have two values of versions

set val1 "2.1.a"
set val2 "1.2.a"

And if I want to get the max of two values i.e. $val1 ( as per above example), how can I do that?

Is there any way besides doing character by character comparison?

Possible set of values:

1.0
1.1a
1.2.3f
2.1

Thanks in advance.

user1851206
  • 61
  • 1
  • 4
  • 1
    Had your versioning system been simpler [like this](http://www.tcl.tk/man/tcl8.6/TclCmd/package.htm#M20), you could've just used `package vcompare $val1 $val2`. For these strings, I think you have to specify better what you mean by "max". Is "2.1.a" less than, equal to or greater than "2.1a"? Is "1.2.3b" less than "1.2.3"? – potrzebie Feb 01 '13 at 16:30

3 Answers3

3

try doing as follows:

set val1 "2.1.a"
puts $val1
set val2 "1.2.a"
puts $val2
puts [string compare $val2 $val1]

It performs a character-by-character comparison of strings string1 and string2. Returns -1, 0, or 1, depending on whether string1 is lexicographically less than, equal to, or greater than string2

Go through this link for further details; hope it will solve your problem.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
Rinku
  • 1,078
  • 6
  • 11
3

I would break up the version string into a list, compare them one by one:

# Breaks the version string into a list of tokens
proc tokenize {v} {
    set v [string map { " " "" } $v]
    set result {}
    foreach token [split $v ".-"] {
        set tokens_scanned [scan $token "%d%s" number alpha]
        if {$tokens_scanned == 0} {lappend result $token}         ;# is alpha, e.g. beta
        if {$tokens_scanned == 1} {lappend result $number}        ;# is number, e.g. 5
        if {$tokens_scanned == 2} {lappend result $number $alpha} ;# is both, e.g. 5beta
    }
    return $result
}

# Examples of versions this function handles:
# 1, 1a, 1.5, 3.2b, 3.2.1, 3.2.1-beta1
proc compare_version {v1 v2} {
    # Sanitize the data
    set v1 [tokenize $v1]
    set v2 [tokenize $v2]

    foreach token1 $v1 token2 $v2 {
        if {$token1 < $token2} { return -1 }
        if {$token1 > $token2} { return 1 }
    }
    return 0
}
Hai Vu
  • 37,849
  • 11
  • 66
  • 93
2

By Tcl documentation, to compare the two version numbers in tcl you should use package command:

package vcompare version1 version2

Compares the two version numbers given by version1 and version2. Returns -1 if version1 is an earlier version than version2, 0 if they are equal, and 1 if version1 is later than version2.

robertm.tum
  • 350
  • 2
  • 12