
/***************************************************************************
**
**    $Header$
**
**    $Log$
**                 
****************************************************************************/

/****************************************************************************
**
**  Name:  VARSVR.CPP
**
**  Description:
**      Routines for variable server.
**
**  Status:  CODED
**
**    Rev 1.0   1 Sept. 1995 8:30:00am   Gates Hua
** Initial revision.
**
**    Rev 1.1   11 Oct. 1995 13:30:00pm   Gates Hua
** Changed by Gates Hua , for set unsigned char variable's value
**
**  Copyright (C) 1995 Microtek International.  All rights reserved.
**
*****************************************************************************/

            /***************************
            *                          *
            *       INCLUDE FILES      *
            *                          *
            ***************************/
#include "stdafx.h"
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include "ldrexp.h"
#ifdef _LINK_WITH_ABI_
//#include "abibase.h"  
#include "abiextfn.h"
#else
typedef int STATUS;
typedef unsigned char FLAG;
typedef struct {
    FLAG addrType;
    unsigned long  addr;
} ADDR;

/* All ABI routines Return codes */
typedef enum {
        ICE_OK              = 0x0,
        ICE_FAIL_STEP,                  //target cannot step
        ICE_FAIL_MEM_WRITE,             //memory write failure
        ICE_FAIL_MAP_INCLUDE,           //map status not included
        ICE_FAIL_MAP_BOUNDARY,          //map address boundary error
        ICE_NOT_FOUND       = 0x5,
        ICE_FOUND,
        ICE_TIME_OUT        = 0x7,
        ICE_PARA_ERROR      = 0x8,
        ICE_EP_RUNNING      = 0x10,
        ICE_TRACE_RUNNING   = 0x11,
        ICE_TRACE_READ_OVER = 0x12,
        ICE_COMMAND_INVALID = 0x13,

        ICE_FLASH_SW_ERROR  = 0x40,
        ICE_FLASH_EC_ERROR  = 0x41,
        ICE_FLASH_PRG_ERROR = 0x42,
        ICE_FLASH_REC_ERROR = 0x43,
        ICE_NO_RESPONSE        = 0xff
} RET_CODE;

#endif

#include "symblsvr.h"
#include "stkinit.h"
#include "sympool.h"
#include "symmgr.h"
#include "varinit.h"
#include "stdio.h"
#include "symimp.h"
//int sscanf( const char *buffer, const char *format ,void* );

            /***************************
            *                          *
            *        EXTERNALS         *
            *                          *
            ***************************/
extern MemPool st;

//extern int SetUserVarValue(char *str,short value);
extern int BuildDetailedType(TYPE_INDEX typeIndex, char *str);
extern int SymbolDetailedType(SYM_DESCRIPTOR symbol , char * str);


extern int SrcIsLoaded(void);
extern RETCODE
SymAddGetModuleName(SYM_DESCRIPTOR module, LPSTR modName);
extern void U16ToStr(U16 ui , char *tt);
extern int SrcIsStatement(void);
extern int SrcIsIEEE(void);
extern int BuildCAddr( SEGMENTTYPE type , U32 addr , char* str );
extern int BuildBValue(TYPE_INDEX typeIndex,
        SEGMENTTYPE type,U32 addr,char* str );
extern int BuildSValue(TYPE_INDEX typeIndex,SEGMENTTYPE type,
			U32 addr,char* str ,int nSize,int );
extern void ConvEnumToAbiType( SEGMENTTYPE type , U16& addrType );
extern void Omf51ConvPtrToSeg( char c , SEGMENTTYPE& type );
extern void UbrofConvPtrToSeg( char c , SEGMENTTYPE& type );
extern void MemoryTypeConvToSeg( MEMORY_TYPE t , SEGMENTTYPE& type );
extern void SrcUpdate();
extern int BuildIEEEBValue(struct VarNode *node, int nFlag, 
    char* str );
extern int FindNextType(TYPE_INDEX oldType , TYPE_INDEX& nextIndex);
extern int BuildEnumValue(TYPE_INDEX typeIndex,SEGMENTTYPE type,U32 addr,
    int nFlag , char* str );
extern int SrcGetFuncRange(const char *command, U32& uStart, U32& uEnd);

            /***************************
            *                          *
            *        DEFINITIONS       *
            *                          *
            ***************************/
static CString strSpecResult="";

            /***************************
            *                          *
            *     LOCAL PROTOTYPES     *
            *                          *
            ***************************/
int CheckIsHexValue(const char* command,int& num,unsigned long& ul);
extern BOOL cpuStatus();
            /**************************
            *                         *
            *    PRIVATE VARIABLES    *
            *                         *
            **************************/

class VarServer varObject;
char temp[256];
int isUpdateGOOD;
            /**************************** 
             *                          *
             *     EXECUTABLE CODE      *
             *                          *
             ****************************/

//int sscanf( const char *buffer, const char *format ,void* )
//{
//return 1;
//}
//////////////////////////////////////////////////////////////////////////
// Variable Server Routines
//////////////////////////////////////////////////////////////////////////
/*
int VarNode::CanBeModify()
{
    if ( flag & VAR_COMPLEX ) return FAILURE;
    if ( flag1 ) {
      int nFlag ;
      if ( GOOD != pExp->IsSymbol(nFlag) ) {
         return FAILURE;
      }
      if ( 0 == nFlag ) return FAILURE;
    }       
    return GOOD;
}
*/
int VarServer::Add(struct VarNode *node)
{
    if ( node == 0 ) return (FAILURE);
    if ( curVarNode == 0 ) {
        curVarNode = varListHeader = node ;
    }
    else {
        curVarNode->next = node;
        node->prev = curVarNode;
        curVarNode = node;
    }
    return GOOD;
}

int VarServer::Delete( struct VarNode* node )
{
    struct VarNode *temp;

    if ( node == 0 ) return (FAILURE);
    temp = varListHeader;
    if ( node == temp ) {
        varListHeader = temp->next;
        if ( varListHeader ) varListHeader->prev = 0;
        else if ( curVarNode == node ) curVarNode = 0;
    }
    else {
        while( temp ) {
            if ( temp->next == node ) break;
            temp = temp->next;
        }
        if ( temp==0 ) return FAILURE;
        temp->next = node->next;
        if ( node->next ) {
            node->next->prev = node->prev;
        }
        else if ( node == curVarNode ) {
            curVarNode = node->prev;
        }
    }
    ClearNode( node );
    delete node;
    return GOOD;
}

int VarServer::DeleteLocal(SYM_DESCRIPTOR desc)
{
    struct VarNode *temp;

    temp = varListHeader;
    while ( temp ) {
        if ( temp->desc == desc )
            return ( Delete( temp ) );
        temp = temp->next;
    }
    return FAILURE;
}

void VarServer::VarDeleteAll()
{
    struct VarNode *temp;

    deleteAll();
    if ( varListHeader == 0 ) return ;
    temp = curVarNode = varListHeader;
    while( curVarNode ) {
        curVarNode = curVarNode->next;
        ClearNode( temp );
        delete temp;
        temp = curVarNode;
    }
    varListHeader = curVarNode = 0;
    return ;
}

/*
int VarServer::AddVar( char *str )
{
    BOOLEAN isGlobal ;
    SYM_DESCRIPTOR desc ;
    struct VarNode *node;
    TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX       typeIndex;
    RETCODE          err;
//   COMMON_SYMBOL_HEADER  *modPtr ;
    VAR_STORAGE_CLASS   storageClass;
    VAR_REGISTER_CLASS  registerClass;
    BOOLEAN             isConstant;
    SYM_DESCRIPTOR      funcDescriptor;
    SYM_DESCRIPTOR      moduleDescriptor;
    SYM_DESCRIPTOR      parentDescriptor;
    GET_VAR_ADDR_STRUCT varAddr;
    char temp[256];
    CSymSyntax *pCalc;
    int nNum;               
    char *pName;     
    RET_ADDR retAddr;

    buildStack();
    node = new struct VarNode;
    if ( 0 == node ) return FAILURE;
    pCalc = new CSymSyntax;
    if ( 0 == pCalc ) {
      delete node;
      return FAILURE;
    }
    
   pCalc->Init( str );
   pCalc->GetErrorNum( nNum );
   if ( nNum ) {
      delete node;
      delete pCalc;
      return FAILURE;
   }

   if ( GOOD != pCalc->CheckSyntax() ) {
      delete node;
      delete pCalc;
      return FAILURE;
   }                                            
   if ( GOOD != pCalc->IsVariable() ) {
      if ( GOOD != pCalc->CalculateValue() ) {
         delete node;
         delete pCalc;
         return FAILURE;
      }          
      node->flag1 = 1;
      node->pExp = pCalc;

        node->command = str;
        node->desc = 0;
      if ( GOOD != pCalc->GetAllTokenNameToStr( node->name ) ) {    
         delete node;
         return FAILURE;
      }          
      if ( GOOD != pCalc->GetExpAddr( node->addr ) ) {    
         delete node;
         return FAILURE;
      }          
      if ( GOOD != pCalc->GetTypeIndex( node->typeIndex ) ) {    
         delete node;
         return FAILURE;
      }          
        if ( GOOD != UpdataOneNode( node ) ) {
         if ( node ) delete node;
         return FAILURE;
        }
        if ( GOOD != isUpdateGOOD ) {
         if ( node ) delete node;
         return FAILURE;
        }
       if ( GOOD == Add( node ) ) 
           return GOOD;
       else 
           return FAILURE;
   }    
       
   nNum = pCalc->GetOneTokenName(0,pName);
   delete pCalc;
   if ( nNum != 0 ) {
      delete node;
      return FAILURE;
    }
      
//    if ( IsValidVar(str,isGlobal,desc) != 0 ) return FAILURE;
//    if ( IsValidVar(str,isGlobal,desc) != 0 ) {
    if ( IsValidVar(pName,isGlobal,desc) != 0 ) {
      delete node;     
      delete []pName;
      return FAILURE;
    }

    if ( isGlobal == TRUE ) {
        node->flag |= VAR_GLOBAL;
    }
    node->desc = desc;
//    node->command = str;
    node->command = pName;
    delete []pName;
    if ( GOOD != SymGetVar( desc,
                            temp,
                            &typeIndex,
                            &storageClass,
                            &registerClass,
                            &isConstant,
                            &funcDescriptor,
                            &moduleDescriptor,
                            &parentDescriptor,
                            &varAddr) ) {
        delete node;
        return FAILURE;
    }
    node->name = temp;
    node->typeIndex = typeIndex;
    typeHeader.typeName = temp;
    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) {
        delete node;
        return FAILURE;
    }                              
    if ( registerClass != NOT_REG ) {
        node->flag |= VAR_REG ;
    } 
    if ( registerClass == NOT_REG ) {
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
            if ( FAILURE == BuildSValue( node->typeIndex ,
               varAddr.fixedAddr.segType,varAddr.fixedAddr.startAddr , buff) ) {
                delete node;
                return FAILURE;
            }
            node->addr.segType = varAddr.fixedAddr.segType;
            node->addr.addr = varAddr.fixedAddr.startAddr;
            node->value = buff;
            if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                delete node;
                return FAILURE;
            }
            node->typeName = buff;
        }
        else {
            if ( typeHeader.t.complexType == TY_TYPE ) {
                while( 1 ) {
                    TYPE_INDEX       typeNext;
                   
                    if ( GOOD != SymGetTypeTypeIndex(typeIndex,&typeNext) ) {
                        delete node;
                        return FAILURE;
                    }
                    typeIndex = typeNext;
                    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))){
                        delete node;
                        return FAILURE;
                    }
                    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
                        break;
                    else if ( typeHeader.t.complexType != TY_TYPE )
                        break;
                }   
                if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
                    if ( FAILURE == BuildSValue( typeIndex ,
                        varAddr.fixedAddr.segType,varAddr.fixedAddr.startAddr,
                        buff) ) {
                        delete node;
                        return FAILURE;
                    }
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr;
                    node->value = buff;
                    if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                        delete node;
                        return FAILURE;
                    }
                    node->typeName = buff;
//                    break;
                }
            }

            if ( (typeHeader.typeChoice==COMPLEX_TYPE_CLASS)&&
                (typeHeader.t.complexType == TY_BITFIELD) ) {
                if ( SrcIsIEEE() == GOOD ) {
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr;
                    if ( FAILURE == BuildIEEEBValue( node , 1 , buff) ) {
                        delete node;
                        return FAILURE;
                    }
                    node->value = buff;
                }
                else {
                    if ( FAILURE == BuildBValue( typeIndex ,
                        varAddr.fixedAddr.segType,
                        varAddr.fixedAddr.startAddr,
                        buff) ) {
                        delete node;
                        return FAILURE;
                    }
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr;
                    node->value = buff;
                }
                if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                    delete node;
                    return FAILURE;
                }
                node->typeName = buff;
            }    
            else if (typeHeader.typeChoice==COMPLEX_TYPE_CLASS &&
                (typeHeader.t.complexType == TY_ENUM_C) ) {
                if ( FAILURE == BuildEnumValue( typeIndex ,
                    varAddr.fixedAddr.segType,
                    varAddr.fixedAddr.startAddr,1,
                    buff) ) {
                    delete node;
                    return FAILURE;
                }
                node->addr.segType = varAddr.fixedAddr.segType;
                node->addr.addr = varAddr.fixedAddr.startAddr;
                node->value = buff;
                if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                    delete node;
                    return FAILURE;
                }
                node->typeName = buff;
            }    
            else if (typeHeader.typeChoice==COMPLEX_TYPE_CLASS) {
                node->flag |= VAR_COMPLEX;
                switch(typeHeader.t.complexType) {
                case TY_SMALL_PTR :
                    if ( typeHeader.sizeCalculated == TRUE ) {
                        ADDR    start , end;
                        char    data[16];
                        U32     address ;
                        SEGMENTTYPE segType;

                        address = 0;
                        ConvEnumToAbiType( varAddr.fixedAddr.segType ,
                                     start.addrType );
                        end.addrType = start.addrType;
                        start.addr=varAddr.fixedAddr.startAddr;
                        end.addr = start.addr + (typeHeader.sizeInMAUs-1);
    #ifdef _LINK_WITH_ABI_
                        if ( ICE_OK != emuGetMemN(start,(U16)(end.addr-start.addr),(U8*)data,&retAddr) ) {
                            delete node;
                            return FAILURE;
                        }
    #endif
                        if ( typeHeader.sizeInMAUs == 3 ) {
                            address = (U8) data[1];
                            address = (address<<8) + (U8)data[2];
                            if ( GOOD == SrcIsStatement() ) {
                                UbrofConvPtrToSeg(data[0],segType);
                            }
                            else {
                                Omf51ConvPtrToSeg(data[0],segType);
                            }
                        }
                        else if ( typeHeader.sizeInMAUs == 2 ) {
                            segType = varAddr.fixedAddr.segType;
                            address = (U8) data[0];
                            address = (address<<8) + (U8)data[1];
                        }
                        else if ( typeHeader.sizeInMAUs == 1 ) {
                            segType = varAddr.fixedAddr.segType;
                            address = (U8) data[0];
                        }
                        else {
                            delete node;
                            return FAILURE;
                        }
                        if ( FAILURE == BuildCAddr( segType , address,
                            buff) ) {
                            delete node;
                            return FAILURE;
                        }
                        node->addr.segType = varAddr.fixedAddr.segType;
                        node->addr.addr = varAddr.fixedAddr.startAddr;
                        node->result.segType = segType;
                        node->result.addr = address;
                        node->value = buff;
                        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                            delete node;
                            return FAILURE;
                        }
                        node->typeName = buff;
                    }
                    break;
                case TY_OMF51_PTR :
                    if ( typeHeader.sizeCalculated == TRUE ) {
                        ADDR    start , end;
                        char    data[16];
                        U32     address ;
                        SEGMENTTYPE segType;
                        SEGMENTTYPE ssss;
                        TYPE_OMF51_PTR_STRUCT omf51Ptr;

                        if ( SymGetTypePointer51(typeIndex,&omf51Ptr) != GOOD )
                            return FAILURE;
                        address = 0;
                        ConvEnumToAbiType( varAddr.fixedAddr.segType ,
                                     start.addrType );
                        end.addrType = start.addrType;
                        start.addr = varAddr.fixedAddr.startAddr;
                        end.addr = start.addr + 
                                   (typeHeader.sizeInMAUs-1);
    #ifdef _LINK_WITH_ABI_
                        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
                            return FAILURE;
                        }
    #endif              
                        if ( typeHeader.sizeInMAUs == 3 ) {
                            address = (U8) data[1];
                            address = (address<<8) + (U8)data[2];
                            if ( GOOD == SrcIsStatement() ) {
                                UbrofConvPtrToSeg(data[0],segType);
                            }
                            else {
                                Omf51ConvPtrToSeg(data[0],segType);
                            }
                            ssss = segType;
                        }
                        else if ( typeHeader.sizeInMAUs == 2 ) {
                            address = (U8) data[0];
                            address = (address<<8) + (U8)data[1];
                            MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                            ssss = segType;
                            if ( SrcIsIEEE() == GOOD ) {
                                if ( (GOOD==SymGetTypeHeader(omf51Ptr.typeIndex, 
                                    &typeHeader)) &&(typeHeader.typeChoice==
                                    COMPLEX_TYPE_CLASS)&&
                                    (typeHeader.t.complexType == TY_TYPE) 
                                ) {                    
                                    TYPE_INDEX tttt;
                                    if ( GOOD != SymGetTypeTypeType(
                                        omf51Ptr.typeIndex,&tttt,&ssss) ) {
                                        if ( ssss != SEG_UNTYPED ) 
                                            ssss = segType;
                                    }    
                                }    
                            }                              
                        }
                        else if ( typeHeader.sizeInMAUs == 1 ) {
                            address = (U8) data[0];
                            MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                            ssss = segType;
                            if ( SrcIsIEEE() == GOOD ) {
                                if ( (GOOD==SymGetTypeHeader(omf51Ptr.typeIndex, 
                                    &typeHeader)) &&(typeHeader.typeChoice==
                                    COMPLEX_TYPE_CLASS)&&
                                    (typeHeader.t.complexType == TY_TYPE) 
                                ) {                    
                                    TYPE_INDEX tttt;
                                    if ( GOOD != SymGetTypeTypeType(
                                        omf51Ptr.typeIndex,&tttt,&ssss) ){
                                        if ( ssss != SEG_UNTYPED ) 
                                            ssss = segType;
                                    }    
                                }    
                            }                              
                        }
//                        if ( FAILURE == BuildCAddr( segType , address,
                        if ( FAILURE == BuildCAddr( ssss , address,
                            buff) ) {
                            delete node;
                            return FAILURE;
                        }
                        node->addr.segType = varAddr.fixedAddr.segType;
                        node->addr.addr = varAddr.fixedAddr.startAddr;
//                        node->result.segType = segType;
                        node->result.segType = ssss;
                        node->result.addr = address;
                        node->value = buff;
                        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                            delete node;
                            return FAILURE;
                        }
                        node->typeName = buff;
                    }
                    break;
    //                return ( BuildCAddr( varAddr.fixedAddr.segType ,
    //                        varAddr.fixedAddr.startAddr ,tmpStr ) );
                default :
                     if ( FAILURE == BuildCAddr( varAddr.fixedAddr.segType ,
                            varAddr.fixedAddr.startAddr ,buff ) ) {
                         delete node;
                         return FAILURE;
                     }
                     node->addr.segType = varAddr.fixedAddr.segType;
                     node->addr.addr = varAddr.fixedAddr.startAddr;
                     node->result.segType = varAddr.fixedAddr.segType;
                     node->result.addr = varAddr.fixedAddr.startAddr;
                     node->value = buff;
                     if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                         delete node;
                         return FAILURE;
                     }
                     node->typeName = buff;
                }
            }
        }
    }
    else {
        sprintf( buff,"Register," );
        node->value = buff;
        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
            delete node;
            return FAILURE;
        }
        node->typeName = buff;
    }
    if ( GOOD == Add( node ) ) 
        return GOOD;
    else 
        return FAILURE;
}
*/

