gusucode.com > symbolic工具箱matlab源码程序 > symbolic/@sym/matlabFunctionBlock.m
function matlabFunctionBlock(block,varargin) %matlabFunctionBlock Generate MATLAB Function block % matlabFunctionBlock(BLOCK,F) generates a 'MATLAB Function' block % with path BLOCK and sets the block definition to the MATLAB % code generated from F using matlabFunction. If BLOCK exists % it must be a MATLAB Function block and the existing block definition is % replaced with F. % % matlabFunctionBlock(BLOCK,F1,F2,...,FN) generates a block with N outputs F1 % through FN. The inputs and outputs of the block are the same as the % inputs and outputs of the MATLAB function in the block definition. % % matlabFunctionBlock(...,PARAM1,VALUE1,...) uses the specified parameter/value % pairs to change the generated block. The parameters customize the % function declaration that appears in the generated code. The template % for the generated code is % function [OUT1, OUT2,..., OUTN] = NAME(IN1, IN2, ... INM) % The parameter names can be any of the following % % 'FunctionName': the value, NAME, must be a string. The default is the name % of the block BLOCK. % % 'Outputs': The value must be a cell array of N strings specifying the output % variable names OUT1, OUT2,... OUTN in the function template. The % default output variable name for OUTk is the variable name of Fk, % or 'outk' if Fk is not a simple variable. % % With one exception matlabFunctionBlock accept all name-value pairs which are accepted % by matlabFunction. The exeption is the 'File' option. This option is not accepted % by matlabFunctionBlock. % % Note: not all MuPAD expressions can be converted to a MATLAB function. % For example sets will not be converted. % % Example: % syms x y % f = x^2 + y^2; % new_system('mysys'); open_system('mysys'); % matlabFunctionBlock('mysys/f',f); % % See also: matlabFunction, simulink % Copyright 2008-2015 The MathWorks, Inc. narginchk(2,inf); % process inputs N = getSyms(varargin); funs = varargin(1:N); funs = cellfun(@(f)sym(f),funs,'UniformOutput',false); args = varargin(N+1:end); funnames = cell(1,N); for k = 1:N funnames{k} = inputname(1+k); end [opts, argsToForward] = getOptions(args,funnames); if isempty(ver('Simulink')) error(message('symbolic:sym:matlabFunctionBlock:SimulinkRequired')); end b = getBlock(block); tempfile_no_extension = tempname; [~,fname] = fileparts(tempfile_no_extension); file = [tempfile_no_extension '.m']; funcname = opts.FunctionName; if isempty(funcname) funcname = b.Name; end opts = rmfield(opts,'FunctionName'); matlabFunction(funs{:},opts,argsToForward,'File',file); tmp = onCleanup(@()delete(file)); fid = fopen(file,'rt'); if fid > 0 tmp2 = onCleanup(@()fclose(fid)); contents = getContents(fid, fname, funcname); clear tmp2; % close file b.Script = contents; else error(message('symbolic:sym:matlabFunctionBlock:FileOpen', file)); end % find the index separating the functions from the option/value pairs % return the last index of the functions, or 0 if none function N = getSyms(args) chars = cellfun(@ischar,args); N = find(chars,1,'first'); if isempty(N) N = length(args); else N = N-1; end % validator for 'FunctionName' parameter function t = isFunc(x) [~,file] = fileparts(x); t = isvarname(file); % parse inputs and return option structure output function [opts, argsToForward] = getOptions(args,funnames) ip = inputParser; ip.addParameter('FunctionName','',@isFunc); ip.addParameter('Outputs',{},@iscellstr); ip.addParameter('File',''); %We want to disallow this so we catch it separately ip.addParameter('Sparse',false); %We want to disallow this so we catch it separately ip.KeepUnmatched = true; ip.parse(args{:}); if ~ismember('File',ip.UsingDefaults) error(message('symbolic:sym:matlabFunctionBlock:InvalidOptionFile')); end if ~ismember('Sparse',ip.UsingDefaults) error(message('symbolic:sym:matlabFunctionBlock:InvalidOptionSparse')); end opts = ip.Results; argsToForward = ip.Unmatched; if isempty(opts.Outputs) outputs = funnames; for k = 1:length(outputs) if isempty(outputs{k}) outputs{k} = sprintf('out%d',k); end end opts.Outputs = outputs; end % find or create block function b = getBlock(block) r = slroot; b = r.find('-isa','Stateflow.EMChart','path',block); if isempty(b) load_system('simulink'); add_block('simulink/User-Defined Functions/MATLAB Function',block); b = r.find('-isa','Stateflow.EMChart','path',block); if isempty(b) error(message('symbolic:sym:matlabFunctionBlock:CouldNotCreate', block)); end end if size(b) > 1 error(message('symbolic:sym:matlabFunctionBlock:AmbiguousBlock', block)); end if ~isa(b,'Stateflow.EMChart') error(message('symbolic:sym:matlabFunctionBlock:InvalidBlock', block)); end % get the contents of the generated file and format for MATLAB Function content function contents = getContents(fid, fname, funcname) s = fgets(fid); contents = [sprintf('%s%s\n', strrep(s,fname,funcname),'%#codegen') skipComments(fid)]; s = fread(fid,'*char'); contents = [contents s.']; function s = skipComments(fid) s = fgets(fid); while ischar(s) && ~isempty(s) && s(1) == '%' s = fgets(fid); end