Subversion Repositories HomeAutomation

Rev

Rev 1258 | Rev 1572 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
979 linlun 1
#!/usr/bin/python
825 migan 2
 
819 migan 3
# Written by Mattias Runge 2008-05-13
4
 
5
import os
6
import sys
7
import getopt
8
 
852 migan 9
moddir = sys.path[0] + "/../../EmbeddedSoftware/AVR/module"
10
localmoddir = os.getcwd() + "/modules"
819 migan 11
 
12
def getModules():
13
	modules = []
14
	for fileName in os.listdir(moddir):
887 migan 15
		if fileName[0] != '.' and fileName != "template":
819 migan 16
			modules.append(fileName)
17
 
18
	return modules
19
 
20
 
21
def getLocalModules():
22
	modules = []
23
	for fileName in os.listdir(localmoddir):
24
		if fileName[0] != '.':
25
			modules.append(fileName)
26
 
27
	return modules
28
 
29
 
30
def parseModuleIdFromFile(moduleName, fileName):
31
	config_inc = open(fileName, 'r') 
32
	config_inc_lines = config_inc.readlines()
33
	config_inc.close()
34
 
35
	for line in config_inc_lines:
36
		line = line.strip("\n").strip(" ")
827 migan 37
 
819 migan 38
		if line.find(moduleName + "_ID") != -1:
39
			parts = line.split("=")
40
			return parts[1].strip(" ")
41
 
42
	return -1;
43
 
44
 
45
def getFreeModuleId(moduleName):
46
	takenIds = []
827 migan 47
 
819 migan 48
	for applicationName in os.listdir("../"):
827 migan 49
 
819 migan 50
		if applicationName[0] != '.' and os.path.exists("../" + applicationName + "/config.inc"):
51
			takenId = parseModuleIdFromFile(moduleName, "../" + applicationName + "/config.inc")
52
			if takenId != -1 and takenId != "<ID>":
53
				takenIds.append(int(takenId, 16))
54
 
55
	if len(takenIds) == 0:
56
		return "0x01"
57
 
58
	takenIds.sort()
59
 
60
	lastId = 0
61
 
62
	for takenId in takenIds:
63
		if takenId != lastId+1:
64
			return hex(lastId+1)
827 migan 65
		lastId = takenId
819 migan 66
 
67
	return hex(lastId+1)
68
 
69
 
70
def compileMainFile():
71
	print "Compiling new main.c..."
72
	main_c_template = open('src/main.c.template', 'r') 
73
	main_c_template_lines = main_c_template.readlines()
74
	main_c_template.close()
75
 
76
	modules = getLocalModules()
77
 
78
	main_c = open('src/main.c', 'w') 
79
 
80
	for main_c_template_line in main_c_template_lines:
81
		pos_include = main_c_template_line.find('%INCLUDE')
82
		pos_init = main_c_template_line.find('%INIT')
83
		pos_process = main_c_template_line.find('%PROCESS')
84
		pos_list = main_c_template_line.find('%LIST')
85
		pos_handlemsg = main_c_template_line.find('%HANDLEMSG')
86
 
87
		if pos_include != -1:
88
			for moduleName in modules:
822 migan 89
				main_c.write(main_c_template_line[:pos_include] + "#include \"../modules/" + moduleName + "/" + moduleName + ".h\"\n")
819 migan 90
		elif pos_init != -1:
91
			for moduleName in modules:
839 migan 92
				main_c.write(main_c_template_line[:pos_init] + moduleName + "_Init();\n")
819 migan 93
		elif pos_process != -1:
94
			for moduleName in modules:
839 migan 95
				main_c.write(main_c_template_line[:pos_process] + moduleName + "_Process();\n")
819 migan 96
		elif pos_list != -1:
97
			count = 1
98
			for moduleName in modules:
839 migan 99
				main_c.write(main_c_template_line[:pos_list] + moduleName + "_List(" + str(count) + ");\n")
