]> git.sesse.net Git - vlc/blobdiff - bindings/python-ctypes/generate.py
python-ctypes: capitalize enum names only if they do not already start with an upperc...
[vlc] / bindings / python-ctypes / generate.py
index c7f61a00e7dacddea0df69906d896d364b635283..87a5b37e3ed76db4bc5547d3656c8cf2585dde7f 100755 (executable)
@@ -59,13 +59,13 @@ blacklist=[
     "libvlc_exception_get_message",
     "libvlc_get_vlc_instance",
 
-    "libvlc_media_add_option_flag",
     "libvlc_media_list_view_index_of_item",
     "libvlc_media_list_view_insert_at_index",
     "libvlc_media_list_view_remove_at_index",
     "libvlc_media_list_view_add_item",
 
     # In svn but not in current 1.0.0
+    "libvlc_media_add_option_flag",
     'libvlc_video_set_deinterlace',
     'libvlc_video_get_marquee_option_as_int',
     'libvlc_video_get_marquee_option_as_string',
@@ -74,10 +74,6 @@ blacklist=[
     'libvlc_vlm_get_event_manager',
 
     'mediacontrol_PlaylistSeq__free',
-
-    # TODO
-    "libvlc_event_detach",
-    "libvlc_event_attach",
     ]
 
 # Precompiled regexps
@@ -88,6 +84,7 @@ comment_re=re.compile('\\param\s+(\S+)')
 python_param_re=re.compile('(@param\s+\S+)(.+)')
 forward_re=re.compile('.+\(\s*(.+?)\s*\)(\s*\S+)')
 enum_re=re.compile('typedef\s+(enum)\s*(\S+\s*)?\{\s*(.+)\s*\}\s*(\S+);')
+special_enum_re=re.compile('^(enum)\s*(\S+\s*)?\{\s*(.+)\s*\};')
 
 # Definition of parameter passing mode for types.  This should not be
 # hardcoded this way, but works alright ATM.
@@ -105,7 +102,7 @@ typ2class={
     'libvlc_log_t*': 'Log',
     'libvlc_log_iterator_t*': 'LogIterator',
     'libvlc_log_message_t*': 'LogMessage',
-    'libvlc_event_type_t': 'EventType',
+    'libvlc_event_type_t': 'ctypes.c_uint',
     'libvlc_event_manager_t*': 'EventManager',
     'libvlc_media_discoverer_t*': 'MediaDiscoverer',
     'libvlc_media_library_t*': 'MediaLibrary',
@@ -133,7 +130,7 @@ typ2class={
     'unsigned': 'ctypes.c_uint',
     'int': 'ctypes.c_int',
     '...': 'FIXMEva_list',
-    'libvlc_callback_t': 'FIXMEcallback',
+    'libvlc_callback_t': 'ctypes.c_void_p',
     'libvlc_time_t': 'ctypes.c_longlong',
     }
 
@@ -146,7 +143,6 @@ defined_classes=(
     'Log',
     'LogIterator',
     #'LogMessage',
-    'EventType',
     'EventManager',
     'MediaDiscoverer',
     'MediaLibrary',
@@ -156,9 +152,6 @@ defined_classes=(
     'TrackDescription',
     'AudioOutput',
     'MediaControl',
-    #'RGBPicture',
-    #'MediaControlPosition',
-    #'MediaControlStreamInformation',
     )
 
 # Definition of prefixes that we can strip from method names when
@@ -194,10 +187,10 @@ def parse_param(s):
         # K&R definition: only type
         return s.replace(' ', ''), ''
 
-def generate_header(classes=None):
-    """Generate header code.
+def insert_code(filename):
+    """Generate header/footer code.
     """
-    f=open('header.py', 'r')
+    f=open(filename, 'r')
     for l in f:
         if 'build_date' in l:
             print 'build_date="%s"' % time.ctime()
@@ -213,7 +206,7 @@ def convert_enum_names(enums):
         pyname=re.findall('(libvlc|mediacontrol)_(.+?)(_t)?$', name)[0][1]
         if '_' in pyname:
             pyname=pyname.title().replace('_', '')
-        else:
+        elif not pyname[0].isupper():
             pyname=pyname.capitalize()
         res[name]=pyname
     return res
@@ -233,7 +226,7 @@ def generate_enums(enums):
             n=k.split('_')[-1]
             if len(n) == 1:
                 # Single character. Some symbols use 1_1, 5_1, etc.
-                n="_".join( k.split('_')[:-2] )
+                n="_".join( k.split('_')[-2:] )
             if re.match('^[0-9]', n):
                 # Cannot start an identifier with a number
                 n='_'+n
@@ -273,17 +266,19 @@ def parse_typedef(name):
             continue
 
         l=l.strip()
+        if l.startswith('/*') or l.endswith('*/'):
+            continue
 
-        if accumulator:
+        if (l.startswith('typedef enum') or l.startswith('enum')) and not l.endswith(';'):
+            # Multiline definition. Accumulate until end of definition
+            accumulator=l
+            continue
+        elif accumulator:
             accumulator=" ".join( (accumulator, l) )
             if l.endswith(';'):
                 # End of definition
                 l=accumulator
                 accumulator=''
-        elif l.startswith('typedef enum') and not l.endswith(';'):
-            # Multiline definition. Accumulate until end of definition
-            accumulator=l
-            continue
 
         m=enum_re.match(l)
         if m:
@@ -300,8 +295,29 @@ def parse_typedef(name):
                     if l:
                         values.append( (l, str(i)) )
             comment=comment.replace('@{', '').replace('@see', 'See').replace('\ingroup', '')
-            yield (typ, name, values, comment)
+            yield (typ, name.strip(), values, comment)
             comment=''
+            continue
+
+        # Special case, used only for libvlc_events.h
+        m=special_enum_re.match(l)
+        if m:
+            values=[]
+            (typ, name, data)=m.groups()
+            for i, l in enumerate(paramlist_re.split(data)):
+                l=l.strip()
+                if l.startswith('/*') or l.startswith('#'):
+                    continue
+                if '=' in l:
+                    # A value was specified. Use it.
+                    values.append(re.split('\s*=\s*', l))
+                else:
+                    if l:
+                        values.append( (l, str(i)) )
+            comment=comment.replace('@{', '').replace('@see', 'See').replace('\ingroup', '')
+            yield (typ, name.strip(), values, comment)
+            comment=''
+            continue
 
 def parse_include(name):
     """Parse include file.
@@ -421,7 +437,7 @@ def parse_override(name):
     """Parse override definitions file.
 
     It is possible to override methods definitions in classes.
-    
+
     It returns a tuple
     (code, overriden_methods, docstring)
     """
@@ -579,11 +595,12 @@ if __name__ == '__main__':
     if debug:
         sys.exit(0)
 
-    generate_header()
+    insert_code('header.py')
     generate_enums(enums)
     wrapped=generate_wrappers(methods)
     for l in methods:
         output_ctypes(*l)
+    insert_code('footer.py')
 
     all=set( t[1] for t in methods )
     not_wrapped=all.difference(wrapped)