objdictgen/node.py
changeset 205 dac0f9b4e3f8
parent 182 988f2b302aa6
child 227 f76c64f66097
equal deleted inserted replaced
204:44ce74232ccb 205:dac0f9b4e3f8
    21 #License along with this library; if not, write to the Free Software
    21 #License along with this library; if not, write to the Free Software
    22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 
    23 
    24 import cPickle
    24 import cPickle
    25 from types import *
    25 from types import *
       
    26 import re
    26 
    27 
    27 """
    28 """
    28 Dictionary of translation between access symbol and their signification
    29 Dictionary of translation between access symbol and their signification
    29 """
    30 """
    30 AccessType = {"ro" : "Read Only", "wo" : "Write Only", "rw" : "Read/Write"}
    31 AccessType = {"ro" : "Read Only", "wo" : "Write Only", "rw" : "Read/Write"}
   202                  {"name" : "COB ID Client to Server (Transmit SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
   203                  {"name" : "COB ID Client to Server (Transmit SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
   203                  {"name" : "COB ID Server to Client (Receive SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
   204                  {"name" : "COB ID Server to Client (Receive SDO)", "type" : 0x07, "access" : 'rw', "pdo" : False},
   204                  {"name" : "Node ID of the SDO Server", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
   205                  {"name" : "Node ID of the SDO Server", "type" : 0x04, "access" : 'rw', "pdo" : False}]},
   205     0x1400 : {"name" : "Receive PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
   206     0x1400 : {"name" : "Receive PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
   206                 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
   207                 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
   207                  {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False},
   208                  {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:self.ID+(base+2)*0x100,False:0}[base<4]"},
   208                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
   209                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
   209                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
   210                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
   210                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
   211                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
   211                  {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
   212                  {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
   212     0x1600 : {"name" : "Receive PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
   213     0x1600 : {"name" : "Receive PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
   213                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
   214                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
   214                  {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
   215                  {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
   215     0x1800 : {"name" : "Transmit PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
   216     0x1800 : {"name" : "Transmit PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
   216                 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
   217                 [{"name" : "Highest SubIndex Supported", "type" : 0x05, "access" : 'ro', "pdo" : False},
   217                  {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False},
   218                  {"name" : "COB ID used by PDO", "type" : 0x07, "access" : 'rw', "pdo" : False, "default" : "{True:self.ID+(base+1)*0x100+0x80,False:0}[base<4]"},
   218                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
   219                  {"name" : "Transmission Type", "type" : 0x05, "access" : 'rw', "pdo" : False},
   219                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
   220                  {"name" : "Inhibit Time", "type" : 0x06, "access" : 'rw', "pdo" : False},
   220                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
   221                  {"name" : "Compatibility Entry", "type" : 0x05, "access" : 'rw', "pdo" : False},
   221                  {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
   222                  {"name" : "Event Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]},
   222     0x1A00 : {"name" : "Transmit PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
   223     0x1A00 : {"name" : "Transmit PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" :
   223                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
   224                 [{"name" : "Number of Entries", "type" : 0x05, "access" : 'rw', "pdo" : False},
   224                  {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
   225                  {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]},
   225 }
   226 }
       
   227 
       
   228 #-------------------------------------------------------------------------------
       
   229 #                         Search in a Mapping Dictionary
       
   230 #-------------------------------------------------------------------------------
       
   231 
       
   232 """
       
   233 Return the index of the typename given by searching in mappingdictionary 
       
   234 """
       
   235 def FindTypeIndex(typename, mappingdictionary):
       
   236     testdic = {}
       
   237     for index, values in mappingdictionary.iteritems():
       
   238         if index < 0x1000:
       
   239             testdic[values["name"]] = index
       
   240     if typename in testdic:
       
   241         return testdic[typename]
       
   242     return None
       
   243 
       
   244 """
       
   245 Return the name of the type by searching in mappingdictionary 
       
   246 """
       
   247 def FindTypeName(typeindex, mappingdictionary):
       
   248     if typeindex < 0x1000 and typeindex in mappingdictionary:
       
   249         return mappingdictionary[typeindex]["name"]
       
   250     return None
       
   251 
       
   252 """
       
   253 Return the default value of the type by searching in mappingdictionary 
       
   254 """
       
   255 def FindTypeDefaultValue(typeindex, mappingdictionary):
       
   256     if typeindex < 0x1000 and typeindex in mappingdictionary:
       
   257         return mappingdictionary[typeindex]["default"]
       
   258     return None
       
   259 
       
   260 """
       
   261 Return the list of types defined in mappingdictionary 
       
   262 """
       
   263 def FindTypeList(mappingdictionary):
       
   264     list = []
       
   265     for index in mappingdictionary.keys():
       
   266         if index < 0x1000:
       
   267             list.append(mappingdictionary[index]["name"])
       
   268     return list
       
   269 
       
   270 """
       
   271 Return the name of an entry by searching in mappingdictionary 
       
   272 """
       
   273 def FindEntryName(index, mappingdictionary):
       
   274     base_index = FindIndex(index, mappingdictionary)
       
   275     if base_index:
       
   276         infos = mappingdictionary[base_index]
       
   277         if infos["struct"] & OD_IdenticalIndexes:
       
   278             return StringFormat(infos["name"], (index - base_index) / infos["incr"] + 1, 0)
       
   279         else:
       
   280             return infos["name"]
       
   281     return None
       
   282 
       
   283 """
       
   284 Return the informations of one entry by searching in mappingdictionary 
       
   285 """
       
   286 def FindEntryInfos(index, mappingdictionary):
       
   287     base_index = FindIndex(index, mappingdictionary)
       
   288     if base_index:
       
   289         copy = mappingdictionary[base_index].copy()
       
   290         if copy["struct"] & OD_IdenticalIndexes:
       
   291             copy["name"] = StringFormat(copy["name"], (index - base_index) / copy["incr"] + 1, 0)
       
   292         copy.pop("values")
       
   293         return copy
       
   294     return None
       
   295 
       
   296 """
       
   297 Return the informations of one subentry of an entry by searching in mappingdictionary 
       
   298 """
       
   299 def FindSubentryInfos(index, subIndex, mappingdictionary):
       
   300     base_index = FindIndex(index, mappingdictionary)
       
   301     if base_index:
       
   302         struct = mappingdictionary[base_index]["struct"]
       
   303         if struct & OD_Subindex:
       
   304             if struct & OD_IdenticalSubindexes:
       
   305                 if struct & OD_IdenticalIndexes:
       
   306                     incr = mappingdictionary[base_index]["incr"]
       
   307                 else:
       
   308                     incr = 1
       
   309                 if subIndex == 0:
       
   310                     return mappingdictionary[base_index]["values"][0].copy()
       
   311                 elif 0 < subIndex <= mappingdictionary[base_index]["values"][1]["nbmax"]:
       
   312                     copy = mappingdictionary[base_index]["values"][1].copy()
       
   313                     copy["name"] = StringFormat(copy["name"], (index - base_index) / incr + 1, subIndex)
       
   314                     return copy
       
   315             elif struct & OD_MultipleSubindexes and 0 <= subIndex < len(mappingdictionary[base_index]["values"]):
       
   316                 return mappingdictionary[base_index]["values"][subIndex].copy()
       
   317             elif subIndex == 0:
       
   318                 return mappingdictionary[base_index]["values"][0].copy()
       
   319     return None
       
   320 
       
   321 """
       
   322 Return the list of variables that can be mapped defined in mappingdictionary 
       
   323 """
       
   324 def FindMapVariableList(mappingdictionary, Node):
       
   325     list = []
       
   326     for index in mappingdictionary.iterkeys():
       
   327         if Node.IsEntry(index):
       
   328             for subIndex, values in enumerate(mappingdictionary[index]["values"]):
       
   329                 if mappingdictionary[index]["values"][subIndex]["pdo"]:
       
   330                     infos = Node.GetEntryInfos(mappingdictionary[index]["values"][subIndex]["type"])
       
   331                     if mappingdictionary[index]["struct"] & OD_IdenticalSubindexes:
       
   332                         values = Node.GetEntry(index)
       
   333                         for i in xrange(len(values) - 1):
       
   334                             list.append((index, i + 1, infos["size"], StringFormat(mappingdictionary[index]["values"][subIndex]["name"],1,i+1)))
       
   335                     else:
       
   336                         list.append((index, subIndex, infos["size"], mappingdictionary[index]["values"][subIndex]["name"]))
       
   337     return list
       
   338 
       
   339 """
       
   340 Return the list of mandatory indexes defined in mappingdictionary 
       
   341 """
       
   342 def FindMandatoryIndexes(mappingdictionary):
       
   343     list = []
       
   344     for index in mappingdictionary.iterkeys():
       
   345         if index >= 0x1000 and mappingdictionary[index]["need"]:
       
   346             list.append(index)
       
   347     return list
       
   348 
       
   349 """
       
   350 Return the index of the informations in the Object Dictionary in case of identical
       
   351 indexes
       
   352 """
       
   353 def FindIndex(index, mappingdictionary):
       
   354     if index in mappingdictionary:
       
   355         return index
       
   356     else:
       
   357         listpluri = [idx for idx in mappingdictionary.keys() if mappingdictionary[idx]["struct"] & OD_IdenticalIndexes]
       
   358         listpluri.sort()
       
   359         for idx in listpluri:
       
   360             nb_max = mappingdictionary[idx]["nbmax"]
       
   361             incr = mappingdictionary[idx]["incr"]
       
   362             if idx < index < idx + incr * nb_max and (index - idx)%incr == 0:
       
   363                 return idx
       
   364     return None
       
   365 
       
   366 #-------------------------------------------------------------------------------
       
   367 #                           Formating Name of an Entry
       
   368 #-------------------------------------------------------------------------------
       
   369 
       
   370 name_model = re.compile('(.*)\[(.*)\]')
       
   371 
       
   372 """
       
   373 Format the text given with the index and subindex defined
       
   374 """
       
   375 def StringFormat(text, idx, sub):
       
   376     result = name_model.match(text)
       
   377     if result:
       
   378         format = result.groups()
       
   379         return format[0]%eval(format[1])
       
   380     else:
       
   381         return text
   226 
   382 
   227 #-------------------------------------------------------------------------------
   383 #-------------------------------------------------------------------------------
   228 #                          Definition of Node Object
   384 #                          Definition of Node Object
   229 #-------------------------------------------------------------------------------
   385 #-------------------------------------------------------------------------------
   230 
   386 
   447         return False
   603         return False
   448     
   604     
   449     """
   605     """
   450     Check if an entry exists in the Object Dictionary and returns the answer.
   606     Check if an entry exists in the Object Dictionary and returns the answer.
   451     """
   607     """
   452     def IsEntry(self, index):
   608     def IsEntry(self, index, subIndex = None):
   453         if index in self.Dictionary:
   609         if index in self.Dictionary:
   454             return True
   610             if not subIndex:
       
   611                 return True
       
   612             return subIndex <= len(self.Dictionary[index])
   455         return False
   613         return False
   456     
   614     
   457     """
   615     """
   458     Returns the value of the entry asked. If the entry has the value "count", it
   616     Returns the value of the entry asked. If the entry has the value "count", it
   459     returns the number of subIndex in the entry except the first.
   617     returns the number of subIndex in the entry except the first.
   461     def GetEntry(self, index, subIndex = None):
   619     def GetEntry(self, index, subIndex = None):
   462         if index in self.Dictionary:
   620         if index in self.Dictionary:
   463             if subIndex == None:
   621             if subIndex == None:
   464                 if type(self.Dictionary[index]) == ListType:
   622                 if type(self.Dictionary[index]) == ListType:
   465                     values = [len(self.Dictionary[index])]
   623                     values = [len(self.Dictionary[index])]
   466                     values.extend(self.Dictionary[index])
   624                     for value in self.Dictionary[index]:
       
   625                         values.append(self.CompileValue(value, index))
   467                     return values
   626                     return values
   468                 else:
   627                 else:
   469                     return self.Dictionary[index]
   628                     return self.Dictionary[index]
   470             elif subIndex == 0:
   629             elif subIndex == 0:
   471                 if type(self.Dictionary[index]) == ListType:
   630                 if type(self.Dictionary[index]) == ListType:
   472                     return len(self.Dictionary[index])
   631                     return len(self.Dictionary[index])
   473                 else:
   632                 else:
   474                     return self.Dictionary[index]
   633                     return self.CompileValue(self.Dictionary[index], index)
   475             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
   634             elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]):
   476                 return self.Dictionary[index][subIndex - 1]
   635                 return self.CompileValue(self.Dictionary[index][subIndex - 1], index)
   477         return None
   636         return None
   478 
   637 
   479     """
   638     """
   480     Returns the value of the entry asked. If the entry has the value "count", it
   639     Returns the value of the entry asked. If the entry has the value "count", it
   481     returns the number of subIndex in the entry except the first.
   640     returns the number of subIndex in the entry except the first.
   592             elif subIndex == len(self.UserMapping[index]["values"]) - 1:
   751             elif subIndex == len(self.UserMapping[index]["values"]) - 1:
   593                 self.UserMapping[index]["values"].pop(subIndex)
   752                 self.UserMapping[index]["values"].pop(subIndex)
   594                 return True
   753                 return True
   595         return False
   754         return False
   596 
   755 
   597     def RemoveMapVariable(self, index, subIndex):
   756     def RemoveMapVariable(self, index, subIndex = None):
   598         model = index << 16
   757         model = index << 16
   599         mask = 0xFFFF << 16
   758         mask = 0xFFFF << 16
   600         if subIndex:
   759         if subIndex:
   601             model += subIndex << 8
   760             model += subIndex << 8
   602             mask = 0xFF << 8
   761             mask = 0xFF << 8
   654     def Print(self):
   813     def Print(self):
   655         listindex = self.Dictionary.keys()
   814         listindex = self.Dictionary.keys()
   656         listindex.sort()
   815         listindex.sort()
   657         for index in listindex:
   816         for index in listindex:
   658             print "%04X : %s"%(index, self.Dictionary[index])    
   817             print "%04X : %s"%(index, self.Dictionary[index])    
       
   818 
       
   819     def CompileValue(self, value, index):
       
   820         if type(value) == StringType and value.find("self.ID") != -1:
       
   821             base = self.GetBaseIndex(index)
       
   822             try:
       
   823                 return eval(value)
       
   824             except:
       
   825                 return 0
       
   826         else:
       
   827             return value
       
   828 
       
   829 #-------------------------------------------------------------------------------
       
   830 #                         Node Informations Functions
       
   831 #-------------------------------------------------------------------------------
       
   832 
       
   833     def GetBaseIndex(self, index):
       
   834         for mapping in self.GetMappings():
       
   835             result = FindIndex(index, mapping)
       
   836             if result != None:
       
   837                 return (index - result) / mapping[result]["incr"]
       
   838         result = FindIndex(index, MappingDictionary)
       
   839         if result != None:
       
   840             return (index - result) / MappingDictionary[result]["incr"]
       
   841         return 0
       
   842 
       
   843     def GetCustomisedTypeValues(self, index):
       
   844         values = self.GetEntry(index)
       
   845         customisabletypes = self.GetCustomisableTypes()
       
   846         return values, customisabletypes[values[1]][1]
       
   847 
       
   848     def GetEntryName(self, index):
       
   849         result = None
       
   850         mappings = self.GetMappings()
       
   851         i = 0
       
   852         while not result and i < len(mappings):
       
   853             result = FindEntryName(index, mappings[i])
       
   854             i += 1
       
   855         if result == None:
       
   856             result = FindEntryName(index, MappingDictionary)
       
   857         return result
       
   858     
       
   859     def GetEntryInfos(self, index):
       
   860         result = None
       
   861         mappings = self.GetMappings()
       
   862         i = 0
       
   863         while not result and i < len(mappings):
       
   864             result = FindEntryInfos(index, mappings[i])
       
   865             i += 1
       
   866         if result == None:
       
   867             result = FindEntryInfos(index, MappingDictionary)
       
   868         return result
       
   869     
       
   870     def GetSubentryInfos(self, index, subIndex):
       
   871         result = None
       
   872         mappings = self.GetMappings()
       
   873         i = 0
       
   874         while not result and i < len(mappings):
       
   875             result = FindSubentryInfos(index, subIndex, mappings[i])
       
   876             if result:
       
   877                 result["user_defined"] = i == len(mappings) - 1 and index >= 0x1000
       
   878             i += 1
       
   879         if result == None:
       
   880             result = FindSubentryInfos(index, subIndex, MappingDictionary)
       
   881             if result:
       
   882                 result["user_defined"] = False
       
   883         return result
       
   884     
       
   885     def GetTypeIndex(self, typename):
       
   886         result = None
       
   887         mappings = self.GetMappings()
       
   888         i = 0
       
   889         while not result and i < len(mappings):
       
   890             result = FindTypeIndex(typename, mappings[i])
       
   891             i += 1
       
   892         if result == None:
       
   893             result = FindTypeIndex(typename, MappingDictionary)
       
   894         return result
       
   895     
       
   896     def GetTypeName(self, typeindex):
       
   897         result = None
       
   898         mappings = self.GetMappings()
       
   899         i = 0
       
   900         while not result and i < len(mappings):
       
   901             result = FindTypeName(typeindex, mappings[i])
       
   902             i += 1
       
   903         if result == None:
       
   904             result = FindTypeName(typeindex, MappingDictionary)
       
   905         return result
       
   906     
       
   907     def GetTypeDefaultValue(self, typeindex):
       
   908         result = None
       
   909         mappings = self.GetMappings()
       
   910         i = 0
       
   911         while not result and i < len(mappings):
       
   912             result = FindTypeDefaultValue(typeindex, mappings[i])
       
   913             i += 1
       
   914         if result == None:
       
   915             result = FindTypeDefaultValue(typeindex, MappingDictionary)
       
   916         return result
       
   917     
       
   918     def GetMapVariableList(self):
       
   919         list = FindMapVariableList(MappingDictionary, self)
       
   920         for mapping in self.GetMappings():
       
   921             list.extend(FindMapVariableList(mapping, self))
       
   922         list.sort()
       
   923         return list
       
   924     
       
   925     def GetMandatoryIndexes(self, node = None):
       
   926         list = FindMandatoryIndexes(MappingDictionary)
       
   927         for mapping in self.GetMappings():
       
   928             list.extend(FindMandatoryIndexes(mapping))
       
   929         return list
       
   930     
       
   931     def GetCustomisableTypes(self):
       
   932         dic = {}
       
   933         for index, valuetype in CustomisableTypes:
       
   934             name = self.GetTypeName(index)
       
   935             dic[index] = [name, valuetype]
       
   936         return dic
       
   937 
       
   938 #-------------------------------------------------------------------------------
       
   939 #                            Type and Map Variable Lists
       
   940 #-------------------------------------------------------------------------------
       
   941     
       
   942     def GetTypeList(self):
       
   943         list = FindTypeList(MappingDictionary)
       
   944         for mapping in self.GetMappings():
       
   945             list.extend(FindTypeList(mapping))
       
   946         list.sort()
       
   947         return ",".join(list)
       
   948 
       
   949     """
       
   950     Generate the list of variables that can be mapped for the current node
       
   951     """
       
   952     def GenerateMapList(self):
       
   953         self.MapList = "None"
       
   954         self.NameTranslation = {"None" : "00000000"}
       
   955         self.MapTranslation = {"00000000" : "None"}
       
   956         list = self.GetMapVariableList()
       
   957         for index, subIndex, size, name in list:
       
   958             self.MapList += ",%s"%name
       
   959             map = "%04X%02X%02X"%(index,subIndex,size)
       
   960             self.NameTranslation[name] = map
       
   961             self.MapTranslation[map] = name
       
   962 
       
   963     def GetMapValue(self, mapname):
       
   964         if mapname == "None":
       
   965             return 0
       
   966         else:
       
   967             list = self.GetMapVariableList()
       
   968             for index, subIndex, size, name in list:
       
   969                 if mapname == name:
       
   970                     return (index << 16) + (subIndex << 8) + size
       
   971             return None
       
   972     
       
   973     def GetMapName(self, value):
       
   974         if value != 0:
       
   975             index = value >> 16
       
   976             subindex = (value >> 8) % (1 << 8)
       
   977             result = self.GetSubentryInfos(index, subindex)
       
   978             if result:
       
   979                 return result["name"]
       
   980         return "None"
       
   981     
       
   982     """
       
   983     Return the list of variables that can be mapped for the current node
       
   984     """
       
   985     def GetMapList(self):
       
   986         list = ["None"] + [name for index, subIndex, size, name in self.GetMapVariableList()]
       
   987         return ",".join(list)