Blame src/dalist_debug.c

e09104
/*****************************************************************************/
e09104
/*  dalist: a zero-dependency book-keeping library                           */
0553af
/*  Copyright (C) 2013--2021  SysDeer Technologies, LLC                      */
e09104
/*  Released under GPLv2 and GPLv3; see COPYING.DALIST.                      */
e09104
/*****************************************************************************/
e09104
e09104
#include <dalist/dalist.h>
e09104
#include "dalist_impl.h"
e09104
e09104
dalist_api
e09104
int dalist_debug_setup(
e09104
	struct dalist_ex *	dlist,
e09104
	struct dalist_debug *	dlist_debug,
e09104
	enum dalist_dbgenv	dbgenv,
e09104
	dalist_sprintf *	pfn_sprintf,
e09104
	dalist_write *		pfn_write,
e09104
	dalist_write_file *	pfn_write_file)
e09104
{
e09104
	if (dlist)
e09104
		/* in case we fail */
e09104
		dlist->debug = 0;
e09104
	else
e09104
		return DALIST_ELIST;
e09104
e09104
	if (!dlist_debug)
e09104
		return DALIST_EDEBUGSTRUCT;
e09104
	else if (!pfn_sprintf)
e09104
		return DALIST_EDEBUGSPRINTF;
e09104
e09104
	switch (dbgenv) {
e09104
		case DALIST_DEBUG_ENV_POSIX:
e09104
			if (!pfn_write)
e09104
				return DALIST_EDEBUGWRITE;
e09104
			break;
e09104
e09104
		case DALIST_DEBUG_ENV_NT:
e09104
			if (!pfn_write_file)
e09104
				return DALIST_EDEBUGWRITEFILE;
e09104
			break;
e09104
e09104
		default:
e09104
			return DALIST_EDEBUGENV;
e09104
	}
e09104
e09104
	dlist_debug->dbgenv        = dbgenv;
e09104
	dlist_debug->sprintf       = pfn_sprintf;
e09104
	dlist_debug->write         = pfn_write;
e09104
	dlist_debug->zw_write_file = pfn_write_file;
e09104
e09104
	dlist->debug = dlist_debug;
e09104
e09104
	return DALIST_OK;
e09104
}
e09104
e09104
e09104
static const char dalist_fmt_header_32[] =
e09104
	"dlist:\t\t0x%08x\n"
e09104
	"dlist->head:\t0x%08x\n"
e09104
	"dlist->tail:\t0x%08x\n\n";
e09104
e09104
static const char dalist_fmt_header_64[] =
e09104
	"dlist:\t\t0x%016x\n"
e09104
	"dlist->head:\t0x%016x\n"
e09104
	"dlist->tail:\t0x%016x\n\n";
e09104
e09104
static const char dalist_fmt_node_32[] =
e09104
	"node: 0x%08x\t"
e09104
	"prev: 0x%08x\t"
e09104
	"next: 0x%08x\t"
e09104
	"any:  0x%08x\t\n";
e09104
e09104
static const char dalist_fmt_node_64[] =
e09104
	"node: 0x%016x\t"
e09104
	"prev: 0x%016x\t"
e09104
	"next: 0x%016x\t"
e09104
	"any:  0x%016x\t\n";
e09104
000e5e
static const char * dalist_fmt_headers[2] = {
000e5e
	dalist_fmt_header_32,
000e5e
	dalist_fmt_header_64
000e5e
};
000e5e
000e5e
static const char * dalist_fmt_nodes[2] = {
000e5e
	dalist_fmt_node_32,
000e5e
	dalist_fmt_node_64
000e5e
};
000e5e
e09104
e09104
static int dalist_dbg_write_posix(
e09104
	struct dalist_ex *	dlist,
e09104
	intptr_t		fildes_or_hfile,
e09104
	const void *		buf,
e09104
	size_t			nbyte)
