diff 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
line wrap: on
line diff
--- a/src/bridge/bridge_contructor.py	Mon Jan 24 01:22:00 2011 +0100
+++ b/src/bridge/bridge_contructor.py	Mon Jan 24 17:47:45 2011 +0100
@@ -41,8 +41,9 @@
 import os
 from os import path
 from optparse import OptionParser
-from ConfigParser import RawConfigParser as Parser
+from ConfigParser import SafeConfigParser as Parser
 from ConfigParser import NoOptionError
+import re
 
 
 class ParseError(Exception):
@@ -67,8 +68,49 @@
                 value = None
             function[option] = value
         return function
+    
+    def getDefault(self, name):
+        """Return default values of a function in a dict
+        @param name: Name of the function to get
+        @return: dict, each key is the integer param number (no key if no default value)"""
+        default_dict={}
+        def_re = re.compile(r"param_(\d+)_default")
+        
+        for option in self.bridge_template.options(name):
+            if option == 'doc_return':
+                default_dict['return'] = self.bridge_template.get(name, option)
+                continue
+            match = def_re.match(option)
+            if match:
+                try:
+                    idx = int(match.group(1))
+                except ValueError:
+                    raise ParseError("Invalid value [%s] for parameter number" % match.group(1))
+                default_dict[idx] = self.bridge_template.get(name, option)
+        
+        return default_dict
 
-    def getArguments(self, signature):
+    def getArgumentsDoc(self, name):
+        """Return documentation of arguments
+        @param name: Name of the function to get
+        @return: dict, each key is the integer param number (no key if no argument doc), value is a tuple (name, doc)"""
+        doc_dict={}
+        option_re = re.compile(r"doc_param_(\d+)")
+        value_re = re.compile(r"^(\w+): (.*)$", re.MULTILINE | re.DOTALL)
+        for option in self.bridge_template.options(name):
+            match = option_re.match(option)
+            if match:
+                try:
+                    idx = int(match.group(1))
+                except ValueError:
+                    raise ParseError("Invalid value [%s] for parameter number" % match.group(1))
+                value_match = value_re.match(self.bridge_template.get(name, option))
+                if not value_match:
+                    raise ParseError("Invalid value for parameter doc [%i]" % idx)
+                doc_dict[idx]=(value_match.group(1),value_match.group(2))
+        return doc_dict
+    
+    def getArguments(self, signature, name=None, default=None):
         """Return arguments to user given a signature
         @param signature: signature in the short form (using s,a,i,b etc)
         @return: list of arguments that correspond to a signature (e.g.: "sss" return "arg1, arg2, arg3")""" 
@@ -79,7 +121,10 @@
             if signature[i] not in ['b','y','n','i','x','q','u','t','d','s','a']:
                 raise ParseError("Unmanaged attribute type [%c]" % signature[i])
 
-            attr_string += ("" if idx==0 else ", ") + ("arg_%i" % idx)
+            attr_string += ("" if idx==0 else ", ") + ("%(name)s%(default)s" % {
+                'name':name[idx][0] if (name and name.has_key(idx)) else "arg_%i" % idx,
+                'default':"="+default[idx] if (default and default.has_key(idx)) else ''
+                }) #give arg_1, arg2, etc or name1, name2=default, etc
             idx+=1
 
             if signature[i] == 'a':
@@ -88,6 +133,7 @@
                     i+=1
                     continue #we have a simple type for the array
                 opening_car = signature[i]
+                assert(opening_car in ['{','('])
                 closing_car = '}' if opening_car == '{' else ')'
                 opening_count = 1
                 while (True): #we have a dict or a list of tuples
@@ -123,12 +169,14 @@
         for section in sections:
             function = self.getValues(section)
             print ("Adding %s %s" % (section, function["type"]))
+            default = self.getDefault(section)
+            arg_doc = self.getArgumentsDoc(section)
             completion = {
         'sig_in':function['sig_in'] or '',
         'sig_out':function['sig_out'] or '',
         'category':'REQ' if function['category'] == 'request' else 'COMM',
         'name':section, 
-        'args':self.getArguments(function['sig_in'])
+        'args':self.getArguments(function['sig_in'], name=arg_doc, default=default, )
         }
 
             if function["type"] == "signal":
@@ -146,11 +194,12 @@
 
             elif function["type"] == "method":
                 completion['debug'] = "" if not self.options.debug else 'debug ("%s")\n%s' % (section,8*' ')
+                completion['args_nodefault'] = self.getArguments(function['sig_in'], name=arg_doc)
                 methods_part.append("""\
     @dbus.service.method(const_INT_PREFIX+const_%(category)s_SUFFIX,
                          in_signature='%(sig_in)s', out_signature='%(sig_out)s')
     def %(name)s(self, %(args)s):
-        %(debug)sreturn self.cb["%(name)s"](%(args)s)
+        %(debug)sreturn self.cb["%(name)s"](%(args_nodefault)s)
 """ % completion)
 
         #at this point, signals_part, methods_part and direct_calls should be filled,