/*
    GSK - a library to write servers
    Copyright (C) 1999-2000 Dave Benson, Paul Mineiro.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA

    Contact:
        daveb@ffem.org <Dave Benson>
        pmineiro@ffe.org <Paul Mineiro>
*/

#ifndef __GSK_DEBUG_H_
#define __GSK_DEBUG_H_

#ifdef GSK_DEBUG

#if HAVE_DMALLOC
/* unsupported */
/* XXX: delete this?!? */
#define USE_DMALLOC 
#include <dmalloc.h>
#define CALLOC(type, count) calloc(count, sizeof(type))
#define ALLOC(type, count) malloc(count * sizeof(type))
#define REALLOC(mem, type, count) realloc(mem, count * sizeof(type))
#define FREE(mem) free(mem)
#endif

#include <glib.h>

/* These macros are quite visually annoying;
 * add lots of whitespace so none of the viewers convulse ;)
 */

#define            g_array_new(a,b,c)                           	\
         gsk_debug_g_array_new(__FILE__, __LINE__, a,b,c)


#define            g_array_free(a,b)                            	\
         gsk_debug_g_array_free(a, b)


#define            g_hash_table_new(a,b)                        	\
         gsk_debug_g_hash_table_new(__FILE__,__LINE__,a,b)


#define            g_hash_table_destroy(g)                      	\
         gsk_debug_g_hash_table_destroy(g)


#define            g_ptr_array_new()                            	\
         gsk_debug_g_ptr_array_new(__FILE__,__LINE__)


#define            g_ptr_array_free(array, free)                	\
         gsk_debug_g_ptr_array_free(array, free)


#define            g_byte_array_new()                           	\
         gsk_debug_g_byte_array_new(__FILE__,__LINE__)


#define            g_byte_array_free(array, free)               	\
         gsk_debug_g_byte_array_free(array, free)


#define            g_string_new(init)                           	\
         gsk_debug_g_string_new(__FILE__,__LINE__,init)


#define            g_string_sized_new(size)                     	\
         gsk_debug_g_string_sized_new(__FILE__,__LINE__,size)


#define            g_string_free(array, free)                   	\
         gsk_debug_g_string_free(array, free)


#define            g_free                                       	\
         gsk_debug_g_free


#define            g_malloc(size)                               	\
         gsk_debug_g_malloc(__FILE__,__LINE__,size)


#define            g_malloc0(size)                              	\
         gsk_debug_g_malloc0(__FILE__,__LINE__,size)


#define            g_realloc(mem, size)                         	\
         gsk_debug_g_realloc(__FILE__,__LINE__,mem,size)


#define            g_strdup(str)                                	\
         gsk_debug_g_strdup(__FILE__,__LINE__,str)


