FormatDosFiles.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # @file FormatDosFiles.py
  2. # This script format the source files to follow dos style.
  3. # It supports Python2.x and Python3.x both.
  4. #
  5. # Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
  6. #
  7. # SPDX-License-Identifier: BSD-2-Clause-Patent
  8. #
  9. #
  10. # Import Modules
  11. #
  12. from __future__ import print_function
  13. import argparse
  14. import os
  15. import os.path
  16. import re
  17. import sys
  18. import copy
  19. __prog__ = 'FormatDosFiles'
  20. __version__ = '%s Version %s' % (__prog__, '0.10 ')
  21. __copyright__ = 'Copyright (c) 2018-2019, Intel Corporation. All rights reserved.'
  22. __description__ = 'Convert source files to meet the EDKII C Coding Standards Specification.\n'
  23. DEFAULT_EXT_LIST = ['.h', '.c', '.nasm', '.nasmb', '.asm', '.S', '.inf', '.dec', '.dsc', '.fdf', '.uni', '.asl', '.aslc', '.vfr', '.idf', '.txt', '.bat', '.py']
  24. #For working in python2 and python3 environment, re pattern should use binary string, which is bytes type in python3.
  25. #Because in python3,read from file in binary mode will return bytes type,and in python3 bytes type can not be mixed with str type.
  26. def FormatFile(FilePath, Args):
  27. with open(FilePath, 'rb') as Fd:
  28. Content = Fd.read()
  29. # Convert the line endings to CRLF
  30. Content = re.sub(br'([^\r])\n', br'\1\r\n', Content)
  31. Content = re.sub(br'^\n', br'\r\n', Content, flags=re.MULTILINE)
  32. # Add a new empty line if the file is not end with one
  33. Content = re.sub(br'([^\r\n])$', br'\1\r\n', Content)
  34. # Remove trailing white spaces
  35. Content = re.sub(br'[ \t]+(\r\n)', br'\1', Content, flags=re.MULTILINE)
  36. # Replace '\t' with two spaces
  37. Content = re.sub(b'\t', b' ', Content)
  38. with open(FilePath, 'wb') as Fd:
  39. Fd.write(Content)
  40. if not Args.Quiet:
  41. print(FilePath)
  42. def FormatFilesInDir(DirPath, ExtList, Args):
  43. FileList = []
  44. ExcludeDir = DirPath
  45. for DirPath, DirNames, FileNames in os.walk(DirPath):
  46. if Args.Exclude:
  47. DirNames[:] = [d for d in DirNames if d not in Args.Exclude]
  48. FileNames[:] = [f for f in FileNames if f not in Args.Exclude]
  49. Continue = False
  50. for Path in Args.Exclude:
  51. Path = Path.strip('\\').strip('/')
  52. if not os.path.isdir(Path) and not os.path.isfile(Path):
  53. Path = os.path.join(ExcludeDir, Path)
  54. if os.path.isdir(Path) and Path.endswith(DirPath):
  55. DirNames[:] = []
  56. Continue = True
  57. elif os.path.isfile(Path):
  58. FilePaths = FileNames
  59. for ItemPath in FilePaths:
  60. FilePath = os.path.join(DirPath, ItemPath)
  61. if Path.endswith(FilePath):
  62. FileNames.remove(ItemPath)
  63. if Continue:
  64. continue
  65. for FileName in [f for f in FileNames if any(f.endswith(ext) for ext in ExtList)]:
  66. FileList.append(os.path.join(DirPath, FileName))
  67. for File in FileList:
  68. FormatFile(File, Args)
  69. if __name__ == "__main__":
  70. parser = argparse.ArgumentParser(prog=__prog__, description=__description__ + __copyright__, conflict_handler = 'resolve')
  71. parser.add_argument('Path', nargs='+',
  72. help='the path for files to be converted.It could be directory or file path.')
  73. parser.add_argument('--version', action='version', version=__version__)
  74. parser.add_argument('--append-extensions', dest='AppendExt', nargs='+',
  75. help='append file extensions filter to default extensions. (Example: .txt .c .h)')
  76. parser.add_argument('--override-extensions', dest='OverrideExt', nargs='+',
  77. help='override file extensions filter on default extensions. (Example: .txt .c .h)')
  78. parser.add_argument('-v', '--verbose', dest='Verbose', action='store_true',
  79. help='increase output messages')
  80. parser.add_argument('-q', '--quiet', dest='Quiet', action='store_true',
  81. help='reduce output messages')
  82. parser.add_argument('--debug', dest='Debug', type=int, metavar='[0-9]', choices=range(0, 10), default=0,
  83. help='set debug level')
  84. parser.add_argument('--exclude', dest='Exclude', nargs='+', help="directory name or file name which will be excluded")
  85. args = parser.parse_args()
  86. DefaultExt = copy.copy(DEFAULT_EXT_LIST)
  87. if args.OverrideExt is not None:
  88. DefaultExt = args.OverrideExt
  89. if args.AppendExt is not None:
  90. DefaultExt = list(set(DefaultExt + args.AppendExt))
  91. for Path in args.Path:
  92. if not os.path.exists(Path):
  93. print("not exists path: {0}".format(Path))
  94. sys.exit(1)
  95. if os.path.isdir(Path):
  96. FormatFilesInDir(Path, DefaultExt, args)
  97. elif os.path.isfile(Path):
  98. FormatFile(Path, args)