1## @file
2# This file is used to define each component of Target.txt file
3#
4# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5# This program and the accompanying materials
6# are licensed and made available under the terms and conditions of the BSD License
7# which accompanies this distribution.  The full text of the license may be found at
8# http://opensource.org/licenses/bsd-license.php
9#
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12#
13
14##
15# Import Modules
16#
17import Common.LongFilePathOs as os
18import EdkLogger
19import DataType
20from BuildToolError import *
21import GlobalData
22from Common.LongFilePathSupport import OpenLongFilePath as open
23
24gDefaultTargetTxtFile = "target.txt"
25
26## TargetTxtClassObject
27#
28# This class defined content used in file target.txt
29#
30# @param object:             Inherited from object class
31# @param Filename:           Input value for full path of target.txt
32#
33# @var TargetTxtDictionary:  To store keys and values defined in target.txt
34#
35class TargetTxtClassObject(object):
36    def __init__(self, Filename = None):
37        self.TargetTxtDictionary = {
38            DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM                            : '',
39            DataType.TAB_TAT_DEFINES_ACTIVE_MODULE                              : '',
40            DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF                            : '',
41            DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER               : '',
42            DataType.TAB_TAT_DEFINES_TARGET                                     : [],
43            DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG                             : [],
44            DataType.TAB_TAT_DEFINES_TARGET_ARCH                                : [],
45            DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF                            : '',
46        }
47        self.ConfDirectoryPath = ""
48        if Filename != None:
49            self.LoadTargetTxtFile(Filename)
50
51    ## LoadTargetTxtFile
52    #
53    # Load target.txt file and parse it, return a set structure to store keys and values
54    #
55    # @param Filename:  Input value for full path of target.txt
56    #
57    # @retval set() A set structure to store keys and values
58    # @retval 1     Error happenes in parsing
59    #
60    def LoadTargetTxtFile(self, Filename):
61        if os.path.exists(Filename) and os.path.isfile(Filename):
62             return self.ConvertTextFileToDict(Filename, '#', '=')
63        else:
64            EdkLogger.error("Target.txt Parser", FILE_NOT_FOUND, ExtraData=Filename)
65            return 1
66
67    ## ConvertTextFileToDict
68    #
69    # Convert a text file to a dictionary of (name:value) pairs.
70    # The data is saved to self.TargetTxtDictionary
71    #
72    # @param FileName:             Text filename
73    # @param CommentCharacter:     Comment char, be used to ignore comment content
74    # @param KeySplitCharacter:    Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
75    #
76    # @retval 0 Convert successfully
77    # @retval 1 Open file failed
78    #
79    def ConvertTextFileToDict(self, FileName, CommentCharacter, KeySplitCharacter):
80        F = None
81        try:
82            F = open(FileName, 'r')
83            self.ConfDirectoryPath = os.path.dirname(FileName)
84        except:
85            EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=FileName)
86            if F != None:
87                F.close()
88
89        for Line in F:
90            Line = Line.strip()
91            if Line.startswith(CommentCharacter) or Line == '':
92                continue
93
94            LineList = Line.split(KeySplitCharacter, 1)
95            Key = LineList[0].strip()
96            if len(LineList) == 2:
97                Value = LineList[1].strip()
98            else:
99                Value = ""
100
101            if Key in [DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM, DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF, \
102                       DataType.TAB_TAT_DEFINES_ACTIVE_MODULE, DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]:
103                self.TargetTxtDictionary[Key] = Value.replace('\\', '/')
104                if Key == DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF and self.TargetTxtDictionary[Key]:
105                    if self.TargetTxtDictionary[Key].startswith("Conf/"):
106                        Tools_Def = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].strip())
107                        if not os.path.exists(Tools_Def) or not os.path.isfile(Tools_Def):
108                            # If Conf/Conf does not exist, try just the Conf/ directory
109                            Tools_Def = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].replace("Conf/", "", 1).strip())
110                    else:
111                        # The File pointed to by TOOL_CHAIN_CONF is not in a Conf/ directory
112                        Tools_Def = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].strip())
113                    self.TargetTxtDictionary[Key] = Tools_Def
114                if Key == DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF and self.TargetTxtDictionary[Key]:
115                    if self.TargetTxtDictionary[Key].startswith("Conf/"):
116                        Build_Rule = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].strip())
117                        if not os.path.exists(Build_Rule) or not os.path.isfile(Build_Rule):
118                            # If Conf/Conf does not exist, try just the Conf/ directory
119                            Build_Rule = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].replace("Conf/", "", 1).strip())
120                    else:
121                        # The File pointed to by BUILD_RULE_CONF is not in a Conf/ directory
122                        Build_Rule = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].strip())
123                    self.TargetTxtDictionary[Key] = Build_Rule
124            elif Key in [DataType.TAB_TAT_DEFINES_TARGET, DataType.TAB_TAT_DEFINES_TARGET_ARCH, \
125                         DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]:
126                self.TargetTxtDictionary[Key] = Value.split()
127            elif Key == DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER:
128                try:
129                    V = int(Value, 0)
130                except:
131                    EdkLogger.error("build", FORMAT_INVALID, "Invalid number of [%s]: %s." % (Key, Value),
132                                    File=FileName)
133                self.TargetTxtDictionary[Key] = Value
134            #elif Key not in GlobalData.gGlobalDefines:
135            #    GlobalData.gGlobalDefines[Key] = Value
136
137        F.close()
138        return 0
139
140    ## Print the dictionary
141    #
142    # Print all items of dictionary one by one
143    #
144    # @param Dict:  The dictionary to be printed
145    #
146    def printDict(Dict):
147        if Dict != None:
148            KeyList = Dict.keys()
149            for Key in KeyList:
150                if Dict[Key] != '':
151                    print Key + ' = ' + str(Dict[Key])
152
153    ## Print the dictionary
154    #
155    # Print the items of dictionary which matched with input key
156    #
157    # @param list:  The dictionary to be printed
158    # @param key:   The key of the item to be printed
159    #
160    def printList(Key, List):
161        if type(List) == type([]):
162            if len(List) > 0:
163                if Key.find(TAB_SPLIT) != -1:
164                    print "\n" + Key
165                    for Item in List:
166                        print Item
167## TargetTxtDict
168#
169# Load target.txt in input Conf dir
170#
171# @param ConfDir:  Conf dir
172#
173# @retval Target An instance of TargetTxtClassObject() with loaded target.txt
174#
175def TargetTxtDict(ConfDir):
176    Target = TargetTxtClassObject()
177    Target.LoadTargetTxtFile(os.path.normpath(os.path.join(ConfDir, gDefaultTargetTxtFile)))
178    return Target
179
180##
181#
182# This acts like the main() function for the script, unless it is 'import'ed into another
183# script.
184#
185if __name__ == '__main__':
186    pass
187    Target = TargetTxtDict(os.getenv("WORKSPACE"))
188    print Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER]
189    print Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TARGET]
190    print Target.TargetTxtDictionary
191