/*
tsdebug.h -- Bob Trower 02/09/91
This file has been
created to add some debugging extensions
to C code. It allows existing debugging code and
information messages
to be cleaned up in the 'LA3' system.
*/
#define
TS_USR_CALLBACK
#define INCL_CONTX
#define INCL_TRACE
#define INCL_PRINT
#define
INCL_TS_DEBUG_CODE
#define INCL_LIST
#define INCL_MALLO
#define TS_TESTCODE
#include <stdarg.h>
#define TS_VERMAJ 0
#define TS_VERMIN 6
#define TS_VERREL 00
/*
To add this file to
an application, add the following lines
to main.h and
main.c:
Add the following
line to main.h:
#include "tsdebug.h"
Add the following 4
lines to the end of main.c:
#ifdef TS_DEBUG
#define INCL_TS_DEBUG_CODE
#include "tsdebug.h"
#endif
Debug code will be
included if TS_DEBUG is defined when the
code is
compiled. The debug code is affected by
the
environment
variables described below.
To turn on debugging
messages, set the environment
variables:
set TS_DEBUG_MODE=1
.
.
.
set TS_DEBUG_MODE=9
TS_DEBUG_MODE must be set in the
environment
for any messages to appear from the
system,
otherwise, all printf statements are
discarded. The maximum debug level is
9,
which will cause all debugging
information
to appear.
set TS_MAIL=<Mail Address>
Some printed messages also cause a mail
message to be sent (use with
caution). If
this variable is set (i.e
TS_MAIL=btrower@ipgnet.com), mail will
be
sent to that address. If the variable is
not set, messages are not sent. Note
that
this requires a program similar to UNIX
'mail', with the name 'mail'.
set TS_MEMVERBOSE=1
set TS_MEMVERBOSE=2
Setting TS_MEMVERBOSE causes messages
to be
printed from the memory allocation
code. A
higher number indicates a more verbose
mode.
This code causes all
instances of malloc, calloc, realloc
and free at the
application level to be replaced with
debugging versions
that track the memory used and check for
memory corruption,
or freeing of invalid memory.
In addition to
memory functions, this code will patch
USR_FunctionBegin,
and USR_FunctionEnd to add tracing to the
debug code if
TS_USR_CALLBACK is defined.
*/
#define TS_PORT
#define tsLPSTR char
*
#ifndef TS_PORT
#include <string.h>
#ifndef FAR
#define FAR _far
#endif
#ifndef tsLPSTR
typedef char FAR* tsLPSTR;
#endif
#define strcpy _fstrcpy
#endif
#ifndef
mytsLPSTR_DEFINED
typedef tsLPSTR mytsLPSTR;
#define mytsLPSTR_DEFINED
#endif
#ifdef
TS_TESTSHELL_CONTX
#define INCL_CONTX
#define TS_TESTCODE
#define INCL_TS_DEBUG_CODE
#endif
#ifdef
TS_TESTSHELL_PRINT
#define INCL_CONTX
#define INCL_PRINT
#define TS_TESTCODE
#define INCL_TS_DEBUG_CODE
#endif
#ifdef
TS_TESTSHELL_MALLO
#define INCL_CONTX
#define INCL_MALLO
#define TS_TESTCODE
#define INCL_TS_DEBUG_CODE
#endif
#ifdef
TS_TESTSHELL_LIST
#define INCL_LIST
#define TS_TESTCODE
#define INCL_TS_DEBUG_CODE
#endif
#ifdef
TS_TESTSHELL_TRACE
#define TS_DEBUG
#define TS_TESTCODE
#define INCL_TS_DEBUG_CODE
#endif
#ifdef
TS_TESTSHELL_TSDEBUG
#define TS_DEBUG
#define TS_TESTCODE
#define INCL_TS_DEBUG_CODE
#endif
#ifdef TS_DEBUG
#define INCL_CONTX
#define INCL_PRINT
#define INCL_MALLO
#define INCL_LIST
#define INCL_TRACE
#endif
/********** External
interface: TSdCONTEXT ** Start **/
#if
defined(INCL_CONTX)
#if !defined(tsdcontx_h)
#define tsdcontx_h
#if !defined(size_t)
#include <stdio.h>
#include <string.h>
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
tsLPSTR TSdSetContextFile(tsLPSTR Name);
int TSdSetContextLine(int Number);
tsLPSTR TSdSetContextFunc(tsLPSTR Name);
void TSdSetContext(tsLPSTR FileName, int
Line, tsLPSTR FuncName);
#define TSdSetCurContext(FuncName) \
TSdSetContext(__FILE__, __LINE__,
FuncName);
tsLPSTR TSdGetContextFunc(void);
int TSdGetContextLine(void);
tsLPSTR TSdGetContextFile(void);
int TSdIncFunctionDepth(void);
int TSdDecFunctionDepth(void);
tsLPSTR TSdPadStr(void);
tsLPSTR TSdContextStr(void);
size_t TSdSetContextMem(size_t
MemAllocated);
size_t TSdSetContextTotMem(size_t
TotMemAllocated);
size_t TSdGetContextMem(void);
size_t TSdGetContextTotMem(void);
void test_tsdcontx(void);
#define TSdMAX_FILE_NAME_LEN 512
#define TSdMAX_FUNC_NAME_LEN 512
#define TSdBUF_LEN_WORK_MEDIUM 1024
#endif
#else
#define TSdSetCurContext(FuncName)
#endif
/********** External
interface: TSdCONTEXT ** End **/
/********** External
interface: TSdMalloc ** Start **/
#if
defined(INCL_MALLO)
#if !defined(tsdmallo_h)
#define tsdmallo_h
#if !defined(max)
#include <stdlib.h>
#endif
#if !defined(size_t)
#include <string.h>
#endif
/*
** Redefine normal library calls to our
replacements
*/
#define malloc(Size) TSdMalloc(Size)
#define realloc(Ptr, Size)
TSdRealloc(Ptr, Size)
#define free(Ptr) TSdFree(Ptr)
#define calloc(Nelem, Esize) TSdCalloc(Nelem, Esize)
#define strdup(Str) TSdStrDup(Str)
#define memalign(Alignment, Size) TSdMalloc(Size)
/*
** Export prototypes for our replacements
*/
void
TSdFree(void *ptr);
void *
TSdMalloc(size_t Size);
void *
TSdCalloc(size_t Nelem, size_t Esize);
void *
TSdRealloc(void *Ptr, size_t Size);
tsLPSTR
TSdStrDup(const tsLPSTR Str);
void *TSdAddTrustedPtr(void *Ptr);
void test_tsdmallo(void);
#endif
#endif
/********** External
interface: TSdMalloc ** End **/
/********** External
interface: TSdPRINTF ** Start **/
#if
defined(INCL_PRINT)
#if !defined(tsdprint_h)
#define tsdprint_h
#if !defined(max)
#include <stdlib.h>
#endif
#if !defined(stdin)
#include <stdio.h>
#endif
#if !defined(size_t)
#include <string.h>
#endif
int TSdDebugMode(void);
#define TSdMAX_DEBUG_MODE 9
#define TSdPrintf(x) TSdebug_Printf x
#define TSdPrintf2(x) if(TSdDebugMode()
> 1) TSdebug_Printf x
#define TSdPrintf3(x) if(TSdDebugMode()
> 2) TSdebug_Printf x
#define TSdPrintf4(x) if(TSdDebugMode()
> 3) TSdebug_Printf x
#define TSdPrintf5(x) if(TSdDebugMode()
> 4) TSdebug_Printf x
#define TSdPrintf6(x) if(TSdDebugMode()
> 5) TSdebug_Printf x
#define TSdPrintf7(x) if(TSdDebugMode()
> 6) TSdebug_Printf x
#define TSdPrintf8(x) if(TSdDebugMode()
> 7) TSdebug_Printf x
#define TSdPrintf9(x) if(TSdDebugMode()
> 8) \
TSdebug_Printf("%s",
TSdPadStr()); TSdebug_Printf x ;\
TSdebug_Printf(":%s:%i\n",
__FILE__, __LINE__);
#define TSdPrint (fmt, ...)
TSdebug_Printf(fmt, ## __VA_ARGS__)
#define TSdPrint2(...) if(TSdDebugMode()
> 1) TSdebug_Printf(__VA_ARGS__)
#define TSdPrint3(...) if(TSdDebugMode()
> 2) TSdebug_Printf(__VA_ARGS__)
#define TSdPrint4(...) if(TSdDebugMode()
> 3) TSdebug_Printf(__VA_ARGS__)
#define TSdPrint5(...) if(TSdDebugMode()
> 4) TSdebug_Printf(__VA_ARGS__)
#define TSdPrint6(...) if(TSdDebugMode() >
5) TSdebug_Printf(__VA_ARGS__)
#define TSdPrint7(...) if(TSdDebugMode()
> 6) TSdebug_Printf(__VA_ARGS__)
#define TSdPrint8(...) if(TSdDebugMode()
> 7) TSdebug_Printf(__VA_ARGS__)
#define TSdPrint9(...) if(TSdDebugMode()
> 8) TSdebug_Printf(__VA_ARGS__)
#define TSdPrintfOutputProcedure(Proc) int
(*Proc)(tsLPSTR Output)
#define TSdSetBufferProcedure(Proc) tsLPSTR
(*Proc)(tsLPSTR Buffer)
#define TSdSetObjectProcedure(Proc) tsLPSTR
(*Proc)(void *Object, tsLPSTR Buffer)
extern
TSdPrintfOutputProcedure(TSdPrintfOutPut);
int TSdebug_Printf(const tsLPSTR fmt, ...);
int TSdDefPrintfOutPut(tsLPSTR Output);
void test_tsdprint(void);
#endif
#else
#define TSdPrintf (x)
#define TSdPrintf2(x)
#define TSdPrintf3(x)
#define TSdPrintf4(x)
#define TSdPrintf5(x)
#define TSdPrintf6(x)
#define TSdPrintf7(x)
#define TSdPrintf8(x)
#define TSdPrintf9(x)
#define TSdPrint (x)
#define TSdPrint2(x)
#define TSdPrint3(x)
#define TSdPrint4(x)
#define TSdPrint5(x)
#define TSdPrint6(x)
#define TSdPrint7(x)
#define TSdPrint8(x)
#define TSdPrint9(x)
#endif
/********** External
interface: TSdPRINTF ** End
**/
/********** External
interface: TSdLIST ** Start **/
#if
defined(INCL_LIST)
#if !defined(tsdlist_h)
#define tsdlist_h
/* List Messages */
#define TSD_MSG_NEW_LIST 16705
#define TSD_MSG_INI_LIST 16706
#define TSD_MSG_DEL_LIST 16707
#define TSD_MSG_EMT_LIST 16708
#define TSD_MSG_NEW_NODE 16709
#define TSD_MSG_INI_NODE 16710
#define TSD_MSG_ADD_NODE 16711
#define TSD_MSG_DEL_NODE 16712
#define TSD_MSG_PUT_NODE 16713
#define TSD_MSG_GET_NODE 16714
#define TSD_MSG_SET_FCMP 16715
#define TSD_LIST_TYPE_ANY 0
#define TSD_LIST_TYPE_LIST 1
typedef int TSdMsgType;
typedef struct tagTSdListNode {
tsLPSTR Data;
struct tagTSdListNode *next;
}TSdListNode, *pTSdListNode;
typedef union{
void *(*Func)(void *);
void *Data;
}TSdGP;
#define TSdListProcedure(Proc) void
*(*Proc)(struct tagTSdList *List, TSdMsgType Msg, void *Data)
#define TSdCompareProcedure(Proc) int
(*Proc)(void *Data1, void *Data2)
#define TSdCompareProcedureProt int
(*)(void *, void *)
typedef struct tagTSdList {
int Type;
pTSdListNode head;
pTSdListNode tail;
pTSdListNode curr;
TSdListProcedure(Proc);
TSdCompareProcedure(Compare);
tsLPSTR Name;
}TSdList, *pTSdList;
#define GetTSdNewList(List, ListProc, Data)
ListProc(List, TSD_MSG_NEW_LIST, Data)
#define TSdNewList(Name)
GetTSdNewList(TSd_ListOfLists(),TSdDefListProc,Name)
#define TSdAddList(List, Name)
GetTSdNewList(List,TSdDefListProc,Name)
#define t_TSdNewListNode(List, Data)
(List->Proc)(List,TSD_MSG_NEW_NODE,Data)
#define t_TSdAddListNode(List, Data)
(List->Proc)(List,TSD_MSG_ADD_NODE,TSdNewListNode(List, Data))
#define t_TSdDelListNode(List, Data)
(List->Proc(List, TSD_MSG_DEL_NODE, Data))
#define t_TSdGetListNode(List, Data)
(List->Proc(List, TSD_MSG_GET_NODE, Data))
#define t_TSdSetCmpFunc(List, Func) (List->Proc(List, TSD_MSG_SET_FCMP, Func))
#define t_TSdDisposeList(List) (List ?
(List->Proc(List, TSD_MSG_DEL_LIST, NULL)) : NULL)
#define t_TSdEmptyList(List)
(List->Proc(List, TSD_MSG_EMT_LIST, NULL))
#define TSdNewListNode(List, Data) (List ?
t_TSdNewListNode(List, Data) : NULL)
#define TSdAddListNode(List, Data) (List ?
t_TSdAddListNode(List, Data) : NULL)
#define TSdDelListNode(List, Data) (List ?
t_TSdDelListNode(List, Data) : NULL)
#define TSdGetListNode(List, Data) (List ?
t_TSdGetListNode(List, Data) : NULL)
#define TSdSetCmpFunc(List, Func)
(List ? t_TSdSetCmpFunc(List, Func)
: NULL)
#define TSdDisposeList(List) (List ? t_TSdDisposeList(List) : NULL)
#define TSdEmptyList(List) (List ? t_TSdEmptyList(List) : NULL)
#define TSdSetListType(List, TSdListType) (List ? List->Type |=
TSdListType : TSD_LIST_TYPE_ANY)
#define TSdSetListIsList(List)
TSdSetListType(List, TSD_LIST_TYPE_LIST)
#define TSdListType(List) (List ?
List->Type : TSD_LIST_TYPE_ANY)
#define TSdListIsList(List) (List ?
(TSdListType(List) & TSD_LIST_TYPE_LIST) : TSD_LIST_TYPE_ANY)
extern pTSdList TSd_ListOfLists_;
#define TSd_ListOfLists() TSd_ListOfLists_
void *TSdDefListProc(pTSdList List,
TSdMsgType Msg, void *Data);
void test_tsdlist(void);
#endif
#endif
/********** External
interface: TSdLIST ** End **/
/********** External
interface: TSdTRACING ** Start **/
#if
defined(INCL_TRACE)
#if !defined(tsdtrace_h)
#define tsdtrace_h
#define printf TSdebug_Printf
#define USR_FunctionBegin(Name) TSdFunctionBegin(Name)
#define USR_FunctionEnd(Name) TSdFunctionEnd(Name)
int TSdebug_FunctionBegin(const tsLPSTR
FunctionName);
int TSdebug_FunctionEnd(const tsLPSTR FunctionName);
#define TSdFunctionBegin(Name) TSdSetCurContext(Name);\
TSdebug_FunctionBegin(Name)
#define TSdFunctionEnd(Name) TSdSetCurContext(Name);\
TSdebug_FunctionEnd(Name)
void test_tsdtrace(void);
tsLPSTR TSdPadStr(void);
#endif
#else
#define TSdFunctionBegin(Name)
#define TSdFunctionEnd(Name)
#endif
/********** External
interface: TSdTRACING ** End **/
/********** External
interface: TSdDEBUG ** Start **/
#if
defined(TS_DEBUG)
#if !defined(tsdebug_h)
#define tsdebug_h
#endif
#endif
/********** External
interface: TSdDEBUG ** End **/
/********** Internal
Implementation: TSdCONTEXT **
Start **/
#if
defined(INCL_CONTX) && defined(INCL_TS_DEBUG_CODE)
#if
!defined(tsdcontx_c)
#define tsdcontx_c
#if !defined(size_t)
#include <stdio.h>
#include <string.h>
#endif
typedef struct
tagContext{
char FileName[TSdMAX_FILE_NAME_LEN];
char FuncName[TSdMAX_FUNC_NAME_LEN];
int Line;
size_t MemAllocated;
size_t TotMemAllocated;
int FunctionDepth;
int DepthStep;
}tTSdContext,
*ptTSdContext;
static tTSdContext TSdContextInfo
= {
"",
"",
0,
0,
0,
0,
4,
}, *TSdContext =
&TSdContextInfo;
tsLPSTR
TSdSetContextFile(tsLPSTR Name)
{
strncpy(TSdContext->FileName, Name,
TSdMAX_FILE_NAME_LEN - 1);
return(TSdContext->FileName);
}
tsLPSTR
TSdSetContextFunc(tsLPSTR Name)
{
strncpy(TSdContext->FuncName, Name,
TSdMAX_FUNC_NAME_LEN - 1);
return(TSdContext->FuncName);
}
int TSdSetContextLine(int
Number)
{
TSdContext->Line = Number;
return(TSdContext->Line);
}
size_t
TSdSetContextMem(size_t MemAllocated)
{
TSdContext->MemAllocated = MemAllocated;
return(TSdContext->MemAllocated);
}
size_t
TSdSetContextTotMem(size_t TotMemAllocated)
{
TSdContext->TotMemAllocated =
TotMemAllocated;
return(TSdContext->TotMemAllocated);
}
tsLPSTR
TSdGetContextFile(void)
{
return(TSdContext->FileName);
}
tsLPSTR
TSdGetContextFunc(void)
{
return(TSdContext->FuncName);
}
int
TSdGetContextLine(void)
{
return(TSdContext->Line);
}
void
TSdSetContext(tsLPSTR FileName, int Line, tsLPSTR FuncName)
{
TSdSetContextFile(FileName);
TSdSetContextLine(Line);
TSdSetContextFunc(FuncName);
}
size_t
TSdGetContextMem(void)
{
return(TSdContext->MemAllocated);
}
size_t
TSdGetContextTotMem(void)
{
return(TSdContext->TotMemAllocated);
}
int
TSdIncFunctionDepth(void)
{
return(TSdContext->FunctionDepth++);
}
int
TSdDecFunctionDepth(void)
{
return(TSdContext->FunctionDepth--);
}
tsLPSTR
TSdPadStr(void)
{
static char Str[TSdBUF_LEN_WORK_MEDIUM];
int Pad;
Pad = TSdContext->FunctionDepth *
TSdContext->DepthStep;
sprintf(Str, "%*.*s", Pad, Pad,
"");
return(Str);
}
tsLPSTR
TSdContextStr(void)
{
static char Buf[TSdBUF_LEN_WORK_MEDIUM];
sprintf(Buf,"%s:%s(%i)", TSdContext->FileName, \
TSdContext->FuncName,
TSdContext->Line);
return(Buf);
}
#if
defined(TS_TESTCODE)
void
test_tsdcontx(void)
{
/*tsLPSTR FuncName, *FileName;
int Line;*/
printf("Context:%s\n",
TSdContextStr());
TSdSetCurContext("test_tsdcontx");
printf("Context:%s\n",
TSdContextStr());
}
#endif
#if
defined(TS_TESTSHELL_CONTX)
int main(int argc, tsLPSTR *argv)
{
if(argc < 2){
printf("Usage: tsdcontx '.'\n");
printf("(Test Shell for
tsdcontx)\n");
}
else{
test_tsdcontx();
}
return( 0 );
}
#endif
#endif
#endif
/********** Internal
Implementation: TSdCONTEXT **
End **/
/********** Internal
Implementation: TSdMalloc **
Start **/
#if
defined(INCL_MALLO) && defined(INCL_TS_DEBUG_CODE)
#if
!defined(tsdmallo_c)
#define tsdmallo_c
#define TSdMPrintf(x)
if(TSdMemVerboseMode(FALSE)) printf x
#define
TSdMPrintf2(x) if(TSdMemVerboseMode(FALSE) > 1) printf x
#define TSdMPrint
(fmt, ...) if(TSdMemVerboseMode(FALSE) > 0) fprintf(stderr, fmt,
__VA_ARGS__)
#define
TSdMPrint2(fmt, ...) if(TSdMemVerboseMode(FALSE) > 1) fprintf(stderr, fmt,
__VA_ARGS__)
#define
TS_MEMVERBOSE_VAR
"TS_MEMVERBOSE"
int
TSdMemVerboseMode(int ForceOn)
{
static int VerboseMode = FALSE;
static int Initialized = FALSE;
if(ForceOn){
VerboseMode = ForceOn;
Initialized = TRUE;
}
else if(!Initialized){
tsLPSTR VerboseSwitch;
VerboseSwitch=getenv(TS_MEMVERBOSE_VAR);
if(VerboseSwitch){
VerboseMode = atoi(VerboseSwitch);
VerboseMode = VerboseMode ? VerboseMode :
TRUE;
}
Initialized = TRUE;
}
return(VerboseMode);
}
/* Point our
redefinitions of standard library code back to the real thing */
#undef malloc
#undef realloc
#undef free
#include <malloc.h>
void
*TSdTrueMalloc(size_t Size)
{
return(malloc(Size));
}
void
TSdTrueFree(void *Ptr)
{
free(Ptr);
}
void
*TSdTrueRealloc(void *Ptr, size_t Size)
{
return(realloc(Ptr, Size));
}
/* Restore our
redefinitions of standard library code */
#define
malloc(Size) TSdMalloc(Size)
#define realloc(Ptr,
Size) TSdRealloc(Ptr, Size)
#define
free(Ptr) TSdFree(Ptr)
/* Trusted memory
allocations list stuff */
typedef struct tagMgMemTrusted{
void *Ptr;
struct tagMgMemTrusted *next;
}tTrustedMem,
*ptTrustedMem;
ptTrustedMem
MgMemTr_head = NULL, MgMemTr_tail = NULL, MgMemTr_current = NULL;
void
*TSdAddTrustedPtr(void *Ptr)
{
void *MemPtr = NULL;
if(Ptr){
MgMemTr_current =
malloc(sizeof(tTrustedMem));
if (MgMemTr_current){
MemPtr = Ptr;
MgMemTr_current->Ptr = Ptr;
MgMemTr_current->next = NULL;
if (MgMemTr_head == NULL) {
MgMemTr_head = MgMemTr_tail =
MgMemTr_current;
}
else {
MgMemTr_tail->next =
MgMemTr_current;
MgMemTr_tail = MgMemTr_current;
}
}
}
TSdMPrintf2(("Add Trusted
pointer:[%p]\n", MgMemTr_current->Ptr));
return(MemPtr);
}
void
*TSdTrustedPtr(void *Ptr)
{
ptTrustedMem Here, Found = NULL;
for(Here = MgMemTr_head;Here &&
!Found;Here = Here->next){
if( Here->Ptr == Ptr){
Found = Here;
}
}
return(Found);
}
void
*TSdDelTrustedPtr(void *Ptr)
{
ptTrustedMem cur = NULL, prev = NULL;
ptTrustedMem Found = FALSE;
cur = MgMemTr_head;
prev = NULL;
while(cur){
if (cur->Ptr == Ptr) {
Found = cur;
if(prev) {
prev->next = cur->next;
free(cur);
cur = prev->next;
if(!cur){
MgMemTr_tail = prev;
}
}
else {
MgMemTr_head = cur->next;
free(cur);
if(!MgMemTr_head){
cur = NULL;
}
else {
cur = MgMemTr_head->next;
}
if(!cur){
MgMemTr_tail =
MgMemTr_head;
}
}
}
else {
prev = cur;
cur = cur->next;
}
}
if(!Found){
TSdMPrintf(("%Dc%Df%Dl%DmTSdDelTrustedPtr: Attempt to free invalid
pointer\n"));
}
return(Found);
}
#define
MgMemStartSentinelValue 121
#define
MgMemEndSentinelValue 97
typedef unsigned
char MgMemSentinel;
typedef struct
tMemBlock {
char pad[7];
MgMemSentinel StartSentinel;
char data[1];
}tMemBlock;
typedef struct
tTSdMalloc_tag {
size_t Size;
tMemBlock *ptr;
struct tTSdMalloc_tag *next;
}fMemt;
#define
MGMEM_UNUSED_FLAG 'u'
#define
MGMEM_FREED_FLAG 'f'
static fMemt
*MgMem_head = NULL;
static fMemt
*MgMem_tail = NULL;
static fMemt
*MgMem_current = NULL;
fMemt
*MgMemMalloc(size_t Size)
{
fMemt *Mem;
Mem = (fMemt *) TSdTrueMalloc(sizeof(fMemt));
if(Mem){
Mem->ptr =
TSdTrueMalloc(sizeof(tMemBlock) + Size );
if(!Mem->ptr){
TSdTrueFree(Mem);
Mem = NULL;
}
else {
Mem->ptr->StartSentinel =
MgMemStartSentinelValue;
memset(Mem->ptr->data,MGMEM_UNUSED_FLAG,Size);
Mem->ptr->data[Size] =
MgMemEndSentinelValue;
Mem->Size = Size;
}
}
return(Mem);
}
void
*TSdMalloc(size_t Size)
{
void *MemoryPtr = NULL;
TSdMPrintf2(("TSdMalloc:Net Memory
in:%li\n", (long) TSdGetContextTotMem()));
MgMem_current = MgMemMalloc(Size);
if (MgMem_current){
MgMem_current->next = NULL;
if (MgMem_head == NULL) {
MgMem_head = MgMem_tail =
MgMem_current;
}
else {
MgMem_tail->next =
MgMem_current;
MgMem_tail = MgMem_current;
}
TSdSetContextTotMem(TSdGetContextTotMem() + Size);
MemoryPtr = MgMem_current->ptr->data;
}
TSdMPrintf2(("TSdMalloc:Net
Memory:%li", (long) TSdGetContextTotMem()));
TSdMPrintf2((" at %s\n", (char *)
TSdContextStr()));
return(MemoryPtr);
}
void
*TSdCalloc(size_t Nelem, size_t Esize)
{
tsLPSTR Mem;
size_t Size = Nelem * Esize;
Mem = TSdMalloc(Size);
if(Mem){
memset(Mem, 0, Size);
}
return(Mem);
}
int
MgMemValidate(fMemt *Mem)
{
int Valid = FALSE;
if(!Mem){
TSdMPrintf(("Attempt to validate
null Memory node\n"));
}
else if(!Mem->ptr){
TSdMPrintf(("Memory node has
invalid memory pointer\n"));
}
else {
tMemBlock *ptr;
ptr = Mem->ptr;
if( Mem->ptr->StartSentinel !=
MgMemStartSentinelValue ){
TSdMPrintf(("Invalid Start
sentinel in memory pointer\n"));
}
else if(
Mem->ptr->data[Mem->Size] != MgMemEndSentinelValue ){
TSdMPrintf(("Invalid End
sentinel in memory pointer\n"));
}
else {
Valid = TRUE;
}
}
if(!Valid){
TSdMPrintf(("Error -- Memory Node
failed validation\n"));
}
return(Valid);
}
int MgMemFree(fMemt
*Mem)
{
int Freed = FALSE;
if(MgMemValidate(Mem)){
memset(Mem->ptr->data,MGMEM_FREED_FLAG, Mem->Size);
TSdTrueFree(Mem->ptr);
TSdTrueFree(Mem);
Freed = TRUE;
}
return(Freed);
}
fMemt
*MgMemRealloc(fMemt *Mem, size_t Size)
{
if(Mem){
Mem->ptr =
TSdTrueRealloc(Mem->ptr, sizeof(tMemBlock) + Size );
if(!Mem->ptr){
TSdTrueFree(Mem);
Mem = NULL;
}
else {
Mem->ptr->StartSentinel =
MgMemStartSentinelValue;
Mem->ptr->data[Size] =
MgMemEndSentinelValue;
Mem->Size = Size;
}
}
return(Mem);
}
void
TSdFreeManagedMem(void *ptr)
{
fMemt *MgMem_cur = NULL, *MgMem_prev =
NULL;
int Found = FALSE;
MgMem_cur = MgMem_head;
MgMem_prev = NULL;
while (MgMem_cur != NULL) {
MgMemValidate(MgMem_cur);
if (MgMem_cur->ptr->data == ptr)
{
Found = TRUE;
TSdSetContextTotMem(
TSdGetContextTotMem() - MgMem_cur->Size );
if(MgMem_prev) {
MgMem_prev->next =
MgMem_cur->next;
MgMemFree(MgMem_cur);
MgMem_cur =
MgMem_prev->next;
if(!MgMem_cur){
MgMem_tail = MgMem_prev;
}
}
else {
MgMem_head =
MgMem_cur->next;
MgMemFree(MgMem_cur);
if(!MgMem_head){
MgMem_cur = NULL;
}
else {
MgMem_cur = MgMem_head->next;
}
if(!MgMem_cur){
MgMem_tail = MgMem_head;
}
if(!MgMem_tail) {
}
}
}
else {
MgMem_prev = MgMem_cur;
MgMem_cur = MgMem_cur->next;
}
}
if(!Found){
TSdMPrintf(("%Dc%Df%Dl%DmError --
Attempt to free invalid pointer\n"));
}
TSdMPrintf2(("TSdFreeManagedMem:Net
Memory:%li\n", (long) TSdGetContextTotMem()));
}
void TSdFree(void
*ptr)
{
TSdMPrintf2(("To Managed Memory:
Pointer %p: ", ptr));
TSdMPrintf2(("To Managed Memory: Value
as string '%s'\n", ptr));
if(TSdTrustedPtr(ptr)){
TSdDelTrustedPtr(ptr);
TSdTrueFree(ptr);
}
else {
TSdFreeManagedMem(ptr);
}
}
void
*TSdRealloc(void *ptr, size_t Size)
{
void *MemoryPtr = NULL;
fMemt *MgMem_cur = NULL, *MgMem_prev =
NULL;
TSdMPrintf2(("Reallocating
Memory:%Dc%Df\n"));
MgMem_cur = MgMem_head;
MgMem_prev = NULL;
if( !ptr ) {
ptr = TSdMalloc( Size );
}
while (MgMem_cur) {
MgMemValidate(MgMem_cur);
if (MgMem_cur->ptr->data == ptr)
{
size_t OldSize =
MgMem_cur->Size;
MgMem_current =
MgMemRealloc(MgMem_cur, Size);
TSdSetContextTotMem(
TSdGetContextTotMem() +(Size - OldSize) );
MgMem_cur = NULL;
MemoryPtr =
MgMem_current->ptr->data;
}
else {
MgMem_prev = MgMem_cur;
MgMem_cur = MgMem_cur->next;
}
}
if(!MemoryPtr){
TSdMPrintf(("%Dc%Df%Dl%DmError --
problem re-allocating pointer\n"));
}
TSdMPrintf2(("TSdRealloc:Net
Memory:%li\n", (long) TSdGetContextTotMem()));
return(MemoryPtr);
}
tsLPSTR
TSdStrDup(const tsLPSTR Str)
{
int len;
tsLPSTR NewStr;
len = strlen(Str);
NewStr = (tsLPSTR ) TSdMalloc(len + 1);
if(NewStr){
strcpy(NewStr, Str);
}
return(NewStr);
}
#if
defined(TS_TESTCODE)
void
test_tsdmallo(void)
{
tsLPSTR str, *p1, *p2;
tsLPSTR *pp;
int i;
printf("Testing TSdMalloc
module\n");
if(!TSdMemVerboseMode(FALSE)){
TSdMemVerboseMode(1);
}
pp = TSdCalloc(10, sizeof(tsLPSTR ));
for(i = 0; i < 9; i++){
pp[i] =
TSdStrDup("Test_String[n]");
pp[i][12] = (char) (i + '0');
}
for(i = 0; pp[i]; i++){
printf("%s\n", pp[i]);
}
for(i = 0; pp[i]; i++){
TSdFree(pp[i]);
}
for(i = 0; pp[i]; i++){
printf("%16.16s\n", pp[i]);
}
TSdFree(pp);
str = TSdStrDup("Test_String");
printf("[Forced error]:");
strcpy(str, "Test_StringO"); /* Last character overwrites sentinel */
TSdFree(str);
strcpy(str, "Test_String"); /* reset sentinel so it can be freed */
TSdFree(str);
str =
TSdStrDup("Test_String3");
TSdFree(str);
printf("[Forced error]:");
TSdFree(str); /* Pointer is now invalid */
p1 = TSdMalloc(100);
str = TSdStrDup("Test_String4");
p2 = TSdRealloc(p1, 15000);
printf("Ptr1=%p, Ptr2=%p\n", p1,
p2);
p1 = TSdMalloc(100);
printf("Ptr2
Contents:'%50.50s'\n", p2);
free(p1);
p1 = TSdTrueMalloc(1000);
TSdAddTrustedPtr(p1);
printf("Freeing trusted
pointer.\n");
free(p1);
printf("Freeing formerly trusted
pointer.\n");
printf("[Forced error]:");
free(p1);
free(p2);
free(str);
}
#endif
#if
defined(TS_TESTSHELL_MALLO)
int main(int argc, tsLPSTR *argv)
{
if(argc < 2){
printf("Usage: tsdmallo '.'\n");
printf("(Test Shell for
tsdmallo)\n");
}
else{
test_tsdmallo();
}
return( 0 );
}
#endif
#endif
#endif
/********** Internal
Implementation: TSdMalloc **
End **/
/********** Internal
Implementation: TSdPRINTF **
Start **/
#if
defined(INCL_PRINT) && defined(INCL_TS_DEBUG_CODE)
#if
!defined(tsdprint_c)
#define tsdprint_c
#if
!defined(va_start)
#include <stdarg.h>
#endif
#define
is_formatchar(c) ((c)=='s')
#define
is_formatflag(c) ((c)=='%')
#define
PRINTF_FLAG_CHARS ".+-0#wl123456789" /* Note '.' may not be portable */
#define
TS_DEBUG_VAR
"TS_DEBUG_MODE"
#define
TSSCOPRightold \
"TSS_DEBUG: 0.00.02 Copr
(C) Trantor Standard Systems Inc. 1986-2003"
#define COPR_LEN 128
static char
TSSCpyr[COPR_LEN] = "";
char *GetTSScpyr()
{
sprintf(TSSCpyr," tsdebug: %i.%2.2i.%2.2i Copr (C) Bob Trower.
1986-2014",\
TS_VERMAJ, \
TS_VERMIN, \
TS_VERREL);\
return(TSSCpyr);
}
#define TSSCOPRight
((*TSSCpyr) == 0 ? GetTSScpyr() : TSSCpyr )
int
TSdDebugMode(void)
{
static int DebugMode = FALSE;
static int Initialized = FALSE;
if(!Initialized){
tsLPSTR DebugSwitch;
DebugSwitch=getenv(TS_DEBUG_VAR);
if(!DebugSwitch){
putenv( TS_DEBUG_VAR"=0"
);
DebugSwitch=getenv(TS_DEBUG_VAR);
}
DebugMode = atoi(DebugSwitch);
DebugMode = DebugMode ? DebugMode : TRUE;
fprintf( stderr, "%s --
DBG:%i\n", TSSCOPRight, DebugMode );
Initialized = TRUE;
}
return(DebugMode);
}
int
TSdDefPrintfOutPut(tsLPSTR Output)
{
int RetVal = 0;
fprintf(stdout, "%s",
TSdPadStr());
RetVal = fprintf(stdout, "%s",
Output);
fflush(stdout);
return(RetVal);
}
TSdPrintfOutputProcedure(TSdPrintfOutPut)
= TSdDefPrintfOutPut;
#define
TS_MAIL_HEADER "--- --- Message from Debug system --- Start ---\n"
#define
TS_MAIL_TRAILER "--- --- Message from Debug system --- End
---\n.\n"
#define
TSD_DEF_MAIL_FILE "/tmp/TSdTempMailFile"
#define
TS_MAIL_ADDRESS_VAR "TS_MAIL"
#define TSdDefaultMailAddress()
"MailForcedByMaximumDebugMode"
tsLPSTR
TSdMailAddress(void)
{
tsLPSTR MailAddress;
MailAddress = getenv(TS_MAIL_ADDRESS_VAR);
if(!MailAddress){
if(TSdDebugMode() >=
TSdMAX_DEBUG_MODE){
MailAddress = TSdDefaultMailAddress();
}
}
return(MailAddress);
}
tsLPSTR
TSdSetOutFileName(tsLPSTR Buf)
{
tsLPSTR LogName;
LogName = getenv("LOGNAME");
if(LogName){
sprintf(Buf, "%s.%s",
TSD_DEF_MAIL_FILE, LogName);
}
else {
sprintf(Buf, "%s.000",
TSD_DEF_MAIL_FILE);
}
return(Buf);
}
void
TSdSendMail(tsLPSTR OutFileName, tsLPSTR UserID)
{
char CmdBuf[TSdBUF_LEN_WORK_MEDIUM];
sprintf(CmdBuf, "mail %s<%s",
UserID, OutFileName);
/*
system(CmdBuf);
*/
}
void
TSdSendMailMsg(tsLPSTR Message)
{
char OutFileName[TSdMAX_FILE_NAME_LEN];
if(TSdSetOutFileName(OutFileName)){
FILE *OutFile = fopen(OutFileName,
"wt");
if(OutFile){
fprintf(OutFile,
"Subject:Message from LiveWire Debug\n");
fprintf(OutFile, TS_MAIL_HEADER);
fprintf(OutFile, "File:%s,
Line:%i\n", TSdGetContextFile(), TSdGetContextLine() );
fprintf(OutFile,
"Function:%s\n", TSdGetContextFunc() );
fprintf(OutFile, "Memory
Allocated:%li\n", (long)TSdGetContextTotMem() );
fprintf(OutFile, "%s",
Message);
fprintf(OutFile, TS_MAIL_TRAILER);
fclose(OutFile);
TSdSendMail(OutFileName,
TSdMailAddress());
remove(OutFileName);
}
}
}
tsLPSTR
TSdDefSetMsgBuf(tsLPSTR Buffer)
{
if(TSdMailAddress()){
sprintf(Buffer, "[SetMsg:Send Mail
to %s]", TSdMailAddress() );
}
else{
sprintf(Buffer, "[SetMsg:No Mail
Address]" );
}
return(Buffer);
}
tsLPSTR
TSdDefSetContextBuf(tsLPSTR Buffer)
{
sprintf(Buffer,
"[Context(Mem=%9.9li)]", (long)TSdGetContextTotMem());
return(Buffer);
}
tsLPSTR
TSdDefSetLogBuf(tsLPSTR Buffer)
{
sprintf(Buffer, "[SetLog:Not
Implemented]");
return(Buffer);
}
TSdSetBufferProcedure(TSdSetMsgBuf)
= TSdDefSetMsgBuf;
TSdSetBufferProcedure(TSdSetContextBuf)
= TSdDefSetContextBuf;
TSdSetBufferProcedure(TSdSetLogBuf)
= TSdDefSetLogBuf;
#define
TSD_MAX_USR_BUFFER_LEN 8192
#ifdef USR_GetStr
tsLPSTR TSdDefSetObjectBuf(void *Object,
tsLPSTR Buffer)
{
static tsLPSTR WrkBuffer = NULL;
if(!WrkBuffer){
WrkBuffer = (tsLPSTR )
malloc(TSD_MAX_USR_BUFFER_LEN * 4);
}
if(Object && WrkBuffer){
USR_GetStr(Object, WrkBuffer,
TSD_MAX_USR_BUFFER_LEN * 2);
strcpy(Buffer, WrkBuffer);
}
else{
*Buffer = 0;
}
return(Buffer);
}
#else
/* Create a default version of object proc
for testing */
tsLPSTR TSdDefSetObjectBuf(void *Object,
tsLPSTR Buffer)
{
if(Object){
sprintf(Buffer, "[%p]",
Object);
}
else{
*Buffer = 0;
}
return(Buffer);
}
#endif
TSdSetObjectProcedure(TSdSetObjectBuf)
= TSdDefSetObjectBuf;
static char fmtbuf[TSD_MAX_USR_BUFFER_LEN] =
"";
static char wrkbuf[TSD_MAX_USR_BUFFER_LEN] =
"";
static char outbuf[TSD_MAX_USR_BUFFER_LEN] =
"";
int TSdebug_Printf(const
tsLPSTR fmt, ...)
{
va_list
ap;
tsLPSTR p;
/*
char fmtbuf[TSD_MAX_USR_BUFFER_LEN] =
"";
char wrkbuf[TSD_MAX_USR_BUFFER_LEN] =
"";
char outbuf[TSD_MAX_USR_BUFFER_LEN] =
"";
*/
int i = 0;
int SendMailFlag = FALSE;
int DebugMode;
va_start(ap, fmt);
fmtbuf[0]=0;
wrkbuf[0]=0;
outbuf[0]=0;
DebugMode = TSdDebugMode(); /* Will pre-empt traversing print code if
FALSE */
for(p = (tsLPSTR )fmt;*p &&
DebugMode;p++){
fmtbuf[i]=*p;
if( is_formatflag( *p ) ){
int in_format = TRUE;
p++;
while(in_format){
switch(*p){
case '%':
i++;
fmtbuf[i] = *p;
in_format = FALSE;
break;
case '*':
{
char lenbuf[128];
sprintf(lenbuf,
"%d", va_arg(ap,int));
strcpy(&fmtbuf[i+1],lenbuf);
i = i +
strlen(lenbuf);
}
p++; /* Just strip out in this version */
break;
case 'Q': /* USR Object printing code */
TSdSetObjectBuf(va_arg(ap,void *), &fmtbuf[i]);
strcat(outbuf, fmtbuf);
wrkbuf[i] = 0;
i = 0;
fmtbuf[i] = 0;
in_format = FALSE;
break;
case 'D': /* Special debug printing code */
fmtbuf[i] = 0;
p++; /* Strip off 'D' */
switch(*p){
case 'c': /* Set Context Buffer */
TSdSetContextBuf(&fmtbuf[i]);
strcat(wrkbuf,
fmtbuf);
break;
case 'f': /* Set Function */
sprintf(&fmtbuf[i],"[%s]", TSdGetContextFunc());
strcat(wrkbuf,
fmtbuf);
break;
case 'l': /* Call Log function */
TSdSetLogBuf(&fmtbuf[i]);
strcat(wrkbuf,
fmtbuf);
break;
case 'm': /* Send Mail Message */
TSdSetMsgBuf(&fmtbuf[i]);
strcat(wrkbuf,
fmtbuf);
if(TSdMailAddress()){
SendMailFlag = TRUE;
}
break;
case 'd':
case 's':
sprintf(&fmtbuf[i],"[%s:%i]", TSdGetContextFile(),TSdGetContextLine());
strcat(wrkbuf,
fmtbuf);
break;
}
strcat(outbuf, wrkbuf);
wrkbuf[0] = 0;
i = 0;
fmtbuf[i] = 0;
in_format = FALSE;
break;
case 'c':
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
case 's':
case 'P':
case 'p':
i++;
fmtbuf[i] = *p;
i++;
fmtbuf[i] = 0;
switch(*p){
case 'c':
sprintf(wrkbuf,
fmtbuf, va_arg(ap,int));
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
sprintf(wrkbuf,
fmtbuf, va_arg(ap,double));
break;
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
if(fmtbuf[i-2]
== 'l'){
sprintf(wrkbuf, fmtbuf, va_arg(ap,long));
}
else{
sprintf(wrkbuf, fmtbuf, va_arg(ap,int));
}
break;
case 's':
case 'P':
case 'p':
sprintf(wrkbuf,
fmtbuf, va_arg(ap,void *));
break;
}
strcat(outbuf, wrkbuf);
wrkbuf[0] = 0;
i = 0;
fmtbuf[i] = 0;
in_format = FALSE;
break;
default:
if(strchr(PRINTF_FLAG_CHARS, *p)){
i++;
fmtbuf[i] = *p;
p++;
}
else {
in_format = FALSE;
}
break;
}
}
fmtbuf[i] = *p;
}
else {
fmtbuf[i] = *p;
i++;
}
}
va_end(ap);
fmtbuf[i] = 0;
strcat(outbuf, fmtbuf);
if( DebugMode ){
TSdPrintfOutPut(outbuf);
}
if(SendMailFlag){
TSdSendMailMsg(outbuf);
}
return(strlen(outbuf));
}
#if
defined(TS_TESTCODE)
void
test_tsdprint(void)
{
TSdPrintf(("Test1%Dc%Df%Dl%Dm\n"));
TSdPrintf(("TestStr%s%s%Dc\n",":","(str)"));
TSdPrintf(("TestInt%li%Dc\n",(long)999L));
TSdPrintf(("TestObj%Q%%\n","Q"));
}
#endif
#if
defined(TS_TESTSHELL_PRINT)
int main(int argc, tsLPSTR *argv)
{
if(argc < 2){
printf("Usage: tsdprint '.'\n");
printf("(Test Shell for
tsdprint)\n");
}
else{
test_tsdprint();
}
return( 0 );
}
#endif
#endif
#endif
/********** Internal
Implementation: TSdPRINTF ** End
**/
/********** Internal
Implementation: TSdLIST **
Start **/
#if
defined(INCL_LIST) && defined(INCL_TS_DEBUG_CODE)
#if
!defined(tsdlist_c)
#define tsdlist_c
#if !defined(max)
#include <stdlib.h>
#endif
#if !defined(size_t)
#include <stdio.h>
#include <string.h>
#endif
pTSdList
TSd_ListOfLists_ = NULL;
int
TSdDefCmpFuncStr(void *D1, void *D2)
{
return(strcmp(D1, D2));
}
int
TSdDefCmpFuncPtr(void *D1, void *D2)
{
int RetVal = 0;
if(D1 != D2){
if(D1 > D2){
RetVal = 1;
}
else {
RetVal = -1;
}
}
return(RetVal);
}
pTSdList
TSdDefNewList(TSdListProcedure(Proc), void *Data)
{
pTSdList List;
List = (pTSdList) malloc(sizeof(TSdList));
if(List){
List->Type = TSD_LIST_TYPE_ANY;
List->head = NULL;
List->tail = NULL;
List->curr = NULL;
List->Proc = Proc;
List->Compare = TSdDefCmpFuncPtr;
Proc(List, TSD_MSG_INI_LIST, Data);
}
return(List);
}
pTSdListNode
TSdDefNewNode(pTSdList List, void *Data)
{
pTSdListNode ListNode, CurrNode;
ListNode = (pTSdListNode)
malloc(sizeof(TSdListNode));
if(ListNode){
ListNode->next = NULL;
CurrNode = List->curr;
List->curr = ListNode;
List->Proc(List, TSD_MSG_INI_NODE,
Data);
List->curr = CurrNode;
}
return(ListNode);
}
pTSdListNode
TSdDefGetNode(pTSdList List, void *Data)
{
pTSdListNode Found = NULL;
if(List->head) {
for(List->curr =
List->head;List->curr && !Found;){
if(!(List->Compare(
List->curr->Data, Data))){
Found = List->curr;
}
else {
List->curr =
List->curr->next;
}
}
}
return(Found);
}
pTSdListNode
TSdDefAddNode(pTSdList List, pTSdListNode ListNode)
{
if(ListNode){
if(!List->head){
List->head = List->tail =
List->curr = ListNode;
}
else {
if(!List->curr){ /* No current value? -- add to front */
ListNode->next =
List->head;
List->head = ListNode;
}
else { /* Current value -- add after current
value */
ListNode->next =
List->curr->next;
List->curr->next =
ListNode;
if(List->tail->next){
List->tail =
List->tail->next;
}
}
List->curr = ListNode;
}
}
return(ListNode);
}
pTSdListNode TSdDefDelNode(pTSdList
List, pTSdListNode ListNode)
{
pTSdListNode ListCur = NULL;
if(List->head && ListNode){
pTSdListNode Found = NULL;
if(ListNode == List->head){
Found = ListNode;
List->head = List->head->next;
if(!List->head){
if(List->tail)
{free(List->tail);}
List->tail = NULL;
if(List->curr)
{free(List->curr);}
List->curr = NULL;
}
}
else {
List->curr = List->head;
while(List->curr->next
&& List->curr->next != ListNode){
List->curr =
List->curr->next;
}
if(List->curr->next ==
ListNode){
Found = ListNode;
List->curr->next =
ListNode->next;
if(ListNode == List->tail){
List->tail =
List->curr;
}
}
else {
if(List->curr !=
List->tail) {
free(List->curr);
List->curr =
List->tail;
}
}
}
ListCur = List->curr;
if(Found){
free(Found);
}
else {
free(ListNode);
}
}
return(ListCur);
}
typedef union
tagTSdSwapType /* Use to suppress
compiler warnings */
{
void *dp; /* As Data Pointer */
int (*fp)(void); /* As Function Pointer (still need
cast) */
} TSdSwapType;
void
*TSdDefListProc(pTSdList List, TSdMsgType Msg, void *Data)
{
void *ReturnValue = NULL;
switch(Msg){
case
TSD_MSG_NEW_LIST:
ReturnValue =
TSdDefNewList(TSdDefListProc, (tsLPSTR ) Data);
if(!List){
if(!TSd_ListOfLists()){
TSd_ListOfLists() =
TSdDefNewList(TSdDefListProc, "TSd_ListOfLists()");
TSdSetListIsList(TSd_ListOfLists());
}
List = TSd_ListOfLists();
}
TSdAddListNode(List,
ReturnValue);
break;
case
TSD_MSG_INI_LIST:
{
TSdSwapType st;
List->Name =
strdup((const tsLPSTR )Data);
st.fp = (int (*)(void))
TSdDefCmpFuncStr;
TSdSetCmpFunc( List, st.dp
);
}
break;
case
TSD_MSG_DEL_LIST:
if(!List) {
printf("Attempt to del
null list\n");
} else {
TSdEmptyList(List);
//#define doofr(x,
n) if(List->curr) { printf("List->%s-xxxxxxxxx\n", n); free(x);
} else {printf("List->%syyyyyyyyyyyyyyy\n", n);}
// doofr(List->Name,
"Name")
// doofr(List->curr,
"curr")
// doofr(List->tail,
"tail")
// doofr(List->head,
"head")
free(List);
List = NULL;
}
break;
case
TSD_MSG_EMT_LIST:
if(!List) {
printf("Attempt to del
null list\n");
} else {
List->curr =
List->tail;
TSdDelListNode(List,
List->curr);
while(TSdDelListNode(List,
List->curr));
}
break;
case
TSD_MSG_NEW_NODE:
ReturnValue = TSdDefNewNode(List, Data);
break;
case
TSD_MSG_INI_NODE:
List->curr->Data = Data;
break;
case
TSD_MSG_ADD_NODE:
ReturnValue =
TSdDefAddNode(List, Data);
break;
case
TSD_MSG_DEL_NODE:
ReturnValue =
TSdDefDelNode(List, Data);
break;
case
TSD_MSG_PUT_NODE:
break;
case
TSD_MSG_GET_NODE:
ReturnValue =
TSdDefGetNode(List, Data);
break;
case
TSD_MSG_SET_FCMP:
List->Compare =
(TSdCompareProcedureProt)((TSdGP *)&Data)->Func;
break;
default:
break;
}
return(ReturnValue);
}
#if
defined(TS_TESTCODE)
void
EnumerateList(pTSdList List)
{
static int depth =0;
int item = 0;
if(!List){
List = TSd_ListOfLists();
}
printf("%*.*s",depth,depth,"");
printf("Enumerating List:%s\n",
List->Name);
depth+=4;
if(TSdListIsList(List)){
pTSdList CurList;
for(List->curr =
List->head;List->curr;List->curr=List->curr->next){
CurList = (pTSdList)List->curr->Data;
EnumerateList(CurList);
}
}
else {
if(List->head) {
for(List->curr =
List->head;List->curr;List->curr=List->curr->next){
printf("%*.*s",depth,depth," ");
printf("Data in list item
%i:%s\n", ++item, List->curr->Data);
}
}
}
if(List->tail) {
List->curr = List->tail;
}
depth-=4;
}
void
PopulateList(pTSdList List)
{
if(List){
TSdAddListNode(List, "Item 1");
TSdAddListNode(List, "Item
2");
TSdAddListNode(List, "Item
3");
TSdAddListNode(List, "Item
4");
TSdAddListNode(List, "Item
5");
}
}
void
PopulateListR(pTSdList List)
{
if(List){
TSdAddListNode(List, "Item 1");
List->curr=NULL;
TSdAddListNode(List, "Item
2");
List->curr=NULL;
TSdAddListNode(List, "Item3
");
List->curr=NULL;
TSdAddListNode(List, "Item
4");
List->curr=NULL;
TSdAddListNode(List, "Item
5");
}
}
void
test_tsdlist(void)
{
pTSdList List1, List2, List3, List4, List5;
List1 = NULL, List2 = NULL, List3 = NULL,
List4 = NULL, List5 = NULL;
TSdFunctionBegin("test_tsdlist");
// List1 =
TSdNewList("Test-List-1"); TSdDisposeList(List1);
// List1 =
TSdNewList("Test-List-1"); TSdDisposeList(List1);
// List1 =
TSdNewList("Test-List-1"); TSdDisposeList(List1);
// List1 =
TSdNewList("Test-List-1"); TSdDisposeList(List1);
// List1 =
TSdNewList("Test-List-1"); TSdDisposeList(List1);
// List1 =
TSdNewList("Test-List-1");
List1 =
TSdNewList("Test-List-1"); TSdDisposeList(List1); List1 = NULL;
if(List1) {
// PopulateList(List1);
EnumerateList(List1);
if(List1->head) {
if(TSdGetListNode(List1,
List1->head->Data)){
printf("Found list item:
List1:'%s'\n", List1->curr->Data);
}
}
if(TSdGetListNode(List1, "Item
3")){
printf("Found list item:
List1:'%s'\n", List1->curr->Data);
} else {
printf("List is
empty\n");
}
//TSdDisposeList(List1);
//
TSdEmptyList(List1);
// EnumerateList(List1);
// PopulateListR(List1);
// TSdEmptyList(List1);
// PopulateList(List1);
// TSdEmptyList(List1);
TSdDisposeList(List1);
// List2 =
TSdNewList("Test-List-2");
if(List2) {
TSdSetListIsList(List2);
List3 = TSdAddList(List2,
"Test-List-3");
if(List3) {
TSdDisposeList(List3);
}
List4 = TSdAddList(List2,
"Test-List-4");
if(List4) {
TSdSetListIsList(List4);
List5 = TSdAddList(List4,
"Test-List-5");
if(List5){
PopulateListR(List5);
TSdEmptyList(List5);
PopulateList(List5);
EnumerateList(List5);
TSdEmptyList(List5);
TSdDisposeList(List5);
}
TSdDisposeList(List4);
}
TSdDisposeList(List2);
return(0);
}
}
TSdFunctionEnd("test_tsdlist");
}
#endif
#if
defined(TS_TESTSHELL_LIST)
int main(int argc, tsLPSTR *argv)
{
if(argc < 2){
printf("Usage: tsdlist '.'\n");
printf("(Test Shell for
tsdlist)\n");
}
else{
test_tsdlist();
}
return( 0 );
}
#endif
#endif
#endif
/********** Internal
Implementation: TSdLIST **
End **/
/********** Internal
Implementation: TSdTRACING **
Start **/
#if
defined(INCL_TRACE) && defined(INCL_TS_DEBUG_CODE)
#if !defined(tsdtrace_c)
#define tsdtrace_c
static pTSdList
TSdFuncCallStack = NULL;
#define
TSdSetFunctionName(FunctionName) TSdSetContextFunc(FunctionName)
#define
TSdGetFunctionName() TSdGetContextFunc()
pTSdList
TSdGetList(tsLPSTR Name)
{
pTSdList List = NULL;
List = TSd_ListOfLists();
if(List){
List = TSdGetListNode(List, Name);
}
if(!List){
List = TSdNewList(Name);
}
return(List);
}
#define
PrintStrIf(condition, fmt, val) if(condition){PrintStr(fmt,val);}
typedef struct
tTSdFuncName_tag {
struct tTSdFuncName_tag *next;
tsLPSTR Name;
size_t MemStart;
}TSdFuncName,
*pTSdFuncName;
pTSdFuncName
TSdNewFuncName(tsLPSTR Name)
{
pTSdFuncName Info = NULL;
Info = malloc(sizeof(TSdFuncName));
if(Info){
// printf("TSdNewFuncName:%s\n",
Name);
Info->Name = strdup(Name);
Info->MemStart =
TSdGetContextTotMem();
}
return(Info);
}
//#define
MAX_PTR_STACK 16384
//static char
*dbgptrstack[MAX_PTR_STACK] = {NULL};
//static int
ptrstackinit = 0;
//static int
ptrstackindex = 0;
//static char
*dbglastptr = "baseofstack";
//#define
pushdbgstack(x) \
// {\
// if(!ptrstackinit)
{\
//
ptrstackinit = 1;\
// }\
//
dbgptrstack[ptrstackindex] = x;\
//
ptrstackindex++;\
// }
//
//#define
popdbgstack() \
// {\
//
if(!ptrstackinit) {\
//
printf("Uninitialized dbgptrstack");\
// } else {\
// dbglastptr =
dbgptrstack[ptrstackindex++];\
//
dbgptrstack[ptrstackindex++] = x;\
//
ptrstackindex++;\
// }\
// }
int
TSdDisposeFuncName( pTSdFuncName Info )
{
int status = 0;
if(!Info){
TSdMPrintf2(("%Dc%Df%Dl%DmError --
attempt to deallocate null Info ptr\n"));
} else {
if(!Info->Name){
TSdMPrintf(("%Dc%Df%Dl%DmError
-- attempt to deallocate null Info->Name ptr\n"));
} else {
TSdMPrintf2(("=============<Name:'%s'\n",
Info->Name));
free(Info->Name);
status = 1;
}
free(Info);
}
return(status);
}
void
TSdPushFunctionName(tsLPSTR Name)
{
/* TSdFuncName *Info; */ /* Revisit RST*/
TSdMPrintf2(("=============>Name:'%s'\n",
Name));
if(!TSdFuncCallStack){
TSdFuncCallStack =
TSdNewList("Function Call Stack");
TSdSetCurContext("Function Name
Stack Base");
TSdPushFunctionName("Name");
}
if(TSdFuncCallStack){
TSdAddListNode(TSdFuncCallStack,
TSdNewFuncName( Name ));
TSdSetFunctionName(Name);
}
}
tsLPSTR
TSdPopFunctionName(void)
{
TSdFuncName *Info;
tsLPSTR Name = NULL;
if(!TSdFuncCallStack){
TSdMPrintf(("Attempt to pop empty
FunctionName stack\n", Name));
} else {
if(TSdFuncCallStack->tail){
Info =
(pTSdFuncName)TSdFuncCallStack->tail->Data;
TSdDelListNode(TSdFuncCallStack,
TSdFuncCallStack->tail);
/*
printf("Info->Name='%s'\n", Info->Name);
printf("%Df:Info->Mem=%i,
%i, [%i]\n", Info->MemStart, \
TSdGetContextTotMem(), \
TSdGetContextTotMem() -
Info->MemStart);
*/
printf( " [%i]<-- Net memory
allocated\n", \
TSdGetContextTotMem() -
Info->MemStart);
TSdDisposeFuncName(Info);
if(TSdFuncCallStack->curr){
Name =
TSdFuncCallStack->curr->Data;
}
}
if(Name){
int assigned = Name[0] != 'u' &&\
Name[1] != 'u'
&&\
Name[2] != 'u'
&&\
Name[3] != 'u';
char *FuncName = assigned ?
FuncName : "[Internal]";
TSdSetFunctionName(FuncName);
}
else{
TSdSetFunctionName(strdup("Unknown"));
}
}
return(TSdGetFunctionName());
}
#undef
USR_FunctionBegin
#undef
USR_FunctionEnd
extern int
USR_FunctionEnd(const tsLPSTR Name);
extern int
USR_FunctionBegin(const tsLPSTR Name);
int
TSdebug_FunctionBegin(const tsLPSTR FunctionName)
{
int RetVal;
static int TraceInitialized = FALSE;
if(!TraceInitialized){
if(TSdDebugMode() >=
TSdMAX_DEBUG_MODE){
TSdMemVerboseMode(TSdMAX_DEBUG_MODE);
/* Force other debug tracing on */
}
}
TSdPushFunctionName((tsLPSTR
)FunctionName);
#ifdef
TS_USR_CALLBACK
RetVal = USR_FunctionBegin(FunctionName);
#else
RetVal = 0;
#endif
printf("Starting function:%s\n",
TSdGetFunctionName());
TSdIncFunctionDepth();
return(RetVal);
}
int
TSdebug_FunctionEnd(const tsLPSTR FunctionName)
{
int RetVal;
tsLPSTR TS_FunctionName;
TSdDecFunctionDepth();
TS_FunctionName = TSdGetFunctionName();
if( TSdDebugMode() > 7 ){
if( strcmp( TS_FunctionName,
FunctionName ) ){
printf("End called as '%s',
", FunctionName );
}
}
printf("Leaving function:%s\n",
TS_FunctionName);
#ifdef
TS_USR_CALLBACK
RetVal = USR_FunctionEnd(FunctionName);
#else
RetVal = 0;
#endif
TSdPopFunctionName();
return(RetVal);
}
#if
defined(TS_TESTCODE)
int
USR_FunctionBegin(const tsLPSTR Name)
{
printf("USR_FunctionBegin('%s')\n", Name);
return(TRUE);
}
int
USR_FunctionEnd(const tsLPSTR Name)
{
printf("USR_FunctionEnd('%s')\n",
Name);
return(TRUE);
}
void
tsdtrace_internal_call(void)
{
TSdFunctionBegin("tsdtrace_internal_call");
printf("%Dc:Nothing happened
here\n");
TSdFunctionEnd("tsdtrace_internal_call");
}
void
test_tsdtrace(void)
{
TSdPrintf(("Context:%Dc\n"));
TSdFunctionBegin("test_tsdtrace");
TSdPrintf(("Context:%Dc\n"));
tsdtrace_internal_call();
tsdtrace_internal_call();
tsdtrace_internal_call();
tsdtrace_internal_call();
tsdtrace_internal_call();
TSdFunctionEnd("test_tsdtrace");
}
#endif
#if
defined(TS_TESTSHELL_TRACE)
int main(int argc, tsLPSTR *argv)
{
TSdFunctionBegin("main");
if(argc < 2){
printf("Usage: tsdtrace '.'\n");
printf("(Test Shell for
tsdtrace)\n");
}
else{
test_tsdtrace();
}
TSdFunctionEnd("main");
return( 0 );
}
#endif
#endif
#endif
/********** Internal
Implementation: TSdTRACING **
End **/
/********** Internal
Implementation: TSdDEBUG **
Start **/
#if
defined(TS_DEBUG) && defined(INCL_TS_DEBUG_CODE)
#if
defined(TS_TESTSHELL_TSDEBUG)
#define Printp(str) fputs(str, stdout)
void test_showhelp(void)
{
Printp("TSDEBUG Test
Shell\n");
Printp("\n");
Printp("Environment
settings:\n");
Printp("\n");
Printp("set
TS_DEBUG_MODE=1\n");
Printp("set TS_MAIL=<Mail Address>\n");
Printp("set
TS_MEMVERBOSE=1>\n");
Printp("\n");
}
void test_showuse(void)
{
printf(" tsd
(TS Debug test shell) Bob
Trower 2014-09-21\n");
printf(" Version %i.%2.2i\n", VERMAJ, VERMIN);
printf(" Usage:
tsd <Test> [opt]\n");
printf(" Purpose: This command will run unit tests on
the tsdebug\n");
printf(" debug wrapper.\n");
printf(" Tests:
'c' Test context\n");
printf(" 'l' Test list\n");
printf(" 'p' Test print\n");
printf(" 'm' Test malloc\n");
printf(" 't' Test trace\n");
printf(" 'h' Display help\n");
printf(" Options: '-s' do side call\n");
printf(" Example: tsd h\n");
printf(" Note:
Side call adds extra function calls to test\n");
printf(" the effect of additional function
calls.\n");
printf(" Note:
Debug functions use some resources so last\n");
printf(" displayed memory allocation is
greater than zero.\n");
printf(" Release: %i.%2.2i.%2.2i, Thu Oct 09 2014
12:04:05:10, ANSI-C\n", VERMAJ, VERMIN, VERREL);
}
/**
*
side call to exercise tracing code.
*/
void tsd_sidecall()
{
TSdFunctionBegin("tsd_sidecall");
{
TSdFunctionBegin("tsd_sidecall_localblock");
{
char *p1, *p2;
p1 = malloc(1000);
if(p1) {
TSdFunctionBegin("tsd_sidecall_localblock1");
p2 = malloc(10000);
if(p2) {
TSdFunctionBegin("tsd_sidecall_localblock2");
free(p2);
TSdFunctionEnd("tsd_sidecall_localblock2");
}
free(p1);
TSdFunctionEnd("tsd_sidecall_localblock1");
}
}
TSdFunctionEnd("tsd_sidecall_localblock");
}
TSdFunctionEnd("tsd_sidecall");
}
void tsd(char opt)
{
TSdFunctionBegin("tsd");
switch(opt){
case 'c': test_tsdcontx(); break;
case 'l': test_tsdlist(); break;
case 'p': test_tsdprint(); break;
case 'm': test_tsdmallo(); break;
case 't': test_tsdtrace(); break;
case 'h': test_showhelp(); break;
default: test_showuse();break;
}
TSdFunctionEnd("tsd");
}
#define Is_Opt(s, x)
(s && s[0] == '-' && s[1] == x ? x : 0)
int main(int argc, char **argv)
{
printf("main:Net Memory:%li\n",
(long) TSdGetContextTotMem());
TSdFunctionBegin("main");
printf("main:Net Memory:%li\n",
(long) TSdGetContextTotMem());
if(argc < 2){
test_showuse();
}
else{
printf("main:Net Memory:%li\n",
(long) TSdGetContextTotMem());
if(Is_Opt(argv[2],'s') == 's' ) {
tsd_sidecall(); }
printf("main:Net Memory:%li\n",
(long) TSdGetContextTotMem());
tsd(*argv[1]);
printf("main:Net Memory:%li\n",
(long) TSdGetContextTotMem());
if(Is_Opt(argv[2],'s') == 's' ) {
tsd_sidecall(); };
printf("main:Net Memory:%li\n",
(long) TSdGetContextTotMem());
}
TSdFunctionEnd("main");
printf("main:Net Memory:%li\n",
(long) TSdGetContextTotMem());
return( 0 );
}
#endif
#endif
/********** Internal
Implementation: TSdDEBUG **
End **/