/src/tools/configuration/etc/liberty_etc_cluster.e
Specman e | 293 lines | 249 code | 27 blank | 17 comment | 17 complexity | e9d6fa83141a9917e82452c19f9abb48 MD5 | raw file
1-- This file is part of Liberty Eiffel. 2-- 3-- Liberty Eiffel is free software: you can redistribute it and/or modify 4-- it under the terms of the GNU General Public License as published by 5-- the Free Software Foundation, version 3 of the License. 6-- 7-- Liberty Eiffel is distributed in the hope that it will be useful, 8-- but WITHOUT ANY WARRANTY; without even the implied warranty of 9-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10-- GNU General Public License for more details. 11-- 12-- You should have received a copy of the GNU General Public License 13-- along with Liberty Eiffel. If not, see <http://www.gnu.org/licenses/>. 14-- 15class LIBERTY_ETC_CLUSTER 16 -- 17 -- A cluster from the master configuration, to be imported if not overridden by the local loadpath. 18 -- 19 20inherit 21 HASHABLE 22 redefine 23 out_in_tagged_out_memory 24 end 25 26insert 27 LOGGING 28 redefine 29 out_in_tagged_out_memory, is_equal 30 end 31 32create {LIBERTY_ETC_VISITOR_IMPL} 33 make 34 35feature {ANY} 36 name: FIXED_STRING 37 locations: TRAVERSABLE[FIXED_STRING] 38 version: FIXED_STRING 39 depth: INTEGER 40 cluster: LIBERTY_CLUSTER 41 42 is_equal (other: like Current): BOOLEAN is 43 do 44 Result := Current = other 45 end 46 47 needs: TRAVERSABLE[LIBERTY_ETC_NEEDS] is 48 do 49 Result := needs_memory 50 ensure 51 Result /= Void 52 end 53 54 hash_code: INTEGER is 55 do 56 Result := name.hash_code 57 end 58 59 out_in_tagged_out_memory is 60 local 61 i: INTEGER 62 do 63 tagged_out_memory.append(once "Master cluster %"") 64 tagged_out_memory.append(name) 65 tagged_out_memory.extend('"') 66 if version /= Void then 67 tagged_out_memory.append(once " (version ") 68 tagged_out_memory.append(version) 69 tagged_out_memory.extend(')') 70 end 71 tagged_out_memory.append(once ": {") 72 from 73 i := locations.lower 74 until 75 i > locations.upper 76 loop 77 if i > locations.lower then 78 tagged_out_memory.append(once ", ") 79 end 80 tagged_out_memory.append(locations.item(i)) 81 i := i + 1 82 end 83 tagged_out_memory.append(once "} (depth: ") 84 depth.append_in(tagged_out_memory) 85 tagged_out_memory.extend(')') 86 end 87 88feature {LIBERTY_ETC_VISITOR_IMPL} 89 set_version (a_version: like version) is 90 require 91 version = Void 92 a_version /= Void 93 do 94 version := a_version 95 ensure 96 version = a_version 97 end 98 99 add_needs (a_needs: LIBERTY_ETC_NEEDS) is 100 require 101 a_needs /= Void 102 do 103 needs_memory.add_last(a_needs) 104 ensure 105 needs_memory.fast_has(a_needs) 106 end 107 108 check_validity (all_clusters: MAP[LIBERTY_ETC_CLUSTER, FIXED_STRING]) is 109 require 110 all_clusters /= Void 111 do 112 needs_memory.do_all(agent {LIBERTY_ETC_NEEDS}.check_validity(all_clusters)) 113 end 114 115 check_cycles is 116 do 117 needs_memory.do_all(agent (n: LIBERTY_ETC_NEEDS) is do n.cluster.check_cycle(Current, n) end) 118 end 119 120feature {LIBERTY_ETC_CLUSTER} 121 check_cycle (a_origin: LIBERTY_ETC_CLUSTER; a_needs: LIBERTY_ETC_NEEDS) is 122 require 123 a_needs.cluster = Current 124 do 125 if find_needs_cycle(a_needs, a_origin, Current) then 126 log.trace.put_new_line 127 end 128 clear_cycle_mark 129 end 130 131 find_cycle (origin, start: LIBERTY_ETC_CLUSTER): BOOLEAN is 132 do 133 if mark = 1 then 134 Result := start = Current 135 if Result then 136 if log.is_trace then 137 log.trace.put_string(once "Cycle in ") 138 log.trace.put_string(origin.name) 139 log.trace.put_string(once ": ") 140 log.trace.put_string(name) 141 end 142 end 143 else 144 mark := 1 145 Result := needs_memory.exists(agent find_needs_cycle(?, origin, start)) 146 if Result then 147 if log.is_trace then 148 log.trace.put_string(once " -> ") 149 log.trace.put_string(name) 150 end 151 end 152 end 153 mark := 0 154 end 155 156 clear_cycle_mark is 157 do 158 if mark /= 0 then 159 mark := 0 160 needs_memory.do_all(agent clear_needs_cycle) 161 end 162 end 163 164feature {} 165 find_needs_cycle (a_needs: LIBERTY_ETC_NEEDS; origin, start: LIBERTY_ETC_CLUSTER): BOOLEAN is 166 do 167 Result := a_needs.cluster.find_cycle(origin, start) 168 if Result then 169 a_needs.set_in_cycle 170 end 171 end 172 173 clear_needs_cycle (a_needs: LIBERTY_ETC_NEEDS) is 174 do 175 a_needs.cluster.clear_cycle_mark 176 end 177 178feature {LIBERTY_ETC_VISITOR_IMPL, LIBERTY_ETC_CLUSTER} 179 fix_depth (a_mark: like mark): BOOLEAN is 180 require 181 a_mark >= mark 182 do 183 if mark < a_mark then 184 mark := a_mark 185 if deepen_needs then 186 Result := fix_needs_depth 187 end 188 end 189 ensure 190 mark = a_mark 191 end 192 193 mark: INTEGER 194 195feature {} 196 deepen_needs: BOOLEAN is 197 local 198 i: INTEGER; need: LIBERTY_ETC_NEEDS 199 do 200 from 201 i := needs_memory.lower 202 until 203 i > needs_memory.upper 204 loop 205 need := needs_memory.item(i) 206 if need.in_cycle then 207 if need.cluster.depth < depth then 208 need.cluster.set_depth(depth) 209 Result := True 210 end 211 elseif need.cluster.depth <= depth then 212 need.cluster.set_depth(depth + 1) 213 Result := True 214 end 215 i := i + 1 216 end 217 end 218 219 fix_needs_depth: BOOLEAN is 220 local 221 i: INTEGER 222 do 223 from 224 i := needs_memory.lower 225 until 226 i > needs_memory.upper 227 loop 228 if needs_memory.item(i).cluster.fix_depth(mark) then 229 Result := True 230 end 231 i := i + 1 232 end 233 end 234 235feature {LIBERTY_ETC_CLUSTER} 236 set_depth (a_depth: like depth) is 237 require 238 a_depth > depth 239 do 240 if log.is_trace then 241 log.trace.put_string(name) 242 log.trace.put_string(once " (mark=") 243 log.trace.put_integer(mark) 244 log.trace.put_string(once "): depth from ") 245 log.trace.put_integer(depth) 246 log.trace.put_string(once " to ") 247 log.trace.put_integer(a_depth) 248 log.trace.put_new_line 249 end 250 depth := a_depth 251 ensure 252 depth = a_depth 253 end 254 255feature {LIBERTY_CLUSTER} 256 set_cluster (a_cluster: like cluster) is 257 require 258 cluster = Void 259 a_cluster /= Void 260 do 261 cluster := a_cluster 262 ensure 263 cluster = a_cluster 264 end 265 266feature {} 267 make (a_name: like name; a_locations: like locations) is 268 require 269 not a_name.is_empty 270 not a_locations.is_empty 271 do 272 name := a_name 273 locations := a_locations 274 create needs_memory.with_capacity(2) 275 if log.is_trace then 276 log.trace.put_string(once "Master cluster definition: ") 277 log.trace.put_string(name) 278 log.trace.put_string(once " -> ") 279 log.trace.put_line(a_locations.out) 280 end 281 ensure 282 name = a_name 283 locations = a_locations 284 end 285 286 needs_memory: FAST_ARRAY[LIBERTY_ETC_NEEDS] 287 288invariant 289 name /= Void 290 not locations.is_empty 291 needs_memory /= Void 292 293end -- class LIBERTY_ETC_CLUSTER