OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 2 |
| 3 # Copyright 2014 Google Inc. |
| 4 # |
| 5 # Use of this source code is governed by a BSD-style license that can be |
| 6 # found in the LICENSE file. |
| 7 |
| 8 import collections |
| 9 import types |
| 10 |
| 11 class OrderedSet(object): |
| 12 """ |
| 13 Ordered set of unique items that supports addition and removal. |
| 14 """ |
| 15 |
| 16 def __init__(self): |
| 17 self.__li = [] |
| 18 |
| 19 def add(self, item): |
| 20 """ |
| 21 Add item, if it is not already in the set. |
| 22 @param item The item to add. |
| 23 """ |
| 24 if item not in self.__li: |
| 25 self.__li.append(item) |
| 26 |
| 27 def __contains__(self, item): |
| 28 """ |
| 29 Whether the set contains item. |
| 30 @param item The item to search for in the set. |
| 31 @return bool Whether the item is in the set. |
| 32 """ |
| 33 return item in self.__li |
| 34 |
| 35 def __iter__(self): |
| 36 """ |
| 37 Iterator for the set. |
| 38 """ |
| 39 return self.__li.__iter__() |
| 40 |
| 41 def remove(self, item): |
| 42 """ |
| 43 Remove item from the set. |
| 44 @param item Item to be removed. |
| 45 """ |
| 46 return self.__li.remove(item) |
| 47 |
| 48 def __len__(self): |
| 49 """ |
| 50 Number of items in the set. |
| 51 """ |
| 52 return len(self.__li) |
| 53 |
| 54 def __getitem__(self, index): |
| 55 """ |
| 56 Return item at index. |
| 57 """ |
| 58 return self.__li[index] |
| 59 |
| 60 VAR_NAMES = ['LOCAL_CFLAGS', |
| 61 'LOCAL_CPPFLAGS', |
| 62 'LOCAL_SRC_FILES', |
| 63 'LOCAL_SHARED_LIBRARIES', |
| 64 'LOCAL_STATIC_LIBRARIES', |
| 65 'LOCAL_C_INCLUDES', |
| 66 'LOCAL_EXPORT_C_INCLUDE_DIRS', |
| 67 'KNOWN_TARGETS'] |
| 68 |
| 69 class VarsDict(collections.namedtuple('VarsDict', VAR_NAMES)): |
| 70 """ |
| 71 Custom class for storing the arguments to Android.mk variables. Can be |
| 72 treated as a dictionary with fixed keys. |
| 73 """ |
| 74 |
| 75 __slots__ = () |
| 76 |
| 77 def __new__(cls): |
| 78 lists = [] |
| 79 # TODO (scroggo): Is there a better way add N items? |
| 80 for __unused__ in range(len(VAR_NAMES)): |
| 81 lists.append(OrderedSet()) |
| 82 return tuple.__new__(cls, lists) |
| 83 |
| 84 def keys(self): |
| 85 """ |
| 86 Return the field names as strings. |
| 87 """ |
| 88 return self._fields |
| 89 |
| 90 def __getitem__(self, index): |
| 91 """ |
| 92 Return an item, indexed by a number or a string. |
| 93 """ |
| 94 if type(index) == types.IntType: |
| 95 # Treat the index as an array index into a tuple. |
| 96 return tuple.__getitem__(self, index) |
| 97 if type(index) == types.StringType: |
| 98 # Treat the index as a key into a dictionary. |
| 99 return eval('self.%s' % index) |
| 100 return None |
| 101 |
| 102 |
| 103 def intersect(var_dict_list): |
| 104 """ |
| 105 Find the intersection of a list of VarsDicts and trim each input to its |
| 106 unique entries. |
| 107 @param var_dict_list list of VarsDicts. WARNING: each VarsDict will be |
| 108 modified in place, to remove the common elements! |
| 109 @return VarsDict containing list entries common to all VarsDicts in |
| 110 var_dict_list |
| 111 """ |
| 112 intersection = VarsDict() |
| 113 # First VarsDict |
| 114 var_dict_a = var_dict_list[0] |
| 115 # The rest. |
| 116 other_var_dicts = var_dict_list[1:] |
| 117 |
| 118 for key in var_dict_a.keys(): |
| 119 # Copy A's list, so we can continue iterating after modifying the original. |
| 120 a_list = list(var_dict_a[key]) |
| 121 for item in a_list: |
| 122 # If item is in all lists, add to intersection, and remove from all. |
| 123 in_all_lists = True |
| 124 for var_dict in other_var_dicts: |
| 125 if not item in var_dict[key]: |
| 126 in_all_lists = False |
| 127 break |
| 128 if in_all_lists: |
| 129 intersection[key].add(item) |
| 130 for var_dict in var_dict_list: |
| 131 var_dict[key].remove(item) |
| 132 return intersection |
| 133 |
OLD | NEW |