Ronald Oussoren avatar Ronald Oussoren committed 6dc74a3

More fooling around with scanframework.py

Comments (0)

Files changed (5)

sandbox/parsing/Changes.txt

+The new parsing code results in several changes, most of which should have no
+effect on user code. The list below tries to enumerate these changes, all 
+changes with effects on user code are definitely mentioned here.
+
+Changes that could affect user code:
+* NSObjC<Some>Type
+ 
+  This family of constants now have type 'str' (of length 1) instead of 
+  type 'int'. These functions are seldomly used.
+
+
+Changes that should not affect user code:
+* Most function wrappers are no longer instances of 
+  ``types.BuiltinFunctionType``.
+
+  This change makes pydoc even less effective on wrapped frameworks. Listed 
+  in this section because pydoc was already quite useless on wrapped frameworks.
+
+* ``from AppKit import *`` will also pull in all symbols from dependent
+  frameworks.
+
+  ``from Framework import *`` now behaves more like 
+  ``#import <Framework/Framework.h>`` in Objective-C. 

sandbox/parsing/Foundation_hints.py

     '_Foundation',
 )
 
+# Some headers that are not picked up by the default scanner
+ADDITIONAL_HEADERS=(
+    'NSDebug.h',
+)
+
+
 _ARGUMENT_KINDS={
     ('NSGetSizeAndAlignment', 1):   'objc._C_OUT',
     ('NSGetSizeAndAlignment', 2):   'objc._C_OUT',
 
     return True
 
+FOOTER="""\
+
+def NSMakePoint(x, y):
+    return NSPoint(x, y)
+
+def NSMakeSize(w, h):
+    return NSSize(w, h)
+
+def NSMakeRect(x, y, w, h):
+    return NSRect(NSPoint(x, y), NSSize(w, h))
+
+def NSMakeRange(loc, len):
+    return NSRange(loc, len)
+
+# These function use indexes instead of attribute
+# access because users might pass in tuples instead of
+# NSRect instances. Both are supported.
+
+def NSMaxX(aRect):
+    '''float NSMaxX(NSRect aRect)'''
+    return aRect[0][0] + aRect[1][0]
+
+def NSMaxY(aRect):
+    '''float NSMaxY(NSRect aRect)'''
+    return aRect[0][1] + aRect[1][1]
+
+def NSMidX(aRect):
+    '''float NSMidX(NSRect aRect)'''
+    return aRect[0][0] + aRect[1][0] / 2.0
+
+def NSMidY(aRect):
+    '''float NSMidY(NSRect aRect)'''
+    return aRect[0][1] + aRect[1][1] / 2.0 
+
+def NSMinX(aRect):
+    '''float NSMinX(NSRect aRect)'''
+    return aRect[0][0]
+
+def NSMinY(aRect):
+    '''float NSMinY(NSRect aRect)'''
+    return aRect[0][1]
+
+def NSWidth(aRect):
+    '''float NSWidth(NSRect aRect);'''
+    return aRect[1][0]
+
+def NSHeight(aRect):
+    '''float NSHeight(NSRect aRect); '''
+    return aRect[0][1]
+
+def NSMaxRange(range):
+    '''unsigned int NSMaxRange(NSRange range);'''
+    return range[0] + range[1]
+
+def NSLocationInRange(loc, range):
+    '''BOOL NSLocationInRange(unsigned int loc, NSRange range)'''
+    return loc - range[0] < range[1]
+
+def NSEqualRanges(range1, range2):
+    '''BOOL NSEqualRanges(NSRange range1, NSRange range2)'''
+    return range1[0] == range2[0] and range1[1] == range2[1]
+
+# NSByteOrder.h
+NSHostByteOrder = CFByteOrderGetCurrent
+NSSwapShort = CFSwapInt16
+NSSwapInt = CFSwapInt32
+NSSwapLong = CFSwapInt32
+NSSwapLongLong = CFSwapInt64
+NSSwapBigShortToHost = CFSwapInt16BigToHost
+NSSwapBigLongLongToHost = CFSwapInt64BigToHost
+NSSwapHostShortToBig = CFSwapInt16HostToBig
+NSSwapHostIntToBig = CFSwapInt32HostToBig
+NSSwapHostLongToBig = CFSwapInt32HostToBig
+NSSwapHostLongLongToBig = CFSwapInt64HostToBig
+NSSwapLittleShortToHost = CFSwapInt16LittleToHost
+NSSwapLittleIntToHost = CFSwapInt32LittleToHost
+NSSwapLittleLongToHost = CFSwapInt32LittleToHost
+NSSwapLittleLongLongToHost = CFSwapInt64LittleToHost
+NSSwapHostShortToLittle = CFSwapInt16HostToLittle
+NSSwapHostIntToLittle = CFSwapInt32HostToLittle
+NSSwapHostLongToLittle = CFSwapInt32HostToLittle
+NSSwapHostLongLongToLittle = CFSwapInt64HostToLittle
+
+"""
+
 
 # Items that should not be wrapped. The key is the C object that shouldn't
 # be wrapped, the value should describe why it isn't wrapped.
     'NSNonOwnedPointerMapValueCallBacks':   'NSMaptables are like dicts',
     'NSNonRetainedObjectMapValueCallBacks': 'NSMaptables are like dicts',
     'NSOwnedPointerMapValueCallBacks':      'NSMaptables are like dicts',
+
+
+    'NSMakePoint':      'static inine, wrapped by hand',
+    'NSMakeSize':       'static inline, wrapped by hand',
+    'NSMakeRect':       'static inline, wrapped by hand',
+    'NSMakeRange':      'static inline, wrapped by hand',
+    'NSMaxX':           'static inline, wrapped by hand',
+    'NSMaxY':           'static inline, wrapped by hand',
+    'NSMidX':           'static inline, wrapped by hand',
+    'NSMidY':           'static inline, wrapped by hand',
+    'NSMinX':           'static inline, wrapped by hand',
+    'NSMinY':           'static inline, wrapped by hand',
+    'NSWidth':          'static inline, wrapped by hand',
+    'NSHeight':         'static inline, wrapped by hand',
+    'NSMaxRange':       'static inline, wrapped by hand',
+    'NSLocationInRange':'static inline, wrapped by hand',
+    'NSEqualRanges':    'static inline, wrapped by hand',
+
+    'NSHostByteOrder':              'static inline function alias',
+    'NSSwapShort':                  'static inline function alias',
+    'NSSwapInt':                    'static inline function alias',
+    'NSSwapLong':                   'static inline function alias',
+    'NSSwapLongLong':               'static inline function alias',
+    'NSSwapBigShortToHost':         'static inline function alias',
+    'NSSwapBigLongLongToHost':      'static inline function alias',
+    'NSSwapHostShortToBig':         'static inline function alias',
+    'NSSwapHostIntToBig':           'static inline function alias',
+    'NSSwapHostLongToBig':          'static inline function alias',
+    'NSSwapHostLongLongToBig':      'static inline function alias',
+    'NSSwapLittleShortToHost':      'static inline function alias',
+    'NSSwapLittleIntToHost':        'static inline function alias',
+    'NSSwapLittleLongToHost':       'static inline function alias',
+    'NSSwapLittleLongLongToHost':   'static inline function alias',
+    'NSSwapHostShortToLittle':      'static inline function alias',
+    'NSSwapHostIntToLittle':        'static inline function alias',
+    'NSSwapHostLongToLittle':       'static inline function alias',
+    'NSSwapHostLongLongToLittle':   'static inline function alias',
 }

