1## @file 2# This file is used to parse a strings file and create or add to a string database 3# file. 4# 5# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> 6# SPDX-License-Identifier: BSD-2-Clause-Patent 7 8## 9# Import Modules 10# 11from __future__ import absolute_import 12import re 13import Common.EdkLogger as EdkLogger 14from Common.BuildToolError import * 15from .UniClassObject import * 16from io import BytesIO 17from struct import pack, unpack 18from Common.LongFilePathSupport import OpenLongFilePath as open 19 20## 21# Static definitions 22# 23EFI_HII_SIBT_END = '0x00' 24EFI_HII_SIBT_STRING_SCSU = '0x10' 25EFI_HII_SIBT_STRING_SCSU_FONT = '0x11' 26EFI_HII_SIBT_STRINGS_SCSU = '0x12' 27EFI_HII_SIBT_STRINGS_SCSU_FONT = '0x13' 28EFI_HII_SIBT_STRING_UCS2 = '0x14' 29EFI_HII_SIBT_STRING_UCS2_FONT = '0x15' 30EFI_HII_SIBT_STRINGS_UCS2 = '0x16' 31EFI_HII_SIBT_STRINGS_UCS2_FONT = '0x17' 32EFI_HII_SIBT_DUPLICATE = '0x20' 33EFI_HII_SIBT_SKIP2 = '0x21' 34EFI_HII_SIBT_SKIP1 = '0x22' 35EFI_HII_SIBT_EXT1 = '0x30' 36EFI_HII_SIBT_EXT2 = '0x31' 37EFI_HII_SIBT_EXT4 = '0x32' 38EFI_HII_SIBT_FONT = '0x40' 39 40EFI_HII_PACKAGE_STRINGS = '0x04' 41EFI_HII_PACKAGE_FORM = '0x02' 42 43StringPackageType = EFI_HII_PACKAGE_STRINGS 44StringPackageForm = EFI_HII_PACKAGE_FORM 45StringBlockType = EFI_HII_SIBT_STRING_UCS2 46StringSkipType = EFI_HII_SIBT_SKIP2 47 48HexHeader = '0x' 49 50COMMENT = '// ' 51DEFINE_STR = '#define' 52COMMENT_DEFINE_STR = COMMENT + DEFINE_STR 53NOT_REFERENCED = 'not referenced' 54COMMENT_NOT_REFERENCED = ' ' + COMMENT + NOT_REFERENCED 55CHAR_ARRAY_DEFIN = 'unsigned char' 56COMMON_FILE_NAME = 'Strings' 57STRING_TOKEN = re.compile('STRING_TOKEN *\(([A-Z0-9_]+) *\)', re.MULTILINE | re.UNICODE) 58 59EFI_HII_ARRAY_SIZE_LENGTH = 4 60EFI_HII_PACKAGE_HEADER_LENGTH = 4 61EFI_HII_HDR_SIZE_LENGTH = 4 62EFI_HII_STRING_OFFSET_LENGTH = 4 63EFI_STRING_ID = 1 64EFI_STRING_ID_LENGTH = 2 65EFI_HII_LANGUAGE_WINDOW = 0 66EFI_HII_LANGUAGE_WINDOW_LENGTH = 2 67EFI_HII_LANGUAGE_WINDOW_NUMBER = 16 68EFI_HII_STRING_PACKAGE_HDR_LENGTH = EFI_HII_PACKAGE_HEADER_LENGTH + EFI_HII_HDR_SIZE_LENGTH + EFI_HII_STRING_OFFSET_LENGTH + EFI_HII_LANGUAGE_WINDOW_LENGTH * EFI_HII_LANGUAGE_WINDOW_NUMBER + EFI_STRING_ID_LENGTH 69 70H_C_FILE_HEADER = ['//', \ 71 '// DO NOT EDIT -- auto-generated file', \ 72 '//', \ 73 '// This file is generated by the StrGather utility', \ 74 '//'] 75LANGUAGE_NAME_STRING_NAME = '$LANGUAGE_NAME' 76PRINTABLE_LANGUAGE_NAME_STRING_NAME = '$PRINTABLE_LANGUAGE_NAME' 77 78## Convert a dec number to a hex string 79# 80# Convert a dec number to a formatted hex string in length digit 81# The digit is set to default 8 82# The hex string starts with "0x" 83# DecToHexStr(1000) is '0x000003E8' 84# DecToHexStr(1000, 6) is '0x0003E8' 85# 86# @param Dec: The number in dec format 87# @param Digit: The needed digit of hex string 88# 89# @retval: The formatted hex string 90# 91def DecToHexStr(Dec, Digit = 8): 92 return '0x{0:0{1}X}'.format(Dec, Digit) 93 94## Convert a dec number to a hex list 95# 96# Convert a dec number to a formatted hex list in size digit 97# The digit is set to default 8 98# DecToHexList(1000) is ['0xE8', '0x03', '0x00', '0x00'] 99# DecToHexList(1000, 6) is ['0xE8', '0x03', '0x00'] 100# 101# @param Dec: The number in dec format 102# @param Digit: The needed digit of hex list 103# 104# @retval: A list for formatted hex string 105# 106def DecToHexList(Dec, Digit = 8): 107 Hex = '{0:0{1}X}'.format(Dec, Digit) 108 return ["0x" + Hex[Bit:Bit + 2] for Bit in range(Digit - 2, -1, -2)] 109 110## Convert a acsii string to a hex list 111# 112# Convert a acsii string to a formatted hex list 113# AscToHexList('en-US') is ['0x65', '0x6E', '0x2D', '0x55', '0x53'] 114# 115# @param Ascii: The acsii string 116# 117# @retval: A list for formatted hex string 118# 119def AscToHexList(Ascii): 120 try: 121 return ['0x{0:02X}'.format(Item) for Item in Ascii] 122 except: 123 return ['0x{0:02X}'.format(ord(Item)) for Item in Ascii] 124 125## Create content of .h file 126# 127# Create content of .h file 128# 129# @param BaseName: The basename of strings 130# @param UniObjectClass A UniObjectClass instance 131# @param IsCompatibleMode Compatible mode 132# @param UniGenCFlag UniString is generated into AutoGen C file when it is set to True 133# 134# @retval Str: A string of .h file content 135# 136def CreateHFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag): 137 Str = [] 138 ValueStartPtr = 60 139 Line = COMMENT_DEFINE_STR + ' ' + LANGUAGE_NAME_STRING_NAME + ' ' * (ValueStartPtr - len(DEFINE_STR + LANGUAGE_NAME_STRING_NAME)) + DecToHexStr(0, 4) + COMMENT_NOT_REFERENCED 140 Str = WriteLine(Str, Line) 141 Line = COMMENT_DEFINE_STR + ' ' + PRINTABLE_LANGUAGE_NAME_STRING_NAME + ' ' * (ValueStartPtr - len(DEFINE_STR + PRINTABLE_LANGUAGE_NAME_STRING_NAME)) + DecToHexStr(1, 4) + COMMENT_NOT_REFERENCED 142 Str = WriteLine(Str, Line) 143 UnusedStr = '' 144 145 #Group the referred/Unused STRING token together. 146 for Index in range(2, len(UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]])): 147 StringItem = UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[0][0]][Index] 148 Name = StringItem.StringName 149 Token = StringItem.Token 150 Referenced = StringItem.Referenced 151 if Name is not None: 152 Line = '' 153 if Referenced == True: 154 if (ValueStartPtr - len(DEFINE_STR + Name)) <= 0: 155 Line = DEFINE_STR + ' ' + Name + ' ' + DecToHexStr(Token, 4) 156 else: 157 Line = DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4) 158 Str = WriteLine(Str, Line) 159 else: 160 if (ValueStartPtr - len(DEFINE_STR + Name)) <= 0: 161 Line = COMMENT_DEFINE_STR + ' ' + Name + ' ' + DecToHexStr(Token, 4) + COMMENT_NOT_REFERENCED 162 else: 163 Line = COMMENT_DEFINE_STR + ' ' + Name + ' ' * (ValueStartPtr - len(DEFINE_STR + Name)) + DecToHexStr(Token, 4) + COMMENT_NOT_REFERENCED 164 UnusedStr = WriteLine(UnusedStr, Line) 165 166 Str.extend( UnusedStr) 167 168 Str = WriteLine(Str, '') 169 if IsCompatibleMode or UniGenCFlag: 170 Str = WriteLine(Str, 'extern unsigned char ' + BaseName + 'Strings[];') 171 return "".join(Str) 172 173## Create a complete .h file 174# 175# Create a complet .h file with file header and file content 176# 177# @param BaseName: The basename of strings 178# @param UniObjectClass A UniObjectClass instance 179# @param IsCompatibleMode Compatible mode 180# @param UniGenCFlag UniString is generated into AutoGen C file when it is set to True 181# 182# @retval Str: A string of complete .h file 183# 184def CreateHFile(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag): 185 HFile = WriteLine('', CreateHFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniGenCFlag)) 186 187 return "".join(HFile) 188 189## Create a buffer to store all items in an array 190# 191# @param BinBuffer Buffer to contain Binary data. 192# @param Array: The array need to be formatted 193# 194def CreateBinBuffer(BinBuffer, Array): 195 for Item in Array: 196 BinBuffer.write(pack("B", int(Item, 16))) 197 198## Create a formatted string all items in an array 199# 200# Use ',' to join each item in an array, and break an new line when reaching the width (default is 16) 201# 202# @param Array: The array need to be formatted 203# @param Width: The line length, the default value is set to 16 204# 205# @retval ArrayItem: A string for all formatted array items 206# 207def CreateArrayItem(Array, Width = 16): 208 MaxLength = Width 209 Index = 0 210 Line = ' ' 211 ArrayItem = [] 212 213 for Item in Array: 214 if Index < MaxLength: 215 Line = Line + Item + ', ' 216 Index = Index + 1 217 else: 218 ArrayItem = WriteLine(ArrayItem, Line) 219 Line = ' ' + Item + ', ' 220 Index = 1 221 ArrayItem = Write(ArrayItem, Line.rstrip()) 222 223 return "".join(ArrayItem) 224 225## CreateCFileStringValue 226# 227# Create a line with string value 228# 229# @param Value: Value of the string 230# 231# @retval Str: A formatted string with string value 232# 233 234def CreateCFileStringValue(Value): 235 Value = [StringBlockType] + Value 236 Str = WriteLine('', CreateArrayItem(Value)) 237 238 return "".join(Str) 239 240## GetFilteredLanguage 241# 242# apply get best language rules to the UNI language code list 243# 244# @param UniLanguageList: language code definition list in *.UNI file 245# @param LanguageFilterList: language code filter list of RFC4646 format in DSC file 246# 247# @retval UniLanguageListFiltered: the filtered language code 248# 249def GetFilteredLanguage(UniLanguageList, LanguageFilterList): 250 UniLanguageListFiltered = [] 251 # if filter list is empty, then consider there is no filter 252 if LanguageFilterList == []: 253 UniLanguageListFiltered = UniLanguageList 254 return UniLanguageListFiltered 255 for Language in LanguageFilterList: 256 # first check for exact match 257 if Language in UniLanguageList: 258 if Language not in UniLanguageListFiltered: 259 UniLanguageListFiltered.append(Language) 260 # find the first one with the same/equivalent primary tag 261 else: 262 if Language.find('-') != -1: 263 PrimaryTag = Language[0:Language.find('-')].lower() 264 else: 265 PrimaryTag = Language 266 267 if len(PrimaryTag) == 3: 268 PrimaryTag = LangConvTable.get(PrimaryTag) 269 270 for UniLanguage in UniLanguageList: 271 if UniLanguage.find('-') != -1: 272 UniLanguagePrimaryTag = UniLanguage[0:UniLanguage.find('-')].lower() 273 else: 274 UniLanguagePrimaryTag = UniLanguage 275 276 if len(UniLanguagePrimaryTag) == 3: 277 UniLanguagePrimaryTag = LangConvTable.get(UniLanguagePrimaryTag) 278 279 if PrimaryTag == UniLanguagePrimaryTag: 280 if UniLanguage not in UniLanguageListFiltered: 281 UniLanguageListFiltered.append(UniLanguage) 282 break 283 else: 284 # Here is rule 3 for "get best language" 285 # If tag is not listed in the Unicode file, the default ("en") tag should be used for that language 286 # for better processing, find the one that best suit for it. 287 DefaultTag = 'en' 288 if DefaultTag not in UniLanguageListFiltered: 289 # check whether language code with primary code equivalent with DefaultTag already in the list, if so, use that 290 for UniLanguage in UniLanguageList: 291 if UniLanguage.startswith('en-') or UniLanguage.startswith('eng-'): 292 if UniLanguage not in UniLanguageListFiltered: 293 UniLanguageListFiltered.append(UniLanguage) 294 break 295 else: 296 UniLanguageListFiltered.append(DefaultTag) 297 return UniLanguageListFiltered 298 299 300## Create content of .c file 301# 302# Create content of .c file 303# 304# @param BaseName: The basename of strings 305# @param UniObjectClass A UniObjectClass instance 306# @param IsCompatibleMode Compatible mode 307# @param UniBinBuffer UniBinBuffer to contain UniBinary data. 308# @param FilterInfo Platform language filter information 309# 310# @retval Str: A string of .c file content 311# 312def CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, UniBinBuffer, FilterInfo): 313 # 314 # Init array length 315 # 316 TotalLength = EFI_HII_ARRAY_SIZE_LENGTH 317 Str = '' 318 Offset = 0 319 320 EDK2Module = FilterInfo[0] 321 if EDK2Module: 322 LanguageFilterList = FilterInfo[1] 323 else: 324 # EDK module is using ISO639-2 format filter, convert to the RFC4646 format 325 LanguageFilterList = [LangConvTable.get(F.lower()) for F in FilterInfo[1]] 326 327 UniLanguageList = [] 328 for IndexI in range(len(UniObjectClass.LanguageDef)): 329 UniLanguageList += [UniObjectClass.LanguageDef[IndexI][0]] 330 331 UniLanguageListFiltered = GetFilteredLanguage(UniLanguageList, LanguageFilterList) 332 333 334 # 335 # Create lines for each language's strings 336 # 337 for IndexI in range(len(UniObjectClass.LanguageDef)): 338 Language = UniObjectClass.LanguageDef[IndexI][0] 339 if Language not in UniLanguageListFiltered: 340 continue 341 342 StringBuffer = BytesIO() 343 StrStringValue = '' 344 ArrayLength = 0 345 NumberOfUseOtherLangDef = 0 346 Index = 0 347 for IndexJ in range(1, len(UniObjectClass.OrderedStringList[UniObjectClass.LanguageDef[IndexI][0]])): 348 Item = UniObjectClass.OrderedStringListByToken[Language][IndexJ] 349 350 Name = Item.StringName 351 Value = Item.StringValueByteList 352 Referenced = Item.Referenced 353 Token = Item.Token 354 UseOtherLangDef = Item.UseOtherLangDef 355 356 if UseOtherLangDef != '' and Referenced: 357 NumberOfUseOtherLangDef = NumberOfUseOtherLangDef + 1 358 Index = Index + 1 359 else: 360 if NumberOfUseOtherLangDef > 0: 361 StrStringValue = WriteLine(StrStringValue, CreateArrayItem([StringSkipType] + DecToHexList(NumberOfUseOtherLangDef, 4))) 362 CreateBinBuffer (StringBuffer, ([StringSkipType] + DecToHexList(NumberOfUseOtherLangDef, 4))) 363 NumberOfUseOtherLangDef = 0 364 ArrayLength = ArrayLength + 3 365 if Referenced and Item.Token > 0: 366 Index = Index + 1 367 StrStringValue = WriteLine(StrStringValue, "// %s: %s:%s" % (DecToHexStr(Index, 4), Name, DecToHexStr(Token, 4))) 368 StrStringValue = Write(StrStringValue, CreateCFileStringValue(Value)) 369 CreateBinBuffer (StringBuffer, [StringBlockType] + Value) 370 ArrayLength = ArrayLength + Item.Length + 1 # 1 is for the length of string type 371 372 # 373 # EFI_HII_PACKAGE_HEADER 374 # 375 Offset = EFI_HII_STRING_PACKAGE_HDR_LENGTH + len(Language) + 1 376 ArrayLength = Offset + ArrayLength + 1 377 378 # 379 # Create PACKAGE HEADER 380 # 381 Str = WriteLine(Str, '// PACKAGE HEADER\n') 382 TotalLength = TotalLength + ArrayLength 383 384 List = DecToHexList(ArrayLength, 6) + \ 385 [StringPackageType] + \ 386 DecToHexList(Offset) + \ 387 DecToHexList(Offset) + \ 388 DecToHexList(EFI_HII_LANGUAGE_WINDOW, EFI_HII_LANGUAGE_WINDOW_LENGTH * 2) * EFI_HII_LANGUAGE_WINDOW_NUMBER + \ 389 DecToHexList(EFI_STRING_ID, 4) + \ 390 AscToHexList(Language) + \ 391 DecToHexList(0, 2) 392 Str = WriteLine(Str, CreateArrayItem(List, 16) + '\n') 393 394 # 395 # Create PACKAGE DATA 396 # 397 Str = WriteLine(Str, '// PACKAGE DATA\n') 398 Str = Write(Str, StrStringValue) 399 400 # 401 # Add an EFI_HII_SIBT_END at last 402 # 403 Str = WriteLine(Str, ' ' + EFI_HII_SIBT_END + ",") 404 405 # 406 # Create binary UNI string 407 # 408 if UniBinBuffer: 409 CreateBinBuffer (UniBinBuffer, List) 410 UniBinBuffer.write (StringBuffer.getvalue()) 411 UniBinBuffer.write (pack("B", int(EFI_HII_SIBT_END, 16))) 412 StringBuffer.close() 413 414 # 415 # Create line for string variable name 416 # "unsigned char $(BaseName)Strings[] = {" 417 # 418 AllStr = WriteLine('', CHAR_ARRAY_DEFIN + ' ' + BaseName + COMMON_FILE_NAME + '[] = {\n') 419 420 if IsCompatibleMode: 421 # 422 # Create FRAMEWORK_EFI_HII_PACK_HEADER in compatible mode 423 # 424 AllStr = WriteLine(AllStr, '// FRAMEWORK PACKAGE HEADER Length') 425 AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(TotalLength + 2)) + '\n') 426 AllStr = WriteLine(AllStr, '// FRAMEWORK PACKAGE HEADER Type') 427 AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(2, 4)) + '\n') 428 else: 429 # 430 # Create whole array length in UEFI mode 431 # 432 AllStr = WriteLine(AllStr, '// STRGATHER_OUTPUT_HEADER') 433 AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(TotalLength)) + '\n') 434 435 # 436 # Join package data 437 # 438 AllStr = Write(AllStr, Str) 439 440 return "".join(AllStr) 441 442## Create end of .c file 443# 444# Create end of .c file 445# 446# @retval Str: A string of .h file end 447# 448def CreateCFileEnd(): 449 Str = Write('', '};') 450 return Str 451 452## Create a .c file 453# 454# Create a complete .c file 455# 456# @param BaseName: The basename of strings 457# @param UniObjectClass A UniObjectClass instance 458# @param IsCompatibleMode Compatible Mode 459# @param FilterInfo Platform language filter information 460# 461# @retval CFile: A string of complete .c file 462# 463def CreateCFile(BaseName, UniObjectClass, IsCompatibleMode, FilterInfo): 464 CFile = '' 465 CFile = WriteLine(CFile, CreateCFileContent(BaseName, UniObjectClass, IsCompatibleMode, None, FilterInfo)) 466 CFile = WriteLine(CFile, CreateCFileEnd()) 467 return "".join(CFile) 468 469## GetFileList 470# 471# Get a list for all files 472# 473# @param IncludeList: A list of all path to be searched 474# @param SkipList: A list of all types of file could be skipped 475# 476# @retval FileList: A list of all files found 477# 478def GetFileList(SourceFileList, IncludeList, SkipList): 479 if IncludeList is None: 480 EdkLogger.error("UnicodeStringGather", AUTOGEN_ERROR, "Include path for unicode file is not defined") 481 482 FileList = [] 483 if SkipList is None: 484 SkipList = [] 485 486 for File in SourceFileList: 487 for Dir in IncludeList: 488 if not os.path.exists(Dir): 489 continue 490 File = os.path.join(Dir, File.Path) 491 # 492 # Ignore Dir 493 # 494 if os.path.isfile(File) != True: 495 continue 496 # 497 # Ignore file listed in skip list 498 # 499 IsSkip = False 500 for Skip in SkipList: 501 if os.path.splitext(File)[1].upper() == Skip.upper(): 502 EdkLogger.verbose("Skipped %s for string token uses search" % File) 503 IsSkip = True 504 break 505 506 if not IsSkip: 507 FileList.append(File) 508 509 break 510 511 return FileList 512 513## SearchString 514# 515# Search whether all string defined in UniObjectClass are referenced 516# All string used should be set to Referenced 517# 518# @param UniObjectClass: Input UniObjectClass 519# @param FileList: Search path list 520# @param IsCompatibleMode Compatible Mode 521# 522# @retval UniObjectClass: UniObjectClass after searched 523# 524def SearchString(UniObjectClass, FileList, IsCompatibleMode): 525 if FileList == []: 526 return UniObjectClass 527 528 for File in FileList: 529 if os.path.isfile(File): 530 Lines = open(File, 'r') 531 for Line in Lines: 532 for StrName in STRING_TOKEN.findall(Line): 533 EdkLogger.debug(EdkLogger.DEBUG_5, "Found string identifier: " + StrName) 534 UniObjectClass.SetStringReferenced(StrName) 535 536 UniObjectClass.ReToken() 537 538 return UniObjectClass 539 540## GetStringFiles 541# 542# This function is used for UEFI2.1 spec 543# 544# 545def GetStringFiles(UniFilList, SourceFileList, IncludeList, IncludePathList, SkipList, BaseName, IsCompatibleMode = False, ShellMode = False, UniGenCFlag = True, UniGenBinBuffer = None, FilterInfo = [True, []]): 546 if len(UniFilList) > 0: 547 if ShellMode: 548 # 549 # support ISO 639-2 codes in .UNI files of EDK Shell 550 # 551 Uni = UniFileClassObject(sorted(UniFilList, key=lambda x: x.File), True, IncludePathList) 552 else: 553 Uni = UniFileClassObject(sorted(UniFilList, key=lambda x: x.File), IsCompatibleMode, IncludePathList) 554 else: 555 EdkLogger.error("UnicodeStringGather", AUTOGEN_ERROR, 'No unicode files given') 556 557 FileList = GetFileList(SourceFileList, IncludeList, SkipList) 558 559 Uni = SearchString(Uni, sorted (FileList), IsCompatibleMode) 560 561 HFile = CreateHFile(BaseName, Uni, IsCompatibleMode, UniGenCFlag) 562 CFile = None 563 if IsCompatibleMode or UniGenCFlag: 564 CFile = CreateCFile(BaseName, Uni, IsCompatibleMode, FilterInfo) 565 if UniGenBinBuffer: 566 CreateCFileContent(BaseName, Uni, IsCompatibleMode, UniGenBinBuffer, FilterInfo) 567 568 return HFile, CFile 569 570# 571# Write an item 572# 573def Write(Target, Item): 574 if isinstance(Target,str): 575 Target = [Target] 576 if not Target: 577 Target = [] 578 if isinstance(Item,list): 579 Target.extend(Item) 580 else: 581 Target.append(Item) 582 return Target 583 584# 585# Write an item with a break line 586# 587def WriteLine(Target, Item): 588 if isinstance(Target,str): 589 Target = [Target] 590 if not Target: 591 Target = [] 592 if isinstance(Item, list): 593 Target.extend(Item) 594 else: 595 Target.append(Item) 596 Target.append('\n') 597 return Target 598 599# This acts like the main() function for the script, unless it is 'import'ed into another 600# script. 601if __name__ == '__main__': 602 EdkLogger.info('start') 603 604 UniFileList = [ 605 r'C:\\Edk\\Strings2.uni', 606 r'C:\\Edk\\Strings.uni' 607 ] 608 609 SrcFileList = [] 610 for Root, Dirs, Files in os.walk('C:\\Edk'): 611 for File in Files: 612 SrcFileList.append(File) 613 614 IncludeList = [ 615 r'C:\\Edk' 616 ] 617 618 SkipList = ['.inf', '.uni'] 619 BaseName = 'DriverSample' 620 (h, c) = GetStringFiles(UniFileList, SrcFileList, IncludeList, SkipList, BaseName, True) 621 hfile = open('unistring.h', 'w') 622 cfile = open('unistring.c', 'w') 623 hfile.write(h) 624 cfile.write(c) 625 626 EdkLogger.info('end') 627