Revision: 7346
          http://playerstage.svn.sourceforge.net/playerstage/?rev=7346&view=rev
Author:   gbiggs
Date:     2009-02-23 01:34:23 +0000 (Mon, 23 Feb 2009)

Log Message:
-----------
New Python bindings generation from Luke Gumbley, fixed installation directory 
for Python bindings.

Modified Paths:
--------------
    code/player/trunk/client_libs/libplayerc/bindings/python/CMakeLists.txt
    code/player/trunk/client_libs/libplayerc/bindings/python/playerc.i
    
code/player/trunk/client_libs/libplayerc/bindings/python/playerc_swig_parse.py
    code/player/trunk/examples/libplayerc++/example3.cc

Modified: 
code/player/trunk/client_libs/libplayerc/bindings/python/CMakeLists.txt
===================================================================
--- code/player/trunk/client_libs/libplayerc/bindings/python/CMakeLists.txt     
2009-02-19 03:47:45 UTC (rev 7345)
+++ code/player/trunk/client_libs/libplayerc/bindings/python/CMakeLists.txt     
2009-02-23 01:34:23 UTC (rev 7346)
@@ -17,16 +17,21 @@
 
             SET (CMAKE_SWIG_FLAGS "")
 
-            # Generate player_oo.i from playerc.h
-            SET (playerc_oo_i "${CMAKE_CURRENT_BINARY_DIR}/playerc_oo.i")
-            ADD_CUSTOM_COMMAND (OUTPUT ${playerc_oo_i}
-                COMMAND ${PYTHON_EXECUTABLE} 
${CMAKE_CURRENT_SOURCE_DIR}/playerc_swig_parse.py 
${PROJECT_SOURCE_DIR}/client_libs/libplayerc/playerc.h ${playerc_oo_i}
+            # Generate playerc_wrap.i and playerc_wrap.h from playerc.h
+            SET (playerc_wrap_prefix 
"${CMAKE_CURRENT_BINARY_DIR}/playerc_wrap")
+            ADD_CUSTOM_COMMAND (OUTPUT "${playerc_wrap_prefix}.i"
+                COMMAND ${PYTHON_EXECUTABLE} 
${CMAKE_CURRENT_SOURCE_DIR}/playerc_swig_parse.py 
${PROJECT_SOURCE_DIR}/client_libs/libplayerc/playerc.h ${playerc_wrap_prefix}
                 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-                VERBATIM
-            )
-            # Empty target to ensure playerc_oo.i gets created
-            ADD_CUSTOM_TARGET (playerc_oo_i_target ALL
-                DEPENDS ${playerc_oo_i})
+                VERBATIM)
+
+            ADD_CUSTOM_COMMAND(OUTPUT "${playerc_wrap_prefix}.h"
+                DEPENDS "${playerc_wrap_prefix}.i")
+
+            # Empty target to ensure playerc_wrap.i and playerc_wrap.h get 
created
+            ADD_CUSTOM_TARGET (playerc_wrap_i_target ALL
+                DEPENDS "${playerc_wrap_prefix}.i"
+                DEPENDS "${playerc_wrap_prefix}.h")
+
             # Copy playerc.i to the build directory
             SET (playerc_i_in "${CMAKE_CURRENT_SOURCE_DIR}/playerc.i")
             SET (playerc_i "${CMAKE_CURRENT_BINARY_DIR}/playerc.i")
@@ -34,18 +39,27 @@
 
             SWIG_ADD_MODULE (playerc python ${playerc_i})
             SWIG_LINK_LIBRARIES (playerc ${PYTHON_LIBRARIES})
-            ADD_DEPENDENCIES (${SWIG_MODULE_playerc_REAL_NAME} 
playerc_oo_i_target)
+            ADD_DEPENDENCIES (${SWIG_MODULE_playerc_REAL_NAME} 
playerc_wrap_i_target)
             TARGET_LINK_LIBRARIES (${SWIG_MODULE_playerc_REAL_NAME} playerxdr 
playerc playererror)
             IF (HAVE_JPEG)
                 TARGET_LINK_LIBRARIES (${SWIG_MODULE_playerc_REAL_NAME} 
playerjpeg)
             ENDIF (HAVE_JPEG)
 