819 migan 100
				count += 1
101
		elif pos_handlemsg != -1:
102
			for moduleName in modules:
839 migan 103
				main_c.write(main_c_template_line[:pos_handlemsg] + moduleName + "_HandleMessage(&rxMsg);\n")
819 migan 104
		else:
105
			main_c.write(main_c_template_line)
106
 
107
	main_c.close()
108
 
109
	print "Creation of main.c complete"
110
 
111
def readConfigSection(fileName, sectionName):
112
	fileInstance = open(fileName, 'r')
113
	lines = fileInstance.readlines()
114
	fileInstance.close()
115
 
116
	sectionLines = []
117
 
118
	inSection = False
119
 
120
	for line in lines:
121
		if not inSection:
122
			if line.find("## Section " + sectionName) != -1:
123
				inSection = True
124
				sectionLines.append(line.strip("\n"))
125
		else:
126
			if line.find("## End section " + sectionName) != -1:
127
				inSection = False
128
 
129
			sectionLines.append(line.strip("\n"))
130
 
131
	return sectionLines
132
 
133
 
134
def updateConfigFile():
135
	print "Updating config.inc..."
136
 
137
	modules = getLocalModules()
138
	moduleSections = {}
139
	applicationSection = []
140
 
141
	if not os.path.exists("config.inc"):
142
		applicationSection = readConfigSection("src/config.inc.template", "application")
143
 
144
		for moduleName in modules:
145
			moduleSections[moduleName] = readConfigSection(localmoddir + "/" + moduleName + "/config.inc.template", moduleName)
146
	else:
147
		applicationSection = readConfigSection("config.inc", "application")
148
 
149
		for moduleName in modules:
150
			moduleSections[moduleName] = readConfigSection("config.inc", moduleName)
151
 
152
			if len(moduleSections[moduleName]) <= 1:
153
				moduleSections[moduleName] = readConfigSection(localmoddir + "/" + moduleName + "/config.inc.template", moduleName)
154
 
155
	timers = 0
1125 linlun 156
	pcints = 0
819 migan 157
 
158
	for moduleName, moduleSection in moduleSections.iteritems():
159
		c = 0
160
		for line in moduleSection:
1259 runge 161
			if len(line) > 0:
162
				if line[0] != '#':
163
					if line.find("<ID>") != -1:
164
						line = line.replace("<ID>", getFreeModuleId(moduleName))
165
					elif line.find("<TIMER>") != -1:
166
						line = line[:line.find("=")+1] + hex(timers) + " /* <TIMER> -- DO NOT REMOVE THIS COMMENT -- */"
167
						timers += 1
168
					elif line.find("<PCINT>") != -1:
169
						line = line[:line.find("=")+1] + hex(pcints) + " /* <PCINT> -- DO NOT REMOVE THIS COMMENT -- */"
170
						pcints += 1
171
 
172
			moduleSection[c] = line;
173
			c += 1
174
 
175
	c = 0
176
	for line in applicationSection:
177
		if len(line) > 0:
1258 runge 178
			if line[0] != '#':
1259 runge 179
				if line.find("<TIMER>") != -1:
1258 runge 180
					line = line[:line.find("=")+1] + hex(timers) + " /* <TIMER> -- DO NOT REMOVE THIS COMMENT -- */"
181
					timers += 1
1259 runge 182
				elif line.find("TIMER_NUM_TIMERS=") != -1:
183
					line = "TIMER_NUM_TIMERS=" + hex(timers)
184
				elif line.find("NUMBER_OF_MODULES=") != -1:
185
					line = "NUMBER_OF_MODULES=" + hex(len(modules))
1258 runge 186
				elif line.find("<PCINT>") != -1:
187
					line = line[:line.find("=")+1] + hex(pcints) + " /* <PCINT> -- DO NOT REMOVE THIS COMMENT -- */"
188
					pcints += 1
1259 runge 189
				elif line.find("PCINT_NUM_PCINTS=") != -1:
