<html><!-- Created using the cpp_pretty_printer from the dlib C++ library.  See http://dlib.net for updates. --><head><title>dlib C++ Library - stack_trace.h</title></head><body bgcolor='white'><pre>
<font color='#009900'>// Copyright (C) 2008  Davis E. King (davis@dlib.net)
</font><font color='#009900'>// License: Boost Software License   See LICENSE.txt for the full license.
</font><font color='#0000FF'>#ifndef</font> DLIB_STACK_TRACe_
<font color='#0000FF'>#define</font> DLIB_STACK_TRACe_

<font color='#009900'>/*!
    This file defines 3 things.  Two of them are preprocessor macros that
    enable you to tag functions with the dlib stack trace watcher.  The
    third thing is a function named get_stack_trace() which returns the
    current stack trace in std::string form.

    To enable the stack trace you must #define DLIB_ENABLE_STACK_TRACE.
    When this #define isn't set then the 3 things described above
    still exist but they don't do anything.

    Also note that when the stack trace is enabled it changes the DLIB_ASSERT
    and DLIB_CASSERT macros so that they print stack traces when 
    an assert fails.

    See the following example program for details:

    #include &lt;iostream&gt;
    #include &lt;dlib/stack_trace.h&gt;

    void funct2()
    {
        // put this macro at the top of each function you would
        // like to appear in stack traces
        DLIB_STACK_TRACE;

        // you may print the current stack trace as follows. 
        std::cout &lt;&lt; dlib::get_stack_trace() &lt;&lt; endl;
    }

    void funct()
    {
        // This alternate form of DLIB_STACK_TRACE allows you to specify
        // the string used to name the current function.  The other form
        // will usually output an appropriate function name automatically
        // so this may not be needed.
        DLIB_STACK_TRACE_NAMED("funct");
        funct2();
    }

    int main()
    {
        funct();
    }
!*/</font>


<font color='#0000FF'>#include</font> <font color='#5555FF'>&lt;</font>string<font color='#5555FF'>&gt;</font>
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='assert.h.html'>assert.h</a>"

<font color='#009900'>// only setup the stack trace stuff if the asserts are enabled (which happens in debug mode
</font><font color='#009900'>// basically).  Also, this stuff doesn't work if you use NO_MAKEFILE
</font><font color='#0000FF'>#if</font> defined<font face='Lucida Console'>(</font>DLIB_ENABLE_STACK_TRACE<font face='Lucida Console'>)</font> 
<font color='#0000FF'>#ifdef</font> NO_MAKEFILE 
<font color='#0000FF'>#error</font> "<font color='#CC0000'>You can't use the dlib stack trace stuff and NO_MAKEFILE at the same time</font>"
<font color='#0000FF'>#endif</font>

<font color='#0000FF'>namespace</font> dlib
<b>{</b>
    <font color='#0000FF'>const</font> std::string <b><a name='get_stack_trace'></a>get_stack_trace</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
<b>}</b>

<font color='#009900'>// redefine the DLIB_CASSERT macro to include the stack trace
</font><font color='#0000FF'>#undef</font> DLIBM_CASSERT
<font color='#0000FF'>#define</font> DLIBM_CASSERT<font face='Lucida Console'>(</font>_exp,_message<font face='Lucida Console'>)</font>                                              \
    <b>{</b><font color='#0000FF'>if</font> <font face='Lucida Console'>(</font> <font color='#5555FF'>!</font><font face='Lucida Console'>(</font>_exp<font face='Lucida Console'>)</font> <font face='Lucida Console'>)</font>                                                         \
    <b>{</b>                                                                       \
        std::ostringstream dlib_o_out;                                       \
        dlib_o_out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\nError occurred at line </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> __LINE__ <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>.\n</font>";    \
        dlib_o_out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>Error occurred in file </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> __FILE__ <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>.\n</font>";      \
        dlib_o_out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>Error occurred in function </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> DLIB_FUNCTION_NAME <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>.\n\n</font>";      \
        dlib_o_out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>Failing expression was </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> #_exp <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>.\n</font>";           \
        dlib_o_out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> _message <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\n</font>";                                      \
        dlib_o_out <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>Stack Trace: \n</font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> dlib::<font color='#BB00BB'>get_stack_trace</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n</font>";        \
        <font color='#BB00BB'>dlib_assert_breakpoint</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;                                           \
        <font color='#0000FF'>throw</font> dlib::<font color='#BB00BB'>fatal_error</font><font face='Lucida Console'>(</font>dlib::EBROKEN_ASSERT,dlib_o_out.<font color='#BB00BB'>str</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;      \
    <b>}</b><b>}</b>                                                                      



<font color='#0000FF'>namespace</font> dlib
<b>{</b>

    <font color='#0000FF'>class</font> <b><a name='stack_tracer'></a>stack_tracer</b>
    <b>{</b>
    <font color='#0000FF'>public</font>:
        <b><a name='stack_tracer'></a>stack_tracer</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font> funct_name,
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>char</u></font><font color='#5555FF'>*</font> file_name,
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>int</u></font> line_number
        <font face='Lucida Console'>)</font>;

        ~<b><a name='stack_tracer'></a>stack_tracer</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;

    <b>}</b>;
<b>}</b>

<font color='#0000FF'>#define</font> DLIB_STACK_TRACE_NAMED<font face='Lucida Console'>(</font>x<font face='Lucida Console'>)</font> dlib::stack_tracer dlib_stack_tracer_object<font face='Lucida Console'>(</font>x,__FILE__,__LINE__<font face='Lucida Console'>)</font>
<font color='#0000FF'>#define</font> DLIB_STACK_TRACE dlib::stack_tracer dlib_stack_tracer_object<font face='Lucida Console'>(</font>DLIB_FUNCTION_NAME,__FILE__,__LINE__<font face='Lucida Console'>)</font>

<font color='#0000FF'>#else</font> <font color='#009900'>// don't do anything if ENABLE_ASSERTS isn't defined
</font><font color='#0000FF'>#define</font> DLIB_STACK_TRACE_NAMED<font face='Lucida Console'>(</font>x<font face='Lucida Console'>)</font> 
<font color='#0000FF'>#define</font> DLIB_STACK_TRACE 

<font color='#0000FF'>namespace</font> dlib
<b>{</b>
    <font color='#0000FF'>inline</font> <font color='#0000FF'>const</font> std::string <b><a name='get_stack_trace'></a>get_stack_trace</b><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <b>{</b> <font color='#0000FF'>return</font> std::<font color='#BB00BB'>string</font><font face='Lucida Console'>(</font>"<font color='#CC0000'>stack trace not enabled</font>"<font face='Lucida Console'>)</font>;<b>}</b>
<b>}</b>

<font color='#0000FF'>#endif</font>


<font color='#0000FF'>#endif</font> <font color='#009900'>// DLIB_STACK_TRACe_
</font>

</pre></body></html>