]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java
Modify code according suggestion from code review meeting.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / autogen / AutogenLibOrder.java
CommitLineData
878ddf1f 1/**@file\r
2 AutogenLibOrder class.\r
3\r
4 This class is to reorder library instance sequence according to library \r
5 dependence.\r
6 \r
7 Copyright (c) 2006, Intel Corporation\r
8 All rights reserved. This program and the accompanying materials\r
9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
12 \r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16 **/\r
17package org.tianocore.build.autogen;\r
18\r
19import java.util.ArrayList;\r
20import java.util.HashMap;\r
21import java.util.List;\r
22import java.util.Map;\r
a29c47e0 23\r
878ddf1f 24import org.apache.xmlbeans.XmlObject;\r
878ddf1f 25import org.tianocore.build.global.GlobalData;\r
26import org.tianocore.build.global.SurfaceAreaQuery;\r
a29c47e0 27import org.tianocore.build.id.ModuleIdentification;\r
878ddf1f 28\r
29/**\r
30 This class This class is to reorder library instance sequence according to\r
31 library dependence.\r
32**/\r
33public class AutogenLibOrder {\r
34 ///\r
35 /// The map of library class and its library instance.\r
36 ///\r
a29c47e0 37 private Map<String, ModuleIdentification> libClassMap = new HashMap<String, ModuleIdentification>();\r
878ddf1f 38\r
39 ///\r
a29c47e0 40 /// The map of library instance and its implemet libraryClass.\r
878ddf1f 41 ///\r
a29c47e0 42 private Map<ModuleIdentification, String[]> libInstanceMap = new HashMap<ModuleIdentification, String[]>();\r
878ddf1f 43\r
44 ///\r
45 /// List of library instance. It is String[3] list, String[0] is libraryName,\r
46 /// String[1] is libraryConstructor name, String[2] is libDestructor name.\r
47 ///\r
a29c47e0 48 private List<LibraryInstanceNode> libInstanceList = new ArrayList<LibraryInstanceNode>();\r
878ddf1f 49 \r
50 /**\r
51 Constructor function\r
52 \r
53 This function mainly initialize some member variable.\r
54 \r
55 @param libraryList List of the library instance.\r
56 @throws Exception\r
57 **/\r
a29c47e0 58 AutogenLibOrder(ModuleIdentification[] libraryList, String arch) throws Exception {\r
59 LibraryInstanceNode libInstanceNode;\r
60 String[] libClassDeclList = null;\r
61 String[] libClassConsmList = null;\r
878ddf1f 62 \r
a29c47e0 63 for (int i = 0; i < libraryList.length; i++) {\r
878ddf1f 64 //\r
65 // Add libraryInstance in to libInstanceList.\r
a29c47e0 66 // \r
67 Map<String, XmlObject> libDoc = GlobalData.getDoc(libraryList[i], arch);\r
878ddf1f 68 SurfaceAreaQuery.push(libDoc);\r
a29c47e0 69 libInstanceNode = new LibraryInstanceNode (libraryList[i],SurfaceAreaQuery.getLibConstructorName(), SurfaceAreaQuery.getLibDestructorName());\r
70 libInstanceList.add(libInstanceNode);\r
878ddf1f 71 \r
72 //\r
73 // Add library instance and consumed library class list to\r
74 // libInstanceMap.\r
75 //\r
76 libClassConsmList = SurfaceAreaQuery\r
cb4d97bd 77 .getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, arch);\r
878ddf1f 78 if (libClassConsmList != null) {\r
79 String[] classStr = new String[libClassConsmList.length];\r
80 for (int k = 0; k < libClassConsmList.length; k++) {\r
a29c47e0 81 classStr[k] = libClassConsmList[k];\r
878ddf1f 82 }\r
a29c47e0 83 if (this.libInstanceMap.containsKey(libraryList[i])) {\r
878ddf1f 84 throw new Exception(\r
a29c47e0 85 libraryList[i].getName()\r
391dbbb1 86 + "this library instance already exists, please check the library instance list!");\r
878ddf1f 87 } else {\r
a29c47e0 88 this.libInstanceMap.put(libraryList[i], classStr);\r
878ddf1f 89 }\r
90 }\r
91\r
92 //\r
93 // Add library class and library instance map.\r
94 //\r
95 libClassDeclList = SurfaceAreaQuery\r
cb4d97bd 96 .getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, arch);\r
878ddf1f 97 if (libClassDeclList != null) {\r
98 for (int j = 0; j < libClassDeclList.length; j++) {\r
a29c47e0 99 if (this.libClassMap.containsKey(libClassDeclList[j])) {\r
100 System.out.println(libClassDeclList[j]\r
878ddf1f 101 + " class is already implement by "\r
a29c47e0 102 + this.libClassMap.get(libClassDeclList[j]));\r
391dbbb1 103 throw new Exception("Library Class: " + libClassDeclList\r
104 + " already has a library instance!");\r
878ddf1f 105 } else {\r
a29c47e0 106 this.libClassMap.put(libClassDeclList[j], libraryList[i]);\r
878ddf1f 107 }\r
108 }\r
109 }\r
110 SurfaceAreaQuery.pop();\r
111 }\r
112\r
113 //\r
114 // Check is the library instance list meet the require;\r
115 //\r
cb4d97bd 116 //for (int s = 0; s < this.libInstanceList.size(); s++) {\r
117 // String[] libClass = this.libInstanceMap.get(this.libInstanceList\r
118 // .get(s));\r
119 // if (libClass != null) {\r
120 // for (int t = 0; t < libClass.length; t++) {\r
121 // if (this.libClassMap.get(libClass[t]) == null) {\r
878ddf1f 122 //\r
123 // Note: There exist a kind of module which depend on \r
124 // library class with no instance or whose instance will\r
125 // never be linked into the module. \r
126 // For this satuation, the module has the description of \r
127 // library class in MSA file but no description of \r
128 // corresponding library instance in MBD file. There \r
129 // will be a warnig message given here after a standard \r
130 // log way has been decided.\r
131 //\r
cb4d97bd 132 // }\r
133 // }\r
134 // }\r
135 //}\r
878ddf1f 136 }\r
137\r
138 /**\r
139 orderLibInstance\r
140 \r
141 This function reorder the library instance according the library class \r
142 dependency.\r
143 \r
144 @return List which content the ordered library instance.\r
145 **/\r
a29c47e0 146 List<ModuleIdentification> orderLibInstance() {\r
147 List<ModuleIdentification> orderList = new ArrayList<ModuleIdentification>();\r
878ddf1f 148 //\r
149 // Stack of node which track the library instance name ant its visiting\r
150 // flag.\r
151 //\r
152 List<Node> stackList = new ArrayList<Node>();\r
153 int stackSize = 0;\r
a29c47e0 154 ModuleIdentification libInstanceId = null;\r
878ddf1f 155 if (libInstanceList.size() < 0) {\r
156 return null;\r
157 }\r
158\r
159 //\r
160 // Reorder the library instance.\r
161 //\r
162 for (int i = 0; i < libInstanceList.size(); i++) {\r
163 //\r
164 // If library instance is already in the order list skip it.\r
165 //\r
a29c47e0 166 if (isInLibInstance(orderList, libInstanceList.get(i).libId)) {\r
878ddf1f 167 continue;\r
168 }\r
169 \r
a29c47e0 170 Node node = new Node(libInstanceList.get(i).libId, false);\r
878ddf1f 171 //\r
172 // Use stack to reorder library instance.\r
173 // Push node to stack.\r
174 //\r
175 stackList.add(node);\r
176 while (stackList.size() > 0) {\r
177 stackSize = stackList.size() - 1;\r
178 //\r
179 // Pop the first node in stack. If the node flag has been visited\r
180 // add this node to orderlist and remove it from stack.\r
181 //\r
182 if (stackList.get(stackSize).isVisit) {\r
183 if (!isInLibInstance(orderList,\r
a29c47e0 184 stackList.get(stackSize).nodeId)) {\r
185 orderList.add(stackList.get(stackSize).nodeId);\r
878ddf1f 186 stackList.remove(stackSize);\r
187 }\r
188 \r
189 } else {\r
190 //\r
191 // Get the node value and set visit flag as true.\r
192 //\r
193 stackList.get(stackList.size() - 1).isVisit = true;\r
194 String[] libClassList = this.libInstanceMap.get(stackList\r
a29c47e0 195 .get(stackSize).nodeId);\r
878ddf1f 196 //\r
197 // Push the node dependence library instance to the stack.\r
198 //\r
199 if (libClassList != null) {\r
200 for (int j = 0; j < libClassList.length; j++) {\r
a29c47e0 201 libInstanceId = this.libClassMap.get(libClassList[j]);\r
202 if (libInstanceId != null\r
203 && !isInLibInstance(orderList, libInstanceId)) {\r
878ddf1f 204 //\r
205 // If and only if the currently library instance\r
206 // is not in stack and it have constructor or \r
207 // destructor function, push this library \r
208 // instacne in stack.\r
209 //\r
210 if (!isInStackList(stackList, this.libClassMap\r
a29c47e0 211 .get(libClassList[j])) && isHaveConsDestructor(libInstanceId)) {\r
878ddf1f 212 stackList.add(new Node(this.libClassMap\r
213 .get(libClassList[j]), false));\r
214 }\r
215 }\r
216 }\r
217 }\r
218 }\r
219 }\r
220 }\r
221 return orderList;\r
222 }\r
223\r
224 /**\r
225 isInLibInstance\r
226 \r
227 This function check does the library instance already in the list.\r
228 \r
229 @param list List of the library instance.\r
230 @param instanceName Name of library instance.\r
231 @return "true" the library instance in list |\r
232 "false" the library instance is not in list.\r
233 **/\r
a29c47e0 234 private boolean isInLibInstance(List<ModuleIdentification> list, ModuleIdentification instanceId) {\r
878ddf1f 235 for (int i = 0; i < list.size(); i++) {\r
a29c47e0 236 \r
237 if (instanceId.equals(list.get(i))) {\r
878ddf1f 238 return true;\r
239 }\r
240 }\r
241 return false;\r
242 }\r
243\r
244 /**\r
245 isInStackList \r
246 \r
247 This function check if the node already in the stack.\r
248 \r
249 @param list Stack.\r
250 @param nodeName Name of node.\r
251 @return "true" if node have in stack |\r
252 "false" if node don't in stack.\r
253 **/ \r
a29c47e0 254 private boolean isInStackList(List<Node> list, ModuleIdentification instanceId) {\r
878ddf1f 255 for (int i = 0; i < list.size(); i++) {\r
a29c47e0 256 if (instanceId.equals(list.get(i).nodeId)) {\r
878ddf1f 257 return true;\r
258 }\r
259 }\r
260 return false;\r
261 }\r
262 \r
263 /**\r
264 isHaveConsDestructor\r
265 \r
266 This function check if the library have constructor or destructor \r
267 function.\r
268 \r
269 @param libName Name of library\r
270 @return "true" if library have constructor or desconstructor |\r
271 "false" if library don't have constructor \r
272 and desconstructor.\r
273 **/\r
a29c47e0 274 private boolean isHaveConsDestructor (ModuleIdentification libNode){\r
878ddf1f 275 for (int i = 0; i < libInstanceList.size(); i++){\r
a29c47e0 276 if (libInstanceList.get(i).libId.equals(libNode)){\r
277 if (libInstanceList.get(i).constructorName != null || libInstanceList.get(i).deconstructorName != null){\r
878ddf1f 278 return true;\r
279 }\r
280 }\r
281 }\r
282 return false;\r
283 }\r
284}\r
285\r
286/**\r
287 Node \r
288 \r
289 This class is used as stack node.\r
290 \r
291 **/\r
292class Node {\r
a29c47e0 293 ModuleIdentification nodeId;\r
878ddf1f 294\r
295 boolean isVisit;\r
296\r
a29c47e0 297 Node(ModuleIdentification nodeId, boolean isVisit) {\r
298 this.nodeId = nodeId;\r
878ddf1f 299 this.isVisit = false;\r
300 }\r
a29c47e0 301} \r
302/**\r
303 LibraryInstance Node \r
304 \r
305 This class is used to store LibrayInstance and it's deconstructor and constructor\r
306**/\r
307 \r
308class LibraryInstanceNode {\r
309 ModuleIdentification libId;\r
310 String deconstructorName;\r
311 String constructorName;\r
312 \r
313 LibraryInstanceNode (ModuleIdentification libId, String deconstructor, String constructor){\r
314 this.libId = libId;\r
315 this.deconstructorName = deconstructor;\r
316 this.constructorName = constructor;\r
317 }\r
318}\r