190
					line = "PCINT_NUM_PCINTS=" + hex(pcints)
819 migan 191
		applicationSection[c] = line;
192
		c += 1
193
 
194
	config_inc = open('config.inc', 'w')
195
 
196
	for line in applicationSection:
197
		config_inc.write(line + "\n")
198
 
199
	for moduleName, moduleSection in moduleSections.iteritems():
200
		for line in moduleSection:
201
			config_inc.write(line + "\n")
202
 
203
	config_inc.close()
204
 
205
	print "Update of config.inc complete"
206
 
207
 
208
def compileSourcesFile():
209
	print "Compiling sources.inc..."
210
 
211
	uniqueSet = []
212
 
213
	sources_list_template = open('src/sources.list.template', 'r')
214
	sources_list_template_lines = sources_list_template.readlines()
215
	sources_list_template.close()
216
 
217
	for sources_list_template_line in sources_list_template_lines:
847 migan 218
		line = sources_list_template_line.strip("\n").strip(" ")
219
		if len(line) > 0:
220
			if line[0] != '#':
221
				uniqueSet.append(line)
819 migan 222
 
223
	modules = getLocalModules()
224
 
225
	for moduleName in modules:
226
		sources_list = open(localmoddir + "/" + moduleName + "/sources.list", 'r')
227
		sources_list_lines = sources_list.readlines()
228
		sources_list.close()
229
 
230
		for sources_list_line in sources_list_lines:
847 migan 231
			line = sources_list_line.strip("\n").strip(" ")
232
			if len(line) > 0:
233
				if line[0] != '#':
234
					uniqueSet.append(line)
235
 
819 migan 236
 
237
	sourcesString = "SOURCES = "
238
 
239
	#FIXME: Make uniqueSet actually unique
240
 
241
	for line in uniqueSet:
242
		sourcesString += line + " "
243
 
244
	sources_inc = open('sources.inc', 'w')
245
	sources_inc.write(sourcesString.strip(" ") + "\n")
246
	sources_inc.close()
247
 
248
	print "Creation of sources.inc complete"
249
 
250
 
251
def regenerateModules():
252
	print "Regenerating modules..."
836 migan 253
	print ""
819 migan 254
	compileSourcesFile()
836 migan 255
	print ""
819 migan 256
	compileMainFile()
836 migan 257
	print ""
819 migan 258
	updateConfigFile()
836 migan 259
	print ""
819 migan 260
	print "Regenerating modules complete"
836 migan 261
	print ""
819 migan 262
 
263
 
264
def addModule(moduleName):
265
	print "Trying to add module " + moduleName
266
 
267
	try:
852 migan 268
		os.symlink(moddir + "/" + moduleName, localmoddir + "/" + moduleName)
820 migan 269
		print "Added module successfully"
819 migan 270
	except OSError, (errno, strerror):
271
		if errno == 17:
272
			print "A link, file or directory named " + moduleName + " is already present in the modules directory, not linking"
273
		else:
274
			raise
275
 
276
	print ""
277
 
278
	regenerateModules()
279
 
280
 
824 migan 281
def delModule(moduleName):
282
	print "Trying to remove module " + moduleName
283
 
284
	try:
285
		os.unlink(localmoddir + "/" + moduleName)
286
		print "Removed module successfully"
287
	except OSError, (errno, strerror):
288
		if errno == 2:
289
			print "No such " + moduleName + " present in the modules directory, not unlinking"
290
		else:
291
			raise
292
 
293
	print ""
294
 
295
	regenerateModules()
296
 
852 migan 297
def createFile(moduleName, templateFileName, moduleFileName):
298
	print "Creating " + moduleName + "/" + templateFileName + "..."
299
	template_file = open(moddir + "/template/" + templateFileName, 'r')
300
	lines = template_file.readlines()
301
	template_file.close()
824 migan 302
 
852 migan 303
	module_file = open(moddir + "/" + moduleName + "/" + moduleFileName, 'w')
