
/***************************************************************************
**
**    $Header:   D:/EPSLDV1/SRC/LOG/SYMBLSVR.CPP   1.8   20 Jun 1996 09:27:00   ZJRD  $
**
**    $Log:   D:/EPSLDV1/SRC/LOG/SYMBLSVR.CPP  $
** 
**    Rev 1.8   20 Jun 1996 09:27:00   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.6   10 Jun 1996 10:21:38   ZJRD
** EasyPack/SLD Version 1.20
** 
**    Rev 1.4   29 May 1996 09:31:54   ZJRD
** EasyPack/SLD Version 1.95
** 
**    Rev 1.3   16 May 1996 09:03:06   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:14:38   ZJRD
** EasyPack/SLD Version 1.93
** 
**    Rev 1.1   02 May 1996 10:29:30   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 13:01:52   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.30   12 Apr 1996 10:38:50   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:51:44   Shirley
** EasyPack/SLD Version 1.01
** 
**    Rev 1.27   12 Feb 1996 14:06:12   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:32:44   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:46:58   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:13:34   Shirley
** EasyPack/SLD Version 0.35b
** 
**    Rev 1.23   26 Jan 1996 09:17:46   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:17:42   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:37:08   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:27:38   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.19   18 Jan 1996 10:10:54   Shirley
** EasyPack/SLD Version 0.34b
** 
**    Rev 1.17   04 Jan 1996 11:10:32   Shirley
** No change.
** 
**    Rev 1.16   30 Nov 1995 09:13:54   Shirley
** EasyPack/SLD Version 0.33
** 
**    Rev 1.15   28 Nov 1995 15:32:48   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:23:16   Shirley
** EasyPack/SLD Version 0.31
** 
**    Rev 1.13   13 Nov 1995 09:26:50   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:30:58   Shirley
** EasyPack/SLD Version 0.24
** 
**    Rev 1.11   08 Nov 1995 16:28:44   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:45:12   Shirley
** EasyPack/SLD Version 0.22
** 
**    Rev 1.9   02 Nov 1995 10:03:42   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:46:54   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:44:26   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:26:14   Shirley
** EasyPack/SLD Version 0.1f
** 
**    Rev 1.5   18 Oct 1995 14:48:56   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:21:12   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:49:10   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:56:46   Shirley
** No change.
** 
**    Rev 1.1   15 Sep 1995 09:49:28   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:53:26   Shirley
** Initial revision.
**
****************************************************************************/

/****************************************************************************
**
**  Name:  symblsrv.cpp
**
**  Description:
**      symbol server routines. symbol server extended 
**
**  Status:  CODE
**
**    Rev 1.0   1 Sept. 1995 8:30:00am   Gates Hua
** Initial revision.
**
**  Copyright (C) 1995 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include "stdafx.h"

#include "symblsvr.h"

#include "uicom.h"
#include "mempool.h"
#include "hosterrs.h"
#include "symget.h"
#include "symmgr.h"
#include "linenum.h"         
#include "ldr.h"
#include "stkinit.h"
#include "varinit.h"
#include "symsyn.h"
#include "symoptpr.h"
#include "symuser1.h"

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
char symsrvtbuf[256];

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
extern void ShowLine(char *);
extern void U16ToStr(U16 ui , char *tt);
extern void StrToU32(U32& ul , char *tt);
extern int SrcIsLoaded(void);
extern int SrcIsStatement(void);
extern int GetUserVarValue(char *str,short& value);

extern MemPool st;
extern class LoaderServer ldrObject;    // global load object .
extern class VarServer stkObject;
extern class VarServer varObject;
extern U32 uLoadBytes;
extern class SymUserVarTable userVariables;

extern int nSymModifyMemory;
                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/
RETCODE SymGetModuleNum(U16 FAR *numReturn) ;
void LowestBlockDesc(U32 addr, SYM_DESCRIPTOR& blockDesc);
int BlockAddrIsFunctionAddr(LPSTR str,ADDRESS_TYPE addr);
int CalcShellExp(int nArgc, char* pszArgv[]);

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
extern void ShowLine(char *);
extern void DisplayStack();
extern RETCODE
SymAddGetModuleName(SYM_DESCRIPTOR module, LPSTR modName);
extern RETCODE DisplayTypes(int flag);
extern RETCODE DisplaySortedSymbols();
extern RETCODE AddressOf(LPSTR cmdString);
extern int BuildCAddr( SEGMENTTYPE type , U32 addr , char* str );

/*************************
 ** SYMBOL ADD ROUTINES **
 *************************/
int SpaGetModule(CStringList* &pList)
{
    SYM_DESCRIPTOR *descArray;
    char temp[200];
    U16 numReturn , i;       
//    int len;            
    CString result;
                   
    if ( GOOD != SymGetModuleNum( &i ) ) {
        return FAILURE;
    }
    descArray = new SYM_DESCRIPTOR[ i+1 ];
    if ( descArray == NULL ) return FAILURE; 
    if (GOOD != SymGetAllModules(descArray,i,&numReturn)){
        delete []descArray;
        return FAILURE;
    }                         
    if ( numReturn == 0 ) {
        delete []descArray;
        return FAILURE;       
    }
    for ( i = 0; i < numReturn; i++ ) {
        if (!UtilIsValidSymDescriptor(descArray[i])) {
            delete descArray;
            return FAILURE;
        }
//        COMMON_SYMBOL_HEADER  *modPtr;

        memset( temp , 0 , 200 );
        if ( GOOD != SymAddGetModuleName(descArray[i],temp) ){
            delete []descArray;
            return FAILURE;     
        }          
        result = temp;
        pList->AddTail( result );
    }
    delete []descArray;
    
    return GOOD;
}

int SpaGetFunction(const CString& strModule, CStringList* &pList)
{              
    SYM_DESCRIPTOR descModule , desc;
    char *temp;
    HANDLE *pHdl;
    COMMON_BLOCK_HEADER  *modPtr;         
    CString str , result;
    
    str = strModule;

    if ( GOOD != SymGetModuleDesc(str.GetBuffer(str.GetLength()),
    	"",&descModule) ) return FAILURE;
    if (!UtilIsValidSymDescriptor( descModule )) {
        return FAILURE;
    }

    modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(descModule);
    desc = modPtr->child;
    while ( desc != NULL_SYMBOL ) {
        if (!UtilIsValidSymDescriptor( desc )) {
            return FAILURE;
        }     
	    temp = 0;
	    if ( GOOD != SymGetSymbolName( desc , &temp ) ) 
	        return FAILURE;         
	    result = temp;    
	    pList->AddTail( result );    
        if ( temp ) {
            pHdl = (HANDLE *)( temp - sizeof(HANDLE) );
            GlobalFree( *pHdl );
        }
        modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(desc);
        desc = modPtr->symHeader.symSiblingOffset;
    }                     
    return GOOD;
}