#define            g_strdup_printf(format,args...)              	\
         gsk_debug_g_strdup_printf(__FILE__,__LINE__,format,##args)


#define            g_strdup_vprintf(format,args)                	\
         gsk_debug_g_strdup_vprintf(__FILE__,__LINE__,format,args)


#define            g_strndup(str, n)                            	\
         gsk_debug_g_strndup(__FILE__,__LINE__,str,n)


#define            g_strnfill(length, fill_char)                	\
         gsk_debug_g_strnfill(__FILE__,__LINE__,length,fill_char)


#define            g_strconcat(args...)                         	\
         gsk_debug_g_strconcat(__FILE__,__LINE__,##args)


#define            g_strjoin(args...)                           	\
         gsk_debug_g_strjoin(__FILE__,__LINE__,##args)


#define            g_strescape(string)                          	\
         gsk_debug_g_strescape(__FILE__,__LINE__,string)


#define            g_memdup(mem, byte_size)                     	\
         gsk_debug_g_memdup(__FILE__,__LINE__,mem,byte_size) 


#define            g_strsplit(string,delim,max)                 	\
         gsk_debug_g_strsplit(__FILE__,__LINE__,                	\
                              string,delim,max)

#define            g_strjoinv(sep,str_array)                    	\
         gsk_debug_g_strjoinv(__FILE__,__LINE__,sep,str_array)


#define            g_strfreev                                   	\
         gsk_debug_g_strfreev

#define            g_string_chunk_new(size)                             \
         gsk_debug_g_string_chunk_new(__FILE__, __LINE__, size)

#define            g_string_chunk_free(chunk)                           \
         gsk_debug_g_string_chunk_free(chunk)

gpointer     gsk_debug_g_malloc                   (const char   *fname,
                                                   int           lineno,
                                                   gulong        size);
gpointer     gsk_debug_g_malloc0                  (const char   *fname,
                                                   int           lineno,
                                                   gulong        size);
gpointer     gsk_debug_g_realloc                  (const char   *fname,
                                                   int           lineno,
                                                   gpointer      mem,
                                                   gulong        size);
void         gsk_debug_g_free                     (gpointer      mem);
                                                               
GArray      *gsk_debug_g_array_new                (const char   *fname,
                                                   int           lineno,
                                                   gboolean     zero_terminated,
                                                   gboolean      clear,
                                                   guint         element_size);
void         gsk_debug_g_array_free               (GArray       *array,
                                                   gboolean      free_segment);
GHashTable  *gsk_debug_g_hash_table_new           (const char   *fname,
                                                   int           lineno,
                                                   GHashFunc     hash_func,
                                                   GCompareFunc  key_comp_func);
void         gsk_debug_g_hash_table_destroy       (GHashTable   *hash_table);
GByteArray  *gsk_debug_g_byte_array_new           (const char   *fname,
                                                   int           lineno);
void         gsk_debug_g_byte_array_free          (GByteArray   *array,
                                                   gboolean      free_seg);
GPtrArray   *gsk_debug_g_ptr_array_new            (const char   *fname,
                                                   int           lineno);
void         gsk_debug_g_ptr_array_free           (GPtrArray    *array,
                                                   gboolean      free_seg);
GString     *gsk_debug_g_string_new               (const char   *fname,
                                                   int           lineno,
                                                   const gchar  *init);
GString     *gsk_debug_g_string_sized_new         (const char   *fname,
                                                   int           lineno,
                                                   guint         size);
void         gsk_debug_g_string_free              (GString      *string,
                                                   gboolean      free_segment);
                                                               
gchar       *gsk_debug_g_strdup                   (const char   *fname,
                                                   int           lineno,
                                                   const gchar  *str);
                                                               
gchar       *gsk_debug_g_strdup_printf            (const char   *fname,
                                                   int           lineno,
                                                   const gchar  *format,
                                                   ...) G_GNUC_PRINTF(3, 4);
                                                               
gchar       *gsk_debug_g_strdup_vprintf           (const char   *fname,
                                                   int           lineno,
                                                   const gchar  *format,
                                                   va_list       args);
                                                               
gchar       *gsk_debug_g_strndup                  (const char   *fname,
                                                   int           lineno,
                                                   const gchar  *str,
                                                   guint         n);
                                                               
gchar       *gsk_debug_g_strnfill                 (const char   *fname,
                                                   int           lineno,
                                                   guint         length,
                                                   gchar         fill_char);
                                                               
gchar       *gsk_debug_g_strconcat                (const char   *fname, 
                                                   int           lineno,
                                                   const gchar  *string1,
                                                   ...);       

gchar       *gsk_debug_g_strjoin                  (const char   *fname,
                                                   int           lineno,
                                                   const gchar  *separator,
                                                   ...);       
                                                               
gchar       *gsk_debug_g_strescape                (const char   *fname,
                                                   int           lineno,
                                                   gchar        *string);
                                                               
gpointer     gsk_debug_g_memdup                   (const char   *fname, 
                                                   int           lineno, 
                                                   gconstpointer mem, 
                                                   guint         byte_size);
                                                               
gchar      **gsk_debug_g_strsplit                 (const char   *fname,
                                                   int           lineno,
                                                   const gchar  *string,
                                                   const gchar  *delim,
                                                   guint         max);
                                                               
gchar       *gsk_debug_g_strjoinv                 (const char   *fname,
                                                   int           lineno,
                                                   const gchar  *separator,
                                                   gchar       **str_array);

void         gsk_debug_g_strfreev                 (gchar       **str_array);

GStringChunk *
             gsk_debug_g_string_chunk_new         (const char   *fname,
                                                   int           lineno,
                                                   gint          size);

void         gsk_debug_g_string_chunk_free        (GStringChunk *chunk);

/* Interface to the debugging functions. */
void         gsk_debug_dump                       ();

void         gsk_debug_track                       (const char  *fname,
                                                    int          lineno,
                                                    gpointer     ptr,
                                                    const char  *type,
                                                    const char  *free_func);
                                                               
void         gsk_debug_untrack                     (gpointer     rv, 
                                                    const char  *free_func);
                                                               
/* Mark that we never intend to free this piece of memory. */  
void         gsk_debug_is_permanent                (gpointer     permanent);
                                                               
gboolean     gsk_debug_test                        (gpointer     ptr,
                                                    const char  *type);
gboolean     gsk_debug_is_tracked                  (gpointer     ptr);

/* useful for marking how certain memory was allocated */
void         gsk_debug_set_type                    (gpointer     ptr,
                                                    const char  *type);
const char  *gsk_debug_get_type                    (gpointer     ptr);
void         gsk_debug_bless                       (gpointer     ptr,
                                                    const char  *type);

void         gsk_debug_add_cleaner                 (GVoidFunc    cleanup);
void         gsk_debug_run_cleaners                ();
                                                               
/* Locked pointers cause warnings to appear if they
 * are freed before they are unlocked.
 */
void         gsk_debug_lock                        (gpointer     ptr);
void         gsk_debug_unlock                      (gpointer     ptr);

#else

/* To avoid having to #ifdef GSK_DEBUG too much... */
#define gsk_debug_is_permanent(ptr) 
#define gsk_debug_lock(ptr)
#define gsk_debug_unlock(ptr)
#define gsk_debug_track(fname,line,ptr,type,free_func)
#define gsk_debug_untrack(ptr,free_func)
#define gsk_debug_add_cleaner(clean_func)

#endif

#endif
