Subversion Repositories HomeAutomation

Rev

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