-            # Generate the set up script
-#             CONFIGURE_FILE (${CMAKE_CURRENT_SOURCE_DIR}/setup.py.cmake 
${CMAKE_CURRENT_BINARY_DIR}/setup.py)
-#             INSTALL (SCRIPT 
${PLAYER_CMAKE_DIR}/internal/InstallPythonModule.cmake)
+            IF (PYTHON_OS_WIN)
+                GET_FILENAME_COMPONENT (playercpyInstallDir 
${PYTHON_EXECUTABLE} PATH)
+            ELSE (PYTHON_OS_WIN)
+                # Get the Python version
+                EXECUTE_PROCESS (COMMAND ${PYTHON_EXECUTABLE} --version
+                                 ERROR_VARIABLE pythonVersionString
+                                 ERROR_STRIP_TRAILING_WHITESPACE)
+                STRING (REGEX REPLACE "^Python ([0-9]+\\.[0-9]+).*" "\\1" 
pythonVersion ${pythonVersionString})
+                SET (playercpyInstallDir 
lib/python${pythonVersion}/site-packages)
+            ENDIF (PYTHON_OS_WIN)
+            SET (PYTHON_BINDINGS_INSTALL_DIR ${playercpyInstallDir} CACHE PATH 
"Python bindings installation directory under $prefix")
+            MARK_AS_ADVANCED (PYTHON_BINDINGS_INSTALL_DIR)
 
             INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/playerc.py 
