-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcmc.py
executable file
·152 lines (117 loc) · 6.33 KB
/
cmc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/python
import re, argparse, os
class CMakeFile:
metadata = {
"headers" : {"regex" : "(?P<declaration>set(\w)*\((\w)*\${PROJECT_NAME}_HEADERS)(?P<files>.*?)\)", "ext" : ".h"},
"implementations" : {"regex" : "(?P<declaration>set(\w)*\((\w)*\${PROJECT_NAME}_SOURCES)(?P<files>.*?)\)", "ext" : ".cpp"},
}
def __init__(self, filename):
self.filename = filename
self.outro = "";
self.groups = [];
with open(self.filename, "r") as cmfile:
text_file = cmfile.read()
found_dict = {}
for key, value in CMakeFile.metadata.iteritems():
match = re.search(value["regex"], text_file, re.DOTALL)
found_dict[match.end()] = value
found_dict[match.end()].update({"match" : match})
found_dict[match.end()].update({"category" : key})
previous_match_end = 0
for key in sorted(found_dict.keys()):
entry = found_dict[key]
match = entry["match"]
self.groups.append( (text_file[previous_match_end:match.start()],
match.group("declaration"),
FileList(match.group("files"), entry["category"]),
"\n)",
))
previous_match_end = match.end()
self.outro = text_file[previous_match_end:]
def __filter_category(self, category_filter_list):
return [file_list for file_list in [group[2] for group in self.groups]
if file_list.category in category_filter_list]
def insert_names(self, name_list, category_filter_list):
new_files = map(lambda x: x.insert_names(name_list), self.__filter_category(category_filter_list))
[open(filename, "a") for filename_list in new_files for filename in filename_list]
def remove_names(self, name_list, category_filter_list):
removed_files = map(lambda x: x.remove_names(name_list), self.__filter_category(category_filter_list))
[os.remove(filename) for filename_list in removed_files for filename in filename_list]
def move_name(self, source_name, dest_name, category_filter_list):
moved_files = map(lambda x: x.move_name(source_name, dest_name), self.__filter_category(category_filter_list))
[os.rename(file_pair[0], file_pair[1]) for file_pair in moved_files if file_pair]
def save_file(self):
output_file = ''.join(str(i) for group in self.groups for i in group)
output_file = output_file + self.outro
with open(self.filename, "w") as cmfile:
cmfile.write(output_file)
class FileList:
def __init__(self, string_list, category):
self.category = category
self.metaref = CMakeFile.metadata[self.category]
self.file_list = string_list.split()
def sort_unicity_filelist(self):
self.file_list = sorted(list(set(self.file_list)))
def complete_filename(self, basename):
return basename + self.metaref["ext"]
def generate_filelist(self, name_list):
return [self.complete_filename(basename) for basename in name_list]
def insert_names(self, name_list):
new_names = self.generate_filelist(name_list)
self.file_list.extend(new_names)
self.sort_unicity_filelist()
return new_names
def remove_names(self, name_list) :
removed_names = [name
for name in self.generate_filelist(name_list)
if name in self.file_list]
[self.file_list.remove(name) for name in removed_names]
return removed_names
def move_name(self, source_name, dest_name) :
source_file = self.complete_filename(source_name)
dest_file = self.complete_filename(dest_name)
if self.file_list.count(source_file):
self.file_list.remove(source_file)
self.file_list.append(dest_file)
self.sort_unicity_filelist()
return (source_file, dest_file)
else:
return None
def __str__(self):
#prepend an empty element, to get the separator before the first elem in file_list
return "\n ".join(['']+self.file_list)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description = 'Add classes to a project.')
parser.add_argument ("command", choices=['add', 'mv', 'remove'],
help="The action that will be taken on the provided classname(s)")
parser.add_argument ("classname", nargs="+", help="The name of the class(es) to apply the command onto, in the current project directory.")
parser.add_argument ("--headers", action="store_true", help="Create header files only. Has the precedence over other filters.")
parser.add_argument ("--implementations", action="store_true", help="Create implementation files only.")
parser.add_argument ("--headers_ext", "--he", help="Replace the default header files extension ["
+ CMakeFile.metadata["headers"]["ext"] + "].")
parser.add_argument ("--implementations_ext", "--ie", help="Replace the default implementation files extension ["
+ CMakeFile.metadata["implementations"]["ext"] + "].")
args = parser.parse_args()
cm_file = CMakeFile("CMakeLists.txt")
if args.headers :
filter = ["headers"]
elif args.implementations :
filter = ["implementations"]
else :
filter = ["headers", "implementations"]
if args.headers_ext:
ext = args.headers_ext
CMakeFile.metadata["headers"]["ext"] = ext if ext.startswith(".") else "."+ext
if args.implementations_ext:
ext = args.implementations_ext
CMakeFile.metadata["implementations"]["ext"] = ext if ext.startswith(".") else "."+ext
if args.command == 'mv' :
if len(args.classname) != 2:
sys.exit(1)
cm_file.move_name(*args.classname, category_filter_list=filter)
elif args.command == 'remove' :
# \todo Would be better if the program was inferring the implementation files extension for removal.
cm_file.remove_names(args.classname, filter)
else :
cm_file.insert_names(args.classname, filter)
cm_file.save_file()