objdictgen/eds_utils.py
changeset 226 abf63d732a84
parent 206 6787754b251b
child 227 f76c64f66097
equal deleted inserted replaced
225:d6538481c47f 226:abf63d732a84
    60                     "DEFAULTVALUE" : lambda x: True, "PDOMAPPING" : is_boolean,
    60                     "DEFAULTVALUE" : lambda x: True, "PDOMAPPING" : is_boolean,
    61                     "OBJFLAGS" : is_integer}
    61                     "OBJFLAGS" : is_integer}
    62 
    62 
    63 # Define entry parameters by entry ObjectType number
    63 # Define entry parameters by entry ObjectType number
    64 ENTRY_TYPES = {7 : {"name" : " VAR",
    64 ENTRY_TYPES = {7 : {"name" : " VAR",
    65                     "require" : ["PARAMETERNAME", "OBJECTTYPE", "DATATYPE", "ACCESSTYPE", "PDOMAPPING"],
    65                     "require" : ["PARAMETERNAME", "DATATYPE", "ACCESSTYPE"],
    66                     "optional" : ["LOWLIMIT", "HIGHLIMIT", "DEFAULTVALUE", "OBJFLAGS"]},
    66                     "optional" : ["OBJECTTYPE", "DEFAULTVALUE", "PDOMAPPING", "LOWLIMIT", "HIGHLIMIT", "OBJFLAGS"]},
    67                8 : {"name" : "n ARRAY",
    67                8 : {"name" : "n ARRAY",
    68                     "require" : ["SUBNUMBER", "PARAMETERNAME", "OBJECTTYPE"],
    68                     "require" : ["PARAMETERNAME", "OBJECTTYPE", "SUBNUMBER"],
    69                     "optional" : ["OBJFLAGS"]},
    69                     "optional" : ["OBJFLAGS"]},
    70                9 : {"name" : " RECORD",
    70                9 : {"name" : " RECORD",
    71                     "require" : ["SUBNUMBER", "PARAMETERNAME", "OBJECTTYPE"],
    71                     "require" : ["PARAMETERNAME", "OBJECTTYPE", "SUBNUMBER"],
    72                     "optional" : ["OBJFLAGS"]}}
    72                     "optional" : ["OBJFLAGS"]}}
    73 
    73 
    74 
    74 
    75 # Function that search into Node Mappings the informations about an index or a subindex
    75 # Function that search into Node Mappings the informations about an index or a subindex
    76 # and return the default value
    76 # and return the default value
   115 # Function that extract sections from a file and returns a dictionary of the informations
   115 # Function that extract sections from a file and returns a dictionary of the informations
   116 def ExtractSections(file):
   116 def ExtractSections(file):
   117     return [(blocktuple[0],                # EntryName : Assignements dict
   117     return [(blocktuple[0],                # EntryName : Assignements dict
   118              blocktuple[-1].splitlines())  # all the lines
   118              blocktuple[-1].splitlines())  # all the lines
   119              for blocktuple in [           # Split the eds files into
   119              for blocktuple in [           # Split the eds files into
   120              block.split("]")              # (EntryName,Assignements) tuple
   120              block.split("]", 1)              # (EntryName,Assignements) tuple
   121              for block in                  # for each blocks staring with '['
   121              for block in                  # for each blocks staring with '['
   122              file.split("[")]
   122              ("\n"+file).split("\n[")]
   123              if blocktuple[0].isalnum()]   # if EntryName exists
   123              if blocktuple[0].isalnum()]   # if EntryName exists
   124     
   124     
   125 
   125 
   126 # Function that parse an CPJ file and returns a dictionary of the informations
   126 # Function that parse an CPJ file and returns a dictionary of the informations
   127 def ParseCPJFile(filepath):
   127 def ParseCPJFile(filepath):
   143                 if assignment.startswith(";"):
   143                 if assignment.startswith(";"):
   144                     pass
   144                     pass
   145                 # Verify that line is a valid assignment
   145                 # Verify that line is a valid assignment
   146                 elif assignment.find('=') > 0:
   146                 elif assignment.find('=') > 0:
   147                     # Split assignment into the two values keyname and value
   147                     # Split assignment into the two values keyname and value
   148                     # Verify that there is only one '=' character in the line
   148                     keyname, value = assignment.split("=", 1)
   149                     try:
       
   150                         keyname, value = assignment.split("=")
       
   151                     except:
       
   152                         raise SyntaxError, "\"%s\" is not a valid EDS line"%assignment.strip()
       
   153                     
   149                     
   154                     # keyname must be immediately followed by the "=" sign, so we
   150                     # keyname must be immediately followed by the "=" sign, so we
   155                     # verify that there is no whitespace into keyname
   151                     # verify that there is no whitespace into keyname
   156                     if keyname.isalnum():
   152                     if keyname.isalnum():
   157                         # value can be preceded and followed by whitespaces, so we escape them
   153                         # value can be preceded and followed by whitespaces, so we escape them
   299             if assignment.startswith(";"):
   295             if assignment.startswith(";"):
   300                 pass
   296                 pass
   301             # Verify that line is a valid assignment
   297             # Verify that line is a valid assignment
   302             elif assignment.find('=') > 0:
   298             elif assignment.find('=') > 0:
   303                 # Split assignment into the two values keyname and value
   299                 # Split assignment into the two values keyname and value
   304                 # Verify that there is only one '=' character in the line
   300                 keyname, value = assignment.split("=", 1)
   305                 try:
   301                 
   306                     keyname, value = assignment.split("=")
       
   307                 except:
       
   308                     raise SyntaxError, "\"%s\" is not a valid EDS line"%assignment.strip()
       
   309                 # keyname must be immediately followed by the "=" sign, so we
   302                 # keyname must be immediately followed by the "=" sign, so we
   310                 # verify that there is no whitespace into keyname
   303                 # verify that there is no whitespace into keyname
   311                 if keyname.isalnum():
   304                 if keyname.isalnum():
   312                     # value can be preceded and followed by whitespaces, so we escape them
   305                     # value can be preceded and followed by whitespaces, so we escape them
   313                     value = value.strip()
   306                     value = value.strip()
   357         if is_entry:
   350         if is_entry:
   358             # Verify that entry has an ObjectType
   351             # Verify that entry has an ObjectType
   359             if "OBJECTTYPE" in values.keys():
   352             if "OBJECTTYPE" in values.keys():
   360                 # Extract entry ObjectType
   353                 # Extract entry ObjectType
   361                 objecttype = values["OBJECTTYPE"]
   354                 objecttype = values["OBJECTTYPE"]
   362                 # Extract parameters defined
       
   363                 keys = Set(values.keys())
       
   364                 keys.discard("subindexes")
       
   365                 # Extract possible parameters and parameters required
       
   366                 possible = Set(ENTRY_TYPES[objecttype]["require"] + ENTRY_TYPES[objecttype]["optional"])
       
   367                 required = Set(ENTRY_TYPES[objecttype]["require"])
       
   368                 # Verify that parameters defined contains all the parameters required
       
   369                 if not keys.issuperset(required):
       
   370                     missing = required.difference(keys)._data.keys()
       
   371                     if len(missing) > 1:
       
   372                         attributes = "Attributes %s are"%", ".join(["\"%s\""%attribute for attribute in missing])
       
   373                     else:
       
   374                         attributes = "Attribute \"%s\" is"%missing[0]
       
   375                     raise SyntaxError, "Error on section \"[%s]\":\n%s required for a%s entry"%(section_name, attributes, ENTRY_TYPES[objecttype]["name"])
       
   376                 # Verify that parameters defined are all in the possible parameters
       
   377                 if not keys.issubset(possible):
       
   378                     unsupported = keys.difference(possible)._data.keys()
       
   379                     if len(unsupported) > 1:
       
   380                         attributes = "Attributes %s are"%", ".join(["\"%s\""%attribute for attribute in unsupported])
       
   381                     else:
       
   382                         attributes = "Attribute \"%s\" is"%unsupported[0]
       
   383                     raise SyntaxError, "Error on section \"[%s]\":\n%s unsupported for a%s entry"%(section_name, attributes, ENTRY_TYPES[objecttype]["name"])
       
   384             else:
   355             else:
   385                 raise SyntaxError, "Error on section \"[%s]\":\nAttribute OBJECTTYPE is required"%section_name
   356                 # Set ObjectType to VAR by default
       
   357                 objecttype = 7
       
   358             # Extract parameters defined
       
   359             keys = Set(values.keys())
       
   360             keys.discard("subindexes")
       
   361             # Extract possible parameters and parameters required
       
   362             possible = Set(ENTRY_TYPES[objecttype]["require"] + ENTRY_TYPES[objecttype]["optional"])
       
   363             required = Set(ENTRY_TYPES[objecttype]["require"])
       
   364             # Verify that parameters defined contains all the parameters required
       
   365             if not keys.issuperset(required):
       
   366                 missing = required.difference(keys)._data.keys()
       
   367                 if len(missing) > 1:
       
   368                     attributes = "Attributes %s are"%", ".join(["\"%s\""%attribute for attribute in missing])
       
   369                 else:
       
   370                     attributes = "Attribute \"%s\" is"%missing[0]
       
   371                 raise SyntaxError, "Error on section \"[%s]\":\n%s required for a%s entry"%(section_name, attributes, ENTRY_TYPES[objecttype]["name"])
       
   372             # Verify that parameters defined are all in the possible parameters
       
   373             if not keys.issubset(possible):
       
   374                 unsupported = keys.difference(possible)._data.keys()
       
   375                 if len(unsupported) > 1:
       
   376                     attributes = "Attributes %s are"%", ".join(["\"%s\""%attribute for attribute in unsupported])
       
   377                 else:
       
   378                     attributes = "Attribute \"%s\" is"%unsupported[0]
       
   379                 raise SyntaxError, "Error on section \"[%s]\":\n%s unsupported for a%s entry"%(section_name, attributes, ENTRY_TYPES[objecttype]["name"])
   386         
   380         
   387     return eds_dict
   381     return eds_dict
   388 
   382 
   389 
   383 
   390 # Function that write an EDS file after generate it's content
   384 # Function that write an EDS file after generate it's content
   647                         Node.AddMappingEntry(entry, name = values["PARAMETERNAME"], struct = 1)
   641                         Node.AddMappingEntry(entry, name = values["PARAMETERNAME"], struct = 1)
   648                         # Add mapping for first subindex
   642                         # Add mapping for first subindex
   649                         Node.AddMappingEntry(entry, 0, values = {"name" : values["PARAMETERNAME"], 
   643                         Node.AddMappingEntry(entry, 0, values = {"name" : values["PARAMETERNAME"], 
   650                                                                  "type" : values["DATATYPE"], 
   644                                                                  "type" : values["DATATYPE"], 
   651                                                                  "access" : ACCESS_TRANSLATE[values["ACCESSTYPE"]], 
   645                                                                  "access" : ACCESS_TRANSLATE[values["ACCESSTYPE"]], 
   652                                                                  "pdo" : values["PDOMAPPING"] == 1})
   646                                                                  "pdo" : values.get("PDOMAPPING", 0) == 1})
   653                     # Second case, entry is an ARRAY
   647                     # Second case, entry is an ARRAY
   654                     elif values["OBJECTTYPE"] == 8:
   648                     elif values["OBJECTTYPE"] == 8:
   655                         # Extract maximum subindex number defined
   649                         # Extract maximum subindex number defined
   656                         try:
   650                         try:
   657                             max_subindex = values["subindexes"][0]["DEFAULTVALUE"]
   651                             max_subindex = values["subindexes"][0]["DEFAULTVALUE"]
   666                             # if subindex is defined
   660                             # if subindex is defined
   667                             if subindex in values["subindexes"]:
   661                             if subindex in values["subindexes"]:
   668                                 Node.AddMappingEntry(entry, subindex, values = {"name" : values["subindexes"][subindex]["PARAMETERNAME"], 
   662                                 Node.AddMappingEntry(entry, subindex, values = {"name" : values["subindexes"][subindex]["PARAMETERNAME"], 
   669                                                                                 "type" : values["subindexes"][subindex]["DATATYPE"], 
   663                                                                                 "type" : values["subindexes"][subindex]["DATATYPE"], 
   670                                                                                 "access" : ACCESS_TRANSLATE[values["subindexes"][subindex]["ACCESSTYPE"]], 
   664                                                                                 "access" : ACCESS_TRANSLATE[values["subindexes"][subindex]["ACCESSTYPE"]], 
   671                                                                                 "pdo" : values["subindexes"][subindex]["PDOMAPPING"] == 1})
   665                                                                                 "pdo" : values["subindexes"][subindex].get("PDOMAPPING", 0) == 1})
   672                             # if not, we add a mapping for compatibility 
   666                             # if not, we add a mapping for compatibility 
   673                             else:
   667                             else:
   674                                 Node.AddMappingEntry(entry, subindex, values = {"name" : "Compatibility Entry", "type" : 0x05, "access" : "rw", "pdo" : False})
   668                                 Node.AddMappingEntry(entry, subindex, values = {"name" : "Compatibility Entry", "type" : 0x05, "access" : "rw", "pdo" : False})
   675                     # Third case, entry is an RECORD
   669                     # Third case, entry is an RECORD
   676                     elif values["OBJECTTYPE"] == 9:
   670                     elif values["OBJECTTYPE"] == 9:
   684                         # Verify that second subindex is defined
   678                         # Verify that second subindex is defined
   685                         if 1 in values:
   679                         if 1 in values:
   686                             Node.AddMappingEntry(entry, 1, values = {"name" : values["PARAMETERNAME"] + " %d[(sub)]", 
   680                             Node.AddMappingEntry(entry, 1, values = {"name" : values["PARAMETERNAME"] + " %d[(sub)]", 
   687                                                                      "type" : values["subindexes"][1]["DATATYPE"], 
   681                                                                      "type" : values["subindexes"][1]["DATATYPE"], 
   688                                                                      "access" : ACCESS_TRANSLATE[values["subindexes"][1]["ACCESSTYPE"]], 
   682                                                                      "access" : ACCESS_TRANSLATE[values["subindexes"][1]["ACCESSTYPE"]], 
   689                                                                      "pdo" : values["subindexes"][1]["PDOMAPPING"] == 1})
   683                                                                      "pdo" : values["subindexes"][1].get("PDOMAPPING", 0) == 1})
   690                         else:
   684                         else:
   691                             raise SyntaxError, "Error on entry 0x%4.4X:\nA RECORD entry must have at least 2 subindexes"%entry
   685                             raise SyntaxError, "Error on entry 0x%4.4X:\nA RECORD entry must have at least 2 subindexes"%entry
   692                 
   686                 
   693                 # Define entry for the new node
   687                 # Define entry for the new node
   694                 
   688