int VarServer::AddVar( const char *str, SYM_DESCRIPTOR symSpecModule,int nLine)
{
    BOOLEAN isGlobal ;
    SYM_DESCRIPTOR desc ;
    struct VarNode *node;
    TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX       typeIndex;
    RETCODE          err;
//   COMMON_SYMBOL_HEADER  *modPtr ;
    VAR_STORAGE_CLASS   storageClass;
    VAR_REGISTER_CLASS  registerClass;
    BOOLEAN             isConstant;
    SYM_DESCRIPTOR      funcDescriptor;
    SYM_DESCRIPTOR      moduleDescriptor;
    SYM_DESCRIPTOR      parentDescriptor;
    GET_VAR_ADDR_STRUCT varAddr;
    char temp[256];
    CSymSyntax *pCalc;
    int nNum;               
    char *pName;

    buildStack();
    node = new struct VarNode;
    if ( 0 == node ) return FAILURE;
    if ( symSpecModule == 0 ) {
        pCalc = new CSymSyntax;
        if ( 0 == pCalc ) {
          delete node;
          return FAILURE;
        }
        
       pCalc->Init( str );
       pCalc->GetErrorNum( nNum );
       if ( nNum ) {
          delete node;
          delete pCalc;
          return FAILURE;
       }
    
       if ( GOOD != pCalc->CheckSyntax() ) {
          delete node;
          delete pCalc;
          return FAILURE;
       }                                            
       if ( GOOD != pCalc->IsVariable() ) {
          if ( GOOD != pCalc->CalculateValue() ) {
             delete node;
             delete pCalc;
             return FAILURE;
          }          
          node->flag1 = 1;
          node->pExp = pCalc;
    
            node->command = str;
            node->desc = 0;
          if ( GOOD != pCalc->GetAllTokenNameToStr( node->name ) ) {    
             delete node;
             return FAILURE;
          }          
          if ( GOOD != pCalc->GetExpAddr( node->addr ) ) {    
             delete node;
             return FAILURE;
          }          
          if ( GOOD != pCalc->GetTypeIndex( node->typeIndex ) ) {    
             delete node;
             return FAILURE;
          }          
            if ( GOOD != UpdataOneNode( node ) ) {
             if ( node ) delete node;
             return FAILURE;
            }
            if ( GOOD != isUpdateGOOD ) {
             if ( node ) delete node;
             return FAILURE;
            }
           if ( GOOD == Add( node ) ) 
               return GOOD;
           else 
               return FAILURE;
           }    
        nNum = pCalc->GetOneTokenName(0,pName);
        delete pCalc;
        if ( nNum != 0 ) {
            delete node;
              return FAILURE;
        }
    }
    else {
        pName = new char[ strlen(str) ];
        if ( pName == NULL ) return FAILURE;
        strcpy(pName, str);
    }
           
//    if ( IsValidVar(str,isGlobal,desc) != 0 ) return FAILURE;
//    if ( IsValidVar(str,isGlobal,desc) != 0 ) {
//    if ( IsValidVar(pName,isGlobal,desc) != 0 ) {
    if ( IsValidVar(pName,isGlobal,desc,symSpecModule,nLine) != 0 ) {
      delete node;     
      delete []pName;
      return FAILURE;
    }

    if ( isGlobal == TRUE ) {
        node->flag |= VAR_GLOBAL;
    }
    node->desc = desc;
//    node->command = str;
    node->command = pName;
    delete []pName;
    if ( GOOD != SymGetVar( desc,
                            temp,
                            &typeIndex,
                            &storageClass,
                            &registerClass,
                            &isConstant,
                            &funcDescriptor,
                            &moduleDescriptor,
                            &parentDescriptor,
                            &varAddr) ) {
        delete node;
        return FAILURE;
    }
    node->name = temp;
    node->typeIndex = typeIndex;
    typeHeader.typeName = temp;
    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) {
        delete node;
        return FAILURE;
    }                              
    if ( registerClass != NOT_REG ) {
        node->flag |= VAR_REG ;
    } 
    //if ( registerClass == NOT_REG ) 
    {
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
            if ( FAILURE == BuildSValue( node->typeIndex ,
               varAddr.fixedAddr.segType,varAddr.fixedAddr.
               startAddr,buff,node->nSize,node->nOffset) )
            {
                delete node;
                return FAILURE;
            }
            node->addr.segType = varAddr.fixedAddr.segType;
            node->addr.addr = varAddr.fixedAddr.startAddr;
            node->value = buff;
            if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                delete node;
                return FAILURE;
            }
            node->typeName = buff;
        }
        else {
            if ( typeHeader.t.complexType == TY_TYPE ) {
                while( 1 ) {
                    TYPE_INDEX       typeNext;
                   
                    if ( GOOD != SymGetTypeTypeIndex(typeIndex,&typeNext) ) {
                        delete node;
                        return FAILURE;
                    }
                    typeIndex = typeNext;
                    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))){
                        delete node;
                        return FAILURE;
                    }
                    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
                        break;
                    else if ( typeHeader.t.complexType != TY_TYPE )
                        break;
                }   
                if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
                    if ( FAILURE == BuildSValue( typeIndex ,
                        varAddr.fixedAddr.segType,varAddr.fixedAddr.startAddr,
                        buff,node->nSize,node->nOffset) ) {
                        delete node;
                        return FAILURE;
                    }
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr;
                    node->value = buff;
                    if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                        delete node;
                        return FAILURE;
                    }
                    node->typeName = buff;
//                    break;
                }
            }

            if ( (typeHeader.typeChoice==COMPLEX_TYPE_CLASS)&&
                (typeHeader.t.complexType == TY_BITFIELD) ) {
                if ( SrcIsIEEE() == GOOD ) {
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr;
                    if ( FAILURE == BuildIEEEBValue( node , 1 , buff) ) {
                        delete node;
                        return FAILURE;
                    }
                    node->value = buff;
                }
                else {
                    if ( FAILURE == BuildBValue( typeIndex ,
                        varAddr.fixedAddr.segType,
                        varAddr.fixedAddr.startAddr,
                        buff) ) {
                        delete node;
                        return FAILURE;
                    }
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr;
                    node->value = buff;
                }
                if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                    delete node;
                    return FAILURE;
                }
                node->typeName = buff;
            }    
            else if (typeHeader.typeChoice==COMPLEX_TYPE_CLASS &&
                (typeHeader.t.complexType == TY_ENUM_C) ) {
                if ( FAILURE == BuildEnumValue( typeIndex ,
                    varAddr.fixedAddr.segType,
                    varAddr.fixedAddr.startAddr,1,
                    buff) ) {
                    delete node;
                    return FAILURE;
                }
                node->addr.segType = varAddr.fixedAddr.segType;
                node->addr.addr = varAddr.fixedAddr.startAddr;
                node->value = buff;
                if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                    delete node;
                    return FAILURE;
                }
                node->typeName = buff;
            }    
            else if (typeHeader.typeChoice==COMPLEX_TYPE_CLASS) {
                node->flag |= VAR_COMPLEX;
                switch(typeHeader.t.complexType) {
                case TY_SMALL_PTR : 
			    case TY_DPTR0 :
			    case TY_DPTR1 :    
			    case TY_DPTR2 :    
			    case TY_DPTR3 :    
			   case TY_DPTR4  :   
			   case TY_DPTR5  :   
			   case TY_DPTR6  :   
			   case TY_DPTR7  :   
			   case TY_CPTR0  :   
			   case TY_CPTR1  :   
			   case TY_CPTR2  :   
			   case TY_CPTR3  :                   
                    if ( typeHeader.sizeCalculated == TRUE ) {
                        ADDR    start , end;
                        char    data[16];
                        U32     address ;
                        SEGMENTTYPE segType;

                        address = 0;
                        ConvEnumToAbiType( varAddr.fixedAddr.segType ,
                                     start.addrType );
                        end.addrType = start.addrType;
                        start.addr=varAddr.fixedAddr.startAddr;
                        end.addr = start.addr + (typeHeader.sizeInMAUs-1);
    #ifdef _LINK_WITH_ABI_
                        RET_ADDR retAddr;
                        if ( ICE_OK != emuGetMemN(start,(U16)(end.addr-start.addr+1),(U8*)data,&retAddr) ) {
                            delete node;
                            return FAILURE;
                        }
    #endif
                        if ( typeHeader.sizeInMAUs == 3 ) {
                            address = (U8) data[1];
                            address = (address<<8) + (U8)data[2];
                            if ( GOOD == SrcIsStatement() ) {
                                UbrofConvPtrToSeg(data[0],segType);
                            }
                            else {
                                Omf51ConvPtrToSeg(data[0],segType);
                            }
                        }
                        else if ( typeHeader.sizeInMAUs == 2 ) {
                            segType = varAddr.fixedAddr.segType;
                            //address = (U8) data[0];
                            //address = (address<<8) + (U8)data[1];
                            address = *((U16*)data); 
                            if(segType == SEG_DATA )   
                            	if(address > 0x1ff) segType = SEG_XDATA;
                        }
                        else if ( typeHeader.sizeInMAUs == 1 ) {
                            segType = varAddr.fixedAddr.segType;
                            address = (U8) data[0];
                        }
                        else {
                            delete node;
                            return FAILURE;
                        }
                        if ( FAILURE == BuildCAddr( segType , address,
                            buff) ) {
                            delete node;
                            return FAILURE;
                        }
                        node->addr.segType = varAddr.fixedAddr.segType;
                        node->addr.addr = varAddr.fixedAddr.startAddr;
                        node->result.segType = segType;
                        node->result.addr = address;
                        node->value = buff;
                        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                            delete node;
                            return FAILURE;
                        }
                        node->typeName = buff;
                    }
                    break;
                case TY_OMF51_PTR :
                    if ( typeHeader.sizeCalculated == TRUE ) {
                        ADDR    start , end;
                        char    data[16];
                        U32     address ;
                        SEGMENTTYPE segType;
                        SEGMENTTYPE ssss;
                        TYPE_OMF51_PTR_STRUCT omf51Ptr;

                        if ( SymGetTypePointer51(typeIndex,&omf51Ptr) != GOOD )
                            return FAILURE;
                        address = 0;
                        ConvEnumToAbiType( varAddr.fixedAddr.segType ,
                                     start.addrType );
                        end.addrType = start.addrType;
                        start.addr = varAddr.fixedAddr.startAddr;
                        end.addr = start.addr + 
                                   (typeHeader.sizeInMAUs-1);
    #ifdef _LINK_WITH_ABI_               
                        RET_ADDR retAddr;
                        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
                            return FAILURE;
                        }
    #endif              
                        if ( typeHeader.sizeInMAUs == 3 ) {
                            address = (U8) data[1];
                            address = (address<<8) + (U8)data[2];
                            if ( GOOD == SrcIsStatement() ) {
                                UbrofConvPtrToSeg(data[0],segType);
                            }
                            else {
                                Omf51ConvPtrToSeg(data[0],segType);
                            }
                            ssss = segType;
                        }
                        else if ( typeHeader.sizeInMAUs == 2 ) {
                            //address = (U8) data[0];
                            // address = (address<<8) + (U8)data[1];
                            address =*((U16*)data);
                            MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                            ssss = segType;
                            if ( SrcIsIEEE() == GOOD ) {
                                if ( (GOOD==SymGetTypeHeader(omf51Ptr.typeIndex, 
                                    &typeHeader)) &&(typeHeader.typeChoice==
                                    COMPLEX_TYPE_CLASS)&&
                                    (typeHeader.t.complexType == TY_TYPE) 
                                ) {                    
                                    TYPE_INDEX tttt;
                                    if ( GOOD != SymGetTypeTypeType(
                                        omf51Ptr.typeIndex,&tttt,&ssss) ) {
                                        if ( ssss != SEG_UNTYPED ) 
                                            ssss = segType;
                                    }    
                                }    
                            }                              
                        }
                        else if ( typeHeader.sizeInMAUs == 1 ) {
                            address = (U8) data[0];
                            MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                            ssss = segType;
                            if ( SrcIsIEEE() == GOOD ) {
                                if ( (GOOD==SymGetTypeHeader(omf51Ptr.typeIndex, 
                                    &typeHeader)) &&(typeHeader.typeChoice==
                                    COMPLEX_TYPE_CLASS)&&
                                    (typeHeader.t.complexType == TY_TYPE) 
                                ) {                    
                                    TYPE_INDEX tttt;
                                    if ( GOOD != SymGetTypeTypeType(
                                        omf51Ptr.typeIndex,&tttt,&ssss) ){
                                        if ( ssss != SEG_UNTYPED ) 
                                            ssss = segType;
                                    }    
                                }    
                            }                              
                        }
//                        if ( FAILURE == BuildCAddr( segType , address,
                        if ( FAILURE == BuildCAddr( ssss , address,
                            buff) ) {
                            delete node;
                            return FAILURE;
                        }
                        node->addr.segType = varAddr.fixedAddr.segType;
                        node->addr.addr = varAddr.fixedAddr.startAddr;
//                        node->result.segType = segType;
                        node->result.segType = ssss;
                        node->result.addr = address;
                        node->value = buff;
                        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                            delete node;
                            return FAILURE;
                        }
                        node->typeName = buff;
                    }
                    break;
    //                return ( BuildCAddr( varAddr.fixedAddr.segType ,
    //                        varAddr.fixedAddr.startAddr ,tmpStr ) );
                default :
                     if ( FAILURE == BuildCAddr( varAddr.fixedAddr.segType ,
                            varAddr.fixedAddr.startAddr ,buff ) ) {
                         delete node;
                         return FAILURE;
                     }
                     node->addr.segType = varAddr.fixedAddr.segType;
                     node->addr.addr = varAddr.fixedAddr.startAddr;
                     node->result.segType = varAddr.fixedAddr.segType;
                     node->result.addr = varAddr.fixedAddr.startAddr;
                     node->value = buff;
                     if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                         delete node;
                         return FAILURE;
                     }
                     node->typeName = buff;
                }
            }
        }
    }
/*  else {
        //sprintf( buff,"Register," );
        //node->value = buff;
		if ( FAILURE == BuildSValue( node->typeIndex ,
               varAddr.fixedAddr.segType,varAddr.fixedAddr.startAddr , buff) ) {
                delete node;
                return FAILURE;
            }
        node->addr.segType = varAddr.fixedAddr.segType;
        node->addr.addr = varAddr.fixedAddr.startAddr;
        node->value = buff;
        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
            delete node;
            return FAILURE;
        }
        node->typeName = buff;
    }
*/    
    if ( symSpecModule == 0 ) {
        if ( GOOD == Add( node ) ) 
            return GOOD;
        else 
            return FAILURE;
    }
    else {          
        strSpecResult = node->value;
        delete node;
        return GOOD;
    }
}


int VarServer::AddLocalVar(SYM_DESCRIPTOR desc,CString name)
{
    struct VarNode *node;
    TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX       typeIndex;
    RETCODE          err;
    VAR_STORAGE_CLASS   storageClass;
    VAR_REGISTER_CLASS  registerClass;
    BOOLEAN             isConstant;
    SYM_DESCRIPTOR      funcDescriptor;
    SYM_DESCRIPTOR      moduleDescriptor;
    SYM_DESCRIPTOR      parentDescriptor;
    GET_VAR_ADDR_STRUCT varAddr;
    char temp[256];

    node = new struct VarNode;

    node->flag |= VAR_GLOBAL;
    node->desc = desc;
    node->command = name;

    if ( GOOD != SymGetVar( desc,
                            temp,
                            &typeIndex,
                            &storageClass,
                            &registerClass,
                            &isConstant,
                            &funcDescriptor,
                            &moduleDescriptor,
                            &parentDescriptor,
                            &varAddr) ) {
        delete node;
        return FAILURE;
    }
    node->name = temp;
    node->typeIndex = typeIndex;
    typeHeader.typeName = temp;
    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) {
        delete node;
        return FAILURE;
    }                              
    if ( registerClass != NOT_REG ) {
        node->flag |= VAR_REG ;
    } 
    if ( registerClass == NOT_REG ) {
        node->addr.segType = varAddr.fixedAddr.segType;
        node->addr.addr = varAddr.fixedAddr.startAddr;
        UpdataOneNode( node );
    }    
    else {
        //sprintf( buff,"Register," );
        //node->value = buff;
//        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
//            delete node;
//            return FAILURE;
//        }
//      node->typeName = buff;
        node->addr.segType = varAddr.fixedAddr.segType;
        node->addr.addr = varAddr.fixedAddr.startAddr;
        UpdataOneNode( node );
    }
    if ( GOOD == Add( node ) ) 
        return GOOD;
    else 
        return FAILURE;
}

void VarServer::ShowOneNode( struct VarNode* node )
{
    int i;
    CString s;    
    struct VarNode* temp ;

    i = node->num*4;
    if ( i ) memset(buff , ' ' , i );
    buff[i] = '\0';
    s = buff;       
    if ( node->flag & VAR_NOVALID ) {
        s += ' ';
        s += node->name ;
        s += ' ';
        s += "value is not valid !";
        SymShowLine( s.GetBuffer(s.GetLength()) ); 
        return;
    }
        
    if ( node->flag & VAR_COMPLEX ) {
        if ( node->flag & VAR_EXTEND )
            s += '-';
        else
            s += '+';
    }
    else s += ' ';
    s += node->name;
    s += ' ';
    s += node->typeName;
    s += ' ';
    s += node->value;
    SymShowLine( s.GetBuffer(s.GetLength()) );
    temp = node->son;
    while ( temp ) {
        ShowOneNode( temp );
        temp = temp->next ;
    }
}

void VarServer::ShowVarToShell()
{
    struct VarNode *temp;

//  UpdataAllNode();
    temp = varListHeader ;
    while ( temp ) {
        ShowOneNode( temp );
        temp = temp->next;
    }
}

int VarServer::EditNode(struct VarNode *node , char *str)
{
    BOOLEAN isGlobal ;
    SYM_DESCRIPTOR desc ;
    TYPE_INDEX       typeIndex;
    VAR_STORAGE_CLASS   storageClass;
    VAR_REGISTER_CLASS  registerClass;
    BOOLEAN             isConstant;
    SYM_DESCRIPTOR      funcDescriptor;
    SYM_DESCRIPTOR      moduleDescriptor;
    SYM_DESCRIPTOR      parentDescriptor;
    GET_VAR_ADDR_STRUCT varAddr;
    char temp[256];
    CSymSyntax *pCalc;
    int nNum;               
    char *pName;
    struct VarNode *pNode;

    if ( node == 0 ) return FAILURE;
    if ( str == 0 ) return FAILURE;
    if ( !(node->flag & VAR_ROOT) ) return FAILURE;

    pCalc = new CSymSyntax;
    if ( 0 == pCalc ) {
      return FAILURE;
    }
    
   pCalc->Init( str );
   pCalc->GetErrorNum( nNum );
   if ( nNum ) {
      delete pCalc;
      return FAILURE;
   }

   if ( GOOD != pCalc->CheckSyntax() ) {
      delete pCalc;
      return FAILURE;
   }                                            
   if ( GOOD != pCalc->IsVariable() ) {
       pNode = new struct VarNode;
       if ( 0 == pNode ) return FAILURE;

      if ( GOOD != pCalc->CalculateValue() ) {
         delete pNode;
         delete pCalc;
         return FAILURE;
      }          
      pNode->flag1 = 1;
      pNode->pExp = pCalc;

        pNode->command = str;
        pNode->desc = 0;
      if ( GOOD != pCalc->GetAllTokenNameToStr( pNode->name ) ) {    
         delete pNode;
         return FAILURE;
      }          
      if ( GOOD != pCalc->GetExpAddr( pNode->addr ) ) {    
         delete pNode;
         return FAILURE;
      }          
      if ( GOOD != pCalc->GetTypeIndex( pNode->typeIndex ) ) {    
         delete pNode;
         return FAILURE;
      }          
        if ( GOOD != UpdataOneNode( pNode ) ) {
         if ( pNode ) delete pNode;
         return FAILURE;
        }
        if ( GOOD != isUpdateGOOD ) {
         if ( pNode ) delete pNode;
         return FAILURE;
        }           
        ClearNode( node );
        node->line = 1;
        node->flag = VAR_ROOT ;
        node->FreeNode();
        node->CopyNode( pNode );
         if ( pNode ) delete pNode;
        return GOOD;
   }    
       
   nNum = pCalc->GetOneTokenName(0,pName);
   delete pCalc;
   if ( nNum != 0 ) {
      return FAILURE;
    }

//    if (IsValidVar(str,isGlobal,desc) != 0 ) {
    if (IsValidVar(pName,isGlobal,desc) != 0 ) {
        return FAILURE;
    }
    else {
        if ( GOOD != SymGetVar( desc,
                                temp,
                                &typeIndex,
                                &storageClass,
                                &registerClass,
                                &isConstant,
                                &funcDescriptor,
                                &moduleDescriptor,
                                &parentDescriptor,
                                &varAddr) ) {
            return FAILURE;
        }

        if ( desc == node->desc ) {             
          if ( pName ) delete []pName;
            return FAILURE;
        }
        else {                       
            ClearNode( node );
            node->line = 1;
            node->flag = VAR_ROOT ;
           node->FreeNode();
            if ( isGlobal == TRUE ) {
                node->flag |= VAR_GLOBAL;
            }
//            node->command = str;
            node->command = pName;
            node->desc = desc;
            node->addr.segType = varAddr.fixedAddr.segType;
            node->addr.addr = varAddr.fixedAddr.startAddr; 
            node->name = temp;
            node->typeIndex = typeIndex;
            if ( registerClass != NOT_REG ) {
                node->flag |= VAR_REG;
            }
            UpdataOneNode( node );
        }
    }
    if ( pName ) delete []pName;
    return GOOD ;
}

int VarServer::SaveVariable(void)
{                                       
    CString str , str1;
    int symbolFile ,  i , j;     
    int *intpos;
    char buf[1024];    
    char buf1[16];
    struct VarNode *temp;

    temp = varListHeader;
    if ( temp == 0 ) return FAILURE;
    if ( SrcIsLoaded() != GOOD ) return FAILURE;
    if ( GOOD != LdrSrcGetLoadPath( str ) ) return FAILURE;
    str1 = str;
//    str1.MakeReverse();
//    i = str1.Find('.');
    i = str1.ReverseFind('.');
    j = str1.ReverseFind('\\');
    if ( i < j ) i = str.GetLength();
    str1 = str.Left( i ) + ".var";
    
    symbolFile = _open( str1,_O_CREAT|_O_RDWR|_O_BINARY,
                                _S_IREAD|_S_IWRITE);
    if ( symbolFile == -1 ) {
        return FAILURE;
    }       
    memset( buf , 0 , 1024 );        
    memset( buf1 , 0 , 16 );        
    buf1[0] = 0x0;
    buf1[1] = 0x1A;
    sprintf(&buf1[2] , "MICROTEK");
    _write( symbolFile , buf1 , 16 ); 
    intpos = (int *)buf;
    i = str.GetLength();
    *intpos = i;                         
    if ( i + 2 > 1024 ) return FAILURE;
    strcpy(&buf[2],str);
    _write( symbolFile , buf , i+2 ); 
    while( temp ) {
        memset( buf , 0 , 1024 );        
        i = temp->command.GetLength();
        *intpos = i;                         
        if ( i + 2 > 1024 ) return FAILURE;
        strcpy(&buf[2],temp->command);
        for( j=0 ; j<i+2; j++ ) {
            buf[j] ^= buf1[j&0xF];
        }        
        _write( symbolFile , buf , i+2 ); 
        temp = temp->next;
    }
    buf[0] = 0^buf1[0];
    buf[1] = 0^buf1[1];
    _write( symbolFile , buf , 2 ); 
    _close( symbolFile );
    return( GOOD );        
}

int VarServer::RestoreVariable(void)
{                                       
    CString str , str1;
    int symbolFile ,  i , j;     
    int *intpos;
    U32 num;
    char buf[1024];    
    char buf1[16];
    struct VarNode *temp;

    if ( SrcIsLoaded() != GOOD ) return FAILURE;
    if ( GOOD != LdrSrcGetLoadPath( str ) ) return FAILURE;
    str1 = str;
//    str1.MakeReverse();
//    i = str1.Find('.');
    i = str1.ReverseFind('.');
    j = str1.ReverseFind('\\');
    j = ( j < 0 ) ? 0 : j;
    if ( i < j ) i = str.GetLength();
    str1 = str.Left( i ) + ".var";
    
    symbolFile = _open( str1,_O_RDONLY|_O_BINARY);
    if ( symbolFile == -1 ) {
        return FAILURE;
    }       
    memset( buf , 0 , 1024 );        
    memset( buf1 , 0 , 16 );        
    buf1[0] = 0x0;
    buf1[1] = 0x1A;
    sprintf(&buf1[2] , "MICROTEK");
    if ( _read( symbolFile , buf , 16 ) == -1 ) {
        _close( symbolFile );
        return FAILURE;
    }
    if ( memcmp(buf1 , buf , 16) != 0 ) {
        _close( symbolFile );
        return FAILURE;
    }
    
    memset( buf , 0 , 1024 );        
    intpos = (int *)buf;
    i = str.GetLength();
    if ( _read( symbolFile , buf , i+2 ) == -1 ) {
        _close( symbolFile );
        return FAILURE;
    }
    if ( *intpos != i ) {
        _close( symbolFile );
        return FAILURE;
    }
    if ( strcmp(&buf[2] , str) != 0 ) {
        _close( symbolFile );
        return FAILURE;
    }
        
    memset( buf , 0 , 1024 );        
    if ( _read( symbolFile , buf , 2 ) == -1 ) {
        _close( symbolFile );
        return FAILURE;
    }
    buf[0] ^= buf1[0];
    buf[1] ^= buf1[1];
    i = *intpos;
    while( i > 0 ) {
        if ( i > 1022 ) { 
            _close( symbolFile );
            return FAILURE;
        }
        temp = new VarNode;
        if ( temp == NULL ) {
            _close( symbolFile );
            return FAILURE;
        }
        if ( _read( symbolFile , &buf[2] , i ) == -1 ) {
            _close( symbolFile );
            return FAILURE;
        }
        for( j=2 ; j<i+2; j++ ) {
            buf[j] ^= buf1[j&0xF];
        }        
        temp->command = &buf[2];
        temp->name = temp->command;
        temp->value = "Invalid value";
        temp->flag |= VAR_RESTORE|VAR_NOVALID;
        if ( Add( temp ) != GOOD ) {
            _close( symbolFile );
            return FAILURE;
        }
        memset( buf , 0 , 1024 );        
        if ( _read( symbolFile , buf , 2 ) == -1 ) {
            _close( symbolFile );
            return FAILURE;
        }
        buf[0] ^= buf1[0];
        buf[1] ^= buf1[1];
        i = *intpos;
    }
    _close( symbolFile );
    UpdataAllNode();
    return( GOOD );        
}
    
int VarServer::UpdataRestoreNode( VarNode *node )
{
    BOOLEAN isGlobal ;
    SYM_DESCRIPTOR desc ;
    TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX       typeIndex;
    RETCODE          err;
//   COMMON_SYMBOL_HEADER  *modPtr ;
    VAR_STORAGE_CLASS   storageClass;
    VAR_REGISTER_CLASS  registerClass;
    BOOLEAN             isConstant;
    SYM_DESCRIPTOR      funcDescriptor;
    SYM_DESCRIPTOR      moduleDescriptor;
    SYM_DESCRIPTOR      parentDescriptor;
    GET_VAR_ADDR_STRUCT varAddr;
    char temp[256];
    CSymSyntax *pCalc;
    int nNum;               
    char *pName;

    pCalc = new CSymSyntax;
    if ( 0 == pCalc ) {
      return FAILURE;
    }
    
//   pCalc->Init( str );
    pCalc->Init(node->command);
   pCalc->GetErrorNum( nNum );
   if ( nNum ) {
      delete pCalc;
      return FAILURE;
   }

   if ( GOOD != pCalc->CheckSyntax() ) {
      delete pCalc;
      return FAILURE;
   }                                            
   if ( GOOD != pCalc->IsVariable() ) {
      if ( GOOD != pCalc->CalculateValue() ) {
         delete pCalc;
         return FAILURE;
      }          
      node->flag1 = 1;
      node->pExp = pCalc;

//      node->command = str;
//      node->desc = 0;
      if ( GOOD != pCalc->GetAllTokenNameToStr( node->name ) ) {    
         return FAILURE;
      }          
      if ( GOOD != pCalc->GetExpAddr( node->addr ) ) {    
         return FAILURE;
      }          
      if ( GOOD != pCalc->GetTypeIndex( node->typeIndex ) ) {    
         return FAILURE;
      }          
      if ( GOOD != UpdataOneNode( node ) ) {
         return FAILURE;
      }
      if ( GOOD != isUpdateGOOD ) {
         return FAILURE;
      }
      node->flag &= ~VAR_RESTORE;           
      node->flag &= ~VAR_NOVALID;           
      return GOOD;
   }    
       
   nNum = pCalc->GetOneTokenName(0,pName);
   delete pCalc;
   if ( nNum != 0 ) {
      return FAILURE;
    }
      
//    if ( IsValidVar(str,isGlobal,desc) != 0 ) return FAILURE;
//    if ( IsValidVar(str,isGlobal,desc) != 0 ) {
    if ( IsValidVar(pName,isGlobal,desc) != 0 ) {
      delete []pName;
      return FAILURE;
    }

    if ( isGlobal == TRUE ) {
        node->flag |= VAR_GLOBAL;
    }
    node->desc = desc;
//    node->command = str;
    node->command = pName;
    delete []pName;
    if ( GOOD != SymGetVar( desc,
                            temp,
                            &typeIndex,
                            &storageClass,
                            &registerClass,
                            &isConstant,
                            &funcDescriptor,
                            &moduleDescriptor,
                            &parentDescriptor,
                            &varAddr) ) {
        return FAILURE;
    }
    node->name = temp;
    node->typeIndex = typeIndex;
    typeHeader.typeName = temp;
    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) {
        return FAILURE;
    }                              
    if ( registerClass != NOT_REG ) {
        node->flag |= VAR_REG ;
    } 
    if ( registerClass == NOT_REG ) {
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
            if ( FAILURE == BuildSValue( node->typeIndex ,
               varAddr.fixedAddr.segType,varAddr.fixedAddr.startAddr,
               buff,node->nSize,node->nOffset) ) {
                return FAILURE;
            }
            node->addr.segType = varAddr.fixedAddr.segType;
            node->addr.addr = varAddr.fixedAddr.startAddr;
            node->value = buff;
            if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                return FAILURE;
            }
            node->typeName = buff;
        }
        else {
            if ( typeHeader.t.complexType == TY_TYPE ) {
                while( 1 ) {
                    TYPE_INDEX       typeNext;
                   
                    if ( GOOD != SymGetTypeTypeIndex(typeIndex,&typeNext) ) {
                        return FAILURE;
                    }
                    typeIndex = typeNext;
                    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))){
                        return FAILURE;
                    }
                    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
                        break;
                    else if ( typeHeader.t.complexType != TY_TYPE )
                        break;
                }   
                if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
                    if ( FAILURE == BuildSValue( typeIndex ,
                        varAddr.fixedAddr.segType,varAddr.fixedAddr.startAddr,
                        buff,node->nSize,node->nOffset) ) {
                        return FAILURE;
                    }
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr;
                    node->value = buff;
                    if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                        return FAILURE;
                    }
                    node->typeName = buff;
