#ifndef DBGUTILS_H
#define DBGUTILS_H

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

typedef struct {
	uint32_t start; /* Start address */
	uint32_t end; /* End address (inclusive) */
	char *name; /* Function name */
	uint32_t hits; /* Hit count for histogram generation */
} gpa_func;

typedef struct {
	uint32_t addr; /* Instruction address */
	uint32_t line; /* Line number */
	char *file; /* Filename */
} gpa_line;

typedef struct {
	uint32_t start;
	uint32_t end; /* 0 if unknown */
	char *name;
	gpa_func *funcs; /* GPA functions */
	int numfunc;
	int funcbufsize;
	gpa_line *lines; /* GPA line numbers */
	int numline;
	int linebufsize;
	int detail; /* Detail level: -1 = hide, 0 = show all, 1=show lines, 2=show functions, 3=show presence */
	uint32_t hits; /* Hit count for histogram generation */
} module;

extern bool modules_inorder; /* Needs setting to false if module details are manually poked */
extern int maxmodnamelen; /* Length of longest module name */

#define MIN(A,B) (((A)<=(B))?(A):(B))
#define MAX(A,B) (((A)>=(B))?(A):(B))

/*

				Utility functions

*/

extern void *safe_realloc(void *ptr,size_t size);
extern void *safe_malloc(size_t size);
extern FILE *safe_fopen(const char *name,const char *mode);

extern void trim(char *buf);

/*

				Lookup functions

*/

extern module *FindModule(const char *name);
extern module *FindAddress(uint32_t addr);
extern gpa_func *FindFunc(module *m,uint32_t addr);
extern gpa_line *FindLine(module *m,uint32_t addr);

/*

				Data loading/management

*/

extern module *AddModule(uint32_t start,uint32_t end,const char *name);
extern void AddGPAFunction(module *m,const char *name,uint32_t start,uint32_t end);
extern void AddGPALine(module *m,uint32_t addr,uint32_t line,const char *file);
extern void KillGPA(module *m);
extern void KillModule(module *m);
extern void LoadGPA(module *m,const char *gpa);
extern void LoadAbsolute(module *m,const char *absol);
extern void LoadSyms(module *m,const char *syms);

extern void LoadROM(const char *builddir,const char *romname);

extern void KillROMModules(void);
extern void KillModules(void);

#endif
