Skip to content

Commit

Permalink
const for pointers
Browse files Browse the repository at this point in the history
This commit needs Cython > 0.18 as support for
const pointers was just recently added with commit
5e1497371ee70fffb2deb6c7dab136cf6684f2df [1].

[1] cython/cython@5e14973
  • Loading branch information
vmx committed Apr 3, 2013
1 parent 67d2d11 commit 739237e
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.rst
Expand Up @@ -11,6 +11,7 @@ Requirements
------------

* the libclang library (libclang.so, libclang.dylib or libclang.dll), contained in `llvm binary distribution <http://llvm.org/releases/download.html>`_ needs to be somewhere on the binary search path.
* if your header files contain const definitions, you need a Cython > 0.18 in order to be able to compile it


Getting started
Expand Down
4 changes: 3 additions & 1 deletion cwrap/backend/cw_ast.py
Expand Up @@ -1470,9 +1470,11 @@ class Pointer(ctype):
value : a ctype node.
"""
def init(self, value):
def init(self, value, const=False, volatile=False):
assert_ctype(value, 'value')
self.value = value
self.const = const
self.volatile = volatile


class Array(ctype):
Expand Down
7 changes: 6 additions & 1 deletion cwrap/backend/renderer.py
Expand Up @@ -1063,6 +1063,8 @@ def extract_reference_types(self, node):

while isinstance(node, (cw_ast.Pointer, cw_ast.Array)):
if isinstance(node, cw_ast.Pointer):
if node.const:
mods.append('const')
mods.append('*')
else:
dim = node.dim
Expand All @@ -1073,7 +1075,8 @@ def extract_reference_types(self, node):

i = 0
while i < (len(mods) - 1):
if mods[i][0] == '[' and mods[i][-1] == ']':
if (mods[i][0] == '[' and mods[i][-1] == ']') or \
mods[i] == 'const' or mods[i + 1] == 'const':
i += 1
elif mods[i] != mods[i + 1]:
mods.insert(i + 1, '()')
Expand All @@ -1091,6 +1094,8 @@ def apply_reference_types(self, mods, name):
name = sub_str % (mod, name)
elif mod == '()':
name = '(%s)' % name
elif mod == 'const':
name = 'const %s' % name
else:
name = sub_str % (name, mod)
return name
Expand Down
8 changes: 6 additions & 2 deletions cwrap/frontends/clang/ast_transforms.py
Expand Up @@ -424,8 +424,12 @@ def translate_ArrayType(self, array):
return cw_ast.Array(self.visit_translate(array.typ), dim)

def translate_CvQualifiedType(self, qual):
return cw_ast.TypeName(cw_ast.Name(qual.typ.name, cw_ast.Param),
qual.const, qual.volatile)
# The `const` and `volatile` attributes are defined for `TypeName`
# and `Pointer`
cvtype = self.visit_translate(qual.typ)
cvtype.const = qual.const
cvtype.volatile = qual.volatile
return cvtype

def translate_Typedef(self, typedef):
return cw_ast.TypeName(cw_ast.Name(typedef.name, cw_ast.Param))
Expand Down
10 changes: 8 additions & 2 deletions cwrap/frontends/clang/clang_parser.py
Expand Up @@ -178,12 +178,18 @@ def type_to_c_ast_type(self, t, level, recurse = True):
return c_ast.ArrayType(a, 0, t.element_count-1), None

elif kind is TypeKind.TYPEDEF:
return c_ast.FundamentalType(t.get_declaration().spelling), None #t.get_declaration().hash
const = t.is_const_qualified()
volatile = t.is_volatile_qualified()
fundtype = c_ast.FundamentalType(t.get_declaration().spelling)
return c_ast.CvQualifiedType(fundtype, const, volatile), None

elif kind is TypeKind.POINTER:
const = t.is_const_qualified()
volatile = t.is_volatile_qualified()
ptrtype, foo = self.type_to_c_ast_type(t.get_pointee(), level+1)
if ptrtype is not None:
return c_ast.PointerType(ptrtype, None, None), None
ptrtype = c_ast.PointerType(ptrtype, None, None)
return c_ast.CvQualifiedType(ptrtype, const, volatile), None

elif kind is TypeKind.LVALUEREFERENCE:
reftype, foo = self.type_to_c_ast_type(t.get_pointee(), level+1)
Expand Down
5 changes: 5 additions & 0 deletions test/data/const_argument.h
@@ -1 +1,6 @@
int foo(const char* bar);
typedef struct my_st my_t
int baz(const my_t **foo);
int bar(const my_t *const *something);
int another(my_t *const *one);
int yet(my_t *const *const another);
7 changes: 7 additions & 0 deletions test/data/const_argument.pxd
@@ -1,2 +1,9 @@
cdef extern from "const_argument.h":
int foo(const char *bar)
cdef struct my_st:
pass
ctypedef my_st my_t
int baz(const my_t **foo)
int bar(const my_t *const *something)
int another(my_t *const *one)
int yet(my_t *const *const another)

0 comments on commit 739237e

Please sign in to comment.