% gcoll
% gcoll vpat1 -ws -opt1 vpat2 ... -opt2 ...
% s = gcoll;
% s = gcoll('vpat1 -ws -opt1 vpat2 ... -opt2 ...');
% s = gcoll('vpat1 ...','-ws -opt1 ...','vpat2 -opt2 ...','...');
%
% garbage-collects workspace variables into
% output-structure <s> of the form:
% sout.varname1 = contents_of_var1
% sout.varnameN = contents_of_varN
%
% vpat: pattern to select var [def: all]
% see: help whos
% -ws : workspace id
% -base [def]
% -caller
% -opt: option flag (can be concatenated)
% -k keep clear var EXCEPT those selected
% -x clear! var in ws AFTER collection [def: keep var]
% -q do NOT display progress [def: show processing]
%
% examples
% % use base variables
% clear all;
% a=rand([128 64 3]);
% bb=1;
% ccc='foo';
% v=gcoll
% % collect> 1: a C:double B:196608 S:128x64x3
% % collect> 2: bb C:double B: 8 S:1x1
% % collect> 3: ccc C:char B: 6 S:1x3
% % garbage collected --------------------------------
% % nr items: 3
% % nr bytes: 196622
% % v = a: [128x64x3 double]
% % bb: 1
% % ccc: 'foo'
% v=gcoll('c* -x')
% % collect.clear> 1: ccc C:char B:6 S:1x3
% % garbage collected --------------------------
% % nr items: 1
% % nr bytes: 6
% % v = ccc: 'foo'
% %--------------------------------------------------------------
% % call from within a function <foo.m>
% % function foo(varargin)
% % x=rand(1024);
% % m=gcoll('-caller');
% % run-time
% % foo(1,2,3)
% % collect> 1: varargin C:cell B: 204 S:1x3
% % collect> 2: x C:double B:8388608 S:1024x1024
% % garbage collected ---------------------------------------
% % nr items: 2
% % nr bytes: 8388812
% % m = varargin: {[1] [2] [3]}
% % x: [1024x1024 double]
% created:
% us 12-Jan-2001
% modified:
% us 01-Oct-2003 17:55:17 / TMW
function sout=gcoll(varargin)
% check input
s=get_collector;
if nargout
sout=s;
end
% parse command line(s)
[mod,ws,flg]=get_com(varargin{:});
% create a valid <whos> command
com=get_mod(mod);
% evaluate
v=evalin(ws,com);
% prepare collection and output
nb=0;
sl=12;
vl=size(v,1);
if vl
% compute dynamic formatting
vl=ceil(log10(vl+1))+2;
c=struct2cell(v);
nl=cellfun('length',c(1,:));
nl=max(nl);
cl=cellfun('length',c(4,:));
cl=max(cl);
bl=max([1 c{3,:}]);
bl=ceil(log10(bl)+1)-1;
fmt1=sprintf('%%%dd: %%%d.%ds C:%%-%d.%ds B:%%%dd S:%%s',...
vl,nl,nl,cl,cl,bl);
% collect GARBAGE
for i=1:size(v,1);
vn=v(i).name;
nb=nb+v(i).bytes;
ns=sprintf('%dx',v(i).size);
var=evalin(ws,vn);
com=sprintf('s.%s=var;',vn);
eval(com);
txt=sprintf(['collect> ' fmt1],...
i,vn,v(i).class,v(i).bytes,ns(1:end-1));
if flg.k
txt=strrep(txt,'collect>','collect.keep>');
end
if flg.x
txt=strrep(txt,'collect>','collect.clear>');
evalin(ws,['clear ' vn]);
end
if flg.q
txt=[];
end
disp(txt);
sl=max(sl,length(txt));
end
end
% recover vars to keep
if flg.k
evalin(ws,'clear variables');
if ~isempty(s)
fn=fieldnames(s);
% first field is collector's ID!
for i=2:length(fn)
assignin(ws,fn{i},s.(fn{i}));
end
end
end
% ... and show results
if ~flg.q
str='garbage collected ';
sl=max(12,sl-length(str));
str=[str repmat('-',1,sl) '\n'];
str=[str 'nr items: %d\n'];
str=[str 'nr bytes: %d'];
disp(sprintf(str,size(v,1),nb));
end
if nargout
sout=s;
end
return;
%--------------------------------------------------------------------------------
function s=get_collector
% create an almost unique struct identifier
r=rand('state');
n=rand;
rand('state',r);
rand;
c=fix(clock);
fn=sprintf('%4.4d',c(1));
fn=[fn sprintf('%2.2d',c(2:end))];
fn=[fn sprintf('_%4.4d',fix(1000*n))];
s.(['g_' fn])=['ID ' datestr(c)];
%--------------------------------------------------------------------------------
function com=get_mod(mod)
tmpl=',;/+-=';
% create args for <whos>
if isempty(mod)
com='whos';
return;
else
com='whos(';
end
ix=ismember(mod,tmpl);
mod(ix)=' ';
suff=mod;
while ~isempty(suff)
[var,suff]=strtok(suff);
com=sprintf('%s''%s'',',com,var);
end
com(end)=')';
return;
%--------------------------------------------------------------------------------
function [mod,ws,flg]=get_com(varargin)
% options
key={
% option alt proc def proc
%---------------------------------------------------------------------
'-base' 'ws=''base'';' 'ws=''base'';'
'-caller' 'ws=''caller'';' 'ws=''base'';'
'-file' 'flg.e=1;' 'flg.e=0;'
'global' 'flg.e=2;' ';'
'-k' 'flg.k=1;' 'flg.k=0;'
'-q' 'flg.q=1;' 'flg.q=0;'
'-x' 'flg.x=1;' 'flg.x=0;'
};
% def parameters
flg=[];
mod='';
com='';
% process command line argument(s)
if nargin
for i=1:nargin
if ischar(varargin{i})
com=[com char(varargin{i}) ' '];
end
end
com=strread(com,'%s');
end
% recover ws/option flags
for i=1:size(key,1)
eval(key{i,3}); % def proc mode
ix=strmatch(key{i,1},com,'exact');
if ~isempty(ix)
com(ix,:)='';
eval(key{i,2}); % alt proc mode
end
end
switch flg.e
case 1
error('gcoll cannot work on files');
case 2
error('gcoll cannot collect <globals>');
end
com=char(com);
if ~isempty(com)
com=[com repmat(' ',size(com,1),1)];
com=reshape(com.',[],1).';
end
mod=deblank(com);
return;
%--------------------------------------------------------------------------------