config-labels.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #!/usr/bin/env python3
  2. #
  3. # for python3.5 or higher
  4. #-----------------------------------
  5. # Within Marlin project MarlinFirmware/Configurations, this program visits all folders
  6. # under .../config/examples/*, processing each Configuration.h, Configuration_adv.h,
  7. # _Bootscreen.h, and _Statusscreen.h, to insert:
  8. # #define CONFIG_EXAMPLES_DIR "examples/<style>/<vendor>/<model>"
  9. # ... or similar path leading to this file.
  10. #
  11. # Warning: The program modifies files in place, so be sure to back them up first if needed.
  12. # Can be run multiple times if needed. Only modifies files which don't have
  13. # correct #define CONFIG_EXAMPLES_DIR line.
  14. #
  15. # Invocation:
  16. #-------------
  17. # 1. Change directory to your MarlinFirmware/Configurations working copy
  18. # 2. python3 config-labels.py
  19. #
  20. #-----------------------------------
  21. # 2020-05-10 GMW original
  22. # 2020-06-05 SRL style tweaks
  23. #-----------------------------------
  24. #
  25. import sys
  26. import os
  27. from pathlib import Path
  28. from distutils.dir_util import copy_tree # for copy_tree, because shutil.copytree can't handle existing files, dirs
  29. # Modify input_examples_dir and output_examples_dir for your installation
  30. # No trailing slash
  31. # Setting output_examples_dir = input_examples_dir causes the program to insert into the existing files.
  32. input_examples_dir = r'config/examples'
  33. # output_examples_dir = input_examples_dir
  34. output_examples_dir = r'config/examples'
  35. #-------------------------------------
  36. files_to_mod = ['Configuration.h', 'Configuration_adv.h', '_Bootscreen.h', '_Statusscreen.h']
  37. macro_name = 'CONFIG_EXAMPLES_DIR'
  38. def_macro_name = '#define ' + macro_name
  39. filenum = 0
  40. different_out_dir = not (output_examples_dir == input_examples_dir)
  41. #----------------------------------------------
  42. def process_file(subdir: str, filename: str):
  43. #----------------------------------------------
  44. global filenum
  45. filenum += 1
  46. print(str(filenum) + ' ' + filename + ': ' + subdir)
  47. def_line = (def_macro_name + ' "' + subdir.replace('\\', '/') + '"')
  48. #------------------------
  49. # Read file
  50. #------------------------
  51. lines = []
  52. infilepath = os.path.join(input_examples_dir, subdir, filename)
  53. try:
  54. # UTF-8 because some files contain unicode chars
  55. with open(infilepath, 'rt', encoding="utf-8") as infile:
  56. lines = infile.readlines()
  57. except Exception as e:
  58. print('Failed to read file: ' + str(e) )
  59. raise Exception
  60. lines = [line.rstrip('\r\n') for line in lines]
  61. #------------------------
  62. # Process lines
  63. #------------------------
  64. file_modified = False
  65. # region state machine
  66. # -1 = before pragma once;
  67. # 0 = region to place define;
  68. # 1 = past region to place define
  69. region = -1
  70. outlines = []
  71. for line in lines:
  72. outline = line
  73. if (region == -1) and (def_macro_name in line):
  74. outline = None
  75. file_modified = True
  76. elif (region == -1) and ('pragma once' in line):
  77. region = 0
  78. elif (region == 0):
  79. if (line.strip() == ''):
  80. pass
  81. elif (def_macro_name in line):
  82. region = 1
  83. if line == def_line: # leave it as is
  84. pass
  85. else:
  86. outline = def_line
  87. file_modified = True
  88. else: # some other string
  89. outlines.append(def_line)
  90. outlines.append('')
  91. region = 1
  92. file_modified = True
  93. elif (region == 1):
  94. if (def_macro_name in line):
  95. outline = None
  96. file_modified = True
  97. else:
  98. pass
  99. # end if
  100. if outline is not None:
  101. outlines.append(outline)
  102. # end for
  103. #-------------------------
  104. # Output file
  105. #-------------------------
  106. outdir = os.path.join(output_examples_dir, subdir)
  107. outfilepath = os.path.join(outdir, filename)
  108. if file_modified:
  109. # Note: no need to create output dirs, as the initial copy_tree
  110. # will do that.
  111. print(' writing ' + str(outfilepath))
  112. try:
  113. # Preserve unicode chars; Avoid CR-LF on Windows.
  114. with open(outfilepath, "w", encoding="utf-8", newline='\n') as outfile:
  115. outfile.write("\n".join(outlines))
  116. outfile.write("\n")
  117. except Exception as e:
  118. print('Failed to write file: ' + str(e) )
  119. raise Exception
  120. else:
  121. print(' no change for ' + str(outfilepath))
  122. #----------
  123. def main():
  124. #----------
  125. global filenum
  126. global input_examples_dir
  127. global output_examples_dir
  128. filenum = 0
  129. #--------------------------------
  130. # Check for requirements
  131. #--------------------------------
  132. input_examples_dir = input_examples_dir.strip()
  133. input_examples_dir = input_examples_dir.rstrip('\\/')
  134. output_examples_dir = output_examples_dir.strip()
  135. output_examples_dir = output_examples_dir.rstrip('\\/')
  136. for dir in [input_examples_dir, output_examples_dir]:
  137. if not (os.path.exists(dir)):
  138. print('Directory not found: ' + dir)
  139. sys.exit(1)
  140. #--------------------------------
  141. # Copy tree if necessary.
  142. #--------------------------------
  143. # This includes files that are not otherwise included in the
  144. # insertion of the define statement.
  145. #
  146. if different_out_dir:
  147. print('Copying files to new directory: ' + output_examples_dir)
  148. try:
  149. copy_tree(input_examples_dir, output_examples_dir)
  150. except Exception as e:
  151. print('Failed to copy directory: ' + str(e) )
  152. raise Exception
  153. #-----------------------------
  154. # Find and process files
  155. #-----------------------------
  156. len_input_examples_dir = len(input_examples_dir);
  157. len_input_examples_dir += 1
  158. for filename in files_to_mod:
  159. input_path = Path(input_examples_dir)
  160. filepathlist = input_path.rglob(filename)
  161. for filepath in filepathlist:
  162. fulldirpath = str(filepath.parent)
  163. subdir = fulldirpath[len_input_examples_dir:]
  164. process_file(subdir, filename)
  165. #==============
  166. print('--- Starting config-labels ---')
  167. main()
  168. print('--- Done ---')