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():
...
@@ -140,17 +140,18 @@ class GeneralInfo():
def
fullName
(
self
,
isCPP
=
False
):
def
fullName
(
self
,
isCPP
=
False
):
result
=
"."
.
join
([
self
.
fullClass
(),
self
.
name
])
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
):
def
fullClass
(
self
,
isCPP
=
False
):
result
=
"."
.
join
([
f
for
f
in
[
self
.
namespace
]
+
self
.
classpath
.
split
(
"."
)
if
len
(
f
)
>
0
])
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
):
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
)
GeneralInfo
.
__init__
(
self
,
"const"
,
decl
,
namespaces
)
self
.
cname
=
self
.
name
.
replace
(
"."
,
"::"
)
self
.
cname
=
get_cname
(
self
.
name
)
self
.
value
=
decl
[
1
]
self
.
value
=
decl
[
1
]
self
.
enumType
=
enumType
self
.
addedManually
=
addedManually
self
.
addedManually
=
addedManually
if
self
.
namespace
in
namespaces_dict
:
if
self
.
namespace
in
namespaces_dict
:
self
.
name
=
'
%
s_
%
s'
%
(
namespaces_dict
[
self
.
namespace
],
self
.
name
)
self
.
name
=
'
%
s_
%
s'
%
(
namespaces_dict
[
self
.
namespace
],
self
.
name
)
...
@@ -166,6 +167,25 @@ class ConstInfo(GeneralInfo):
...
@@ -166,6 +167,25 @@ class ConstInfo(GeneralInfo):
return
True
return
True
return
False
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
():
class
ClassPropInfo
():
def
__init__
(
self
,
decl
):
# [f_ctype, f_name, '', '/RW']
def
__init__
(
self
,
decl
):
# [f_ctype, f_name, '', '/RW']
self
.
ctype
=
decl
[
0
]
self
.
ctype
=
decl
[
0
]
...
@@ -178,7 +198,7 @@ class ClassPropInfo():
...
@@ -178,7 +198,7 @@ class ClassPropInfo():
class
ClassInfo
(
GeneralInfo
):
class
ClassInfo
(
GeneralInfo
):
def
__init__
(
self
,
decl
,
namespaces
=
[]):
# [ 'class/struct cname', ': base', [modlist] ]
def
__init__
(
self
,
decl
,
namespaces
=
[]):
# [ 'class/struct cname', ': base', [modlist] ]
GeneralInfo
.
__init__
(
self
,
"class"
,
decl
,
namespaces
)
GeneralInfo
.
__init__
(
self
,
"class"
,
decl
,
namespaces
)
self
.
cname
=
self
.
name
.
replace
(
"."
,
"::"
)
self
.
cname
=
get_cname
(
self
.
name
)
self
.
methods
=
[]
self
.
methods
=
[]
self
.
methods_suffixes
=
{}
self
.
methods_suffixes
=
{}
self
.
consts
=
[]
# using a list to save the occurrence order
self
.
consts
=
[]
# using a list to save the occurrence order
...
@@ -303,7 +323,7 @@ class ArgInfo():
...
@@ -303,7 +323,7 @@ class ArgInfo():
class
FuncInfo
(
GeneralInfo
):
class
FuncInfo
(
GeneralInfo
):
def
__init__
(
self
,
decl
,
namespaces
=
[]):
# [ funcname, return_ctype, [modifiers], [args] ]
def
__init__
(
self
,
decl
,
namespaces
=
[]):
# [ funcname, return_ctype, [modifiers], [args] ]
GeneralInfo
.
__init__
(
self
,
"func"
,
decl
,
namespaces
)
GeneralInfo
.
__init__
(
self
,
"func"
,
decl
,
namespaces
)
self
.
cname
=
decl
[
0
]
.
replace
(
"."
,
"::"
)
self
.
cname
=
get_cname
(
decl
[
0
]
)
self
.
jname
=
self
.
name
self
.
jname
=
self
.
name
self
.
isconstructor
=
self
.
name
==
self
.
classname
self
.
isconstructor
=
self
.
name
==
self
.
classname
if
"["
in
self
.
name
:
if
"["
in
self
.
name
:
...
@@ -341,7 +361,6 @@ class JavaWrapperGenerator(object):
...
@@ -341,7 +361,6 @@ class JavaWrapperGenerator(object):
self
.
classes
=
{
"Mat"
:
ClassInfo
([
'class Mat'
,
''
,
[],
[]
],
self
.
namespaces
)
}
self
.
classes
=
{
"Mat"
:
ClassInfo
([
'class Mat'
,
''
,
[],
[]
],
self
.
namespaces
)
}
self
.
module
=
""
self
.
module
=
""
self
.
Module
=
""
self
.
Module
=
""
self
.
enum_types
=
[]
self
.
ported_func_list
=
[]
self
.
ported_func_list
=
[]
self
.
skipped_func_list
=
[]
self
.
skipped_func_list
=
[]
self
.
def_args_hist
=
{}
# { def_args_cnt : funcs_cnt }
self
.
def_args_hist
=
{}
# { def_args_cnt : funcs_cnt }
...
@@ -404,8 +423,8 @@ class JavaWrapperGenerator(object):
...
@@ -404,8 +423,8 @@ class JavaWrapperGenerator(object):
)
)
logging
.
info
(
'ok: class
%
s, name:
%
s, base:
%
s'
,
classinfo
,
name
,
classinfo
.
base
)
logging
.
info
(
'ok: class
%
s, name:
%
s, base:
%
s'
,
classinfo
,
name
,
classinfo
.
base
)
def
add_const
(
self
,
decl
):
# [ "const cname", val, [], [] ]
def
add_const
(
self
,
decl
,
enumType
=
None
):
# [ "const cname", val, [], [] ]
constinfo
=
ConstInfo
(
decl
,
namespaces
=
self
.
namespaces
)
constinfo
=
ConstInfo
(
decl
,
namespaces
=
self
.
namespaces
,
enumType
=
enumType
)
if
constinfo
.
isIgnored
():
if
constinfo
.
isIgnored
():
logging
.
info
(
'ignored:
%
s'
,
constinfo
)
logging
.
info
(
'ignored:
%
s'
,
constinfo
)
elif
not
self
.
isWrapped
(
constinfo
.
classname
):
elif
not
self
.
isWrapped
(
constinfo
.
classname
):
...
@@ -423,12 +442,16 @@ class JavaWrapperGenerator(object):
...
@@ -423,12 +442,16 @@ class JavaWrapperGenerator(object):
logging
.
info
(
'ok:
%
s'
,
constinfo
)
logging
.
info
(
'ok:
%
s'
,
constinfo
)
def
add_enum
(
self
,
decl
):
# [ "enum cname", "", [], [] ]
def
add_enum
(
self
,
decl
):
# [ "enum cname", "", [], [] ]
enumname
=
decl
[
0
]
.
replace
(
"enum "
,
""
)
.
strip
()
enumType
=
decl
[
0
]
.
rsplit
(
" "
,
1
)[
1
]
self
.
enum_types
.
append
(
enumname
)
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
]
const_decls
=
decl
[
3
]
for
decl
in
const_decls
:
for
decl
in
const_decls
:
self
.
add_const
(
decl
)
self
.
add_const
(
decl
,
enumType
)
def
add_func
(
self
,
decl
):
def
add_func
(
self
,
decl
):
fi
=
FuncInfo
(
decl
,
namespaces
=
self
.
namespaces
)
fi
=
FuncInfo
(
decl
,
namespaces
=
self
.
namespaces
)
...
@@ -530,7 +553,7 @@ class JavaWrapperGenerator(object):
...
@@ -530,7 +553,7 @@ class JavaWrapperGenerator(object):
if
self
.
isWrapped
(
t
):
if
self
.
isWrapped
(
t
):
return
self
.
getClass
(
t
)
.
fullName
(
isCPP
=
True
)
return
self
.
getClass
(
t
)
.
fullName
(
isCPP
=
True
)
else
:
else
:
return
t
return
cast_from
(
t
)
def
gen_func
(
self
,
ci
,
fi
,
prop_name
=
''
):
def
gen_func
(
self
,
ci
,
fi
,
prop_name
=
''
):
logging
.
info
(
"
%
s"
,
fi
)
logging
.
info
(
"
%
s"
,
fi
)
...
@@ -563,7 +586,7 @@ class JavaWrapperGenerator(object):
...
@@ -563,7 +586,7 @@ class JavaWrapperGenerator(object):
msg
=
"// Return type '
%
s' is not supported, skipping the function
\n\n
"
%
fi
.
ctype
msg
=
"// Return type '
%
s' is not supported, skipping the function
\n\n
"
%
fi
.
ctype
self
.
skipped_func_list
.
append
(
c_decl
+
"
\n
"
+
msg
)
self
.
skipped_func_list
.
append
(
c_decl
+
"
\n
"
+
msg
)
j_code
.
write
(
" "
*
4
+
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
return
for
a
in
fi
.
args
:
for
a
in
fi
.
args
:
if
a
.
ctype
not
in
type_dict
:
if
a
.
ctype
not
in
type_dict
:
...
@@ -575,7 +598,7 @@ class JavaWrapperGenerator(object):
...
@@ -575,7 +598,7 @@ class JavaWrapperGenerator(object):
msg
=
"// Unknown type '
%
s' (
%
s), skipping the function
\n\n
"
%
(
a
.
ctype
,
a
.
out
or
"I"
)
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
)
self
.
skipped_func_list
.
append
(
c_decl
+
"
\n
"
+
msg
)
j_code
.
write
(
" "
*
4
+
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
return
self
.
ported_func_list
.
append
(
c_decl
)
self
.
ported_func_list
.
append
(
c_decl
)
...
@@ -654,7 +677,7 @@ class JavaWrapperGenerator(object):
...
@@ -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
if
"I"
in
a
.
out
or
not
a
.
out
or
self
.
isWrapped
(
a
.
ctype
):
# input arg, pass by primitive fields
for
f
in
fields
:
for
f
in
fields
:
jn_args
.
append
(
ArgInfo
([
f
[
0
],
a
.
name
+
f
[
1
],
""
,
[],
""
])
)
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[]
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
,
""
,
[],
""
])
)
jn_args
.
append
(
ArgInfo
([
"double[]"
,
"
%
s_out"
%
a
.
name
,
""
,
[],
""
])
)
jni_args
.
append
(
ArgInfo
([
"double[]"
,
"
%
s_out"
%
a
.
name
,
""
,
[],
""
])
)
jni_args
.
append
(
ArgInfo
([
"double[]"
,
"
%
s_out"
%
a
.
name
,
""
,
[],
""
])
)
...
@@ -702,7 +725,7 @@ class JavaWrapperGenerator(object):
...
@@ -702,7 +725,7 @@ class JavaWrapperGenerator(object):
" private static native $type $name($args);
\n
"
)
.
substitute
(
\
" private static native $type $name($args);
\n
"
)
.
substitute
(
\
type
=
type_dict
[
fi
.
ctype
]
.
get
(
"jn_type"
,
"double[]"
),
\
type
=
type_dict
[
fi
.
ctype
]
.
get
(
"jn_type"
,
"double[]"
),
\
name
=
fi
.
jname
+
'_'
+
str
(
suffix_counter
),
\
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:
# java part:
...
@@ -860,7 +883,7 @@ class JavaWrapperGenerator(object):
...
@@ -860,7 +883,7 @@ class JavaWrapperGenerator(object):
if
not
a
.
out
and
not
"jni_var"
in
type_dict
[
a
.
ctype
]:
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)
# 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)
# 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
if
not
a
.
ctype
:
# hidden
jni_name
=
a
.
defval
jni_name
=
a
.
defval
cvargs
.
append
(
type_dict
[
a
.
ctype
]
.
get
(
"jni_name"
,
jni_name
)
%
{
"n"
:
a
.
name
})
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
...
@@ -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
])
%
s;
\n\n
"""
%
(
",
\n
"
+
" "
*
12
)
.
join
([
"
%
s =
%
s"
%
(
c
.
name
,
c
.
value
)
for
c
in
ci
.
private_consts
])
)
)
if
ci
.
consts
:
if
ci
.
consts
:
logging
.
info
(
"
%
s"
,
ci
.
consts
)
enumTypes
=
set
(
map
(
lambda
c
:
c
.
enumType
,
ci
.
consts
))
ci
.
j_code
.
write
(
"""
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
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
# methods
for
fi
in
ci
.
getAllMethods
():
for
fi
in
ci
.
getAllMethods
():
self
.
gen_func
(
ci
,
fi
)
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