//                    break;
                }
            }

            if ( (typeHeader.typeChoice==COMPLEX_TYPE_CLASS)&&
                (typeHeader.t.complexType == TY_BITFIELD) ) {
                if ( SrcIsIEEE() == GOOD ) {
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr;
                    if ( FAILURE == BuildIEEEBValue( node , 1 , buff) ) {
                        return FAILURE;
                    }
                    node->value = buff;
                }
                else {
                    if ( FAILURE == BuildBValue( typeIndex ,
                        varAddr.fixedAddr.segType,
                        varAddr.fixedAddr.startAddr,
                        buff) ) {
                        return FAILURE;
                    }
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr;
                    node->value = buff;
                }
                if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                    return FAILURE;
                }
                node->typeName = buff;
            }    
            else if (typeHeader.typeChoice==COMPLEX_TYPE_CLASS &&
                (typeHeader.t.complexType == TY_ENUM_C) ) {
                if ( FAILURE == BuildEnumValue( typeIndex ,
                    varAddr.fixedAddr.segType,
                    varAddr.fixedAddr.startAddr,1,
                    buff) ) {
                    return FAILURE;
                }
                node->addr.segType = varAddr.fixedAddr.segType;
                node->addr.addr = varAddr.fixedAddr.startAddr;
                node->value = buff;
                if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                    return FAILURE;
                }
                node->typeName = buff;
            }    
            else if (typeHeader.typeChoice==COMPLEX_TYPE_CLASS) {
                node->flag |= VAR_COMPLEX;
                switch(typeHeader.t.complexType) {
                case TY_SMALL_PTR :  
			    case TY_DPTR0 :
			    case TY_DPTR1 :    
			    case TY_DPTR2 :    
			    case TY_DPTR3 :    
			   case TY_DPTR4  :   
			   case TY_DPTR5  :   
			   case TY_DPTR6  :   
			   case TY_DPTR7  :   
			   case TY_CPTR0  :   
			   case TY_CPTR1  :   
			   case TY_CPTR2  :   
			   case TY_CPTR3  :                   
                    if ( typeHeader.sizeCalculated == TRUE ) {
                        ADDR    start , end;
                        char    data[16];
                        U32     address ;
                        SEGMENTTYPE segType;

                        address = 0;
                        ConvEnumToAbiType( varAddr.fixedAddr.segType ,
                                     start.addrType );
                        end.addrType = start.addrType;
                        start.addr=(unsigned short)varAddr.fixedAddr.startAddr;
                        end.addr = start.addr + 
                                   (unsigned short)(typeHeader.sizeInMAUs-1);
    #ifdef _LINK_WITH_ABI_
                        RET_ADDR retAddr;
                        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
                            return FAILURE;
                        }  
    #endif
                        if ( typeHeader.sizeInMAUs == 3 ) {
                            address = (U8) data[1];
                            address = (address<<8) + (U8)data[2];
                            if ( GOOD == SrcIsStatement() ) {
                                UbrofConvPtrToSeg(data[0],segType);
                            }
                            else {
                                Omf51ConvPtrToSeg(data[0],segType);
                            }
                        }
                        else if ( typeHeader.sizeInMAUs == 2 ) {
                            segType = varAddr.fixedAddr.segType;
                            //address = (U8) data[0];
                            //address = (address<<8) + (U8)data[1];
                            address =*((U16*)data);
                        }
                        else if ( typeHeader.sizeInMAUs == 1 ) {
                            segType = varAddr.fixedAddr.segType;
                            address = (U8) data[0];
                        }
                        else {
                            return FAILURE;
                        }
                        if ( FAILURE == BuildCAddr( segType , address,
                            buff) ) {
                            return FAILURE;
                        }
                        node->addr.segType = varAddr.fixedAddr.segType;
                        node->addr.addr = varAddr.fixedAddr.startAddr;
                        node->result.segType = segType;
                        node->result.addr = address;
                        node->value = buff;
                        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                            return FAILURE;
                        }
                        node->typeName = buff;
                    }
                    break;
                case TY_OMF51_PTR :
                    if ( typeHeader.sizeCalculated == TRUE ) {
                        ADDR    start , end;
                        char    data[16];
                        U32     address ;
                        SEGMENTTYPE segType;
                        SEGMENTTYPE ssss;
                        TYPE_OMF51_PTR_STRUCT omf51Ptr;

                        if ( SymGetTypePointer51(typeIndex,&omf51Ptr) != GOOD )
                            return FAILURE;
                        address = 0;
                        ConvEnumToAbiType( varAddr.fixedAddr.segType ,
                                     start.addrType );
                        end.addrType = start.addrType;
                        start.addr = (unsigned short) varAddr.fixedAddr.startAddr;
                        end.addr = start.addr + 
                                   (unsigned short)(typeHeader.sizeInMAUs-1);
    #ifdef _LINK_WITH_ABI_
                        RET_ADDR retAddr;
                        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
                            return FAILURE;
                        }
    #endif              
                        if ( typeHeader.sizeInMAUs == 3 ) {
                            address = (U8) data[1];
                            address = (address<<8) + (U8)data[2];
                            if ( GOOD == SrcIsStatement() ) {
                                UbrofConvPtrToSeg(data[0],segType);
                            }
                            else {
                                Omf51ConvPtrToSeg(data[0],segType);
                            }
                            ssss = segType;
                        }
                        else if ( typeHeader.sizeInMAUs == 2 ) {
                            //address = (U8) data[0];
                            //address = (address<<8) + (U8)data[1];
                            address =*((U16*)data);
                            MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                            ssss = segType;
                            if ( SrcIsIEEE() == GOOD ) {
                                if ( (GOOD==SymGetTypeHeader(omf51Ptr.typeIndex, 
                                    &typeHeader)) &&(typeHeader.typeChoice==
                                    COMPLEX_TYPE_CLASS)&&
                                    (typeHeader.t.complexType == TY_TYPE) 
                                ) {                    
                                    TYPE_INDEX tttt;
                                    if ( GOOD != SymGetTypeTypeType(
                                        omf51Ptr.typeIndex,&tttt,&ssss) ) {
                                        if ( ssss != SEG_UNTYPED ) 
                                            ssss = segType;
                                    }    
                                }    
                            }                              
                        }
                        else if ( typeHeader.sizeInMAUs == 1 ) {
                            address = (U8) data[0];
                            MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                            ssss = segType;
                            if ( SrcIsIEEE() == GOOD ) {
                                if ( (GOOD==SymGetTypeHeader(omf51Ptr.typeIndex, 
                                    &typeHeader)) &&(typeHeader.typeChoice==
                                    COMPLEX_TYPE_CLASS)&&
                                    (typeHeader.t.complexType == TY_TYPE) 
                                ) {                    
                                    TYPE_INDEX tttt;
                                    if ( GOOD != SymGetTypeTypeType(
                                        omf51Ptr.typeIndex,&tttt,&ssss) ){
                                        if ( ssss != SEG_UNTYPED ) 
                                            ssss = segType;
                                    }    
                                }    
                            }                              
                        }
//                        if ( FAILURE == BuildCAddr( segType , address,
                        if ( FAILURE == BuildCAddr( ssss , address,
                            buff) ) {
                            return FAILURE;
                        }
                        node->addr.segType = varAddr.fixedAddr.segType;
                        node->addr.addr = varAddr.fixedAddr.startAddr;
//                        node->result.segType = segType;
                        node->result.segType = ssss;
                        node->result.addr = address;
                        node->value = buff;
                        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                            return FAILURE;
                        }
                        node->typeName = buff;
                    }
                    break;
    //                return ( BuildCAddr( varAddr.fixedAddr.segType ,
    //                        varAddr.fixedAddr.startAddr ,tmpStr ) );
                default :
                     if ( FAILURE == BuildCAddr( varAddr.fixedAddr.segType ,
                            varAddr.fixedAddr.startAddr ,buff ) ) {
                         return FAILURE;
                     }
                     node->addr.segType = varAddr.fixedAddr.segType;
                     node->addr.addr = varAddr.fixedAddr.startAddr;
                     node->result.segType = varAddr.fixedAddr.segType;
                     node->result.addr = varAddr.fixedAddr.startAddr;
                     node->value = buff;
                     if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
                         return FAILURE;
                     }
                     node->typeName = buff;
                }
            }
        }
    }
    else {
        //sprintf( buff,"Register," );
        //node->value = buff;
		if ( FAILURE == BuildSValue( node->typeIndex ,varAddr.fixedAddr.
					segType,varAddr.fixedAddr.startAddr ,
					buff,node->nSize,node->nOffset) ) {
                delete node;
                return FAILURE;
            }
        node->addr.segType = varAddr.fixedAddr.segType;
        node->addr.addr = varAddr.fixedAddr.startAddr;
        node->value = buff;        
        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
            return FAILURE;
        }
        node->typeName = buff;
    }
    node->flag &= ~VAR_RESTORE;           
    node->flag &= ~VAR_NOVALID;           
    return GOOD;
}

int VarServer::UpdataAllLocal()
{
    struct VarNode *node;
    
    U32    uch;

    ////emuGetCpuStatus(&uch);
    if ( !cpuStatus()) {
        return GOOD;
    }

    node = varListHeader ;
    while ( node ) {
        node->flag &= ~VAR_NOVALID;
        UpdataOneNode( node );
        node = node->next ;
    }
    return GOOD ;
}

int VarServer::UpdataAllNode()
{
    BOOLEAN isGlobal ;
    SYM_DESCRIPTOR desc ;
    struct VarNode *node;
//   TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX       typeIndex;
//   RETCODE          err;
//   COMMON_SYMBOL_HEADER  *modPtr ;
    VAR_STORAGE_CLASS   storageClass;
    VAR_REGISTER_CLASS  registerClass;
    BOOLEAN             isConstant;
    SYM_DESCRIPTOR      funcDescriptor;
    SYM_DESCRIPTOR      moduleDescriptor;
    SYM_DESCRIPTOR      parentDescriptor;
    GET_VAR_ADDR_STRUCT varAddr;
    char temp[256];

    U32    uch;

//    //emuGetCpuStatus(&uch);
    if ( !cpuStatus() ) {
        return GOOD;
    }

    buildStack();            
    node = varListHeader ;
    while ( node ) {
        if ( node->flag & VAR_RESTORE ) {
            UpdataRestoreNode( node );
            node = node->next;
            continue;
        }
        if ( node->flag & VAR_NOVALID ) {
            node->flag &= ~VAR_EXTEND;
        }
        node->flag &= ~VAR_NOVALID;
//      if ( node->flag & VAR_EXTEND ) {
//          ClearNode( node );
//          node->flag &= ~VAR_EXTEND;
//      }
        if ( node->flag1 ) {
         TYPE_INDEX t_i;
            if ( 0 != node->pExp->ReflushExpress() ) {
                ClearNode( node );
                node->line = 1;
                node->flag |= VAR_NOVALID ;
                node = node->next;
                continue;
            }
         if ( GOOD != node->pExp->GetExpAddr( node->addr ) ) {    
                ClearNode( node );
                node->line = 1;
                node->flag |= VAR_NOVALID ;
                node = node->next;
                continue;
         }          
         if ( GOOD != node->pExp->GetTypeIndex( t_i ) ) {    
                ClearNode( node );
                node->line = 1;
                node->flag |= VAR_NOVALID ;
                node = node->next;
                continue;
         }          
         if ( t_i == node->typeIndex ) {
            UpdataOneNode( node );
         }
         else {
                ClearNode( node );
                node->line = 1;
                node->flag = VAR_ROOT ;
                node->typeIndex = t_i;
            UpdataOneNode( node );
         }            
        }
        else if ( node->flag & VAR_GLOBAL ) {
//          node->flag &= ~VAR_NOVALID;
            UpdataOneNode( node );
        }
        else {                    
            if (IsValidVar(node->command.GetBuffer(node->command.GetLength()),
                isGlobal,desc) != 0 ) {
                ClearNode( node );
                node->line = 1;
                node->flag |= VAR_NOVALID ;
            }
            else {
                if ( GOOD != SymGetVar( desc,
                                        temp,
                                        &typeIndex,
                                        &storageClass,
                                        &registerClass,
                                        &isConstant,
                                        &funcDescriptor,
                                        &moduleDescriptor,
                                        &parentDescriptor,
                                        &varAddr) ) {
                    node->flag |= VAR_NOVALID ;
                    ClearNode( node );
                    node->line = 1;
                    node = node->next;
                    continue ;
                }

                if ( desc == node->desc ) {             
                    UpdataOneNode( node );
                }
                else {                       
                    ClearNode( node );
                    node->line = 1;
                    node->flag = VAR_ROOT ;
                    if ( isGlobal == TRUE ) {
                        node->flag |= VAR_GLOBAL;
                    }
                    node->desc = desc;
                    node->addr.segType = varAddr.fixedAddr.segType;
                    node->addr.addr = varAddr.fixedAddr.startAddr; 
                    node->name = temp;
                    node->typeIndex = typeIndex;
                    if ( registerClass != NOT_REG ) {
                        node->flag |= VAR_REG;
                    }
                    UpdataOneNode( node );
                }
            }
        }
        node = node->next ;
    }
    return GOOD ;
}

void VarServer::ClearNode( struct VarNode *node )
{
    struct VarNode *temp , *temp1;
    
    if ( node == 0 ) return;
    temp = node->son;
    while( temp ) {
        temp1 = temp->next;
        ClearNode( temp );
        delete temp;
        temp = temp1 ;
    }
    node->son = 0;
    return;
}       

int VarServer::VarExtendedNode( struct VarNode* node )
{
    TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX       typeIndex , pTypeIndex;
    RETCODE          err;
    char             temp[256];
    struct VarNode   *son , *brother ;
    TYPE_OMF51_PTR_STRUCT omf51Ptr;
    TYPE_S_U_STRUCT  s;                
    U16              ui;
    TYPE_C_ARRAY_STRUCT arr;
    TYPE_OMF51_ARRAY_STRUCT omf51Arr;
    S32              *pMaxArr , *pCurArr;   
    S32              nArrSize , nCur;
    U32              uOneSize ;
    U32              uNowAddr;
        
    if ( node == 0 ) return FAILURE;
    if ( !(node->flag & VAR_COMPLEX) ) return FAILURE;
    if ( node->flag & VAR_EXTEND ) return GOOD;
//    if ( node->num >= 30 ) {
//        AfxMessageBox("Out of Memory!");
//        return FAILURE;
//    }
                                        
    typeIndex = node->typeIndex ;                                        
    typeHeader.typeName = temp;
/*
    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) {
        node->flag |= VAR_NOVALID ;
        return FAILURE;
    }
    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) return FAILURE;
*/    
    do {
        if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) {
            node->flag |= VAR_NOVALID ;
            return FAILURE;
        }
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) return FAILURE;
        if ( typeHeader.t.complexType == TY_TYPE ) {
            U32 typeNext;
            if ( GOOD != SymGetTypeTypeIndex(typeIndex,&typeNext) ) {
//                node->flag |= VAR_NOVALID ;
                return FAILURE;
            }
            typeIndex = typeNext;
        }    
    } while ( typeHeader.t.complexType == TY_TYPE );    
    switch(typeHeader.t.complexType) {
    case TY_SMALL_PTR : 
    case TY_DPTR0 :
    case TY_DPTR1 :    
    case TY_DPTR2 :    
    case TY_DPTR3 :    
	case TY_DPTR4  :   
	case TY_DPTR5  :   
	case TY_DPTR6  :   
	case TY_DPTR7  :   
	case TY_CPTR0  :   
	case TY_CPTR1  :   
	case TY_CPTR2  :   
	case TY_CPTR3  :   
        if ( GOOD != ( err = SymGetTypePointerTypeIndex( typeIndex ,
                &pTypeIndex ) ) ) {
            node->flag |= VAR_NOVALID ;
            return FAILURE;
        }                 
        son = new struct VarNode ;
        if ( son == 0 ) {
            return FAILURE ;
        }
        son->flag &= ~VAR_ROOT;
        son->typeIndex = pTypeIndex ;
        son->num = node->num + 1;
        son->addr.addr = node->result.addr;
        son->addr.segType = node->result.segType;
        son->father = node;
        node->son = son;
        sprintf( buff , "*%s", node->name.GetBuffer(node->name.GetLength()) );
        son->name = buff;
        node->flag |= VAR_EXTEND;
        UpdataOneNode( son );
        UpdataLine( 1 , node );     
        break;
    case TY_OMF51_PTR :
        if ( SymGetTypePointer51(typeIndex,&omf51Ptr) != GOOD ) {
            node->flag |= VAR_NOVALID ;
            return FAILURE;
        }
        son = new struct VarNode ;
        if ( son == 0 ) {
            return FAILURE ;
        }
        son->flag &= ~VAR_ROOT;
        son->typeIndex = omf51Ptr.typeIndex ;
        son->addr.addr = node->result.addr;
        son->addr.segType = node->result.segType;
        son->father = node;
        son->num = node->num + 1;
        node->son = son;
        sprintf( buff , "*%s", node->name.GetBuffer(node->name.GetLength()) );
        son->name = buff;
        node->flag |= VAR_EXTEND;
        UpdataOneNode( son );
        UpdataLine( 1 , node );     
        break;                       
    case TY_STRUCT :
    case TY_UNION :  
        ui = 0 ;
        s.name = temp ;
        brother = 0;
        while ( GOOD == SymGetTypeStructUnionNth( typeIndex , ui , &s ) ) {
            son = new struct VarNode ;
            if ( son == 0 ) {
                return FAILURE ;
            }
            son->flag &= ~VAR_ROOT;
            son->typeIndex = s.typeIndex ;                
            son->name = s.name;
            son->num = node->num + 1;
            son->addr.addr = node->result.addr + s.offset;
            son->addr.segType = node->result.segType;
            son->bBit =s.bBit; 
            if(s.bBit)
            {	son->nSize = s.size;son->nOffset = s.offset;}
            else	
            {	son->nSize = 0;son->nOffset = 0;}
//            
            if(s.bBit)
            {          
                son->addr.addr = node->result.addr + (s.offset>>3);
            }    
/*           if ( SrcIsIEEE() == GOOD ) {              
                TYPE_INDEX nextIndex;
                TYPE_HEADER_TYPE tpHeader;
                char ttt[256];
            
                if ( GOOD==FindNextType(s.typeIndex, nextIndex) ) {
                    tpHeader.typeName = ttt;  
                    if (GOOD == SymGetTypeHeader(nextIndex, &tpHeader) && 
                        tpHeader.typeChoice==COMPLEX_TYPE_CLASS &&
                        tpHeader.t.complexType == TY_BITFIELD ) {
                        son->addr.addr = node->result.addr + (s.offset>>3);
                    }
                }
            }
*/
            son->father = node;
            if ( ui == 0 ) {
                node->son = son;
            }  
            if ( brother ) {
                brother->next = son;
            }
            son->prev = brother;
            brother = son;
            UpdataOneNode( son );
            ui++;
        }
        if ( ui ) node->flag |= VAR_EXTEND;
        UpdataLine( ui , node );        
        break;          
    case  TY_C_ARRAY :        
        if ( typeHeader.sizeCalculated == TRUE ) {
            uOneSize = typeHeader.sizeInMAUs;
        }
        else uOneSize = 0;      
        nArrSize = 0;
        do {
            if ( GOOD != SymGetTypeCArray(typeIndex,&arr) ) 
                return FAILURE ;
            typeIndex = arr.typeIndex ;
            nArrSize++;
            if (GOOD!=SymGetTypeHeader(typeIndex,&typeHeader)) 
                return FAILURE;
            if (typeHeader.typeChoice!=COMPLEX_TYPE_CLASS )
                break;
            if (typeHeader.t.complexType != TY_C_ARRAY )
                break;
        } while( TRUE );
        pMaxArr = new long [ nArrSize+1 ];
        pCurArr = new long [ nArrSize+1 ];
        if ( (pMaxArr==0) || (pCurArr==0) ) 
            return FAILURE ;
        memset( pCurArr , 0 , (size_t)((nArrSize+1)*sizeof(long)) );
        nCur = 0; 
        typeIndex = node->typeIndex;
        do {
            if ( GOOD != SymGetTypeCArray(typeIndex,&arr) ) 
                return FAILURE ;
            typeIndex = arr.typeIndex ;
            pMaxArr[nCur] = arr.highBound ; 
            nCur++;
            SymGetTypeHeader(typeIndex,&typeHeader); 
            if (typeHeader.typeChoice!=COMPLEX_TYPE_CLASS )
                break;
            if (typeHeader.t.complexType != TY_C_ARRAY )
                break;
        } while( TRUE );
        if ( nCur != nArrSize ) {
            delete pMaxArr;
            delete pCurArr;
            return FAILURE;
        }       
        nCur = 0;
        if ( typeHeader.sizeCalculated == TRUE ) {
            uOneSize = typeHeader.sizeInMAUs;
        }
        else if ( uOneSize ) {
            while( nCur < nArrSize ) {
                uOneSize = uOneSize / pMaxArr[nCur];
                nCur++;
            }
        }
        if ( uOneSize == 0 ) {      
            delete pMaxArr;
            delete pCurArr;
            return FAILURE;
        }                               
        uNowAddr = node->result.addr;
        ui = 0;
        brother = 0;
        while ( pMaxArr[0] >= pCurArr[0] ) {
            int i , j;
        
            son = new struct VarNode ;
            if ( son == 0 ) {
                return FAILURE ;
            }
            son->flag &= ~VAR_ROOT;
            son->typeIndex = typeIndex ;                
            j = 0;
            for(i=0;i<nArrSize;i++) {
                sprintf(&temp[j],"[%d]",pCurArr[i]);
                j=strlen(temp);
            }
            son->name = node->name+temp;
            son->num = node->num + 1;
            son->addr.addr = uNowAddr;
            son->addr.segType = node->result.segType;
            son->father = node;
            if ( ui == 0 ) {
                node->son = son;
            }  
            if ( brother ) {
                brother->next = son;
            }
            son->prev = brother;
            brother = son;
            UpdataOneNode( son );
            ui++;   
            uNowAddr += uOneSize;
            pCurArr[ nArrSize-1 ]++;
            for(i=(int)(nArrSize-1);i>=1;i--) {
                if( pCurArr[i]>pMaxArr[i] ) {
                    pCurArr[i] = 0;
                    pCurArr[i-1]++;
                }
            }
        }
        if ( ui ) node->flag |= VAR_EXTEND;
        UpdataLine( ui , node );        
        break;
                    
    case  TY_OMF51_ARRAY :        
        if ( typeHeader.sizeCalculated == TRUE ) {
            uOneSize = typeHeader.sizeInMAUs;
        }
        else uOneSize = 0;      
        if ( GOOD != SymGetTypeArray51(typeIndex,&omf51Arr) ) 
            return FAILURE ;
        nArrSize = omf51Arr.dim;
        pMaxArr = new long [ nArrSize+1 ];
        pCurArr = new long [ nArrSize+1 ];
        if ( (pMaxArr==0) || (pCurArr==0) ) 
            return FAILURE ;
        memset( pCurArr , 0 , (size_t)((nArrSize+1)*sizeof(long)) );
        nCur = 0; 
        typeIndex = node->typeIndex;
        for( nCur=0; nCur<nArrSize; nCur++) {                   
            U16 tt;
            if ( GOOD != SymGetTypeArrayDimSizeNth(typeIndex,
                                         (U8)(nCur+1), &tt) )
                return FAILURE;
            pMaxArr[nCur] = tt;
        }                                         
        typeIndex = omf51Arr.typeIndex ;    
        if ( GOOD != SymGetTypeHeader(typeIndex,&typeHeader) ) { 
            delete pMaxArr;
            delete pCurArr;
            return FAILURE;
        }       
        nCur = 0;
        if ( typeHeader.sizeCalculated == TRUE ) {
            uOneSize = typeHeader.sizeInMAUs;
        }
        else if ( uOneSize ) {
            while( nCur < nArrSize ) {
                uOneSize = uOneSize / pMaxArr[nCur];
                nCur++;
            }
        }
        if ( uOneSize == 0 ) {      
            delete pMaxArr;
            delete pCurArr;
            return FAILURE;
        }                               
        uNowAddr = node->result.addr;
        ui = 0;
        brother = 0;
        while ( pMaxArr[0] >= pCurArr[0] ) {
            int i , j;
        
            son = new struct VarNode ;
            if ( son == 0 ) {
                return FAILURE ;
            }
            son->flag &= ~VAR_ROOT;
            son->typeIndex = typeIndex ;                
            j = 0;
            for(i=0;i<nArrSize;i++) {
                sprintf(&temp[j],"[%d]",pCurArr[i]);
                j=strlen(temp);
            }
            son->name = node->name+temp;
            son->num = node->num + 1;
            son->addr.addr = uNowAddr;
            son->addr.segType = node->result.segType;
            son->father = node;
            if ( ui == 0 ) {
                node->son = son;
            }  
            if ( brother ) {
                brother->next = son;
            }
            son->prev = brother;
            brother = son;
            UpdataOneNode( son );
            ui++;   
            uNowAddr += uOneSize;
            pCurArr[ nArrSize-1 ]++;
            for(i=(int)(nArrSize-1);i>=1;i--) {
                if( pCurArr[i]>pMaxArr[i] ) {
                    pCurArr[i] = 0;
                    pCurArr[i-1]++;
                }
            }
        }
        if ( ui ) node->flag |= VAR_EXTEND;
        UpdataLine( ui , node );        
        break;
                    
    default :
        return FAILURE;
    }

    return GOOD;
}

int VarServer::VarCompressNode( struct VarNode* node )
{
    if ( node == 0 ) return FAILURE;
    if ( !(node->flag & VAR_COMPLEX) ) return FAILURE;
    if ( node->flag & VAR_EXTEND ) {
        node->flag &= ~VAR_EXTEND ;
        ClearNode( node );         
        UpdataLine( 1-node->line, node );
    }
    else return FAILURE;
    return GOOD;
} 


void VarServer::UpdataLine(int nLine,struct VarNode* node)
{
    struct VarNode *temp;
    
    temp = node;
                
    while( temp ) {
        temp->line += nLine ;
        if ( temp->line < 1 ) {
            temp->line = 1;
        }
        temp = temp->father ;
    }
}

int VarServer::VarLineToNode(int nRow,struct VarNode*& node)
{
    struct VarNode * temp;
    
    if ( nRow < 0 ) return FAILURE;
    nRow++;
    temp = varListHeader ;
    while ( temp ) {
        nRow --;
        if ( nRow == 0 ) {
            node = temp;
            return GOOD;
        }
        if ( temp->line > nRow ) {
            temp = temp->son ;
//          nRow -= temp.line-1;
        }
        else {
            nRow -= temp->line-1;
            temp = temp->next ;
//          nRow -= temp->line-1;
        }
    }
    node = 0;           
    return FAILURE;
}        

int VarServer::VarNodeToPos(struct VarNode* node,int& nPos)
{
    struct VarNode * temp;
    
    nPos = 0;
    if ( node == 0 ) return FAILURE;
    temp = varListHeader ;
    while ( temp ) {
        if ( temp == node ) {
            break;
        } 
        nPos++;
        temp = temp->next ;
    }          
    if ( temp ) return GOOD;
    return FAILURE;
}        

void VarServer::VarAddrToStr(ADDRESS_TYPE addr,CString& str)
{
    BuildCAddr(addr.segType,addr.addr,buff);
    str = buff;
}

int VarServer::Search( char *str , int & nLine )
{
    struct VarNode *tt;
    
    nLine = 0;  
    if ( str == 0 ) return FAILURE;
    if ( *str == '\0' ) return FAILURE;
    tt = varListHeader ;
    while( tt ) {
        if ( tt->name.Find( str ) >= 0 )
            break;              
        nLine++;
        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;
    }           
    if ( tt ) return GOOD;
    else return FAILURE;
}

int VarServer::SearchNext( char *str , int nStartLine , int & nLine )
{
    struct VarNode *tt;                                         
    RET_ADDR retAddr;
    
    if ( nStartLine <  0 ) return FAILURE;
    nLine = nStartLine; 
    if ( str == 0 ) return FAILURE;
    if ( *str == '\0' ) return FAILURE;
    if ( GOOD != VarLineToNode(nStartLine,tt) ) return FAILURE;
//  tt = varListHeader ;
    while( tt ) {
        if ( tt->name.Find( str ) >= 0 )
            break;              
        nLine++;
        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;
    }           
    if ( tt ) return GOOD;
    else return FAILURE;
} 

int VarServer::ModifyValue(int nLine , CString str)
{
    struct VarNode *tt;
    char *ttt;
    
    if ( GOOD != VarLineToNode(nLine,tt) ) return FAILURE;
    ttt = str.GetBuffer(str.GetLength());
    if ( ttt == 0 ) return FAILURE;
    if (*ttt == '\0') return FAILURE;
    if ( tt == 0 ) return FAILURE;
    if ( tt->flag & VAR_COMPLEX ) return FAILURE;
    if ( tt->flag1 ) {
      int nFlag ;
      if ( GOOD != tt->pExp->IsSymbol(nFlag) ) {
         return FAILURE;
      }
      if ( 0 == nFlag ) return FAILURE;
    }
    if ( GOOD != SetValue( tt , ttt ) ) return FAILURE;

#ifdef _LINK_WITH_SOURCE_    
    if ( tt->addr.segType == SEG_CODE ) 
        SrcUpdate();
#endif
        
    UpdataAllNode( );
    return ( GOOD );
}

int VarServer::SetValue(struct VarNode* node, char *str)
{   
    ADDR start , end;
    char data[16] ;
    char temp[256];
    char *pValue;    
    char *pEnd;       
    char *endPtr;
//    U8 uc;
    U16 ui , uj , uk;
    U32 ul;
    float f;
    int num;
    double d;
    TYPE_INDEX nextIndex;
    RET_ADDR retAddr;
    
    if ( node == 0 ) return FAILURE;
    if ( node->flag & VAR_COMPLEX ) return FAILURE;
    int nBank;
    switch( node->addr.segType ) {
    case SEG_CODE : 
        start.addrType = end.addrType = MEM_P0;
        SymConvertToBank( start.addr , nBank );
        start.addrType += nBank;
        start.addr = (start.addr&0x0FFFFL);
        end.addr = (end.addr&0x0FFFFL);
        break;
    case SEG_DATA :
        start.addrType = end.addrType = MEM_I;
        break;
    case SEG_XDATA :
        start.addrType = end.addrType = MEM_X0;
        SymConvertToBank( start.addr , nBank );
        start.addrType += nBank;
        start.addr = (start.addr&0x0FFFFL);
        end.addr = (end.addr&0x0FFFFL);
//      start.addrType = end.addrType = 3;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 6;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 5;
        break;
    case SEG_SFR :
        start.addrType = end.addrType = 7;
        break;
    default :
        start.addrType = end.addrType = MEM_P0;
        break;
    }   //end of switch
    start.addr = node->addr.addr ;
    if ( GOOD != FindNextType(node->typeIndex,nextIndex) )
        return FAILURE;

// jerry modify
    TYPE_HEADER_TYPE typeHeader;
    typeHeader.typeName=temp;
    TYPE_BITFIELD_STRUCT bit;        
    int nLen;
    bit.offset =0;    
    if(nextIndex == BI_UNKNOWN)
    {
        if ( node->father ) {
            struct VarNode *father;
    
            father = node->father;
            if (GOOD != SymGetTypeHeader(father->typeIndex, &typeHeader)) 
                return FAILURE;
            if ( typeHeader.t.complexType == TY_STRUCT||typeHeader.t.complexType == TY_UNION ) {
                TYPE_S_U_STRUCT  s;
                ui = 0 ;
                struct VarNode *tt;
                tt = father->son;
                while( tt ) {
                    if ( tt == node ) break;
                    ui++;    
                    tt = tt->next;
                }
                if ( tt == 0 ) return FAILURE;
                s.name = temp ;
                if ( GOOD != SymGetTypeStructUnionNth( father->typeIndex,
                    ui , &s ) ) return FAILURE;             
                if(s.bBit)
                {
                    uj=s.offset>>3  ;                                     
                    start.addr = (U16)(father->result.addr + uj);    
                    bit.offset = (U8)( bit.offset + (U8)(s.offset%8) );                     
                    bit.size  = s.size;
                    nLen =1+((bit.offset+bit.size)>>3) ;
                    if(nLen <2)
                    {
                        BYTE mask, nT;
                        nT=(BYTE)strtol(str , &pEnd , 10 ); 
                        if(nT>(1<<bit.size) ) return FAILURE;
                        if ( pEnd == 0 ) return FAILURE;
                        if ( *pEnd != '\0' ) {                   
                            int num;
                            unsigned long ul;
                            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                                return FAILURE;
                            if ( num > 2 ) return FAILURE;
                        }
                        end.addr = start.addr;
                        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
                            return !GOOD;
                        }        
                        mask =~( ((1<<bit.size)-1)<<bit.offset );
                        data[0]=data[0]&mask;
                        data[0]=data[0]|(nT<<bit.offset);
                        if ( ICE_OK != emuSetMemN(start,(U8*)data,1,&retAddr) ) {
                            return !GOOD;
                        }             
                        return GOOD;
                    }
                    else
                    {
                        //if ( (bit.offset+bit.size)>16 ) return FAILURE;
                        end.addr = start.addr+1;
                        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
                            return !GOOD;
                        }
                        //ui = (U16) data[1];
                        //ui = (ui<<8) + (U8)data[0];
                        ui=*( (U16*)data);
                        uj = 1;
                        //for(int i=0;i<(int)bit.size;i++)
                            uj = uj << 1;
                        //uj--;
                        uj =( (1<<bit.size)-1)<<bit.offset;
                        uj=~uj; 
                        uj=uj&ui;
                        //ui = ui & (~(uj<<bit.offset));
                        //ui =(ui&(~uj))>>bit.offset;
                        strtol(str , &pEnd , 10 );
                        if ( pEnd == 0 ) return FAILURE;
                        if ( *pEnd != '\0' ) {                   
                            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                                return FAILURE;
                            if ( num > 4 ) return FAILURE;
                            uk = (U16) ul;
                        }
                        else uk=strtoul(str,&endPtr,0);//sscanf( str , "%d" , &uk);
                        if(uk>(1<<bit.size) ) return -1; 
                        uk=uk<<bit.offset;
                        uk = uk|uj;
                        //ui = ui | ( uk << bit.offset ); 
                        data[0] = ( char ) ( ui & 0xFF );
                        data[1] = ( char ) ( ui >> 8 );
                        //data =(BYTE*)(&uk);
                        if ( ICE_OK != emuSetMemN(start,(U8*)data,2,&retAddr) ) {
                            return !GOOD;
                        }             
                    }    
                    return GOOD;
                }
            }
        }
    }
        
    if ( nextIndex >= 256 ) {    //jerryadd
        int i;
        typeHeader.typeName = temp;
        if (GOOD != SymGetTypeHeader(nextIndex, &typeHeader)) 
            return FAILURE;
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
            return FAILURE;
        if ( typeHeader.t.complexType != TY_BITFIELD ) {
            if ( typeHeader.t.complexType != TY_ENUM_C )
                return FAILURE;                                
            BOOLEAN isNoMatch;
            isNoMatch = TRUE;    
            if ( GOOD != SymGetTypeEnumValue(nextIndex,str,&ul,&isNoMatch) )
                return FAILURE;
            if ( isNoMatch == TRUE ) {
                strtol(str , &pEnd , 10 );
                if ( pEnd == 0 ) return FAILURE;
                if ( *pEnd != '\0' ) {                   
                    if ( FAILURE == CheckIsHexValue(str,num,ul) ) 
                        return FAILURE;
                    if ( num > 4 ) return FAILURE;
                    ui = (U16) ul;
                }
                else ui=strtoul(str,&endPtr,0);//sscanf(str,"%u",&ui);
            }
            else {
                ui = (U16)ul;
            }  
            pValue = (char *) &ui;      
            data[0] = pValue[1];
            data[1] = pValue[0];
    #ifdef _LINK_WITH_ABI_        
            if ( ICE_OK != emuSetMemN(start,(U8*)data,2,&retAddr) ) { 
                return GOOD;
            }
    #endif  
            return GOOD;
        }    
        
//        if ( GOOD != SymGetTypeBitfield(node->typeIndex,&bit) )
/*        if ( GOOD != SymGetTypeBitfield(nextIndex,&bit) )
            return FAILURE;

        if ( node->father ) {
            struct VarNode *father;

            father = node->father;
            if (GOOD != SymGetTypeHeader(father->typeIndex, &typeHeader)) 
                return FAILURE;
            if ( typeHeader.t.complexType == TY_STRUCT ) {
                TYPE_S_U_STRUCT  s;
                ui = 0 ;
                struct VarNode *tt;
                tt = father->son;
                while( tt ) {
                    if ( tt == node ) break;
                    ui++;    
                    tt = tt->next;
                }
                if ( tt == 0 ) return FAILURE;
                s.name = temp ;
                if ( GOOD != SymGetTypeStructUnionNth( father->typeIndex,
                    ui , &s ) ) return FAILURE;             
                uj = s.offset >> 3;
                start.addr = (unsigned short) (father->result.addr + uj);
                bit.offset = (U8) ( bit.offset + (U8)(s.offset%8) ); 
            }
        }
    
        switch ( bit.baseTypeIndex ) {
        case BI_S8_SCHAR:
        case BI_U8_UCHAR:
        case BI_S8_CHAR:  
            if ( (bit.offset+bit.size)>8 ) return FAILURE;
            end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
            if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
//                return FAILURE;
                return GOOD;
            }
#else 
            data[0] = 0;    
#endif  
            ui = data[0];
            uj = 1;
            for(i=0;i<(int)bit.size;i++)
                uj = uj << 1;
            uj--;
            ui = ui & (~(uj<<bit.offset));

            strtol(str , &pEnd , 10 );
            if ( pEnd == 0 ) return FAILURE;
            if ( *pEnd != '\0' ) {                   
                if ( FAILURE == CheckIsHexValue(str,num,ul) )
                    return FAILURE;
                if ( num > 2 ) return FAILURE;
                uk = (U16) ul;
            }
            else uk=strtoul(str,&endPtr,0);//sscanf( str , "%d" , &uk);

            uk = uk&uj;
            ui = ui | ( uk << bit.offset ); 
            data[0] = ( char ) ui;
            if ( ICE_OK != emuSetMemN(start,(U8*)data,1,&retAddr) ) {
                return GOOD;
            }
            return GOOD;

        default :   
            if ( (bit.offset+bit.size)>16 ) return FAILURE;
            end.addr = start.addr+1;
            if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
                return GOOD;
            }
            ui = (U16) data[1];
            ui = (ui<<8) + (U8)data[0];
            uj = 1;
            for(i=0;i<(int)bit.size;i++)
                uj = uj << 1;
            uj--;
            ui = ui & (~(uj<<bit.offset));

            strtol(str , &pEnd , 10 );
            if ( pEnd == 0 ) return FAILURE;
            if ( *pEnd != '\0' ) {                   
                if ( FAILURE == CheckIsHexValue(str,num,ul) )
                    return FAILURE;
                if ( num > 4 ) return FAILURE;
                uk = (U16) ul;
            }
            else uk=strtoul(str,&endPtr,0);//sscanf( str , "%d" , &uk);
            
            uk = uk&uj;
            ui = ui | ( uk << bit.offset ); 
            data[0] = ( char ) ( ui & 0xFF );
            data[1] = ( char ) ( ui >> 8 );
            if ( ICE_OK != emuSetMemN(start,(U8*)data,2,&retAddr) ) {
                return GOOD;
            }
            return GOOD;
        }
*/    }


//    switch ( node->typeIndex ) {
    switch ( nextIndex ) {
    case BI_BIT :
        strtol(str , &pEnd , 10 );
        if ( pEnd == 0 ) return FAILURE;
        if ( *pEnd != '\0' ) {                   
            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                return FAILURE;
            if ( num > 1 ) return FAILURE;
            data[0] = (U8) ul;
        }
        else data[0]=strtoul(str,&endPtr,0);//sscanf( str , "%d" , &data[0]);

#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuSetMemN(start,(U8*)data,1,&retAddr) ) {
            return GOOD;
//            return FAILURE;
        }
#endif  
        return GOOD;
    case BI_S8_SCHAR:
    case BI_U8_UCHAR:
    case BI_S8_CHAR:
/*    
        sscanf( str , "%c" , &data[0]);
*/
        if ( *str == 39 ) {
            data[0] = str[1];
        }
        else {            
            strtol(str , &pEnd , 10 );
            if ( pEnd == 0 ) return FAILURE;
            if ( *pEnd != '\0' ) {                   
                if ( FAILURE == CheckIsHexValue(str,num,ul) )
                    return FAILURE;
                if ( num > 2 ) return FAILURE;
                ui = (U16) ul;
            }
            else ui=strtoul(str,&endPtr,0);//sscanf(str,"%d",&ui);
            
            pValue = (char *) &ui;      
            data[0] = pValue[0];
        }
        
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuSetMemN(start,(U8*)data,1,&retAddr) ) {
//            return FAILURE;
            return GOOD;
        }
#endif  
        return GOOD;
    case BI_S16_SINT:
    case BI_U16_UINT:
    case BI_S16_SHORT:
    case BI_S16_USHORT:
    case BI_S16_SHORTINT:
    case BI_S16_SSHORT:

    case BI_STACK_INT:
    case BI_STACK_U:
    case BI_STACK_UINT:
        strtol(str , &pEnd , 10 );
        if ( pEnd == 0 ) return FAILURE;
        if ( *pEnd != '\0' ) {                   
            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                return FAILURE;
            if ( num > 4 ) return FAILURE;
            ui = (U16) ul;
        }
        else if ( node->typeIndex==BI_U16_UINT || 
//            node->typeIndex==BI_S16_USHORT ) {
            node->typeIndex==BI_S16_USHORT || 
            node->typeIndex==BI_STACK_U ||
            node->typeIndex==BI_STACK_UINT ) {
            ui=strtoul(str,&endPtr,0);//sscanf(str,"%u",&ui);
        }
        else {
            ui=strtoul(str,&endPtr,0);//sscanf(str,"%d",&ui);
        }
        pValue = (char *) &ui;      
        data[0] = pValue[0];
        data[1] = pValue[1];
//        data[0] = pValue[1];
//        data[1] = pValue[0];
        
        if ( node->flag1 ) {
            if ( GOOD == node->pExp->IsUserVariable() ) 
               return SetUserVarValue(
                   node->name.GetBuffer(node->name.GetLength()),(short)ui);
        }

#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuSetMemN(start,(U8*)data,2,&retAddr) ) {
            return GOOD;
//            return FAILURE;
        }
#endif  
        return GOOD;
    case BI_S32_SLONG:
    case BI_U32_ULONG:
    case BI_S32_LONG:
        strtol(str , &pEnd , 10 );
        if ( pEnd == 0 ) return FAILURE;
        if ( *pEnd != '\0' ) {                   
            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                return FAILURE;
            if ( num > 8 ) return FAILURE;
        }
        else if ( node->typeIndex==BI_U32_ULONG ) {
            ul=strtoul(str,&endPtr,0);//sscanf(str,"%luL",&ul);
        }
        else {
            ul=strtoul(str,&endPtr,0);//sscanf(str,"%ldL",&ul);
        }
        pValue = (char *) &ul;      
        data[0] = pValue[0];
        data[1] = pValue[1];
        data[2] = pValue[2];
        data[3] = pValue[3];
//        data[0] = pValue[3];
//        data[1] = pValue[2];
//        data[2] = pValue[1];
//        data[3] = pValue[0];
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuSetMemN(start,(U8*)data,4,&retAddr) ) {
//            return FAILURE;
            return GOOD;
        }
#endif  
        return GOOD;
    case BI_F32 :
        f=strtod(str,&endPtr);//sscanf( str , "%e" , &f );
        pValue = ( char * )&f;
        if ( GOOD == SrcIsStatement() || GOOD == SrcIsIEEE() ) {
            data[3] = pValue[0];
            data[2] = pValue[1];
            data[1] = pValue[2];
            data[0] = pValue[3];        
        }
        else {
            data[3] = pValue[3];
            data[2] = pValue[2];
            data[1] = pValue[1];
            data[0] = pValue[0];        
        }
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuSetMemN(start,(U8*)data,4,&retAddr) ) {
            return GOOD;
//            return FAILURE;
        }
#endif  
        return GOOD;
    case BI_F64 :    
        if ( GOOD == SrcIsStatement() || GOOD == SrcIsIEEE() ) {
            f=strtod(str,&endPtr);//sscanf( str , "%e" , &f );
            pValue = ( char * )&f;
            data[3] = pValue[0];
            data[2] = pValue[1];
            data[1] = pValue[2];
            data[0] = pValue[3];        
#ifdef _LINK_WITH_ABI_        
            if ( ICE_OK != emuSetMemN(start,(U8*)data,4,&retAddr) ) {
                return GOOD;
//                return FAILURE;
            }
#endif  
        }
        else {
            d=_strtold(str,&endPtr);//sscanf( str , "%le" , &d );
            pValue = ( char * )&d;
            data[0] = pValue[0];
            data[1] = pValue[1];
            data[2] = pValue[2];
            data[3] = pValue[3];        
            data[4] = pValue[4];
            data[5] = pValue[5];
            data[6] = pValue[6];
            data[7] = pValue[7];        
#ifdef _LINK_WITH_ABI_        
            if ( ICE_OK != emuSetMemN(start,(U8*)data,7,&retAddr) ) {
                return GOOD;
//                return FAILURE;
            }
#endif  
        }
        return GOOD;
    default :
        if ( *str == 39 ) {
            data[0] = str[1];
        }
        else {            
            strtol(str , &pEnd , 10 );
            if ( pEnd == 0 ) return FAILURE;
            if ( *pEnd != '\0' ) {                   
                if ( FAILURE == CheckIsHexValue(str,num,ul) )
                    return FAILURE;
                if ( num > 2 ) return FAILURE;
                ui = (U16) ul;
            }
            else ui=strtoul(str,&endPtr,0);//sscanf(str,"%d",&ui);
            pValue = (char *) &ui;      
            data[0] = pValue[0];
        }
        if ( ICE_OK != emuSetMemN(start,(U8*)data,1,&retAddr) ) {
            return GOOD;
        }
        return GOOD;
    }
    return GOOD;        
}

void VarServer::DeleteAllLocal(void)
{
    struct VarNode *temp;

    if ( varListHeader == 0 ) return ;
    temp = curVarNode = varListHeader;
    while( curVarNode ) {
        curVarNode = curVarNode->next;
        ClearNode( temp );
        delete temp;
        temp = curVarNode;
    }
    varListHeader = curVarNode = 0;
    return ;
}

void VarServer::VarMaxLine(int& nLine)
{
    struct VarNode *temp;

    nLine = 0;
    if ( varListHeader == 0 ) return ;
    temp = varListHeader;
    while( temp ) {
        nLine += temp->line ;
        temp = temp->next;
    }
    return ;
}

int VarServer::IsLegalValue(int nLine , CString str)
{
    struct VarNode *tt;
    char *ttt;
    
    if ( GOOD != VarLineToNode(nLine,tt) ) return FAILURE;
    ttt = str.GetBuffer(str.GetLength());
    if ( ttt == 0 ) return FAILURE;
    if (*ttt == '\0') return FAILURE;
    if ( tt == 0 ) return FAILURE;
    if ( tt->flag & VAR_COMPLEX ) return FAILURE;
    if ( GOOD != CheckValue( tt , ttt ) ) return FAILURE;

    return ( GOOD );
}

