[vlc-commits] fixes and changes
Alberto Invernizzi
git at videolan.org
Wed Apr 29 13:12:41 CEST 2020
vlc/python | branch: master | Alberto Invernizzi <alby.inve at gmail.com> | Tue Apr 21 23:01:17 2020 +0200| [7b8704b2103fb7fb97fedf81b42acb3822437809] | committer: Alberto Invernizzi
fixes and changes
- improvement for function pointer regex
- improvements for Par parse_param
- refactored parse_param as Par classmethod
> http://git.videolan.org/gitweb.cgi/vlc/python.git/?a=commit;h=7b8704b2103fb7fb97fedf81b42acb3822437809
---
generator/generate.py | 151 +++++++++++++++++++++++++-------------------------
1 file changed, 76 insertions(+), 75 deletions(-)
diff --git a/generator/generate.py b/generator/generate.py
index c4b3e00..06543cb 100755
--- a/generator/generate.py
+++ b/generator/generate.py
@@ -156,7 +156,7 @@ callback_type_re = re.compile(r'^typedef\s+\w+(\s*\*)?\s*\(\s*\*')
callback_re = re.compile(r'typedef\s+\*?(\w+\s*\*?)\s*\(\s*\*\s*(\w+)\s*\)\s*\((.+)\);')
struct_type_re = re.compile(r'^typedef\s+struct\s*(\S+)\s*$')
struct_re = re.compile(r'typedef\s+(struct)\s*(\S+)?\s*\{\s*(.+)\s*\}\s*(?:\S+)?\s*;')
-func_pointer_re = re.compile(r'(\(?[^\(]+)\s+\((\*\s*\S*)\)(\(.*\))') # (ret_type, *pointer_name, ([params]))
+func_pointer_re = re.compile(r'(\(?[^\(]+)\s*\((\*\s*\S*)\)(\(.*\))') # (ret_type, *pointer_name, ([params]))
typedef_re = re.compile(r'^typedef\s+(?:struct\s+)?(\S+)\s+(\S+);')
forward_re = re.compile(r'.+\(\s*(.+?)\s*\)(\s*\S+)')
libvlc_re = re.compile(r'libvlc_[a-z_]+')
@@ -442,6 +442,77 @@ class Par(object):
else: # see ctypes 15.16.2.4 Function prototypes
return f, self.name, default #PYCHOK expected
+ @classmethod
+ def parse_param(cls, param_raw):
+ """Parse a C parameter expression.
+
+ It is used to parse the type/name of functions
+ and type/name of the function parameters.
+
+ @return: a Par instance.
+ """
+ param_raw = param_raw.strip()
+ if _VLC_FORWARD_ in param_raw:
+ m = forward_re.match(param_raw)
+ param_raw = m.group(1) + m.group(2)
+
+ # is this a function pointer?
+ if func_pointer_re.search(param_raw):
+ return None
+
+ # is this parameter a pointer?
+ split_pointer = param_raw.split('*')
+ if len(split_pointer) > 1:
+ param_type = split_pointer[0]
+ param_name = split_pointer[-1].split(' ')[-1]
+ param_deref_levels = len(split_pointer) - 1
+
+ # it is a pointer, so it should have at least 1 level of indirection
+ assert(param_deref_levels > 0)
+
+ # POINTER SEMANTIC
+ constness = split_pointer[:-1]
+ constness += ['const' if len(split_pointer[-1].strip().split(' ')) > 1 else '']
+ param_constness = ['const' in deref_level for deref_level in constness]
+
+ # PARAM TYPE
+ param_type = split_pointer[0].replace('const ', '').strip()
+ # remove the struct keyword, this information is currently not used
+ param_type = param_type.replace('struct ', '').strip()
+
+ # add back the information of how many dereference levels there are
+ param_type += '*' * param_deref_levels
+
+ # ASSUMPTION
+ # just indirection level 0 and 1 can be const
+ for deref_level_constness in param_constness[2:]: assert(not deref_level_constness)
+ # ... or is it a simple variable?
+ else:
+ # WARNING: workaround for "union { struct {"
+ param_raw = param_raw.split('{')[-1]
+
+ # ASSUMPTIONs
+ # these allows to constrain param_raw to these options:
+ # - named: "type name" (e.g. "int param")
+ # - anonymous: "type" (e.g. "int")
+ assert('struct' not in param_raw)
+ assert('const' not in param_raw)
+
+ # normalize spaces
+ param_raw = re.sub('\s+', ' ', param_raw)
+
+ split_value = param_raw.split(' ')
+ if len(split_value) > 1:
+ param_name = split_value[-1]
+ param_type = ' '.join(split_value[:-1])
+ else:
+ param_type = split_value[0]
+ param_name = ''
+
+ param_constness = [False]
+
+ return Par(param_name.strip(), param_type.strip(), param_constness)
+
class Val(object):
"""Enum name and value.
"""
@@ -531,7 +602,7 @@ class Parser(object):
_blacklist[name] = type_
continue
- pars = [self.parse_param(p) for p in paramlist_re.split(pars)]
+ pars = [Par.parse_param(p) for p in paramlist_re.split(pars)]
yield Func(name, type_.replace(' ', '') + '*', pars, docs,
file_=self.h_file, line=line)
@@ -584,7 +655,7 @@ class Parser(object):
@return: yield a Struct instance for each struct.
"""
for typ, name, body, docs, line in self.parse_groups(struct_type_re.match, struct_re.match, re.compile(r'^\}(\s*\S+)?\s*;$')):
- fields = [ self.parse_param(t.strip()) for t in decllist_re.split(body) if t.strip() and not '%s()' % name in t ]
+ fields = [ Par.parse_param(t.strip()) for t in decllist_re.split(body) if t.strip() and not '%s()' % name in t ]
fields = [ f for f in fields if f is not None ]
name = name.strip()
@@ -606,12 +677,12 @@ class Parser(object):
for name, pars, docs, line in self.parse_groups(match_t, api_re.match, ');'):
- f = self.parse_param(name)
+ f = Par.parse_param(name)
if f.name in _blacklist:
_blacklist[f.name] = f.type
continue
- pars = [self.parse_param(p) for p in paramlist_re.split(pars)]
+ pars = [Par.parse_param(p) for p in paramlist_re.split(pars)]
if len(pars) == 1 and pars[0].type == 'void':
pars = [] # no parameters
@@ -700,76 +771,6 @@ class Parser(object):
d = []
f.close()
- def parse_param(self, param_raw):
- """Parse a C parameter expression.
-
- It is used to parse the type/name of functions
- and type/name of the function parameters.
-
- @return: a Par instance.
- """
- param_raw = param_raw.strip()
- if _VLC_FORWARD_ in param_raw:
- m = forward_re.match(param_raw)
- param_raw = m.group(1) + m.group(2)
-
- # is this a function pointer?
- if func_pointer_re.search(param_raw):
- return None
-
- # is this parameter a pointer?
- split_pointer = param_raw.split('*')
- if len(split_pointer) > 1:
- param_type = split_pointer[0]
- param_name = split_pointer[-1]
- param_deref_levels = len(split_pointer) - 1
-
- # it is a pointer, so it should have at least 1 level of indirection
- assert(param_deref_levels > 0)
-
- # PARAM TYPE
- param_type = split_pointer[0].replace('const', '').strip()
- # remove the struct keyword, this information is currently not used
- param_type = param_type.replace('struct ', '').strip()
-
- # POINTER SEMANTIC
- # add back the information of how many dereference levels there are
- param_type += '*' * param_deref_levels
-
- constness = ['const' in deref_level for deref_level in split_pointer]
-
- # ASSUMPTION
- # just indirection level 0 and 1 can be const
- for deref_level_constness in constness[2:]: assert(not deref_level_constness)
-
- param_constness = constness[:2]
- # ... or is it a simple variable?
- else:
- # WARNING: workaround for "union { struct {"
- param_raw = param_raw.split('{')[-1]
-
- # ASSUMPTIONs
- # these allows to constrain param_raw to these options:
- # - named: "type name" (e.g. "int param")
- # - anonymous: "type" (e.g. "int")
- assert('struct' not in param_raw)
- assert('const' not in param_raw)
-
- # normalize spaces
- param_raw = re.sub('\s+', ' ', param_raw)
-
- split_value = param_raw.split(' ')
- if len(split_value) > 1:
- param_name = split_value[-1]
- param_type = ' '.join(split_value[:-1])
- else:
- param_type = split_value[0]
- param_name = ''
-
- param_constness = [False]
-
- return Par(param_name.strip(), param_type.strip(), param_constness)
-
def parse_version(self, h_files):
"""Get the libvlc version from the C header files:
LIBVLC_VERSION_MAJOR, _MINOR, _REVISION, _EXTRA
More information about the vlc-commits
mailing list