Skip to content

Commit 0fcb20e

Browse files
committed
Generalized handling of cumulative attributes in target overrides
In tools/config.py, Config now aggregates all cumulative attributes in target overrides. { "target_overrides": { "K64F": { "target.features_add": ["UVISOR"], "target.extra_labels_add": ["UVISOR_SUPPORTED"], "target.macros_add": ["UVISOR_MACRO"], "target.device_has_add": ["UVISOR_HAS"] } } } Note: no action is performed on overrides yet
1 parent 48c1d2e commit 0fcb20e

File tree

1 file changed

+62
-39
lines changed

1 file changed

+62
-39
lines changed

tools/config.py

Lines changed: 62 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,40 @@ def __init__(self, name, unit_name, unit_kind):
137137
self.macro_name = name
138138
self.macro_value = None
139139

140+
# Representation of overrides for cumulative attributes
141+
class ConfigCumulativeOverride:
142+
def __init__(self, name, additions=set(), removals=set(), strict=False):
143+
self.name = name
144+
self.additions = set(additions)
145+
self.removals = set(removals)
146+
self.strict = strict
147+
148+
# Add attr to the cumulative override
149+
def remove_cumulative_override(self, overrides):
150+
for override in overrides:
151+
if override in self.additions:
152+
raise ConfigException("Configuration conflict. The %s %s both added and removed." % (self.name, override))
153+
154+
self.removals |= set(overrides)
155+
156+
# Remove attr from the cumulative overrides
157+
def add_cumulative_overrides(self, overrides):
158+
for override in overrides:
159+
if (override in self.removals or (self.strict and override not in self.additions)):
160+
raise ConfigException("Configuration conflict. The %s %s both added and removed." % (self.name, override))
161+
162+
self.additions |= set(overrides)
163+
164+
# Enable strict set of cumulative overrides for the specified attr
165+
def strict_cumulative_overrides(self, overrides):
166+
self.remove_cumulative_override(self.additions - set(overrides))
167+
self.add_cumulative_override(overrides)
168+
self.strict = True
169+
170+
def get_cumulative_overrides(self, target):
171+
return set(getattr(target, self.name)) | self.additions - self.removals
172+
173+
140174
# 'Config' implements the mbed configuration mechanism
141175
class Config:
142176
# Libraries and applications have different names for their configuration files
@@ -184,9 +218,9 @@ def __init__(self, target, top_level_dirs = []):
184218
self.processed_configs = {}
185219
self.target = target if isinstance(target, basestring) else target.name
186220
self.target_labels = Target.get_target(self.target).get_labels()
187-
self.added_features = set()
188-
self.removed_features = set()
189-
self.removed_unecessary_features = False
221+
222+
self.cumulative_overrides = { key: ConfigCumulativeOverride(key)
223+
for key in Target._Target__cumulative_attributes }
190224

191225
# Add one or more configuration files
192226
def add_config_files(self, flist):
@@ -222,23 +256,6 @@ def _process_config_parameters(self, data, params, unit_name, unit_kind):
222256
params[full_name] = ConfigParameter(name, v if isinstance(v, dict) else {"value": v}, unit_name, unit_kind)
223257
return params
224258

225-
# Add features to the available features
226-
def remove_features(self, features):
227-
for feature in features:
228-
if feature in self.added_features:
229-
raise ConfigException("Configuration conflict. Feature %s both added and removed." % feature)
230-
231-
self.removed_features |= set(features)
232-
233-
# Remove features from the available features
234-
def add_features(self, features):
235-
for feature in features:
236-
if (feature in self.removed_features
237-
or (self.removed_unecessary_features and feature not in self.added_features)):
238-
raise ConfigException("Configuration conflict. Feature %s both added and removed." % feature)
239-
240-
self.added_features |= set(features)
241-
242259
# Helper function: process "config_parameters" and "target_config_overrides" in a given dictionary
243260
# data: the configuration data of the library/appliation
244261
# params: storage for the discovered configuration parameters
@@ -250,21 +267,19 @@ def _process_config_and_overrides(self, data, params, unit_name, unit_kind):
250267
for label, overrides in data.get("target_overrides", {}).items():
251268
# If the label is defined by the target or it has the special value "*", process the overrides
252269
if (label == '*') or (label in self.target_labels):
253-
# Parse out features
254-
if 'target.features' in overrides:
255-
features = overrides['target.features']
256-
self.remove_features(self.added_features - set(features))
257-
self.add_features(features)
258-
self.removed_unecessary_features = True
259-
del overrides['target.features']
260-
261-
if 'target.features_add' in overrides:
262-
self.add_features(overrides['target.features_add'])
263-
del overrides['target.features_add']
264-
265-
if 'target.features_remove' in overrides:
266-
self.remove_features(overrides['target.features_remove'])
267-
del overrides['target.features_remove']
270+
# Parse out cumulative overrides
271+
for attr, cumulatives in self.cumulative_overrides.iteritems():
272+
if 'target.'+attr in overrides:
273+
cumulatives.strict_cumulative_overrides(overrides['target.'+attr])
274+
del overrides['target.'+attr]
275+
276+
if 'target.'+attr+'_add' in overrides:
277+
cumulatives.add_cumulative_overrides(overrides['target.'+attr+'_add'])
278+
del overrides['target.'+attr+'_add']
279+
280+
if 'target.'+attr+'_remove' in overrides:
281+
cumulatives.remove_cumulative_overrides(overrides['target.'+attr+'_remove'])
282+
del overrides['target.'+attr+'_remove']
268283

269284
# Consider the others as overrides
270285
for name, v in overrides.items():
@@ -385,12 +400,20 @@ def config_to_macros(config):
385400
def get_config_data_macros(self):
386401
return self.config_to_macros(self.get_config_data())
387402

388-
# Returns any features in the configuration data
389-
def get_features(self):
403+
# Returns any cumulative overrides in the configuration data
404+
def get_cumulative_overrides(self, attr):
405+
if attr not in self.cumulative_overrides:
406+
return None
407+
390408
params, _ = self.get_config_data()
391409
self._check_required_parameters(params)
392-
features = ((set(Target.get_target(self.target).features)
393-
| self.added_features) - self.removed_features)
410+
411+
return self.cumulative_overrides[attr].get_cumulative_overrides(
412+
Target.get_target(self.target))
413+
414+
# Returns any features in the configuration data
415+
def get_features(self):
416+
features = self.get_cumulative_overrides('features')
394417

395418
for feature in features:
396419
if feature not in self.__allowed_features:

0 commit comments

Comments
 (0)