Subversion Repositories HomeAutomation

Rev

Go to most recent revision | Details | Last modification | View Log | SVN | RSS feed

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