1## @file 2# 3# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> 4# 5# SPDX-License-Identifier: BSD-2-Clause-Patent 6# 7 8from plugins.EdkPlugins.basemodel import ini 9import re, os 10from plugins.EdkPlugins.basemodel.message import * 11 12class INFFile(ini.BaseINIFile): 13 _libobjs = {} 14 15 def GetSectionInstance(self, parent, name, isCombined=False): 16 return INFSection(parent, name, isCombined) 17 18 def GetProduceLibraryClass(self): 19 obj = self.GetDefine("LIBRARY_CLASS") 20 if obj is None: return None 21 22 return obj.split('|')[0].strip() 23 24 def GetSectionObjectsByName(self, name, arch=None): 25 arr = [] 26 sects = self.GetSectionByName(name) 27 for sect in sects: 28 # skip unmatched archtecture content 29 if not sect.IsArchMatch(arch): 30 continue 31 32 for obj in sect.GetObjects(): 33 arr.append(obj) 34 35 return arr 36 37 def GetSourceObjects(self, arch=None, tool=None): 38 arr = [] 39 sects = self.GetSectionByName('sources') 40 for sect in sects: 41 # skip unmatched archtecture content 42 if not sect.IsArchMatch(arch): 43 continue 44 45 for obj in sect.GetObjects(): 46 if not obj.IsMatchFamily(tool): 47 continue 48 arr.append(obj) 49 50 return arr 51 52 def Parse(self): 53 if not ini.BaseINIFile.Parse(self): 54 return False 55 classname = self.GetProduceLibraryClass() 56 if classname is not None: 57 libobjdict = INFFile._libobjs 58 if classname in libobjdict: 59 if self not in libobjdict[classname]: 60 libobjdict[classname].append(self) 61 else: 62 libobjdict[classname] = [self] 63 64 return True 65 66 def GetBaseName(self): 67 return self.GetDefine("BASE_NAME").strip() 68 69 def GetModuleRootPath(self): 70 return os.path.dirname(self.GetFilename()) 71 72 def Clear(self): 73 classname = self.GetProduceLibraryClass() 74 if classname is not None: 75 libobjdict = INFFile._libobjs 76 libobjdict[classname].remove(self) 77 if len(libobjdict[classname]) == 0: 78 del libobjdict[classname] 79 ini.BaseINIFile.Clear(self) 80 81 82class INFSection(ini.BaseINISection): 83 def GetSectionINIObject(self, parent): 84 type = self.GetType() 85 86 if type.lower() == 'libraryclasses': 87 return INFLibraryClassObject(self) 88 if type.lower() == 'sources': 89 return INFSourceObject(self) 90 if type.lower().find('pcd') != -1: 91 return INFPcdObject(self) 92 if type.lower() == 'packages': 93 return INFDependentPackageObject(self) 94 if type.lower() in ['guids', 'protocols', 'ppis']: 95 return INFGuidObject(self) 96 if type.lower() == 'defines': 97 return INFDefineSectionObject(self) 98 return INFSectionObject(self) 99 100 def GetType(self): 101 arr = self._name.split('.') 102 return arr[0].strip() 103 104 def GetArch(self): 105 arr = self._name.split('.') 106 if len(arr) == 1: 107 return 'common' 108 return arr[1] 109 110 def IsArchMatch(self, arch): 111 if arch is None or self.GetArch() == 'common': 112 return True 113 114 if self.GetArch().lower() != arch.lower(): 115 return False 116 117 return True 118 119class INFSectionObject(ini.BaseINISectionObject): 120 def GetArch(self): 121 return self.GetParent().GetArch() 122 123class INFDefineSectionObject(INFSectionObject): 124 def __init__(self, parent): 125 INFSectionObject.__init__(self, parent) 126 self._key = None 127 self._value = None 128 129 def Parse(self): 130 assert (self._start == self._end), 'The object in define section must be in single line' 131 132 line = self.GetLineByOffset(self._start).strip() 133 134 line = line.split('#')[0] 135 arr = line.split('=') 136 if len(arr) != 2: 137 ErrorMsg('Invalid define section object', 138 self.GetFilename(), 139 self._start 140 ) 141 return False 142 143 self._key = arr[0].strip() 144 self._value = arr[1].strip() 145 146 return True 147 148 def GetKey(self): 149 return self._key 150 151 def GetValue(self): 152 return self._value 153 154class INFLibraryClassObject(INFSectionObject): 155 _objs = {} 156 def __init__(self, parent): 157 INFSectionObject.__init__(self, parent) 158 self._classname = None 159 160 def GetClass(self): 161 return self._classname 162 163 def Parse(self): 164 self._classname = self.GetLineByOffset(self._start).split('#')[0].strip() 165 objdict = INFLibraryClassObject._objs 166 if self._classname in objdict: 167 objdict[self._classname].append(self) 168 else: 169 objdict[self._classname] = [self] 170 return True 171 172 def Destroy(self): 173 objdict = INFLibraryClassObject._objs 174 objdict[self._classname].remove(self) 175 if len(objdict[self._classname]) == 0: 176 del objdict[self._classname] 177 178 def GetName(self): 179 return self._classname 180 181 @staticmethod 182 def GetObjectDict(): 183 return INFLibraryClassObject._objs 184 185class INFDependentPackageObject(INFSectionObject): 186 def GetPath(self): 187 return self.GetLineByOffset(self._start).split('#')[0].strip() 188 189class INFSourceObject(INFSectionObject): 190 _objs = {} 191 def __init__(self, parent): 192 INFSectionObject.__init__(self, parent) 193 194 self.mSourcename = None 195 self.mToolCode = None 196 self.mFamily = None 197 self.mTagName = None 198 self.mFeaturePcd = None 199 self.mFilename = None 200 201 def GetSourcePath(self): 202 return self.mSourcename 203 204 def GetSourceFullPath(self): 205 path = os.path.dirname(self.GetFilename()) 206 path = os.path.join(path, self.GetSourcePath()) 207 return os.path.normpath(path) 208 209 def GetToolCode(self): 210 return self.mToolCode 211 212 def GetFamily(self): 213 return self.mFamily 214 215 def GetTagName(self): 216 return self.mTagName 217 218 def GetFeaturePcd(self): 219 return self.mFeaturePcd 220 221 def Parse(self): 222 line = self.GetLineByOffset(self._start).strip().split('#')[0] 223 224 arr = line.split('|') 225 226 self.mSourcename = arr[0].strip() 227 if len(arr) >= 2: 228 self.mFamily = arr[1].strip() 229 if len(arr) >= 3: 230 self.mTagName = arr[2].strip() 231 if len(arr) >= 4: 232 self.mToolCode = arr[3].strip() 233 if len(arr) >= 5: 234 self.mFeaturePcd = arr[4].strip() 235 236 self.mFilename = os.path.basename(self.GetSourceFullPath()) 237 objdict = INFSourceObject._objs 238 if self.mFilename not in objdict: 239 objdict[self.mFilename] = [self] 240 else: 241 objdict[self.mFilename].append(self) 242 243 return True 244 245 def GetName(self): 246 return self.mFilename 247 248 def Destroy(self): 249 objdict = INFSourceObject._objs 250 objdict[self.mFilename].remove(self) 251 if len(objdict[self.mFilename]) == 0: 252 del objdict[self.mFilename] 253 254 def IsMatchFamily(self, family): 255 if family is None: 256 return True 257 if self.mFamily is not None: 258 if family.strip().lower() == self.mFamily.lower(): 259 return True 260 else: 261 return False 262 else: 263 fname = self.GetSourcePath() 264 if fname.endswith('.S') and family.lower() != 'gcc': 265 return False 266 if fname.endswith('.s') and (self.GetArch().lower() != 'ipf' and self.GetArch().lower() != 'common'): 267 return False 268 if fname.lower().endswith('.asm') and (family.lower() != 'msft' and family.lower() != 'intel'): 269 return False 270 return True 271 272 @staticmethod 273 def GetObjectDict(): 274 return INFSourceObject._objs 275 276class INFPcdObject(INFSectionObject): 277 _objs = {} 278 279 def __init__(self, parent): 280 INFSectionObject.__init__(self, parent) 281 282 self.mPcdType = None 283 self.mDefaultValue = None 284 self.mPcdName = None 285 286 @staticmethod 287 def GetObjectDict(): 288 return INFPcdObject._objs 289 290 def Parse(self): 291 line = self.GetLineByOffset(self._start).strip().split('#')[0] 292 293 arr = line.split('|') 294 self.mPcdName = arr[0].strip() 295 296 if len(arr) >= 2: 297 self.mDefaultValue = arr[1].strip() 298 299 objdict = INFPcdObject._objs 300 if self.GetName() in objdict: 301 if self not in objdict[self.GetName()]: 302 objdict[self.GetName()].append(self) 303 else: 304 objdict[self.GetName()] = [self] 305 return True 306 307 def GetPcdName(self): 308 return self.mPcdName 309 310 def GetPcdType(self): 311 return self.GetParent().GetType() 312 313 def GetName(self): 314 return self.mPcdName.split('.')[1] 315 316 def Destroy(self): 317 objdict = INFPcdObject._objs 318 objdict[self.GetName()].remove(self) 319 if len(objdict[self.GetName()]) == 0: 320 del objdict[self.GetName()] 321 322class INFGuidObject(INFSectionObject): 323 def __init__(self, parent): 324 INFSectionObject.__init__(self, parent) 325 self._name = None 326 327 def Parse(self): 328 line = self.GetLineByOffset(self._start).strip().split('#')[0].split("|")[0] 329 self._name = line.strip() 330 return True 331 332 def GetName(self): 333 return self._name 334 335 336