sandbox/parsing/diffWrappers.py

             print "OLD isn't callable, NEW is for %s (%r, %r)" % (
                     k, v_old, v_new)
 
+    elif isinstance(v_old, (tuple, list)):
+        if v_old != v_new:
+            print "OLD != NEW for %s (%r != %r)"%(k, v_old, v_new)
+
+    elif v_old is None:
+        if v_new is not None:
+            print "OLD != NEW for %s (%r != %r)"%(k, v_old, v_new)
+
     else:
-        print k, type(v_old), type(v_new)
+        print "FIXME!", k, type(v_old), type(v_new)
 
 for k, v in new.__dict__.iteritems():
+    if k.startswith('_') and k.endswith('_encoded'):
+        # Most likely '_SOMESTRUCT_encoded', these are introduced by 
+        # the wrapper generator and are not interesting at all.
+        continue
+
     if not hasattr(old, k):
         print "Not in OLD: %s (%r)" % (k, v)

sandbox/parsing/scanframework.py

 # - test, test and even more testing
 # - refactor script: make it possible to create wrappers for multiple 
 #   frameworks in one go, without rescanning headers over and over again.
+#   [maybe: add cache file to wrapped frameworks, that would make it easier
+#    to scan an add-on framework]
 # - integrate into build process
 # - Scanframework of CoreFoundation seems to indicate that the tokenizer 
 #   isn't good enough yet (or that I broke it).
 
         return fun(name, fieldnames, fieldtypes)
 
