Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test failure on i586 #61

Open
jayvdb opened this issue Oct 20, 2019 · 2 comments
Open

Test failure on i586 #61

jayvdb opened this issue Oct 20, 2019 · 2 comments

Comments

@jayvdb
Copy link
Contributor

jayvdb commented Oct 20, 2019

[   72s] ======================================================================
[   72s] FAIL: test_extern_function_pointer_multiarg (test_types_values.ConstantsTest)
[   72s] ----------------------------------------------------------------------
[   72s] Traceback (most recent call last):
[   72s]   File "/home/abuild/rpmbuild/BUILD/ctypeslib-2.2.2/test/test_types_values.py", line 283, in test_extern_function_pointer_multiarg
[   72s]     'c_int')
[   72s] AssertionError: 'c_long' != 'c_int'
[   72s] - c_long
[   72s] + c_int
@trolldbois
Copy link
Owner

mmh.. yeah, that would requires making the tests architecture-aware... i'll pass on that.

does clang2py produces workable results on i586 ?

For example:
clang2py test/data/test-records.c --clang-args="-target i586-linux"

@jayvdb
Copy link
Contributor Author

jayvdb commented Feb 19, 2021

clang2py test/data/test-records.c --clang-args="-target i586-linux"

When run on i586 machine

[   56s] INFO:codegen:No members for: struct_Anon
[   56s] INFO:codegen:No members for: struct_Anon2
[   56s] # -*- coding: utf-8 -*-
[   56s] #
[   56s] # TARGET arch is: ['-target', 'i586-linux']
[   56s] # WORD_SIZE is: 4
[   56s] # POINTER_SIZE is: 4
[   56s] # LONGDOUBLE_SIZE is: 12
[   56s] #
[   56s] import ctypes
[   56s] 
[   56s] 
[   56s] class AsDictMixin:
[   56s]     @classmethod
[   56s]     def as_dict(cls, self):
[   56s]         result = {}
[   56s]         if not isinstance(self, AsDictMixin):
[   56s]             # not a structure, assume it's already a python object
[   56s]             return self
[   56s]         if not hasattr(cls, "_fields_"):
[   56s]             return result
[   56s]         for (field, *_) in cls._fields_:  # noqa
[   56s]             if field.startswith('PADDING_'):
[   56s]                 continue
[   56s]             value = getattr(self, field)
[   56s]             type_ = type(value)
[   56s]             if hasattr(value, "_length_") and hasattr(value, "_type_"):
[   56s]                 # array
[   56s]                 if not hasattr(type_, "as_dict"):
[   56s]                     value = [v for v in value]
[   56s]                 else:
[   56s]                     type_ = type_._type_
[   56s]                     value = [type_.as_dict(v) for v in value]
[   56s]             elif hasattr(value, "contents") and hasattr(value, "_type_"):
[   56s]                 # pointer
[   56s]                 try:
[   56s]                     if not hasattr(type_, "as_dict"):
[   56s]                         value = value.contents
[   56s]                     else:
[   56s]                         type_ = type_._type_
[   56s]                         value = type_.as_dict(value.contents)
[   56s]                 except ValueError:
[   56s]                     # nullptr
[   56s]                     value = None
[   56s]             elif isinstance(value, AsDictMixin):
[   56s]                 # other structure
[   56s]                 value = type_.as_dict(value)
[   56s]             result[field] = value
[   56s]         return result
[   56s] 
[   56s] 
[   56s] class Structure(ctypes.Structure, AsDictMixin):
[   56s] 
[   56s]     def __init__(self, *args, **kwds):
[   56s]         # We don't want to use positional arguments fill PADDING_* fields
[   56s] 
[   56s]         args = dict(zip(self.__class__._field_names_(), args))
[   56s]         args.update(kwds)
[   56s]         super(Structure, self).__init__(**args)
[   56s] 
[   56s]     @classmethod
[   56s]     def _field_names_(cls):
[   56s]         if hasattr(cls, '_fields_'):
[   56s]             return (f[0] for f in cls._fields_ if not f[0].startswith('PADDING'))
[   56s]         else:
[   56s]             return ()
[   56s] 
[   56s]     @classmethod
[   56s]     def get_type(cls, field):
[   56s]         for f in cls._fields_:
[   56s]             if f[0] == field:
[   56s]                 return f[1]
[   56s]         return None
[   56s] 
[   56s]     @classmethod
[   56s]     def bind(cls, bound_fields):
[   56s]         fields = {}
[   56s]         for name, type_ in cls._fields_:
[   56s]             if hasattr(type_, "restype"):
[   56s]                 if name in bound_fields:
[   56s]                     # use a closure to capture the callback from the loop scope
[   56s]                     fields[name] = (
[   56s]                         type_((lambda callback: lambda *args: callback(*args))(
[   56s]                             bound_fields[name]))
[   56s]                     )
[   56s]                     del bound_fields[name]
[   56s]                 else:
[   56s]                     # default callback implementation (does nothing)
[   56s]                     try:
[   56s]                         default_ = type_(0).restype().value
[   56s]                     except TypeError:
[   56s]                         default_ = None
[   56s]                     fields[name] = type_((
[   56s]                         lambda default_: lambda *args: default_)(default_))
[   56s]             else:
[   56s]                 # not a callback function, use default initialization
[   56s]                 if name in bound_fields:
[   56s]                     fields[name] = bound_fields[name]
[   56s]                     del bound_fields[name]
[   56s]                 else:
[   56s]                     fields[name] = type_()
[   56s]         if len(bound_fields) != 0:
[   56s]             raise ValueError(
[   56s]                 "Cannot bind the following unknown callback(s) {}.{}".format(
[   56s]                     cls.__name__, bound_fields.keys()
[   56s]             ))
[   56s]         return cls(**fields)
[   56s] 
[   56s] 
[   56s] class Union(ctypes.Union, AsDictMixin):
[   56s]     pass
[   56s] 
[   56s] 
[   56s] 
[   56s] # if local wordsize is same as target, keep ctypes pointer function.
[   56s] if ctypes.sizeof(ctypes.c_void_p) == 4:
[   56s]     POINTER_T = ctypes.POINTER
[   56s] else:
[   56s]     class IncorrectWordSizeError(TypeError):
[   56s]         pass
[   56s]     # required to access _ctypes
[   56s]     import _ctypes
[   56s]     # Emulate a pointer class using the approriate c_int32/c_int64 type
[   56s]     # The new class should have :
[   56s]     # ['__module__', 'from_param', '_type_', '__dict__', '__weakref__', '__doc__']
[   56s]     # but the class should be submitted to a unique instance for each base type
[   56s]     # to that if A == B, POINTER_T(A) == POINTER_T(B)
[   56s]     ctypes._pointer_t_type_cache = {}
[   56s]     def POINTER_T(pointee):
[   56s]         # a pointer should have the same length as LONG
[   56s]         fake_ptr_base_type = ctypes.c_uint32
[   56s]         # specific case for c_void_p
[   56s]         if pointee is None: # VOID pointer type. c_void_p.
[   56s]             pointee = type(None) # ctypes.c_void_p # ctypes.c_ulong
[   56s]             clsname = 'c_void'
[   56s]         else:
[   56s]             clsname = pointee.__name__
[   56s]         if clsname in ctypes._pointer_t_type_cache:
[   56s]             return ctypes._pointer_t_type_cache[clsname]
[   56s]         # make template
[   56s]         class _T(_ctypes._SimpleCData,):
[   56s]             _type_ = 'L'
[   56s]             _subtype_ = pointee
[   56s]             def _sub_addr_(self):
[   56s]                 return self.value
[   56s]             def __repr__(self):
[   56s]                 return '%s(%d)'%(clsname, self.value)
[   56s]             def contents(self):
[   56s]                 raise IncorrectWordSizeError('This is not a ctypes pointer.')
[   56s]             def __init__(self, **args):
[   56s]                 raise IncorrectWordSizeError('This is not a ctypes pointer. It is not instanciable.')
[   56s]         _class = type('LP_%d_%s'%(4, clsname), (_T,),{})
[   56s]         ctypes._pointer_t_type_cache[clsname] = _class
[   56s]         return _class
[   56s] 
[   56s] c_int128 = ctypes.c_ubyte*16
[   56s] c_uint128 = c_int128
[   56s] void = None
[   56s] if ctypes.sizeof(ctypes.c_longdouble) == 12:
[   56s]     c_long_double_t = ctypes.c_longdouble
[   56s] else:
[   56s]     c_long_double_t = ctypes.c_ubyte*12
[   56s] 
[   56s] 
[   56s] 
[   56s] class struct_Name(Structure):
[   56s]     _pack_ = True # source:True
[   56s]     _fields_ = [
[   56s]     ('member1', ctypes.c_int16),
[   56s]     ('member2', ctypes.c_int32),
[   56s]     ('member3', ctypes.c_uint32),
[   56s]     ('member4', ctypes.c_uint32),
[   56s]     ('member5', ctypes.c_uint32),
[   56s]      ]
[   56s] 
[   56s] class struct_Name2(Structure):
[   56s]     _pack_ = True # source:False
[   56s]     _fields_ = [
[   56s]     ('member1', ctypes.c_int16),
[   56s]     ('PADDING_0', ctypes.c_ubyte * 2),
[   56s]     ('member2', ctypes.c_int32),
[   56s]     ('member3', ctypes.c_uint32),
[   56s]     ('member4', ctypes.c_uint32),
[   56s]     ('member5', ctypes.c_uint32),
[   56s]      ]
[   56s] 
[   56s] class struct_Node(Structure):
[   56s]     pass
[   56s] 
[   56s] class struct_Node2(Structure):
[   56s]     _pack_ = True # source:False
[   56s]     _fields_ = [
[   56s]     ('m1', ctypes.c_ubyte),
[   56s]     ('PADDING_0', ctypes.c_ubyte * 3),
[   56s]     ('m2', POINTER_T(struct_Node)),
[   56s]      ]
[   56s] 
[   56s] struct_Node._pack_ = True # source:False
[   56s] struct_Node._fields_ = [
[   56s]     ('val1', ctypes.c_uint32),
[   56s]     ('ptr2', POINTER_T(None)),
[   56s]     ('ptr3', POINTER_T(ctypes.c_int32)),
[   56s]     ('ptr4', POINTER_T(struct_Node2)),
[   56s] ]
[   56s] 
[   56s] class struct_Node3(Structure):
[   56s]     _pack_ = True # source:False
[   56s]     _fields_ = [
[   56s]     ('ptr1', POINTER_T(struct_Node)),
[   56s]     ('ptr2', POINTER_T(ctypes.c_ubyte)),
[   56s]     ('ptr3', POINTER_T(ctypes.c_uint16)),
[   56s]     ('ptr4', POINTER_T(ctypes.c_uint32)),
[   56s]     ('ptr5', POINTER_T(ctypes.c_uint32)),
[   56s]     ('ptr6', POINTER_T(ctypes.c_uint64)),
[   56s]     ('ptr7', POINTER_T(ctypes.c_double)),
[   56s]     ('ptr8', POINTER_T(c_long_double_t)),
[   56s]     ('ptr9', POINTER_T(None)),
[   56s]      ]
[   56s] 
[   56s] class struct_Node4(Structure):
[   56s]     _pack_ = True # source:False
[   56s]     _fields_ = [
[   56s]     ('f1', struct_Node),
[   56s]     ('f2', ctypes.c_ubyte),
[   56s]     ('PADDING_0', ctypes.c_ubyte),
[   56s]     ('f3', ctypes.c_uint16),
[   56s]     ('f4', ctypes.c_uint32),
[   56s]     ('f5', ctypes.c_uint32),
[   56s]     ('f6', ctypes.c_uint64),
[   56s]     ('f7', ctypes.c_double),
[   56s]     ('f8', c_long_double_t),
[   56s]      ]
[   56s] 
[   56s] 
[   56s] # values for enumeration 'myEnum'
[   56s] myEnum__enumvalues = {
[   56s]     0: 'ONE',
[   56s]     1: 'TWO',
[   56s]     4: 'FOUR',
[   56s] }
[   56s] ONE = 0
[   56s] TWO = 1
[   56s] FOUR = 4
[   56s] myEnum = ctypes.c_int # enum
[   56s] class struct_c__SA_my__quad_t(Structure):
[   56s]     _pack_ = True # source:False
[   56s]     _fields_ = [
[   56s]     ('__val', ctypes.c_int32 * 2),
[   56s]      ]
[   56s] 
[   56s] my__quad_t = struct_c__SA_my__quad_t
[   56s] class struct_c__SA_my_bitfield(Structure):
[   56s]     _pack_ = True # source:False
[   56s]     _fields_ = [
[   56s]     ('a', ctypes.c_int32, 3),
[   56s]     ('b', ctypes.c_int32, 4),
[   56s]     ('c', ctypes.c_int32, 3),
[   56s]     ('d', ctypes.c_int32, 3),
[   56s]     ('f', ctypes.c_int32, 2),
[   56s]     ('PADDING_0', ctypes.c_uint32, 17),
[   56s]      ]
[   56s] 
[   56s] my_bitfield = struct_c__SA_my_bitfield
[   56s] class struct_c__SA_mystruct(Structure):
[   56s]     _pack_ = True # source:True
[   56s]     _fields_ = [
[   56s]     ('a', ctypes.c_int32),
[   56s]     ('c', ctypes.c_char),
[   56s]      ]
[   56s] 
[   56s] mystruct = struct_c__SA_mystruct
[   56s] class struct_Anon(Structure):
[   56s]     pass
[   56s] 
[   56s] class struct_Anon2(Structure):
[   56s]     pass
[   56s] 
[   56s] __all__ = \
[   56s]     ['FOUR', 'ONE', 'TWO', 'myEnum', 'my__quad_t', 'my_bitfield',
[   56s]     'mystruct', 'struct_Anon', 'struct_Anon2', 'struct_Name',
[   56s]     'struct_Name2', 'struct_Node', 'struct_Node2', 'struct_Node3',
[   56s]     'struct_Node4', 'struct_c__SA_my__quad_t',
[   56s]     'struct_c__SA_my_bitfield', 'struct_c__SA_mystruct']

Note test_callbacks also fails. one test method fails on 64 bit, and the other fails on 32 bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants