Last active
September 8, 2016 07:20
-
-
Save tdalon/28c27eed23630cf474d3f7834e703616 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function [opt, callstr] = plot_depfun(foo,varargin) | |
% PLOT_DEPFUN plots a call graph tree of the function dependencies | |
% SYNTAX | |
% plot_depfun(foo,varargin) | |
% | |
% Ignores MATLAB function in matlabroot and any function names given in varargin. | |
% Uses current file in MATLAB Editor as default if no argument is passed or first argument is empty. | |
% | |
% See also depfun, mydepfun, plot_subfun (file exchange ID 46070) | |
% Calls: plot_graph, mydepfun, EditorGetFile | |
% Source: FEX http://www.mathworks.com/matlabcentral/fileexchange/46080-plot-depfun | |
% Modified by Thierry Dalon: calls mydepfun, EditorGetFile | |
% Use current file in Editor as default | |
if nargin==0 || isempty(foo), | |
foo= EditorGetFile(); | |
end | |
opt.ignore = varargin; | |
opt.me = which(foo); | |
if isempty(opt.me); error('this file could not be found'); end | |
opt.me = sub_fileparts(opt.me); | |
opt = sub_deps(opt); | |
opt.us = sub_fileparts(opt.us); | |
opt.us.islocal = ismember(opt.us.fol,opt.me.fol); | |
sub_plot(opt); | |
if nargout==0 | |
clear opt; | |
elseif nargout>1 | |
callstr=sprintf('%s, ',opt.us.short{:}); | |
callstr=['Calls: ',callstr(1:end-2)]; | |
disp(callstr); | |
end | |
end | |
function out = sub_fileparts(foos) | |
if iscell(foos) | |
for i=1:numel(foos) | |
if ~exist(foos{i},'file') | |
disp(foos{i}); | |
error('this file does not exist'); | |
end | |
end | |
end | |
fols = regexprep(foos,'[^/|\\]+$',''); | |
%short name of each function, and the folder it occurs | |
short = regexp(foos,'[^/|\\]+$','match','once'); | |
short = regexprep(short,'\..+',''); | |
out.full = foos; | |
out.fol = fols; | |
out.short = short; | |
end | |
function opt = sub_deps(opt) | |
%find dependencies of opt.me | |
%uses recursive calls to depfun with -toponly | |
%calls builtin functions for speed | |
names = {opt.me.full}; %list of all files found (will grow) | |
done = false; %which files have been examined | |
from = []; %dependency - parent | |
to = []; %dependency - child | |
t = now; | |
while any(~done) | |
for i=find(~done) | |
new=mydepfun(names{i}); | |
keep = true(size(new)); | |
%catch any strange return sizes from other os/versions | |
if size(new,1)>1; new = new'; end | |
%remove self | |
keep(ismember(new,names{i})) = false; | |
%remove ignored : full filename | |
keep(ismember(new,opt.ignore)) = false; | |
%remove ignored : short filename | |
short = regexp(new,'[^/|\\]+$','match','once'); | |
keep(ismember(short,opt.ignore)) = false; | |
%remove ignored : short filename no extension | |
short = regexprep(short,'\..+',''); | |
keep(ismember(short,opt.ignore)) = false; | |
%reduce the set of new | |
new = new(keep); | |
%add to list of names any new that are not already in it | |
[I,I,I] = setxor(names,new); | |
names = [names new(I)]; %#ok<AGROW> | |
%rearrange I because apparently mac and pc do things differently | |
if size(I,1)>1; I = I'; end | |
%add to list of done | |
done = [done false(size(I))]; %#ok<AGROW> | |
done(i) = true; | |
%new dependencies | |
[newkid,newkid] = ismember(new,names); | |
newdad = repmat(i,size(newkid)); | |
from = [from newdad]; %#ok<AGROW> | |
to = [to newkid]; %#ok<AGROW> | |
%report every 10 seconds | |
if now-t>10; | |
t = now; | |
fprintf(1,'%d dependencies found so far',numel(names)); | |
end | |
end | |
end | |
%sort names | |
[names,order] = sort(names); | |
%sort from/to references to match new names order | |
[rev,rev] = sort(order); | |
from = rev(from); | |
to = rev(to); | |
%export results | |
opt.us = names; | |
opt.from = from; | |
opt.to = to; | |
end | |
function sub_plot(opt) | |
if isempty(opt.from); disp('this function has no dependencies'); return; end | |
cols = repmat('b',size(opt.us.short)); | |
cols(~opt.us.islocal) = 'r'; | |
plot_graph(opt.us.short,opt.from,opt.to,'-colour',cols); | |
end | |
%% DEVNOTES | |
%140329 added handling of functions with no dependencies | |
%150311 bugfix : was not ignoring function calls correctly if they didn't | |
% have an extension. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment