Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-gpu
Commits
109ee984
Commit
109ee984
authored
Aug 10, 2009
by
Olivier Aubert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
python-ctypes: refactor generate.py to be more modular
parent
33043ba3
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
569 additions
and
509 deletions
+569
-509
bindings/python-ctypes/TODO
bindings/python-ctypes/TODO
+0
-11
bindings/python-ctypes/generate.py
bindings/python-ctypes/generate.py
+569
-498
No files found.
bindings/python-ctypes/TODO
View file @
109ee984
...
...
@@ -4,14 +4,3 @@
* Support multiple VLC versions: define a front-end module which will
load the appropriate versionned module from a subdirectory.
* Support options: --debug/-c, --output/-o, --check-symbols/-s, ...
* Use setup.py
* Refactor code:
class Parser(list_of_includes) -> properties enums, methods...,
dump()
check()...
class PythonGenerator(parser) -> p.save( filename )
bindings/python-ctypes/generate.py
View file @
109ee984
...
...
@@ -33,6 +33,7 @@ import re
import
time
import
operator
import
itertools
from
optparse
import
OptionParser
# DefaultDict from ASPN python cookbook
import
copy
...
...
@@ -91,75 +92,16 @@ special_enum_re=re.compile('^(enum)\s*(\S+\s*)?\{\s*(.+)\s*\};')
parameter_passing=DefaultDict(default=1)
parameter_passing['
libvlc_exception_t
*
']=3
# C-type to ctypes/python type conversion.
# Note that enum types conversions are generated (cf convert_enum_names)
typ2class={
'
libvlc_exception_t
*
': '
ctypes
.
POINTER
(
VLCException
)
',
class Parser(object):
def __init__(self, list_of_files):
self.methods=[]
self.enums=[]
'
libvlc_media_player_t
*
': '
MediaPlayer
',
'
libvlc_instance_t
*
': '
Instance
',
'
libvlc_media_t
*
': '
Media
',
'
libvlc_log_t
*
': '
Log
',
'
libvlc_log_iterator_t
*
': '
LogIterator
',
'
libvlc_log_message_t
*
': '
LogMessage
',
'
libvlc_event_type_t
': '
ctypes
.
c_uint
',
'
libvlc_event_manager_t
*
': '
EventManager
',
'
libvlc_media_discoverer_t
*
': '
MediaDiscoverer
',
'
libvlc_media_library_t
*
': '
MediaLibrary
',
'
libvlc_media_list_t
*
': '
MediaList
',
'
libvlc_media_list_player_t
*
': '
MediaListPlayer
',
'
libvlc_media_list_view_t
*
': '
MediaListView
',
'
libvlc_track_description_t
*
': '
TrackDescription
',
'
libvlc_audio_output_t
*
': '
AudioOutput
',
'
mediacontrol_Instance
*
': '
MediaControl
',
'
mediacontrol_Exception
*
': '
MediaControlException
',
'
mediacontrol_RGBPicture
*
': '
ctypes
.
POINTER
(
RGBPicture
)
',
'
mediacontrol_PlaylistSeq
*
': '
MediaControlPlaylistSeq
',
'
mediacontrol_Position
*
': '
ctypes
.
POINTER
(
MediaControlPosition
)
',
'
mediacontrol_StreamInformation
*
': '
ctypes
.
POINTER
(
MediaControlStreamInformation
)
',
'
WINDOWHANDLE
': '
ctypes
.
c_ulong
',
for name in list_of_files:
self.enums.extend(self.parse_typedef(name))
self.methods.extend(self.parse_include(name))
'
void
': '
None
',
'
void
*
': '
ctypes
.
c_void_p
',
'
short
': '
ctypes
.
c_short
',
'
char
*
': '
ctypes
.
c_char_p
',
'
char
**
': '
ListPOINTER
(
ctypes
.
c_char_p
)
',
'
uint32_t
': '
ctypes
.
c_uint
',
'
float
': '
ctypes
.
c_float
',
'
unsigned
': '
ctypes
.
c_uint
',
'
int
': '
ctypes
.
c_int
',
'
...
': '
FIXMEva_list
',
'
libvlc_callback_t
': '
ctypes
.
c_void_p
',
'
libvlc_time_t
': '
ctypes
.
c_longlong
',
}
# Defined python classes, i.e. classes for which we want to generate
# class wrappers around libvlc functions
defined_classes=(
'
MediaPlayer
',
'
Instance
',
'
Media
',
'
Log
',
'
LogIterator
',
#'
LogMessage
',
'
EventManager
',
'
MediaDiscoverer
',
'
MediaLibrary
',
'
MediaList
',
'
MediaListPlayer
',
'
MediaListView
',
'
TrackDescription
',
'
AudioOutput
',
'
MediaControl
',
)
# Definition of prefixes that we can strip from method names when
# wrapping them into class methods
prefixes=dict( (v, k[:-2]) for (k, v) in typ2class.iteritems() if v in defined_classes )
prefixes['
MediaControl
']='
mediacontrol_
'
def parse_param(s):
def parse_param(self, s):
"""Parse a C parameter expression.
It is used to parse both the type/name for methods, and type/name
...
...
@@ -187,65 +129,7 @@ def parse_param(s):
# K&R definition: only type
return s.replace('
', ''), ''
def insert_code(filename):
"""Generate header/footer code.
"""
f=open(filename, 'r')
for l in f:
if '
build_date
' in l:
print '
build_date
=
"%s"' % time.ctime()
else:
print l,
f.close()
def convert_enum_names(enums):
res={}
for (typ, name, values, comment) in enums:
if typ != '
enum
':
raise Exception('
This
method
only
handles
enums
')
pyname=re.findall('
(
libvlc
|
mediacontrol
)
_
(.
+
?
)(
_t
)
?$
', name)[0][1]
if '
_
' in pyname:
pyname=pyname.title().replace('
_
', '')
elif not pyname[0].isupper():
pyname=pyname.capitalize()
res[name]=pyname
return res
def generate_enums(enums):
for (typ, name, values, comment) in enums:
if typ != '
enum
':
raise Exception('
This
method
only
handles
enums
')
pyname=typ2class[name]
print "class %s(ctypes.c_uint):" % pyname
print '
"""%s
\
n
"""' % comment
conv={}
# Convert symbol names
for k, v in values:
n=k.split('
_
')[-1]
if len(n) == 1:
# Single character. Some symbols use 1_1, 5_1, etc.
n="_".join( k.split('
_
')[-2:] )
if re.match('
^
[
0
-
9
]
', n):
# Cannot start an identifier with a number
n='
_
'+n
conv[k]=n
for k, v in values:
print " %s=%s" % (conv[k], v)
print " _names={"
for k, v in values:
print " %s: '
%
s
'," % (v, conv[k])
print " }"
print """
def __repr__(self):
return ".".join((self.__class__.__module__, self.__class__.__name__, self._names[self.value]))
"""
def parse_typedef(name):
def parse_typedef(self, name):
"""Parse include file for typedef expressions.
This generates a tuple for each typedef:
...
...
@@ -319,7 +203,7 @@ def parse_typedef(name):
comment
=
''
continue
def
parse_include
(
name
):
def
parse_include
(
self
,
name
):
"""Parse include file.
This generates a tuple for each function:
...
...
@@ -356,11 +240,11 @@ def parse_include(name):
if
m
:
(
ret
,
param
)
=
m
.
groups
()
rtype
,
method
=
parse_param
(
ret
)
rtype
,
method
=
self
.
parse_param
(
ret
)
params
=
[]
for
p
in
paramlist_re
.
split
(
param
):
params
.
append
(
parse_param
(
p
)
)
params
.
append
(
self
.
parse_param
(
p
)
)
if
len
(
params
)
==
1
and
params
[
0
][
0
]
==
'void'
:
# Empty parameter list
...
...
@@ -384,10 +268,6 @@ def parse_include(name):
# but it prevented code generation for a minor detail (some bad descriptions).
params
=
[
(
p
[
0
],
names
[
i
])
for
(
i
,
p
)
in
enumerate
(
params
)
]
for
typ
,
name
in
params
:
if
not
typ
in
typ2class
:
raise
Exception
(
"No conversion for %s (from %s:%s)"
%
(
typ
,
method
,
name
))
# Transform Doxygen syntax into epydoc syntax
comment
=
comment
.
replace
(
'
\
\
param'
,
'@param'
).
replace
(
'
\
\
return'
,
'@return'
)
...
...
@@ -405,7 +285,193 @@ def parse_include(name):
comment
)
comment
=
''
def
output_ctypes
(
rtype
,
method
,
params
,
comment
):
def
dump_methods
(
self
):
print
"** Defined functions **"
for
(
rtype
,
name
,
params
,
comment
)
in
self
.
methods
:
print
"%(name)s (%(rtype)s):"
%
locals
()
for
t
,
n
in
params
:
print
" %(n)s (%(t)s)"
%
locals
()
def
dump_enums
(
self
):
print
"** Defined enums **"
for
(
typ
,
name
,
values
,
comment
)
in
self
.
enums
:
print
"%(name)s (%(typ)s):"
%
locals
()
for
k
,
v
in
values
:
print
" %(k)s=%(v)s"
%
locals
()
class
PythonGenerator
(
object
):
# C-type to ctypes/python type conversion.
# Note that enum types conversions are generated (cf convert_enum_names)
type2class
=
{
'libvlc_exception_t*'
:
'ctypes.POINTER(VLCException)'
,
'libvlc_media_player_t*'
:
'MediaPlayer'
,
'libvlc_instance_t*'
:
'Instance'
,
'libvlc_media_t*'
:
'Media'
,
'libvlc_log_t*'
:
'Log'
,
'libvlc_log_iterator_t*'
:
'LogIterator'
,
'libvlc_log_message_t*'
:
'LogMessage'
,
'libvlc_event_type_t'
:
'ctypes.c_uint'
,
'libvlc_event_manager_t*'
:
'EventManager'
,
'libvlc_media_discoverer_t*'
:
'MediaDiscoverer'
,
'libvlc_media_library_t*'
:
'MediaLibrary'
,
'libvlc_media_list_t*'
:
'MediaList'
,
'libvlc_media_list_player_t*'
:
'MediaListPlayer'
,
'libvlc_media_list_view_t*'
:
'MediaListView'
,
'libvlc_track_description_t*'
:
'TrackDescription'
,
'libvlc_audio_output_t*'
:
'AudioOutput'
,
'mediacontrol_Instance*'
:
'MediaControl'
,
'mediacontrol_Exception*'
:
'MediaControlException'
,
'mediacontrol_RGBPicture*'
:
'ctypes.POINTER(RGBPicture)'
,
'mediacontrol_PlaylistSeq*'
:
'MediaControlPlaylistSeq'
,
'mediacontrol_Position*'
:
'ctypes.POINTER(MediaControlPosition)'
,
'mediacontrol_StreamInformation*'
:
'ctypes.POINTER(MediaControlStreamInformation)'
,
'WINDOWHANDLE'
:
'ctypes.c_ulong'
,
'void'
:
'None'
,
'void*'
:
'ctypes.c_void_p'
,
'short'
:
'ctypes.c_short'
,
'char*'
:
'ctypes.c_char_p'
,
'char**'
:
'ListPOINTER(ctypes.c_char_p)'
,
'uint32_t'
:
'ctypes.c_uint'
,
'float'
:
'ctypes.c_float'
,
'unsigned'
:
'ctypes.c_uint'
,
'int'
:
'ctypes.c_int'
,
'...'
:
'FIXMEva_list'
,
'libvlc_callback_t'
:
'ctypes.c_void_p'
,
'libvlc_time_t'
:
'ctypes.c_longlong'
,
}
# Defined python classes, i.e. classes for which we want to generate
# class wrappers around libvlc functions
defined_classes
=
(
'MediaPlayer'
,
'Instance'
,
'Media'
,
'Log'
,
'LogIterator'
,
'EventManager'
,
'MediaDiscoverer'
,
'MediaLibrary'
,
'MediaList'
,
'MediaListPlayer'
,
'MediaListView'
,
'TrackDescription'
,
'AudioOutput'
,
'MediaControl'
,
)
def
__init__
(
self
,
parser
=
None
):
self
.
parser
=
parser
# Generate python names for enums
self
.
type2class
.
update
(
self
.
convert_enum_names
(
parser
.
enums
))
self
.
check_types
()
# Definition of prefixes that we can strip from method names when
# wrapping them into class methods
self
.
prefixes
=
dict
(
(
v
,
k
[:
-
2
])
for
(
k
,
v
)
in
self
.
type2class
.
iteritems
()
if
v
in
self
.
defined_classes
)
self
.
prefixes
[
'MediaControl'
]
=
'mediacontrol_'
def
save
(
self
,
filename
=
None
):
if
filename
is
None
or
filename
==
'-'
:
self
.
fd
=
sys
.
stdout
else
:
self
.
fd
=
open
(
filename
,
'w'
)
self
.
insert_code
(
'header.py'
)
self
.
generate_enums
(
self
.
parser
.
enums
)
wrapped_methods
=
self
.
generate_wrappers
(
self
.
parser
.
methods
)
for
l
in
self
.
parser
.
methods
:
self
.
output_ctypes
(
*
l
)
self
.
insert_code
(
'footer.py'
)
all_methods
=
set
(
t
[
1
]
for
t
in
self
.
parser
.
methods
)
not_wrapped
=
all_methods
.
difference
(
wrapped_methods
)
self
.
output
(
"# Not wrapped methods:"
)
for
m
in
not_wrapped
:
self
.
output
(
"# "
,
m
)
if
self
.
fd
!=
sys
.
stdout
:
self
.
fd
.
close
()
def
output
(
self
,
*
p
):
self
.
fd
.
write
(
" "
.
join
(
p
))
self
.
fd
.
write
(
"
\
n
"
)
def
check_types
(
self
):
"""Make sure that all types are properly translated.
This method must be called *after* convert_enum_names, since
the latter populates type2class with converted enum names.
"""
for
(
rt
,
met
,
params
,
c
)
in
self
.
parser
.
methods
:
for
typ
,
name
in
params
:
if
not
typ
in
self
.
type2class
:
raise
Exception
(
"No conversion for %s (from %s:%s)"
%
(
typ
,
met
,
name
))
def
insert_code
(
self
,
filename
):
"""Generate header/footer code.
"""
f
=
open
(
filename
,
'r'
)
for
l
in
f
:
if
'build_date'
in
l
:
self
.
output
(
'build_date="%s"'
%
time
.
ctime
())
else
:
self
.
output
(
l
.
rstrip
())
f
.
close
()
def
convert_enum_names
(
self
,
enums
):
res
=
{}
for
(
typ
,
name
,
values
,
comment
)
in
enums
:
if
typ
!=
'enum'
:
raise
Exception
(
'This method only handles enums'
)
pyname
=
re
.
findall
(
'(libvlc|mediacontrol)_(.+?)(_t)?$'
,
name
)[
0
][
1
]
if
'_'
in
pyname
:
pyname
=
pyname
.
title
().
replace
(
'_'
,
''
)
elif
not
pyname
[
0
].
isupper
():
pyname
=
pyname
.
capitalize
()
res
[
name
]
=
pyname
return
res
def
generate_enums
(
self
,
enums
):
for
(
typ
,
name
,
values
,
comment
)
in
enums
:
if
typ
!=
'enum'
:
raise
Exception
(
'This method only handles enums'
)
pyname
=
self
.
type2class
[
name
]
self
.
output
(
"class %s(ctypes.c_uint):"
%
pyname
)
self
.
output
(
' """%s
\
n
"""'
%
comment
)
conv
=
{}
# Convert symbol names
for
k
,
v
in
values
:
n
=
k
.
split
(
'_'
)[
-
1
]
if
len
(
n
)
==
1
:
# Single character. Some symbols use 1_1, 5_1, etc.
n
=
"_"
.
join
(
k
.
split
(
'_'
)[
-
2
:]
)
if
re
.
match
(
'^[0-9]'
,
n
):
# Cannot start an identifier with a number
n
=
'_'
+
n
conv
[
k
]
=
n
for
k
,
v
in
values
:
self
.
output
(
" %s=%s"
%
(
conv
[
k
],
v
))
self
.
output
(
" _names={"
)
for
k
,
v
in
values
:
self
.
output
(
" %s: '%s',"
%
(
v
,
conv
[
k
]))
self
.
output
(
" }"
)
self
.
output
(
"""
def __repr__(self):
return ".".join((self.__class__.__module__, self.__class__.__name__, self._names[self.value]))
"""
)
def
output_ctypes
(
self
,
rtype
,
method
,
params
,
comment
):
"""Output ctypes decorator for the given method.
"""
if
method
in
blacklist
:
...
...
@@ -413,10 +479,10 @@ def output_ctypes(rtype, method, params, comment):
return
if
params
:
print
"prototype=ctypes.CFUNCTYPE(%s, %s)"
%
(
typ
2class
.
get
(
rtype
,
'FIXME_%s'
%
rtype
),
","
.
join
(
typ2class
[
p
[
0
]]
for
p
in
params
))
self
.
output
(
"prototype=ctypes.CFUNCTYPE(%s, %s)"
%
(
self
.
type
2class
.
get
(
rtype
,
'FIXME_%s'
%
rtype
),
","
.
join
(
self
.
type2class
[
p
[
0
]]
for
p
in
params
)
))
else
:
print
"prototype=ctypes.CFUNCTYPE(%s)"
%
typ2class
.
get
(
rtype
,
'FIXME_%s'
%
rtype
)
self
.
output
(
"prototype=ctypes.CFUNCTYPE(%s)"
%
self
.
type2class
.
get
(
rtype
,
'FIXME_%s'
%
rtype
)
)
if
not
params
:
...
...
@@ -425,15 +491,15 @@ def output_ctypes(rtype, method, params, comment):
flags
=
"paramflags=( (%d, ), )"
%
parameter_passing
[
params
[
0
][
0
]]
else
:
flags
=
"paramflags=%s"
%
","
.
join
(
'(%d,)'
%
parameter_passing
[
p
[
0
]]
for
p
in
params
)
print
flags
print
'%s = prototype( ("%s", dll), paramflags )'
%
(
method
,
method
)
self
.
output
(
flags
)
self
.
output
(
'%s = prototype( ("%s", dll), paramflags )'
%
(
method
,
method
)
)
if
'3'
in
flags
:
# A VLCException is present. Process it.
print
"%s.errcheck = check_vlc_exception"
%
method
print
'%s.__doc__ = """%s"""'
%
(
method
,
comment
)
print
self
.
output
(
"%s.errcheck = check_vlc_exception"
%
method
)
self
.
output
(
'%s.__doc__ = """%s"""'
%
(
method
,
comment
)
)
self
.
output
()
def
parse_override
(
name
):
def
parse_override
(
self
,
name
):
"""Parse override definitions file.
It is possible to override methods definitions in classes.
...
...
@@ -470,7 +536,7 @@ def parse_override(name):
return code, overridden_methods, docstring
def fix_python_comment(
c):
def fix_python_comment(self,
c):
"""Fix comment by removing first and last parameters (self and exception)
"""
data=c.replace('
@
{
', '').replace('
@
see
', '
See
').splitlines()
...
...
@@ -485,32 +551,32 @@ def fix_python_comment(c):
return "
\
n
".join(itertools.chain(body, param, ret))
def generate_wrappers(
methods):
def generate_wrappers(self,
methods):
"""Generate class wrappers for all appropriate methods.
@return: the set of wrapped method names
"""
ret=set()
# Sort methods against the element they apply to.
elements=sorted( ( (typ
2class.get(params[0][0]), rt, met, params, c)
elements=sorted( ( (self.type
2class.get(params[0][0]), rt, met, params, c)
for (rt, met, params, c) in methods
if params and typ2class.get(params[0][0], '
_
') in
defined_classes
if params and self.type2class.get(params[0][0], '
_
') in self.
defined_classes
),
key=operator.itemgetter(0))
overrides, overriden_methods, docstring=
parse_override('
override
.
py
')
overrides, overriden_methods, docstring=self.
parse_override('
override
.
py
')
for classname, el in itertools.groupby(elements, key=operator.itemgetter(0)):
print """class %(name)s(object):""" % {'
name
': classname}
self.output("""class %(name)s(object):""" % {'
name
': classname})
if classname in docstring:
print '
"""%s
\
n
"""' % docstring[classname]
self.output('
"""%s
\
n
"""' % docstring[classname])
print
"""
self.output(
"""
def __new__(cls, pointer=None):
'''Internal method used for instanciating wrappers from ctypes.
'''
if pointer is None:
raise Exception("Internal method. You should instanciate objects through other class methods (probably named '
new
' or ending with '
new
')
")
raise Exception("Internal method. Surely this class cannot be instanciated by itself.
")
if pointer == 0:
return None
else:
...
...
@@ -523,12 +589,12 @@ def generate_wrappers(methods):
'''(INTERNAL) ctypes parameter conversion method.
'''
return arg._as_parameter_
""" % {'
name
': classname}
""" % {'
name
': classname})
if classname in overrides:
print overrides[classname]
self.output(overrides[classname])
prefix=
prefixes.get(classname, '')
prefix=self.
prefixes.get(classname, '')
for cl, rtype, method, params, comment in el:
if method in blacklist:
...
...
@@ -547,64 +613,69 @@ def generate_wrappers(methods):
else:
args=", ".join( p[1] for p in params )
print " def %s(%s):" % (name, args
)
print '
"""%s
\
n
"""' % fix_python_comment(comment
)
self.output(" def %s(%s):" % (name, args)
)
self.output('
"""%s
\
n
"""' % self.fix_python_comment(comment)
)
if params and params[-1][0] == '
libvlc_exception_t
*
':
# Exception handling
print " e=VLCException()"
print " return %s(%s, e)" % (method, args
)
self.output(" e=VLCException()")
self.output(" return %s(%s, e)" % (method, args)
)
elif params and params[-1][0] == '
mediacontrol_Exception
*
':
# Exception handling
print " e=MediaControlException()"
print " return %s(%s, e)" % (method, args
)
self.output(" e=MediaControlException()")
self.output(" return %s(%s, e)" % (method, args)
)
else:
print " return %s(%s)" % (method, args
)
print
self.output(" return %s(%s)" % (method, args)
)
self.output()
# Check for standard methods
if name == '
count
':
# There is a count method. Generate a __len__ one.
print " def __len__(self):"
print " e=VLCException()"
print " return %s(self, e)" % method
print
self.output(""" def __len__(self):
e=VLCException()
return %s(self, e)
""" % method)
elif name.endswith('
item_at_index
'):
# Indexable (and thus iterable)"
print " def __getitem__(self, i):"
print " e=VLCException()"
print " return %s(self, i, e)" % method
print
print " def __iter__(self):"
print " e=VLCException()"
print " for i in xrange(len(self)):"
print " yield self[i]"
print
self.output(""" def __getitem__(self, i):
e=VLCException()
return %s(self, i, e)
def __iter__(self):
e=VLCException()
for i in xrange(len(self)):
yield self[i]
""" % method)
return ret
def process(output, list_of_includes):
p=Parser(list_of_includes)
g=PythonGenerator(p)
g.save(output)
if __name__ == '
__main__
':
enums=[]
for name in sys.argv[1:]:
enums.extend(list(parse_typedef(name)))
# Generate python names for enums
typ2class.update(convert_enum_names(enums))
opt=OptionParser(usage="""Parse VLC include files and generate bindings code.
%prog [options] include_file.h [...]""")
methods=[]
for name in sys.argv[1:]:
methods.extend(list(parse_include(name)))
if debug:
sys.exit(0)
opt.add_option("-d", "--debug", dest="debug", action="store_true",
default=False,
help="Debug mode")
insert_code('
header
.
py
')
generate_enums(enums)
wrapped=generate_wrappers(methods)
for l in methods:
output_ctypes(*l)
insert_code('
footer
.
py
')
opt.add_option("-o", "--output", dest="output", action="store",
type="str", default="-",
help="Output filename")
all=set( t[1] for t in methods )
not_wrapped=all.difference(wrapped)
print "# Not wrapped methods:"
for m in not_wrapped:
print "# ", m
(options, args) = opt.parse_args()
if not args:
opt.print_help()
sys.exit(1)
p=Parser(args)
if options.debug:
p.dump_methods()
p.dump_enums()
sys.exit(0)
g=PythonGenerator(p)
g.save(options.output)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment