Mercurial > libervia-backend
comparison src/bridge/bridge_contructor.py @ 266:c4b84a2d2ad1
bridge: constructor and template improved, documentation added
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 24 Jan 2011 17:47:45 +0100 |
parents | b5f1f3dc9ac6 |
children |
comparison
equal
deleted
inserted
replaced
265:b5f1f3dc9ac6 | 266:c4b84a2d2ad1 |
---|---|
39 | 39 |
40 import sys | 40 import sys |
41 import os | 41 import os |
42 from os import path | 42 from os import path |
43 from optparse import OptionParser | 43 from optparse import OptionParser |
44 from ConfigParser import RawConfigParser as Parser | 44 from ConfigParser import SafeConfigParser as Parser |
45 from ConfigParser import NoOptionError | 45 from ConfigParser import NoOptionError |
46 import re | |
46 | 47 |
47 | 48 |
48 class ParseError(Exception): | 49 class ParseError(Exception): |
49 #Used when the signature parsing is going wrong (invalid signature ?) | 50 #Used when the signature parsing is going wrong (invalid signature ?) |
50 pass | 51 pass |
65 value = self.bridge_template.get(name, option) | 66 value = self.bridge_template.get(name, option) |
66 except NoOptionError: | 67 except NoOptionError: |
67 value = None | 68 value = None |
68 function[option] = value | 69 function[option] = value |
69 return function | 70 return function |
70 | 71 |
71 def getArguments(self, signature): | 72 def getDefault(self, name): |
73 """Return default values of a function in a dict | |
74 @param name: Name of the function to get | |
75 @return: dict, each key is the integer param number (no key if no default value)""" | |
76 default_dict={} | |
77 def_re = re.compile(r"param_(\d+)_default") | |
78 | |
79 for option in self.bridge_template.options(name): | |
80 if option == 'doc_return': | |
81 default_dict['return'] = self.bridge_template.get(name, option) | |
82 continue | |
83 match = def_re.match(option) | |
84 if match: | |
85 try: | |
86 idx = int(match.group(1)) | |
87 except ValueError: | |
88 raise ParseError("Invalid value [%s] for parameter number" % match.group(1)) | |
89 default_dict[idx] = self.bridge_template.get(name, option) | |
90 | |
91 return default_dict | |
92 | |
93 def getArgumentsDoc(self, name): | |
94 """Return documentation of arguments | |
95 @param name: Name of the function to get | |
96 @return: dict, each key is the integer param number (no key if no argument doc), value is a tuple (name, doc)""" | |
97 doc_dict={} | |
98 option_re = re.compile(r"doc_param_(\d+)") | |
99 value_re = re.compile(r"^(\w+): (.*)$", re.MULTILINE | re.DOTALL) | |
100 for option in self.bridge_template.options(name): | |
101 match = option_re.match(option) | |
102 if match: | |
103 try: | |
104 idx = int(match.group(1)) | |
105 except ValueError: | |
106 raise ParseError("Invalid value [%s] for parameter number" % match.group(1)) | |
107 value_match = value_re.match(self.bridge_template.get(name, option)) | |
108 if not value_match: | |
109 raise ParseError("Invalid value for parameter doc [%i]" % idx) | |
110 doc_dict[idx]=(value_match.group(1),value_match.group(2)) | |
111 return doc_dict | |
112 | |
113 def getArguments(self, signature, name=None, default=None): | |
72 """Return arguments to user given a signature | 114 """Return arguments to user given a signature |
73 @param signature: signature in the short form (using s,a,i,b etc) | 115 @param signature: signature in the short form (using s,a,i,b etc) |
74 @return: list of arguments that correspond to a signature (e.g.: "sss" return "arg1, arg2, arg3")""" | 116 @return: list of arguments that correspond to a signature (e.g.: "sss" return "arg1, arg2, arg3")""" |
75 i=0 | 117 i=0 |
76 idx=0 | 118 idx=0 |
77 attr_string="" | 119 attr_string="" |
78 while i<len(signature): | 120 while i<len(signature): |
79 if signature[i] not in ['b','y','n','i','x','q','u','t','d','s','a']: | 121 if signature[i] not in ['b','y','n','i','x','q','u','t','d','s','a']: |
80 raise ParseError("Unmanaged attribute type [%c]" % signature[i]) | 122 raise ParseError("Unmanaged attribute type [%c]" % signature[i]) |
81 | 123 |
82 attr_string += ("" if idx==0 else ", ") + ("arg_%i" % idx) | 124 attr_string += ("" if idx==0 else ", ") + ("%(name)s%(default)s" % { |
125 'name':name[idx][0] if (name and name.has_key(idx)) else "arg_%i" % idx, | |
126 'default':"="+default[idx] if (default and default.has_key(idx)) else '' | |
127 }) #give arg_1, arg2, etc or name1, name2=default, etc | |
83 idx+=1 | 128 idx+=1 |
84 | 129 |
85 if signature[i] == 'a': | 130 if signature[i] == 'a': |
86 i+=1 | 131 i+=1 |
87 if signature[i]!='{' and signature[i]!='(': #FIXME: must manage tuples out of arrays | 132 if signature[i]!='{' and signature[i]!='(': #FIXME: must manage tuples out of arrays |
88 i+=1 | 133 i+=1 |
89 continue #we have a simple type for the array | 134 continue #we have a simple type for the array |
90 opening_car = signature[i] | 135 opening_car = signature[i] |
136 assert(opening_car in ['{','(']) | |
91 closing_car = '}' if opening_car == '{' else ')' | 137 closing_car = '}' if opening_car == '{' else ')' |
92 opening_count = 1 | 138 opening_count = 1 |
93 while (True): #we have a dict or a list of tuples | 139 while (True): #we have a dict or a list of tuples |
94 i+=1 | 140 i+=1 |
95 if i>=len(signature): | 141 if i>=len(signature): |
121 sections = self.bridge_template.sections() | 167 sections = self.bridge_template.sections() |
122 sections.sort() | 168 sections.sort() |
123 for section in sections: | 169 for section in sections: |
124 function = self.getValues(section) | 170 function = self.getValues(section) |
125 print ("Adding %s %s" % (section, function["type"])) | 171 print ("Adding %s %s" % (section, function["type"])) |
172 default = self.getDefault(section) | |
173 arg_doc = self.getArgumentsDoc(section) | |
126 completion = { | 174 completion = { |
127 'sig_in':function['sig_in'] or '', | 175 'sig_in':function['sig_in'] or '', |
128 'sig_out':function['sig_out'] or '', | 176 'sig_out':function['sig_out'] or '', |
129 'category':'REQ' if function['category'] == 'request' else 'COMM', | 177 'category':'REQ' if function['category'] == 'request' else 'COMM', |
130 'name':section, | 178 'name':section, |
131 'args':self.getArguments(function['sig_in']) | 179 'args':self.getArguments(function['sig_in'], name=arg_doc, default=default, ) |
132 } | 180 } |
133 | 181 |
134 if function["type"] == "signal": | 182 if function["type"] == "signal": |
135 completion['body'] = "pass" if not self.options.debug else 'debug ("%s")' % section | 183 completion['body'] = "pass" if not self.options.debug else 'debug ("%s")' % section |
136 signals_part.append("""\ | 184 signals_part.append("""\ |
144 self.dbus_bridge.%(name)s(%(args)s) | 192 self.dbus_bridge.%(name)s(%(args)s) |
145 """ % completion) | 193 """ % completion) |
146 | 194 |
147 elif function["type"] == "method": | 195 elif function["type"] == "method": |
148 completion['debug'] = "" if not self.options.debug else 'debug ("%s")\n%s' % (section,8*' ') | 196 completion['debug'] = "" if not self.options.debug else 'debug ("%s")\n%s' % (section,8*' ') |
197 completion['args_nodefault'] = self.getArguments(function['sig_in'], name=arg_doc) | |
149 methods_part.append("""\ | 198 methods_part.append("""\ |
150 @dbus.service.method(const_INT_PREFIX+const_%(category)s_SUFFIX, | 199 @dbus.service.method(const_INT_PREFIX+const_%(category)s_SUFFIX, |
151 in_signature='%(sig_in)s', out_signature='%(sig_out)s') | 200 in_signature='%(sig_in)s', out_signature='%(sig_out)s') |
152 def %(name)s(self, %(args)s): | 201 def %(name)s(self, %(args)s): |
153 %(debug)sreturn self.cb["%(name)s"](%(args)s) | 202 %(debug)sreturn self.cb["%(name)s"](%(args_nodefault)s) |
154 """ % completion) | 203 """ % completion) |
155 | 204 |
156 #at this point, signals_part, methods_part and direct_calls should be filled, | 205 #at this point, signals_part, methods_part and direct_calls should be filled, |
157 #we just have to place them in the right part of the template | 206 #we just have to place them in the right part of the template |
158 core_bridge = [] | 207 core_bridge = [] |