function blocks = find_signal(sys,signame,direction,varargin)
% find_signal - Finds blocks with a named input or output signal.
%
% Returns blocks in the specified block diagram or subsystem whose
% InputSignalNames or OutputSignalNames parameter include the specified
% string, indicating that a signal with the specified name is an input
% or output to that block.
%
% blocks = find_signal(sys,signame,direction,...)
%
% "sys" is a block diagram of subsystem name or handle, exactly as would be
% supplied to find_system.
% "signame" is the name of the signal for which to search.
% "direction" is a string: either "in" or "out". If "in", blocks whose
% "InputSignalNames" parameter includes signame will be returned. If "out",
% blocks whose "OutputSignalNames" parameter includes signame will be
% returned.
% additional arguments are passed to find_system. These should be
% parameter name-value pairs, or special find_system options (e.g.
% LookUnderMasks, FollowLinks, etc.). Special find_system options must
% appear before any parameter name-value pairs.
%
% "blocks" is a cell array of strings giving the names of blocks which meet
% the specified criteria.
%
% Examples:
% blocks = find_signal('sldemo_fuelsys','Throttle','in')
% blocks = find_signal('sldemo_fuelsys','Throttle','out','LookUnderMasks','on')
%
% See also: find_system, get_param
%
% Copyright 2009 The MathWorks, Inc.
if ~ischar(direction)
error('find_signal:BadInput','direction must a string');
end
if strcmp(direction,'in')
is_input = true;
elseif strcmp(direction,'out')
is_input = false;
else
error('find_signal:BadInput','direction must be ''in'' or ''out''');
end
% Special block parameter which returns a cell array of strings.
if is_input
paramname = 'InputSignalNames';
else
paramname = 'OutputSignalNames';
end
if ~ischar(signame)
error('find_signal:BadInput','signame must be a string');
end
if nargin<4 && ~iscellstr(varargin)
error('find_signal:BadInput','Additional arguments must be strings');
end
% Find all blocks matching the input requirements.
% varargin can contain "special" find_system options, as well as parameter
% name-value pairs. So it needs to go *before* the Type=block restriction.
allblocks = find_system(sys,varargin{:},'Type','block');
if isempty(allblocks)
blocks = {};
return;
end
% Find the signal names for these blocks.
sigs = get_param(allblocks,paramname);
if numel(allblocks)==1
sigs = {sigs};
end
% Identify the blocks which have this signal name.
has_signal = false(size(allblocks));
for i=1:numel(sigs)
has_signal(i) = ismember(signame,sigs{i});
end
% Return only the blocks which have this signal name.
blocks = allblocks(has_signal);