/* These include any routines that add symbol information to the database */
void WatchCmd(int nArgc, char* pszArgv[])
{
    CSymSyntax CExpress;     
    int nNum;
    
    nSymModifyMemory = 0;
    if ( nArgc != 2 ) return;
	CExpress.Init( pszArgv[1] );
	CExpress.GetErrorNum( nNum );
	if ( nNum ) {
//        ShowLine("Init Error!");
        CString strErr;
        if ( GOOD == ErrGetErrorText(ER_ID_EXP_INIT_ERR, strErr) ) {
            ShowLine(strErr.GetBuffer( strErr.GetLength() ) );
        }
        return;
	}
	
	if ( GOOD != CExpress.CheckSyntax() ) {
//      ShowLine("C Expression syntax error!");
        CString strErr;
        if ( GOOD == ErrGetErrorText(ER_ID_EXP_SYNTAX_ERR, strErr) ) {
            ShowLine(strErr.GetBuffer( strErr.GetLength() ) );
        }
        return;
	}
	if ( GOOD != CExpress.CalculateValue() ) {
//        ShowLine("C Expression calculate error!");
        CString strErr;
        if ( GOOD == ErrGetErrorText(ER_ID_EXP_CALC_ERR, strErr) ) {
            ShowLine(strErr.GetBuffer( strErr.GetLength() ) );
        }
        return;
	}                                      
	CExpress.DisplayValue();
    if ( nSymModifyMemory ) {
        RepaintStack();
        RepaintVariable();
    }
    return ;
}

int CheckExpressionStatus(char* pStr,BOOL& bResult)
{
    CSymSyntax CExpress;     
    int nNum;
    
	CExpress.Init( pStr );
	CExpress.GetErrorNum( nNum );
	if ( nNum ) {
		return FAILURE;
	}
	
	if ( GOOD != CExpress.CheckSyntax() ) {
		return FAILURE;
	}
	if ( GOOD != CExpress.CalculateValue() ) {
		return FAILURE;
	}          
	if ( GOOD != CExpress.GetStatus(bResult) ) {
		return FAILURE;
	}
    return GOOD;
}

void CalcCmd(int nArgc, char* pszArgv[])
{
    nSymModifyMemory = 0;
    if ( 0 != CalcShellExp(nArgc,pszArgv) ) {
//        ShowLine("Syntax Error!!");
        CString strErr;
        if ( GOOD == ErrGetErrorText(ER_ID_EXP_SHELL_SYNTAX_ERR, strErr) ) {
            ShowLine(strErr.GetBuffer( strErr.GetLength() ) );
        }
        return;
    }                           
    if ( nSymModifyMemory ) {
        RepaintStack();
        RepaintVariable();
    }
}
	
int CalcShellExp(int nArgc, char* pszArgv[])
{
    CSymSyntax CExpress;     
    int nNum;
    int nFlag;               
    char *p, *pTop;
    char c;
    char *pName;
	short value;
                    
    nFlag = 0;                
    if ( nArgc != 1 ) {
    	return FAILURE;
    }                           
    p = pszArgv[0];
    while( *p == ' ' ) {
    	p++;
    }
    if ( '$' != *p ) {
    	return FAILURE;
    }             
    pTop = p;              
    p++;	      

	c = *p;
	if ( (c!='_')&&(c!='?')&&((c>'z')||(c<'a'))&&((c>'Z')||(c<'A')) ) {
        return FAILURE;
    }       
    p++;
    nNum = 2;        
		 
    while( 1 ) {
        c = *p ;
		if ( ((c>'z')||(c<'a'))&&((c>'Z')||(c<'A')) ) {
			if ( (c!='_')&&(c!='?')&&((c<'0')||(c>'9')) ) {
				break;
//	        	return FAILURE;
	        }
	    }    
//	    else break;
	    p++;
	    nNum++;
    }                                                 

	while( ' ' == *p ) {
		p++;
	}
                       
	pName = new char[ nNum+1 ];
	if ( 0 == pName ) return FAILURE;
	memcpy( pName , pTop , nNum );
	pName[nNum] = '\0';
	
	if ( '\0' == *p	) {                                       
		if ( GOOD == GetUserVarValue(pName,value) ) {
			char temp[255];
	        sprintf(temp,"     %s = %d (0x%04x)",pName,value,value); 
	        ShowLine( temp );
	    }
	    else {
		    delete []pName;
	    	return FAILURE;
	    }
	    delete []pName;
	    return GOOD;
	}

	if ( '=' != *p ) {
	    delete []pName;
    	return FAILURE;
    }
    else {
    	p++;
		if ( '=' == *p ) {
		    delete []pName;
	    	return FAILURE;
	    }
	}
		
    if ( GOOD != GetUserVarValue(pName,value) ) {
		if ( GOOD == userVariables.SymUserVarCreate(pName) ) {
			nFlag = 1;
		}
		else {
			delete []pName;
		}
	}
	else if ( GOOD == userVariables.IsPC(pName) ) {
//        ShowLine("$PC can not be set value!");
        CString strErr;
        if ( GOOD == ErrGetErrorText(ER_ID_EXP_SET_PC, strErr) ) {
            ShowLine(strErr.GetBuffer( strErr.GetLength() ) );
        }
        return GOOD;
	}
	
	CExpress.Init( pszArgv[0] );
	CExpress.GetErrorNum( nNum );
	if ( nNum ) {     
		if ( nFlag ) userVariables.SymUserVarDelete(pName);
		delete []pName;
		return FAILURE;
	}
	
	if ( GOOD != CExpress.CheckSyntax() ) {
		if ( nFlag ) userVariables.SymUserVarDelete(pName);
		delete []pName;
		return FAILURE;
	}
	if ( GOOD != CExpress.CalculateValue() ) {
		if ( nFlag ) userVariables.SymUserVarDelete(pName);
		delete []pName;
		return FAILURE;
	}                                      
	if ( GOOD == GetUserVarValue(pName,value) ) {
		char temp[255];
        sprintf(temp,"     %s = %d (0x%04x)",pName,value,value); 
        ShowLine( temp );
    }
    else {
		if ( nFlag ) userVariables.SymUserVarDelete(pName);
	    delete []pName;
    	return FAILURE;
    }
    delete []pName;
    return GOOD;
}

RETCODE
SymAddSourceState(SOURCE_RANGE_TYPE *srcStatement,
                      ADDR_RANGE_TYPE   *codeAddrRange)
{
    LINENUM_TYPE linenum;
    U8 column;
    OFFSET_ADDR_TYPE addr;     
    if ( (codeAddrRange->startAddr == DEFAULT_START_ADDR) &&
         (codeAddrRange->endAddr == DEFAULT_END_ADDR) ) 
         return GOOD;
    if ( srcStatement->lineNumStart == srcStatement->lineNumEnd ) {
        linenum = srcStatement->lineNumStart;
        column = (U8) srcStatement->columnEnd;
    }                                        
    else if ( srcStatement->columnEnd == 1 ) {
//        linenum = srcStatement->lineNumEnd - 1;
//        column = (U8) 0;
        linenum = srcStatement->lineNumEnd;
        column = (U8) 1;
    } 
    else {      
        linenum = srcStatement->lineNumEnd;
        column = (U8) srcStatement->columnEnd;
    }
    addr = codeAddrRange->startAddr;
    return SymAddLinenum(linenum,column,addr);
}

