lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, 2010-11-10 at 11:36 +0900, Miles Bader wrote: 
> Nick Gammon <nick@gammon.com.au> writes:
> 
> >> * Changes from version 0.9 to 0.10
> >
> > If I may just point out, doing either a string or numeric comparison,
> > version 0.10 is a lower version than 0.9.
> >
> > print ("0.10" > "0.9") --> false
> > print (0.10 > 0.9)  --> false
> 
> Nonetheless, it's a very standard format for version numbers.
> 
> When comparing version strings, you should compare runs of digits in
> isolation, as numbers.  Most package-handling programs should do that
> automatically (and glibc even contains a variant of strcmp that does it
> -- "strverscmp").
> 
> -Miles
> 

Something like this

function strverscmp(a, b)
   if type(a) == 'string' and type(b) == 'string' then
      local aa = a:gmatch('%d+')
      local bb = b:gmatch('%d+')
      while true do
local na = aa()
local nb = bb()
if not na and not nb then return 0 end
if not na then return -1 end
if not nb then return 1 end
local delta = tonumber(na) - tonumber(nb)
if delta < 0 then return -1 end
if delta > 0 then return 1 end
      end
   elseif type(a) == 'number' and type(b) == 'number' then
      return a - b
   end
   return nil
end

function test(a, b)
   print(a, b, strverscmp(a, b))
end

test('0.9', '0.10')
test('0.9', '0.9')
test('0.9.1', '0.10')
test('0.9.1', '0.9.0')
test('0.9.1', '0.9.2')
test(0.9, 0.9)

</nk>