mirror of
https://github.com/opencv/opencv.git
synced 2024-11-29 05:29:54 +08:00
input/output assignment in templates is working for non-trivial cases. Updated parse_tree to handle '/IO' and '/S' modifiers
This commit is contained in:
parent
1a15ed3279
commit
f45bc35652
@ -7,11 +7,10 @@ def inputs(args):
|
||||
In OpenCV input arguments are all arguments with names
|
||||
not beginning with 'dst'
|
||||
'''
|
||||
out = []
|
||||
for arg in args:
|
||||
if not arg.name.startswith('dst'):
|
||||
out.append(arg)
|
||||
return out
|
||||
try:
|
||||
return [arg for arg in args['only'] if arg.I and not arg.O]
|
||||
except:
|
||||
return [arg for arg in args if arg.I]
|
||||
|
||||
def ninputs(args):
|
||||
'''Counts the number of input arguments in the input list'''
|
||||
@ -22,15 +21,24 @@ def outputs(args):
|
||||
reference, and returns a list of only those elements.
|
||||
In OpenCV, output references are preceeded by 'dst'
|
||||
'''
|
||||
out = []
|
||||
for arg in args:
|
||||
if arg.name.startswith('dst'):
|
||||
out.append(arg)
|
||||
return out
|
||||
try:
|
||||
return [arg for arg in args['only'] if arg.O and not arg.I]
|
||||
except:
|
||||
return [arg for arg in args if arg.O]
|
||||
|
||||
def only(args):
|
||||
'''Returns exclusively the arguments which are only inputs
|
||||
or only outputs'''
|
||||
d = {};
|
||||
d['only'] = args
|
||||
return d
|
||||
|
||||
def void(arg):
|
||||
return arg == 'void'
|
||||
|
||||
def flip(arg):
|
||||
return not arg
|
||||
|
||||
def output(arg):
|
||||
return True if arg.name.startswith('dst') else False
|
||||
|
||||
def noutputs(args):
|
||||
'''Counts the number of output arguments in the input list'''
|
||||
return len(outputs(args))
|
||||
|
@ -32,10 +32,13 @@ class MatlabWrapperGenerator(object):
|
||||
jtemplate.filters['toUnderCase'] = toUnderCase
|
||||
jtemplate.filters['comment'] = comment
|
||||
jtemplate.filters['inputs'] = inputs
|
||||
jtemplate.filters['outputs'] = outputs
|
||||
jtemplate.filters['output'] = output
|
||||
jtemplate.filters['noutputs'] = noutputs
|
||||
jtemplate.filters['ninputs'] = ninputs
|
||||
jtemplate.filters['outputs'] = outputs
|
||||
jtemplate.filters['noutputs'] = noutputs
|
||||
jtemplate.filters['only'] = only
|
||||
jtemplate.filters['void'] = void
|
||||
jtemplate.filters['not'] = flip
|
||||
|
||||
|
||||
# load the templates
|
||||
tfunction = jtemplate.get_template('template_function_base.cpp')
|
||||
|
@ -65,6 +65,7 @@ class Translator(object):
|
||||
name = self.translateName(defn[0])
|
||||
clss = self.translateClassName(defn[0])
|
||||
rtp = defn[1]
|
||||
static = True if 'S' in ''.join(defn[2]) else False
|
||||
args = defn[3]
|
||||
req = []
|
||||
opt = []
|
||||
@ -72,7 +73,7 @@ class Translator(object):
|
||||
if arg:
|
||||
a = self.translateArgument(arg)
|
||||
opt.append(a) if a.default else req.append(a)
|
||||
return Function(name, clss, '', rtp, False, req, opt)
|
||||
return Function(name, clss, static, '', rtp, False, req, opt)
|
||||
|
||||
def translateConstant(self, defn):
|
||||
const = True if 'const' in defn[0] else False
|
||||
@ -83,10 +84,16 @@ class Translator(object):
|
||||
return Constant(name, clss, tp, const, '', val)
|
||||
|
||||
def translateArgument(self, defn):
|
||||
tp = defn[0]
|
||||
ref = '*' if '*' in defn[0] else ''
|
||||
ref = '&' if '&' in defn[0] else ref
|
||||
const = ' const ' in ' '+defn[0]+' '
|
||||
tp = " ".join([word for word in defn[0].replace(ref, '').split() if not ' const ' in ' '+word+' '])
|
||||
name = defn[1]
|
||||
default = defn[2] if defn[2] else ''
|
||||
return Argument(name, tp, False, '', default)
|
||||
modifiers = ''.join(defn[3])
|
||||
I = True if not modifiers or 'I' in modifiers else False
|
||||
O = True if 'O' in modifiers else False
|
||||
return Argument(name, tp, const, I, O, ref, default)
|
||||
|
||||
def translateName(self, name):
|
||||
return name.split(' ')[-1].split('.')[-1]
|
||||
@ -123,9 +130,10 @@ class Class(object):
|
||||
(join((f.__str__() for f in self.functions), '\n\t') if self.functions else '')+'\n};'
|
||||
|
||||
class Function(object):
|
||||
def __init__(self, name='', clss='', namespace='', rtp='', const=False, req=None, opt=None):
|
||||
def __init__(self, name='', clss='', static=False, namespace='', rtp='', const=False, req=None, opt=None):
|
||||
self.name = name
|
||||
self.clss = clss
|
||||
self.static = static
|
||||
self.const = const
|
||||
self.namespace = namespace
|
||||
self.rtp = rtp
|
||||
@ -138,10 +146,12 @@ class Function(object):
|
||||
')'+(' const' if self.const else '')+';'
|
||||
|
||||
class Argument(object):
|
||||
def __init__(self, name='', tp='', const=False, ref='', default=''):
|
||||
def __init__(self, name='', tp='', const=False, I=True, O=False, ref='', default=''):
|
||||
self.name = name
|
||||
self.tp = tp
|
||||
self.ref = ref
|
||||
self.I = I
|
||||
self.O = O
|
||||
self.const = const
|
||||
self.default = default
|
||||
|
||||
|
@ -1,13 +1,24 @@
|
||||
// compose a function
|
||||
{% macro compose(fun, retname="ret") %}
|
||||
{%- if not fun.rtp == "void" -%} {{fun.rtp}} retname = {% endif -%}
|
||||
{{fun.name}}(
|
||||
/*
|
||||
* compose
|
||||
* compose a function call
|
||||
* This macro takes as input a Function object and composes
|
||||
* a function call by inspecting the types and argument names
|
||||
*/
|
||||
/
|
||||
{% macro compose(fun) %}
|
||||
{# ----------- Return type ------------- #}
|
||||
{%- if not fun.rtp|void -%} {{fun.rtp}} retval = {% endif -%}
|
||||
cv::{{fun.name}}(
|
||||
{#- ----------- Required ------------- -#}
|
||||
{%- for arg in fun.req -%}
|
||||
{%- if arg.ref == '*' -%}&{%- endif -%}
|
||||
{{arg.name}}
|
||||
{%- if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{#- ----------- Optional ------------- -#}
|
||||
{% if fun.req and fun.opt %}, {% endif %}
|
||||
{%- for opt in fun.opt -%}
|
||||
{%- if opt.ref == '*' -%}&{%- endif -%}
|
||||
{{opt.name}}
|
||||
{%- if not loop.last -%}, {% endif %}
|
||||
{%- endfor -%}
|
||||
@ -18,19 +29,18 @@
|
||||
{%- macro generate(fun) -%}
|
||||
|
||||
// unpack the arguments
|
||||
// inputs
|
||||
{# ----------- Inputs ------------- #}
|
||||
{% for arg in fun.req|inputs %}
|
||||
{{arg.tp}} {{arg.name}} = inputs[{{ loop.index0 }}];
|
||||
{% endfor %}
|
||||
{% for opt in fun.opt|inputs %}
|
||||
{{opt.tp}} {{opt.name}} = (nrhs > {{loop.index0 + fun.req|ninputs}}) ? inputs[{{loop.index0 + fun.req|ninputs}}] : {{opt.default}};
|
||||
{{opt.tp}} {{opt.name}} = (nrhs > {{loop.index0 + fun.req|inputs|length}}) ? inputs[{{loop.index0 + fun.req|inputs|length}}] : {{opt.default}};
|
||||
{% endfor %}
|
||||
|
||||
// outputs
|
||||
{% for arg in fun.req|outputs %}
|
||||
{# ----------- Outputs ------------ #}
|
||||
{% for arg in fun.req|only|outputs %}
|
||||
{{arg.tp}} {{arg.name}};
|
||||
{% endfor %}
|
||||
{% for opt in fun.opt|outputs %}
|
||||
{% for opt in fun.opt|only|outputs %}
|
||||
{{opt.tp}} {{opt.name}};
|
||||
{% endfor %}
|
||||
|
||||
@ -47,11 +57,14 @@
|
||||
}
|
||||
|
||||
// assign the outputs into the bridge
|
||||
{% if not fun.rtp|void %}
|
||||
outputs[0] = retval;
|
||||
{% endif %}
|
||||
{% for arg in fun.req|outputs %}
|
||||
outputs[{{loop.index0}}] = {{arg.name}};
|
||||
outputs[{{loop.index0 + fun.rtp|void|not}}] = {{arg.name}};
|
||||
{% endfor %}
|
||||
{% for opt in fun.opt|outputs %}
|
||||
outputs[{{loop.index0 + fun.req|noutputs}}] = {{opt.name}};
|
||||
outputs[{{loop.index0 + fun.rtp|void|not + fun.req|outputs|length}}] = {{opt.name}};
|
||||
{% endfor %}
|
||||
|
||||
{%- endmacro -%}
|
||||
|
@ -13,14 +13,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
#include <opencv2/{{ns}}.hpp>
|
||||
#include <opencv2/{{includes}}.hpp>
|
||||
{% block includes %}
|
||||
{% endblock %}
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
/*
|
||||
* {{ fun.name }}
|
||||
* {{ fun }}
|
||||
* Gateway routine
|
||||
* nlhs - number of return arguments
|
||||
* plhs - pointers to return arguments
|
||||
@ -31,15 +30,13 @@ void mexFunction(int nlhs, mxArray* plhs[],
|
||||
int nrhs, const mxArray* prhs[]) {
|
||||
|
||||
// assertions
|
||||
mxAssert(nrhs >= {{fun.req|length - fun.req|noutputs}}, "Too few required input arguments specified");
|
||||
mxAssert(nrhs <= {{fun.req|length + fun.opt|length - fun.req|noutputs - fun.opt|noutputs}}, "Too many input arguments specified");
|
||||
mxAssert(nlhs <= {{fun.ret|length + fun.req|noutputs + fun.opt|noutputs}}, "Too many output arguments specified");
|
||||
mxAssert(nrhs >= {{fun.req|length - fun.req|outputs|length}}, "Too few required input arguments specified");
|
||||
mxAssert(nrhs <= {{fun.req|length + fun.opt|length - fun.req|outputs|length - fun.opt|outputs|length}}, "Too many input arguments specified");
|
||||
mxAssert(nlhs <= {{ fun.rtp|void|not + fun.req|outputs|length + fun.opt|outputs|length}}, "Too many output arguments specified");
|
||||
|
||||
// setup
|
||||
vector<Bridge> inputs(plhs, plhs+nrhs);
|
||||
vector<Bridge> outputs(nlhs);
|
||||
|
||||
{{ fun }}
|
||||
std::vector<Bridge> inputs(plhs, plhs+nrhs);
|
||||
std::vector<Bridge> outputs(nlhs);
|
||||
|
||||
{{ functional.generate(fun) }}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user