summaryrefslogtreecommitdiff
path: root/scipy/weave/cpp_namespace_spec.py
diff options
context:
space:
mode:
Diffstat (limited to 'scipy/weave/cpp_namespace_spec.py')
-rwxr-xr-xscipy/weave/cpp_namespace_spec.py110
1 files changed, 110 insertions, 0 deletions
diff --git a/scipy/weave/cpp_namespace_spec.py b/scipy/weave/cpp_namespace_spec.py
new file mode 100755
index 000000000..bfd67d2f3
--- /dev/null
+++ b/scipy/weave/cpp_namespace_spec.py
@@ -0,0 +1,110 @@
+""" This converter works with classes protected by a namespace with
+ SWIG pointers (Python strings). To use it to wrap classes in
+ a C++ namespace called "ft", use the following:
+
+ class ft_converter(cpp_namespace_converter):
+ namespace = 'ft::'
+"""
+
+from weave import common_info
+from weave import base_info
+from weave.base_spec import base_converter
+
+cpp_support_template = \
+"""
+static %(cpp_struct)s* convert_to_%(cpp_clean_struct)s(PyObject* py_obj,char* name)
+{
+ %(cpp_struct)s *cpp_ptr = 0;
+ char* str = PyString_AsString(py_obj);
+ if (!str)
+ handle_conversion_error(py_obj,"%(cpp_struct)s", name);
+ // work on this error reporting...
+ //std::cout << "in:" << name << " " py_obj << std::endl;
+ if (SWIG_GetPtr(str,(void **) &cpp_ptr,"_%(cpp_struct)s_p"))
+ {
+ handle_conversion_error(py_obj,"%(cpp_struct)s", name);
+ }
+ //std::cout << "out:" << name << " " << str << std::endl;
+ return cpp_ptr;
+}
+
+static %(cpp_struct)s* py_to_%(cpp_clean_struct)s(PyObject* py_obj,char* name)
+{
+ %(cpp_struct)s *cpp_ptr;
+ char* str = PyString_AsString(py_obj);
+ if (!str)
+ handle_conversion_error(py_obj,"%(cpp_struct)s", name);
+ // work on this error reporting...
+ if (SWIG_GetPtr(str,(void **) &cpp_ptr,"_%(cpp_struct)s_p"))
+ {
+ handle_conversion_error(py_obj,"%(cpp_struct)s", name);
+ }
+ return cpp_ptr;
+}
+
+std::string %(cpp_clean_struct)s_to_py( %(cpp_struct)s* cpp_ptr)
+{
+ char ptr_string[%(ptr_string_len)s];
+ SWIG_MakePtr(ptr_string, cpp_ptr, "_%(cpp_struct)s_p");
+ return std::string(ptr_string);
+}
+
+"""
+
+class cpp_namespace_converter(base_converter):
+ _build_information = [common_info.swig_info()]
+ def __init__(self,class_name=None):
+ self.type_name = 'unkown cpp_object'
+ self.name = 'no name'
+ if class_name:
+ # customize support_code for whatever type I was handed.
+ clean_name = class_name.replace('::','_')
+ clean_name = clean_name.replace('<','_')
+ clean_name = clean_name.replace('>','_')
+ clean_name = clean_name.replace(' ','_')
+ # should be enough for 64 bit machines
+ str_len = len(clean_name) + 20
+ vals = {'cpp_struct': class_name,
+ 'cpp_clean_struct': clean_name,
+ 'ptr_string_len': str_len }
+ specialized_support = cpp_support_template % vals
+ custom = base_info.base_info()
+ custom._support_code = [specialized_support]
+ self._build_information = self._build_information + [custom]
+ self.type_name = class_name
+
+ def type_match(self,value):
+ try:
+ cpp_ident = value.split('_')[2]
+ if cpp_ident.find(self.namespace) != -1:
+ return 1
+ except:
+ pass
+ return 0
+
+ def type_spec(self,name,value):
+ # factory
+ ptr_fields = value.split('_')
+ class_name = '_'.join(ptr_fields[2:-1])
+ new_spec = self.__class__(class_name)
+ new_spec.name = name
+ return new_spec
+
+ def declaration_code(self,inline=0):
+ type = self.type_name
+ clean_type = type.replace('::','_')
+ name = self.name
+ var_name = self.retrieve_py_variable(inline)
+ template = '%(type)s *%(name)s = '\
+ 'convert_to_%(clean_type)s(%(var_name)s,"%(name)s");\n'
+ code = template % locals()
+ return code
+
+ def __repr__(self):
+ msg = "(%s:: name: %s)" % (self.type_name,self.name)
+ return msg
+ def __cmp__(self,other):
+ #only works for equal
+ return cmp(self.name,other.name) or \
+ cmp(self.__class__, other.__class__) or \
+ cmp(self.type_name,other.type_name)