1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# Copyright: 2005 Gentoo Foundation
# Author(s): Brian Harring (ferringb@gentoo.org)
# License: GPL2
# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/restrictions/Attic/restrictionSet.py,v 1.9 2005/08/09 07:51:09 ferringb Exp $
"""
This module provides classes that can be used to combine arbitrary collections of restrictions in AND, NAND, OR, NOR, XOR, XNOR
style operations.
"""
import restriction
from itertools import imap
__all__ = ("AndRestrictionSet", "OrRestrictionSet", "XorRestrictionSet")
class RestrictionSet(restriction.base):
__slots__ = tuple(["restrictions"] + restriction.base.__slots__)
def __init__(self, *restrictions, **kwds):
"""Optionally hand in (positionally) restrictions to use as the basis of this restriction
finalize=False, set it to True to notify this instance to internally finalize itself (no way to reverse it yet)
negate=False, controls whether matching results are negated
"""
if "finalize" in kwds:
finalize = kwds["finalize"]
del kwds["finalize"]
else:
finalize = False
super(RestrictionSet, self).__init__(**kwds)
for x in restrictions:
if not isinstance(x, restriction.base):
#bad monkey.
raise TypeError, x
if finalize:
self.restrictions = tuple(restrictions)
else:
self.restrictions = list(restrictions)
def add_restriction(self, *new_restrictions, **kwds):
"""add restriction(s)
strict=True, set to false to disable isinstance checks to ensure all restrictions are restriction.base derivatives
"""
if len(new_restrictions) == 0:
raise TypeError("need at least one restriction handed in")
if kwds.get("strict", True):
for r in new_restrictions:
if not isinstance(r, restriction.base):
raise TypeError("instance '%s' isn't a restriction.base, and strict is on" % r)
self.restrictions.extend(new_restrictions)
def finalize(self):
self.restrictions = tuple(self.restrictions)
def total_len(self): return sum(imap(lambda x: x.total_len(), self.restrictions)) + 1
def __len__(self): return len(self.restrictions)
def __iter__(self): return iter(self.restrictions)
def __getitem__(self, key):
return self.restrictions[key]
def unwind_changes(pkg, pop_count, negate):
while pop_count:
pkg.pop_change()
pop_count-=1
if negate:
return pkg
return None
class AndRestrictionSet(RestrictionSet):
"""Boolean AND grouping of restrictions."""
__slots__ = tuple(RestrictionSet.__slots__)
def match(self, packagedataInstance):
for rest in self.restrictions:
if not rest.match(packagedataInstance):
return self.negate
return not self.negate
def cmatch(self, pkg):
entry_point = pkg.changes_count()
for rest in self.restrictions:
if c.match(pkg) == False:
pkg.rollback_changes(entry_point)
if self.negate: return pkg
return self.negate
# for this to be reached, things went well.
if self.negate:
pkg.rollback_changes(entry_point)
# yes, normally it's "not negate", but we no negates status already via the if
return False
return True
def __str__(self):
if self.negate: return "not ( %s )" % " && ".join(imap(str, self.restrictions))
return "( %s )" % " && ".join(imap(str, self.restrictions))
class OrRestrictionSet(RestrictionSet):
"""Boolean OR grouping of restrictions."""
__slots__ = tuple(RestrictionSet.__slots__)
def match(self, packagedataInstance):
for rest in self.restrictions:
if rest.match(packagedataInstance):
return not self.negate
return self.negate
def cmatch(self, pkg):
entry_point = pkg.changes_count()
for rest in self.restrictions:
if rest.cmatch(pkg) == True:
if self.negate:
pkg.rollback_changes(entry_point)
return not self.negate
else:
pkg.rollback_changes(entry_point)
if self.negate:
pkg.rollback_changes(entry_point)
return self.negate
def __str__(self):
if self.negate: return "not ( %s )" % " || ".join(imap(str, self.restrictions))
return "( %s )" % " || ".join(imap(str, self.restrictions))
class XorRestrictionSet(RestrictionSet):
"""Boolean XOR grouping of restrictions."""
__slots__ = tuple(RestrictionSet.__slots__)
def match(self, pkginst):
armed = False
for rest in self.restrictions:
if rest.match(pkginst):
if armed:
return self.negate
armed = True
return armed ^ self.negate
def cmatch(self, pkg):
entry_point = None
armed = False
for ret in self.restrictions:
node_entry_point = pkg.changes_count()
if rest.cmatch(pkg):
if armed:
pkg.rollback_changes(entry_point)
return self.negate
armed = True
else:
pkg.rollback_changes(node_entry_point)
if self.negate and entry_point != None:
pkg.rollback_changes(entry_point)
return armed ^ self.negate
def __str__(self):
if self.negate: return "not ( %s )" % " ^^ ".join(imap(str, self.restrictions))
return "( %s )" % " ^^ ".join(imap(str, self.restrictions))
bases = (AndRestrictionSet, OrRestrictionSet, XorRestrictionSet)
|