Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 26490 Details for
Bug 37406
rewrite of version handling code
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
code which allows numberless suffixes
versions.py (text/plain), 9.05 KB, created by
Marius Mauch (RETIRED)
on 2004-02-27 16:14:05 UTC
(
hide
)
Description:
code which allows numberless suffixes
Filename:
MIME Type:
Creator:
Marius Mauch (RETIRED)
Created:
2004-02-27 16:14:05 UTC
Size:
9.05 KB
patch
obsolete
>import re,string > >############### new code ############### > >ver_regexp = re.compile("^(cvs-)?(\\d+)((\\.\\d+)*)([a-zA-Z]?)((_(pre|p|beta|alpha|rc)\\d*)*)(-r(\\d+))?$") >suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$") >suffix_value = {"pre": -2, "p": 0, "alpha": -4, "beta": -3, "rc": -1} > >def ververify(myver, silent=1): > if ver_regexp.match(myver): > return 1 > else: > if not silent: > print "!!! syntax error in version: %s" % myver > return 0 > >vercmp_cache = {} >def vercmp(ver1, ver2, silent=1): > if ver1 == ver2: > return 0 > mykey=ver1+":"+ver2 > try: > return vercmp_cache[mykey] > except KeyError: > pass > match1 = ver_regexp.match(ver1) > match2 = ver_regexp.match(ver2) > > # checking that the versions are valid > if not match1 or not match1.groups(): > if not silent: > print "!!! syntax error in version: %s" % ver1 > return None > if not match2 or not match2.groups(): > if not silent: > print "!!! syntax error in version: %s" % ver2 > return None > > # shortcut for cvs ebuilds (new style) > if match1.group(1) and not match2.group(1): > vercmp_cache[mykey] = 1 > return 1 > elif match2.group(1) and not match1.group(1): > vercmp_cache[mykey] = -1 > return -1 > > # building lists of the version parts before the suffix > # first part is simple > list1 = [string.atoi(match1.group(2))] > list2 = [string.atoi(match2.group(2))] > # this part would greatly benefit from a fixed-length version pattern > if len(match1.group(3)) or len(match2.group(3)): > vlist1 = match1.group(3)[1:].split(".") > vlist2 = match2.group(3)[1:].split(".") > for i in range(0, max(len(vlist1), len(vlist2))): > if len(vlist1) <= i or len(vlist1[i]) == 0: > list1.append(0) > list2.append(string.atoi(vlist2[i])) > elif len(vlist2) <= i or len(vlist2[i]) == 0: > list1.append(string.atoi(vlist1[i])) > list2.append(0) > # Let's make life easy and use integers unless we're forced to use floats > elif (vlist1[i][0] != "0" and vlist2[i][0] != "0"): > list1.append(string.atoi(vlist1[i])) > list2.append(string.atoi(vlist2[i])) > # now we have to use floats so 1.02 compares correctly against 1.1 > else: > list1.append(string.atof("0."+vlist1[i])) > list2.append(string.atof("0."+vlist2[i])) > # and now the final letter > if len(match1.group(5)): > list1.append(ord(match1.group(5))) > if len(match2.group(5)): > list2.append(ord(match2.group(5))) > > for i in range(0, max(len(list1), len(list2))): > if len(list1) <= i: > vercmp_cache[mykey] = -1 > return -1 > elif len(list2) <= i: > vercmp_cache[mykey] = 1 > return 1 > elif list1[i] != list2[i]: > vercmp_cache[mykey] = list1[i] - list2[i] > return list1[i] - list2[i] > > # main version is equal, so now compare the _suffix part > list1 = match1.group(6).split("_")[1:] > list2 = match2.group(6).split("_")[1:] > > for i in range(0, max(len(list1), len(list2))): > if len(list1) <= i: > s1 = ("p","0") > else: > s1 = suffix_regexp.match(list1[i]).groups() > if len(list2) <= i: > s2 = ("p","0") > else: > s2 = suffix_regexp.match(list2[i]).groups() > if s1[0] != s2[0]: > return suffix_value[s1[0]] - suffix_value[s2[0]] > if s1[1] != s2[1]: > return string.atoi(s1[1]) - string.atoi(s2[1]) > > # the suffix part is equal to, so finally check the revision > if match1.group(10): > r1 = string.atoi(match1.group(10)) > else: > r1 = 0 > if match2.group(10): > r2 = string.atoi(match2.group(10)) > else: > r2 = 0 > vercmp_cache[mykey] = r1 - r2 > return r1 - r2 > >def pkgcmp(pkg1, pkg2): > if pkg1[0] != pkg2[0]: > return None > mycmp=vercmp(pkg1[1],pkg2[1]) > if mycmp>0: > return 1 > if mycmp<0: > return -1 > r1=string.atof(pkg1[2][1:]) > r2=string.atof(pkg2[2][1:]) > if r1>r2: > return 1 > if r2>r1: > return -1 > return 0 > >################ old code ################### > >_endversion={"pre":-2,"p":0,"alpha":-4,"beta":-3,"rc":-1} >_endversion_keys = ["pre", "p", "alpha", "beta", "rc"] > >def _pkgcmp(pkg1,pkg2): > """if returnval is less than zero, then pkg2 is newer than pkg1, zero if equal and positive if older.""" > if pkg1[0] != pkg2[0]: > return None > mycmp=vercmp(pkg1[1],pkg2[1]) > if mycmp>0: > return 1 > if mycmp<0: > return -1 > r1=string.atoi(pkg1[2][1:]) > r2=string.atoi(pkg2[2][1:]) > if r1>r2: > return 1 > if r2>r1: > return -1 > return 0 > >def _relparse(myver): > "converts last version part into three components" > number=0 > suffix=0 > endtype=0 > endnumber=0 > > mynewver=string.split(myver,"_") > myver=mynewver[0] > > #normal number or number with letter at end > divider=len(myver)-1 > if myver[divider:] not in "1234567890": > #letter at end > suffix=ord(myver[divider:]) > number=string.atof(myver[0:divider]) > else: > number=string.atof(myver) > > if len(mynewver)==2: > #an endversion > for x in _endversion_keys: > elen=len(x) > if mynewver[1][:elen] == x: > match=1 > endtype=_endversion[x] > try: > endnumber=string.atof(mynewver[1][elen:]) > except: > endnumber=0 > break > return [number,suffix,endtype,endnumber] > >#returns 1 if valid version string, else 0 ># valid string in format: <v1>.<v2>...<vx>[a-z,_{endversion}[vy]] ># ververify doesn't do package rev. > >_vercache={} >def _ververify(myorigval,silent=1): > try: > return _vercache[myorigval] > except KeyError: > pass > if len(myorigval)==0: > if not silent: > print "!!! Name error: package contains empty \"-\" part." > return 0 > myval=string.split(myorigval,'.') > if len(myval)==0: > if not silent: > print "!!! Name error: empty version string." > _vercache[myorigval]=0 > return 0 > #all but the last version must be a numeric > for x in myval[:-1]: > if not len(x): > if not silent: > print "!!! Name error in",myorigval+": two decimal points in a row" > _vercache[myorigval]=0 > return 0 > try: > foo=string.atoi(x) > except: > if not silent: > print "!!! Name error in",myorigval+": \""+x+"\" is not a valid version component." > _vercache[myorigval]=0 > return 0 > if not len(myval[-1]): > if not silent: > print "!!! Name error in",myorigval+": two decimal points in a row" > _vercache[myorigval]=0 > return 0 > try: > foo=string.atoi(myval[-1]) > _vercache[myorigval]=1 > return 1 > except: > pass > #ok, our last component is not a plain number or blank, let's continue > if myval[-1][-1] in string.lowercase: > try: > foo=string.atoi(myval[-1][:-1]) > return 1 > _vercache[myorigval]=1 > # 1a, 2.0b, etc. > except: > pass > #ok, maybe we have a 1_alpha or 1_beta2; let's see > #ep="endpart" > ep=string.split(myval[-1],"_") > if len(ep)!=2: > if not silent: > print "!!! Name error in",myorigval > _vercache[myorigval]=0 > return 0 > try: > foo=string.atoi(ep[0][-1]) > chk=ep[0] > except: > # because it's ok last char is not numeric. example: foo-1.0.0a_pre1 > chk=ep[0][:-1] > > try: > foo=string.atoi(chk) > except: > #this needs to be numeric or numeric+single letter, > #i.e. the "1" in "1_alpha" or "1a_alpha" > if not silent: > print "!!! Name error in",myorigval+": characters before _ must be numeric or numeric+single letter" > _vercache[myorigval]=0 > return 0 > for mye in _endversion_keys: > if ep[1][0:len(mye)]==mye: > if len(mye)==len(ep[1]): > #no trailing numeric; ok > _vercache[myorigval]=1 > return 1 > else: > try: > foo=string.atoi(ep[1][len(mye):]) > _vercache[myorigval]=1 > return 1 > except: > #if no endversions work, *then* we return 0 > pass > if not silent: > print "!!! Name error in",myorigval > _vercache[myorigval]=0 > return 0 > ># vercmp: ># This takes two version strings and returns an integer to tell you whether ># the versions are the same, val1>val2 or val2>val1. >_vcmpcache={} >def _vercmp(val1,val2): > if val1==val2: > #quick short-circuit > return 0 > valkey=val1+" "+val2 > try: > return _vcmpcache[valkey] > try: > return -_vcmpcache[val2+" "+val1] > except KeyError: > pass > except KeyError: > pass > > # consider 1_p2 vc 1.1 > # after expansion will become (1_p2,0) vc (1,1) > # then 1_p2 is compared with 1 before 0 is compared with 1 > # to solve the bug we need to convert it to (1,0_p2) > # by splitting _prepart part and adding it back _after_expansion > val1_prepart = val2_prepart = '' > if val1.count('_'): > val1, val1_prepart = val1.split('_', 1) > if val2.count('_'): > val2, val2_prepart = val2.split('_', 1) > > # replace '-' by '.' > # FIXME: Is it needed? can val1/2 contain '-'? > val1=string.split(val1,'-') > if len(val1)==2: > val1[0]=val1[0]+"."+val1[1] > val2=string.split(val2,'-') > if len(val2)==2: > val2[0]=val2[0]+"."+val2[1] > > val1=string.split(val1[0],'.') > val2=string.split(val2[0],'.') > > #add back decimal point so that .03 does not become "3" ! > for x in range(1,len(val1)): > if val1[x][0] == '0' : > val1[x]='.' + val1[x] > for x in range(1,len(val2)): > if val2[x][0] == '0' : > val2[x]='.' + val2[x] > > # extend version numbers > if len(val2)<len(val1): > val2.extend(["0"]*(len(val1)-len(val2))) > elif len(val1)<len(val2): > val1.extend(["0"]*(len(val2)-len(val1))) > > # add back _prepart tails > if val1_prepart: > val1[-1] += '_' + val1_prepart > if val2_prepart: > val2[-1] += '_' + val2_prepart > #The above code will extend version numbers out so they > #have the same number of digits. > for x in range(0,len(val1)): > cmp1=_relparse(val1[x]) > cmp2=_relparse(val2[x]) > for y in range(0,4): > myret=cmp1[y]-cmp2[y] > if myret != 0: > _vcmpcache[valkey]=myret > return myret > _vcmpcache[valkey]=0 > return 0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 37406
:
25267
|
25711
|
26490
|
26491
|
26883
|
31566
|
31767