#!/usr/bin/python3 import re import argparse parser = argparse.ArgumentParser() parser.add_argument('inputs', nargs='+', help='Input filename') parser.add_argument('--min_lines', type=int, default=1, help='Specify the min number of lines to rearrange') args = parser.parse_args() min_num_lines = args.min_lines filename_regex = '(src|source|unit_test|include)/.*$' # caveat: Does fully not handle numbers with different number of digits. def compare_strs(str1, str2): winner = 0 # which one's bigger num_sort_mode = False for i in range(min(len(str1),len(str2))): if winner == 0: if str1[i].isdigit() and str2[i].isdigit(): if num_sort_mode: str1_num += str1[i] str2_num += str2[i] else: num_sort_mode = True str1_num = str1[i] str2_num = str2[i] elif num_sort_mode: if str1[i].isdigit(): str1_num += str1[i] if str2[i].isdigit(): str2_num += str2[i] winner = int(str1_num) - int(str2_num) num_sort_mode = False if winner != 0: break if str1[i] != str2[i] and not num_sort_mode: if str1[i] > str2[i]: winner = 1 else: winner = -1 if num_sort_mode: # if it's still in num_sort_mode then find the results if len(str1)-1 > i: i += 1 if str1[i].isdigit(): str1_num += str1[i] elif len(str2)-1 > i: i += 1 if str2[i].isdigit(): str2_num += str2[i] if int(str1_num) > int(str2_num): winner = 1 elif int(str1_num) < int(str2_num): winner = -1 num_sort_mode = False if winner == 0: if len(str1) != len(str2): if len(str1) > len(str2): winner = 1 else: winner = -1 return winner def cmp_to_key(mycmp): 'Convert a cmp= function into a key= function' class K: def __init__(self, obj, *args): self.obj = obj def __lt__(self, other): return mycmp(self.obj, other.obj) < 0 def __gt__(self, other): return mycmp(self.obj, other.obj) > 0 def __eq__(self, other): return mycmp(self.obj, other.obj) == 0 def __le__(self, other): return mycmp(self.obj, other.obj) <= 0 def __ge__(self, other): return mycmp(self.obj, other.obj) >= 0 def __ne__(self, other): return mycmp(self.obj, other.obj) != 0 return K def custom_sort(listy): for _ in range(len(listy)-1+1): for i in range(len(listy)-1): bigger = compare_strs(listy[i], listy[i+1]) if bigger > 0: tmp_str = listy[i] listy[i] = listy[i+1] listy[i+1] = tmp_str return listy # file_lines = [l.strip(stripchars) for l in file_lines] # currently sorting by first number in filename. smallest numbers first # this thing may need the ability to recognize filenames # file_lines = sorted(file_lines, key=lambda line: int(re.search('\d+', line.split('/')[-1] + ' 0').group(0))) input_filenames=args.inputs for input_filename in input_filenames: with open(input_filename,'r') as file: file_lines = file.read().split('\n') output_filename=input_filename files_range = [] # is a tuple filenames_ranges = [] for i, line in enumerate(file_lines): if re.search(filename_regex, line): if files_range == []: files_range.append(i) else: if files_range != []: files_range.append(i-1) # manages min num lines if files_range[1] - files_range[0] + 1 >= min_num_lines:filenames_ranges.append(files_range) files_range = [] if files_range != []: files_range.append(i-1) # manages min num lines if files_range[1] - files_range[0] + 1 >= min_num_lines:filenames_ranges.append(files_range) files_range = [] for x in filenames_ranges: # accommodate for a close bracket at the end of the last filename if file_lines[x[1]][-1] == ')': append_chars = ')' file_lines[x[1]] = file_lines[x[1]][:-1] else: append_chars = '' new_lines = sorted(file_lines[x[0]:x[1]+1], key=cmp_to_key(compare_strs)) for i, l in enumerate(range(x[0], x[1]+1)): file_lines[l] = new_lines[i] if l == x[1]: file_lines[l] += append_chars with open(output_filename, 'w') as file: file.write('\n'.join(file_lines))