/*
    ####             #    #     # #
    #   #            #    #       #          The FreeWare C library for
    #   #  ##   ###  #  # #     # ###             RISC OS machines
    #   # #  # #     # #  #     # #  #   ___________________________________
    #   # ####  ###  ##   #     # #  #
    #   # #        # # #  #     # #  #    Please refer to the accompanying
    ####   ### ####  #  # ##### # ###    documentation for conditions of use
    ________________________________________________________________________

    File:    Debug.c.Debug
    Author:  Julian Smith
    Version: 0.00 (10 Jul 1995)
    Purpose: Core Debug things. This file's object file is LibFile-d into 
             every debugging library.
*/

#include <stdlib.h>
#include <ctype.h>

#include "Desk.BackTrace.h"
#include "Desk.Debug.h"
#include "Desk.Error2.h"

#include "Defs.h"


int	Desk_debug_level = 0;
/*
Programs can set this to 0-5, and Debug1_Printf statements will
come into effect.
*/






void	Desk_Debug__Assert( const char *expression, const char *sourcefile, int line)
{
Desk_Debug_Printf( 
	"Assertion '%s' failed at line %i of file '%s'.\n", 
	expression, line, sourcefile
	);

abort();
}


static const char*	debug__indentstring = "";

void	Desk_Debug_SetNestingIndentation( const char* indentstring)
	{
	debug__indentstring = indentstring;
	}

void	Desk_Debug__LineNestingPrefix( FILE* stream)
	{
	int	i;
	
	if (debug__indentstring[0]==0)	return;
	
	for ( i=Desk_BackTrace_GetNestingDepth(); i>0; i--)	{
		fputs( debug__indentstring, stream);
		}
	}


static int	Desk_Debug_DescribeFn( void* reference, const char* format, va_list va)
	{
	return Desk_Debug_VPrintf( format, va);
	Desk_UNUSED( reference);
	}


int	Desk_Debug_PrintfRef( void* reference, const char *format, ...)
	{
	va_list	va;
	int	i;
	va_start( va, format);
	i = Desk_Debug_VPrintf( format, va);
	va_end( va);
	return i;
	
	Desk_UNUSED( reference);
	}


void	Desk_Debug_DescribeError2( const struct Desk_error2_block* error)
	{
	Desk_Error2_VDescribe( Desk_Debug_DescribeFn, NULL, error);
	Desk_Debug_Printf( "\n");	/* error description isn't ended with \n	*/
	}



void	Desk_Debug_BackTrace( void)
	{
	Desk_BackTrace_OutputToFFunctionWithPrefix( Desk_Debug_PrintfRef, NULL, "");
	}



void	Desk_Debug_PrintMemory( void* start, int size)
	{
	int	i, j;
	const char*	old_indent = debug__indentstring;
	char*	mem_char;
	int*	mem_int;
	
	Desk_Debug_SetNestingIndentation( "");
	
	start = (void*) (((int) start) & (~3));
	mem_char	= (char*) start;
	mem_int		= (int*) start;
	
	Desk_Debug_Printf( "%i bytes of memory starting at 0x%p:\n", size, start);
	
	for ( i=0; i<size; i+=16)	{
		
		Desk_Debug_Printf( "%p : ", mem_char+i);
		
		for ( j=0; j<16; j+=4)	{
			Desk_Debug_Printf( "%02x%02x%02x%02x ", mem_char[i+j+3], mem_char[i+j+2], mem_char[i+j+1], mem_char[i+j+0]);
			}
		
		Desk_Debug_Printf( " : ");
		
		for ( j=0; j<16; j++)	{
			char	c = mem_char[ i+j];
			if ( isprint( c))	Desk_Debug_Printf( "%c", c);
			else			Desk_Debug_Printf( ".");
			}
		
		Desk_Debug_Printf( "\n");
		}
	
	Desk_Debug_SetNestingIndentation( old_indent);
	}
