| #!/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)) |