${CMAKE_CURRENT_BINARY_DIR}/_playerc.so
-                DESTINATION lib/python/site-packages)
+                DESTINATION ${PYTHON_BINDINGS_INSTALL_DIR})
         ELSE (SWIG_FOUND)
             MESSAGE (STATUS "Python bindings for C client library will not be 
built - could not find Swig")
         ENDIF (SWIG_FOUND)
@@ -55,3 +69,4 @@
 ELSE (PYTHONINTERP_FOUND)
     MESSAGE (STATUS "Python bindings for C client library will not be built - 
could not find Python")
 ENDIF (PYTHONINTERP_FOUND)
+

Modified: code/player/trunk/client_libs/libplayerc/bindings/python/playerc.i
===================================================================
--- code/player/trunk/client_libs/libplayerc/bindings/python/playerc.i  
2009-02-19 03:47:45 UTC (rev 7345)
+++ code/player/trunk/client_libs/libplayerc/bindings/python/playerc.i  
2009-02-23 01:34:23 UTC (rev 7346)
@@ -2,7 +2,7 @@
 %module playerc
 
 %{
-#include "playerc.h"
+#include "playerc_wrap.h"
 
 #ifndef Py_RETURN_NONE
 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
@@ -408,31 +408,8 @@
 // Use this for object-oriented bindings;
 // e.g., client.connect(...)
 // This file is created by running ../parse_header.py
-%include "playerc_oo.i"
+%include "playerc_wrap.i"
 
-%extend playerc_laser
-{
-double get_range (int index)
-{
-       if (index < self->scan_count)
-               return self->ranges[index];
-       else
-               return 0;
-};
-}
-
-%extend playerc_sonar
-{
-double get_scan (int index)
-{
-       if (index < self->scan_count)
-               return self->scan[index];
-       else
-               return 0;
-};
-}
-
-
 %extend playerc_blackboard
 {
 

Modified: 
code/player/trunk/client_libs/libplayerc/bindings/python/playerc_swig_parse.py
===================================================================
--- 
code/player/trunk/client_libs/libplayerc/bindings/python/playerc_swig_parse.py  
    2009-02-19 03:47:45 UTC (rev 7345)
+++ 
code/player/trunk/client_libs/libplayerc/bindings/python/playerc_swig_parse.py  
    2009-02-23 01:34:23 UTC (rev 7346)
@@ -4,309 +4,248 @@
 import string
 import sys
 
+# Global array of PlayerStruct objects (defined below) to hold information 
about
+# structure definitions.
+structures=[]
 
-class Rule:
+# Accessor functions to allow access to dynamic arrays (e.g. 
playerc_laser_t.ranges).
+# accessor_header goes in playerc_wrap.h, accessor_interface goes in 
playerc_wrap.i.
+accessor_header="""
+typedef struct
+{
+    TYPE *actual;
+} TYPEArray;
+"""
 
-    def __init__(self):
+accessor_interface="""
+typedef struct
+{
+    TYPE *actual;
 
-        self.patterns = []
-        self.replacements = []
-        self.head = ''
-        self.foot = ''
-        return
+    %extend {
+        TYPE __getitem__(int index) {return $self->actual[index];}
+        void __setitem__(int index,TYPE value) {$self->actual[index]=value;}
+    }
+} TYPEArray;
+"""
 
+# Class for holding information about a detected structure, including a header
+# section for preprocessor directives and typedefs and a 'members' section for
+# external functions that become members.
+class PlayerStruct:
+    name=''
+    header=""
+    members=""
+    
+    def __init__(self,initName):
+        self.name=initName
+        
+    def __eq__(self,other):
+        if isinstance(other,str):
+            return self.name==other
+        return NotImplemented
 
-class Replace:
-    pass
+# Called for every function that matches the regex in main.  If successful,
+# the function will be removed, temporarily stored in a 'PlayerStruct' class,
+# and later reconstituted as a member function.
+def memberize(match):
+    # Used to remove the first parameter from a list of function parameters.
+    # The first parameter to a potential member function is a pointer to the 
structure
+    # to work with, which is not necessary after the transformation.
+    lastParams=re.compile('\(\s*\w+?.*?,\s*(?P<last>.*)\)',re.DOTALL)
+    funcName=match.group('name')
+    # The start of the loop checks chunks of the function name for a 
recognizable structure
+    # name.  e.g. playerc_some_class_do_some_action will try playerc_some, 
playerc_some_class
+    # and so on until a match is found.
+    objName="playerc"
+    for i in range(1,funcName.count("_")):
+        objName=funcName[:funcName.find("_",len(objName)+1)]
+        action=funcName[len(objName)+1:]
+        # Once a match is found, transform the external function to a member 
function.
+        if objName in structures:
+            struct=structures[structures.index(objName)]
+            # e.g. playerc_client_create
+            if action=="create":
+                # add the function to a structure
+                struct.members+="\t\t" + objName + " " + match.group('params') 
+ ";\n"
+                # add a preprocessor directive to ensure swig picks up the old 
library
+                # function name as a constructor.
+                struct.header+="\t#define new_" + objName + " " + funcName + 
"\n"
+            # e.g. playerc_client_destroy
+            elif action == "destroy":
+                # add the destructor to the structure.  No destructors take 
parameters
+                # or return a value.
+                struct.members+="\t\tvoid destroy(void);\n"
+                struct.header+="\t#define del_" + objName + " " + funcName + 
"\n"
+            # e.g. playerc_client_connect
+            else:
+                # set 'last' to every parameter in the parameter list except 
the first.
+                # if no match, there are less than two parameters, in which 
case the
+                # transformed function will have no parameters (void).
+                lm=lastParams.match(match.group('params'))
+                if lm:
+                    last=lm.group('last')
+                else:
+                    last="void"
+                # add the function prototype to the structure.
+                struct.members+="\t\t" + match.group('retval') + " " + action 
+ " (%s);\n" % last
+                # functions that are not constructors or destructors already 
match the required SWIG pattern,
+                # so no preprocessor directive is required.
+            # Since the function is a member function and will now have a 
prototype
+            # inside an 'extend' clause in the structure definition, remove 
the external
+            # reference by substituting with ''
+            return ''
+    # If the function is not a member function of a structure, take no action.
+    return match.group()
 
+# This function is called for every structure.  It attempts to find dynamically
+# allocated arrays of simple types (which are not subscriptable in python with
+# standard binding) and wrap them in an accessor structure defined at the top 
of this file.
+def accessorize(match):
+    # 'text' is the new code for the matched structure (to be returned)
+    text=match.group('decl')+"{"
+    # 'body' is everything within the {}s of the structure definition
+    body=match.group('body');
+    # 'arrayMember' is a regex designed to match certain member definitions,
+    # e.g. 'double *ranges;' (playerc_laser_t)
+    
arrayMember=re.compile(r"\b(?P<type>int|double|float)\s*[*]\s*(?P<name>\w+);",re.MULTILINE)
+    
+    # performs a substitution on the member definitions described above,
+    # e.g. 'double *ranges;' becomes 'doubleArray ranges;',
+    # and appends the modified struct body to the code.
+    text+=arrayMember.sub("\g<type>Array \g<name>;",body)
+    
+    # terminate the modified structure and add the 'footer', usually just the 
end
+    # of the typedef.
+    text+="}"+match.group('footer')
+    return text;
 
+# Called for every structure in the input stream.  Modifies the code block to 
include
+# an appropriate 'header' section with typedefs and preprocessor directives,
+# and adds new member function prototypes in a SWIG 'extend' block at the end 
of the
+# structure.
+def genifacestruct(match):
+    # ensure the structure has previously been scanned (should always be the 
case)
+    if match.group('name') in structures:
+        # retrieve the data about the matched structure
+        struct=structures[structures.index(match.group('name'))]
+        # add the header block and a typedef to permit the change from 
structname_t to structname
+        # (for clarity in python)
+        text="%header\n%{\n"+struct.header+"\ttypedef " + struct.name+"_t 
"+struct.name+";\n%}\n\n"
+        # add the structure declaration and the body, omitting a closing brace
+        text+=match.group('decl')+"{"+match.group('body')
+        # add the extension block with member function protoypes, plus a 
closing brace.
+        text+="\t%extend\n\t{\n"+struct.members+"\t}\n}"
+        # add the remainder of the original structure definition (usually just 
the typedef name)
+        text+=match.group('footer')
+        return text
+    # if no match, print a statement to that effect and return the original 
structure definition.
+    # should never happen.
+    print "No match on %s" % match.group('name')
+    return match.group() 
 
