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

/****************************************************************************
**
**  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 "abibase.h"
#include "symblsvr.h"
#include "stkinit.h"
#include "mempool.h"
#include "symmgr.h"
#include "varinit.h"

            /***************************
            *                          *
            *        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 void ShowLine(char *);
extern STATUS AbiGetOneReg(int iRegId, UINT* uRegValue);
extern STATUS AbiSetMemN(ADDR addr, char* pchBuff, UINT uPatternLen);
extern STATUS AbiGetMemN(ADDR addr1, ADDR addr2,char* pchBuff);
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 );
extern void ConvEnumToAbiType( SEGMENTTYPE type , unsigned char& 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 BOOL GetCpuStatus(unsigned char & uchStatus);
            /***************************
            *                          *
            *        DEFINITIONS       *
            *                          *
            ***************************/

            /***************************
            *                          *
            *     LOCAL PROTOTYPES     *
            *                          *
            ***************************/
int CheckIsHexValue(const char* command,int& num,unsigned long& ul);

            /**************************
            *                         *
            *    PRIVATE VARIABLES    *
            *                         *
            **************************/

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

//////////////////////////////////////////////////////////////////////////
// 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;

    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=(unsigned short)varAddr.fixedAddr.startAddr;
                        end.addr = start.addr + 
                                   (unsigned short)(typeHeader.sizeInMAUs-1);
    #ifdef _ZLR_
                        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
                            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 = (unsigned short) varAddr.fixedAddr.startAddr;
                        end.addr = start.addr + 
                                   (unsigned short)(typeHeader.sizeInMAUs-1);
    #ifdef _ZLR_
                        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
                            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::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;
    }
    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 !";
        ShowLine( 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;
    ShowLine( 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::UpdataAllLocal()
{
    struct VarNode *node;
    
    unsigned char    uch;

	GetCpuStatus(uch);
	if ( uch ) {
        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];

    unsigned char    uch;

	GetCpuStatus(uch);
	if ( uch ) {
        return GOOD;
    }

    buildStack();            
    node = varListHeader ;
    while ( node ) {
        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 :
        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;

            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;
} 

/*
int VarServer::VarUpdataExtendedNode( 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;
                                        
    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;
    switch(typeHeader.t.complexType) {
    case TY_SMALL_PTR :
        if ( GOOD != ( err = SymGetTypePointerTypeIndex( typeIndex ,
                &pTypeIndex ) ) ) {
            node->flag |= VAR_NOVALID ;
            return FAILURE;
        }                 
//      son = new struct VarNode ;
        son = node->son;
        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 );
        
        break;
    case TY_OMF51_PTR :
        if ( SymGetTypePointer51(typeIndex,&omf51Ptr) != GOOD ) {
            node->flag |= VAR_NOVALID ;
            return FAILURE;
        }
//      son = new struct VarNode ;
        son = node->son;
        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 );
        break;                       
    case TY_STRUCT :
    case TY_UNION :  
        ui = 0 ;
        s.name = temp ;
//      brother = 0;
        brother = node->son;
        while ( GOOD == SymGetTypeStructUnionNth( typeIndex , ui , &s ) ) {
//          son = new struct VarNode ;
            son = brother ;
            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->father = node;
//          if ( ui == 0 ) {
//              node->son = son;
//          }  
//          if ( brother ) {
//              brother->next = son;
//          }
            brother = son->next;
//          son->prev = brother;
//          brother = son;
            UpdataOneNode( son );
            ui++;
        }
//      if ( ui ) node->flag |= VAR_EXTEND;
        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;
        brother = node->son;
        while ( pMaxArr[0] >= pCurArr[0] ) {
//          int i , j;
            int i;
        
//          son = new struct VarNode ;
            son = brother;
            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;
            brother = son->next;
            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;
        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;
        brother = node->son;
        while ( pMaxArr[0] >= pCurArr[0] ) {
//            int i , j;
            int i ;
        
//            son = new struct VarNode ;
            son = brother ;
            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;
            brother = son->next ;
            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;
}
*/

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;
    
    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;
    if ( tt->addr.segType == SEG_CODE ) 
        SrcUpdate();
    UpdataAllNode( );
    return ( GOOD );
}

int VarServer::SetValue(struct VarNode* node, char *str)
{   
    ADDR start , end;
    char data[16] ;
    char temp[256];
    char *pValue;    
    char *pEnd;
//    U8 uc;
    U16 ui , uj , uk;
    U32 ul;
    float f;
    int num;
    double d;
    TYPE_INDEX nextIndex;
    
    if ( node == 0 ) return FAILURE;
    if ( node->flag & VAR_COMPLEX ) return FAILURE;

    switch( node->addr.segType ) {
    case SEG_CODE :
        start.addrType = end.addrType = 1;
        break;
    case SEG_DATA :
        start.addrType = end.addrType = 3;
        break;
    case SEG_XDATA :
        start.addrType = end.addrType = 2;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 5;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 4;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = (unsigned short)node->addr.addr ;
    if ( GOOD != FindNextType(node->typeIndex,nextIndex) )
        return FAILURE;
    if ( nextIndex >= 256 ) {
//    if ( node->typeIndex >= 256 ) {
        int i;
        TYPE_HEADER_TYPE typeHeader;
        TYPE_BITFIELD_STRUCT bit;            
        
//        if ( GOOD != FindNextType(node->typeIndex,nextIndex) )
//            return FAILURE;
        typeHeader.typeName = temp;
//        if (GOOD != SymGetTypeHeader(node->typeIndex, &typeHeader)) 
        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 sscanf(str,"%u",&ui);
            }
            else {
                ui = (U16)ul;
            }  
            pValue = (char *) &ui;      
            data[0] = pValue[1];
            data[1] = pValue[0];
    #ifdef _ZLR_        
            if ( ICE_OK != AbiSetMemN(start,data,2) ) {
                return GOOD;
            }
    #endif  
            return GOOD;
        }    
        
//        if ( GOOD != SymGetTypeBitfield(node->typeIndex,&bit) )
        if ( GOOD != SymGetTypeBitfield(nextIndex,&bit) )
            return FAILURE;
            
//        addr = node->addr.addr;
        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 _ZLR_        
            if ( ICE_OK != AbiGetMemN(start,end,data) ) {
//                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 sscanf( str , "%d" , &uk);

            uk = uk&uj;
            ui = ui | ( uk << bit.offset ); 
            data[0] = ( char ) ui;
#ifdef _ZLR_        
            if ( ICE_OK != AbiSetMemN(start,data,1) ) {
//                return FAILURE;
                return GOOD;
            }
#endif  
            return GOOD;
        default :   
            if ( (bit.offset+bit.size)>16 ) return FAILURE;
            end.addr = start.addr+1;
#ifdef _ZLR_        
            if ( ICE_OK != AbiGetMemN(start,end,data) ) {
//                return FAILURE;
                return GOOD;
            }
#else 
            data[0] = 0;    
            data[1] = 0;
#endif  
//          ui = (U16) data[0];
//          ui = (ui<<8) + (U8)data[1];
            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 sscanf( str , "%d" , &uk);
            
            uk = uk&uj;
            ui = ui | ( uk << bit.offset ); 
            data[0] = ( char ) ( ui & 0xFF );
            data[1] = ( char ) ( ui >> 8 );
//            data[1] = ( char ) ( ui & 0xFF );
//            data[0] = ( char ) ( ui >> 8 );
#ifdef _ZLR_        
            if ( ICE_OK != AbiSetMemN(start,data,2) ) {
//                return FAILURE;
                return GOOD;
            }
#endif  
            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 sscanf( str , "%d" , &data[0]);

#ifdef _ZLR_        
        if ( ICE_OK != AbiSetMemN(start,data,1) ) {
            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 sscanf(str,"%d",&ui);
            
            pValue = (char *) &ui;      
            data[0] = pValue[0];
        }
        
#ifdef _ZLR_        
        if ( ICE_OK != AbiSetMemN(start,data,1) ) {
//            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 ) {
            sscanf(str,"%u",&ui);
        }
        else {
            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 _ZLR_        
        if ( ICE_OK != AbiSetMemN(start,data,2) ) {
            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 ) {
            sscanf(str,"%luL",&ul);
        }
        else {
            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 _ZLR_        
        if ( ICE_OK != AbiSetMemN(start,data,4) ) {
//            return FAILURE;
            return GOOD;
        }
#endif  
        return GOOD;
    case BI_F32 :
        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 _ZLR_        
        if ( ICE_OK != AbiSetMemN(start,data,4) ) {
            return GOOD;
//            return FAILURE;
        }
#endif  
        return GOOD;
    case BI_F64 :    
        if ( GOOD == SrcIsStatement() || GOOD == SrcIsIEEE() ) {
            sscanf( str , "%e" , &f );
            pValue = ( char * )&f;
            data[3] = pValue[0];
            data[2] = pValue[1];
            data[1] = pValue[2];
            data[0] = pValue[3];        
#ifdef _ZLR_        
            if ( ICE_OK != AbiSetMemN(start,data,4) ) {
                return GOOD;
//                return FAILURE;
            }
#endif  
        }
        else {
            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 _ZLR_        
            if ( ICE_OK != AbiSetMemN(start,data,7) ) {
                return GOOD;
//                return FAILURE;
            }
#endif  
        }
        return GOOD;
    default :
/*    
        sscanf( str , "%u" ,&ui );
        pValue = (char *) &ui;      
//        data[0] = pValue[0];
//        data[1] = pValue[1];
        data[0] = pValue[1];
        data[1] = pValue[0];
#ifdef _ZLR_        
        if ( ICE_OK != AbiSetMemN(start,data,2) ) {
            return GOOD;
//            return FAILURE;
        }
#endif  
*/
        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 sscanf(str,"%d",&ui);
            pValue = (char *) &ui;      
            data[0] = pValue[0];
        }
        
#ifdef _ZLR_        
        if ( ICE_OK != AbiSetMemN(start,data,1) ) {
//            return FAILURE;
            return GOOD;
        }
#endif  
        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;
    }
*/    

//    if ( node->typeIndex >= 256 ) {
    if ( nextIndex >= 256 ) {
//        int i;
        TYPE_HEADER_TYPE typeHeader;
        TYPE_BITFIELD_STRUCT bit;
        
//        if ( GOOD != FindNextType(node->typeIndex,nextIndex) )
//            return FAILURE;
        typeHeader.typeName = temp;
//        if (GOOD != SymGetTypeHeader(node->typeIndex, &typeHeader)) 
        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;
                }
            }
            return GOOD;
        }    
        
        if ( GOOD != SymGetTypeBitfield(nextIndex,&bit) )
//        if ( GOOD != SymGetTypeBitfield(node->typeIndex,&bit) )
            return FAILURE;
            
        switch ( bit.baseTypeIndex ) {
        case BI_S8_SCHAR:
        case BI_U8_UCHAR:
        case BI_S8_CHAR:  
            if ( (bit.offset+bit.size)>8 ) return FAILURE;
            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;
        default :   
            if ( (bit.offset+bit.size)>16 ) return FAILURE;
            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;
        }
    }
//    switch ( node->typeIndex ) {
    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;
        }

        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;
        }

        return GOOD;
    case BI_F32 :
        strtod(str , &pEnd);
        if ( pEnd == 0 ) return FAILURE;
        if ( *pEnd != '\0' ) return FAILURE;

        return GOOD;
    case BI_F64 :    
        strtod(str , &pEnd);
        if ( pEnd == 0 ) return FAILURE;
        if ( *pEnd != '\0' ) return FAILURE;

        return GOOD;
    default :
/*
        strtol(str , &pEnd , 10);
        if ( pEnd == 0 ) return FAILURE;
        if ( *pEnd != '\0' ) return FAILURE;
*/        
        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;
    }
    return GOOD;        
}

int VarServer::UpdataOneNodeValue(struct VarNode *node)
{
    TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX       typeIndex;
    RETCODE          err;

    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 ( !(node->flag & VAR_REG ) ) {
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
            if ( FAILURE == BuildSValue( node->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.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->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 :
                    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 = (unsigned short) node->addr.addr;
                        end.addr = start.addr + 
                                   (unsigned short)(typeHeader.sizeInMAUs-1);
#ifdef _ZLR_
                        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
                            
//                            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];
                        }
                        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 = (unsigned short) node->addr.addr;
                        end.addr = start.addr + 
                                   (unsigned short)(typeHeader.sizeInMAUs-1);
#ifdef _ZLR_
                        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
                            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];
                            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 :
        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 ;
            }
            son->addr.addr = node->result.addr + s.offset;
            son->addr.segType = node->result.segType;
            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;
}

int 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);
}     

int 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;
}
/******************************** E O F ***********************************/
