# -*- coding: iso-8859-1 -*-
"""Debug functions 

Copyright © 2005-2012, Anders Andersen, University of Tromsų, Norway.
See http://www.cs.uit.no/~aa/dist/tools/noop/COPYING (../COPYING) for
details.


Provides the `debugmsg()` function that is used to print debug
information.  Use the `debugit()` function to set the deblug flag for
this function.  If the debug flag is not set the `debugmsg()` function
calls will not produce any output.

"""


# CVS/RCS information

__file__    = r"$RCSfile: debug.py,v $"
__version__ = r"$Revision: 1.18 $"
__date__    = r"$Date: 2012-10-09 16:48:28 $"
__state__   = r"$State: Exp $"
__author__  = r"$Author: aa $"

__log__     = r"""

$Log: debug.py,v $
Revision 1.18  2012-10-09 16:48:28  aa
Added better comments and better support for modules.

Revision 1.17  2012-10-09 09:54:04  aa
Added "showmodule" flag to debug messages.

Revision 1.16  2012-10-08 20:26:32  aa
Corrected module document string.

Revision 1.15  2012-10-08 20:25:01  aa
Added copyright notice.

Revision 1.14  2005-03-22 17:18:31  aa
Added copyright notice.

Revision 1.13  2005/03/21 14:16:07  aa
Corrected obj error.

Revision 1.12  2005/03/21 14:11:12  aa
Added argument description and removed unused prefix argument.

Revision 1.11  2005/03/20 16:33:22  aa
Changed the name of the rcs/cvs info variables (to __var__ style).

Revision 1.10  2005/03/14 12:46:06  aa
Minor updates in comments.

Revision 1.9  2005/03/14 11:00:37  aa
Minor.

Revision 1.8  2005/03/14 10:26:20  aa
Minor simplification of implementation.

Revision 1.7  2005/03/14 10:21:42  aa
Added an else inside 'if obj'.

Revision 1.6  2005/03/14 10:13:36  aa
Major rewrite: debugmsg and debugit.

Revision 1.5  2005/03/14 09:29:37  aa
Corrected debug test (it was inversed).

Revision 1.4  2005/03/14 09:25:06  aa
Corrected arguments to mdebug.

Revision 1.3  2005/03/14 09:21:31  aa
Check for debug flag.

Revision 1.2  2005/03/12 16:25:23  aa
Corrected typo (missing '.').

Revision 1.1  2005/03/12 16:23:10  aa
Created the debug module.


"""


# Standard libraries
from types import *
import sys


# Where are debug messages printed
stddebug = sys.stderr


def debugit(obj, showmodule=False):
    """Set the debug flag

    Add a debug attribute with the value true to the object (method or
    function). If `showmodule` is true the module name is shown in the
    debug messages.

    obj -- the object to debug
    showmodule -- show module name in debug messages

    """
    obj.__dict__["__debug__"] = {}
    obj.__debug__["on"] = True
    obj.__debug__["showmodule"] = showmodule
    

def debugmsg(msg, obj=None):
    """Debug message in a function

    Prints a debug message in a function, a method or a
    module. Inlcudes information about the function/method.

    msg -- the message string to print
    obj -- the object (function, method) related to the message

    """

    # Used to put message in context (if we can dig it up)
    pre = ""

    # Add prefix (module, class and method/function info)
    if obj:

        # Only print debug information if the debug flag of the object is set
        try:
            if not obj.__debug__:
                return
        except AttributeError:
            return

        # Include module in message?
        if obj.__debug__["showmodule"]:
            if hasattr(obj, "__module__"):
                pre += obj.__module__ + "."

        # Recognize different types (what about 'generator' and 'type'?)
        if hasattr(obj, "__class__"):

            # A method of an object
            if obj.__class__.__name__ == 'method':
                pre += obj.__self__.__class__.__name__ + "." + \
                    obj.__name__ + ": "

            # A class method of a class
            elif obj.__class__.__name__ == 'classmethod':
                pre += obj.__func__.__self__.__class__.__name__ + "." + \
                    obj.__name__ + ": "

            # A stand alone function or a module
            elif obj.__class__.__name__ in ['function', 'module']:
                pre += obj.__name__ + ": "

        # Others (never used)?
        elif hasattr(obj, "__name__"):
            pre += obj.__name__ + ": "

    # Print debug message
    stddebug.write(pre + msg + "\n");
    stddebug.flush()
