/src/tools/configuration/etc/liberty_etc_cluster.e

http://github.com/tybor/Liberty · 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. --
  15. class LIBERTY_ETC_CLUSTER
  16. --
  17. -- A cluster from the master configuration, to be imported if not overridden by the local loadpath.
  18. --
  19. inherit
  20. HASHABLE
  21. redefine
  22. out_in_tagged_out_memory
  23. end
  24. insert
  25. LOGGING
  26. redefine
  27. out_in_tagged_out_memory, is_equal
  28. end
  29. create {LIBERTY_ETC_VISITOR_IMPL}
  30. make
  31. feature {ANY}
  32. name: FIXED_STRING
  33. locations: TRAVERSABLE[FIXED_STRING]
  34. version: FIXED_STRING
  35. depth: INTEGER
  36. cluster: LIBERTY_CLUSTER
  37. is_equal (other: like Current): BOOLEAN is
  38. do
  39. Result := Current = other
  40. end
  41. needs: TRAVERSABLE[LIBERTY_ETC_NEEDS] is
  42. do
  43. Result := needs_memory
  44. ensure
  45. Result /= Void
  46. end
  47. hash_code: INTEGER is
  48. do
  49. Result := name.hash_code
  50. end
  51. out_in_tagged_out_memory is
  52. local
  53. i: INTEGER
  54. do
  55. tagged_out_memory.append(once "Master cluster %"")
  56. tagged_out_memory.append(name)
  57. tagged_out_memory.extend('"')
  58. if version /= Void then
  59. tagged_out_memory.append(once " (version ")
  60. tagged_out_memory.append(version)
  61. tagged_out_memory.extend(')')
  62. end
  63. tagged_out_memory.append(once ": {")
  64. from
  65. i := locations.lower
  66. until
  67. i > locations.upper
  68. loop
  69. if i > locations.lower then
  70. tagged_out_memory.append(once ", ")
  71. end
  72. tagged_out_memory.append(locations.item(i))
  73. i := i + 1
  74. end
  75. tagged_out_memory.append(once "} (depth: ")
  76. depth.append_in(tagged_out_memory)
  77. tagged_out_memory.extend(')')
  78. end
  79. feature {LIBERTY_ETC_VISITOR_IMPL}
  80. set_version (a_version: like version) is
  81. require
  82. version = Void
  83. a_version /= Void
  84. do
  85. version := a_version
  86. ensure
  87. version = a_version
  88. end
  89. add_needs (a_needs: LIBERTY_ETC_NEEDS) is
  90. require
  91. a_needs /= Void
  92. do
  93. needs_memory.add_last(a_needs)
  94. ensure
  95. needs_memory.fast_has(a_needs)
  96. end
  97. check_validity (all_clusters: MAP[LIBERTY_ETC_CLUSTER, FIXED_STRING]) is
  98. require
  99. all_clusters /= Void
  100. do
  101. needs_memory.do_all(agent {LIBERTY_ETC_NEEDS}.check_validity(all_clusters))
  102. end
  103. check_cycles is
  104. do
  105. needs_memory.do_all(agent (n: LIBERTY_ETC_NEEDS) is do n.cluster.check_cycle(Current, n) end)
  106. end
  107. feature {LIBERTY_ETC_CLUSTER}
  108. check_cycle (a_origin: LIBERTY_ETC_CLUSTER; a_needs: LIBERTY_ETC_NEEDS) is
  109. require
  110. a_needs.cluster = Current
  111. do
  112. if find_needs_cycle(a_needs, a_origin, Current) then
  113. log.trace.put_new_line
  114. end
  115. clear_cycle_mark
  116. end
  117. find_cycle (origin, start: LIBERTY_ETC_CLUSTER): BOOLEAN is
  118. do
  119. if mark = 1 then
  120. Result := start = Current
  121. if Result then
  122. if log.is_trace then
  123. log.trace.put_string(once "Cycle in ")
  124. log.trace.put_string(origin.name)
  125. log.trace.put_string(once ": ")
  126. log.trace.put_string(name)
  127. end
  128. end
  129. else
  130. mark := 1
  131. Result := needs_memory.exists(agent find_needs_cycle(?, origin, start))
  132. if Result then
  133. if log.is_trace then
  134. log.trace.put_string(once " -> ")
  135. log.trace.put_string(name)
  136. end
  137. end
  138. end
  139. mark := 0
  140. end
  141. clear_cycle_mark is
  142. do
  143. if mark /= 0 then
  144. mark := 0
  145. needs_memory.do_all(agent clear_needs_cycle)
  146. end
  147. end
  148. feature {}
  149. find_needs_cycle (a_needs: LIBERTY_ETC_NEEDS; origin, start: LIBERTY_ETC_CLUSTER): BOOLEAN is
  150. do
  151. Result := a_needs.cluster.find_cycle(origin, start)
  152. if Result then
  153. a_needs.set_in_cycle
  154. end
  155. end
  156. clear_needs_cycle (a_needs: LIBERTY_ETC_NEEDS) is
  157. do
  158. a_needs.cluster.clear_cycle_mark
  159. end
  160. feature {LIBERTY_ETC_VISITOR_IMPL, LIBERTY_ETC_CLUSTER}
  161. fix_depth (a_mark: like mark): BOOLEAN is
  162. require
  163. a_mark >= mark
  164. do
  165. if mark < a_mark then
  166. mark := a_mark
  167. if deepen_needs then
  168. Result := fix_needs_depth
  169. end
  170. end
  171. ensure
  172. mark = a_mark
  173. end
  174. mark: INTEGER
  175. feature {}
  176. deepen_needs: BOOLEAN is
  177. local
  178. i: INTEGER; need: LIBERTY_ETC_NEEDS
  179. do
  180. from
  181. i := needs_memory.lower
  182. until
  183. i > needs_memory.upper
  184. loop
  185. need := needs_memory.item(i)
  186. if need.in_cycle then
  187. if need.cluster.depth < depth then
  188. need.cluster.set_depth(depth)
  189. Result := True
  190. end
  191. elseif need.cluster.depth <= depth then
  192. need.cluster.set_depth(depth + 1)
  193. Result := True
  194. end
  195. i := i + 1
  196. end
  197. end
  198. fix_needs_depth: BOOLEAN is
  199. local
  200. i: INTEGER
  201. do
  202. from
  203. i := needs_memory.lower
  204. until
  205. i > needs_memory.upper
  206. loop
  207. if needs_memory.item(i).cluster.fix_depth(mark) then
  208. Result := True
  209. end
  210. i := i + 1
  211. end
  212. end
  213. feature {LIBERTY_ETC_CLUSTER}
  214. set_depth (a_depth: like depth) is
  215. require
  216. a_depth > depth
  217. do
  218. if log.is_trace then
  219. log.trace.put_string(name)
  220. log.trace.put_string(once " (mark=")
  221. log.trace.put_integer(mark)
  222. log.trace.put_string(once "): depth from ")
  223. log.trace.put_integer(depth)
  224. log.trace.put_string(once " to ")
  225. log.trace.put_integer(a_depth)
  226. log.trace.put_new_line
  227. end
  228. depth := a_depth
  229. ensure
  230. depth = a_depth
  231. end
  232. feature {LIBERTY_CLUSTER}
  233. set_cluster (a_cluster: like cluster) is
  234. require
  235. cluster = Void
  236. a_cluster /= Void
  237. do
  238. cluster := a_cluster
  239. ensure
  240. cluster = a_cluster
  241. end
  242. feature {}
  243. make (a_name: like name; a_locations: like locations) is
  244. require
  245. not a_name.is_empty
  246. not a_locations.is_empty
  247. do
  248. name := a_name
  249. locations := a_locations
  250. create needs_memory.with_capacity(2)
  251. if log.is_trace then
  252. log.trace.put_string(once "Master cluster definition: ")
  253. log.trace.put_string(name)
  254. log.trace.put_string(once " -> ")
  255. log.trace.put_line(a_locations.out)
  256. end
  257. ensure
  258. name = a_name
  259. locations = a_locations
  260. end
  261. needs_memory: FAST_ARRAY[LIBERTY_ETC_NEEDS]
  262. invariant
  263. name /= Void
  264. not locations.is_empty
  265. needs_memory /= Void
  266. end -- class LIBERTY_ETC_CLUSTER