Subversion Repositories HomeAutomation

Rev

Rev 824 | Blame | Last modification | View Log | SVN | RSS feed

  1. #!/bin/env python
  2.  
  3. # Written by Mattias Runge 2008-05-13
  4.  
  5. import os
  6. import sys
  7. import getopt
  8.  
  9. moddir = '../../module'
  10. localmoddir = 'modules'
  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(" ")
  37.         if line.find(moduleName + "_ID") != -1:
  38.             parts = line.split("=")
  39.             return parts[1].strip(" ")
  40.    
  41.     return -1;
  42.  
  43.  
  44. def getFreeModuleId(moduleName):
  45.     takenIds = []
  46.    
  47.     for applicationName in os.listdir("../"):
  48.         if applicationName[0] != '.' and os.path.exists("../" + applicationName + "/config.inc"):
  49.             takenId = parseModuleIdFromFile(moduleName, "../" + applicationName + "/config.inc")
  50.            
  51.             if takenId != -1 and takenId != "<ID>":
  52.                 takenIds.append(int(takenId, 16))
  53.  
  54.     if len(takenIds) == 0:
  55.         return "0x01"
  56.  
  57.     takenIds.sort()
  58.  
  59.     lastId = 0
  60.  
  61.     for takenId in takenIds:
  62.         if takenId != lastId+1:
  63.             return hex(lastId+1)
  64.  
  65.     return hex(lastId+1)
  66.    
  67.  
  68. def compileMainFile():
  69.     print "Compiling new main.c..."
  70.     main_c_template = open('src/main.c.template', 'r')
  71.     main_c_template_lines = main_c_template.readlines()
  72.     main_c_template.close()
  73.    
  74.     modules = getLocalModules()
  75.    
  76.     main_c = open('src/main.c', 'w')
  77.    
  78.     for main_c_template_line in main_c_template_lines:
  79.         pos_include = main_c_template_line.find('%INCLUDE')
  80.         pos_init = main_c_template_line.find('%INIT')
  81.         pos_process = main_c_template_line.find('%PROCESS')
  82.         pos_list = main_c_template_line.find('%LIST')
  83.         pos_handlemsg = main_c_template_line.find('%HANDLEMSG')
  84.        
  85.         if pos_include != -1:
  86.             for moduleName in modules:
  87.                 main_c.write(main_c_template_line[:pos_include] + "#include \"../modules/" + moduleName + "/" + moduleName + ".h\"\n")
  88.         elif pos_init != -1:
  89.             for moduleName in modules:
  90.                 main_c.write(main_c_template_line[:pos_init] + moduleName + "_Init();\n")
  91.         elif pos_process != -1:
  92.             for moduleName in modules:
  93.                 main_c.write(main_c_template_line[:pos_process] + moduleName + "_Process();\n")
  94.         elif pos_list != -1:
  95.             count = 1
  96.             for moduleName in modules:
  97.                 main_c.write(main_c_template_line[:pos_list] + moduleName + "_List(" + str(count) + ");\n")
  98.                 count += 1
  99.         elif pos_handlemsg != -1:
  100.             for moduleName in modules:
  101.                 main_c.write(main_c_template_line[:pos_handlemsg] + moduleName + "_HandleMessage(&rxMsg);\n")
  102.         else:
  103.             main_c.write(main_c_template_line)
  104.  
  105.     main_c.close()
  106.    
  107.     print "Creation of main.c complete"
  108.  
  109. def readConfigSection(fileName, sectionName):
  110.     fileInstance = open(fileName, 'r')
  111.     lines = fileInstance.readlines()
  112.     fileInstance.close()
  113.    
  114.     sectionLines = []
  115.    
  116.     inSection = False
  117.    
  118.     for line in lines:
  119.         if not inSection:
  120.             if line.find("## Section " + sectionName) != -1:
  121.                 inSection = True
  122.                 sectionLines.append(line.strip("\n"))
  123.         else:
  124.             if line.find("## End section " + sectionName) != -1:
  125.                 inSection = False
  126.                
  127.             sectionLines.append(line.strip("\n"))
  128.            
  129.     return sectionLines
  130.    
  131.  
  132. def updateConfigFile():
  133.     print "Updating config.inc..."
  134.    
  135.     modules = getLocalModules()
  136.     moduleSections = {}
  137.     applicationSection = []
  138.    
  139.     if not os.path.exists("config.inc"):
  140.         applicationSection = readConfigSection("src/config.inc.template", "application")
  141.        
  142.         for moduleName in modules:
  143.             moduleSections[moduleName] = readConfigSection(localmoddir + "/" + moduleName + "/config.inc.template", moduleName)
  144.     else:
  145.         applicationSection = readConfigSection("config.inc", "application")
  146.        
  147.         for moduleName in modules:
  148.             moduleSections[moduleName] = readConfigSection("config.inc", moduleName)
  149.            
  150.             if len(moduleSections[moduleName]) <= 1:
  151.                 moduleSections[moduleName] = readConfigSection(localmoddir + "/" + moduleName + "/config.inc.template", moduleName)
  152.    
  153.     timers = 0
  154.        
  155.     for moduleName, moduleSection in moduleSections.iteritems():
  156.         c = 0
  157.         for line in moduleSection:
  158.             if line.find("<ID>") != -1:
  159.                 line = line.replace("<ID>", getFreeModuleId(moduleName))
  160.             elif line.find("<TIMER>") != -1:
  161.                 line = line[:line.find("=")+1] + hex(timers) + " /* <TIMER> -- DO NOT REMOVE THIS COMMENT -- */"
  162.                 timers += 1
  163.                
  164.             moduleSection[c] = line;
  165.             c += 1
  166.    
  167.     c = 0
  168.     for line in applicationSection:
  169.         if line.find("<TIMER>") != -1:
  170.             line = line[:line.find("=")+1] + hex(timers) + " /* <TIMER> -- DO NOT REMOVE THIS COMMENT -- */"
  171.             timers += 1
  172.         elif line.find("<NUMBER_OF_TIMERS>") != -1:
  173.             line = line.replace("<NUMBER_OF_TIMERS>", hex(timers))
  174.         elif line.find("<NUMBER_OF_MODULES>") != -1:
  175.             line = line.replace("<NUMBER_OF_MODULES>", hex(len(modules)))
  176.        
  177.         applicationSection[c] = line;
  178.         c += 1
  179.        
  180.     config_inc = open('config.inc', 'w')
  181.    
  182.     for line in applicationSection:
  183.         config_inc.write(line + "\n")
  184.        
  185.     for moduleName, moduleSection in moduleSections.iteritems():
  186.         for line in moduleSection:
  187.             config_inc.write(line + "\n")
  188.        
  189.     config_inc.close()
  190.    
  191.     print "Update of config.inc complete"
  192.  
  193.  
  194. def compileSourcesFile():
  195.     print "Compiling sources.inc..."
  196.    
  197.     uniqueSet = []
  198.    
  199.     sources_list_template = open('src/sources.list.template', 'r')
  200.     sources_list_template_lines = sources_list_template.readlines()
  201.     sources_list_template.close()
  202.    
  203.     for sources_list_template_line in sources_list_template_lines:
  204.         if len(sources_list_template_line) > 0:
  205.             uniqueSet.append(sources_list_template_line.strip("\n"))
  206.        
  207.     modules = getLocalModules()
  208.    
  209.     for moduleName in modules:
  210.         sources_list = open(localmoddir + "/" + moduleName + "/sources.list", 'r')
  211.         sources_list_lines = sources_list.readlines()
  212.         sources_list.close()
  213.    
  214.         for sources_list_line in sources_list_lines:
  215.             if len(sources_list_line) > 0:
  216.                 uniqueSet.append(sources_list_line.strip("\n"))
  217.    
  218.     sourcesString = "SOURCES = "
  219.    
  220.     #FIXME: Make uniqueSet actually unique
  221.    
  222.     for line in uniqueSet:
  223.         sourcesString += line + " "
  224.        
  225.     sources_inc = open('sources.inc', 'w')
  226.     sources_inc.write(sourcesString.strip(" ") + "\n")
  227.     sources_inc.close()
  228.    
  229.     print "Creation of sources.inc complete"
  230.  
  231.  
  232. def regenerateModules():
  233.     print "Regenerating modules..."
  234.     compileSourcesFile()
  235.     compileMainFile()
  236.     updateConfigFile()
  237.     print "Regenerating modules complete"
  238.  
  239.  
  240. def addModule(moduleName):
  241.     print "Trying to add module " + moduleName
  242.    
  243.     try:
  244.         os.symlink("../" + moddir + "/" + moduleName, localmoddir + "/" + moduleName)
  245.         print "Added module successfully"
  246.     except OSError, (errno, strerror):
  247.         if errno == 17:
  248.             print "A link, file or directory named " + moduleName + " is already present in the modules directory, not linking"
  249.         else:
  250.             raise
  251.    
  252.     print ""
  253.    
  254.     regenerateModules()
  255.  
  256.  
  257. def delModule(moduleName):
  258.     print "Trying to remove module " + moduleName
  259.    
  260.     try:
  261.         os.unlink(localmoddir + "/" + moduleName)
  262.         print "Removed module successfully"
  263.     except OSError, (errno, strerror):
  264.         if errno == 2:
  265.             print "No such " + moduleName + " present in the modules directory, not unlinking"
  266.         else:
  267.             raise
  268.    
  269.     print ""
  270.    
  271.     regenerateModules()
  272.  
  273.  
  274. def usage():
  275.     print "Options:"
  276.     print "\t--regenare\t\tRegenarate modules and files"
  277.     print "\t--list\t\t\tList avalible modules"
  278.     print "\t--help\t\t\tPrint this help"
  279.     print "\t--add=<module name>\tAdds a module to the application"
  280.     print ""
  281.  
  282.  
  283. def main():
  284.     try:
  285.         opts, args = getopt.getopt(sys.argv[1:], "hlrd", ["help", "list", "regenerate", "add=", "del="])
  286.     except getopt.GetoptError, err:
  287.         # print help information and exit:
  288.         print str(err) # will print something like "option -a not recognized"
  289.         usage()
  290.         sys.exit(2)
  291.    
  292.     if len(sys.argv) == 1:
  293.         usage()
  294.         sys.exit()
  295.    
  296.     for o, a in opts:
  297.         if o in ("-l", "--list"):
  298.             print getModules()
  299.            
  300.         elif o in ("-h", "--help"):
  301.             usage()
  302.             sys.exit()
  303.            
  304.         elif o in ("-r", "--regenerate"):
  305.             regenerateModules()
  306.            
  307.         elif o in ("--add"):
  308.             if len(a) == 0:
  309.                 print "No modulename specified"
  310.                 usage()
  311.                 sys.exit()
  312.            
  313.             if a not in getModules():
  314.                 print a + " is not a recognized module name"
  315.                 sys.exit()
  316.                
  317.             addModule(a)
  318.            
  319.         elif o in ("--del"):
  320.             if len(a) == 0:
  321.                 print "No modulename specified"
  322.                 usage()
  323.                 sys.exit()
  324.            
  325.             if a not in getModules():
  326.                 print a + " is not a recognized module name"
  327.                 sys.exit()
  328.                
  329.             delModule(a)
  330.            
  331.         else:
  332.             assert False, "unhandled option"
  333.  
  334.  
  335. if __name__ == "__main__":
  336.     main()
  337.  
  338.