<commit_before>'''Create ctypes wrapper code for abstract type descriptions.
Type descriptions are collections of typedesc instances.
'''

import typedesc, sys, os
import textwrap
import struct
import ctypes

import clangparser

import logging
log = logging.getLogger('codegen')

import code

import StringIO # need unicode support, no cStringIO



def get_real_type(tp):
    if type(tp) is typedesc.Typedef:
        if type(tp.typ) is typedesc.Typedef:
            import code
            code.interact(local=locals())
            raise TypeError('Nested loop in Typedef %s'%(tp.name))
        return get_real_type(tp.typ)
    elif isinstance(tp, typedesc.CvQualifiedType):
        return get_real_type(tp.typ)
    return tp

################################################################

class Generator(object):
    def __init__(self, output,
                 generate_comments=False,
                 known_symbols=None,
                 searched_dlls=None,
                 preloaded_dlls=[],
                 generate_docstrings=False,
                 generate_locations=False):
        self.output = output
        self.stream = StringIO.StringIO()
        self.imports = StringIO.StringIO()
        self.generate_locations = generate_locations
        self.generate_comments = generate_comments
        self.generate_docstrings = generate_docstrings
        self.known_symbols = known_symbols or {}
        self.preloaded_dlls = preloaded_dlls
        if searched_dlls is None:
            self.searched_dlls = []
        else:
            self.searched_dlls = searched_dlls

        self.done = set() # type descriptions that have been generated
        self.names = set() # names that have been generated

    def enable_pythonic_types(self):
        """
        If a type name starts with '__', some wrapper needs to be used for
        the generated code to be valid.
        """
        self.enable_pythonic_types = lambda : True
        import pkgutil
        headers = pkgutil.get_data('ctypeslib','data/pythonic_type_name.tpl')
        print >> self.imports, headers
    
    def type_name(self, t, generate=True):
        """
        Returns a string containing an expression that can be used to
        refer to the type. Assumes the 'from ctypes import *'
        namespace is available.
        """
        #import code
        #code.interact(local=locals())
        if isinstance(t, typedesc.Argument):
            return "%s" % self.type_name(t.typ, generate)
        elif isinstance(t, typedesc.ArrayType):
            return "%s * %s" % (self.type_name(t.typ, generate), t.size)
        elif isinstance(t, typedesc.CvQualifiedType):
            # const and volatile are ignored
            return "%s" % self.type_name(t.typ, generate)
        elif isinstance(t, typedesc.Enumeration):
            if t.name:
                return t.name
            return "ctypes.c_int" # enums are integers
        elif isinstance(t, typedesc.FunctionType):
            args = [self.type_name(x, generate) for x in [t.returns] + list(t.iterArgTypes())]
            if "__stdcall__" in t.attributes:
                return "ctypes.WINFUNCTYPE(%s)" % ", ".join(args)
            else:
                return "ctypes.CFUNCTYPE(%s)" % ", ".join(args)
        elif isinstance(t, typedesc.FundamentalType):
            return self.FundamentalType(t) #t.name #"ctypes.%s"%(t.name)
        elif isinstance(t, typedesc.PointerType):
            return "POINTER_T(%s)" %(self.type_name(t.typ, generate))
        elif isinstance(t, typedesc.Structure):
            return t.name
        elif isinstance(t, typedesc.Typedef):
            return t.name
        elif isinstance(t, typedesc.Union):
            return t.name
        elif isinstance(t, typedesc.Variable):
            return "%s" % self.type_name(t.typ, generate)
        # All typedesc typedefs should be handled
        raise TypeError('This typedesc should be handled %s'%(t))

    ################################################################

    def Alias(self, alias):
        if self.generate_comments:
            self.print_comment(alias)
        print >> self.stream, "%s = %s # alias" % (alias.name, alias.alias)
        return            <commit_msg>cleanup type_name function<commit_after>'''Create ctypes wrapper code for abstract type descriptions.
Type descriptions are collections of typedesc instances.
'''

import typedesc, sys, os
import textwrap
import struct
import ctypes

import clangparser

import logging
log = logging.getLogger('codegen')

import code

import StringIO # need unicode support, no cStringIO



def get_real_type(tp):
    if type(tp) is typedesc.Typedef:
        if type(tp.typ) is typedesc.Typedef:
            import code
            code.interact(local=locals())
            raise TypeError('Nested loop in Typedef %s'%(tp.name))
        return get_real_type(tp.typ)
    elif isinstance(tp, typedesc.CvQualifiedType):
        return get_real_type(tp.typ)
    return tp

################################################################

class Generator(object):
    def __init__(self, output,
                 generate_comments=False,
                 known_symbols=None,
                 searched_dlls=None,
                 preloaded_dlls=[],
                 generate_docstrings=False,
                 generate_locations=False):
        self.output = output
        self.stream = StringIO.StringIO()
        self.imports = StringIO.StringIO()
        self.generate_locations = generate_locations
        self.generate_comments = generate_comments
        self.generate_docstrings = generate_docstrings
        self.known_symbols = known_symbols or {}
        self.preloaded_dlls = preloaded_dlls
        if searched_dlls is None:
            self.searched_dlls = []
        else:
            self.searched_dlls = searched_dlls

        self.done = set() # type descriptions that have been generated
        self.names = set() # names that have been generated

    def enable_pythonic_types(self):
        """
        If a type name starts with '__', some wrapper needs to be used for
        the generated code to be valid.
        """
        self.enable_pythonic_types = lambda : True
        import pkgutil
        headers = pkgutil.get_data('ctypeslib','data/pythonic_type_name.tpl')
        print >> self.imports, headers
    
    def type_name(self, t, generate=True):
        """
        Returns a string containing an expression that can be used to
        refer to the type. Assumes the 'from ctypes import *'
        namespace is available.
        """
        # no Test case for these
        #elif isinstance(t, typedesc.Argument):
        #elif isinstance(t, typedesc.CvQualifiedType):
        #elif isinstance(t, typedesc.Variable):
        #   return "%s" % self.type_name(t.typ, generate)
        #elif isinstance(t, typedesc.Enumeration):
        #   return t.name
        
        if isinstance(t, typedesc.FundamentalType):
            return self.FundamentalType(t) 
        elif isinstance(t, typedesc.ArrayType):
            return "%s * %s" % (self.type_name(t.typ, generate), t.size)
        elif isinstance(t, typedesc.PointerType):
            return "POINTER_T(%s)" %(self.type_name(t.typ, generate))
        elif isinstance(t, typedesc.FunctionType):
            args = [self.type_name(x, generate) for x in [t.returns] + list(t.iterArgTypes())]
            if "__stdcall__" in t.attributes:
                return "ctypes.WINFUNCTYPE(%s)" % ", ".join(args)
            else:
                return "ctypes.CFUNCTYPE(%s)" % ", ".join(args)
        #elif isinstance(t, typedesc.Structure):
        #elif isinstance(t, typedesc.Typedef):
        #elif isinstance(t, typedesc.Union):
        return t.name
        # All typedesc typedefs should be handled
        #raise TypeError('This typedesc should be handled %s'%(t))

    ################################################################

    def Alias(self, alias):
        if self.generate_comments:
            self.print_comment(alias)
        print >> self.stream, "%s = %s # alias" % (alias.name, alias.alias)
        return            
{'fraction_non_alphanumeric': 0.12397100380882173, 'fraction_numerical': 0.0, 'mean_word_length': 2.388842631140716, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2535986', 'n_tokens_mistral': 2284, 'n_tokens_neox': 2234, 'n_words': 588}