void ModuleCmd(void)
{
    SYM_DESCRIPTOR *descArray;
    char temp[200];
    U16 numReturn , i;       
    int len;
                   
    if ( GOOD != SymGetModuleNum( &i ) ) {
        return ;
    }
    descArray = new SYM_DESCRIPTOR[ i+1 ];
    if ( descArray == NULL ) return ; 
    if (GOOD != SymGetAllModules(descArray,i,&numReturn)){
        delete descArray;
        return ;
    }                         
    if ( numReturn == 0 ) {
        delete descArray;
        return ;       
    }
    for ( i = 0; i < numReturn; i++ ) {
        if (!UtilIsValidSymDescriptor(descArray[i])) {
            delete descArray;
            return ;
        }
        COMMON_SYMBOL_HEADER  *modPtr;

        memset( temp , 0 , 200 );
        memset( temp , ' ' , 4 );
        modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(descArray[i]);
        if ( GOOD != SymAddGetModuleName(descArray[i],&temp[4]) ){
            delete descArray;
            return;     
        }   
        len = strlen(temp);
        sprintf(&temp[len],"    %lx %lx",
            modPtr->beginAddrInfo.startAddr ,
            modPtr->endAddrInfo.endAddr) ;
        ShowLine( temp );
    }
    delete descArray;
    
    return ;
}

void SymbolLineCmd(void)
{
    SYM_DESCRIPTOR *descArray;
    char temp[200];
    U16 numReturn , i;       
    int len;
    int nFlag;
    LINENUM_DESCRIPTOR index ;
                   
    if ( GOOD == SrcIsStatement() ) nFlag = 1;
    else nFlag = 0;
    
    if ( GOOD != SymGetModuleNum( &i ) ) {
        return ;
    }
    descArray = new SYM_DESCRIPTOR[ i+1 ];
    if ( descArray == NULL ) return ; 
    if (GOOD != SymGetAllModules(descArray,i,&numReturn)){
        delete descArray;
        return ;
    }                         
    if ( numReturn == 0 ) {
        delete descArray;
        return ;       
    }
    for ( i = 0; i < numReturn; i++ ) {
        if (!UtilIsValidSymDescriptor(descArray[i])) {
            delete descArray;
            return ;
        }
        COMMON_SYMBOL_HEADER  *modPtr;

        memset( temp , 0 , 200 );
        memset( temp , ' ' , 4 );
        modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(descArray[i]);
        if ( GOOD != SymAddGetModuleName(descArray[i],&temp[4]) ){
            delete descArray;
            return;     
        }   
        len = strlen(temp);
        sprintf(&temp[len],"    %lx %lx",
            modPtr->beginAddrInfo.startAddr ,
            modPtr->endAddrInfo.endAddr) ;
        if ( GOOD == SymGetLinenumFirstIndex(descArray[i],&index) ) {
            ShowLine( temp );                 
            if ( nFlag ) DisplayStatement( descArray[i] );
            else DisplayLinenum( descArray[i] );
        }
    }
    delete descArray;
    
    return ;
}

void LineCmd(int nArgc, char* pszArgv[])
{
    SYM_DESCRIPTOR *descArray;
    char temp[200];
    U16 numReturn , i;       
    int len;
    int nFlag;
    LINENUM_DESCRIPTOR index ;
                   
    if ( GOOD == SrcIsStatement() ) nFlag = 1;
    else nFlag = 0;
    
    if ( nArgc != 1 ) return;
    if ( !pszArgv[0][0] ) return;
    if ( GOOD != SymGetModuleNum( &i ) ) {
        return ;
    }
    descArray = new SYM_DESCRIPTOR[ i+1 ];
    if ( descArray == NULL ) return ; 
    if (GOOD != SymGetAllModules(descArray,i,&numReturn)){
        delete descArray;
        return ;
    }                         
    if ( numReturn == 0 ) {
        delete descArray;
        return ;       
    }
    for ( i = 0; i < numReturn; i++ ) {
        if (!UtilIsValidSymDescriptor(descArray[i])) {
            delete descArray;
            return ;
        }
        COMMON_SYMBOL_HEADER  *modPtr;

        memset( temp , 0 , 200 );
        memset( temp , ' ' , 4 );
        modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(descArray[i]);
        if ( GOOD != SymAddGetModuleName(descArray[i],&temp[4]) ){
            delete descArray;
            return;     
        }   
        len = strlen(temp);
        sprintf(&temp[len],"    %lx %lx",
            modPtr->beginAddrInfo.startAddr ,
            modPtr->endAddrInfo.endAddr) ;
        if ( GOOD == SymGetLinenumFirstIndex(descArray[i],&index) ) {
            ShowLine( temp );                 
            if ( nFlag ) DisplayStatement( descArray[i] );
            else DisplayLinenum( descArray[i] );
        }
    }
    delete descArray;
    
    return ;
}

void VoidCmd(int nArgc, char* pszArgv[])
{             
    if ( nArgc == 3 ) {
        DisplayStack();     
        return;
    }
    if ( nArgc == 1 ) {
        char temp1[256] , temp[1000];
        U32 numSymbols;
        U16 numModules;
        U32 numTypes;
        U32 numFuncs;
        U32 linenums;                                   
        U32 bytes;                                        
        int ii;
                        
        if ( GOOD != SrcGetLdrStats(temp1,&numSymbols,&numModules,
                    &numTypes,&numFuncs,&linenums,&bytes,&ii ) ) {
            return ;
        }                   
        else {
            sprintf(temp ,"Last Module Name : %s, Symbols : %ld ,Modules : %d , Types : %ld , Functions : %ld ,Linenums : %ld, percentage : %d",
            temp1,numSymbols,numModules,numTypes,numFuncs,linenums,ii);
            ShowLine( temp );
        }
        return;
    }                     
    if ( nArgc == 2 ) {
        varObject.AddVar( pszArgv[1] );
    }
    else if ( nArgc == 4 ) {
        varObject.UpdataAllNode();
        varObject.ShowVarToShell();
    }    
    else if ( nArgc == 6 ) {
//        struct VarNode *tt , *tt1;
        struct VarNode *tt ;
        
        tt = varObject.curVarNode ;
        while( tt ) {
            if ( (tt->flag&VAR_COMPLEX)&&(!(tt->flag&VAR_EXTEND)) )
                break;      
            if ( tt->son ) {
                tt = tt->son;
            }   
            else if ( tt->next ) {
                tt = tt->next;
            }    
            else if ( tt->father ) {
                tt = tt->father;
                while ( tt ) {
                    if ( tt->next ) {
                        tt = tt->next;
                        break;
                    }
                    tt = tt->father;
                }
            }
            else tt = 0;
        }
        varObject.VarExtendedNode( tt );
        varObject.ShowVarToShell();
    }       
    else {
        varObject.VarDeleteAll();
    }
/*
    if ( nArgc == 2 )
        AddressOf( pszArgv[1] );
    else 
        DisplaySortedSymbols();
*/      
}

void TypeCmd(int nArgc, char* pszArgv[])
{
    if ( nArgc != 1 ) return;
    if ( !pszArgv[0][0] ) return;
    DisplayTypes(1) ;
    DisplayTypes(0) ;
}

void CountCmd(int nArgc, char* pszArgv[])
{
    SYM_DESCRIPTOR *descArray;
    char temp[200];
    U16 numReturn , i;       
    int len;
                   
    if ( nArgc != 1 ) return;
    if ( !pszArgv[0][0] ) return;
    if ( GOOD != SymGetModuleNum( &i ) ) {
        return ;
    }
    descArray = new SYM_DESCRIPTOR[ i+1 ];
    if ( descArray == NULL ) return ; 
    if (GOOD != SymGetAllModules(descArray, i ,&numReturn)){
        delete descArray;
        return ;
    }                         
    if ( numReturn == 0 ) {
        delete descArray;
        return ;       
    }
    for ( i = 0; i < numReturn; i++ ) {
        if (!UtilIsValidSymDescriptor(descArray[i])) {
            delete descArray;
            return ;
        }
        COMMON_SYMBOL_HEADER  *modPtr;

        memset( temp , 0 , 200 );
        memset( temp , ' ' , 4 );
        modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(descArray[i]);
        if ( GOOD != SymAddGetModuleName(descArray[i],&temp[4]) ){
            delete descArray;
            return;     
        }   
        len = strlen(temp);
        sprintf(&temp[len],"    %lx %lx",
            modPtr->beginAddrInfo.startAddr ,
            modPtr->endAddrInfo.endAddr) ;
        ShowLine( temp );                 
        DisplayStatement( descArray[i]);
    }
    delete descArray;
    
    return ;
}

int SrcGetModuleNum(U16& num)
{
//    SYM_DESCRIPTOR *descArray;
    U16 numReturn ;       
                   
    if ( GOOD != SymGetModuleNum( &numReturn ) ) {
        return -1;
    }
    num = numReturn;
    
    return 0;
}

int SrcGetModuleName(U32 moduleDesc , LPSTR str)
{
    if ( GOOD != SymAddGetModuleName(moduleDesc,str) ){
        return -1;      
    }   
    return 0;
}                   

int SrcGetModuleRange(U32 moduleDesc , U32& start , U32& end)
{
    char moduleName[256];
    ADDR_RANGE_TYPE moduleAddrRange ;

    if ( GOOD != SymGetModule(moduleDesc,moduleName,&moduleAddrRange) ){
        return -1;      
    }   
    start = moduleAddrRange.startAddr ;
    end = moduleAddrRange.endAddr ;
    return 0;
}                   

int SrcGetModuleIndex(U16 num , U32* buffer , U16& returnNum)
{
//    SYM_DESCRIPTOR *descArray;
//    U16 numReturn , i;       
    U16 numReturn;       
//    LINENUM_DESCRIPTOR index ;
                   
    returnNum = 0;
//    descArray = new SYM_DESCRIPTOR[ num+1 ];
//    if ( descArray == NULL ) return FAILURE; 
    if ( buffer == NULL ) return FAILURE; 
//    if (GOOD != SymGetAllModules(descArray,num,&numReturn)){
    if (GOOD != SymGetAllModules(buffer,num,&numReturn)){
//        delete descArray;
        return FAILURE;
    }                         
    if ( numReturn == 0 ) {
//        delete descArray;
        return FAILURE;       
    }                         
/*    
    for ( i = 0; i < numReturn; i++ ) {
        if ( GOOD == SymGetLinenumFirstIndex(descArray[i],&index) ) {
            memcpy(&buffer[returnNum],&descArray[i],sizeof(U32));
            returnNum++;
        }
    }
*/    
//    delete descArray;
    
//    if ( returnNum == 0 ) return FAILURE;
	returnNum = numReturn;
    return GOOD;
}

int SrcCheckModuleHasLineInfo(SYM_DESCRIPTOR desc)
{
    LINENUM_DESCRIPTOR index ;
	if ( !UtilIsValidSymDescriptor(desc) ) return GOOD;
    if ( GOOD == SymGetLinenumFirstIndex(desc,&index) ) {
		return GOOD;
    }               
    return FAILURE;
}

int SrcAddr2Linenum(U32 addr , U16& linenum , U32& moduleDesc)
{
//  ADDRESS_TYPE lineAddr;
    SYM_DESCRIPTOR modDesc;
    ADDR_RANGE_TYPE modRange;
    LINENUM_TYPE line;
    COLUMN_TYPE column;
    ADDR_RANGE_TYPE addrRange;
    LINENUM_DESCRIPTOR index;
    
//  lineAddr.addr = addr;
//  lineAddr.segType = (SEGMENTTYPE) SEG_CODE;
    if ( GOOD != SymMapAddr2LinenumModule(
//      lineAddr,    &modDesc, &modRange,  &line,
        addr,    &modDesc, &modRange,  &line,
        &column,     &addrRange, &index) )  {
        return -1;
    }
    linenum = line;
    moduleDesc = modDesc;
    return 0;
}

int SrcAddr2LinenumRange(U32 addr,U16& linenum,U32& startAddr,U32& endAddr)
{
    SYM_DESCRIPTOR modDesc;
    ADDR_RANGE_TYPE modRange;
    LINENUM_TYPE line;
    COLUMN_TYPE column;
    ADDR_RANGE_TYPE addrRange;
    LINENUM_DESCRIPTOR index;
    
    if ( GOOD != SymMapAddr2LinenumModule(
        addr,    &modDesc, &modRange,  &line,
        &column,     &addrRange, &index) )  {
        return -1;
    }
    linenum = line;
    startAddr = addrRange.startAddr ;
    endAddr = addrRange.endAddr ;
    return 0;
}

int SrcAddr2Statement(U32 addr,U16& linenum,U16& startCol,
                    U16& endCol,U32& moduleDesc)
{
//  ADDRESS_TYPE lineAddr;
    SYM_DESCRIPTOR modDesc;
    ADDR_RANGE_TYPE modRange;
    LINENUM_TYPE line;
    COLUMN_RANGE_TYPE columnRange;
//COLUMN_TYPE column;
    ADDR_RANGE_TYPE addrRange;
    LINENUM_DESCRIPTOR index;
    
    if ( GOOD != SymMapAddr2LinenumStmtModule(
        addr,    &modDesc, &modRange,  &line,
        &columnRange,  &addrRange, &index) )  {
        return -1;
    }
    linenum = line;  
    startCol = columnRange.columnStart;
    endCol = columnRange.columnEnd;
    moduleDesc = modDesc;
    return 0;
}

int SrcAddr2StatementRange(U32 addr,U16& linenum,U16& startCol,
        U16& endCol,U32& startAddr,U32& endAddr)
{
    SYM_DESCRIPTOR modDesc;
    ADDR_RANGE_TYPE modRange;
    LINENUM_TYPE line;
    COLUMN_RANGE_TYPE columnRange;
    ADDR_RANGE_TYPE addrRange;
    LINENUM_DESCRIPTOR index;
    
    if ( GOOD != SymMapAddr2LinenumStmtModule(
        addr,    &modDesc, &modRange,  &line,
        &columnRange,  &addrRange, &index) )  {
        return -1;
    }

    linenum = line;
    startAddr = addrRange.startAddr ;
    endAddr = addrRange.endAddr ;
    startCol = columnRange.columnStart;
    endCol = columnRange.columnEnd;
    return 0;
}

BOOL IsLibFunction( unsigned short uAddr )
{
    U16 addr;
    U16 linenum;
    U32 startAddr , endAddr ;

    addr = (U16) uAddr ;
    if ( GOOD == SrcAddr2LinenumRange(addr , linenum , startAddr , endAddr) ) {
        return FALSE ;
    }
    else return TRUE;
}

void GetStatementRange(unsigned short uAddr , unsigned short& uStart ,
                                         unsigned short& uEnd )
{
    U16 addr;
    U16 linenum;
    U32 startAddr , endAddr ;
    U16 startCol , endCol;

    addr = (U16) uAddr ;
    SrcAddr2StatementRange(addr,linenum,startCol,endCol,
                            startAddr, endAddr);
    if ( startAddr > endAddr ) {
        uStart = uEnd = uAddr;
    }
    else {                        
        uStart = (unsigned short) startAddr ;
        uEnd = (unsigned short) endAddr ;
    }
}

void GetLineRange(unsigned short uAddr , unsigned short& uStart ,
                                         unsigned short& uEnd )
{
    U16 addr;
    U16 linenum;
    U32 startAddr , endAddr ;

    addr = (U16) uAddr ;
    SrcAddr2LinenumRange(addr , linenum , startAddr , endAddr);
    if ( startAddr > endAddr ) {
        uStart = uEnd = uAddr;
    }
    else {                        
        uStart = (unsigned short) startAddr ;
        uEnd = (unsigned short) endAddr ;
    }
}

int SrcAddr2LinenumStart(U32 addr , U16& linenum , U32& moduleDesc)
{
//  ADDRESS_TYPE lineAddr;
    SYM_DESCRIPTOR modDesc;
    ADDR_RANGE_TYPE modRange;
    LINENUM_TYPE line;
    COLUMN_TYPE column;
    ADDR_RANGE_TYPE addrRange;
    LINENUM_DESCRIPTOR index;
    
//  lineAddr.addr = addr;
//  lineAddr.segType = (SEGMENTTYPE) SEG_CODE;
    if ( GOOD != SymMapAddr2LinenumModule(
//      lineAddr,    &modDesc, &modRange,  &line,
        addr,    &modDesc, &modRange,  &line,
        &column,     &addrRange, &index) )  {
        return -1;
    }                   
    if ( addr != addrRange.startAddr ) return( -1 );
    linenum = line;
    moduleDesc = modDesc;
    return 0;
}
    
int SrcLinenum2Addr(U32 moduleDesc , U16 linenum , U32& addr)
{
    SYM_DESCRIPTOR modDesc;
    LINENUM_TYPE line;
    ADDR_RANGE_TYPE addrRange;
    LINENUM_TYPE    actualLinenum;
    COLUMN_TYPE     actualColumn;
    LINENUM_DESCRIPTOR  nextIndex;
    
    modDesc = moduleDesc;
    line = linenum; 
    if ( GOOD != SymGetLinenum(modDesc,  line,
        &addrRange, &actualLinenum, &actualColumn, &nextIndex) ) {
        return -1;
    }
    if ( linenum != actualLinenum ) {
        return -1;
    }
    addr = addrRange.startAddr;
    return 0;
}    

int SrcLinenum2Range(U32 moduleDesc,U16 linenum,
        U32& startAddr , U32& endAddr)
{
    SYM_DESCRIPTOR modDesc;
    LINENUM_TYPE line;
    ADDR_RANGE_TYPE addrRange , addrRange1;
    LINENUM_TYPE    actualLinenum;
    COLUMN_TYPE     actualColumn;
    LINENUM_DESCRIPTOR  nextIndex , index;
    
    modDesc = moduleDesc;
    line = linenum; 
    if ( GOOD != SymGetLinenum(modDesc,  line,
        &addrRange, &actualLinenum, &actualColumn, &nextIndex) ) {
        return -1;
    }
    if ( linenum != actualLinenum ) {
        return -1;
    }                                    
    index = nextIndex;
    while( GOOD == SymGetLinenumByIndex(moduleDesc,
                     index,
                     &addrRange1,
                     &nextIndex,
                     &line,
                     &actualColumn) ) {
        if ( line == linenum ) {
            if ( addrRange.startAddr > addrRange1.startAddr )
                addrRange.startAddr = addrRange1.startAddr;
            if ( addrRange.endAddr < addrRange1.endAddr )
                addrRange.endAddr = addrRange1.endAddr;
        }
        index = nextIndex;
    }                     
    
    startAddr = addrRange.startAddr;
    endAddr = addrRange.endAddr;
    return 0;
}    

void DisplayLinenum( SYM_DESCRIPTOR moduleDesc ) 
{
    LINENUM_DESCRIPTOR nextIndex , index ;
    ADDR_RANGE_TYPE addrRange;
    LINENUM_TYPE linenum;
    COLUMN_TYPE column; 
    char temp[100];
    if ( GOOD != SymGetLinenumFirstIndex(moduleDesc,&index) ) {
        return ;
    }
    while( GOOD == SymGetLinenumByIndex(moduleDesc,
                     index,
                     &addrRange,
                     &nextIndex,
                     &linenum,
                     &column) ) {
//        sprintf(temp,"    %u %u %lx %lx" , linenum ,  column ,
//                addrRange.startAddr , addrRange.endAddr);
        sprintf(temp,"    line %u : start addr %lx --- end addr %lx" , linenum ,
                addrRange.startAddr , addrRange.endAddr);
        ShowLine( temp );
        index = nextIndex;
    }                     
    return;
}   

void DisplayStatement( SYM_DESCRIPTOR moduleDesc ) 
{
    LINENUM_DESCRIPTOR nextIndex , index ;
    ADDR_RANGE_TYPE addrRange;
    LINENUM_TYPE linenum;
    COLUMN_RANGE_TYPE columnRange;
//  COLUMN_TYPE column; 
    char temp[100];
    if ( GOOD != SymGetLinenumFirstIndex(moduleDesc,&index) ) {
        return ;
    }
    while( GOOD == SymGetLinenumStmtByIndex(moduleDesc,
                     index,
                     &addrRange,
//                     &nextIndex,
                     &linenum,
                     &columnRange,
                     &nextIndex ) ) {
//        sprintf(temp,"    %u %u %u %lx %lx" , linenum ,
//                columnRange.columnStart , columnRange.columnEnd ,
//                addrRange.startAddr , addrRange.endAddr);
        sprintf(temp,"    line %u start col %u end col %u : start addr %lx --- end addr %lx" , linenum ,
                columnRange.columnStart , columnRange.columnEnd ,
                addrRange.startAddr , addrRange.endAddr);
        ShowLine( temp );
        index = nextIndex;
    }                     
    return;
}   

RETCODE SymGetModuleNum(U16 FAR *numReturn) {

   HPU8 ptr;
//   SYM_DESCRIPTOR headDesc, nextDesc, *tmpPtr;
   SYM_DESCRIPTOR headDesc, nextDesc;
   RETCODE err;

   // if the modulesList is empty we're done
   *numReturn = 0;
   
   // get the module head descriptor
   if ((err = SymGetModuleListHead(&headDesc)) != GOOD)
      return err;
   
   // make sure the symbol descriptor is ok
   if (!UtilIsValidSymDescriptor(headDesc))
      return ER_INVALID_SYM_DESCRIPTOR;

   ptr=st.GetHugeDataPtr(headDesc);
   // make sure it is module type
   if (SYM_MODULE != (((COMMON_SYMBOL_HEADER *)ptr)->typeIndex.symType & 0xF))
      return ER_SYMBOL_HAS_NO_LISTS;
   *numReturn = 1;
   // get all modules until reach NULL_DESCRIPTOR or 
   while (((nextDesc =
          ((COMMON_BLOCK_HEADER *)ptr)->symHeader.symSiblingOffset)
                       != NULL_SYMBOL) ) {
      ++(*numReturn);                    // count it 
      ptr = st.GetHugeDataPtr(nextDesc); // advance to next one
   }
       
   return GOOD;
}  // end of SymGetAllModules

int SpaGetRangeEnd(const CString& strSymbol, CString& strEnd)
{
    RETCODE           err;
    ADDR_RANGE_TYPE   addrRange;
    SYM_DESCRIPTOR    symDesc = 0L;
    LINENUM_TYPE      actualLinenum;
    COLUMN_RANGE_TYPE actualColumnRange;
    LPSTR             lpParam;
    char              *tt;
    char              temp[100];
    int i , j;

    tt = new char [ strSymbol.GetLength()+2 ];
    strcpy( tt , strSymbol );
    lpParam = tt;
    err = SymGetAddrFromName(lpParam,
                            SYM_UNKNOWN_ADDR,
                            &symDesc,
                            &addrRange,
                            &actualLinenum,
                            &actualColumnRange);
    delete tt;
    if ( err != GOOD ) {
	    tt = new char [ strSymbol.GetLength()+3 ];
	    strcpy( tt , strSymbol );
        i = strSymbol.GetLength();
        j = i;
        while( j ) {
            if ( tt[j-1] == '#') {
                for(int ii=i;ii>=j;ii--) {
                    tt[ii] = tt[ii-1];
                }
                tt[j] = '_';
                lpParam = tt;
                err = SymGetAddrFromName(lpParam,
                                        SYM_UNKNOWN_ADDR,
                                        &symDesc,
                                        &addrRange,
                                        &actualLinenum,
                                        &actualColumnRange);
                delete tt;
                if ( err != GOOD ) return FAILURE;
                break;
            }
            j--;
        }
        if ( j == 0 ) return FAILURE;
    }
    
	if ( GOOD != BuildCAddr(addrRange.segType,addrRange.endAddr,temp) ) {
		return FAILURE;
	}
	else {
		strEnd = temp;
	}		
    return GOOD ;
}

RETCODE SymServerSymToAddr(char *lpStr , U8* lpType , U32 * lpAddr)
{
    RETCODE           err;
    ADDR_RANGE_TYPE   addrRange;
    SYM_DESCRIPTOR    symDesc = 0L;
    LINENUM_TYPE      actualLinenum;
    COLUMN_RANGE_TYPE actualColumnRange;
    LPSTR             lpParam;
    char              *tt;
    int i , j;

    tt = new char [ strlen(lpStr)+1 ];
    strcpy( tt , lpStr );
//    lpParam = lpStr;                               
    lpParam = tt;
    err = SymGetAddrFromName(lpParam,
                            SYM_UNKNOWN_ADDR,
                            &symDesc,
                            &addrRange,
                            &actualLinenum,
                            &actualColumnRange);
    delete tt;
//  if ( err != GOOD ) return( err );
    if ( err != GOOD ) {
//        delete tt;
        tt = new char[ strlen(lpStr)+2 ];
        strcpy( tt, lpStr );
        i = strlen(lpStr);
        j = i;
        while( j ) {
            if ( tt[j-1] == '#') {
                for(int ii=i;ii>=j;ii--) {
                    tt[ii] = tt[ii-1];
                }
                tt[j] = '_';
                lpParam = tt;
                err = SymGetAddrFromName(lpParam,
                                        SYM_UNKNOWN_ADDR,
                                        &symDesc,
                                        &addrRange,
                                        &actualLinenum,
                                        &actualColumnRange);
                delete tt;
                if ( err != GOOD ) return( err );
                break;
            }
            j--;
        }
        if ( j == 0 ) return (err);
    }

    switch( addrRange.segType ) {
    case SEG_CODE :
        *lpType = 1;
        break;
    case SEG_DATA :
        *lpType = 3;
        break;
    case SEG_XDATA :
        *lpType = 2;
        break;
    case SEG_BIT :
        *lpType = 5;
        break;
    case SEG_REGISTER :
        *lpType = 4;
        break;
    default :
        *lpType = 0;
        break;
    }
    *lpAddr = addrRange.startAddr;
    return GOOD ;
}

RETCODE SymServerAddrToSym(U8 type , U32 addr , char *lpStr)
{
   RETCODE    err;
   BOOLEAN    noSymbolsLoaded;
//   char       *tt;
   ADDRESS_TYPE   inputAddr;
   MEM_ADDR_CLASS memoryClass;
   SYM_TYPE_TYPE  symbolType;
   U32            offset;
   SYM_DESCRIPTOR outputSymbol;
   SYM_DESCRIPTOR funcDescriptor;
   SYM_DESCRIPTOR moduleDescriptor;
   HANDLE *pHdl;
   
   if (GOOD != (err = SymCheckForNoSymbols(&noSymbolsLoaded)))
      return FAILURE;
   if (noSymbolsLoaded) {
      return FAILURE;  // reports "no symbols are loaded"
   }
                      
   inputAddr.addr = addr;   
   inputAddr.segType = (SEGMENTTYPE) SEG_CODE;
   switch ( type ) {
   case 2 :
        inputAddr.segType = (SEGMENTTYPE) SEG_XDATA;
        break;
   case 3 :
        inputAddr.segType = (SEGMENTTYPE) SEG_DATA;
        break;
   case 4 :
        inputAddr.segType = (SEGMENTTYPE) SEG_REGISTER;
        break;
   case 5 :
        inputAddr.segType = (SEGMENTTYPE) SEG_BIT;
        break;
   default :
        break;
   }
            
   if ( GOOD != SymMapAddr2Symbol(inputAddr,
                  &memoryClass,
                  &symbolType,
                  &offset,
                  &outputSymbol,
                  &funcDescriptor,
                  &moduleDescriptor) ) {
        return FAILURE ;
    }    
   
    if ( offset != 0 ) return FAILURE ;

    char *temp1;
    
    temp1 = 0;
    if ( GOOD != SymGetSymbolName( outputSymbol ,
                                   &temp1 ) ) 
        return FAILURE;         
    
    if( *temp1 == '\0' ) {
        if ( temp1 ) {
            pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
            GlobalFree( *pHdl );
        }
        temp1 = 0;
        if ( GOOD != SymGetSymbolName( funcDescriptor ,
                                       &temp1 ) ) 
            return FAILURE;         
        if ( GOOD != BlockAddrIsFunctionAddr(temp1, inputAddr) )
            return FAILURE;
    }
    
    if( *temp1 == '\0' ) {
        if ( temp1 ) {
            pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
            GlobalFree( *pHdl );
        }
        temp1 = 0;
        return FAILURE;
    }

    if ( *temp1 == '?' ) {
        if ( temp1 ) {
            pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
            GlobalFree( *pHdl );
        }
        return FAILURE;
    }    
    sprintf(lpStr,"#%s",temp1);


    if ( temp1 ) {
        pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
        GlobalFree( *pHdl );
    }
//  if ( temp2 ) delete temp2;
   return GOOD;
}

int BlockAddrIsFunctionAddr(LPSTR str,ADDRESS_TYPE addr)
{
char *tt;                              
U8 tType;
U32 tAddr;

    tt = new char[ strlen(str)+3 ];
    if ( tt == 0 ) return FAILURE;
    sprintf(tt , "#%s" , str ); 
    if ( GOOD != SymServerSymToAddr(tt,&tType ,&tAddr) ) {
        if (tt) delete tt;
        tt = 0;
        return FAILURE;   
    }
    
    if( tt ) delete tt;
    tt = 0; 
        
    if ( tAddr != addr.addr ) return FAILURE;
    if ( (tType != 1)||(addr.segType != SEG_CODE) ) return FAILURE;
    return GOOD;    

}