int VarServer::CheckValue(struct VarNode* node, char *str)
{   
    char temp[256];
    char *pEnd;
    TYPE_INDEX nextIndex;
    
    if ( GOOD != FindNextType(node->typeIndex,nextIndex) )
        return FAILURE;
    if ( node == 0 ) return FAILURE;
    if ( node->flag & VAR_COMPLEX ) return FAILURE;
/*
    if ( node->flag1 ) {
      int nFlag ;
      if ( GOOD != node->pExp->IsSymbol(nFlag) ) {
         return FAILURE;
      }
      if ( 0 == nFlag ) return FAILURE;
    }
*/    

    TYPE_HEADER_TYPE typeHeader;  
    typeHeader.typeName =new char[32];
    TYPE_BITFIELD_STRUCT bit;
    U32 ui,uj; 
    int nLen;                     
    ADDR start;
    if(nextIndex == BI_UNKNOWN)
    {
        if ( node->father )
        {
            struct VarNode *father;
            father = node->father;
            if (GOOD != SymGetTypeHeader(father->typeIndex, &typeHeader)) 
            {   delete typeHeader.typeName ;
                return FAILURE;             
            }    
            if ( typeHeader.t.complexType == TY_STRUCT||typeHeader.t.complexType == TY_UNION )
            {
                TYPE_S_U_STRUCT  s;
                ui = 0 ;
                struct VarNode *tt;
                tt = father->son;
                while( tt ) {
                    if ( tt == node ) break;
                    ui++;    
                    tt = tt->next;
                }
                if ( tt == 0 ) return FAILURE;
                s.name = temp ;
                if ( GOOD != SymGetTypeStructUnionNth( father->typeIndex,
                    ui , &s ) ) 
                {
                    delete typeHeader.typeName ;
                    return FAILURE;             
                }
                if(s.bBit)
                {
                    uj=s.offset>>3 ; 
                    start.addr = (U16)(father->result.addr + uj);    
                    bit.offset = s.offset%8;//(U8)( bit.offset + (U8)(s.offset%8) );                     
                    bit.size  = s.size;
                    nLen =1+((bit.offset+bit.size)>>3) ;
                    if(nLen <2)
                    {
                        strtol(str , &pEnd , 10 );
                        if ( pEnd == 0 ) return FAILURE;
                        if ( *pEnd != '\0' ) {                   
                            int num;
                            unsigned long ul;
                            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                                return FAILURE;
                            if ( num > 2 ) return FAILURE;
                        }
                        return GOOD;
                    }
                    else
                    {
                        if ( (bit.offset+bit.size)>16 ) return FAILURE;
                        strtol(str , &pEnd , 10 );
                        if ( pEnd == 0 ) return FAILURE;
                        if ( *pEnd != '\0' ) {                   
                            int num;
                            unsigned long ul;
                            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                                return FAILURE;
                            if ( num > 4 ) return FAILURE;
                        }   
                        delete typeHeader.typeName ;
                        return GOOD;
                       }
                }
            }
        } 
    }    
    
    
        
    if ( nextIndex >= 256 )
    {
        typeHeader.typeName = temp;
        if (GOOD != SymGetTypeHeader(nextIndex, &typeHeader)) 
            return FAILURE;
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
            return FAILURE;
//        if ( typeHeader.t.complexType != TY_BITFIELD ) 
//            return FAILURE;
        if ( typeHeader.t.complexType != TY_BITFIELD ) {
            if ( typeHeader.t.complexType != TY_ENUM_C )
                return FAILURE;                                
            BOOLEAN isNoMatch;   
            U32 ul;
            isNoMatch = TRUE;    
            if ( GOOD != SymGetTypeEnumValue(nextIndex,str,&ul,&isNoMatch) )
                return FAILURE;
            if ( isNoMatch == TRUE ) {
                strtol(str , &pEnd , 10 );
                if ( pEnd == 0 ) return FAILURE;
//                if ( *pEnd != '\0' ) return FAILURE;
                if ( *pEnd != '\0' ) {                   
                    int num;
                    unsigned long ul;
                    if ( FAILURE == CheckIsHexValue(str,num,ul) )
                        return FAILURE;
                    if ( num > 4 ) return FAILURE;
                }
            }                          
            delete typeHeader.typeName ;
            return GOOD;
        }    
    }
    switch ( nextIndex ) {
    case BI_BIT :
        strtol(str , &pEnd , 10 );
        if ( pEnd == 0 ) return FAILURE;
//        if ( *pEnd != '\0' ) return FAILURE;
        if ( *pEnd != '\0' ) {                   
            int num;
            unsigned long ul;
            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                return FAILURE;
            if ( num > 1 ) return FAILURE;
        }
           delete typeHeader.typeName ;
        return GOOD;
    case BI_S8_SCHAR:
    case BI_U8_UCHAR:
    case BI_S8_CHAR:
/*    
        if ( strlen( str ) != 1 ) return FAILURE;
        return GOOD;
*/        
        if (*str == 39) {
            if ( (str[2]==39)&&(str[3]==0) ) return GOOD;
            return FAILURE;
        }
        else {
            strtol(str , &pEnd , 10 );
            if ( pEnd == 0 ) return FAILURE;
//            if ( *pEnd != '\0' ) return FAILURE;
            if ( *pEnd != '\0' ) {                   
                int num;
                unsigned long ul;
                if ( FAILURE == CheckIsHexValue(str,num,ul) )
                    return FAILURE;
                if ( num > 2 ) return FAILURE;
            }
        }

        return GOOD;
    case BI_S16_SINT:
    case BI_U16_UINT:
    case BI_S16_SHORT:
    case BI_S16_USHORT:
    case BI_S16_SHORTINT:
    case BI_S16_SSHORT:

    case BI_STACK_INT:
    case BI_STACK_U:
    case BI_STACK_UINT:
        strtol(str , &pEnd , 10 );
        if ( pEnd == 0 ) return FAILURE;
//        if ( *pEnd != '\0' ) return FAILURE;
        if ( *pEnd != '\0' ) {                   
            int num;
            unsigned long ul;
            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                return FAILURE;
            if ( num > 4 ) return FAILURE;
        }

        return GOOD;
    case BI_S32_SLONG:
    case BI_U32_ULONG:
    case BI_S32_LONG:
        strtol(str , &pEnd , 10 );
        if ( pEnd == 0 ) return FAILURE;
//        if ( *pEnd != '\0' ) return FAILURE;
        if ( *pEnd != '\0' ) {                   
            int num;
            unsigned long ul;
            if ( FAILURE == CheckIsHexValue(str,num,ul) )
                return FAILURE;
            if ( num > 8 ) return FAILURE;
        }
        delete typeHeader.typeName ;
        return GOOD;
    case BI_F32 :
        strtod(str , &pEnd);
        if ( pEnd == 0 ) return FAILURE;
        if ( *pEnd != '\0' ) return FAILURE;
        delete typeHeader.typeName ;
        return GOOD;
    case BI_F64 :    
        strtod(str , &pEnd);
        if ( pEnd == 0 ) return FAILURE;
        if ( *pEnd != '\0' ) return FAILURE;

        return GOOD;
    default :
        if (*str == 39) {
            if ( (str[2]==39)&&(str[3]==0) ) return GOOD;
            return FAILURE;
        }
        else
        {
            strtol(str , &pEnd , 10 );
            if ( pEnd == 0 ) return FAILURE;
//            if ( *pEnd != '\0' ) return FAILURE;
            if ( *pEnd != '\0' )
            {                   
                int num;
                unsigned long ul;
                if ( FAILURE == CheckIsHexValue(str,num,ul) )
                    return FAILURE;
                if ( num > 2 ) return FAILURE;
            }
            
        }               
        delete typeHeader.typeName ;
        return GOOD;
    }//end of switch                   
    delete typeHeader.typeName ;
    return GOOD;        
}
             
             
int VarServer::UpdataOneNodeValue(struct VarNode *node)
{
    TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX       typeIndex;
    RETCODE          err;
    RET_ADDR retAddr;

    typeHeader.typeName = temp;
    typeIndex = node->typeIndex ;
//    if ( node->flag & VAR_NOVALID ) {
//        node->flag &= ~VAR_EXTEND;
//    }
    node->flag &= ~VAR_NOVALID;
//    if ( node->flag & VAR_ROOT ) {
    if ( (node->flag & VAR_ROOT)&&(0==node->flag1) ) {
        if ( FAILURE == SymbolDetailedType(node->desc,buff) ) {
            node->flag |= VAR_NOVALID ;
            ClearNode( node );
            UpdataLine( 1-node->line, node );
            return FAILURE;
        }
    }
    else {
        if ( FAILURE == BuildDetailedType(node->typeIndex,buff) ) {
            node->flag |= VAR_NOVALID ;
            ClearNode( node );
            UpdataLine( 1-node->line, node );
            return FAILURE;
        }
    }                   
    node->typeName = buff;
    
    if ( node->flag1 ) {                         
      int nResult;
      if ( GOOD == node->pExp->IsComplexResult(nResult) ) {
         if ( nResult == 0 ) {
            if ( GOOD != node->pExp->DisplayValue(buff) ){
                 node->flag |= VAR_NOVALID ;
                 ClearNode( node );
                 UpdataLine( 1-node->line, node );
                 return FAILURE;
             }
            node->value = buff;                    
            return GOOD;
         }
      }
      else {
           node->flag |= VAR_NOVALID ;
           ClearNode( node );
           UpdataLine( 1-node->line, node );
           return FAILURE;
       }
    }
    
    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) {
        node->flag |= VAR_NOVALID ;
        ClearNode( node );
        UpdataLine( 1-node->line, node );
        return FAILURE;
    }
    if ( 1/*!(node->flag & VAR_REG )*/ ) {
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
            if ( FAILURE == BuildSValue( node->typeIndex ,
               node->addr.segType,node->addr.addr , buff,
               node->nSize,node->nOffset) ) {
                node->flag |= VAR_NOVALID;
                ClearNode( node );
                UpdataLine( 1-node->line, node );
                return FAILURE;
            }
            node->value = buff;
        }
        else {
            if ( typeHeader.t.complexType == TY_TYPE ) {
                while( 1 ) {
                    TYPE_INDEX       typeNext;
                   
                    if ( GOOD != SymGetTypeTypeIndex(typeIndex,&typeNext) ) {
                        node->flag |= VAR_NOVALID ;
                        ClearNode( node );
                        UpdataLine( 1-node->line, node );
                        return FAILURE;
                    }
                    typeIndex = typeNext;
                    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))){
                        node->flag |= VAR_NOVALID ;
                        ClearNode( node );
                        UpdataLine( 1-node->line, node );
                        return FAILURE;
                    }
                    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
                        break;
                    else if ( typeHeader.t.complexType != TY_TYPE )
                        break;
                }   
                if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
                    if ( FAILURE == BuildSValue( typeIndex ,
                        node->addr.segType,node->addr.addr,buff,
                        node->nSize,node->nOffset) ) {
                        node->flag |= VAR_NOVALID;
                        ClearNode( node );
                        UpdataLine( 1-node->line, node );
                        return FAILURE;
                    }
                    node->value = buff;
                }
            }

            if ( (typeHeader.typeChoice==COMPLEX_TYPE_CLASS)&&
                (typeHeader.t.complexType == TY_BITFIELD) ) {
                if ( SrcIsIEEE() == GOOD ) {
                    if ( FAILURE == BuildIEEEBValue(node ,1, buff) ) {
                        node->flag |= VAR_NOVALID;
                        ClearNode( node );
                        UpdataLine( 1-node->line, node );
                        return FAILURE;
                    } 
                }
                else {
                    if ( FAILURE == BuildBValue( typeIndex ,
                        node->addr.segType,node->addr.addr,buff) ) {
                        node->flag |= VAR_NOVALID;
                        ClearNode( node );
                        UpdataLine( 1-node->line, node );
                        return FAILURE;
                    } 
                }
                node->value = buff;
            }
            else if ( (typeHeader.typeChoice==COMPLEX_TYPE_CLASS)&&
                (typeHeader.t.complexType == TY_ENUM_C) ) {
                if ( FAILURE == BuildEnumValue( typeIndex ,
                    node->addr.segType,node->addr.addr,1,buff) ) {
                    node->flag |= VAR_NOVALID;
                    ClearNode( node );
                    UpdataLine( 1-node->line, node );
                    return FAILURE;
                } 
                node->value = buff;
            }
            else if ( typeHeader.typeChoice == COMPLEX_TYPE_CLASS ) {
                node->flag |= VAR_COMPLEX;
                switch(typeHeader.t.complexType) {
                case TY_SMALL_PTR :  
				case TY_DPTR0 :
				case TY_DPTR1 :    
				case TY_DPTR2 :    
				case TY_DPTR3 :    
				case TY_DPTR4  :   
				case TY_DPTR5  :   
				case TY_DPTR6  :   
				case TY_DPTR7  :   
				case TY_CPTR0  :   
				case TY_CPTR1  :   
				case TY_CPTR2  :   
				case TY_CPTR3  :   
                    if ( typeHeader.sizeCalculated == TRUE ) {
                        ADDR    start , end;
                        char    data[16];
                        U32     address ;
                        SEGMENTTYPE segType;

                        address = 0;
                        ConvEnumToAbiType( node->addr.segType ,
                                     start.addrType );
                        end.addrType = start.addrType;
                        start.addr = node->addr.addr;
                        end.addr = start.addr + (typeHeader.sizeInMAUs-1);
#ifdef _LINK_WITH_ABI_
                        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
                            
//                            delete node;
                            node->flag |= VAR_NOVALID;
                            ClearNode( node );
                            UpdataLine( 1-node->line, node );
                            return FAILURE;
                        }
#endif
                        if ( typeHeader.sizeInMAUs == 3 ) {
                            address = (U8) data[1];
                            address = (address<<8) + (U8)data[2];
                            if ( GOOD == SrcIsStatement() ) {
                                UbrofConvPtrToSeg(data[0],segType);
                            }
                            else {
                                Omf51ConvPtrToSeg(data[0],segType);
                            }
                        }
                        else if ( typeHeader.sizeInMAUs == 2 ) {
                            segType = node->addr.segType;
                            //address = (U8) data[0];
                            //address = (address<<8) + (U8)data[1];
                            address =*((U16*)data);
                        }
                        else if ( typeHeader.sizeInMAUs == 1 ) {
                            segType = node->addr.segType;
                            address = (U8) data[0];
                        }
                        else {
                            delete node;
                            return FAILURE;
                        }
                        if ( FAILURE == BuildCAddr( segType , address,
                            buff) ) {
//                            delete node;
                            node->flag |= VAR_NOVALID;
                            ClearNode( node );
                            UpdataLine( 1-node->line, node );
                            return FAILURE;
                        }
                        node->result.segType = segType;
                        node->result.addr = address;
                        node->value = buff;
                    }
                    break;
                case TY_OMF51_PTR :
                    if ( typeHeader.sizeCalculated == TRUE ) {
                        ADDR    start , end;
                        char    data[16];
                        U32     address ;
                        SEGMENTTYPE segType;
                        SEGMENTTYPE ssss;
                        TYPE_OMF51_PTR_STRUCT omf51Ptr;

                        if ( SymGetTypePointer51(typeIndex,&omf51Ptr) != GOOD )
                            return FAILURE;
                        address = 0;
                        ConvEnumToAbiType( node->addr.segType ,
                                     start.addrType );
                        end.addrType = start.addrType;
                        start.addr = node->addr.addr;
                        end.addr = start.addr + (typeHeader.sizeInMAUs-1);
#ifdef _LINK_WITH_ABI_
                        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)data,&retAddr) ) {
                            node->flag |= VAR_NOVALID;
                            ClearNode( node );
                            UpdataLine( 1-node->line, node );
                            return FAILURE;
                        }
#endif
                        if ( typeHeader.sizeInMAUs == 3 ) {
                            address = (U8) data[1];
                            address = (address<<8) + (U8)data[2];
                            if ( GOOD == SrcIsStatement() ) {
                                UbrofConvPtrToSeg(data[0],segType);
                            }
                            else {
                                Omf51ConvPtrToSeg(data[0],segType);
                            }            
                            ssss = segType;
                        }
                        else if ( typeHeader.sizeInMAUs == 2 ) {
                            //address = (U8) data[0];
                            //address = (address<<8) + (U8)data[1];
                            address =*((U16*)data);
                            MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                            ssss = segType;
                            if ( SrcIsIEEE() == GOOD ) {
                                if ( (GOOD==SymGetTypeHeader(omf51Ptr.typeIndex, 
                                    &typeHeader)) &&(typeHeader.typeChoice==
                                    COMPLEX_TYPE_CLASS)&&
                                    (typeHeader.t.complexType == TY_TYPE) 
                                ) {                    
                                    TYPE_INDEX tttt;
                                    if ( GOOD != SymGetTypeTypeType(
                                        omf51Ptr.typeIndex,&tttt,&ssss) ){
                                        if ( ssss != SEG_UNTYPED ) 
                                            ssss = segType;
                                    }    
                                }    
                            }                              
                        }
                        else if ( typeHeader.sizeInMAUs == 1 ) {
                            address = (U8) data[0];
                            MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                            ssss = segType;
                            if ( SrcIsIEEE() == GOOD ) {
                                if ( (GOOD==SymGetTypeHeader(omf51Ptr.typeIndex, 
                                    &typeHeader)) &&(typeHeader.typeChoice==
                                    COMPLEX_TYPE_CLASS)&&
                                    (typeHeader.t.complexType == TY_TYPE) 
                                ) {                    
                                    TYPE_INDEX tttt;
                                    if ( GOOD != SymGetTypeTypeType(
                                        omf51Ptr.typeIndex,&tttt,&ssss) ) {
                                        if ( ssss != SEG_UNTYPED ) 
                                            ssss = segType;
                                    }    
                                }    
                            }                              
                        }
