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
78835ad8
Commit
78835ad8
authored
Aug 27, 2018
by
Hamdi Sahloul
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support enum arguments for Java binding
parent
4e6be21a
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
69 additions
and
22 deletions
+69
-22
gen_java.py
modules/java/generator/gen_java.py
+69
-22
No files found.
modules/java/generator/gen_java.py
View file @
78835ad8
...
...
@@ -140,17 +140,18 @@ class GeneralInfo():
def
fullName
(
self
,
isCPP
=
False
):
result
=
"."
.
join
([
self
.
fullClass
(),
self
.
name
])
return
result
if
not
isCPP
else
result
.
replace
(
"."
,
"::"
)
return
result
if
not
isCPP
else
get_cname
(
result
)
def
fullClass
(
self
,
isCPP
=
False
):
result
=
"."
.
join
([
f
for
f
in
[
self
.
namespace
]
+
self
.
classpath
.
split
(
"."
)
if
len
(
f
)
>
0
])
return
result
if
not
isCPP
else
result
.
replace
(
"."
,
"::"
)
return
result
if
not
isCPP
else
get_cname
(
result
)
class
ConstInfo
(
GeneralInfo
):
def
__init__
(
self
,
decl
,
addedManually
=
False
,
namespaces
=
[]):
def
__init__
(
self
,
decl
,
addedManually
=
False
,
namespaces
=
[]
,
enumType
=
None
):
GeneralInfo
.
__init__
(
self
,
"const"
,
decl
,
namespaces
)
self
.
cname
=
self
.
name
.
replace
(
"."
,
"::"
)
self
.
cname
=
get_cname
(
self
.
name
)
self
.
value
=
decl
[
1
]
self
.
enumType
=
enumType
self
.
addedManually
=
addedManually
if
self
.
namespace
in
namespaces_dict
:
self
.
name
=
'
%
s_
%
s'
%
(
namespaces_dict
[
self
.
namespace
],
self
.
name
)
...
...
@@ -166,6 +167,25 @@ class ConstInfo(GeneralInfo):
return
True
return
False
def
normalize_field_name
(
name
):
return
name
.
replace
(
"."
,
"_"
)
.
replace
(
"["
,
""
)
.
replace
(
"]"
,
""
)
.
replace
(
"_getNativeObjAddr()"
,
"_nativeObj"
)
def
normalize_class_name
(
name
):
return
re
.
sub
(
r"^cv\."
,
""
,
name
)
.
replace
(
"."
,
"_"
)
def
get_cname
(
name
):
return
name
.
replace
(
"."
,
"::"
)
def
cast_from
(
t
):
if
t
in
type_dict
and
"cast_from"
in
type_dict
[
t
]:
return
type_dict
[
t
][
"cast_from"
]
return
t
def
cast_to
(
t
):
if
t
in
type_dict
and
"cast_to"
in
type_dict
[
t
]:
return
type_dict
[
t
][
"cast_to"
]
return
t
class
ClassPropInfo
():
def
__init__
(
self
,
decl
):
# [f_ctype, f_name, '', '/RW']
self
.
ctype
=
decl
[
0
]
...
...
@@ -178,7 +198,7 @@ class ClassPropInfo():
class
ClassInfo
(
GeneralInfo
):
def
__init__
(
self
,
decl
,
namespaces
=
[]):
# [ 'class/struct cname', ': base', [modlist] ]
GeneralInfo
.
__init__
(
self
,
"class"
,
decl
,
namespaces
)
self
.
cname
=
self
.
name
.
replace
(
"."
,
"::"
)
self
.
cname
=
get_cname
(
self
.
name
)
self
.
methods
=
[]
self
.
methods_suffixes
=
{}
self
.
consts
=
[]
# using a list to save the occurrence order
...
...
@@ -303,7 +323,7 @@ class ArgInfo():
class
FuncInfo
(
GeneralInfo
):
def
__init__
(
self
,
decl
,
namespaces
=
[]):
# [ funcname, return_ctype, [modifiers], [args] ]
GeneralInfo
.
__init__
(
self
,
"func"
,
decl
,
namespaces
)
self
.
cname
=
decl
[
0
]
.
replace
(
"."
,
"::"
)
self
.
cname
=
get_cname
(
decl
[
0
]
)
self
.
jname
=
self
.
name
self
.
isconstructor
=
self
.
name
==
self
.
classname
if
"["
in
self
.
name
:
...
...
@@ -341,7 +361,6 @@ class JavaWrapperGenerator(object):
self
.
classes
=
{
"Mat"
:
ClassInfo
([
'class Mat'
,
''
,
[],
[]
],
self
.
namespaces
)
}
self
.
module
=
""
self
.
Module
=
""
self
.
enum_types
=
[]
self
.
ported_func_list
=
[]
self
.
skipped_func_list
=
[]
self
.
def_args_hist
=
{}
# { def_args_cnt : funcs_cnt }
...
...
@@ -404,8 +423,8 @@ class JavaWrapperGenerator(object):
)
logging
.
info
(
'ok: class
%
s, name:
%
s, base:
%
s'
,
classinfo
,
name
,
classinfo
.
base
)
def
add_const
(
self
,
decl
):
# [ "const cname", val, [], [] ]
constinfo
=
ConstInfo
(
decl
,
namespaces
=
self
.
namespaces
)
def
add_const
(
self
,
decl
,
enumType
=
None
):
# [ "const cname", val, [], [] ]
constinfo
=
ConstInfo
(
decl
,
namespaces
=
self
.
namespaces
,
enumType
=
enumType
)
if
constinfo
.
isIgnored
():
logging
.
info
(
'ignored:
%
s'
,
constinfo
)
elif
not
self
.
isWrapped
(
constinfo
.
classname
):
...
...
@@ -423,12 +442,16 @@ class JavaWrapperGenerator(object):
logging
.
info
(
'ok:
%
s'
,
constinfo
)
def
add_enum
(
self
,
decl
):
# [ "enum cname", "", [], [] ]
enumname
=
decl
[
0
]
.
replace
(
"enum "
,
""
)
.
strip
()
self
.
enum_types
.
append
(
enumname
)
enumType
=
decl
[
0
]
.
rsplit
(
" "
,
1
)[
1
]
if
enumType
.
endswith
(
"<unnamed>"
):
enumType
=
None
else
:
ctype
=
normalize_class_name
(
enumType
)
type_dict
[
ctype
]
=
{
"cast_from"
:
"int"
,
"cast_to"
:
get_cname
(
enumType
),
"j_type"
:
"int"
,
"jn_type"
:
"int"
,
"jni_type"
:
"jint"
,
"suffix"
:
"I"
}
const_decls
=
decl
[
3
]
for
decl
in
const_decls
:
self
.
add_const
(
decl
)
self
.
add_const
(
decl
,
enumType
)
def
add_func
(
self
,
decl
):
fi
=
FuncInfo
(
decl
,
namespaces
=
self
.
namespaces
)
...
...
@@ -530,7 +553,7 @@ class JavaWrapperGenerator(object):
if
self
.
isWrapped
(
t
):
return
self
.
getClass
(
t
)
.
fullName
(
isCPP
=
True
)
else
:
return
t
return
cast_from
(
t
)
def
gen_func
(
self
,
ci
,
fi
,
prop_name
=
''
):
logging
.
info
(
"
%
s"
,
fi
)
...
...
@@ -563,7 +586,7 @@ class JavaWrapperGenerator(object):
msg
=
"// Return type '
%
s' is not supported, skipping the function
\n\n
"
%
fi
.
ctype
self
.
skipped_func_list
.
append
(
c_decl
+
"
\n
"
+
msg
)
j_code
.
write
(
" "
*
4
+
msg
)
logging
.
warning
(
"SKIP:"
+
c_decl
.
strip
()
+
"
\t
due to RET type"
+
fi
.
ctype
)
logging
.
warning
(
"SKIP:"
+
c_decl
.
strip
()
+
"
\t
due to RET type
"
+
fi
.
ctype
)
return
for
a
in
fi
.
args
:
if
a
.
ctype
not
in
type_dict
:
...
...
@@ -575,7 +598,7 @@ class JavaWrapperGenerator(object):
msg
=
"// Unknown type '
%
s' (
%
s), skipping the function
\n\n
"
%
(
a
.
ctype
,
a
.
out
or
"I"
)
self
.
skipped_func_list
.
append
(
c_decl
+
"
\n
"
+
msg
)
j_code
.
write
(
" "
*
4
+
msg
)
logging
.
warning
(
"SKIP:"
+
c_decl
.
strip
()
+
"
\t
due to ARG type"
+
a
.
ctype
+
"/"
+
(
a
.
out
or
"I"
))
logging
.
warning
(
"SKIP:"
+
c_decl
.
strip
()
+
"
\t
due to ARG type
"
+
a
.
ctype
+
"/"
+
(
a
.
out
or
"I"
))
return
self
.
ported_func_list
.
append
(
c_decl
)
...
...
@@ -654,7 +677,7 @@ class JavaWrapperGenerator(object):
if
"I"
in
a
.
out
or
not
a
.
out
or
self
.
isWrapped
(
a
.
ctype
):
# input arg, pass by primitive fields
for
f
in
fields
:
jn_args
.
append
(
ArgInfo
([
f
[
0
],
a
.
name
+
f
[
1
],
""
,
[],
""
])
)
jni_args
.
append
(
ArgInfo
([
f
[
0
],
a
.
name
+
f
[
1
]
.
replace
(
"."
,
"_"
)
.
replace
(
"["
,
""
)
.
replace
(
"]"
,
""
)
.
replace
(
"_getNativeObjAddr()"
,
"_nativeObj"
),
""
,
[],
""
])
)
jni_args
.
append
(
ArgInfo
([
f
[
0
],
a
.
name
+
normalize_field_name
(
f
[
1
]
),
""
,
[],
""
])
)
if
"O"
in
a
.
out
and
not
self
.
isWrapped
(
a
.
ctype
):
# out arg, pass as double[]
jn_args
.
append
(
ArgInfo
([
"double[]"
,
"
%
s_out"
%
a
.
name
,
""
,
[],
""
])
)
jni_args
.
append
(
ArgInfo
([
"double[]"
,
"
%
s_out"
%
a
.
name
,
""
,
[],
""
])
)
...
...
@@ -702,7 +725,7 @@ class JavaWrapperGenerator(object):
" private static native $type $name($args);
\n
"
)
.
substitute
(
\
type
=
type_dict
[
fi
.
ctype
]
.
get
(
"jn_type"
,
"double[]"
),
\
name
=
fi
.
jname
+
'_'
+
str
(
suffix_counter
),
\
args
=
", "
.
join
([
"
%
s
%
s"
%
(
type_dict
[
a
.
ctype
][
"jn_type"
],
a
.
name
.
replace
(
"."
,
"_"
)
.
replace
(
"["
,
""
)
.
replace
(
"]"
,
""
)
.
replace
(
"_getNativeObjAddr()"
,
"_nativeObj"
))
for
a
in
jn_args
])
args
=
", "
.
join
([
"
%
s
%
s"
%
(
type_dict
[
a
.
ctype
][
"jn_type"
],
normalize_field_name
(
a
.
name
))
for
a
in
jn_args
])
)
);
# java part:
...
...
@@ -860,7 +883,7 @@ class JavaWrapperGenerator(object):
if
not
a
.
out
and
not
"jni_var"
in
type_dict
[
a
.
ctype
]:
# explicit cast to C type to avoid ambiguous call error on platforms (mingw)
# where jni types are different from native types (e.g. jint is not the same as int)
jni_name
=
"(
%
s)
%
s"
%
(
a
.
ctype
,
jni_name
)
jni_name
=
"(
%
s)
%
s"
%
(
cast_to
(
a
.
ctype
)
,
jni_name
)
if
not
a
.
ctype
:
# hidden
jni_name
=
a
.
defval
cvargs
.
append
(
type_dict
[
a
.
ctype
]
.
get
(
"jni_name"
,
jni_name
)
%
{
"n"
:
a
.
name
})
...
...
@@ -934,11 +957,35 @@ JNIEXPORT $rtype JNICALL Java_org_opencv_${module}_${clazz}_$fname
%
s;
\n\n
"""
%
(
",
\n
"
+
" "
*
12
)
.
join
([
"
%
s =
%
s"
%
(
c
.
name
,
c
.
value
)
for
c
in
ci
.
private_consts
])
)
if
ci
.
consts
:
logging
.
info
(
"
%
s"
,
ci
.
consts
)
ci
.
j_code
.
write
(
"""
enumTypes
=
set
(
map
(
lambda
c
:
c
.
enumType
,
ci
.
consts
))
grouped_consts
=
{
enumType
:
[
c
for
c
in
ci
.
consts
if
c
.
enumType
==
enumType
]
for
enumType
in
enumTypes
}
for
typeName
,
consts
in
grouped_consts
.
items
():
logging
.
info
(
"
%
s"
,
consts
)
if
typeName
:
typeName
=
typeName
.
rsplit
(
"."
,
1
)[
-
1
]
###################### Utilize Java enums ######################
# ci.j_code.write("""
# public enum {1} {{
# {0};
#
# private final int id;
# {1}(int id) {{ this.id = id; }}
# {1}({1} _this) {{ this.id = _this.id; }}
# public int getValue() {{ return id; }}
# }}\n\n""".format((",\n"+" "*8).join(["%s(%s)" % (c.name, c.value) for c in consts]), typeName)
# )
################################################################
ci
.
j_code
.
write
(
"""
// C++: enum {1}
public static final int
%
s;
\n\n
"""
%
(
",
\n
"
+
" "
*
12
)
.
join
([
"
%
s =
%
s"
%
(
c
.
name
,
c
.
value
)
for
c
in
ci
.
consts
])
)
{0};
\n\n
"""
.
format
((
",
\n
"
+
" "
*
12
)
.
join
([
"
%
s =
%
s"
%
(
c
.
name
,
c
.
value
)
for
c
in
consts
]),
typeName
)
)
else
:
ci
.
j_code
.
write
(
"""
// C++: enum <unnamed>
public static final int
{0};
\n\n
"""
.
format
((
",
\n
"
+
" "
*
12
)
.
join
([
"
%
s =
%
s"
%
(
c
.
name
,
c
.
value
)
for
c
in
consts
]))
)
# methods
for
fi
in
ci
.
getAllMethods
():
self
.
gen_func
(
ci
,
fi
)
...
...
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