int SrcGetLdrStats(LPSTR moduleName,U32 *numSymbols,U16 *numModules,
    U32 *numTypes , U32 *numFuncs , U32 *linenums , U32 *bytes , int *percent)
{
//    *bytes = 0;
    *bytes = uLoadBytes;
    *numFuncs = 0;
    *linenums = 0;
    *numSymbols = 0;
    *numModules = 0;
    *numTypes = 0;
    *moduleName = '\0';
    if ( SrcIsLoaded() == GOOD ) {
        *percent = 100;
    }
    else {       
        long l1 , l2;
        ldrObject.GetFileLength( l1 );
        ldrObject.GetFileCurPos( l2 );   
//        if ( l2 > l1 ) *percent = 95;
        if ( l2 > l1 ) *percent = 100;
        else if ( l2 > 0x800000 ) {
            *percent = (int) ( ( (l2>>8)*100 ) / (l1 >> 8 ) );
        }
        else if ( l1 == 0 ) *percent = 0;
        else *percent = (int) ( (l2*100)/l1 ); 
    }       

    if ( GOOD != SymGetLdrStats(moduleName,numSymbols,numModules,
                   numTypes) ) {
        *numSymbols = 0;           
        *numModules = 0;
        *numTypes = 0;
        return GOOD;  
//        return FAILURE;
    }                   
    if ( (*numModules==0)&&(*numSymbols==1)&&(*numTypes==0xff) ) {
        *numSymbols = 0;           
        *numModules = 0;
        *numTypes = 0;
        return GOOD;  
//        return FAILURE;
    }                   
                                                              
//    *bytes = 0;                                                          
//    *numFuncs = 0;
//    *linenums = 0;

    SYM_DESCRIPTOR *descArray;
//    char temp[200];
    U16 numReturn , i;       
//    int len;
                   
    if ( GOOD != SymGetModuleNum( &i ) ) {
//        return FAILURE;
        return GOOD;
    }
    descArray = new SYM_DESCRIPTOR[ i+1 ];
    if ( descArray == NULL ) return FAILURE; 
    if (GOOD != SymGetAllModules(descArray,i,&numReturn)){
        delete descArray;
//        return FAILURE;
        return GOOD;
    }                         
    if ( numReturn == 0 ) {
        delete descArray;
//        return FAILURE;       
        return GOOD;
    }
    for ( i = 0; i < numReturn; i++ ) {
        if (!UtilIsValidSymDescriptor(descArray[i])) {
            delete descArray;
            return GOOD;
//            return FAILURE;
        }
        COMMON_SYMBOL_HEADER  *modPtr;
        SYM_TYPE_MODULE *modulePtr;

        modulePtr = (SYM_TYPE_MODULE *)st.GetHugeDataPtr(descArray[i]);

        if (modulePtr->linenumOffsetEnd>modulePtr->linenumOffsetStart)
            *linenums=*linenums+(U16)(((modulePtr->linenumOffsetEnd-
               modulePtr->linenumOffsetStart)/LINENUM_STRUCT_SIZE)+ 1);
//        if (modulePtr->symHeader.symHeader.beginAddrInfo.startAddr <=
//            modulePtr->symHeader.symHeader.endAddrInfo.endAddr ) {
//            *bytes=*bytes+modulePtr->symHeader.symHeader.endAddrInfo.endAddr-
//                modulePtr->symHeader.symHeader.beginAddrInfo.startAddr+1;
//        }
        if ( modulePtr->symHeader.child != NULL_SYMBOL ) {
            if (!UtilIsValidSymDescriptor( modulePtr->symHeader.child )) {
                delete descArray;
                return GOOD;
//                return FAILURE;
            }
            modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                modulePtr->symHeader.child);
            if ( ((modPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION )
                *numFuncs = *numFuncs+1;
            while ( modPtr->symSiblingOffset != NULL_SYMBOL ) {
                if (!UtilIsValidSymDescriptor( modPtr->symSiblingOffset )) {
                    delete descArray;
//                    return FAILURE;
                    return GOOD;
                }
                modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                    modPtr->symSiblingOffset);
                if ( ((modPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION )
                    (*numFuncs)++ ;
            }
        }
    }
    delete descArray;
    return GOOD;
}

int SrcGetFirstFuncIndex(SYM_DESCRIPTOR moduleDesc,
    SYM_DESCRIPTOR& funcDesc)
{
    COMMON_SYMBOL_HEADER  *modPtr;
    SYM_TYPE_MODULE *modulePtr;

    if (!UtilIsValidSymDescriptor(moduleDesc)) {
        return FAILURE;
    }

    modulePtr = (SYM_TYPE_MODULE *)st.GetHugeDataPtr(moduleDesc);
    if ( ((modulePtr->symHeader.symHeader.typeIndex.symType)&0x0F) !=
        SYM_MODULE )
        return FAILURE;

    if ( modulePtr->symHeader.child != NULL_SYMBOL ) {
        if (!UtilIsValidSymDescriptor( modulePtr->symHeader.child )) {
            return FAILURE;
        }
        modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                modulePtr->symHeader.child);
        if ( ((modPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) {
            funcDesc = modulePtr->symHeader.child;
        }
        else {
            while ( modPtr->symSiblingOffset != NULL_SYMBOL ) {
                if (!UtilIsValidSymDescriptor( modPtr->symSiblingOffset )) {
                    return FAILURE;
                }
                funcDesc = modPtr->symSiblingOffset;
                modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                    modPtr->symSiblingOffset);
                if ( ((modPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) 
                    break;
            }
        }
        return GOOD;
    }
    return FAILURE;
}

int SrcGetNextFunc(SYM_DESCRIPTOR funcDesc,LPSTR funcName,
    SYM_DESCRIPTOR& nextDesc)
{
    COMMON_SYMBOL_HEADER  *modPtr;
    HANDLE *pHdl;
    char *temp1;
    
    temp1 = 0;
    if ( funcDesc == NULL_SYMBOL )
        return FAILURE;
    if (!UtilIsValidSymDescriptor(funcDesc)) {
        return FAILURE;
    }

    modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(funcDesc);
    if ( ((modPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) {
        if ( GOOD != SymGetSymbolName( funcDesc , &temp1 ) ) 
            return FAILURE;                       
        strcpy( funcName , temp1 );         
        if ( temp1 ) {
            pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
            GlobalFree( *pHdl );
        }
        nextDesc = NULL_SYMBOL;
        while ( modPtr->symSiblingOffset != NULL_SYMBOL ) {
            if (!UtilIsValidSymDescriptor( modPtr->symSiblingOffset )) {
                break;
            }
            nextDesc = modPtr->symSiblingOffset;
            modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                   modPtr->symSiblingOffset);
            if ( ((modPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) 
                break;
        }
    }
    else {
        return FAILURE;
    }
    return GOOD;

}
                              
void LowestBlockDesc(U32 addr, SYM_DESCRIPTOR& blockDesc)
{
    SYM_DESCRIPTOR desc1;
    COMMON_BLOCK_HEADER  *modPtr;
    
    modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(blockDesc);
    desc1 = modPtr->child;
    while ( desc1 != NULL_SYMBOL ) {
        if (!UtilIsValidSymDescriptor( desc1 )) {
            return ;
        }
        modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(desc1);
        if ( (addr>=modPtr->symHeader.beginAddrInfo.startAddr)&&
            (addr<=modPtr->symHeader.endAddrInfo.endAddr) ) {
            blockDesc = desc1;
            LowestBlockDesc(addr, blockDesc);
            break;
        }
        desc1 = modPtr->symHeader.symSiblingOffset;
    }
}
                                  
int StackAddrMapBlock(U32 addr , SYM_DESCRIPTOR& moduleDesc ,
            SYM_DESCRIPTOR& funcDesc , SYM_DESCRIPTOR& blockDesc)
{
    SYM_DESCRIPTOR *descArray;
    SYM_DESCRIPTOR desc , desc1 ;
//  char temp[200];
    U16 numReturn , i;       
//    int len;

    moduleDesc = NULL_SYMBOL;
    funcDesc = NULL_SYMBOL;
    blockDesc = NULL_SYMBOL;
                       
    if ( GOOD != SymGetModuleNum( &i ) ) {
        return FAILURE;
    }
    descArray = new SYM_DESCRIPTOR[ i+1 ];
    if ( descArray == NULL ) return FAILURE; 
    if (GOOD != SymGetAllModules(descArray,i,&numReturn)){
        delete descArray;
        return FAILURE;
    }                         
    if ( numReturn == 0 ) {
        delete descArray;
        return FAILURE;       
    }
//  for ( i = 0; i < numReturn; i++ ) {
    i = 0;
    while( i < numReturn ) {
        if (!UtilIsValidSymDescriptor(descArray[i])) {
            delete descArray;
            return FAILURE;
        }
        COMMON_BLOCK_HEADER  *modPtr;

        modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(descArray[i]);
        if ( (addr>=modPtr->symHeader.beginAddrInfo.startAddr)&&
            (addr<=modPtr->symHeader.endAddrInfo.endAddr) ) {
            moduleDesc = descArray[i];
            desc = modPtr->child;
            while ( desc != NULL_SYMBOL ) {
                if (!UtilIsValidSymDescriptor( desc )) {
                    delete descArray;
                    return FAILURE;
                }
                modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(desc);
                if ( (addr>=modPtr->symHeader.beginAddrInfo.startAddr)&&
                    (addr<=modPtr->symHeader.endAddrInfo.endAddr) ) {
                    funcDesc = desc;
                    desc1 = modPtr->child;
                    while ( desc1 != NULL_SYMBOL ) {
                        if (!UtilIsValidSymDescriptor( desc1 )) {
                            delete descArray;
                            return FAILURE;
                        }
                        modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(desc1);
                        if ( (addr>=modPtr->symHeader.beginAddrInfo.startAddr)&&
                            (addr<=modPtr->symHeader.endAddrInfo.endAddr) ) {
                            blockDesc = desc1;                               
                            LowestBlockDesc(addr,blockDesc);
                            break;
                        }
                        desc1 = modPtr->symHeader.symSiblingOffset;
                    }
                    break;
                }
                desc = modPtr->symHeader.symSiblingOffset;
            }
            break;
        }
        i++;
    }
    delete descArray;

    if ( moduleDesc )   
        return GOOD;
    else 
        return FAILURE; 
}

void ClearStkAndVar(void)
{
    stkObject.VarDeleteAll();
    varObject.VarDeleteAll();
}

int FrankGetFuncRange(U32 addr , U32& uStart , U32& uEnd)
{
    SYM_DESCRIPTOR *descArray;
    SYM_DESCRIPTOR desc;
    U16 numReturn , i;       

    if ( GOOD != SymGetModuleNum( &i ) ) {
        return FAILURE;
    }
    descArray = new SYM_DESCRIPTOR[ i+1 ];
    if ( descArray == NULL ) return FAILURE; 
    if (GOOD != SymGetAllModules(descArray,i,&numReturn)){
        delete descArray;
        return FAILURE;
    }                         
    if ( numReturn == 0 ) {
        delete descArray;
        return FAILURE;       
    }
    i = 0;
    while( i < numReturn ) {
        if (!UtilIsValidSymDescriptor(descArray[i])) {
            delete descArray;
            return FAILURE;
        }
        COMMON_BLOCK_HEADER  *modPtr;

        modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(descArray[i]);
        if ( (addr>=modPtr->symHeader.beginAddrInfo.startAddr)&&
            (addr<=modPtr->symHeader.endAddrInfo.endAddr) ) {
            desc = modPtr->child;
            while ( desc != NULL_SYMBOL ) {
                if (!UtilIsValidSymDescriptor( desc )) {
                    delete descArray;
                    return FAILURE;
                }
                modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(desc);
                if ( (addr>=modPtr->symHeader.beginAddrInfo.startAddr)&&
                    (addr<=modPtr->symHeader.endAddrInfo.endAddr) ) {
                    uStart = modPtr->symHeader.beginAddrInfo.startAddr;
                    uEnd = modPtr->symHeader.endAddrInfo.endAddr;
                    delete descArray;
                    return GOOD;
                }
                desc = modPtr->symHeader.symSiblingOffset;
            }
            delete descArray;
            return FAILURE;
        }
        i++;
    }
    delete descArray;
    return FAILURE; 
}

int StepAddrMapFunc( unsigned short uAddr , unsigned short& uStart ,
			unsigned short& uEnd )				 
{                   
	U32 addr;           
	SYM_DESCRIPTOR moduleDesc;
    SYM_DESCRIPTOR *descArray;
    SYM_DESCRIPTOR desc;
    U16 numReturn , i; 
    int isFound = 0;      

    moduleDesc = NULL_SYMBOL;
    addr = (U32) uAddr;
                       
    if ( GOOD != SymGetModuleNum( &i ) ) {
        return FAILURE;
    }
    descArray = new SYM_DESCRIPTOR[ i+1 ];
    if ( descArray == NULL ) return FAILURE; 
    if (GOOD != SymGetAllModules(descArray,i,&numReturn)){
        delete descArray;
        return FAILURE;
    }                         
    if ( numReturn == 0 ) {
        delete descArray;
        return FAILURE;       
    }

    i = 0;
    while( i < numReturn ) {
        if (!UtilIsValidSymDescriptor(descArray[i])) {
            delete descArray;
            return FAILURE;
        }
        COMMON_BLOCK_HEADER  *modPtr;

        modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(descArray[i]);
        if ( (addr>=modPtr->symHeader.beginAddrInfo.startAddr)&&
            (addr<=modPtr->symHeader.endAddrInfo.endAddr) ) {
            moduleDesc = descArray[i];
            desc = modPtr->child;
            while ( desc != NULL_SYMBOL ) {
                if (!UtilIsValidSymDescriptor( desc )) {
                    delete descArray;
                    return FAILURE;
                }
                modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(desc);
                if ( (addr>=modPtr->symHeader.beginAddrInfo.startAddr)&&
                    (addr<=modPtr->symHeader.endAddrInfo.endAddr) ) {
//                    modPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(desc);
                    uStart = modPtr->symHeader.beginAddrInfo.startAddr;
                    uEnd = modPtr->symHeader.endAddrInfo.endAddr;
                    isFound = 1;
                    break;
                }
                desc = modPtr->symHeader.symSiblingOffset;
            }
            break;
        }
        i++;
    }
    delete descArray;

    if ( isFound )   
        return GOOD;
    else 
        return FAILURE; 
}

/******************************** E O F ***********************************/
