Search code examples
matlabdebuggingdependencies

find all call to a function in matlab


Say you modified a function, changed how many parameter it accepts as input and how many it outputs; you've also modified its name for good measure.

Now you want to go and change all the calls to this function, because now the structure of the data is different, so every single call to this function will result in an error; how can you find a list of all the places where this function is called? This is sort of the inverse of depfun, which given a function it lists all the dependencies on file and other functions; I want a list of all the functions which depend on the function I input.

I looked into profile but the project is big and there isn't a unique entry point that touches each and every file, so it doesn't satisfy me

Thank in advance!


Solution

  • You can use the semi-documented function getcallinfo.

    Simple example

    Say you want to see in which lines the function spiral calls the function ceil:

    h = getcallinfo('spiral.m');
    h.calls.fcnCalls.lines(strcmp(h.calls.fcnCalls.names,'ceil'))
    

    gives

    ans =
         9    10
    

    General case

    Since you want to do that for a whole project, you could loop over all M-files in the folder. Also, getcallinfo apparently returns an array of structs, where each element of the array refers to a different type of call: from the main function in the file, from subfunctions in that file, etc. So you need to loop over that too. (This didn't happen in the example above because spiral doesn't have any subfunctions.)

    So you could proceed along these lines:

    fn = 'disp'; % function you want track down
    pp = 'path\to\folder'; % project path
    d = dir([pp filesep '*.m']); % list M-files in folder. Not recursive
    for k = 1:numel(d);
       file = d(k).name;
       h = getcallinfo(file);
       for n = 1:numel(h) % distinguish calls from subfunctions etc
          name = h(n).functionPrefix;
          lines = h(n).calls.fcnCalls.lines(strcmp(h(n).calls.fcnCalls.names, fn));
          if lines
             disp(['Function ' fn ' is called by function ' name ' at lines ' num2str(lines)])
          end
       end
    end
    

    Here's a sample output from a project of mine:

    Function disp is called by function matl> at lines 190  198  199  232  257  269  280
    Function disp is called by function matl_compile> at lines 32
    Function disp is called by function matl_disp> at lines 77  79  81  83
    Function disp is called by function matl_help> at lines 10  57  67  69  71  72  74  77
    

    I have checked some of the lines and the results are correct. (You can check yourself here).