-def compile_comment():
-    """Compile comment rule."""
+# Used to remove _t from structure references.
+# Had to do this due to ambiguity with typedef statements and callback 
function prototypes.
+# e.g.   typedef void (*playerc_putmsg_fn_t) (void *device, char *header, char 
*data);
+# also   typedef player_blobfinder_blob_t playerc_blobfinder_blob_t;
+# This function ensures that only structures defined in playerc.h are modified.
+def underscore(match):
+    if match.group('name') in structures:
+        return match.group('name')
+    return match.group()
 
-    rule = Rule()
-    rule.type = 'comment'
-    rule.patterns += [re.compile('/\*.*?\*/', re.DOTALL)]
-    rule.patterns += [re.compile('//.*')]
-
-    return [rule]
-
-
-
-def compile(prefix):
-    """Compute the grammar."""
-
-    rules = []
-
-    # Create rule for typedefs
-    #rule = Rule()
-    #rule.type = 'typedef'
-    #rule.patterns += [re.compile('\s*\}\s*%s_t\s*;' % prefix)]
-    #rules += [rule]
-
-    # Create rule for constructor
-    rule = Rule()
-    rule.type = 'constructor'
-    rule.patterns += [re.compile('%s_t\s*\*\s*%s_create\s*\(.*?;' % (prefix, 
prefix), re.DOTALL)]
-
-    rule.head = '\n%%extend %s\n{\n' % prefix
-    rule.foot = '\n}\n'
-
-    rep = Replace()
-    rep.src = re.compile('\s*%s_create\s*' % (prefix))
-    rep.dst = '%s' % prefix
-    rule.replacements += [rep]
-
-    rep = Replace()
-    rep.src = re.compile('\(*\s*%s_t\s*\*\w*\s*\)' % prefix)
-    rep.dst = '()'
-    rule.replacements += [rep]
-
-    rep = Replace()
-    rep.src = re.compile('\(*\s*%s_t\s*\*\w*\s*,\s*' % prefix)
-    rep.dst = '('
-    rule.replacements += [rep]
-
-    rules += [rule]
-
-    # Create rule for destructor
-    rule = Rule()
-    rule.type = 'destructor'
-    rule.patterns += [re.compile('\w*\s*%s_destroy\s*\(.*?;' % (prefix), 
re.DOTALL)]
-
-    rule.head = '\n%%extend %s\n{\n' % prefix
-    rule.foot = '\n}\n'
-
-    rep = Replace()
-    rep.src = re.compile('\w*\s*%s_destroy\s*' % (prefix))
-    rep.dst = '~%s' % prefix
-    rule.replacements += [rep]
-
-    rep = Replace()
-    rep.src = re.compile('\(*\s*%s_t\s*\*\w*\s*\)' % prefix)
-    rep.dst = '()'
-    rule.replacements += [rep]
-
-    rep = Replace()
-    rep.src = re.compile('\(*\s*%s_t\s*\*\w*\s*,\s*' % prefix)
-    rep.dst = '('
-    rule.replacements += [rep]
-
-    rules += [rule]
-
-    # Create rule for regular functions
-    rule = Rule()
-    rule.type = 'method'
-    rule.patterns += [re.compile('\w*\s*%s_\w*\s*\(.*?;' % prefix, re.DOTALL)]
-    #rule.patterns += [re.compile('\w*\s*%s_[a-zA-Z0-9]*\s*\(.*?;' % prefix, 
re.DOTALL)]
-    rule.patterns += [re.compile('\w*\s*\w*\s*%s_\w*\s*\(.*?;' % prefix, 
re.DOTALL)]
-    #rule.patterns += [re.compile('\w*\s*\w*\s*%s_[a-zA-Z0-9]*\s*\(.*?;' % 
prefix, re.DOTALL)]
-    rule.patterns += [re.compile('\w*\s*\*%s_\w*\s*\(.*?;' % prefix, 
re.DOTALL)]
-    #rule.patterns += [re.compile('\w*\s*\*%s_[a-zA-Z0-9]*\s*\(.*?;' % prefix, 
re.DOTALL)]
-
-    rule.head = '\n%%extend %s\n{\n' % prefix
-    rule.foot = '\n}\n'
-
-    rep = Replace()
-    rep.src = re.compile('%s_*' % prefix)
-    rep.dst = ''
-    rule.replacements += [rep]
-
-    rep = Replace()
-    rep.src = re.compile('\(*\s*%s_t\s*\*\s*\w*\s*\)' % prefix)
-    rep.dst = '()'
-    rule.replacements += [rep]
-
-    rep = Replace()
-    rep.src = re.compile('\(*\s*%s_t\s*\*\s*\w*\s*,\s*' % prefix)
-    rep.dst = '('
-    rule.replacements += [rep]
-
-    rules += [rule]
-
-    return rules
-
-
-def extract_prefixes(instream):
-    """Extract class prefixes."""
-
-    # Remove block comments from the file
-    commentRule = re.compile('/\*.*?\*/', re.DOTALL)
-    tempstream = commentRule.sub ('', instream)
-    commentRule = re.compile('//.*')
-    tempstream = commentRule.sub ('', tempstream)
-
-    src = re.compile('playerc_\w*_create')
-    constructors = src.findall(tempstream)
-
-    prefixes = []
-    for c in constructors:
-        prefixes += [c[:-7]]
-
-    return prefixes
-
-
-def parse_file(instream, rules):
-    """Apply replacement rules."""
-
-    outstream = ''
-    current_struct = None
-
-    while instream:
-
-        line = instream
-        m = None
-
-        for rule in rules:
-            # See if this line matches the rule
-            for pattern in rule.patterns:
-                m = pattern.match(line)
-                if m:
-                    break
-            if not m:
-                continue
-
-            func = line[m.start():m.end()]
-
-            # Parse comment blocks
-            if rule.type == 'comment':
-                #print instream[m.start():m.end()]
-                instream = instream[m.end():]
-                outstream += func
-                break
-
-            # Parse function name and args
-            (name, sig) = string.split(func, '(', 1)
-            sig = '(' + sig
-            tokens = string.split(name)
-            (rval, name) = (string.join(tokens[:-1]), tokens[-1])
-            if name[0] == '*':
-                name = name[1:]
-                rval = rval + ' *'
-            #print '%s | %s | %s' % (rval, name, sig)
-
-            # Apply replacement rules to return type
-            if rule.type == 'constructor':
-                rval = ''
-
-            # Apply replacement rules to name
-            for rep in rule.replacements:
-                mm = rep.src.search(name)
-                if not mm:
-                    continue
-                name = name[:mm.start()] + rep.dst + name[mm.end():]
-
-            # Apply replacement rules to signature
-            for rep in rule.replacements:
-                mm = rep.src.match(sig)
-                if not mm:
-                    continue
-                sig = sig[:mm.start()] + rep.dst + sig[mm.end():]
-
-            #print rval, name, sig
-
-            outstream += rule.head
-            outstream += '%s %s %s' % (rval, name, sig)
-            outstream += rule.foot
-
-            instream = instream[m.end():]
-
-            break
-
-        # If no rule matches
-        if not m:
-            outstream += instream[:1]
-            instream = instream[1:]
-
-    return outstream
-
-
-
-
 if __name__ == '__main__':
 