//                        if ( FAILURE == BuildCAddr( segType , address,
                        if ( FAILURE == BuildCAddr( ssss , address,
                            buff) ) {
                            node->flag |= VAR_NOVALID;
                            ClearNode( node );
                            UpdataLine( 1-node->line, node );
//                            delete node;
                            return FAILURE;
                        }
//                        node->result.segType = segType;
                        node->result.segType = ssss;
                        node->result.addr = address;
                        node->value = buff;
                    }
                    break;
                default :
                    if ( FAILURE == BuildCAddr( node->addr.segType ,
                            node->addr.addr ,buff ) ) {
//                         delete node;
                        node->flag |= VAR_NOVALID;
                        ClearNode( node );
                        UpdataLine( 1-node->line, node );
                        return FAILURE;
                    }
                    node->result.segType = node->addr.segType;
                    node->result.addr = node->addr.addr;
                    node->value = buff;
                }
            }
        }
    }
    else {
        sprintf( buff,"Register," );
        node->value = buff;
  
        node->typeName = buff;
    }
    return ( VarUpdataExtendedNode( node ) );
    
}

int VarServer::VarUpdataExtendedNode( struct VarNode* node )
{
    TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX       typeIndex , pTypeIndex;
    RETCODE          err;
    struct VarNode   *son , *brother ;
    TYPE_OMF51_PTR_STRUCT omf51Ptr;
    TYPE_S_U_STRUCT  s;
    U16              ui;
    TYPE_C_ARRAY_STRUCT arr;                       
    TYPE_OMF51_ARRAY_STRUCT omf51Arr;
    S32              *pMaxArr , *pCurArr;   
    S32              nArrSize , nCur;
    U32              uOneSize ;
    U32              uNowAddr;
        
    if ( node == 0 ) return FAILURE;
    if ( !(node->flag & VAR_COMPLEX) ) return FAILURE;
    if ( !(node->flag & VAR_EXTEND) ) return GOOD;
                                        
    typeIndex = node->typeIndex ;                                        
    typeHeader.typeName = temp;
    do {
        if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) {
            node->flag |= VAR_NOVALID ;
            return FAILURE;
        }
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) return FAILURE;
        if ( typeHeader.t.complexType == TY_TYPE ) {
            U32 typeNext;
            if ( GOOD != SymGetTypeTypeIndex(typeIndex,&typeNext) ) {
//                node->flag |= VAR_NOVALID ;
                return FAILURE;
            }
            typeIndex = typeNext;
        }    
    } while ( typeHeader.t.complexType == TY_TYPE );    
    switch(typeHeader.t.complexType) {
    case TY_SMALL_PTR :
    case TY_DPTR0 :
    case TY_DPTR1 :    
    case TY_DPTR2 :    
    case TY_DPTR3 :    
   case TY_DPTR4  :   
   case TY_DPTR5  :   
   case TY_DPTR6  :   
   case TY_DPTR7  :   
   case TY_CPTR0  :   
   case TY_CPTR1  :   
   case TY_CPTR2  :   
   case TY_CPTR3  :       
        if ( GOOD != ( err = SymGetTypePointerTypeIndex( typeIndex ,
                &pTypeIndex ) ) ) {
            node->flag |= VAR_NOVALID ;
            ClearNode( node );
            UpdataLine( 1-node->line, node );
            return FAILURE;
        }                 
        son = node->son;
        if ( son == 0 ) {
            return FAILURE ;
        }
        son->addr.addr = node->result.addr;
        son->addr.segType = node->result.segType;
        break;
    case TY_OMF51_PTR :
        if ( SymGetTypePointer51(typeIndex,&omf51Ptr) != GOOD ) {
            node->flag |= VAR_NOVALID ;
            ClearNode( node );
            UpdataLine( 1-node->line, node );
            return FAILURE;
        }
        son = node->son;
        if ( son == 0 ) {
            return FAILURE ;
        }
        son->addr.addr = node->result.addr;
        son->addr.segType = node->result.segType;
        break;                       
    case TY_STRUCT :
    case TY_UNION :  
        ui = 0 ;
        s.name = temp ;
        brother = node->son;
        while ( GOOD == SymGetTypeStructUnionNth( typeIndex , ui , &s ) ) {
            son = brother ;
            if ( son == 0 ) {
                return FAILURE ;
            }                   
            if(s.bBit)
            {
                son->addr.addr = node->result.addr + (s.offset>>3);    
            }
            else
            {
                son->addr.addr = node->result.addr + s.offset;
            }    
              son->addr.segType = node->result.segType;
              son->bBit =s.bBit;
              if(s.bBit)  son->nSize=s.size;
              else   son->nSize=0;
            brother = son->next;
/*
            if ( SrcIsIEEE() == GOOD ) {              
                TYPE_INDEX nextIndex;
                TYPE_HEADER_TYPE tpHeader;
                char ttt[256];
            
                if ( GOOD==FindNextType(s.typeIndex, nextIndex) ) {
                    tpHeader.typeName = ttt;  
                    if (GOOD == SymGetTypeHeader(nextIndex, &tpHeader) && 
                        tpHeader.typeChoice==COMPLEX_TYPE_CLASS &&
                        tpHeader.t.complexType == TY_BITFIELD ) {
                        son->addr.addr = node->result.addr + (s.offset>>3);
                    }
                }
            }
*/          ui++;
        }
        break;          
    case  TY_C_ARRAY :        
        if ( typeHeader.sizeCalculated == TRUE ) {
            uOneSize = typeHeader.sizeInMAUs;
        }
        else uOneSize = 0;      
        nArrSize = 0;
        do {
            if ( GOOD != SymGetTypeCArray(typeIndex,&arr) ) 
                return FAILURE ;
            typeIndex = arr.typeIndex ;
            nArrSize++;
            if (GOOD!=SymGetTypeHeader(typeIndex,&typeHeader)) 
                return FAILURE;
            if (typeHeader.typeChoice!=COMPLEX_TYPE_CLASS )
                break;
            if (typeHeader.t.complexType != TY_C_ARRAY )
                break;
        } while( TRUE );
        pMaxArr = new long [ nArrSize+1 ];
        pCurArr = new long [ nArrSize+1 ];
        if ( (pMaxArr==0) || (pCurArr==0) ) 
            return FAILURE ;
        memset( pCurArr , 0 , (size_t)((nArrSize+1)*sizeof(long)) );
        nCur = 0; 
        typeIndex = node->typeIndex;
        do {
            if ( GOOD != SymGetTypeCArray(typeIndex,&arr) ) 
                return FAILURE ;
            typeIndex = arr.typeIndex ;
            pMaxArr[nCur] = arr.highBound ; 
            nCur++;
            SymGetTypeHeader(typeIndex,&typeHeader); 
            if (typeHeader.typeChoice!=COMPLEX_TYPE_CLASS )
                break;
            if (typeHeader.t.complexType != TY_C_ARRAY )
                break;
        } while( TRUE );
        if ( nCur != nArrSize ) {
            delete pMaxArr;
            delete pCurArr;
            return FAILURE;
        }       
        nCur = 0;
        if ( typeHeader.sizeCalculated == TRUE ) {
            uOneSize = typeHeader.sizeInMAUs;
        }
        else if ( uOneSize ) {
            while( nCur < nArrSize ) {
                uOneSize = uOneSize / pMaxArr[nCur];
                nCur++;
            }
        }
        if ( uOneSize == 0 ) {      
            delete pMaxArr;
            delete pCurArr;
            return FAILURE;
        }                               
        uNowAddr = node->result.addr;
        ui = 0;
        brother = node->son;
        while ( pMaxArr[0] >= pCurArr[0] ) {
            int i;
        
            son = brother;
            if ( son == 0 ) {
                return FAILURE ;
            }
            son->addr.addr = uNowAddr;
            son->addr.segType = node->result.segType;
            brother = son->next;
            ui++;   
            uNowAddr += uOneSize;
            pCurArr[ nArrSize-1 ]++;
            for(i=(int)(nArrSize-1);i>=1;i--) {
                if( pCurArr[i]>pMaxArr[i] ) {
                    pCurArr[i] = 0;
                    pCurArr[i-1]++;
                }
            }
        }
        break;
                    
    case  TY_OMF51_ARRAY :        
        if ( typeHeader.sizeCalculated == TRUE ) {
            uOneSize = typeHeader.sizeInMAUs;
        }
        else uOneSize = 0;      
        if ( GOOD != SymGetTypeArray51(typeIndex,&omf51Arr) ) 
            return FAILURE ;
        nArrSize = omf51Arr.dim;
        pMaxArr = new long [ nArrSize+1 ];
        pCurArr = new long [ nArrSize+1 ];
        if ( (pMaxArr==0) || (pCurArr==0) ) 
            return FAILURE ;
        memset( pCurArr , 0 , (size_t)((nArrSize+1)*sizeof(long)) );
        nCur = 0; 
        typeIndex = node->typeIndex;
        for( nCur=0; nCur<nArrSize; nCur++) {                   
            U16 tt;
            if ( GOOD != SymGetTypeArrayDimSizeNth(typeIndex,
                                         (U8)(nCur+1), &tt) )
                return FAILURE;
            pMaxArr[nCur] = tt;
        }                                         
        typeIndex = omf51Arr.typeIndex ;    
        if ( GOOD != SymGetTypeHeader(typeIndex,&typeHeader) ) { 
            delete pMaxArr;
            delete pCurArr;
            return FAILURE;
        }       
        nCur = 0;
        if ( typeHeader.sizeCalculated == TRUE ) {
            uOneSize = typeHeader.sizeInMAUs;
        }
        else if ( uOneSize ) {
            while( nCur < nArrSize ) {
                uOneSize = uOneSize / pMaxArr[nCur];
                nCur++;
            }
        }
        if ( uOneSize == 0 ) {      
            delete pMaxArr;
            delete pCurArr;
            return FAILURE;
        }                               
        uNowAddr = node->result.addr;
        ui = 0;
        brother = node->son;
        while ( pMaxArr[0] >= pCurArr[0] ) {
            int i ;
        
            son = brother ;
            if ( son == 0 ) {
                return FAILURE ;
            }
            son->addr.addr = uNowAddr;
            son->addr.segType = node->result.segType;
            brother = son->next ;
            ui++;   
            uNowAddr += uOneSize;
            pCurArr[ nArrSize-1 ]++;
            for(i=(int)(nArrSize-1);i>=1;i--) {
                if( pCurArr[i]>pMaxArr[i] ) {
                    pCurArr[i] = 0;
                    pCurArr[i-1]++;
                }
            }
        }
        break;
                    
    default :
        return FAILURE;
    }

    return GOOD;
}

int VarServer::UpdataOneNode( struct VarNode *node )
{
//    struct VarNode *pNode , *pNode1;
    struct VarNode *pNode ;

    isUpdateGOOD = UpdataOneNodeValue( node ) ;

    pNode = node->son;

    while( pNode ) {
        UpdataOneNodeValue( pNode );
        if ( pNode->son ) {
            pNode = pNode->son;
            continue;
        }
        if ( pNode->next ) {
            pNode = pNode->next;
            continue;
        }
        while( pNode->next == 0 ) {
            pNode = pNode->father;
            if ( pNode == node ) break;
        }
        if ( pNode == node ) break;
        pNode = pNode->next;
    }
    return GOOD;
}

extern "C" int WINAPI SrcIsVariable(const char* command,int nLineNo) 
{
    BOOLEAN isGlobal ;
    SYM_DESCRIPTOR desc ;
    char *str;          
    class VarServer varObject1; 
                                
    isGlobal = (BOOLEAN) nLineNo;                                
    varObject1.buildStack();                           
    str = new char[ strlen(command)+1 ];
    if ( str == 0 ) return FAILURE;
    strcpy(str , command);
            
    if ( varObject1.IsValidVar(str,isGlobal,desc) != 0 ) return FAILURE;
    
    if ( str ) {
        delete str;
    }
    return GOOD;
}

int CheckIsHexValue(const char* command,int& num,unsigned long& ul)
{
    const char *str;
    unsigned char uc;
    
    str = command;
    num = 0;
    ul = 0L;
    while( *str == ' ' ) str++;
    if ( *str != '0' ) return FAILURE;
    str++;
    if ( *str != 'x' && *str != 'X' ) return FAILURE;
    str++;
//    while( *str == ' ' ) str++;
    if ( *str == '\0' ) return FAILURE;
    while( *str == '0' ) str++;
    if ( *str == '\0' ) {
        return GOOD;
    }
    while( *str ) {
        if ( *str >= '0' && *str <= '9' ) {
            uc = (unsigned char)( *str - '0' );
            ul <<= 4;
            ul += (unsigned long) uc;
        }
        else if ( *str >= 'a' && *str <= 'f' ) {
            uc = (unsigned char)( *str - 'a' + 10 );
            ul <<= 4;
            ul += (unsigned long) uc;
        }
        else if ( *str >= 'A' && *str <= 'F' ) {
            uc = (unsigned char)( *str - 'A' + 10 );
            ul <<= 4;
            ul += (unsigned long) uc;
        }
        else if ( *str == ' ' ) {
            while( *str == ' ' ) str++;
            if ( *str == '\0' ) return GOOD;
            else return FAILURE;
        }
        else return FAILURE;
        num++;
        str++;
    }
    
    return GOOD;
}

int VarServer::CheckVar(char *str,SYM_DESCRIPTOR &desc,
   TYPE_INDEX &typeIndex,BOOLEAN &isGlobal,ADDRESS_TYPE& addr)
{
//    SYM_DESCRIPTOR desc ;
//    struct VarNode *node;
    TYPE_HEADER_TYPE typeHeader;
//    RETCODE          err;
    VAR_STORAGE_CLASS   storageClass;
    VAR_REGISTER_CLASS  registerClass;
    BOOLEAN             isConstant;
    SYM_DESCRIPTOR      funcDescriptor;
    SYM_DESCRIPTOR      moduleDescriptor;
    SYM_DESCRIPTOR      parentDescriptor;
    GET_VAR_ADDR_STRUCT varAddr;
    char temp[256];

    buildStack();
    if ( IsValidVar(str,isGlobal,desc) != 0 ) return FAILURE;
    if ( GOOD != SymGetVar( desc,
                            temp,
                            &typeIndex,
                            &storageClass,
                            &registerClass,
                            &isConstant,
                            &funcDescriptor,
                            &moduleDescriptor,
                            &parentDescriptor,
                            &varAddr) ) {
        return FAILURE;
    }
//    if ( registerClass == NOT_REG ) {
        addr.segType = varAddr.fixedAddr.segType;
        addr.addr = varAddr.fixedAddr.startAddr;
//    }
//    else {
//        return FAILURE;
//    }
   return GOOD;
}               

int CheckIsValidVar(char *str,SYM_DESCRIPTOR &desc,
   TYPE_INDEX &typeIndex,BOOLEAN &isGlobal,ADDRESS_TYPE& addr)
{
   return varObject.CheckVar(str,desc,typeIndex,isGlobal,addr);
}     

extern "C" int WINAPI Var_IsValidVarAddr(struct VarNode* pVarNode)
{
   if ( 0 == pVarNode ) return FAILURE;
   if ( 1 == pVarNode->flag1 ) {
      int nFlag;
      if ( GOOD != pVarNode->pExp->IsSymbol(nFlag) ) {
         return FAILURE;
      }
      if ( nFlag ) {
         return (!pVarNode->pExp->IsUserVariable());
      }
      return FAILURE;
   }
   return GOOD;
}    

extern "C" int WINAPI  SrcGetTipValue(const char *str, SYM_DESCRIPTOR symSpecModule, int nLine, CString& strResult)
{
    if ( symSpecModule == 0 ) return FAILURE;
    if ( GOOD != varObject.AddVar( str , symSpecModule , nLine ) ) {
        U32 uStart, uEnd;        
        CString string;
        if ( *str != '#' ) {
        	string = "#";
        	string += str;
        }
        else {            
        	string = str;
        }
		if ( GOOD == SrcGetFuncRange((const char *)string, uStart, uEnd) ) {
			char ttt[100];
			BuildCAddr( SEG_CODE, uStart, ttt );
		    strResult = ttt;
		    strSpecResult = "";    
		    return GOOD;
		}
    	return FAILURE;
    }
    strResult = strSpecResult;
    strSpecResult = "";    
    return GOOD;
}



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