objdictgen/eds_utils.py
changeset 309 5d08887347a9
parent 305 db803c81f19f
child 323 4df7e6d2d1db
equal deleted inserted replaced
308:bd6606630a3f 309:5d08887347a9
    43 
    43 
    44 # Dictionary for quickly translate boolean into integer value
    44 # Dictionary for quickly translate boolean into integer value
    45 BOOL_TRANSLATE = {True : "1", False : "0"}
    45 BOOL_TRANSLATE = {True : "1", False : "0"}
    46 
    46 
    47 # Dictionary for quickly translate eds access value into canfestival access value
    47 # Dictionary for quickly translate eds access value into canfestival access value
    48 ACCESS_TRANSLATE = {"ro" : "ro", "wo" : "wo", "rw" : "rw", "rwr" : "rw", "rww" : "rw", "const" : "ro"}
    48 ACCESS_TRANSLATE = {"RO" : "ro", "WO" : "wo", "RW" : "rw", "RWR" : "rw", "RWW" : "rw", "CONST" : "ro"}
    49 
    49 
    50 # Function for verifying data values
    50 # Function for verifying data values
    51 is_integer = lambda x: type(x) in (IntType, LongType)
    51 is_integer = lambda x: type(x) in (IntType, LongType)
    52 is_string = lambda x: type(x) in (StringType, UnicodeType)
    52 is_string = lambda x: type(x) in (StringType, UnicodeType)
    53 is_boolean = lambda x: x in (0, 1)
    53 is_boolean = lambda x: x in (0, 1)
    54 
    54 
    55 # Define checking of value for each attribute
    55 # Define checking of value for each attribute
    56 ENTRY_ATTRIBUTES = {"SUBNUMBER" : is_integer, "PARAMETERNAME" : is_string, 
    56 ENTRY_ATTRIBUTES = {"SUBNUMBER" : is_integer, "PARAMETERNAME" : is_string, 
    57                     "OBJECTTYPE" : lambda x: x in (7, 8, 9), "DATATYPE" : is_integer, 
    57                     "OBJECTTYPE" : lambda x: x in (7, 8, 9), "DATATYPE" : is_integer, 
    58                     "LOWLIMIT" : is_integer, "HIGHLIMIT" : is_integer,
    58                     "LOWLIMIT" : is_integer, "HIGHLIMIT" : is_integer,
    59                     "ACCESSTYPE" : lambda x: x in ["ro","wo", "rw", "rwr", "rww", "const"],
    59                     "ACCESSTYPE" : lambda x: x.upper() in ACCESS_TRANSLATE.keys(),
    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",
   152                     # verify that there is no whitespace into keyname
   152                     # verify that there is no whitespace into keyname
   153                     if keyname.isalnum():
   153                     if keyname.isalnum():
   154                         # value can be preceded and followed by whitespaces, so we escape them
   154                         # value can be preceded and followed by whitespaces, so we escape them
   155                         value = value.strip()
   155                         value = value.strip()
   156                 
   156                 
   157                         # First case, value starts with "0x", then it's an hexadecimal value
   157                         # First case, value starts with "0x" or "-0x", then it's an hexadecimal value
   158                         if value.startswith("0x"):
   158                         if value.startswith("0x") or value.startswith("-0x"):
   159                             try:
   159                             try:
   160                                 computed_value = int(value, 16)
   160                                 computed_value = int(value, 16)
   161                             except:
   161                             except:
   162                                 raise SyntaxError, "\"%s\" is not a valid value for attribute \"%s\" of section \"[%s]\""%(value, keyname, section_name)
   162                                 raise SyntaxError, "\"%s\" is not a valid value for attribute \"%s\" of section \"[%s]\""%(value, keyname, section_name)
   163                         elif value.isdigit():
   163                         elif value.isdigit() or value.startswith("-") and value[1:].isdigit():
   164                             # Second case, value is a number and starts with "0", then it's an octal value
   164                             # Second case, value is a number and starts with "0" or "-0", then it's an octal value
   165                             if value.startswith("0"):
   165                             if value.startswith("0") or value.startswith("-0"):
   166                                 computed_value = int(value, 8)
   166                                 computed_value = int(value, 8)
   167                             # Third case, value is a number and don't start with "0", then it's a decimal value
   167                             # Third case, value is a number and don't start with "0", then it's a decimal value
   168                             else:
   168                             else:
   169                                 computed_value = int(value)
   169                                 computed_value = int(value)
   170                         # In any other case, we keep string value
   170                         # In any other case, we keep string value
   311                             test = int(value.replace("$NODEID+", ""), 16)
   311                             test = int(value.replace("$NODEID+", ""), 16)
   312                             computed_value = "\"%s\""%value
   312                             computed_value = "\"%s\""%value
   313                         except:
   313                         except:
   314                             raise SyntaxError, "\"%s\" is not a valid formula for attribute \"%s\" of section \"[%s]\""%(value, keyname, section_name)
   314                             raise SyntaxError, "\"%s\" is not a valid formula for attribute \"%s\" of section \"[%s]\""%(value, keyname, section_name)
   315                     # Second case, value starts with "0x", then it's an hexadecimal value
   315                     # Second case, value starts with "0x", then it's an hexadecimal value
   316                     elif value.startswith("0x"):
   316                     elif value.startswith("0x") or value.startswith("-0x"):
   317                         try:
   317                         try:
   318                             computed_value = int(value, 16)
   318                             computed_value = int(value, 16)
   319                         except:
   319                         except:
   320                             raise SyntaxError, "\"%s\" is not a valid value for attribute \"%s\" of section \"[%s]\""%(value, keyname, section_name)
   320                             raise SyntaxError, "\"%s\" is not a valid value for attribute \"%s\" of section \"[%s]\""%(value, keyname, section_name)
   321                     elif value.isdigit():
   321                     elif value.isdigit() or value.startswith("-") and value[1:].isdigit():
   322                         # Third case, value is a number and starts with "0", then it's an octal value
   322                         # Third case, value is a number and starts with "0", then it's an octal value
   323                         if value.startswith("0"):
   323                         if value.startswith("0") or value.startswith("-0"):
   324                             computed_value = int(value, 8)
   324                             computed_value = int(value, 8)
   325                         # Forth case, value is a number and don't start with "0", then it's a decimal value
   325                         # Forth case, value is a number and don't start with "0", then it's a decimal value
   326                         else:
   326                         else:
   327                             computed_value = int(value)
   327                             computed_value = int(value)
   328                     # In any other case, we keep string value
   328                     # In any other case, we keep string value
   663                         # Add mapping for entry
   663                         # Add mapping for entry
   664                         Node.AddMappingEntry(entry, name = values["PARAMETERNAME"], struct = 1)
   664                         Node.AddMappingEntry(entry, name = values["PARAMETERNAME"], struct = 1)
   665                         # Add mapping for first subindex
   665                         # Add mapping for first subindex
   666                         Node.AddMappingEntry(entry, 0, values = {"name" : values["PARAMETERNAME"], 
   666                         Node.AddMappingEntry(entry, 0, values = {"name" : values["PARAMETERNAME"], 
   667                                                                  "type" : values["DATATYPE"], 
   667                                                                  "type" : values["DATATYPE"], 
   668                                                                  "access" : ACCESS_TRANSLATE[values["ACCESSTYPE"]], 
   668                                                                  "access" : ACCESS_TRANSLATE[values["ACCESSTYPE"].upper()], 
   669                                                                  "pdo" : values.get("PDOMAPPING", 0) == 1})
   669                                                                  "pdo" : values.get("PDOMAPPING", 0) == 1})
   670                     # Second case, entry is an ARRAY
   670                     # Second case, entry is an ARRAY or RECORD
   671                     elif values["OBJECTTYPE"] == 8:
   671                     elif values["OBJECTTYPE"] in [8, 9]:
   672                         # Extract maximum subindex number defined
   672                         # Extract maximum subindex number defined
   673                         try:
   673                         try:
   674                             max_subindex = values["subindexes"][0]["DEFAULTVALUE"]
   674                             max_subindex = values["subindexes"][0]["DEFAULTVALUE"]
   675                         except:
   675                         except:
   676                             raise SyntaxError, "Error on entry 0x%4.4X:\nSubindex 0 must be defined for an ARRAY entry"%entry
   676                             raise SyntaxError, "Error on entry 0x%4.4X:\nSubindex 0 must be defined for an ARRAY entry"%entry
   682                         for subindex in xrange(1, int(max_subindex) + 1):
   682                         for subindex in xrange(1, int(max_subindex) + 1):
   683                             # if subindex is defined
   683                             # if subindex is defined
   684                             if subindex in values["subindexes"]:
   684                             if subindex in values["subindexes"]:
   685                                 Node.AddMappingEntry(entry, subindex, values = {"name" : values["subindexes"][subindex]["PARAMETERNAME"], 
   685                                 Node.AddMappingEntry(entry, subindex, values = {"name" : values["subindexes"][subindex]["PARAMETERNAME"], 
   686                                                                                 "type" : values["subindexes"][subindex]["DATATYPE"], 
   686                                                                                 "type" : values["subindexes"][subindex]["DATATYPE"], 
   687                                                                                 "access" : ACCESS_TRANSLATE[values["subindexes"][subindex]["ACCESSTYPE"]], 
   687                                                                                 "access" : ACCESS_TRANSLATE[values["subindexes"][subindex]["ACCESSTYPE"].upper()], 
   688                                                                                 "pdo" : values["subindexes"][subindex].get("PDOMAPPING", 0) == 1})
   688                                                                                 "pdo" : values["subindexes"][subindex].get("PDOMAPPING", 0) == 1})
   689                             # if not, we add a mapping for compatibility 
   689                             # if not, we add a mapping for compatibility 
   690                             else:
   690                             else:
   691                                 Node.AddMappingEntry(entry, subindex, values = {"name" : "Compatibility Entry", "type" : 0x05, "access" : "rw", "pdo" : False})
   691                                 Node.AddMappingEntry(entry, subindex, values = {"name" : "Compatibility Entry", "type" : 0x05, "access" : "rw", "pdo" : False})
   692                     # Third case, entry is an RECORD
   692 ##                    # Third case, entry is an RECORD
   693                     elif values["OBJECTTYPE"] == 9:
   693 ##                    elif values["OBJECTTYPE"] == 9:
   694                         # Verify that the first subindex is defined
   694 ##                        # Verify that the first subindex is defined
   695                         if 0 not in values["subindexes"]:
   695 ##                        if 0 not in values["subindexes"]:
   696                             raise SyntaxError, "Error on entry 0x%4.4X:\nSubindex 0 must be defined for a RECORD entry"%entry
   696 ##                            raise SyntaxError, "Error on entry 0x%4.4X:\nSubindex 0 must be defined for a RECORD entry"%entry
   697                         # Add mapping for entry
   697 ##                        # Add mapping for entry
   698                         Node.AddMappingEntry(entry, name = values["PARAMETERNAME"], struct = 7)
   698 ##                        Node.AddMappingEntry(entry, name = values["PARAMETERNAME"], struct = 7)
   699                         # Add mapping for first subindex
   699 ##                        # Add mapping for first subindex
   700                         Node.AddMappingEntry(entry, 0, values = {"name" : "Number of Entries", "type" : 0x05, "access" : "ro", "pdo" : False})
   700 ##                        Node.AddMappingEntry(entry, 0, values = {"name" : "Number of Entries", "type" : 0x05, "access" : "ro", "pdo" : False})
   701                         # Verify that second subindex is defined
   701 ##                        # Verify that second subindex is defined
   702                         if 1 in values:
   702 ##                        if 1 in values["subindexes"]:
   703                             Node.AddMappingEntry(entry, 1, values = {"name" : values["PARAMETERNAME"] + " %d[(sub)]", 
   703 ##                            Node.AddMappingEntry(entry, 1, values = {"name" : values["PARAMETERNAME"] + " %d[(sub)]", 
   704                                                                      "type" : values["subindexes"][1]["DATATYPE"], 
   704 ##                                                                     "type" : values["subindexes"][1]["DATATYPE"], 
   705                                                                      "access" : ACCESS_TRANSLATE[values["subindexes"][1]["ACCESSTYPE"]], 
   705 ##                                                                     "access" : ACCESS_TRANSLATE[values["subindexes"][1]["ACCESSTYPE"].upper()], 
   706                                                                      "pdo" : values["subindexes"][1].get("PDOMAPPING", 0) == 1})
   706 ##                                                                     "pdo" : values["subindexes"][1].get("PDOMAPPING", 0) == 1,
   707                         else:
   707 ##                                                                     "nbmax" : 0xFE})
   708                             raise SyntaxError, "Error on entry 0x%4.4X:\nA RECORD entry must have at least 2 subindexes"%entry
   708 ##                        else:
       
   709 ##                            raise SyntaxError, "Error on entry 0x%4.4X:\nA RECORD entry must have at least 2 subindexes"%entry
   709                 
   710                 
   710                 # Define entry for the new node
   711                 # Define entry for the new node
   711                 
   712                 
   712                 # First case, entry is a VAR
   713                 # First case, entry is a VAR
   713                 if values["OBJECTTYPE"] == 7:
   714                 if values["OBJECTTYPE"] == 7:
   720                     Node.AddEntry(entry, 0, value)
   721                     Node.AddEntry(entry, 0, value)
   721                 # Second case, entry is an ARRAY or a RECORD
   722                 # Second case, entry is an ARRAY or a RECORD
   722                 elif values["OBJECTTYPE"] in (8, 9):
   723                 elif values["OBJECTTYPE"] in (8, 9):
   723                     # Verify that "Subnumber" attribute is defined and has a valid value
   724                     # Verify that "Subnumber" attribute is defined and has a valid value
   724                     if "SUBNUMBER" in values and values["SUBNUMBER"] > 0:
   725                     if "SUBNUMBER" in values and values["SUBNUMBER"] > 0:
       
   726                         consecutive = False
   725                         # Extract maximum subindex number defined
   727                         # Extract maximum subindex number defined
   726                         try:
   728                         try:
   727                             max_subindex = values["subindexes"][0]["DEFAULTVALUE"]
   729                             max_subindex = values["subindexes"][0]["DEFAULTVALUE"]
   728                         except:
   730                         except:
   729                             raise SyntaxError, "Error on entry 0x%4.4X:\nSubindex 0 must be defined for an ARRAY or a RECORD entry"%entry
   731                             max_subindex = values["SUBNUMBER"] - 1
       
   732                             consecutive = True
       
   733                             #raise SyntaxError, "Error on entry 0x%4.4X:\nSubindex 0 must be defined for an ARRAY or a RECORD entry"%entry
   730                         Node.AddEntry(entry, value = [])
   734                         Node.AddEntry(entry, value = [])
   731                         # Define value for all subindexes except the first 
   735                         # Define value for all subindexes except the first 
   732                         for subindex in xrange(1, int(max_subindex) + 1):
   736                         for subindex in xrange(1, int(max_subindex) + 1):
   733                             # Take default value if it is defined and entry is defined
   737                             # Take default value if it is defined and entry is defined
   734                             if subindex in values["subindexes"] and "DEFAULTVALUE" in values["subindexes"][subindex]:
   738                             if subindex in values["subindexes"] and "DEFAULTVALUE" in values["subindexes"][subindex]:
   735                                 value = values["subindexes"][subindex]["DEFAULTVALUE"]
   739                                 value = values["subindexes"][subindex]["DEFAULTVALUE"]
   736                             # Find default value for value type of the subindex
   740                             # Find default value for value type of the subindex
       
   741                             elif subindex in values["subindexes"] or not consecutive:
       
   742                                 value = GetDefaultValue(entry, subindex)
   737                             else:
   743                             else:
   738                                 value = GetDefaultValue(entry, subindex)
   744                                 raise SyntaxError, "Error on entry 0x%4.4X:\nCan't recompose implemented subindexes in this ARRAY or RECORD entry"%entry
   739                             Node.AddEntry(entry, subindex, value)
   745                             Node.AddEntry(entry, subindex, value)
   740                     else:
   746                     else:
   741                         raise SyntaxError, "Array or Record entry 0x%4.4X must have a \"SubNumber\" attribute"%entry
   747                         raise SyntaxError, "Array or Record entry 0x%4.4X must have a \"SubNumber\" attribute"%entry
   742         return Node
   748         return Node
   743     except SyntaxError, message:
   749     except SyntaxError, message: