|
|
e09104 |
/*****************************************************************************/
|
|
|
e09104 |
/* dalist: a zero-dependency book-keeping library */
|
|
|
e09104 |
/* Copyright (C) 2013,2014,2015 Z. Gilboa */
|
|
|
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 |
|
|
|
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 |
|
|
|
e09104 |
if (bytes_written == nbyte)
|
|
|
e09104 |
return DALIST_OK;
|
|
|
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;
|
|
|
e09104 |
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 |
if (iosb.info == nbyte)
|
|
|
e09104 |
return DALIST_OK;
|
|
|
e09104 |
else
|
|
|
e09104 |
return DALIST_EDEBUGENV;
|
|
|
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;
|
|
|
e09104 |
|
|
|
e09104 |
if (sizeof(size_t) == 4) {
|
|
|
e09104 |
fmt_header = (char *)dalist_fmt_header_32;
|
|
|
e09104 |
fmt_node = (char *)dalist_fmt_node_32;
|
|
|
e09104 |
} else if (sizeof(size_t) == 8) {
|
|
|
e09104 |
fmt_header = (char *)dalist_fmt_header_64;
|
|
|
e09104 |
fmt_node = (char *)dalist_fmt_node_64;
|
|
|
e09104 |
} else
|
|
|
e09104 |
return DALIST_EDEBUGENV;
|
|
|
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 |
}
|