Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
Commits
d7b1ce91
Commit
d7b1ce91
authored
Jul 31, 2009
by
Olivier Aubert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
python-ctypes: generate classes for enum typedefs
parent
fc43e13f
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
107 additions
and
31 deletions
+107
-31
bindings/python-ctypes/TODO
bindings/python-ctypes/TODO
+0
-4
bindings/python-ctypes/generate.py
bindings/python-ctypes/generate.py
+107
-11
bindings/python-ctypes/header.py
bindings/python-ctypes/header.py
+0
-16
No files found.
bindings/python-ctypes/TODO
View file @
d7b1ce91
* Investigate memory management
* Find how to properly define enums
* Autogenerate enums from include files
* Implement event callbacks
* Write a test suite
...
...
bindings/python-ctypes/generate.py
View file @
d7b1ce91
...
...
@@ -87,13 +87,15 @@ paramlist_re=re.compile('\s*,\s*')
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
+
);
')
# Definition of parameter passing mode for types. This should not be
# hardcoded this way, but works alright ATM.
parameter_passing=DefaultDict(default=1)
parameter_passing['
libvlc_exception_t
*
']=3
# C-type to ctypes/python type conversion
# 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
)
',
...
...
@@ -119,28 +121,20 @@ typ2class={
'
mediacontrol_PlaylistSeq
*
': '
MediaControlPlaylistSeq
',
'
mediacontrol_Position
*
': '
MediaControlPosition
',
'
mediacontrol_StreamInformation
*
': '
MediaControlStreamInformation
',
'
mediacontrol_PositionOrigin
': '
ctypes
.
c_uint
',
'
mediacontrol_PositionKey
': '
ctypes
.
c_uint
',
'
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
',
'
void
': '
None
',
'
void
*
': '
ctypes
.
c_void_p
',
'
int
': '
ctypes
.
c_int
',
'
...
': '
FIXMEva_list
',
'
libvlc_callback_t
': '
FIXMEcallback
',
'
libvlc_time_t
': '
ctypes
.
c_longlong
',
'
libvlc_video_marquee_int_option_t
': '
ctypes
.
c_int
',
'
libvlc_video_marquee_string_option_t
': '
ctypes
.
c_char_p
',
# FIXME: enums -> to be processed
'
libvlc_media_option_t
': '
ctypes
.
c_uint
',
'
libvlc_meta_t
': '
ctypes
.
c_uint
',
'
libvlc_state_t
': '
State
',
}
# Defined python classes, i.e. classes for which we want to generate
...
...
@@ -211,6 +205,101 @@ def generate_header(classes=None):
print l,
f.close()
def convert_enum_names(enums):
res={}
for (typ, name, values) 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('
_
', '')
else:
pyname=pyname.capitalize()
res[name]=pyname
return res
def generate_enums(enums):
for (typ, name, values) in enums:
if typ != '
enum
':
raise Exception('
This
method
only
handles
enums
')
pyname=typ2class[name]
print "class %s(ctypes.c_uint):" % pyname
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):
"""Parse include file for typedef expressions.
This generates a tuple for each typedef:
(type, name, value_list)
with type == '
enum
' (for the moment) and value_list being a list of (name, value)
Note that values are string, since this is intended for code generation.
"""
f=open(name, 'r')
accumulator=''
for l in f:
# Note: lstrip() should not be necessary, but there is 1 badly
# formatted comment in vlc1.0.0 includes
if l.lstrip().startswith('
/**
'):
comment=''
continue
elif l.startswith('
*
'):
comment = comment + l[3:]
continue
l=l.strip()
if 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:
values=[]
(typ, dummy, data, name)=m.groups()
for i, l in enumerate(paramlist_re.split(data)):
l=l.strip()
if 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)) )
yield (typ, name, values)
def parse_include(name):
"""Parse include file.
...
...
@@ -429,6 +518,12 @@ class %(name)s(object):
return ret
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))
methods=[]
for name in sys.argv[1:]:
methods.extend(list(parse_include(name)))
...
...
@@ -436,6 +531,7 @@ if __name__ == '__main__':
sys.exit(0)
generate_header()
generate_enums(enums)
wrapped=generate_wrappers(methods)
for l in methods:
output_ctypes(*l)
...
...
bindings/python-ctypes/header.py
View file @
d7b1ce91
...
...
@@ -101,22 +101,6 @@ class MediaControlPositionOrigin(ctypes.c_uint):
def
__repr__
(
self
):
return
self
.
enum
[
self
.
value
]
class
State
(
ctypes
.
c_uint
):
# FIXME: should be improved (State.NothingSpecial should hold the value)
# and maybe auto-generated from typedefs
enum
=
(
'NothingSpecial'
,
'Opening'
,
'Buffering'
,
'Playing'
,
'Paused'
,
'Stopped'
,
'Ended'
,
'Error'
,
)
def
__repr__
(
self
):
return
self
.
enum
[
self
.
value
]
class
MediaControlException
(
ctypes
.
Structure
):
_fields_
=
[
(
'code'
,
ctypes
.
c_int
),
...
...
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