plugger.py
changeset 47 fd45c291fed0
parent 41 1608a434fb8c
child 49 45dc6a944ab6
equal deleted inserted replaced
46:6f2689a2438b 47:fd45c291fed0
   158         return [],""
   158         return [],""
   159     
   159     
   160     def _Generate_C(self, buildpath, locations, logger):
   160     def _Generate_C(self, buildpath, locations, logger):
   161         # Generate plugins [(Cfiles, CFLAGS)], LDFLAGS
   161         # Generate plugins [(Cfiles, CFLAGS)], LDFLAGS
   162         PlugCFilesAndCFLAGS, PlugLDFLAGS = self.PlugGenerate_C(buildpath, locations, logger)
   162         PlugCFilesAndCFLAGS, PlugLDFLAGS = self.PlugGenerate_C(buildpath, locations, logger)
       
   163         # if some files heve been generated put them in the list with their location
       
   164         if PlugCFilesAndCFLAGS:
       
   165             LocationCFilesAndCFLAGS = [(self.GetCurrentLocation(), PlugCFilesAndCFLAGS)]
       
   166         else:
       
   167             LocationCFilesAndCFLAGS = []
       
   168 
       
   169         # plugin asks some some LDFLAGS
       
   170         if PlugLDFLAGS:
       
   171             # LDFLAGS can be either string
       
   172             if type(PlugLDFLAGS)==type(str()):
       
   173                 LDFLAGS=[PlugLDFLAGS]
       
   174             #or list of strings
       
   175             elif type(PlugLDFLAGS)==type(list()):
       
   176                 LDFLAGS=PlugLDFLAGS[:]
       
   177         else:
       
   178             LDFLAGS=[]
       
   179         
   163         # recurse through all childs, and stack their results
   180         # recurse through all childs, and stack their results
   164         for PlugChild in self.IterChilds():
   181         for PlugChild in self.IECSortedChilds():
   165             new_location = PlugChild.GetCurrentLocation()
   182             new_location = PlugChild.GetCurrentLocation()
   166             # How deep are we in the tree ?
   183             # How deep are we in the tree ?
   167             depth=len(new_location)
   184             depth=len(new_location)
   168             CFilesAndCFLAGS, LDFLAGS = \
   185             _LocationCFilesAndCFLAGS, _LDFLAGS = \
   169                 PlugChild._Generate_C(
   186                 PlugChild._Generate_C(
   170                     #keep the same path
   187                     #keep the same path
   171                     buildpath,
   188                     buildpath,
   172                     # filter locations that start with current IEC location
   189                     # filter locations that start with current IEC location
   173                     [loc for loc in locations if loc["LOC"][0:depth] == new_location ],
   190                     [loc for loc in locations if loc["LOC"][0:depth] == new_location ],
   174                     #propagete logger
   191                     #propagete logger
   175                     logger)
   192                     logger)
   176             # stack the result
   193             # stack the result
   177             PlugCFilesAndCFLAGS += CFilesAndCFLAGS
   194             LocationCFilesAndCFLAGS += _LocationCFilesAndCFLAGS
   178             PlugLDFLAGS += LDFLAGS
   195             LDFLAGS += _LDFLAGS
   179         
   196         
   180         return PlugCFilesAndCFLAGS,PlugLDFLAGS
   197         return LocationCFilesAndCFLAGS,LDFLAGS
   181 
   198 
   182     def BlockTypesFactory(self):
   199     def BlockTypesFactory(self):
   183         return []
   200         return []
   184 
   201 
   185     def STLibraryFactory(self):
   202     def STLibraryFactory(self):
   188     def IterChilds(self):
   205     def IterChilds(self):
   189         for PlugType, PluggedChilds in self.PluggedChilds.items():
   206         for PlugType, PluggedChilds in self.PluggedChilds.items():
   190             for PlugInstance in PluggedChilds:
   207             for PlugInstance in PluggedChilds:
   191                    yield PlugInstance
   208                    yield PlugInstance
   192     
   209     
   193     def _GetChildBySomething(self, sep, something, matching):
   210     def IECSortedChilds(self):
   194         toks = matching.split(sep,1)
   211         # reorder childs by IEC_channels
       
   212         ordered = [(chld.BaseParams.getIEC_Channel(),chld) for chld in self.IterChilds()]
       
   213         if ordered:
       
   214             ordered.sort()
       
   215             return zip(*ordered)[1]
       
   216         else:
       
   217             return []
       
   218     
       
   219     def _GetChildBySomething(self, something, toks):
   195         for PlugInstance in self.IterChilds():
   220         for PlugInstance in self.IterChilds():
   196             # if match component of the name
   221             # if match component of the name
   197             if getattr(PlugInstance.BaseParams, something) == toks[0]:
   222             if getattr(PlugInstance.BaseParams, something) == toks[0]:
   198                 # if Name have other components
   223                 # if Name have other components
   199                 if len(toks) == 2:
   224                 if len(toks) >= 2:
   200                     # Recurse in order to find the latest object
   225                     # Recurse in order to find the latest object
   201                     return PlugInstance._GetChildBySomething( sep, something, toks[1])
   226                     return PlugInstance._GetChildBySomething( something, toks[1:])
   202                 # No sub name -> found
   227                 # No sub name -> found
   203                 return PlugInstance
   228                 return PlugInstance
   204         # Not found
   229         # Not found
   205         return None
   230         return None
   206 
   231 
   207     def GetChildByName(self, Name):
   232     def GetChildByName(self, Name):
   208         return self._GetChildBySomething('.',"Name", Name)
   233         if Name:
       
   234             toks = Name.split('.')
       
   235             return self._GetChildBySomething("Name", toks)
       
   236         else:
       
   237             return self
   209 
   238 
   210     def GetChildByIECLocation(self, Location):
   239     def GetChildByIECLocation(self, Location):
   211         return self._GetChildBySomething('_',"IEC_Channel", Name)
   240         if Location:
       
   241             return self._GetChildBySomething("IEC_Channel", Location)
       
   242         else:
       
   243             return self
   212     
   244     
   213     def GetCurrentLocation(self):
   245     def GetCurrentLocation(self):
   214         """
   246         """
   215         @return:  Tupple containing plugin IEC location of current plugin : %I0.0.4.5 => (0,0,4,5)
   247         @return:  Tupple containing plugin IEC location of current plugin : %I0.0.4.5 => (0,0,4,5)
   216         """
   248         """
   217         return self.PlugParent.GetCurrentLocation() + (self.BaseParams.getIEC_Channel(),)
   249         return self.PlugParent.GetCurrentLocation() + (self.BaseParams.getIEC_Channel(),)
       
   250 
       
   251     def GetCurrentName(self):
       
   252         """
       
   253         @return:  String "ParentParentName.ParentName.Name"
       
   254         """
       
   255         return  self.PlugParent._GetCurrentName() + self.BaseParams.getName()
       
   256 
       
   257     def _GetCurrentName(self):
       
   258         """
       
   259         @return:  String "ParentParentName.ParentName.Name."
       
   260         """
       
   261         return  self.PlugParent._GetCurrentName() + self.BaseParams.getName() + "."
   218 
   262 
   219     def GetPlugRoot(self):
   263     def GetPlugRoot(self):
   220         return self.PlugParent.GetPlugRoot()
   264         return self.PlugParent.GetPlugRoot()
   221 
   265 
   222     def GetPlugInfos(self):
   266     def GetPlugInfos(self):
   223         childs = []
   267         childs = []
   224         # reorder childs by IEC_channels
   268         # reorder childs by IEC_channels
   225         ordered = [(chld.BaseParams.getIEC_Channel(),chld) for chld in self.IterChilds()]
   269         for child in self.IECSortedChilds():
   226         if ordered:
   270             childs.append(child.GetPlugInfos())
   227             ordered.sort()
       
   228             for child in zip(*ordered)[1]:
       
   229                 childs.append(child.GetPlugInfos())
       
   230         return {"name" : "%d-%s"%(self.BaseParams.getIEC_Channel(),self.BaseParams.getName()), "type" : self.BaseParams.getName(), "values" : childs}
   271         return {"name" : "%d-%s"%(self.BaseParams.getIEC_Channel(),self.BaseParams.getName()), "type" : self.BaseParams.getName(), "values" : childs}
   231     
       
   232     
   272     
   233     def FindNewName(self, DesiredName, logger):
   273     def FindNewName(self, DesiredName, logger):
   234         """
   274         """
   235         Changes Name to DesiredName if available, Name-N if not.
   275         Changes Name to DesiredName if available, Name-N if not.
   236         @param DesiredName: The desired Name (string)
   276         @param DesiredName: The desired Name (string)
   462     # For root object, available Childs Types are modules of the plugin packages.
   502     # For root object, available Childs Types are modules of the plugin packages.
   463     PlugChildsTypes = [(name, _GetClassFunction(name)) for name in plugins.__all__]
   503     PlugChildsTypes = [(name, _GetClassFunction(name)) for name in plugins.__all__]
   464 
   504 
   465     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
   505     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
   466     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   506     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   467       <xsd:simpleType name="Win32Compiler">
       
   468         <xsd:restriction base="xsd:string">
       
   469           <xsd:enumeration value="Cygwin"/>
       
   470           <xsd:enumeration value="MinGW"/>
       
   471           <xsd:enumeration value="VC++"/>
       
   472         </xsd:restriction>
       
   473       </xsd:simpleType>
       
   474       <xsd:element name="BeremizRoot">
   507       <xsd:element name="BeremizRoot">
   475         <xsd:complexType>
   508         <xsd:complexType>
   476           <xsd:element name="TargetType">
   509           <xsd:element name="TargetType">
   477             <xsd:complexType>
   510             <xsd:complexType>
   478               <xsd:choice>
   511               <xsd:choice>
   479                 <xsd:element name="Win32">
   512                 <xsd:element name="Win32">
   480                   <xsd:complexType>
   513                   <xsd:complexType>
   481                     <xsd:attribute name="ToolChain" type="ppx:Win32Compiler" use="required" default="MinGW"/>
       
   482                     <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
   514                     <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
   483                   </xsd:complexType>
   515                   </xsd:complexType>
   484                 </xsd:element>
   516                 </xsd:element>
   485                 <xsd:element name="Linux">
   517                 <xsd:element name="Linux">
   486                   <xsd:complexType>
   518                   <xsd:complexType>
   487                     <xsd:attribute name="Compiler" type="xsd:string" use="required" default="gcc"/>
       
   488                     <xsd:attribute name="Nice" type="xsd:integer" use="required"/>
   519                     <xsd:attribute name="Nice" type="xsd:integer" use="required"/>
   489                   </xsd:complexType>
   520                   </xsd:complexType>
   490                 </xsd:element>
   521                 </xsd:element>
   491                 <xsd:element name="Xenomai">
   522                 <xsd:element name="Xenomai">
   492                   <xsd:complexType>
   523                   <xsd:complexType>
   493                     <xsd:attribute name="xeno-config" type="xsd:string" use="required" default="/usr/xenomai/"/>
   524                     <xsd:attribute name="xeno-config" type="xsd:string" use="required" default="/usr/xenomai/"/>
   494                     <xsd:attribute name="Compiler" type="xsd:string" use="required"/>
       
   495                     <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
   525                     <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
   496                   </xsd:complexType>
   526                   </xsd:complexType>
   497                 </xsd:element>
   527                 </xsd:element>
   498                 <xsd:element name="RTAI">
   528                 <xsd:element name="RTAI">
   499                   <xsd:complexType>
   529                   <xsd:complexType>
   500                     <xsd:attribute name="xeno-config" type="xsd:string" use="required"/>
   530                     <xsd:attribute name="rtai-config" type="xsd:string" use="required"/>
   501                     <xsd:attribute name="Compiler" type="xsd:string" use="required"/>
       
   502                     <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
   531                     <xsd:attribute name="Priority" type="xsd:integer" use="required"/>
   503                   </xsd:complexType>
   532                   </xsd:complexType>
   504                 </xsd:element>
   533                 </xsd:element>
   505                 <xsd:element name="Library">
   534                 <xsd:element name="Library">
   506                   <xsd:complexType>
   535                   <xsd:complexType>
   507                     <xsd:attribute name="Dynamic" type="xsd:boolean" use="required" default="true"/>
   536                     <xsd:attribute name="Dynamic" type="xsd:boolean" use="required" default="true"/>
   508                     <xsd:attribute name="Compiler" type="xsd:string" use="required"/>
       
   509                   </xsd:complexType>
   537                   </xsd:complexType>
   510                 </xsd:element>
   538                 </xsd:element>
   511               </xsd:choice>
   539               </xsd:choice>
   512             </xsd:complexType>
   540             </xsd:complexType>
   513           </xsd:element>
   541           </xsd:element>
       
   542           <xsd:attribute name="Compiler" type="xsd:string" use="required" default="gcc"/>
   514         </xsd:complexType>
   543         </xsd:complexType>
   515       </xsd:element>
   544       </xsd:element>
   516     </xsd:schema>
   545     </xsd:schema>
   517     """
   546     """
   518 
   547 
   546     def GetPlugRoot(self):
   575     def GetPlugRoot(self):
   547         return self
   576         return self
   548 
   577 
   549     def GetCurrentLocation(self):
   578     def GetCurrentLocation(self):
   550         return ()
   579         return ()
   551     
   580 
       
   581     def GetCurrentName(self):
       
   582         return ""
       
   583     
       
   584     def _GetCurrentName(self):
       
   585         return ""
       
   586 
   552     def GetProjectPath(self):
   587     def GetProjectPath(self):
   553         return self.ProjectPath
   588         return self.ProjectPath
   554     
   589     
   555     def GetPlugInfos(self):
   590     def GetPlugInfos(self):
   556         childs = []
   591         childs = []
   643         @param locations: List of complete variables locations \
   678         @param locations: List of complete variables locations \
   644             [(IEC_loc, IEC_Direction, IEC_Type, Name)]\
   679             [(IEC_loc, IEC_Direction, IEC_Type, Name)]\
   645             ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...]
   680             ex: [((0,0,4,5),'I','STRING','__IX_0_0_4_5'),...]
   646         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
   681         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
   647         """
   682         """
   648         return [(C_file_name, "") for C_file_name in self.PLCGeneratedCFiles ] , ""
   683         return [(C_file_name, "-I"+ieclib_path) for C_file_name in self.PLCGeneratedCFiles ] , ""
   649     
   684     
   650     def _getBuildPath(self):
   685     def _getBuildPath(self):
   651         return os.path.join(self.ProjectPath, "build")
   686         return os.path.join(self.ProjectPath, "build")
   652     
   687     
   653     def _getIECcodepath(self):
   688     def _getIECcodepath(self):
   672         result = self.GenerateProgram(plc_file)
   707         result = self.GenerateProgram(plc_file)
   673         if not result:
   708         if not result:
   674             # Failed !
   709             # Failed !
   675             logger.write_error("Error : ST/IL/SFC code generator returned %d\n"%result)
   710             logger.write_error("Error : ST/IL/SFC code generator returned %d\n"%result)
   676             return False
   711             return False
   677         logger.write("Compiling ST Program in to C Program...\n")
   712         logger.write("Compiling IEC Program in to C code...\n")
   678         # Now compile IEC code into many C files
   713         # Now compile IEC code into many C files
   679         # files are listed to stdout, and errors to stderr. 
   714         # files are listed to stdout, and errors to stderr. 
   680         status, result, err_result = logger.LogCommand("%s %s -I %s %s"%(iec2cc_path, plc_file, ieclib_path, buildpath))
   715         status, result, err_result = logger.LogCommand("%s %s -I %s %s"%(iec2cc_path, plc_file, ieclib_path, buildpath), no_stdout=True)
   681         if status:
   716         if status:
   682             # Failed !
   717             # Failed !
   683             logger.write_error("Error : IEC to C compiler returned %d\n"%status)
   718             logger.write_error("Error : IEC to C compiler returned %d\n"%status)
   684             return False
   719             return False
   685         # Now extract C files of stdout
   720         # Now extract C files of stdout
   732         # Generate SoftPLC code
   767         # Generate SoftPLC code
   733         if not self._Generate_SoftPLC(logger):
   768         if not self._Generate_SoftPLC(logger):
   734             logger.write_error("SoftPLC code generation failed !\n")
   769             logger.write_error("SoftPLC code generation failed !\n")
   735             return False
   770             return False
   736 
   771 
   737         logger.write("SoftPLC code generation successfull\n")
   772         #logger.write("SoftPLC code generation successfull\n")
       
   773 
       
   774         logger.write("Generating plugins code ...\n")
   738         
   775         
   739         # Generate C code and compilation params from plugin hierarchy
   776         # Generate C code and compilation params from plugin hierarchy
   740         try:
   777         try:
   741             CFilesAndCFLAGS, LDFLAGS = self._Generate_C(
   778             LocationCFilesAndCFLAGS,LDFLAGS = self._Generate_C(
   742                 buildpath, 
   779                 buildpath, 
   743                 self.PLCGeneratedLocatedVars,
   780                 self.PLCGeneratedLocatedVars,
   744                 logger)
   781                 logger)
   745         except Exception, msg:
   782         except Exception, msg:
   746             logger.write_error("Plugins code generation Failed !\n")
   783             logger.write_error("Plugins code generation Failed !\n")
   747             logger.write_error(str(msg))
   784             logger.write_error(str(msg))
   748             return False
   785             return False
   749 
   786 
   750         logger.write("Plugins code generation successfull\n")
   787 
   751 
   788         #debug
       
   789         #import pprint
       
   790         #pp = pprint.PrettyPrinter(indent=4)
       
   791         #logger.write("LocationCFilesAndCFLAGS :\n"+pp.pformat(LocationCFilesAndCFLAGS)+"\n")
       
   792         #logger.write("LDFLAGS :\n"+pp.pformat(LDFLAGS)+"\n")
       
   793         
   752         # Compile the resulting code into object files.
   794         # Compile the resulting code into object files.
   753         for CFile, CFLAG in CFilesAndCFLAGS:
   795         compiler = self.BeremizRoot.getCompiler()
   754             logger.write(str((CFile,CFLAG)))
   796         for Location, CFilesAndCFLAGS in LocationCFilesAndCFLAGS:
       
   797             if Location:
       
   798                 logger.write("Plugin : " + self.GetChildByIECLocation(Location).GetCurrentName() + " " + str(Location)+"\n")
       
   799             else:
       
   800                 logger.write("PLC :\n")
       
   801                 
       
   802             for CFile, CFLAGS in CFilesAndCFLAGS:
       
   803                 bn = os.path.basename(CFile)
       
   804                 logger.write("   [CC]  "+bn+" -> "+os.path.splitext(bn)[0]+".o\n")
       
   805                 objectfilename = os.path.splitext(bn)[0]+".o"
       
   806                 status, result, err_result = logger.LogCommand("%s -c %s -o %s %s"%(compiler, CFile, objectfilename, CFLAGS))
       
   807         
   755         
   808         
   756         # Link object files into something that can be executed on target
   809         # Link object files into something that can be executed on target
   757         logger.write(LDFLAGS)
       
   758 
   810 
   759     def _showIECcode(self, logger):
   811     def _showIECcode(self, logger):
   760         plc_file = self._getIECcodepath()
   812         plc_file = self._getIECcodepath()
   761         new_dialog = wx.Frame(None)
   813         new_dialog = wx.Frame(None)
   762         ST_viewer = TextViewer(new_dialog, None, None)
   814         ST_viewer = TextViewer(new_dialog, None, None)
   791     
   843     
   792     def _Run(self, logger):
   844     def _Run(self, logger):
   793         logger.write_error("Not impl\n")
   845         logger.write_error("Not impl\n")
   794 
   846 
   795     PluginMethods = [("EditPLC",_EditPLC), ("Build",_build), ("Clean",_Clean), ("Run",_Run), ("Show IEC code",_showIECcode)]
   847     PluginMethods = [("EditPLC",_EditPLC), ("Build",_build), ("Clean",_Clean), ("Run",_Run), ("Show IEC code",_showIECcode)]
   796