304
 
305
	for line in lines:
306
		line = line.replace("<template>", moduleName)
307
		line = line.replace("<TEMPLATE>", moduleName.upper())
308
 
309
		module_file.write(line)
310
 
311
	module_file.close()
312
 
313
def newModule(moduleName):
314
	print "Creating " + moddir + "/" + moduleName + " directory..."
315
	os.mkdir(moddir + "/" + moduleName + "/")
316
 
317
	createFile(moduleName, "config.inc.template", "config.inc.template")
318
	createFile(moduleName, "sources.list", "sources.list")
319
	createFile(moduleName, "template.h", moduleName + ".h")
320
	createFile(moduleName, "template.c", moduleName + ".c")
1106 linlun 321
	createFile(moduleName, "template_eeprom.h", moduleName + "_eeprom.h")
852 migan 322
 
819 migan 323
def usage():
836 migan 324
	print "Syntax: ./ModuleManager [options]"
819 migan 325
	print "Options:"
836 migan 326
	print "  --help               Print this help"
327
	print "  --regenerate         Regenarate modules and files"
328
	print "  --list               List avalible and installed modules"
329
	print "  --add=<module name>  Adds a module to the application"
330
	print "  --del=<module name>  Removes a module from the application"
852 migan 331
	print "  --new=<module name>  Creates a new module from the module template"
819 migan 332
	print ""
333
 
334
 
335
def main():
336
	try:
885 migan 337
		opts, args = getopt.getopt(sys.argv[1:], "hlrc", ["help", "list", "regenerate", "add=", "del=", "new="])
819 migan 338
	except getopt.GetoptError, err:
339
		# print help information and exit:
340
		print str(err) # will print something like "option -a not recognized"
341
		usage()
342
		sys.exit(2)
825 migan 343
 
344
	if len(sys.argv) == 1:
345
		usage()
346
		sys.exit()
347
 
819 migan 348
	for o, a in opts:
885 migan 349
		if o in ("-c"):
836 migan 350
			modules = getModules()
824 migan 351
 
885 migan 352
			for module in modules:
353
				print module
354
 
355
		elif o in ("-l", "--list"):
356
			modules = getModules()
357
 
836 migan 358
			print "Available modules"
359
			print "================="
360
			for module in modules:
361
				print module
362
 
885 migan 363
 
364
			if os.path.exists(localmoddir):
365
				print ""
836 migan 366
 
885 migan 367
				modules = getLocalModules()
836 migan 368
 
885 migan 369
				print "Modules used in this application"
370
				print "================================"
371
				for module in modules:
372
					print module
373
 
819 migan 374
		elif o in ("-h", "--help"):
375
			usage()
376
			sys.exit()
824 migan 377
 
819 migan 378
		elif o in ("-r", "--regenerate"):
379
			regenerateModules()
824 migan 380
 
819 migan 381
		elif o in ("--add"):
382
			if len(a) == 0:
383
				print "No modulename specified"
384
				usage()
385
				sys.exit()
386
 
387
			if a not in getModules():
388
				print a + " is not a recognized module name"
389
				sys.exit()
390
 
391
			addModule(a)
824 migan 392
 
393
		elif o in ("--del"):
394
			if len(a) == 0:
395
				print "No modulename specified"
396
				usage()
397
				sys.exit()
398
 
399
			if a not in getModules():
400
				print a + " is not a recognized module name"
401
				sys.exit()
402
 
403
			delModule(a)
404
 
852 migan 405
		elif o in ("--new"):
406
			if len(a) == 0:
407
				print "No modulename specified"
408
				usage()
409
				sys.exit()
410
 
411
			if a in getModules():
412
				print a + " already exists"
413
				sys.exit()
414
 
415
			newModule(a)
416
 
819 migan 417
		else:
418
			assert False, "unhandled option"
419
 
420
 
421
if __name__ == "__main__":
422
	main()
423