function replace(va,wh,pa)
% REPLACE -- Replace defaut parameters with specified parameters.
%
% Use as follows:
% function out = foo(varargin)
% a = 1;
% b = 20;
% c = 300;
% d = 4000;
% param = {'b','d'};
% replace(varargin,who,param)
% OR
% replace(varagin,who);
%
% Then call FOO with parameters:
% out = foo('a',2) --> replaces default a=1 with new a=2
% out = foo('b',10,'c',100) --> likewise replaces b=10, c=100
% can also pass structures or specify functions returning structures.
% for other features see code
%
% Code written by SEAN CARVER, last modified Dec-5-2007
% va is the variable argument list
% wh is the who variable list (used for error checking)
% when get_value is FALSE (0) get name of parameter and put in variable "name"
% when get_value is TRUE (1) get value of parameter
% if don't pass wh make wh empty
if nargin == 1
wh = {};
end
get_value = 0; % get name of parameter not value
p = 0;
for i=1:length(va) % step through variable length argument
if get_value % if we must get value
assignin('caller',name,va{i}); % assign to name va{i} in caller's workspace
get_value = 0; % get name next time
elseif isa(va{i},'function_handle') % if name of parameter is a function ...
% ... handle not a string
newvars = va{i}(); % then evaluate function
nvnames = fieldnames(newvars); % should return structure, names of ...
% ... params are fieldnames of struct
% The code below steps through field names of structure
% checks that names are in wh structure and assigns values to the names
% in the caller's workspace.
for k = 1:length(nvnames)
if check_var(nvnames{k},wh)
assignin('caller',nvnames{k},newvars(1,1).(nvnames{k}));
else
error(['Replace error: Parameter ', nvnames{k},' not found']);
end
end
% Do same thing if name of parameter is a structure
elseif isstruct(va{i})
newvars = va{i}();
nvnames = fieldnames(newvars);
for k = 1:length(nvnames)
if check_var(nvnames{k},wh)
assignin('caller',nvnames{k},newvars(1,1).(nvnames{k}));
else
error(['Replace error: Parameter ', nvnames{k},' not found']);
end
end
% If name of parameter is numeric assign to names in pa argument
elseif isnumeric(va{i}) | p
p = p+1;
if p > length(pa)
error('Attempt to assign parameter to name unspecified by 3rd argument');
elseif check_var(pa{p},wh)
assignin('caller',pa{p},va{i});
else
error(['Replace error: Parameter ', pa{p},' not found']);
end
% If name is a string in wh struct interpret as name, set get_value true.
elseif isstr(va{i})
if check_var(va{i},wh)
get_value = 1;
name = va{i};
% if not in wh structure, see if its a filename
elseif exist(va{i},'file')
newvars = runscript(va{i});
nvnames = fieldnames(newvars);
for k = 1:length(nvnames)
if check_var(nvnames{k},wh)
assignin('caller',nvnames{k},newvars(1,1).(nvnames{k}));
else
error(['Replace error: Parameter ', nvnames{k},' not found']);
end
end
else
error(['Replace error: Parameter ', va{i},' not found']);
end
else
error('Replace: Unrecognized type for in argument list');
end
end
%%%%%%%%%%%%%%%%
function cv = check_var(var,wh)
% CHECK to see if var is in list wh;
cv = 0;
for i = 1:length(wh)
if strcmp(var,wh{i})
cv = 1;
break;
end
end
%%%%%%%%%%%%%%%%
function nv = runscript(TEMPSCRIPT)
% Run script and assemble
eval(TEMPSCRIPT);
clear TEMPSCRIPT
nv = assemble(who);