+    # should always be playerc.h
     infilename = sys.argv[1]
+    # should always be 'playerc_wrap'
     outfilename = sys.argv[2]
 
     # Read in the entire file
     file = open(infilename, 'r')
-    instream = file.read()
+    ifaceStream = file.read()
+    file.close()
 
-    # Extract "class prefixes" from the header
-    prefixes = extract_prefixes(instream)
+    # Pattern to remove all double-spacing (used later)
+    blank=re.compile('([ \t\f\v\r]*\n){3,}',re.MULTILINE)
 
-    #prefixes = ['playerc_log']
+    # Remove all comments (multi- and single-line).
+    comment=re.compile('((/\*.*?\*/)|(//.*?$))', re.DOTALL|re.MULTILINE)
+    ifaceStream=comment.sub('',ifaceStream)
 
-    # Compute the grammar
-    rules = []
-    rules += compile_comment()
-    for prefix in prefixes:
-        print 'prefix: %s' % prefix
-        rules += compile(prefix)
+    # Pattern to recognise structure definitions
+    struct=re.compile("""
+        (?P<decl>typedef\s+struct\s*\w*\s*)  # Declaration
+        {(?P<body>.*?)}(?P<footer>\s*        # Body
+        (?P<name>playerc_\w+?)(_t)?          # Name
+        \s*;)
+    """, re.DOTALL|re.VERBOSE)
+    
+    # Match and replace all structure definitions with versions that have
+    # accessor structures for dynamically allocated arrays using the 
'accessorize'
+    # function above.
+    ifaceStream=struct.sub(accessorize,ifaceStream)
+    
+    # remove all double-spacing (pattern defined above)
+    ifaceStream=blank.sub('\n\n',ifaceStream)
 
