Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
931ebab8
Commit
931ebab8
authored
Jun 12, 2013
by
Gabe Schwartz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated generator and parser to support Python 3.
parent
6faf00b8
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
71 additions
and
59 deletions
+71
-59
gen2.py
modules/python/src2/gen2.py
+45
-34
hdr_parser.py
modules/python/src2/hdr_parser.py
+26
-25
No files found.
modules/python/src2/gen2.py
View file @
931ebab8
#!/usr/bin/env python
import
hdr_parser
,
sys
,
re
,
os
,
cStringIO
from
__future__
import
print_function
import
hdr_parser
,
sys
,
re
,
os
from
string
import
Template
if
sys
.
version_info
[
0
]
>=
3
:
from
io
import
StringIO
else
:
from
cStringIO
import
StringIO
ignored_arg_types
=
[
"RNG*"
]
gen_template_check_self
=
Template
(
""" if(!PyObject_TypeCheck(self, &pyopencv_${name}_Type))
...
...
@@ -33,6 +39,13 @@ gen_template_func_body = Template("""$code_decl
}
"""
)
py_major_version
=
sys
.
version_info
[
0
]
if
py_major_version
>=
3
:
head_init_str
=
"PyVarObject_HEAD_INIT(&PyType_Type, 0)"
else
:
head_init_str
=
"""PyObject_HEAD_INIT(&PyType_Type)
0,"""
gen_template_simple_type_decl
=
Template
(
"""
struct pyopencv_${name}_t
{
...
...
@@ -42,8 +55,7 @@ struct pyopencv_${name}_t
static PyTypeObject pyopencv_${name}_Type =
{
PyObject_HEAD_INIT(&PyType_Type)
0,
%
s
MODULESTR".$wname",
sizeof(pyopencv_${name}_t),
};
...
...
@@ -66,13 +78,13 @@ template<> bool pyopencv_to(PyObject* src, ${cname}& dst, const char* name)
return true;
if(!PyObject_TypeCheck(src, &pyopencv_${name}_Type))
{
failmsg("Expected ${cname} for argument '
%
s'", name);
failmsg("Expected ${cname} for argument '
%
%
s'", name);
return false;
}
dst = ((pyopencv_${name}_t*)src)->v;
return true;
}
"""
)
"""
%
head_init_str
)
gen_template_type_decl
=
Template
(
"""
...
...
@@ -84,8 +96,7 @@ struct pyopencv_${name}_t
static PyTypeObject pyopencv_${name}_Type =
{
PyObject_HEAD_INIT(&PyType_Type)
0,
%
s
MODULESTR".$wname",
sizeof(pyopencv_${name}_t),
};
...
...
@@ -110,14 +121,14 @@ template<> bool pyopencv_to(PyObject* src, Ptr<${cname}>& dst, const char* name)
return true;
if(!PyObject_TypeCheck(src, &pyopencv_${name}_Type))
{
failmsg("Expected ${cname} for argument '
%
s'", name);
failmsg("Expected ${cname} for argument '
%
%
s'", name);
return false;
}
dst = ((pyopencv_${name}_t*)src)->v;
return true;
}
"""
)
"""
%
head_init_str
)
gen_template_map_type_cvt
=
Template
(
"""
template<> bool pyopencv_to(PyObject* src, ${cname}& dst, const char* name);
...
...
@@ -245,9 +256,9 @@ class ClassInfo(object):
if
decl
:
self
.
bases
=
decl
[
1
]
.
split
()[
1
:]
if
len
(
self
.
bases
)
>
1
:
print
"Note: Class
%
s has more than 1 base class (not supported by Python C extensions)"
%
(
self
.
name
,
)
print
" Bases: "
,
" "
.
join
(
self
.
bases
)
print
" Only the first base class will be used"
print
(
"Note: Class
%
s has more than 1 base class (not supported by Python C extensions)"
%
(
self
.
name
,)
)
print
(
" Bases: "
,
" "
.
join
(
self
.
bases
)
)
print
(
" Only the first base class will be used"
)
self
.
bases
=
[
self
.
bases
[
0
]
.
strip
(
","
)]
#return sys.exit(-1)
if
self
.
bases
and
self
.
bases
[
0
]
.
startswith
(
"cv::"
):
...
...
@@ -280,8 +291,8 @@ class ClassInfo(object):
if
self
.
ismap
:
return
self
.
gen_map_code
(
all_classes
)
getset_code
=
cStringIO
.
StringIO
()
getset_inits
=
cStringIO
.
StringIO
()
getset_code
=
StringIO
()
getset_inits
=
StringIO
()
sorted_props
=
[(
p
.
name
,
p
)
for
p
in
self
.
props
]
sorted_props
.
sort
()
...
...
@@ -304,10 +315,10 @@ class ClassInfo(object):
getset_code
.
write
(
gen_template_set_prop
.
substitute
(
name
=
self
.
name
,
member
=
pname
,
membertype
=
p
.
tp
,
access
=
access_op
))
getset_inits
.
write
(
gen_template_rw_prop_init
.
substitute
(
name
=
self
.
name
,
member
=
pname
))
methods_code
=
cStringIO
.
StringIO
()
methods_inits
=
cStringIO
.
StringIO
()
methods_code
=
StringIO
()
methods_inits
=
StringIO
()
sorted_methods
=
self
.
methods
.
items
(
)
sorted_methods
=
list
(
self
.
methods
.
items
()
)
sorted_methods
.
sort
()
for
mname
,
m
in
sorted_methods
:
...
...
@@ -315,7 +326,7 @@ class ClassInfo(object):
methods_inits
.
write
(
m
.
get_tab_entry
())
baseptr
=
"NULL"
if
self
.
bases
and
all_classes
.
has_key
(
self
.
bases
[
0
])
:
if
self
.
bases
and
self
.
bases
[
0
]
in
all_classes
:
baseptr
=
"&pyopencv_"
+
all_classes
[
self
.
bases
[
0
]]
.
name
+
"_Type"
code
=
gen_template_type_impl
.
substitute
(
name
=
self
.
name
,
wname
=
self
.
wname
,
cname
=
self
.
cname
,
...
...
@@ -609,7 +620,7 @@ class FuncInfo(object):
defval0
=
"0"
tp1
=
tp
.
replace
(
"*"
,
"_ptr"
)
if
tp1
.
endswith
(
"*"
):
print
"Error: type with star: a.tp=
%
s, tp=
%
s, tp1=
%
s"
%
(
a
.
tp
,
tp
,
tp1
)
print
(
"Error: type with star: a.tp=
%
s, tp=
%
s, tp1=
%
s"
%
(
a
.
tp
,
tp
,
tp1
)
)
sys
.
exit
(
-
1
)
amapping
=
simple_argtype_mapping
.
get
(
tp
,
(
tp
,
"O"
,
defval0
))
...
...
@@ -715,11 +726,11 @@ class PythonWrapperGenerator(object):
self
.
classes
=
{}
self
.
funcs
=
{}
self
.
consts
=
{}
self
.
code_types
=
cStringIO
.
StringIO
()
self
.
code_funcs
=
cStringIO
.
StringIO
()
self
.
code_func_tab
=
cStringIO
.
StringIO
()
self
.
code_type_reg
=
cStringIO
.
StringIO
()
self
.
code_const_reg
=
cStringIO
.
StringIO
()
self
.
code_types
=
StringIO
()
self
.
code_funcs
=
StringIO
()
self
.
code_func_tab
=
StringIO
()
self
.
code_type_reg
=
StringIO
()
self
.
code_const_reg
=
StringIO
()
self
.
class_idx
=
0
def
add_class
(
self
,
stype
,
name
,
decl
):
...
...
@@ -727,9 +738,9 @@ class PythonWrapperGenerator(object):
classinfo
.
decl_idx
=
self
.
class_idx
self
.
class_idx
+=
1
if
self
.
classes
.
has_key
(
classinfo
.
name
)
:
print
"Generator error: class
%
s (cname=
%
s) already exists"
\
%
(
classinfo
.
name
,
classinfo
.
cname
)
if
classinfo
.
name
in
self
.
classes
:
print
(
"Generator error: class
%
s (cname=
%
s) already exists"
\
%
(
classinfo
.
name
,
classinfo
.
cname
)
)
sys
.
exit
(
-
1
)
self
.
classes
[
classinfo
.
name
]
=
classinfo
if
classinfo
.
bases
and
not
classinfo
.
isalgorithm
:
...
...
@@ -738,9 +749,9 @@ class PythonWrapperGenerator(object):
def
add_const
(
self
,
name
,
decl
):
constinfo
=
ConstInfo
(
name
,
decl
[
1
])
if
self
.
consts
.
has_key
(
constinfo
.
name
)
:
print
"Generator error: constant
%
s (cname=
%
s) already exists"
\
%
(
constinfo
.
name
,
constinfo
.
cname
)
if
constinfo
.
name
in
self
.
consts
:
print
(
"Generator error: constant
%
s (cname=
%
s) already exists"
\
%
(
constinfo
.
name
,
constinfo
.
cname
)
)
sys
.
exit
(
-
1
)
self
.
consts
[
constinfo
.
name
]
=
constinfo
...
...
@@ -779,7 +790,7 @@ class PythonWrapperGenerator(object):
else
:
classinfo
=
self
.
classes
.
get
(
classname
,
ClassInfo
(
""
))
if
not
classinfo
.
name
:
print
"Generator error: the class for method
%
s is missing"
%
(
name
,
)
print
(
"Generator error: the class for method
%
s is missing"
%
(
name
,)
)
sys
.
exit
(
-
1
)
func_map
=
classinfo
.
methods
...
...
@@ -819,7 +830,7 @@ class PythonWrapperGenerator(object):
self
.
add_func
(
decl
)
# step 2: generate code for the classes and their methods
classlist
=
self
.
classes
.
items
(
)
classlist
=
list
(
self
.
classes
.
items
()
)
classlist
.
sort
()
for
name
,
classinfo
in
classlist
:
if
classinfo
.
ismap
:
...
...
@@ -844,7 +855,7 @@ class PythonWrapperGenerator(object):
self
.
code_type_reg
.
write
(
"MKTYPE2(
%
s);
\n
"
%
(
classinfo
.
name
,)
)
# step 3: generate the code for all the global functions
funclist
=
self
.
funcs
.
items
(
)
funclist
=
list
(
self
.
funcs
.
items
()
)
funclist
.
sort
()
for
name
,
func
in
funclist
:
code
=
func
.
gen_code
(
self
.
classes
)
...
...
@@ -852,7 +863,7 @@ class PythonWrapperGenerator(object):
self
.
code_func_tab
.
write
(
func
.
get_tab_entry
())
# step 4: generate the code for constants
constlist
=
self
.
consts
.
items
(
)
constlist
=
list
(
self
.
consts
.
items
()
)
constlist
.
sort
()
for
name
,
constinfo
in
constlist
:
self
.
gen_const_reg
(
constinfo
)
...
...
modules/python/src2/hdr_parser.py
View file @
931ebab8
#!/usr/bin/env python
from
__future__
import
print_function
import
os
,
sys
,
re
,
string
# the list only for debugging. The real list, used in the real OpenCV build, is specified in CMakeLists.txt
...
...
@@ -43,13 +44,13 @@ class CppHeaderParser(object):
def
get_macro_arg
(
self
,
arg_str
,
npos
):
npos2
=
npos3
=
arg_str
.
find
(
"("
,
npos
)
if
npos2
<
0
:
print
"Error: no arguments for the macro at
%
d"
%
(
self
.
lineno
,
)
print
(
"Error: no arguments for the macro at
%
d"
%
(
self
.
lineno
,)
)
sys
.
exit
(
-
1
)
balance
=
1
while
1
:
t
,
npos3
=
self
.
find_next_token
(
arg_str
,
[
'('
,
')'
],
npos3
+
1
)
if
npos3
<
0
:
print
"Error: no matching ')' in the macro call at
%
d"
%
(
self
.
lineno
,
)
print
(
"Error: no matching ')' in the macro call at
%
d"
%
(
self
.
lineno
,)
)
sys
.
exit
(
-
1
)
if
t
==
'('
:
balance
+=
1
...
...
@@ -143,13 +144,13 @@ class CppHeaderParser(object):
angle_stack
.
append
(
0
)
elif
w
==
","
or
w
==
'>'
:
if
not
angle_stack
:
print
"Error at
%
d: argument contains ',' or '>' not within template arguments"
%
(
self
.
lineno
,
)
print
(
"Error at
%
d: argument contains ',' or '>' not within template arguments"
%
(
self
.
lineno
,)
)
sys
.
exit
(
-
1
)
if
w
==
","
:
arg_type
+=
"_and_"
elif
w
==
">"
:
if
angle_stack
[
0
]
==
0
:
print
"Error at
%
s:
%
d: template has no arguments"
%
(
self
.
hname
,
self
.
lineno
)
print
(
"Error at
%
s:
%
d: template has no arguments"
%
(
self
.
hname
,
self
.
lineno
)
)
sys
.
exit
(
-
1
)
if
angle_stack
[
0
]
>
1
:
arg_type
+=
"_end_"
...
...
@@ -173,7 +174,7 @@ class CppHeaderParser(object):
p1
=
arg_name
.
find
(
"["
)
p2
=
arg_name
.
find
(
"]"
,
p1
+
1
)
if
p2
<
0
:
print
"Error at
%
d: no closing ]"
%
(
self
.
lineno
,
)
print
(
"Error at
%
d: no closing ]"
%
(
self
.
lineno
,)
)
sys
.
exit
(
-
1
)
counter_str
=
arg_name
[
p1
+
1
:
p2
]
.
strip
()
if
counter_str
==
""
:
...
...
@@ -358,7 +359,7 @@ class CppHeaderParser(object):
if
bool
(
re
.
match
(
r".*\)\s*const(\s*=\s*0)?"
,
decl_str
)):
decl
[
2
]
.
append
(
"/C"
)
if
"virtual"
in
decl_str
:
print
decl_str
print
(
decl_str
)
return
decl
def
parse_func_decl
(
self
,
decl_str
):
...
...
@@ -412,12 +413,12 @@ class CppHeaderParser(object):
if
decl_str
.
startswith
(
"CVAPI"
):
rtype_end
=
decl_str
.
find
(
")"
,
args_begin
+
1
)
if
rtype_end
<
0
:
print
"Error at
%
d. no terminating ) in CVAPI() macro:
%
s"
%
(
self
.
lineno
,
decl_str
)
print
(
"Error at
%
d. no terminating ) in CVAPI() macro:
%
s"
%
(
self
.
lineno
,
decl_str
)
)
sys
.
exit
(
-
1
)
decl_str
=
decl_str
[
args_begin
+
1
:
rtype_end
]
+
" "
+
decl_str
[
rtype_end
+
1
:]
args_begin
=
decl_str
.
find
(
"("
)
if
args_begin
<
0
:
print
"Error at
%
d: no args in '
%
s'"
%
(
self
.
lineno
,
decl_str
)
print
(
"Error at
%
d: no args in '
%
s'"
%
(
self
.
lineno
,
decl_str
)
)
sys
.
exit
(
-
1
)
decl_start
=
decl_str
[:
args_begin
]
.
strip
()
...
...
@@ -425,7 +426,7 @@ class CppHeaderParser(object):
if
decl_start
.
endswith
(
"operator"
):
args_begin
=
decl_str
.
find
(
"("
,
args_begin
+
1
)
if
args_begin
<
0
:
print
"Error at
%
d: no args in '
%
s'"
%
(
self
.
lineno
,
decl_str
)
print
(
"Error at
%
d: no args in '
%
s'"
%
(
self
.
lineno
,
decl_str
)
)
sys
.
exit
(
-
1
)
decl_start
=
decl_str
[:
args_begin
]
.
strip
()
# TODO: normalize all type of operators
...
...
@@ -455,7 +456,7 @@ class CppHeaderParser(object):
return
[]
# exotic - dynamic 2d array
else
:
#print rettype, funcname, modlist, argno
print
"Error at
%
s:
%
d the function/method name is missing: '
%
s'"
%
(
self
.
hname
,
self
.
lineno
,
decl_start
)
print
(
"Error at
%
s:
%
d the function/method name is missing: '
%
s'"
%
(
self
.
hname
,
self
.
lineno
,
decl_start
)
)
sys
.
exit
(
-
1
)
if
self
.
wrap_mode
and
((
"::"
in
funcname
)
or
funcname
.
startswith
(
"~"
)):
...
...
@@ -486,9 +487,9 @@ class CppHeaderParser(object):
npos
+=
1
t
,
npos
=
self
.
find_next_token
(
decl_str
,
[
"("
,
")"
,
","
,
"<"
,
">"
],
npos
)
if
not
t
:
print
"Error: no closing ')' at
%
d"
%
(
self
.
lineno
,
)
print
decl_str
print
decl_str
[
arg_start
:]
print
(
"Error: no closing ')' at
%
d"
%
(
self
.
lineno
,)
)
print
(
decl_str
)
print
(
decl_str
[
arg_start
:])
sys
.
exit
(
-
1
)
if
t
==
"<"
:
angle_balance
+=
1
...
...
@@ -583,7 +584,7 @@ class CppHeaderParser(object):
if
block_type
in
[
"file"
,
"enum"
]:
continue
if
block_type
not
in
[
"struct"
,
"class"
,
"namespace"
]:
print
"Error at
%
d: there are non-valid entries in the current block stack "
%
(
self
.
lineno
,
self
.
block_stack
)
print
(
"Error at
%
d: there are non-valid entries in the current block stack "
%
(
self
.
lineno
,
self
.
block_stack
)
)
sys
.
exit
(
-
1
)
if
block_name
:
n
+=
block_name
+
"."
...
...
@@ -605,7 +606,7 @@ class CppHeaderParser(object):
stmt_type
=
"block"
if
context
==
"block"
:
print
"Error at
%
d: should not call parse_stmt inside blocks"
%
(
self
.
lineno
,
)
print
(
"Error at
%
d: should not call parse_stmt inside blocks"
%
(
self
.
lineno
,)
)
sys
.
exit
(
-
1
)
if
context
==
"class"
or
context
==
"struct"
:
...
...
@@ -632,7 +633,7 @@ class CppHeaderParser(object):
try
:
classname
,
bases
,
modlist
=
self
.
parse_class_decl
(
stmt
[
len
(
"typedef "
):])
except
:
print
"Error at
%
s:
%
d"
%
(
self
.
hname
,
self
.
lineno
)
print
(
"Error at
%
s:
%
d"
%
(
self
.
hname
,
self
.
lineno
)
)
exit
(
1
)
if
classname
.
startswith
(
"_Ipl"
):
classname
=
classname
[
1
:]
...
...
@@ -647,7 +648,7 @@ class CppHeaderParser(object):
try
:
classname
,
bases
,
modlist
=
self
.
parse_class_decl
(
stmt
)
except
:
print
"Error at
%
s:
%
d"
%
(
self
.
hname
,
self
.
lineno
)
print
(
"Error at
%
s:
%
d"
%
(
self
.
hname
,
self
.
lineno
)
)
exit
(
1
)
decl
=
[]
if
(
"CV_EXPORTS_W"
in
stmt
)
or
(
"CV_EXPORTS_AS"
in
stmt
)
or
(
not
self
.
wrap_mode
):
# and ("CV_EXPORTS" in stmt)):
...
...
@@ -767,7 +768,7 @@ class CppHeaderParser(object):
state
=
SCAN
if
state
!=
SCAN
:
print
"Error at
%
d: invlid state =
%
d"
%
(
self
.
lineno
,
state
)
print
(
"Error at
%
d: invlid state =
%
d"
%
(
self
.
lineno
,
state
)
)
sys
.
exit
(
-
1
)
while
1
:
...
...
@@ -795,7 +796,7 @@ class CppHeaderParser(object):
while
1
:
t2
,
pos2
=
self
.
find_next_token
(
l
,
[
"
\\
"
,
"
\"
"
],
pos2
)
if
t2
==
""
:
print
"Error at
%
d: no terminating '
\"
'"
%
(
self
.
lineno
,
)
print
(
"Error at
%
d: no terminating '
\"
'"
%
(
self
.
lineno
,)
)
sys
.
exit
(
-
1
)
if
t2
==
"
\"
"
:
break
...
...
@@ -836,7 +837,7 @@ class CppHeaderParser(object):
if
token
==
"}"
:
if
not
self
.
block_stack
:
print
"Error at
%
d: the block stack is empty"
%
(
self
.
lineno
,
)
print
(
"Error at
%
d: the block stack is empty"
%
(
self
.
lineno
,)
)
self
.
block_stack
[
-
1
:]
=
[]
if
pos
+
1
<
len
(
l
)
and
l
[
pos
+
1
]
==
';'
:
pos
+=
1
...
...
@@ -851,13 +852,13 @@ class CppHeaderParser(object):
Prints the list of declarations, retrieived by the parse() method
"""
for
d
in
decls
:
print
d
[
0
],
d
[
1
],
";"
.
join
(
d
[
2
]
)
print
(
d
[
0
],
d
[
1
],
";"
.
join
(
d
[
2
])
)
for
a
in
d
[
3
]:
print
" "
,
a
[
0
],
a
[
1
],
a
[
2
],
print
(
" "
,
a
[
0
],
a
[
1
],
a
[
2
],
end
=
""
)
if
a
[
3
]:
print
"; "
.
join
(
a
[
3
]
)
print
(
"; "
.
join
(
a
[
3
])
)
else
:
print
print
()
if
__name__
==
'__main__'
:
parser
=
CppHeaderParser
()
...
...
@@ -867,4 +868,4 @@ if __name__ == '__main__':
#for hname in sys.argv[1:]:
#decls += parser.parse(hname, wmode=False)
parser
.
print_decls
(
decls
)
print
len
(
decls
)
print
(
len
(
decls
)
)
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