e09104
{
e09104
	int		fildes;
e09104
	dalist_write *	pfn_write;
e09104
	ssize_t		bytes_written;
e09104
e09104
	fildes = (int)fildes_or_hfile;
e09104
	pfn_write = (dalist_write *)dlist->debug->write;
e09104
e09104
	bytes_written = pfn_write(fildes,buf,nbyte);
e09104
00dc83
	if (bytes_written < 0)
00dc83
		return DALIST_EDEBUGENV;
00dc83
00dc83
	else if (bytes_written == (ssize_t)nbyte)
e09104
		return DALIST_OK;
00dc83
e09104
	else
e09104
		return DALIST_EDEBUGENV;
e09104
}
e09104
e09104
e09104
static int dalist_dbg_write_nt(
e09104
	struct dalist_ex *	dlist,
e09104
	intptr_t		fildes_or_hfile,
e09104
	const void *		buf,
e09104
	size_t			nbyte)
e09104
{
e09104
	void *			hfile;
0f8a8b
	struct dalist_iosb	iosb;
e09104
	dalist_write_file *	pfn_write_file;
e09104
e09104
	hfile          = (void *)fildes_or_hfile;
e09104
	pfn_write_file = (dalist_write_file *)dlist->debug->zw_write_file;
e09104
e09104
	return pfn_write_file(
e09104
		hfile,
e09104
		(void *)0,
e09104
		(void *)0,
e09104
		(void *)0,
e09104
		&iosb,
e09104
		(void *)buf,
e09104
		(uint32_t)nbyte,
e09104
		(int64_t *)0,
e09104
		(uint32_t *)0);
e09104
}
e09104
e09104
e09104
dalist_api
e09104
int dalist_debug_print(
e09104
	struct dalist_ex *	dlist,
e09104
	intptr_t		fildes_or_hfile)
e09104
{
e09104
	const char *		fmt_header;
e09104
	const char *		fmt_node;
e09104
	char			dbg_buf[128];
e09104
	intptr_t		nbyte;
e09104
e09104
	int			status;
e09104
	struct dalist_node *	node;
e09104
	dalist_sprintf *	dbg_sprintf;
e09104
	dalist_dbg_write *	dbg_write;
e09104
e09104
	if (!dlist)
e09104
		return DALIST_ELIST;
e09104
	else if (!dlist->debug)
e09104
		return DALIST_EDEBUGENV;
e09104
e09104
	/* initial setup */
e09104
	dbg_sprintf = (dalist_sprintf *)dlist->debug->sprintf;
000e5e
	fmt_header  = dalist_fmt_headers[(sizeof(size_t)-4)/4];
000e5e
	fmt_node    = dalist_fmt_nodes[(sizeof(size_t)-4)/4];
e09104
e09104
	if (dlist->debug->dbgenv == DALIST_DEBUG_ENV_POSIX)
e09104
		dbg_write = dalist_dbg_write_posix;
e09104
	else if (dlist->debug->dbgenv == DALIST_DEBUG_ENV_NT)
e09104
		dbg_write = dalist_dbg_write_nt;
e09104
	else
e09104
		dbg_write = 0;
e09104
e09104
	if ((!dbg_sprintf) || (!dbg_write))
e09104
		return DALIST_EDEBUGENV;
e09104
e09104
	/* print list header */
e09104
	nbyte = dbg_sprintf((char *)dbg_buf,fmt_header,dlist,dlist->head,dlist->tail);
e09104
e09104
	if (nbyte < 0)
e09104
		return DALIST_EDEBUGENV;
e09104
e09104
	status = dbg_write(dlist,fildes_or_hfile,dbg_buf,nbyte);
e09104
e09104
	if (status != NT_STATUS_SUCCESS)
e09104
		return DALIST_EDEBUGENV;
e09104
e09104
	/* print node information */
e09104
	status = DALIST_OK;
e09104
	node   = (struct dalist_node *)dlist->head;
e09104
e09104
	while (node && (status == DALIST_OK)) {
e09104
		/* create output line */
e09104
		nbyte = dbg_sprintf(
e09104
			(char *)dbg_buf,
e09104
			fmt_node,
e09104
			node,
e09104
			node->prev,
e09104
			node->next,
e09104
			node->any);
e09104
e09104
		if (nbyte < 0)
e09104
			return DALIST_EDEBUGENV;
e09104
e09104
		/* write output line */
e09104
		status = dbg_write(
e09104
			dlist,
e09104
			fildes_or_hfile,
e09104
			dbg_buf,
e09104
			nbyte);
e09104
e09104
		node = node->next;
e09104
	}
e09104
e09104
	return DALIST_OK;
e09104
}