-    # Parse the file and appy replacement rules
-    outstream = parse_file(instream, rules)
+    # output to new header file.  It is necessary to modify the original 
header file to
+    # allow for data types of structure members to be changed.  Pointers are 
modified
+    # to structures containing a pointer, to allow the member to be 
subscriptable in python.
+    # see comments on the 'accessorize' function above.  
+    file=open("%s.h" % outfilename,"w")
+    # write accessor structure definitions for arrays of ints, doubles and 
floats.
+    for type in ["int","double","float"]:
+        file.write(accessor_header.replace("TYPE",type))
+    # write the modified header file.
+    file.write(ifaceStream)
+    file.close()
+    
+    # find the names of all the structures defined in the file, and make
+    # a list of objects to store information about the structures.
+    # could be done as part of 'accessorize' but left here for clarity.
+    am=struct.finditer(ifaceStream)
+    for m in am:
+        structures+=[PlayerStruct(m.group('name'))]
 
-    # Do some final replacements
-    for prefix in prefixes:
-        outstream = string.replace(outstream, '%s_t' % prefix, '%s' % prefix)
+    # Pattern to match function prototypes that could be changed to 'member 
functions'
+    # of structures, allowing object-oriented style calling from Python.
+    function=re.compile("""
+        \s*    
+        ((?P<retval>                  # Capture the return type:
+            \w+\s*?(                  # Type name, is a 
+            \** |                     # pointer OR
+            &?  |                     # reference OR
+            (\[\s*[0-9]*\s*\])        # array.
+            )
+        )\s*)?                        # Only one (potential) return value.
+        (?P<name>                     # Capture function name
+            playerc_\w+               # Class name and member function name
+        )\s*
+        (?P<params>\(.*?\))           # Parameters
+        \s*;
+    """, re.DOTALL|re.VERBOSE)
 
