Subversion Repositories HomeAutomation

Rev

Rev 1106 | Rev 1126 | 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:
161
			if line.find("<ID>") != -1:
162
				line = line.replace("<ID>", getFreeModuleId(moduleName))
163
			elif line.find("<TIMER>") != -1:
164
				line = line[:line.find("=")+1] + hex(timers) + " /* <TIMER> -- DO NOT REMOVE THIS COMMENT -- */"
165
				timers += 1
1125 linlun 166
			elif line.find("<PCINT>") != -1:
167
				line = line[:line.find("=")+1] + hex(timers) + " /* <PCINT> -- DO NOT REMOVE THIS COMMENT -- */"
168
				pcints += 1
169
 
819 migan 170
			moduleSection[c] = line;
171
			c += 1
172
 
173
	c = 0
174
	for line in applicationSection:
175
		if line.find("<TIMER>") != -1:
176
			line = line[:line.find("=")+1] + hex(timers) + " /* <TIMER> -- DO NOT REMOVE THIS COMMENT -- */"
177
			timers += 1
828 migan 178
		elif line.find("TIMER_NUM_TIMERS=") != -1:
179
			line = "TIMER_NUM_TIMERS=" + hex(timers)
180
		elif line.find("NUMBER_OF_MODULES=") != -1:
181
			line = "NUMBER_OF_MODULES=" + hex(len(modules))
1125 linlun 182
		elif line.find("<PCINT>") != -1:
183
			line = line[:line.find("=")+1] + hex(pcints) + " /* <PCINT> -- DO NOT REMOVE THIS COMMENT -- */"
184
			pcints += 1
185
		elif line.find("PCINT_NUM_PCINTS=") != -1:
186
			line = "PCINT_NUM_PCINTS=" + hex(pcints)
819 migan 187
		applicationSection[c] = line;
188
		c += 1
189
 
190
	config_inc = open('config.inc', 'w')
191
 
192
	for line in applicationSection:
193
		config_inc.write(line + "\n")
194
 
195
	for moduleName, moduleSection in moduleSections.iteritems():
196
		for line in moduleSection:
197
			config_inc.write(line + "\n")
198
 
199
	config_inc.close()
200
 
201
	print "Update of config.inc complete"
202
 
203
 
204
def compileSourcesFile():
205
	print "Compiling sources.inc..."
206
 
207
	uniqueSet = []
208
 
209
	sources_list_template = open('src/sources.list.template', 'r')
210
	sources_list_template_lines = sources_list_template.readlines()
211
	sources_list_template.close()
212
 
213
	for sources_list_template_line in sources_list_template_lines:
847 migan 214
		line = sources_list_template_line.strip("\n").strip(" ")
215
		if len(line) > 0:
216
			if line[0] != '#':
217
				uniqueSet.append(line)
819 migan 218
 
219
	modules = getLocalModules()
220
 
221
	for moduleName in modules:
222
		sources_list = open(localmoddir + "/" + moduleName + "/sources.list", 'r')
223
		sources_list_lines = sources_list.readlines()
224
		sources_list.close()
225
 
226
		for sources_list_line in sources_list_lines:
847 migan 227
			line = sources_list_line.strip("\n").strip(" ")
228
			if len(line) > 0:
229
				if line[0] != '#':
230
					uniqueSet.append(line)
231
 
819 migan 232
 
233
	sourcesString = "SOURCES = "
234
 
235
	#FIXME: Make uniqueSet actually unique
236
 
237
	for line in uniqueSet:
238
		sourcesString += line + " "
239
 
240
	sources_inc = open('sources.inc', 'w')
241
	sources_inc.write(sourcesString.strip(" ") + "\n")
242
	sources_inc.close()
243
 
244
	print "Creation of sources.inc complete"
245
 
246
 
247
def regenerateModules():
248
	print "Regenerating modules..."
836 migan 249
	print ""
819 migan 250
	compileSourcesFile()
836 migan 251
	print ""
819 migan 252
	compileMainFile()
836 migan 253
	print ""
819 migan 254
	updateConfigFile()
836 migan 255
	print ""
819 migan 256
	print "Regenerating modules complete"
836 migan 257
	print ""
819 migan 258
 
259
 
260
def addModule(moduleName):
261
	print "Trying to add module " + moduleName
262
 
263
	try:
852 migan 264
		os.symlink(moddir + "/" + moduleName, localmoddir + "/" + moduleName)
820 migan 265
		print "Added module successfully"
819 migan 266
	except OSError, (errno, strerror):
267
		if errno == 17:
268
			print "A link, file or directory named " + moduleName + " is already present in the modules directory, not linking"
269
		else:
270
			raise
271
 
272
	print ""
273
 
274
	regenerateModules()
275
 
276
 