+    def getFooter(self):
+        """ Return some text for at the end of __init__.py """
+        return self._globals.get('FOOTER', '')
 
+    def additionalHeaders(self):
+        return self._globals.get('ADDITIONAL_HEADERS', None)
 
 
 def update_fallback(env, framework):
     
 
 class FrameworkScanner(object):
-    def __init__(self):
+    def __init__(self, additional=None):
         self._scanner = None
+        if additional is not None:
+            self._additionalHeaders = additional
+        else:
+            self._additionalHeaders = []
 
     def scanframework(self, name, sub=None):
         if sub is None:
         if os.path.exists(startfile):
             seen.add(start)
             scanners.append(self.scanfile(startfile))
+            for item in self._additionalHeaders:
+                headers = glob.glob(locate_header('%s/%s.h' % (name, item)))
+                for header in headers:
+                    seen.add(name + '/' + os.path.basename(header))
+                    scanners.append(self.scanfile(header))
+
         else:
             headers = glob.glob(locate_header('%s/*.h' % (name,)))
             for header in headers:
 def makeInit(framework, out, hinter = None, types=None):
     framework_name = filter(None, os.path.split(framework))[0]
     framework_path = unicode(os.path.dirname(framework_find(framework_name)), sys.getfilesystemencoding())
-    f = FrameworkScanner()
+
+    if hinter is not None:
+        x = hinter.additionalHeaders()
+    else:
+        x = None
+    f = FrameworkScanner(x)
     if types is None:
         types = typedict()
 
             do_function(token, types, functions, hinter)
 
         elif isinstance(token, StaticInlineFunction):
-            # TODO: emit wrapper inside a C file.
-            pass
+            if hinter and hinter.should_ignore(token['name']):
+                continue
+
+            # TODO: emit wrapper inside a C file (or just wrap by hand...)
+            print "[SKIP STATIC INLINE]", token['name']
 
         else:
             if type(token) not in ignores:
     ])
 """ % locals()
     print >>out, """
-_initialize()
+_initialize(); del _initialize
 del objc
 """
 
+    text = hinter.getFooter()
+    if text:
+        print >>out, text
+
 def makeWrapper(fmwk, hinter, types):
     try:
         os.makedirs(fmwk)

sandbox/parsing/tokenize_header.py

     FOUNDATION_EXPORT NSString * const Foo;
     extern CFStringRef cfFoo AVAILABLE_MAC_OSX_10_8;
     APPKIT_EXTERN const char foosball[] AVAILABLE_NEVER;
+    FOUNDATION_EXPORT BOOL NSKeepAllocationStatistics;
     ''')
 
 class ForwardClassReference(Token):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.