-    guff = ''
-    propguff = ''
-    for prefix in prefixes:
-        guff += '%%header\n %%{\ntypedef %s_t %s;\n' % (prefix, prefix)
-        guff += '#define new_%s %s_create\n' % (prefix, prefix)
-        guff += '#define del_%s %s_destroy\n' % (prefix, prefix)
-        guff += '%}\n'
-        
-        # stuff for properties 
-        if prefix != "playerc_mclient" and prefix != "playerc_client":
-            propguff += """
-%%extend %(prefix)s
-{
-int get_intprop (char * propname)
-{
-    int ret;
-    if (playerc_device_get_intprop(&self->info,propname,&ret) == 0)
-        return ret;
-    else
-        return 0;
-};
-int set_intprop (char * propname, int value)
-{
-    return playerc_device_set_intprop(&self->info,propname,value);
-};
+    # remove the _t from the end of all the struct references.
+    structNames=re.compile(r"\b(?P<name>playerc_\w+)_t\b")
+    ifaceStream=structNames.sub(underscore,ifaceStream)
 
-double get_dblprop (char * propname)
-{
-    double ret;
-    if (playerc_device_get_dblprop(&self->info,propname,&ret) == 0)
-        return ret;
-    else
-        return 0;
-};
-int set_dblprop (char * propname, double value)
-{
-    return playerc_device_set_dblprop(&self->info,propname,value);
-};
+    # using the 'memberize' function, find functions that should be struct 
'members' and shift them.
+    ifaceStream=function.sub(memberize,ifaceStream)
 
-char * get_strprop (char * propname)
-{
-    char * ret;
-    if (playerc_device_get_strprop(&self->info,propname,&ret) == 0)
-        return ret;
-    else
-        return NULL;
-};
-int set_strprop (char * propname, char * value)
-{
-    return playerc_device_set_strprop(&self->info,propname,value);
-};
-} """ % {"prefix": prefix}
-        
+    # Using the gathered information about functions and structures, rewrite 
the structure
+    # definitions in the interface file to include required extensions 
(function prototypes), 
+    # typedefs and preprocessor directives.  see comments on 'genifacestruct' 
function above.
+    ifaceStream=struct.sub(genifacestruct,ifaceStream)
 
-    outstream = guff + outstream + propguff
-
-    file = open(outfilename, 'w+')
-    file.write(outstream)
-
+    # remove all double spacing.
+    ifaceStream=blank.sub('\n\n',ifaceStream)
+    
+    # write the SWIG interface definition file.
+    file=open("%s.i" % outfilename,"w")
+    # write interfaces for the accessor structs including subscripting 
functions.
+    for type in ["int","double","float"]:
+        file.write(accessor_interface.replace("TYPE",type))
+    file.write(ifaceStream)
+    file.close()
+    
\ No newline at end of file

Modified: code/player/trunk/examples/libplayerc++/example3.cc
===================================================================
--- code/player/trunk/examples/libplayerc++/example3.cc 2009-02-19 03:47:45 UTC 
(rev 7345)
+++ code/player/trunk/examples/libplayerc++/example3.cc 2009-02-23 01:34:23 UTC 
(rev 7346)
@@ -2,6 +2,7 @@
 #include <iostream>
 #include <list>
 #include <algorithm>
+#include <functional>
 
 int main(int argc, char** argv)
 {


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Playerstage-commit mailing list
Playerstage-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to