2 # Common routines used by all tools
4 # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
6 # This program and the accompanying materials are licensed and made available
7 # under the terms and conditions of the BSD License which accompanies this
8 # distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 from os
import makedirs
28 from os
import listdir
31 from os
import linesep
33 from os
import environ
35 from UserDict
import IterableUserDict
37 import Logger
.Log
as Logger
38 from Logger
import StringTable
as ST
39 from Logger
import ToolError
40 from Library
import GlobalData
41 from Library
.DataType
import SUP_MODULE_LIST
42 from Library
.DataType
import END_OF_LINE
43 from Library
.DataType
import TAB_SPLIT
44 from Library
.DataType
import LANGUAGE_EN_US
45 from Library
.String
import GetSplitValueList
46 from Library
.ParserValidate
import IsValidHexVersion
47 from Library
.ParserValidate
import IsValidPath
48 from Object
.POM
.CommonObject
import TextObject
50 ## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C
53 # @param Guid: The GUID string
55 def GuidStringToGuidStructureString(Guid
):
56 GuidList
= Guid
.split('-')
58 for Index
in range(0, 3, 1):
59 Result
= Result
+ '0x' + GuidList
[Index
] + ', '
60 Result
= Result
+ '{0x' + GuidList
[3][0:2] + ', 0x' + GuidList
[3][2:4]
61 for Index
in range(0, 12, 2):
62 Result
= Result
+ ', 0x' + GuidList
[4][Index
:Index
+ 2]
66 ## Check whether GUID string is of format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
68 # @param GuidValue: The GUID value
70 def CheckGuidRegFormat(GuidValue
):
71 ## Regular expression used to find out register format of GUID
73 RegFormatGuidPattern
= re
.compile("^\s*([0-9a-fA-F]){8}-"
77 "([0-9a-fA-F]){12}\s*$")
79 if RegFormatGuidPattern
.match(GuidValue
):
85 ## Convert GUID string in C structure style to
86 # xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
88 # @param GuidValue: The GUID value in C structure format
90 def GuidStructureStringToGuidString(GuidValue
):
91 GuidValueString
= GuidValue
.lower().replace("{", "").replace("}", "").\
92 replace(" ", "").replace(";", "")
93 GuidValueList
= GuidValueString
.split(",")
94 if len(GuidValueList
) != 11:
97 return "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (
98 int(GuidValueList
[0], 16),
99 int(GuidValueList
[1], 16),
100 int(GuidValueList
[2], 16),
101 int(GuidValueList
[3], 16),
102 int(GuidValueList
[4], 16),
103 int(GuidValueList
[5], 16),
104 int(GuidValueList
[6], 16),
105 int(GuidValueList
[7], 16),
106 int(GuidValueList
[8], 16),
107 int(GuidValueList
[9], 16),
108 int(GuidValueList
[10], 16)
110 except BaseException
:
113 ## Create directories
115 # @param Directory: The directory name
117 def CreateDirectory(Directory
):
118 if Directory
== None or Directory
.strip() == "":
121 if not access(Directory
, F_OK
):
123 except BaseException
:
127 ## Remove directories, including files and sub-directories in it
129 # @param Directory: The directory name
131 def RemoveDirectory(Directory
, Recursively
=False):
132 if Directory
== None or Directory
.strip() == "" or not \
133 os
.path
.exists(Directory
):
136 CurrentDirectory
= getcwd()
138 for File
in listdir("."):
139 if os
.path
.isdir(File
):
140 RemoveDirectory(File
, Recursively
)
143 chdir(CurrentDirectory
)
146 ## Store content in file
148 # This method is used to save file only when its content is changed. This is
149 # quite useful for "make" system to decide what will be re-built and what
152 # @param File: The path of file
153 # @param Content: The new content of the file
154 # @param IsBinaryFile: The flag indicating if the file is binary file
157 def SaveFileOnChange(File
, Content
, IsBinaryFile
=True):
159 Content
= Content
.replace("\n", linesep
)
161 if os
.path
.exists(File
):
163 if Content
== open(File
, "rb").read():
165 except BaseException
:
166 Logger
.Error(None, ToolError
.FILE_OPEN_FAILURE
, ExtraData
=File
)
168 CreateDirectory(os
.path
.dirname(File
))
170 FileFd
= open(File
, "wb")
171 FileFd
.write(Content
)
173 except BaseException
:
174 Logger
.Error(None, ToolError
.FILE_CREATE_FAILURE
, ExtraData
=File
)
178 ## Get all files of a directory
180 # @param Root: Root dir
181 # @param SkipList : The files need be skipped
183 def GetFiles(Root
, SkipList
=None, FullPath
=True):
184 OriPath
= os
.path
.normpath(Root
)
186 for Root
, Dirs
, Files
in walk(Root
):
188 for Item
in SkipList
:
192 if Dir
.startswith('.'):
196 if File
.startswith('.'):
198 File
= os
.path
.normpath(os
.path
.join(Root
, File
))
200 File
= File
[len(OriPath
) + 1:]
201 FileList
.append(File
)
205 ## Get all non-metadata files of a directory
207 # @param Root: Root Dir
208 # @param SkipList : List of path need be skipped
209 # @param FullPath: True if the returned file should be full path
210 # @param PrefixPath: the path that need to be added to the files found
211 # @return: the list of files found
213 def GetNonMetaDataFiles(Root
, SkipList
, FullPath
, PrefixPath
):
214 FileList
= GetFiles(Root
, SkipList
, FullPath
)
216 for File
in FileList
:
217 ExtName
= os
.path
.splitext(File
)[1]
219 # skip '.dec', '.inf', '.dsc', '.fdf' files
221 if ExtName
.lower() not in ['.dec', '.inf', '.dsc', '.fdf']:
222 NewFileList
.append(os
.path
.normpath(os
.path
.join(PrefixPath
, File
)))
226 ## Check if given file exists or not
228 # @param File: File name or path to be checked
229 # @param Dir: The directory the file is relative to
231 def ValidFile(File
, Ext
=None):
232 File
= File
.replace('\\', '/')
234 FileExt
= os
.path
.splitext(File
)[1]
235 if FileExt
.lower() != Ext
.lower():
237 if not os
.path
.exists(File
):
243 # @param File: File name or path to be checked
244 # @param Dir: The directory the file is relative to
245 # @param OverrideDir: The override directory
247 def RealPath(File
, Dir
='', OverrideDir
=''):
248 NewFile
= os
.path
.normpath(os
.path
.join(Dir
, File
))
249 NewFile
= GlobalData
.gALL_FILES
[NewFile
]
250 if not NewFile
and OverrideDir
:
251 NewFile
= os
.path
.normpath(os
.path
.join(OverrideDir
, File
))
252 NewFile
= GlobalData
.gALL_FILES
[NewFile
]
257 # @param File: File name or path to be checked
258 # @param Dir: The directory the file is relative to
259 # @param OverrideDir: The override directory
261 def RealPath2(File
, Dir
='', OverrideDir
=''):
263 NewFile
= GlobalData
.gALL_FILES
[os
.path
.normpath(os
.path
.join\
264 (OverrideDir
, File
))]
266 if OverrideDir
[-1] == os
.path
.sep
:
267 return NewFile
[len(OverrideDir
):], NewFile
[0:len(OverrideDir
)]
269 return NewFile
[len(OverrideDir
) + 1:], \
270 NewFile
[0:len(OverrideDir
)]
272 NewFile
= GlobalData
.gALL_FILES
[os
.path
.normpath(os
.path
.join(Dir
, File
))]
275 if Dir
[-1] == os
.path
.sep
:
276 return NewFile
[len(Dir
):], NewFile
[0:len(Dir
)]
278 return NewFile
[len(Dir
) + 1:], NewFile
[0:len(Dir
)]
284 ## A dict which can access its keys and/or values orderly
286 # The class implements a new kind of dict which its keys or values can be
287 # accessed in the order they are added into the dict. It guarantees the order
288 # by making use of an internal list to keep a copy of keys.
290 class Sdict(IterableUserDict
):
294 IterableUserDict
.__init
__(self
)
299 def __setitem__(self
, Key
, Value
):
300 if Key
not in self
._key
_list
:
301 self
._key
_list
.append(Key
)
302 IterableUserDict
.__setitem
__(self
, Key
, Value
)
306 def __delitem__(self
, Key
):
307 self
._key
_list
.remove(Key
)
308 IterableUserDict
.__delitem
__(self
, Key
)
310 ## used in "for k in dict" loop to ensure the correct order
313 return self
.iterkeys()
318 return len(self
._key
_list
)
322 def __contains__(self
, Key
):
323 return Key
in self
._key
_list
327 def index(self
, Key
):
328 return self
._key
_list
.index(Key
)
332 def insert(self
, Key
, Newkey
, Newvalue
, Order
):
333 Index
= self
._key
_list
.index(Key
)
334 if Order
== 'BEFORE':
335 self
._key
_list
.insert(Index
, Newkey
)
336 IterableUserDict
.__setitem
__(self
, Newkey
, Newvalue
)
337 elif Order
== 'AFTER':
338 self
._key
_list
.insert(Index
+ 1, Newkey
)
339 IterableUserDict
.__setitem
__(self
, Newkey
, Newvalue
)
343 def append(self
, Sdict2
):
345 if Key
not in self
._key
_list
:
346 self
._key
_list
.append(Key
)
347 IterableUserDict
.__setitem
__(self
, Key
, Sdict2
[Key
])
350 def has_key(self
, Key
):
351 return Key
in self
._key
_list
357 IterableUserDict
.clear(self
)
359 ## Return a copy of keys
363 for Key
in self
._key
_list
:
367 ## Return a copy of values
371 for Key
in self
._key
_list
:
372 Values
.append(self
[Key
])
375 ## Return a copy of (key, value) list
379 for Key
in self
._key
_list
:
380 Items
.append((Key
, self
[Key
]))
386 return iter(self
.items())
388 ## Keys interation support
391 return iter(self
.keys())
393 ## Values interation support
395 def itervalues(self
):
396 return iter(self
.values())
398 ## Return value related to a key, and remove the (key, value) from the dict
400 def pop(self
, Key
, *Dv
):
402 if Key
in self
._key
_list
:
404 self
.__delitem
__(Key
)
409 ## Return (key, value) pair, and remove the (key, value) from the dict
412 Key
= self
._key
_list
[-1]
414 self
.__delitem
__(Key
)
418 def update(self
, Dict
=None, **Kwargs
):
420 for Key1
, Val1
in Dict
.items():
423 for Key1
, Val1
in Kwargs
.items():
428 # @param PathList: PathList
430 def CommonPath(PathList
):
431 Path1
= min(PathList
).split(os
.path
.sep
)
432 Path2
= max(PathList
).split(os
.path
.sep
)
433 for Index
in xrange(min(len(Path1
), len(Path2
))):
434 if Path1
[Index
] != Path2
[Index
]:
435 return os
.path
.sep
.join(Path1
[:Index
])
436 return os
.path
.sep
.join(Path1
)
440 class PathClass(object):
441 def __init__(self
, File
='', Root
='', AlterRoot
='', Type
='', IsBinary
=False,
442 Arch
='COMMON', ToolChainFamily
='', Target
='', TagName
='', \
445 self
.File
= str(File
)
446 if os
.path
.isabs(self
.File
):
450 self
.Root
= str(Root
)
451 self
.AlterRoot
= str(AlterRoot
)
454 # Remove any '.' and '..' in path
457 self
.Path
= os
.path
.normpath(os
.path
.join(self
.Root
, self
.File
))
458 self
.Root
= os
.path
.normpath(CommonPath([self
.Root
, self
.Path
]))
460 # eliminate the side-effect of 'C:'
462 if self
.Root
[-1] == ':':
463 self
.Root
+= os
.path
.sep
465 # file path should not start with path separator
467 if self
.Root
[-1] == os
.path
.sep
:
468 self
.File
= self
.Path
[len(self
.Root
):]
470 self
.File
= self
.Path
[len(self
.Root
) + 1:]
472 self
.Path
= os
.path
.normpath(self
.File
)
474 self
.SubDir
, self
.Name
= os
.path
.split(self
.File
)
475 self
.BaseName
, self
.Ext
= os
.path
.splitext(self
.Name
)
479 self
.Dir
= os
.path
.join(self
.Root
, self
.SubDir
)
483 self
.Dir
= self
.SubDir
488 self
.Type
= self
.Ext
.lower()
490 self
.IsBinary
= IsBinary
492 self
.TagName
= TagName
493 self
.ToolCode
= ToolCode
494 self
.ToolChainFamily
= ToolChainFamily
498 ## Convert the object of this class to a string
500 # Convert member Path of the class to a string
505 ## Override __eq__ function
507 # Check whether PathClass are the same
509 def __eq__(self
, Other
):
510 if type(Other
) == type(self
):
511 return self
.Path
== Other
.Path
513 return self
.Path
== str(Other
)
515 ## Override __hash__ function
517 # Use Path as key in hash table
520 return hash(self
.Path
)
524 def _GetFileKey(self
):
525 if self
._Key
== None:
526 self
._Key
= self
.Path
.upper()
530 def Validate(self
, Type
='', CaseSensitive
=True):
531 if GlobalData
.gCASE_INSENSITIVE
:
532 CaseSensitive
= False
533 if Type
and Type
.lower() != self
.Type
:
534 return ToolError
.FILE_TYPE_MISMATCH
, '%s (expect %s but got %s)' % \
535 (self
.File
, Type
, self
.Type
)
537 RealFile
, RealRoot
= RealPath2(self
.File
, self
.Root
, self
.AlterRoot
)
538 if not RealRoot
and not RealFile
:
541 RealFile
= os
.path
.join(self
.AlterRoot
, self
.File
)
543 RealFile
= os
.path
.join(self
.Root
, self
.File
)
544 return ToolError
.FILE_NOT_FOUND
, os
.path
.join(self
.AlterRoot
, RealFile
)
548 if RealRoot
!= self
.Root
or RealFile
!= self
.File
:
549 if CaseSensitive
and (RealFile
!= self
.File
or \
550 (RealRoot
!= self
.Root
and RealRoot
!= \
552 ErrorCode
= ToolError
.FILE_CASE_MISMATCH
553 ErrorInfo
= self
.File
+ '\n\t' + RealFile
+ \
556 self
.SubDir
, self
.Name
= os
.path
.split(RealFile
)
557 self
.BaseName
, self
.Ext
= os
.path
.splitext(self
.Name
)
559 self
.Dir
= os
.path
.join(RealRoot
, self
.SubDir
)
564 self
.Path
= os
.path
.join(RealRoot
, RealFile
)
565 return ErrorCode
, ErrorInfo
567 Key
= property(_GetFileKey
)
569 ## Check environment variables
571 # Check environment variables that must be set for build. Currently they are
573 # WORKSPACE The directory all packages/platforms start from
574 # EDK_TOOLS_PATH The directory contains all tools needed by the build
575 # PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
577 # If any of above environment variable is not set or has error, the build
580 def CheckEnvVariable():
584 if "WORKSPACE" not in environ
:
586 ToolError
.UPT_ENVIRON_MISSING_ERROR
,
587 ST
.ERR_NOT_FOUND_ENVIRONMENT
,
588 ExtraData
="WORKSPACE")
590 WorkspaceDir
= os
.path
.normpath(environ
["WORKSPACE"])
591 if not os
.path
.exists(WorkspaceDir
):
593 ToolError
.UPT_ENVIRON_MISSING_ERROR
,
594 ST
.ERR_WORKSPACE_NOTEXIST
,
595 ExtraData
="%s" % WorkspaceDir
)
596 elif ' ' in WorkspaceDir
:
598 ToolError
.FORMAT_NOT_SUPPORTED
,
599 ST
.ERR_SPACE_NOTALLOWED
,
600 ExtraData
=WorkspaceDir
)
602 ## Check whether all module types are in list
604 # check whether all module types (SUP_MODULE_LIST) are in list
606 # @param ModuleList: a list of ModuleType
608 def IsAllModuleList(ModuleList
):
609 NewModuleList
= [Module
.upper() for Module
in ModuleList
]
610 for Module
in SUP_MODULE_LIST
:
611 if Module
not in NewModuleList
:
616 ## Dictionary that use comment(GenericComment, TailComment) as value,
617 # if a new comment which key already in the dic is inserted, then the
618 # comment will be merged.
619 # Key is (Statement, SupArch), when TailComment is added, it will ident
620 # according to Statement
622 class MergeCommentDict(dict):
625 def __setitem__(self
, Key
, CommentVal
):
626 GenericComment
, TailComment
= CommentVal
628 OrigVal1
, OrigVal2
= dict.__getitem
__(self
, Key
)
630 dict.__setitem
__(self
, Key
, (OrigVal1
+ GenericComment
, OrigVal2 \
631 + len(Statement
) * ' ' + TailComment
))
633 dict.__setitem
__(self
, Key
, (GenericComment
, TailComment
))
637 def __getitem__(self
, Key
):
638 return dict.__getitem
__(self
, Key
)
641 ## GenDummyHelpTextObj
643 # @retval HelpTxt: Generated dummy help text object
645 def GenDummyHelpTextObj():
646 HelpTxt
= TextObject()
647 HelpTxt
.SetLang(LANGUAGE_EN_US
)
648 HelpTxt
.SetString(' ')
651 ## ConvertVersionToDecimal, the minor version should be within 0 - 99
652 # <HexVersion> ::= "0x" <Major> <Minor>
653 # <Major> ::= (a-fA-F0-9){4}
654 # <Minor> ::= (a-fA-F0-9){4}
655 # <DecVersion> ::= (0-65535) ["." (0-99)]
657 # @param StringIn: The string contains version defined in INF file.
658 # It can be Decimal or Hex
660 def ConvertVersionToDecimal(StringIn
):
661 if IsValidHexVersion(StringIn
):
662 Value
= int(StringIn
, 16)
664 Minor
= Value
& 0xFFFF
665 MinorStr
= str(Minor
)
666 if len(MinorStr
) == 1:
667 MinorStr
= '0' + MinorStr
668 return str(Major
) + '.' + MinorStr
670 if StringIn
.find(TAB_SPLIT
) != -1:
673 return StringIn
+ '.0'
676 # when StringIn is '', return it directly
680 ## GetHelpStringByRemoveHashKey
682 # Remove hash key at the header of string and return the remain.
684 # @param String: The string need to be processed.
686 def GetHelpStringByRemoveHashKey(String
):
688 PattenRemoveHashKey
= re
.compile(r
"^[#+\s]+", re
.DOTALL
)
689 String
= String
.strip()
693 LineList
= GetSplitValueList(String
, END_OF_LINE
)
694 for Line
in LineList
:
695 ValueList
= PattenRemoveHashKey
.split(Line
)
696 if len(ValueList
) == 1:
697 ReturnString
+= ValueList
[0] + END_OF_LINE
699 ReturnString
+= ValueList
[1] + END_OF_LINE
701 if ReturnString
.endswith('\n') and not ReturnString
.endswith('\n\n') and ReturnString
!= '\n':
702 ReturnString
= ReturnString
[:-1]
706 ## ConvPathFromAbsToRel
708 # Get relative file path from absolute path.
710 # @param Path: The string contain file absolute path.
711 # @param Root: The string contain the parent path of Path in.
714 def ConvPathFromAbsToRel(Path
, Root
):
715 Path
= os
.path
.normpath(Path
)
716 Root
= os
.path
.normpath(Root
)
717 FullPath
= os
.path
.normpath(os
.path
.join(Root
, Path
))
720 # If Path is absolute path.
721 # It should be in Root.
723 if os
.path
.isabs(Path
):
724 return FullPath
[FullPath
.find(Root
) + len(Root
) + 1:]
731 # Convert special characters to '_', '\' to '/'
732 # return converted path: Test!1.inf -> Test_1.inf
734 # @param Path: Path to be converted
736 def ConvertPath(Path
):
738 for Char
in Path
.strip():
739 if Char
.isalnum() or Char
in '.-_/':
740 RetPath
= RetPath
+ Char
742 RetPath
= RetPath
+ '/'
744 RetPath
= RetPath
+ '_'
749 # during install, convert the Spec string extract from UPD into INF allowable definition,
750 # the difference is period is allowed in the former (not the first letter) but not in the latter.
751 # return converted Spec string
753 # @param SpecStr: SpecStr to be converted
755 def ConvertSpec(SpecStr
):
758 if Char
.isalnum() or Char
== '_':
759 RetStr
= RetStr
+ Char
761 RetStr
= RetStr
+ '_'
768 # Judge two lists are identical(contain same item).
769 # The rule is elements in List A are in List B and elements in List B are in List A.
771 # @param ListA, ListB Lists need to be judged.
773 # @return True ListA and ListB are identical
774 # @return False ListA and ListB are different with each other
776 def IsEqualList(ListA
, ListB
):
781 if not ItemA
in ListB
:
785 if not ItemB
in ListA
:
792 # Convert item in ArchList if the start character is lower case.
793 # In UDP spec, Arch is only allowed as: [A-Z]([a-zA-Z0-9])*
795 # @param ArchList The ArchList need to be converted.
797 # @return NewList The ArchList been converted.
799 def ConvertArchList(ArchList
):
804 if type(ArchList
) == list:
805 for Arch
in ArchList
:
807 NewArchList
.append(Arch
)
808 elif type(ArchList
) == str:
809 ArchList
= ArchList
.upper()
810 NewArchList
.append(ArchList
)
814 ## ProcessLineExtender
816 # Process the LineExtender of Line in LineList.
817 # If one line ends with a line extender, then it will be combined together with next line.
819 # @param LineList The LineList need to be processed.
821 # @return NewList The ArchList been processed.
823 def ProcessLineExtender(LineList
):
826 while Count
< len(LineList
):
827 if LineList
[Count
].strip().endswith("\\") and Count
+ 1 < len(LineList
):
828 NewList
.append(LineList
[Count
].strip()[:-2] + LineList
[Count
+ 1])
831 NewList
.append(LineList
[Count
])
839 # Process EDK style comment in LineList: c style /* */ comment or cpp style // comment
842 # @param LineList The LineList need to be processed.
844 # @return LineList The LineList been processed.
845 # @return FirstPos Where Edk comment is first found, -1 if not found
847 def ProcessEdkComment(LineList
):
848 FindEdkBlockComment
= False
854 while(Count
< len(LineList
)):
855 Line
= LineList
[Count
].strip()
856 if Line
.startswith("/*"):
858 # handling c style comment
861 while Count
< len(LineList
):
862 Line
= LineList
[Count
].strip()
863 if Line
.endswith("*/"):
864 if (Count
== StartPos
) and Line
.strip() == '/*/':
868 FindEdkBlockComment
= True
872 if FindEdkBlockComment
:
875 for Index
in xrange(StartPos
, EndPos
+1):
877 FindEdkBlockComment
= False
878 elif Line
.find("//") != -1 and not Line
.startswith("#"):
880 # handling cpp style comment
882 LineList
[Count
] = Line
.replace("//", '#')
888 return LineList
, FirstPos
890 ## GetLibInstanceInfo
892 # Get the information from Library Instance INF file.
894 # @param string. A string start with # and followed by INF file path
895 # @param WorkSpace. The WorkSpace directory used to combined with INF file path.
897 # @return GUID, Version
898 def GetLibInstanceInfo(String
, WorkSpace
, LineNo
):
903 OrignalString
= String
904 String
= String
.strip()
908 # Remove "#" characters at the beginning
910 String
= GetHelpStringByRemoveHashKey(String
)
911 String
= String
.strip()
914 # Validate file name exist.
916 FullFileName
= os
.path
.normpath(os
.path
.realpath(os
.path
.join(WorkSpace
, String
)))
917 if not (ValidFile(FullFileName
)):
918 Logger
.Error("InfParser",
919 ToolError
.FORMAT_INVALID
,
920 ST
.ERR_FILELIST_EXIST
% (String
),
921 File
=GlobalData
.gINF_MODULE_NAME
,
923 ExtraData
=OrignalString
)
926 # Validate file exist/format.
928 if IsValidPath(String
, WorkSpace
):
929 IsValidFileFlag
= True
931 Logger
.Error("InfParser",
932 ToolError
.FORMAT_INVALID
,
933 ST
.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID
% (String
),
934 File
=GlobalData
.gINF_MODULE_NAME
,
936 ExtraData
=OrignalString
)
942 FInputfile
= open(FullFileName
, "rb", 0)
944 FileLinesList
= FInputfile
.readlines()
945 except BaseException
:
946 Logger
.Error("InfParser",
947 ToolError
.FILE_READ_FAILURE
,
948 ST
.ERR_FILE_OPEN_FAILURE
,
952 except BaseException
:
953 Logger
.Error("InfParser",
954 ToolError
.FILE_READ_FAILURE
,
955 ST
.ERR_FILE_OPEN_FAILURE
,
958 ReFileGuidPattern
= re
.compile("^\s*FILE_GUID\s*=.*$")
959 ReVerStringPattern
= re
.compile("^\s*VERSION_STRING\s*=.*$")
961 FileLinesList
= ProcessLineExtender(FileLinesList
)
963 for Line
in FileLinesList
:
964 if ReFileGuidPattern
.match(Line
):
965 FileGuidString
= Line
966 if ReVerStringPattern
.match(Line
):
970 FileGuidString
= GetSplitValueList(FileGuidString
, '=', 1)[1]
972 VerString
= GetSplitValueList(VerString
, '=', 1)[1]
974 return FileGuidString
, VerString