• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3
2import re
3import argparse
4
5parser = argparse.ArgumentParser()
6parser.add_argument('inputs', nargs='+', help='Input filename')
7parser.add_argument('--min_lines', type=int, default=1, help='Specify the min number of lines to rearrange')
8args = parser.parse_args()
9
10min_num_lines = args.min_lines
11
12filename_regex = '(src|source|unit_test|include)/.*$'
13
14# caveat: Does fully not handle numbers with different number of digits.
15def compare_strs(str1, str2):
16    winner = 0 # which one's bigger
17    num_sort_mode = False
18    for i in range(min(len(str1),len(str2))):
19        if winner == 0:
20            if str1[i].isdigit() and str2[i].isdigit():
21                if num_sort_mode:
22                    str1_num += str1[i]
23                    str2_num += str2[i]
24                else:
25                    num_sort_mode = True
26                    str1_num = str1[i]
27                    str2_num = str2[i]
28            elif num_sort_mode:
29                if str1[i].isdigit(): str1_num += str1[i]
30                if str2[i].isdigit(): str2_num += str2[i]
31                winner = int(str1_num) - int(str2_num)
32                num_sort_mode = False
33                if winner != 0: break
34            if str1[i] != str2[i] and not num_sort_mode:
35                if str1[i] > str2[i]:
36                    winner = 1
37                else:
38                    winner = -1
39    if num_sort_mode: # if it's still in num_sort_mode then find the results
40        if len(str1)-1 > i:
41            i += 1
42            if str1[i].isdigit(): str1_num += str1[i]
43        elif len(str2)-1 > i:
44            i += 1
45            if str2[i].isdigit(): str2_num += str2[i]
46        if int(str1_num) > int(str2_num):
47            winner = 1
48        elif int(str1_num) < int(str2_num):
49            winner = -1
50        num_sort_mode = False
51
52    if winner == 0:
53        if len(str1) != len(str2):
54            if len(str1) > len(str2):
55                winner = 1
56            else:
57                winner = -1
58    return winner
59
60def cmp_to_key(mycmp):
61    'Convert a cmp= function into a key= function'
62    class K:
63        def __init__(self, obj, *args):
64            self.obj = obj
65        def __lt__(self, other):
66            return mycmp(self.obj, other.obj) < 0
67        def __gt__(self, other):
68            return mycmp(self.obj, other.obj) > 0
69        def __eq__(self, other):
70            return mycmp(self.obj, other.obj) == 0
71        def __le__(self, other):
72            return mycmp(self.obj, other.obj) <= 0
73        def __ge__(self, other):
74            return mycmp(self.obj, other.obj) >= 0
75        def __ne__(self, other):
76            return mycmp(self.obj, other.obj) != 0
77    return K
78
79def custom_sort(listy):
80    for _ in range(len(listy)-1+1):
81        for i in range(len(listy)-1):
82            bigger = compare_strs(listy[i], listy[i+1])
83            if bigger > 0:
84                tmp_str = listy[i]
85                listy[i] = listy[i+1]
86                listy[i+1] = tmp_str
87    return listy
88
89# file_lines = [l.strip(stripchars) for l in file_lines]
90# currently sorting by first number in filename. smallest numbers first
91# this thing may need the ability to recognize filenames
92# file_lines = sorted(file_lines, key=lambda line: int(re.search('\d+', line.split('/')[-1] + ' 0').group(0)))
93input_filenames=args.inputs
94for input_filename in input_filenames:
95    with open(input_filename,'r') as file:
96        file_lines = file.read().split('\n')
97    output_filename=input_filename
98    files_range = [] # is a tuple
99    filenames_ranges = []
100    for i, line in enumerate(file_lines):
101        if re.search(filename_regex, line):
102            if files_range == []:
103                files_range.append(i)
104        else:
105            if files_range != []:
106                files_range.append(i-1)
107                # manages min num lines
108                if files_range[1] - files_range[0] + 1 >= min_num_lines:filenames_ranges.append(files_range)
109                files_range = []
110    if files_range != []:
111        files_range.append(i-1)
112        # manages min num lines
113        if files_range[1] - files_range[0] + 1 >= min_num_lines:filenames_ranges.append(files_range)
114        files_range = []
115
116
117    for x in filenames_ranges:
118        # accommodate for a close bracket at the end of the last filename
119        if file_lines[x[1]][-1] == ')':
120            append_chars = ')'
121            file_lines[x[1]] = file_lines[x[1]][:-1]
122        else:
123            append_chars = ''
124
125        new_lines = sorted(file_lines[x[0]:x[1]+1], key=cmp_to_key(compare_strs))
126        for i, l in enumerate(range(x[0], x[1]+1)):
127            file_lines[l] = new_lines[i]
128            if l == x[1]:
129                file_lines[l] += append_chars
130
131    with open(output_filename, 'w') as file:
132        file.write('\n'.join(file_lines))
133