**/\r
package org.tianocore.build.toolchain;\r
\r
+import org.tianocore.build.exception.GenBuildException;\r
+\r
import java.io.BufferedReader;\r
import java.io.File;\r
import java.io.FileReader;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.Vector;\r
-\r
-import org.apache.tools.ant.BuildException;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
\r
/**\r
\r
**/\r
public class ConfigReader {\r
\r
- private static String confPath = ".";\r
-\r
- /**\r
- Public construct method. \r
- **/\r
- public ConfigReader () {\r
- }\r
-\r
/**\r
- Default filepath is ".".\r
+ Parse specified tool chain definition file.\r
\r
- @param filename the config file name like "target.txt"\r
- @return the variables defined in file\r
+ @param filename The config file name with full path\r
+\r
+ @return String[][] The definition array\r
**/\r
- public static synchronized String[][] parse(String filename) {\r
- return parse(confPath, filename);\r
+ public static synchronized String[][] parse(String filename) throws GenBuildException {\r
+ return parse(new File(filename));\r
}\r
\r
/**\r
- Get all variables defined in config file. the config file format is flat\r
+ Get all definitions in config file. the config file format is flat\r
with "A=B". If line started with '#' looks as comments. \r
\r
- @param confPath the path of config file\r
- @param filename the file name of the config file\r
- @return the variables defined in the config file\r
- @throws BuildException\r
- Config file's format is not valid\r
+ @param configFile The config file\r
+\r
+ @return String[][] The variables defined in the config file\r
+\r
+ @throws EdkException\r
+ Config file's format is not valid\r
**/\r
- public static synchronized String[][] parse(String confPath, String filename) throws BuildException {\r
+ public static synchronized String[][] parse(File configFile) throws GenBuildException {\r
+ List<String> keyList = new ArrayList<String>(256);\r
+ List<String> valueList = new ArrayList<String>(256);\r
+ int lines = 0;\r
+\r
try {\r
- Map<String, String> map = new HashMap<String, String>(20);\r
- File file = new File(confPath + File.separatorChar + filename);\r
- FileReader reader = new FileReader(file);\r
+ FileReader reader = new FileReader(configFile);\r
BufferedReader in = new BufferedReader(reader);\r
String str;\r
+\r
while ((str = in.readLine()) != null) {\r
+ ++lines;\r
str = str.trim();\r
//\r
- // if str is empty line or comments (start with '#')\r
+ // skip empty line, comment (start with '#') \r
//\r
- if (str.equalsIgnoreCase("") || str.startsWith("#")) {\r
+ if (str.length() == 0 || str.startsWith("#")) {\r
continue;\r
}\r
+\r
//\r
- // if str without '=' or start with '='\r
- //\r
- if (str.indexOf('=') <= 0) {\r
- continue;\r
+ // stop if the definition line is not in "name=value" form\r
+ // \r
+ int index;\r
+ if ((index = str.indexOf('=')) <= 0) {\r
+ throw new GenBuildException("ERROR Processing file [" + configFile.getAbsolutePath() \r
+ + "] (line " + lines + ").\n");\r
}\r
+\r
//\r
// look as line "A = B"\r
//\r
- int index = str.indexOf('=');\r
- String key = str.substring(0, index).trim();\r
- String value = str.substring(index + 1).trim();\r
- //\r
- // if key is existed, then update\r
- //\r
- if (map.containsKey(key)) {\r
- map.remove(key);\r
- }\r
- map.put(key, value);\r
- }\r
- Set keyset = map.keySet();\r
- Iterator iter = keyset.iterator();\r
- String[][] result = new String[map.size()][2];\r
- int i = 0;\r
- while (iter.hasNext()) {\r
- String key = (String) iter.next();\r
- result[i][0] = key;\r
- result[i++][1] = (String) map.get(key);\r
+ keyList.add(str.substring(0, index).trim());\r
+ valueList.add(str.substring(index + 1).trim());\r
}\r
- return result;\r
} catch (Exception e) {\r
- throw new BuildException("Processor file [" + filename + "] error. \n" + e.getMessage());\r
+ throw new GenBuildException("ERROR Processing file [" + configFile.getAbsolutePath() \r
+ + "] (line " + lines + ").\n" + e.getMessage());\r
}\r
- }\r
\r
- /**\r
- Parse global flags table. The format is like such(global flag name, value, \r
- vendor_arch_cmd, [add flags], [sub flags]): \r
- \r
- <pre>\r
- # EFI_DEBUG\r
- EFI_DEBUG YES MSFT_IA32_ASM ADD.["/Zi", "/DEBUG"]\r
- EFI_DEBUG YES MSFT_IA32_CC ADD.["/Zi", "/Gm", "/D EFI_DEBUG"] SUB.["/nologo", "/WX"]\r
- EFI_DEBUG YES MSFT_IA32_LINK ADD.["/DEBUG"]\r
- EFI_DEBUG YES MSFT_NT32_CC ADD.["/DEBUG"]\r
- </pre>\r
- \r
- @param confPath the file path of config file\r
- @param filename the file name of config file\r
- @return the value list\r
- @throws BuildException\r
- Config file is not valid\r
- **/\r
- public static synchronized String[][] parseTable(String confPath,\r
- String filename) throws BuildException {\r
- try {\r
- Vector<String[]> vector = new Vector<String[]>(20);\r
- File file = new File(confPath + File.separatorChar + filename);\r
- FileReader reader = new FileReader(file);\r
- BufferedReader in = new BufferedReader(reader);\r
- String str;\r
- while ((str = in.readLine()) != null) {\r
- str = str.trim();\r
- //\r
- // if str is empty line or comments (start with '#')\r
- //\r
- if (str.equalsIgnoreCase("") || str.startsWith("#")) {\r
- continue;\r
- }\r
- String[] item = new String[5];\r
- for(int i=0; i < item.length; i++){\r
- item[i] = "";\r
- }\r
- //\r
- // EFI_DEBUG YES MSFT_IA32_ASM ADD.["/Zi", "/DEBUG"]\r
- // FLAGS: EFI_DEBUG\r
- //\r
- int index = str.indexOf(" ");\r
- item[0] = str.substring(0, index);\r
- str = str.substring(index + 1).trim();\r
- //\r
- // Setting: YES\r
- //\r
- index = str.indexOf(" ");\r
- item[1] = str.substring(0, index);\r
- str = str.substring(index + 1).trim();\r
- //\r
- // Vendor_Arch_Commandtype: MSFT_IA32_ASM\r
- //\r
- index = str.indexOf(" ");\r
- item[2] = str.substring(0, index);\r
- str = str.substring(index + 1).trim();\r
- //\r
- // Add or/and Sub\r
- //\r
- if (str.startsWith("ADD.")) {\r
- index = str.indexOf("]");\r
- if ( index > 0){\r
- item[3] = str.substring(5, index);\r
- str = str.substring(index + 1).trim();\r
- }\r
- }\r
- else if(str.startsWith("SUB.")){\r
- index = str.indexOf("]");\r
- if ( index > 0){\r
- item[4] = str.substring(5, index);\r
- str = str.substring(index + 1).trim();\r
- }\r
- }\r
- else {\r
- throw new BuildException("File [" + filename + "] never conform to Global Flags Table format.");\r
- }\r
- \r
- if (str.startsWith("ADD.")) {\r
- index = str.indexOf("]");\r
- if ( index > 0){\r
- item[3] = str.substring(5, index);\r
- str = str.substring(index + 1).trim();\r
- }\r
- }\r
- else if(str.startsWith("SUB.")){\r
- index = str.indexOf("]");\r
- if ( index > 0){\r
- item[4] = str.substring(5, index);\r
- str = str.substring(index + 1).trim();\r
- }\r
- }\r
- vector.addElement(item);\r
- }\r
- String[][] result = new String[vector.size()][5];\r
- for(int i=0; i < vector.size(); i++){\r
- result[i] = (String[])vector.get(i);\r
- }\r
- return result;\r
- } catch (Exception e) {\r
- throw new BuildException("Processor file [" + filename + "] error. \n" + e.getMessage());\r
- }\r
+ String[][] definitions = new String[2][keyList.size()];\r
+ definitions[0] = (String[])keyList.toArray(definitions[0]);\r
+ definitions[1] = (String[])valueList.toArray(definitions[1]);\r
+\r
+ return definitions;\r
}\r
}\r
+\r
+\r