Updated 2013-12-01 02:33:23 by AMG

Problem: it doesn't

A version number is:
   join $listOfNonNegativeIntegers .

Want to add recognition of things like 8.4b1

Concept: allow values -1 and -2 in the list.

Wherever the result has .-1. replace with b

Wherever the result has .-2. replace with a

Implies: a or b can't be next to a .

a or b can't be first or last char in version number

Things like 1.2a5b3.7 are OK (if weird)


[package vcompare] extended obvious way (-2 < -1 < 0).

[package vsatisfies] -- need to specify sensible rules (for itself and to be used by [package require])

[package vsatisfies 1.1 1.0] => 1

[package vsatisfies 1.1a0 1.0] => 1

[package vsatisfies 1.1b0 1.0] => 1

Note: implies responsibility for controlling package availability placed on package installer! (Provide alpha/beta releases to developers, but hide from end-users, for example -- special TCLLIBPATH, etc.)

[package vsatisfies 1.1a1 1.1a0] => ???

[package vsatisfies 1.1b0 1.1a0] => ???

[package vsatisfies 1.1 1.1a0] => ???

[package vsatisfies 1.1b1 1.1b0] => ???

[package vsatisfies 1.1 1.1b0] => ???

Also consider new cases when package BoF: PACKAGE REQUIRE support for RANGES of acceptable versions is present.

[package vsatisfies $version $range ?$range ...?]

Why stop to a and b?
 proc vsplit {ver} {
  if {![regexp {^\d+($|(.\d+|[a-z]{1}(\d+|$))*)$} $ver]} {error "expected version number but got \"$ver\""}
  set r {}
  foreach {a b c d e} [regexp -all -inline {(\d+)[.$]?|([a-z])($|(\d+))} $ver] {
   if {$b ne {}} {lappend r $b} else {
    lappend r [expr {[scan $c %c]-123}]
    if {$d ne {}} {lappend r $d}
  return $r
 proc vcompare {uv vv} {
  set uv [vsplit $uv]
  set vv [vsplit $vv]
  if {[set m [llength $uv]] > [llength $vv]} {
   lappend vv {*}[lrepeat [expr {$m-[llength $vv]}] 0]
  } elseif {[set m [llength $vv]] > [llength $uv]} {
   lappend uv {*}[lrepeat [expr {$m-[llength $uv]}] 0]
  for {set i 0} {$i < $m} {incr i} {
   if {[lindex $uv $i] < [lindex $vv $i]} {return -1}
   if {[lindex $uv $i] > [lindex $vv $i]} {return 1}
  return 0

I wrote this because I needed something like this. So far it has worked, but I haven't tested it a lot. Or at all.

It does:

  • allow letters in version numbers (1.2a, 1.2a5, 1.2a5b3.7, 0.59r)
  • conform to [package vcompare] even to extent of error message
  • not allow a letter to be followed by a letter, or version number to start with anything but a number
  • require 8.5 due {*} and [lrepeat]
  • bite the bullet in performance and elegance, probably.

Just to make my second appearance in this great Wiki,