from portage import _unicode_decode
from portage.eapi import eapi_has_slot_deps, eapi_has_src_uri_arrows, \
eapi_has_use_deps, eapi_has_strong_blocks, eapi_has_use_dep_defaults, \
- eapi_has_repo_deps
+ eapi_has_repo_deps, eapi_allows_dots_in_PN
from portage.exception import InvalidAtom, InvalidData, InvalidDependString
from portage.localization import _
from portage.versions import catpkgsplit, catsplit, \
else:
blocker = False
self.__dict__['blocker'] = blocker
- m = _atom_re.match(s)
+ m = _get_atom_re(eapi).match(s)
extended_syntax = False
if m is None:
if allow_wildcard:
- m = _atom_wildcard_re.match(s)
+ m = _get_atom_wildcard_re(eapi).match(s)
if m is None:
raise InvalidAtom(self)
op = None
else:
raise InvalidAtom(self)
elif m.group('op') is not None:
- base = _atom_re.groupindex['op']
+ base = _get_atom_re(eapi).groupindex['op']
op = m.group(base + 1)
cpv = m.group(base + 2)
cp = m.group(base + 3)
- slot = m.group(_atom_re.groups - 2)
- repo = m.group(_atom_re.groups - 1)
- use_str = m.group(_atom_re.groups)
+ slot = m.group(_get_atom_re(eapi).groups - 2)
+ repo = m.group(_get_atom_re(eapi).groups - 1)
+ use_str = m.group(_get_atom_re(eapi).groups)
if m.group(base + 4) is not None:
raise InvalidAtom(self)
elif m.group('star') is not None:
- base = _atom_re.groupindex['star']
+ base = _get_atom_re(eapi).groupindex['star']
op = '=*'
cpv = m.group(base + 1)
cp = m.group(base + 2)
- slot = m.group(_atom_re.groups - 2)
- repo = m.group(_atom_re.groups - 1)
- use_str = m.group(_atom_re.groups)
+ slot = m.group(_get_atom_re(eapi).groups - 2)
+ repo = m.group(_get_atom_re(eapi).groups - 1)
+ use_str = m.group(_get_atom_re(eapi).groups)
if m.group(base + 3) is not None:
raise InvalidAtom(self)
elif m.group('simple') is not None:
op = None
- cpv = cp = m.group(_atom_re.groupindex['simple'] + 1)
- slot = m.group(_atom_re.groups - 2)
- repo = m.group(_atom_re.groups - 1)
- use_str = m.group(_atom_re.groups)
- if m.group(_atom_re.groupindex['simple'] + 2) is not None:
+ cpv = cp = m.group(_get_atom_re(eapi).groupindex['simple'] + 1)
+ slot = m.group(_get_atom_re(eapi).groups - 2)
+ repo = m.group(_get_atom_re(eapi).groups - 1)
+ use_str = m.group(_get_atom_re(eapi).groups)
+ if m.group(_get_atom_re(eapi).groupindex['simple'] + 2) is not None:
raise InvalidAtom(self)
else:
_repo_name = r'[\w][\w-]*'
_repo = r'(?:' + _repo_separator + '(' + _repo_name + ')' + ')?'
-_atom_re = re.compile('^(?P<without_use>(?:' +
- '(?P<op>' + _op + _cpv + ')|' +
- '(?P<star>=' + _cpv + r'\*)|' +
- '(?P<simple>' + _cp + '))' +
- '(' + _slot_separator + _slot + ')?' + _repo + ')(' + _use + ')?$', re.VERBOSE)
+_atom_re = {
+ "dots_disallowed_in_PN": re.compile('^(?P<without_use>(?:' +
+ '(?P<op>' + _op + _cpv['dots_disallowed_in_PN'] + ')|' +
+ '(?P<star>=' + _cpv['dots_disallowed_in_PN'] + r'\*)|' +
+ '(?P<simple>' + _cp['dots_disallowed_in_PN'] + '))' +
+ '(' + _slot_separator + _slot + ')?' + _repo + ')(' + _use + ')?$', re.VERBOSE),
+ "dots_allowed_in_PN": re.compile('^(?P<without_use>(?:' +
+ '(?P<op>' + _op + _cpv['dots_allowed_in_PN'] + ')|' +
+ '(?P<star>=' + _cpv['dots_allowed_in_PN'] + r'\*)|' +
+ '(?P<simple>' + _cp['dots_allowed_in_PN'] + '))' +
+ '(' + _slot_separator + _slot + ')?' + _repo + ')(' + _use + ')?$', re.VERBOSE),
+}
+
+def _get_atom_re(eapi):
+ if eapi is None or eapi_allows_dots_in_PN(eapi):
+ return _atom_re["dots_allowed_in_PN"]
+ else:
+ return _atom_re["dots_disallowed_in_PN"]
_extended_cat = r'[\w+*][\w+.*-]*'
-_extended_pkg = r'[\w+*][\w+*-]*?'
+_extended_pkg = {
+ "dots_disallowed_in_PN": r'[\w+*][\w+*-]*?',
+ "dots_allowed_in_PN": r'[\w+*][\w+.*-]*?',
+}
-_atom_wildcard_re = re.compile('(?P<simple>(' + _extended_cat + ')/(' + _extended_pkg + '))(:(?P<slot>' + _slot + '))?(' + _repo_separator + '(?P<repo>' + _repo_name + '))?$')
+_atom_wildcard_re = {
+ "dots_disallowed_in_PN": re.compile('(?P<simple>(' + _extended_cat + ')/(' + _extended_pkg['dots_disallowed_in_PN'] + '))(:(?P<slot>' + _slot + '))?(' + _repo_separator + '(?P<repo>' + _repo_name + '))?$'),
+ "dots_allowed_in_PN": re.compile('(?P<simple>(' + _extended_cat + ')/(' + _extended_pkg['dots_allowed_in_PN'] + '))(:(?P<slot>' + _slot + '))?(' + _repo_separator + '(?P<repo>' + _repo_name + '))?$'),
+}
+
+def _get_atom_wildcard_re(eapi):
+ if eapi is None or eapi_allows_dots_in_PN(eapi):
+ return _atom_wildcard_re["dots_allowed_in_PN"]
+ else:
+ return _atom_wildcard_re["dots_disallowed_in_PN"]
_useflag_re = {
"0": re.compile(r'^[A-Za-z0-9][A-Za-z0-9+_@-]*$'),
# versions.py -- core Portage functionality
-# Copyright 1998-2010 Gentoo Foundation
+# Copyright 1998-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
__all__ = [
portage.proxy.lazyimport.lazyimport(globals(),
'portage.util:cmp_sort_key'
)
+from portage.eapi import eapi_allows_dots_in_PN
from portage.localization import _
# \w is [a-zA-Z0-9_]
# 2.1.2 A package name may contain any of the characters [A-Za-z0-9+_-].
# It must not begin with a hyphen,
# and must not end in a hyphen followed by one or more digits.
-_pkg = r'[\w+][\w+-]*?'
+_pkg = {
+ "dots_disallowed_in_PN": r'[\w+][\w+-]*?',
+ "dots_allowed_in_PN": r'[\w+][\w+.-]*?',
+}
_v = r'(cvs\.)?(\d+)((\.\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\d*)*)'
_rev = r'\d+'
_vr = _v + '(-r(' + _rev + '))?'
-_cp = '(' + _cat + '/' + _pkg + '(-' + _vr + ')?)'
-_cpv = '(' + _cp + '-' + _vr + ')'
-_pv = '(?P<pn>' + _pkg + '(?P<pn_inval>-' + _vr + ')?)' + '-(?P<ver>' + _v + ')(-r(?P<rev>' + _rev + '))?'
+_cp = {
+ "dots_disallowed_in_PN": '(' + _cat + '/' + _pkg['dots_disallowed_in_PN'] + '(-' + _vr + ')?)',
+ "dots_allowed_in_PN": '(' + _cat + '/' + _pkg['dots_allowed_in_PN'] + '(-' + _vr + ')?)',
+}
+_cpv = {
+ "dots_disallowed_in_PN": '(' + _cp['dots_disallowed_in_PN'] + '-' + _vr + ')',
+ "dots_allowed_in_PN": '(' + _cp['dots_allowed_in_PN'] + '-' + _vr + ')',
+}
+_pv = {
+ "dots_disallowed_in_PN": '(?P<pn>' + _pkg['dots_disallowed_in_PN'] + '(?P<pn_inval>-' + _vr + ')?)' + '-(?P<ver>' + _v + ')(-r(?P<rev>' + _rev + '))?',
+ "dots_allowed_in_PN": '(?P<pn>' + _pkg['dots_allowed_in_PN'] + '(?P<pn_inval>-' + _vr + ')?)' + '-(?P<ver>' + _v + ')(-r(?P<rev>' + _rev + '))?',
+}
ver_regexp = re.compile("^" + _vr + "$")
suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$")
return None
return vercmp("-".join(pkg1[1:]), "-".join(pkg2[1:]))
-_pv_re = re.compile('^' + _pv + '$', re.VERBOSE)
+_pv_re = {
+ "dots_disallowed_in_PN": re.compile('^' + _pv['dots_disallowed_in_PN'] + '$', re.VERBOSE),
+ "dots_allowed_in_PN": re.compile('^' + _pv['dots_allowed_in_PN'] + '$', re.VERBOSE),
+}
-def _pkgsplit(mypkg):
+def _get_pv_re(eapi):
+ if eapi is None or eapi_allows_dots_in_PN(eapi):
+ return _pv_re["dots_allowed_in_PN"]
+ else:
+ return _pv_re["dots_disallowed_in_PN"]
+
+def _pkgsplit(mypkg, eapi=None):
"""
@param mypkg: pv
@return:
1. None if input is invalid.
2. (pn, ver, rev) if input is pv
"""
- m = _pv_re.match(mypkg)
+ m = _get_pv_re(eapi).match(mypkg)
if m is None:
return None
_cat_re = re.compile('^%s$' % _cat)
_missing_cat = 'null'
catcache={}
-def catpkgsplit(mydata,silent=1):
+def catpkgsplit(mydata, silent=1, eapi=None):
"""
Takes a Category/Package-Version-Rev and returns a list of each.
p_split=None
if len(mysplit)==1:
cat = _missing_cat
- p_split = _pkgsplit(mydata)
+ p_split = _pkgsplit(mydata, eapi=eapi)
elif len(mysplit)==2:
cat = mysplit[0]
if _cat_re.match(cat) is not None:
- p_split = _pkgsplit(mysplit[1])
+ p_split = _pkgsplit(mysplit[1], eapi=eapi)
if not p_split:
catcache[mydata]=None
return None
catcache[mydata]=retval
return retval
-def pkgsplit(mypkg, silent=1):
+def pkgsplit(mypkg, silent=1, eapi=None):
"""
@param mypkg: either a pv or cpv
@return:
2. (pn, ver, rev) if input is pv
3. (cp, ver, rev) if input is a cpv
"""
- catpsplit = catpkgsplit(mypkg)
+ catpsplit = catpkgsplit(mypkg, eapi=eapi)
if catpsplit is None:
return None
cat, pn, ver, rev = catpsplit
else:
return (cat + '/' + pn, ver, rev)
-def cpv_getkey(mycpv):
+def cpv_getkey(mycpv, eapi=None):
"""Calls catpkgsplit on a cpv and returns only the cp."""
- mysplit = catpkgsplit(mycpv)
+ mysplit = catpkgsplit(mycpv, eapi=eapi)
if mysplit is not None:
return mysplit[0] + '/' + mysplit[1]
DeprecationWarning, stacklevel=2)
myslash = mycpv.split("/", 1)
- mysplit = _pkgsplit(myslash[-1])
+ mysplit = _pkgsplit(myslash[-1], eapi=eapi)
if mysplit is None:
return None
mylen = len(myslash)
else:
return mysplit[0]
-def cpv_getversion(mycpv):
+def cpv_getversion(mycpv, eapi=None):
"""Returns the v (including revision) from an cpv."""
- cp = cpv_getkey(mycpv)
+ cp = cpv_getkey(mycpv, eapi=eapi)
if cp is None:
return None
return mycpv[len(cp+"-"):]
-def cpv_sort_key():
+def cpv_sort_key(eapi=None):
"""
Create an object for sorting cpvs, to be used as the 'key' parameter
in places like list.sort() or sorted(). This calls catpkgsplit() once for
split1 = split_cache.get(cpv1, False)
if split1 is False:
- split1 = catpkgsplit(cpv1)
+ split1 = catpkgsplit(cpv1, eapi=eapi)
if split1 is not None:
split1 = (split1[:2], '-'.join(split1[2:]))
split_cache[cpv1] = split1
split2 = split_cache.get(cpv2, False)
if split2 is False:
- split2 = catpkgsplit(cpv2)
+ split2 = catpkgsplit(cpv2, eapi=eapi)
if split2 is not None:
split2 = (split2[:2], '-'.join(split2[2:]))
split_cache[cpv2] = split2
def catsplit(mydep):
return mydep.split("/", 1)
-def best(mymatches):
+def best(mymatches, eapi=None):
"""Accepts None arguments; assumes matches are valid."""
if not mymatches:
return ""
if len(mymatches) == 1:
return mymatches[0]
bestmatch = mymatches[0]
- p2 = catpkgsplit(bestmatch)[1:]
+ p2 = catpkgsplit(bestmatch, eapi=eapi)[1:]
for x in mymatches[1:]:
- p1 = catpkgsplit(x)[1:]
+ p1 = catpkgsplit(x, eapi=eapi)[1:]
if pkgcmp(p1, p2) > 0:
bestmatch = x
- p2 = catpkgsplit(bestmatch)[1:]
+ p2 = catpkgsplit(bestmatch, eapi=eapi)[1:]
return bestmatch