]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/String.py
2 # This file is used to define common string related functions used in parsing process
4 # Copyright (c) 2007 - 2015, 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
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.
19 import Common
.LongFilePathOs
as os
21 import EdkLogger
as EdkLogger
24 from BuildToolError
import *
25 from CommonDataClass
.Exceptions
import *
26 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
27 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
29 gHexVerPatt
= re
.compile('0x[a-f0-9]{4}[a-f0-9]{4}$', re
.IGNORECASE
)
30 gHumanReadableVerPatt
= re
.compile(r
'([1-9][0-9]*|0)\.[0-9]{1,2}$')
34 # Get a value list from a string with multiple values splited with SplitTag
35 # The default SplitTag is DataType.TAB_VALUE_SPLIT
36 # 'AAA|BBB|CCC' -> ['AAA', 'BBB', 'CCC']
38 # @param String: The input string to be splitted
39 # @param SplitTag: The split key, default is DataType.TAB_VALUE_SPLIT
40 # @param MaxSplit: The max number of split values, default is -1
42 # @retval list() A list for splitted string
44 def GetSplitValueList(String
, SplitTag
=DataType
.TAB_VALUE_SPLIT
, MaxSplit
= -1):
49 for Index
in range(0, len(String
)):
53 # Found a splitter not in a string, split it
54 if not InString
and Char
== SplitTag
:
55 ValueList
.append(String
[Last
:Index
].strip())
57 if MaxSplit
> 0 and len(ValueList
) >= MaxSplit
:
60 if Char
== '\\' and InString
:
70 if Last
< len(String
):
71 ValueList
.append(String
[Last
:].strip())
72 elif Last
== len(String
):
79 # Get a value list from a string with multiple values splited with SplitString
80 # The default SplitTag is DataType.TAB_VALUE_SPLIT
81 # 'AAA|BBB|CCC' -> ['AAA', 'BBB', 'CCC']
83 # @param String: The input string to be splitted
84 # @param SplitStr: The split key, default is DataType.TAB_VALUE_SPLIT
85 # @param MaxSplit: The max number of split values, default is -1
87 # @retval list() A list for splitted string
89 def GetSplitList(String
, SplitStr
=DataType
.TAB_VALUE_SPLIT
, MaxSplit
= -1):
90 return map(lambda l
: l
.strip(), String
.split(SplitStr
, MaxSplit
))
94 # Find a key's all arches in dict, add the new arch to the list
95 # If not exist any arch, set the arch directly
97 # @param Dict: The input value for Dict
98 # @param Key: The input value for Key
99 # @param Arch: The Arch to be added or merged
101 def MergeArches(Dict
, Key
, Arch
):
102 if Key
in Dict
.keys():
103 Dict
[Key
].append(Arch
)
105 Dict
[Key
] = Arch
.split()
109 # Parse a string with format "DEFINE <VarName> = <PATH>"
110 # Generate a map Defines[VarName] = PATH
111 # Return False if invalid format
113 # @param String: String with DEFINE statement
114 # @param Arch: Supportted Arch
115 # @param Defines: DEFINE statement to be parsed
117 # @retval 0 DEFINE statement found, and valid
118 # @retval 1 DEFINE statement found, but not valid
119 # @retval -1 DEFINE statement not found
121 def GenDefines(String
, Arch
, Defines
):
122 if String
.find(DataType
.TAB_DEFINE
+ ' ') > -1:
123 List
= String
.replace(DataType
.TAB_DEFINE
+ ' ', '').split(DataType
.TAB_EQUAL_SPLIT
)
125 Defines
[(CleanString(List
[0]), Arch
)] = CleanString(List
[1])
134 # Parse a string with format "!include <Filename>"
135 # Return the file path
136 # Return False if invalid format or NOT FOUND
138 # @param String: String with INCLUDE statement
139 # @param IncludeFiles: INCLUDE statement to be parsed
140 # @param Arch: Supportted Arch
145 def GenInclude(String
, IncludeFiles
, Arch
):
146 if String
.upper().find(DataType
.TAB_INCLUDE
.upper() + ' ') > -1:
147 IncludeFile
= CleanString(String
[String
.upper().find(DataType
.TAB_INCLUDE
.upper() + ' ') + len(DataType
.TAB_INCLUDE
+ ' ') : ])
148 MergeArches(IncludeFiles
, IncludeFile
, Arch
)
153 ## GetLibraryClassesWithModuleType
155 # Get Library Class definition when no module type defined
157 # @param Lines: The content to be parsed
158 # @param Key: Reserved
159 # @param KeyValues: To store data after parsing
160 # @param CommentCharacter: Comment char, used to ignore comment content
162 # @retval True Get library classes successfully
164 def GetLibraryClassesWithModuleType(Lines
, Key
, KeyValues
, CommentCharacter
):
165 newKey
= SplitModuleType(Key
)
166 Lines
= Lines
.split(DataType
.TAB_SECTION_END
, 1)[1]
167 LineList
= Lines
.splitlines()
168 for Line
in LineList
:
169 Line
= CleanString(Line
, CommentCharacter
)
170 if Line
!= '' and Line
[0] != CommentCharacter
:
171 KeyValues
.append([CleanString(Line
, CommentCharacter
), newKey
[1]])
179 # @param Lines: The content to be parsed
180 # @param Key: Reserved
181 # @param KeyValues: To store data after parsing
182 # @param CommentCharacter: Comment char, used to ignore comment content
184 # @retval True Get Dynamic Pcds successfully
186 def GetDynamics(Lines
, Key
, KeyValues
, CommentCharacter
):
188 # Get SkuId Name List
190 SkuIdNameList
= SplitModuleType(Key
)
192 Lines
= Lines
.split(DataType
.TAB_SECTION_END
, 1)[1]
193 LineList
= Lines
.splitlines()
194 for Line
in LineList
:
195 Line
= CleanString(Line
, CommentCharacter
)
196 if Line
!= '' and Line
[0] != CommentCharacter
:
197 KeyValues
.append([CleanString(Line
, CommentCharacter
), SkuIdNameList
[1]])
203 # Split ModuleType out of section defien to get key
204 # [LibraryClass.Arch.ModuleType|ModuleType|ModuleType] -> [ 'LibraryClass.Arch', ['ModuleType', 'ModuleType', 'ModuleType'] ]
206 # @param Key: String to be parsed
208 # @retval ReturnValue A list for module types
210 def SplitModuleType(Key
):
211 KeyList
= Key
.split(DataType
.TAB_SPLIT
)
217 # Fill in for moduletype
221 KeyValue
= KeyList
[0]
223 KeyValue
= KeyValue
+ DataType
.TAB_SPLIT
+ KeyList
[1]
224 ReturnValue
.append(KeyValue
)
225 ReturnValue
.append(GetSplitValueList(KeyList
[2]))
229 ## Replace macro in strings list
231 # This method replace macros used in a given string list. The macros are
232 # given in a dictionary.
234 # @param StringList StringList to be processed
235 # @param MacroDefinitions The macro definitions in the form of dictionary
236 # @param SelfReplacement To decide whether replace un-defined macro to ''
238 # @retval NewList A new string list whose macros are replaced
240 def ReplaceMacros(StringList
, MacroDefinitions
={}, SelfReplacement
=False):
242 for String
in StringList
:
243 if type(String
) == type(''):
244 NewList
.append(ReplaceMacro(String
, MacroDefinitions
, SelfReplacement
))
246 NewList
.append(String
)
250 ## Replace macro in string
252 # This method replace macros used in given string. The macros are given in a
255 # @param String String to be processed
256 # @param MacroDefinitions The macro definitions in the form of dictionary
257 # @param SelfReplacement To decide whether replace un-defined macro to ''
259 # @retval string The string whose macros are replaced
261 def ReplaceMacro(String
, MacroDefinitions
={}, SelfReplacement
=False, RaiseError
=False):
263 while String
and MacroDefinitions
:
264 MacroUsed
= GlobalData
.gMacroRefPattern
.findall(String
)
265 # no macro found in String, stop replacing
266 if len(MacroUsed
) == 0:
269 for Macro
in MacroUsed
:
270 if Macro
not in MacroDefinitions
:
272 raise SymbolNotFound("%s not defined" % Macro
)
274 String
= String
.replace("$(%s)" % Macro
, '')
276 if "$(%s)" % Macro
not in MacroDefinitions
[Macro
]:
277 String
= String
.replace("$(%s)" % Macro
, MacroDefinitions
[Macro
])
278 # in case there's macro not defined
279 if String
== LastString
:
287 # Create a normal path
288 # And replace DFEINE in the path
290 # @param Path: The input value for Path to be converted
291 # @param Defines: A set for DEFINE statement
293 # @retval Path Formatted path
295 def NormPath(Path
, Defines
={}):
296 IsRelativePath
= False
299 IsRelativePath
= True
301 # Replace with Define
304 Path
= ReplaceMacro(Path
, Defines
)
306 # To local path format
308 Path
= os
.path
.normpath(Path
)
309 if Path
.startswith(GlobalData
.gWorkspace
) and not os
.path
.exists(Path
):
310 Path
= Path
[len (GlobalData
.gWorkspace
):]
311 if Path
[0] == os
.path
.sep
:
313 Path
= mws
.join(GlobalData
.gWorkspace
, Path
)
315 if IsRelativePath
and Path
[0] != '.':
316 Path
= os
.path
.join('.', Path
)
322 # Remove comments in a string
325 # @param Line: The string to be cleaned
326 # @param CommentCharacter: Comment char, used to ignore comment content, default is DataType.TAB_COMMENT_SPLIT
328 # @retval Path Formatted path
330 def CleanString(Line
, CommentCharacter
=DataType
.TAB_COMMENT_SPLIT
, AllowCppStyleComment
=False, BuildOption
=False):
336 # Replace Edk's comment character
338 if AllowCppStyleComment
:
339 Line
= Line
.replace(DataType
.TAB_COMMENT_EDK_SPLIT
, CommentCharacter
)
341 # remove comments, but we should escape comment character in string
344 CommentInString
= False
345 for Index
in range(0, len(Line
)):
346 if Line
[Index
] == '"':
347 InString
= not InString
348 elif Line
[Index
] == CommentCharacter
and InString
:
349 CommentInString
= True
350 elif Line
[Index
] == CommentCharacter
and not InString
:
351 Line
= Line
[0: Index
]
354 if CommentInString
and BuildOption
:
355 Line
= Line
.replace('"', '')
356 ChIndex
= Line
.find('#')
358 if GlobalData
.gIsWindows
:
359 if ChIndex
== 0 or Line
[ChIndex
- 1] != '^':
360 Line
= Line
[0:ChIndex
] + '^' + Line
[ChIndex
:]
361 ChIndex
= Line
.find('#', ChIndex
+ 2)
363 ChIndex
= Line
.find('#', ChIndex
+ 1)
365 if ChIndex
== 0 or Line
[ChIndex
- 1] != '\\':
366 Line
= Line
[0:ChIndex
] + '\\' + Line
[ChIndex
:]
367 ChIndex
= Line
.find('#', ChIndex
+ 2)
369 ChIndex
= Line
.find('#', ChIndex
+ 1)
371 # remove whitespace again
379 # Split statement with comments in a string
382 # @param Line: The string to be cleaned
383 # @param CommentCharacter: Comment char, used to ignore comment content, default is DataType.TAB_COMMENT_SPLIT
385 # @retval Path Formatted path
387 def CleanString2(Line
, CommentCharacter
=DataType
.TAB_COMMENT_SPLIT
, AllowCppStyleComment
=False):
393 # Replace Edk's comment character
395 if AllowCppStyleComment
:
396 Line
= Line
.replace(DataType
.TAB_COMMENT_EDK_SPLIT
, CommentCharacter
)
398 # separate comments and statements, but we should escape comment character in string
401 CommentInString
= False
403 for Index
in range(0, len(Line
)):
404 if Line
[Index
] == '"':
405 InString
= not InString
406 elif Line
[Index
] == CommentCharacter
and InString
:
407 CommentInString
= True
408 elif Line
[Index
] == CommentCharacter
and not InString
:
409 Comment
= Line
[Index
:].strip()
410 Line
= Line
[0:Index
].strip()
415 ## GetMultipleValuesOfKeyFromLines
417 # Parse multiple strings to clean comment and spaces
418 # The result is saved to KeyValues
420 # @param Lines: The content to be parsed
421 # @param Key: Reserved
422 # @param KeyValues: To store data after parsing
423 # @param CommentCharacter: Comment char, used to ignore comment content
425 # @retval True Successfully executed
427 def GetMultipleValuesOfKeyFromLines(Lines
, Key
, KeyValues
, CommentCharacter
):
428 Lines
= Lines
.split(DataType
.TAB_SECTION_END
, 1)[1]
429 LineList
= Lines
.split('\n')
430 for Line
in LineList
:
431 Line
= CleanString(Line
, CommentCharacter
)
432 if Line
!= '' and Line
[0] != CommentCharacter
:
439 # Parse a DEFINE statement to get defined value
442 # @param String: The content to be parsed
443 # @param Key: The key of DEFINE statement
444 # @param CommentCharacter: Comment char, used to ignore comment content
446 # @retval string The defined value
448 def GetDefineValue(String
, Key
, CommentCharacter
):
449 String
= CleanString(String
)
450 return String
[String
.find(Key
+ ' ') + len(Key
+ ' ') : ]
454 # Get a Hex Version Value
456 # @param VerString: The version string to be parsed
459 # @retval: If VerString is incorrectly formatted, return "None" which will break the build.
460 # If VerString is correctly formatted, return a Hex value of the Version Number (0xmmmmnnnn)
461 # where mmmm is the major number and nnnn is the adjusted minor number.
463 def GetHexVerValue(VerString
):
464 VerString
= CleanString(VerString
)
466 if gHumanReadableVerPatt
.match(VerString
):
467 ValueList
= VerString
.split('.')
472 DeciValue
= (int(Major
) << 16) + int(Minor
);
473 return "0x%08x" % DeciValue
474 elif gHexVerPatt
.match(VerString
):
480 ## GetSingleValueOfKeyFromLines
482 # Parse multiple strings as below to get value of each definition line
485 # The result is saved to Dictionary
487 # @param Lines: The content to be parsed
488 # @param Dictionary: To store data after parsing
489 # @param CommentCharacter: Comment char, be used to ignore comment content
490 # @param KeySplitCharacter: Key split char, between key name and key value. Key1 = Value1, '=' is the key split char
491 # @param ValueSplitFlag: Value split flag, be used to decide if has multiple values
492 # @param ValueSplitCharacter: Value split char, be used to split multiple values. Key1 = Value1|Value2, '|' is the value split char
494 # @retval True Successfully executed
496 def GetSingleValueOfKeyFromLines(Lines
, Dictionary
, CommentCharacter
, KeySplitCharacter
, ValueSplitFlag
, ValueSplitCharacter
):
497 Lines
= Lines
.split('\n')
505 # Handle DEFINE and SPEC
507 if Line
.find(DataType
.TAB_INF_DEFINES_DEFINE
+ ' ') > -1:
508 if '' in DefineValues
:
509 DefineValues
.remove('')
510 DefineValues
.append(GetDefineValue(Line
, DataType
.TAB_INF_DEFINES_DEFINE
, CommentCharacter
))
512 if Line
.find(DataType
.TAB_INF_DEFINES_SPEC
+ ' ') > -1:
514 SpecValues
.remove('')
515 SpecValues
.append(GetDefineValue(Line
, DataType
.TAB_INF_DEFINES_SPEC
, CommentCharacter
))
521 LineList
= Line
.split(KeySplitCharacter
, 1)
522 if len(LineList
) >= 2:
523 Key
= LineList
[0].split()
524 if len(Key
) == 1 and Key
[0][0] != CommentCharacter
:
526 # Remove comments and white spaces
528 LineList
[1] = CleanString(LineList
[1], CommentCharacter
)
530 Value
= map(string
.strip
, LineList
[1].split(ValueSplitCharacter
))
532 Value
= CleanString(LineList
[1], CommentCharacter
).splitlines()
534 if Key
[0] in Dictionary
:
535 if Key
[0] not in Keys
:
536 Dictionary
[Key
[0]] = Value
539 Dictionary
[Key
[0]].extend(Value
)
541 Dictionary
[DataType
.TAB_INF_DEFINES_MACRO
][Key
[0]] = Value
[0]
543 if DefineValues
== []:
547 Dictionary
[DataType
.TAB_INF_DEFINES_DEFINE
] = DefineValues
548 Dictionary
[DataType
.TAB_INF_DEFINES_SPEC
] = SpecValues
552 ## The content to be parsed
554 # Do pre-check for a file before it is parsed
558 # @param FileName: Used for error report
559 # @param FileContent: File content to be parsed
560 # @param SupSectionTag: Used for error report
562 def PreCheck(FileName
, FileContent
, SupSectionTag
):
566 for Line
in FileContent
.splitlines():
571 Line
= CleanString(Line
)
574 # Remove commented line
576 if Line
.find(DataType
.TAB_COMMA_SPLIT
) == 0:
581 if Line
.find('$') > -1:
582 if Line
.find('$(') < 0 or Line
.find(')') < 0:
583 EdkLogger
.error("Parser", FORMAT_INVALID
, Line
=LineNo
, File
=FileName
, RaiseError
=EdkLogger
.IsRaiseError
)
588 if Line
.find('[') > -1 or Line
.find(']') > -1:
590 # Only get one '[' or one ']'
592 if not (Line
.find('[') > -1 and Line
.find(']') > -1):
593 EdkLogger
.error("Parser", FORMAT_INVALID
, Line
=LineNo
, File
=FileName
, RaiseError
=EdkLogger
.IsRaiseError
)
596 # Regenerate FileContent
598 NewFileContent
= NewFileContent
+ Line
+ '\r\n'
601 EdkLogger
.error("Parser", FORMAT_INVALID
, Line
=LineNo
, File
=FileName
, RaiseError
=EdkLogger
.IsRaiseError
)
603 return NewFileContent
607 # Check if the Filename is including ExtName
608 # Return True if it exists
609 # Raise a error message if it not exists
611 # @param CheckFilename: Name of the file to be checked
612 # @param ExtName: Ext name of the file to be checked
613 # @param ContainerFilename: The container file which describes the file to be checked, used for error report
614 # @param SectionName: Used for error report
615 # @param Line: The line in container file which defines the file to be checked
617 # @retval True The file type is correct
619 def CheckFileType(CheckFilename
, ExtName
, ContainerFilename
, SectionName
, Line
, LineNo
= -1):
620 if CheckFilename
!= '' and CheckFilename
!= None:
621 (Root
, Ext
) = os
.path
.splitext(CheckFilename
)
622 if Ext
.upper() != ExtName
.upper():
623 ContainerFile
= open(ContainerFilename
, 'r').read()
625 LineNo
= GetLineNo(ContainerFile
, Line
)
626 ErrorMsg
= "Invalid %s. '%s' is found, but '%s' file is needed" % (SectionName
, CheckFilename
, ExtName
)
627 EdkLogger
.error("Parser", PARSER_ERROR
, ErrorMsg
, Line
=LineNo
,
628 File
=ContainerFilename
, RaiseError
=EdkLogger
.IsRaiseError
)
634 # Check if the file exists
635 # Return True if it exists
636 # Raise a error message if it not exists
638 # @param CheckFilename: Name of the file to be checked
639 # @param WorkspaceDir: Current workspace dir
640 # @param ContainerFilename: The container file which describes the file to be checked, used for error report
641 # @param SectionName: Used for error report
642 # @param Line: The line in container file which defines the file to be checked
644 # @retval The file full path if the file exists
646 def CheckFileExist(WorkspaceDir
, CheckFilename
, ContainerFilename
, SectionName
, Line
, LineNo
= -1):
648 if CheckFilename
!= '' and CheckFilename
!= None:
649 CheckFile
= WorkspaceFile(WorkspaceDir
, CheckFilename
)
650 if not os
.path
.isfile(CheckFile
):
651 ContainerFile
= open(ContainerFilename
, 'r').read()
653 LineNo
= GetLineNo(ContainerFile
, Line
)
654 ErrorMsg
= "Can't find file '%s' defined in section '%s'" % (CheckFile
, SectionName
)
655 EdkLogger
.error("Parser", PARSER_ERROR
, ErrorMsg
,
656 File
=ContainerFilename
, Line
=LineNo
, RaiseError
=EdkLogger
.IsRaiseError
)
662 # Find the index of a line in a file
664 # @param FileContent: Search scope
665 # @param Line: Search key
667 # @retval int Index of the line
668 # @retval -1 The line is not found
670 def GetLineNo(FileContent
, Line
, IsIgnoreComment
=True):
671 LineList
= FileContent
.splitlines()
672 for Index
in range(len(LineList
)):
673 if LineList
[Index
].find(Line
) > -1:
675 # Ignore statement in comment
678 if LineList
[Index
].strip()[0] == DataType
.TAB_COMMENT_SPLIT
:
686 # Raise a parser error
688 # @param Line: String which has error
689 # @param Section: Used for error report
690 # @param File: File which has the string
691 # @param Format: Correct format
693 def RaiseParserError(Line
, Section
, File
, Format
='', LineNo
= -1):
695 LineNo
= GetLineNo(open(os
.path
.normpath(File
), 'r').read(), Line
)
696 ErrorMsg
= "Invalid statement '%s' is found in section '%s'" % (Line
, Section
)
698 Format
= "Correct format is " + Format
699 EdkLogger
.error("Parser", PARSER_ERROR
, ErrorMsg
, File
=File
, Line
=LineNo
, ExtraData
=Format
, RaiseError
=EdkLogger
.IsRaiseError
)
703 # Return a full path with workspace dir
705 # @param WorkspaceDir: Workspace dir
706 # @param Filename: Relative file name
708 # @retval string A full path
710 def WorkspaceFile(WorkspaceDir
, Filename
):
711 return mws
.join(NormPath(WorkspaceDir
), NormPath(Filename
))
715 # Revmove '"' which startswith and endswith string
717 # @param String: The string need to be splited
719 # @retval String: The string after removed '""'
721 def SplitString(String
):
722 if String
.startswith('\"'):
724 if String
.endswith('\"'):
729 ## Convert To Sql String
731 # 1. Replace "'" with "''" in each item of StringList
733 # @param StringList: A list for strings to be converted
735 def ConvertToSqlString(StringList
):
736 return map(lambda s
: s
.replace("'", "''") , StringList
)
738 ## Convert To Sql String
740 # 1. Replace "'" with "''" in the String
742 # @param String: A String to be converted
744 def ConvertToSqlString2(String
):
745 return String
.replace("'", "''")
748 # Remove comment block
750 def RemoveBlockComment(Lines
):
751 IsFindBlockComment
= False
752 IsFindBlockCode
= False
759 # Remove comment block
761 if Line
.find(DataType
.TAB_COMMENT_EDK_START
) > -1:
762 ReservedLine
= GetSplitList(Line
, DataType
.TAB_COMMENT_EDK_START
, 1)[0]
763 IsFindBlockComment
= True
764 if Line
.find(DataType
.TAB_COMMENT_EDK_END
) > -1:
765 Line
= ReservedLine
+ GetSplitList(Line
, DataType
.TAB_COMMENT_EDK_END
, 1)[1]
767 IsFindBlockComment
= False
768 if IsFindBlockComment
:
772 NewLines
.append(Line
)
776 # Get String of a List
778 def GetStringOfList(List
, Split
=' '):
779 if type(List
) != type([]):
783 Str
= Str
+ Item
+ Split
788 # Get HelpTextList from HelpTextClassList
790 def GetHelpTextList(HelpTextClassList
):
792 if HelpTextClassList
:
793 for HelpText
in HelpTextClassList
:
794 if HelpText
.String
.endswith('\n'):
795 HelpText
.String
= HelpText
.String
[0: len(HelpText
.String
) - len('\n')]
796 List
.extend(HelpText
.String
.split('\n'))
800 def StringToArray(String
):
801 if isinstance(String
, unicode):
802 if len(unicode) == 0:
803 return "{0x00, 0x00}"
804 return "{%s, 0x00, 0x00}" % ", ".join(["0x%02x, 0x00" % ord(C
) for C
in String
])
805 elif String
.startswith('L"'):
806 if String
== "L\"\"":
807 return "{0x00, 0x00}"
809 return "{%s, 0x00, 0x00}" % ", ".join(["0x%02x, 0x00" % ord(C
) for C
in String
[2:-1]])
810 elif String
.startswith('"'):
814 StringLen
= len(String
[1:-1])
816 return "{%s, 0x00}" % ", ".join(["0x%02x" % ord(C
) for C
in String
[1:-1]])
818 return "{%s, 0x00,0x00}" % ", ".join(["0x%02x" % ord(C
) for C
in String
[1:-1]])
819 elif String
.startswith('{'):
820 StringLen
= len(String
.split(","))
822 return "{%s, 0x00}" % ", ".join([ C
for C
in String
[1:-1].split(',')])
824 return "{%s}" % ", ".join([ C
for C
in String
[1:-1].split(',')])
827 if len(String
.split()) % 2:
828 return '{%s, 0}' % ', '.join(String
.split())
830 return '{%s, 0,0}' % ', '.join(String
.split())
832 def StringArrayLength(String
):
833 if isinstance(String
, unicode):
834 return (len(String
) + 1) * 2 + 1;
835 elif String
.startswith('L"'):
836 return (len(String
) - 3 + 1) * 2
837 elif String
.startswith('"'):
838 return (len(String
) - 2 + 1)
840 return len(String
.split()) + 1
842 def RemoveDupOption(OptionString
, Which
="/I", Against
=None):
843 OptionList
= OptionString
.split()
847 for Index
in range(len(OptionList
)):
848 Opt
= OptionList
[Index
]
849 if not Opt
.startswith(Which
):
851 if len(Opt
) > len(Which
):
852 Val
= Opt
[len(Which
):]
856 OptionList
[Index
] = ""
858 ValueList
.append(Val
)
859 return " ".join(OptionList
)
863 # This acts like the main() function for the script, unless it is 'import'ed into another
866 if __name__
== '__main__':