How to throw an error when fprintf or disp is called?

I have a large library of impenetrable code that writes out really annoying linebreaks. I can't seem to find where they are for some weird reason. So I was thinking if I could make MATLAB throw an error whenever sprintf or disp is called, I could find them. Is there a way to do this?

I tried evalc but all it gives is the output itself not from where it was called.

Answers


dbstop in

Sure you can overload disp or fprintf, or you can just tell the debugger to stop at these functions with dbstop. Then use dbstack to see where you are and how you got there. It's OK that these are built-ins with no MATLAB code. It will stop right before the call:

>> dbstop in disp
Warning: MATLAB debugger can only stop in MATLAB code files, and "libmwbuiltins>disp" is not a MATLAB code file.
         Instead, the debugger will stop at the point right before "libmwbuiltins>disp" is called. 

>> dbstop in fprintf
Warning: MATLAB debugger can only stop in MATLAB code files, and "libmwbuiltins>fprintf" is not a MATLAB code file.
         Instead, the debugger will stop at the point right before "libmwbuiltins>fprintf" is called.

Looking good!

Consider the following test function testdbstop with a nested function fprintTest:

function testdbstop
x=1;
disp(x)
fprintTest(x)
    function fprintTest(x)
        fprintf('%d\n',x);
    end
end

Running it from the command line:

>> testdbstop
3   disp(x)
K>> dbstack
> In testdbstop at 3
K>> dbcont
     1
6           fprintf('%d\n',x);
K>> dbstack
> In testdbstop>fprintTest at 6
  In testdbstop at 4
K>> dbcont
1

There you have it -- disp is called on line 3 of testdbstop.m, and fprintf is called on line 6 of testdbstop.m in testdbstop>fprintTest called from line 4 of testdbstop.

Note: When you are done, remove the virtual breakpoints with dbclear (i.e. dbclear in disp and dbclear in fprintf).


I would not recommend to throw an error. For example disp is called by workspacefunc whenever you exit the debugger. Setting a breakpoint makes it easier, if you want an error replace the keyboard with an error.

function disp( varargin )
builtin('disp',varargin{:});
x=dbstack;
%it's nessecary to exclude all calls which come via workspacefunc,
%otherwise it's impossible to quit the debugger.
if numel(x)>2&&strcmpi(x(2).file,'workspacefunc.m')
    return;
end
keyboard;
end

Place this disp.m on top of your path, it will call the builtin, thus you see what was printed and stop afterwards. Do the same for fprint


What you can do is write your own disp() function (which could generate an error with the error() function), save it as disp.m in your current Matlab path. This will override the built in disp() & allow you to find where it is called.

Alternatively, you could open up all the files in your library in something like Notepad++ and search across all opened files for the term "disp("


Making fprintf throw an error is very easy since there are no overloaded methods for fprintf.

You can shadow the built-in fprintf by creating a new function called fprintf.m in your current directory (which is always highest in the Matlab path). The function should contain code like this:

function fprintf(varargin)
error('Error message to help find fprintf statements')

Now when you run the impenetrable code, you will get an error whenever fprintf is called.

If the impenetrable code changes directories, your new fprintf.m may not get called. In this case, I would place your custom fprintf.m code in a folder that is on the matlab path higher than Matlabs fprintf function. You can check that it is higher by giving this command at the command line:

which fprintf -all

Matlab's built-in function should be shadowed and yours should be on top. It should look something like this:

which fprintf -all C:\Users\MyName\Documents\MATLAB\fprintf.m C:\Program Files (x86)\MATLAB\R2009a\toolbox\matlab\iofun\@serial\fprintf.m % serial method built-in (C:\Program Files (x86)\MATLAB\R2009a\toolbox\matlab\iofun\fprintf) % Shadowed

Finding missing semicolons that are making variables is more difficult since there are many different disp methods.


Need Your Help

XML parser skipping duplicate values JAVA

java xml parsing xml-parsing

I've written an XML parser which parses an XML documents and returns me a Map of and ID and Name. For some reason it's skipping duplicates IDs.

Converting nvarchar(50) column to datetime in SQL CE 4.0

datetime database-design sql-server-ce webmatrix sql-server-ce-4

I'm new to SQL and have inherited a database which uses nvarchar(50) as the data type for the "Date" column. I want to convert this column into datetime format but I cannot figure out how to do so ...