#!/usr/bin/env python # # for python3.5 or higher #----------------------------------- # Within Marlin project MarlinFirmware/Configurations, this program visits all folders # under .../config/examples/*, processing each Configuration.h, Configuration_adv.h, # _Bootscreen.h, and _Statusscreen.h, to insert: # #define CONFIG_EXAMPLES_DIR "examples/<style>/<vendor>/<model>" # ... or similar path leading to this file. # # Warning: The program modifies files in place, so be sure to back them up first if needed. # Can be run multiple times if needed. Only modifies files which don't have # correct #define CONFIG_EXAMPLES_DIR line. # # Invocation: #------------- # 1. Change directory to your MarlinFirmware/Configurations working copy # 2. python3 config-labels.py # #----------------------------------- # 2020-05-10 GMW original # 2020-06-05 SRL style tweaks #----------------------------------- # import sys import os from pathlib import Path from distutils.dir_util import copy_tree # for copy_tree, because shutil.copytree can't handle existing files, dirs # Modify input_examples_dir and output_examples_dir for your installation # No trailing slash # Setting output_examples_dir = input_examples_dir causes the program to insert into the existing files. input_examples_dir = r'config/examples' # output_examples_dir = input_examples_dir output_examples_dir = r'config/examples' #------------------------------------- files_to_mod = ['Configuration.h', 'Configuration_adv.h', '_Bootscreen.h', '_Statusscreen.h'] macro_name = 'CONFIG_EXAMPLES_DIR' def_macro_name = '#define ' + macro_name filenum = 0 different_out_dir = not (output_examples_dir == input_examples_dir) #---------------------------------------------- def process_file(subdir: str, filename: str): #---------------------------------------------- global filenum filenum += 1 print(str(filenum) + ' ' + filename + ': ' + subdir) def_line = (def_macro_name + ' "' + subdir.replace('\\', '/') + '"') #------------------------ # Read file #------------------------ lines = [] infilepath = os.path.join(input_examples_dir, subdir, filename) try: # UTF-8 because some files contain unicode chars with open(infilepath, 'rt', encoding="utf-8") as infile: lines = infile.readlines() except Exception as e: print('Failed to read file: ' + str(e) ) raise Exception lines = [line.rstrip('\r\n') for line in lines] #------------------------ # Process lines #------------------------ file_modified = False # region state machine # -1 = before pragma once; # 0 = region to place define; # 1 = past region to place define region = -1 outlines = [] for line in lines: outline = line if (region == -1) and (def_macro_name in line): outline = None file_modified = True elif (region == -1) and ('pragma once' in line): region = 0 elif (region == 0): if (line.strip() == ''): pass elif (def_macro_name in line): region = 1 if line == def_line: # leave it as is pass else: outline = def_line file_modified = True else: # some other string outlines.append(def_line) outlines.append('') region = 1 file_modified = True elif (region == 1): if (def_macro_name in line): outline = None file_modified = True else: pass # end if if outline is not None: outlines.append(outline) # end for #------------------------- # Output file #------------------------- outdir = os.path.join(output_examples_dir, subdir) outfilepath = os.path.join(outdir, filename) if file_modified: # Note: no need to create output dirs, as the initial copy_tree # will do that. print(' writing ' + str(outfilepath)) try: # Preserve unicode chars; Avoid CR-LF on Windows. with open(outfilepath, "w", encoding="utf-8", newline='\n') as outfile: outfile.write("\n".join(outlines)) outfile.write("\n") except Exception as e: print('Failed to write file: ' + str(e) ) raise Exception else: print(' no change for ' + str(outfilepath)) #---------- def main(): #---------- global filenum global input_examples_dir global output_examples_dir filenum = 0 #-------------------------------- # Check for requirements #-------------------------------- input_examples_dir = input_examples_dir.strip() input_examples_dir = input_examples_dir.rstrip('\\/') output_examples_dir = output_examples_dir.strip() output_examples_dir = output_examples_dir.rstrip('\\/') for dir in [input_examples_dir, output_examples_dir]: if not (os.path.exists(dir)): print('Directory not found: ' + dir) sys.exit(1) #-------------------------------- # Copy tree if necessary. #-------------------------------- # This includes files that are not otherwise included in the # insertion of the define statement. # if different_out_dir: print('Copying files to new directory: ' + output_examples_dir) try: copy_tree(input_examples_dir, output_examples_dir) except Exception as e: print('Failed to copy directory: ' + str(e) ) raise Exception #----------------------------- # Find and process files #----------------------------- len_input_examples_dir = len(input_examples_dir); len_input_examples_dir += 1 for filename in files_to_mod: input_path = Path(input_examples_dir) filepathlist = input_path.rglob(filename) for filepath in filepathlist: fulldirpath = str(filepath.parent) subdir = fulldirpath[len_input_examples_dir:] process_file(subdir, filename) #============== print('--- Starting config-labels ---') main() print('--- Done ---')