/**@file\r
AutogenLibOrder class.\r
\r
- This class is to reorder library instance sequence according to library \r
+ This class is to reorder library instance sequence according to library\r
dependence.\r
- \r
+\r
Copyright (c) 2006, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
- \r
+\r
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
/// String[1] is libraryConstructor name, String[2] is libDestructor name.\r
///\r
private ModuleIdentification[] libInstanceList = null;\r
- \r
+\r
/**\r
Constructor function\r
- \r
+\r
This function mainly initialize some member variable.\r
- \r
+\r
@param libraryList List of the library instance.\r
@throws Exception\r
**/\r
String[] libClassDeclList = null;\r
String[] libClassConsmList = null;\r
\r
- libInstanceList = new ModuleIdentification[libraryList.length];\r
+ libInstanceList = libraryList;\r
for (int i = 0; i < libraryList.length; i++) {\r
libInstance = libraryList[i];\r
- libInstanceList[i] = libInstance;\r
//\r
- // Add libraryInstance in to libInstanceList.\r
- // \r
+ // Fetch the constructor & destructor.\r
+ //\r
Map<String, XmlObject> libDoc = GlobalData.getDoc(libInstance, arch);\r
SurfaceAreaQuery saq = new SurfaceAreaQuery(libDoc);\r
libInstance.setConstructor(saq.getLibConstructorName());\r
libInstance.setDestructor(saq.getLibDestructorName());\r
- \r
+\r
//\r
- // Add library instance and consumed library class list to\r
- // libInstanceConsumes.\r
+ // Create library class consume database.\r
//\r
- libClassConsmList = saq.getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, arch);\r
+ libClassConsmList = saq.getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, arch, null);\r
if (libClassConsmList != null) {\r
- /*\r
- String[] classStr = new String[libClassConsmList.length];\r
- for (int k = 0; k < libClassConsmList.length; k++) {\r
- classStr[k] = libClassConsmList[k];\r
- }\r
- */\r
if (this.libInstanceConsumes.containsKey(libInstance)) {\r
throw new AutoGenException(\r
libraryList[i].getName()\r
}\r
\r
//\r
- // Add library class and library instance map.\r
+ // Create library class implementer database\r
//\r
- libClassDeclList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, arch);\r
+ libClassDeclList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, arch, null);\r
if (libClassDeclList != null) {\r
this.libInstanceProduces.put(libInstance, libClassDeclList);\r
for (int j = 0; j < libClassDeclList.length; j++) {\r
}\r
}\r
\r
+ //\r
+ // Create a consumed-by database\r
+ //\r
for (Iterator it = libClassProducer.keySet().iterator(); it.hasNext();) {\r
String className = (String)it.next();\r
libInstance = libClassProducer.get(className);\r
/**\r
orderLibInstance\r
\r
- This function reorder the library instance according the library class \r
- dependency.\r
+ This function reorder the library instance according the library class\r
+ dependency, using DAG anaylysis algothim\r
\r
@return List which content the ordered library instance.\r
**/\r
LinkedList<ModuleIdentification> orderList = new LinkedList<ModuleIdentification>();\r
LinkedList<ModuleIdentification> noConsumerList = new LinkedList<ModuleIdentification>();\r
\r
+ //\r
+ // First, add the library instance without consumers to the Q\r
+ //\r
for (int i = 0; i < libInstanceList.length; ++i) {\r
if (libInstanceConsumedBy.get(libInstanceList[i]).size() == 0) {\r
noConsumerList.add(libInstanceList[i]);\r
continue;\r
}\r
HashSet<ModuleIdentification> consumedBy = libInstanceConsumedBy.get(m);\r
+ if (consumedBy.size() == 0) {\r
+ continue;\r
+ }\r
+\r
consumedBy.remove(n);\r
if (consumedBy.size() == 0) {\r
noConsumerList.addLast(m);\r
if (consumer.hasConstructor()) {\r
continue;\r
}\r
+\r
//\r
- // if there's no constructor in the library instance's consumer, \r
+ // if there's no constructor in the library instance's consumer,\r
// remove it from the consumer list\r
- // \r
+ //\r
consumedBy.remove(consumer);\r
circularlyConsumed = false;\r
if (consumedBy.size() == 0) {\r
break;\r
}\r
}\r
+\r
+ if (noConsumerList.size() == 0 && !circularlyConsumed) {\r
+ break;\r
+ }\r
}\r
}\r
\r
+ //\r
+ // Append the remaining library instance to the end of sorted list\r
+ //\r
+ boolean HasError = false;\r
for (int i = 0; i < libInstanceList.length; ++i) {\r
+ HashSet<ModuleIdentification> consumedBy = libInstanceConsumedBy.get(libInstanceList[i]);\r
+ if (consumedBy.size() > 0 && libInstanceList[i].hasConstructor()) {\r
+ EdkLog.log(EdkLog.EDK_ERROR, libInstanceList[i].getName()\r
+ + " with constructor has a circular dependency!");\r
+ ModuleIdentification[] consumedByList = consumedBy.toArray(new ModuleIdentification[consumedBy.size()]);\r
+ for (int j = 0; j < consumedByList.length; ++j) {\r
+ EdkLog.log(EdkLog.EDK_ERROR, " consumed by " + consumedByList[j].getName());\r
+ }\r
+ HasError = true;\r
+ }\r
+\r
if (!orderList.contains(libInstanceList[i])) {\r
orderList.add(libInstanceList[i]);\r
}\r
}\r
+ if (HasError) {\r
+ throw new AutoGenException("Circular dependency in library instances is found!");\r
+ }\r
+\r
return orderList;\r
}\r
}\r