824 migan 277
def delModule(moduleName):
278
	print "Trying to remove module " + moduleName
279
 
280
	try:
281
		os.unlink(localmoddir + "/" + moduleName)
282
		print "Removed module successfully"
283
	except OSError, (errno, strerror):
284
		if errno == 2:
285
			print "No such " + moduleName + " present in the modules directory, not unlinking"
286
		else:
287
			raise
288
 
289
	print ""
290
 
291
	regenerateModules()
292
 
852 migan 293
def createFile(moduleName, templateFileName, moduleFileName):
294
	print "Creating " + moduleName + "/" + templateFileName + "..."
295
	template_file = open(moddir + "/template/" + templateFileName, 'r')
296
	lines = template_file.readlines()
297
	template_file.close()
824 migan 298
 
852 migan 299
	module_file = open(moddir + "/" + moduleName + "/" + moduleFileName, 'w')
300
 
301
	for line in lines:
302
		line = line.replace("<template>", moduleName)
303
		line = line.replace("<TEMPLATE>", moduleName.upper())
304
 
305
		module_file.write(line)
306
 
307
	module_file.close()
308
 
309
def newModule(moduleName):
310
	print "Creating " + moddir + "/" + moduleName + " directory..."
311
	os.mkdir(moddir + "/" + moduleName + "/")
312
 
313
	createFile(moduleName, "config.inc.template", "config.inc.template")
314
	createFile(moduleName, "sources.list", "sources.list")
315
	createFile(moduleName, "template.h", moduleName + ".h")
316
	createFile(moduleName, "template.c", moduleName + ".c")
1106 linlun 317
	createFile(moduleName, "template_eeprom.h", moduleName + "_eeprom.h")
852 migan 318
 
819 migan 319
def usage():
836 migan 320
	print "Syntax: ./ModuleManager [options]"
819 migan 321
	print "Options:"
836 migan 322
	print "  --help               Print this help"
323
	print "  --regenerate         Regenarate modules and files"
324
	print "  --list               List avalible and installed modules"
325
	print "  --add=<module name>  Adds a module to the application"
326
	print "  --del=<module name>  Removes a module from the application"
852 migan 327
	print "  --new=<module name>  Creates a new module from the module template"
819 migan 328
	print ""
329
 
330
 
331
def main():
332
	try:
885 migan 333
		opts, args = getopt.getopt(sys.argv[1:], "hlrc", ["help", "list", "regenerate", "add=", "del=", "new="])
819 migan 334
	except getopt.GetoptError, err:
335
		# print help information and exit:
336
		print str(err) # will print something like "option -a not recognized"
337
		usage()
338
		sys.exit(2)
825 migan 339
 
340
	if len(sys.argv) == 1:
341
		usage()
342
		sys.exit()
343
 
819 migan 344
	for o, a in opts:
885 migan 345
		if o in ("-c"):
836 migan 346
			modules = getModules()
824 migan 347
 
885 migan 348
			for module in modules:
349
				print module
350
 
351
		elif o in ("-l", "--list"):
352
			modules = getModules()
353
 
836 migan 354
			print "Available modules"
355
			print "================="
356
			for module in modules:
357
				print module
358
 
885 migan 359
 
360
			if os.path.exists(localmoddir):
361
				print ""
836 migan 362
 
885 migan 363
				modules = getLocalModules()
836 migan 364
 
885 migan 365
				print "Modules used in this application"
366
				print "================================"
367
				for module in modules:
368
					print module
369
 
819 migan 370
		elif o in ("-h", "--help"):
371
			usage()
372
			sys.exit()
824 migan 373
 
819 migan 374
		elif o in ("-r", "--regenerate"):
375
			regenerateModules()
824 migan 376
 
819 migan 377
		elif o in ("--add"):
378
			if len(a) == 0:
379
				print "No modulename specified"
380
				usage()
381
				sys.exit()
382
 
383
			if a not in getModules():
384
				print a + " is not a recognized module name"
385
				sys.exit()
386
 
387
			addModule(a)
824 migan 388
 
389
		elif o in ("--del"):
390
			if len(a) == 0:
391
				print "No modulename specified"
392
				usage()
393
				sys.exit()
394
 
395
			if a not in getModules():
396
				print a + " is not a recognized module name"
397
				sys.exit()
398
 
399
			delModule(a)
400
 
852 migan 401
		elif o in ("--new"):
402
			if len(a) == 0:
403
				print "No modulename specified"
404
				usage()
405
				sys.exit()
406
 
407
			if a in getModules():
408
				print a + " already exists"
409
				sys.exit()
410
 
411
			newModule(a)
412
 
819 migan 413
		else:
414
			assert False, "unhandled option"
415
 
416
 
417
if __name__ == "__main__":
418
	main()
419