@@ -137,6 +137,40 @@ def __init__(self, name, unit_name, unit_kind):
137
137
self .macro_name = name
138
138
self .macro_value = None
139
139
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
+
140
174
# 'Config' implements the mbed configuration mechanism
141
175
class Config :
142
176
# Libraries and applications have different names for their configuration files
@@ -184,9 +218,9 @@ def __init__(self, target, top_level_dirs = []):
184
218
self .processed_configs = {}
185
219
self .target = target if isinstance (target , basestring ) else target .name
186
220
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 }
190
224
191
225
# Add one or more configuration files
192
226
def add_config_files (self , flist ):
@@ -222,23 +256,6 @@ def _process_config_parameters(self, data, params, unit_name, unit_kind):
222
256
params [full_name ] = ConfigParameter (name , v if isinstance (v , dict ) else {"value" : v }, unit_name , unit_kind )
223
257
return params
224
258
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
-
242
259
# Helper function: process "config_parameters" and "target_config_overrides" in a given dictionary
243
260
# data: the configuration data of the library/appliation
244
261
# params: storage for the discovered configuration parameters
@@ -250,21 +267,19 @@ def _process_config_and_overrides(self, data, params, unit_name, unit_kind):
250
267
for label , overrides in data .get ("target_overrides" , {}).items ():
251
268
# If the label is defined by the target or it has the special value "*", process the overrides
252
269
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' ]
268
283
269
284
# Consider the others as overrides
270
285
for name , v in overrides .items ():
@@ -385,12 +400,20 @@ def config_to_macros(config):
385
400
def get_config_data_macros (self ):
386
401
return self .config_to_macros (self .get_config_data ())
387
402
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
+
390
408
params , _ = self .get_config_data ()
391
409
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' )
394
417
395
418
for feature in features :
396
419
if feature not in self .__allowed_features :
0 commit comments