/****************************************************************************
**
**  Name:  TEXTGEN.C
**
**  Description:
**     Routines to generate text buffers for display by presenters.
**
**  Status:  TESTED
**
**  $Log:   S:/tbird/arcppc/varsrv/textgen.c_v  $
** 
**    Rev 1.4   31 Mar 1997 13:36:28   cjchen
** FT_void
** 
**    Rev 1.3   14 Mar 1997 13:35:00   cjchen
** 
**    Rev 1.2   05 Mar 1997 13:08:08   cjchen
** 
**    Rev 1.1   04 Mar 1997 09:58:22   cjchen
** 
**    Rev 1.0   17 Jan 1997 09:29:32   kevin
** Initial revision.
** 
**    Rev 1.0   03 Jun 1996 11:44:00   gene
** Initial revision.
** 
**    Rev 1.1   01 Dec 1995 10:02:40   kevin
** joyce's modification
** 
**    Rev 1.0   07 Sep 1995 11:24:50   gene
** Initial revision.
** 
**    Rev 1.51.1.0   27 May 1994 11:51:32   nghia
** Fixed PPR for PV 2.2b:
** - 9403: enum value sometimes displayed in lowercase letter for hex.
** - 9404, 9405, 9406 display built-in pointer types (Intermetrics toolchain).
** 
**    Rev 1.51   16 Nov 1993 10:11:48   nghia
** Fixed PPR 9087 : Locked Register variable without life-time information must
** be ALIVE when adding to Variable window.  Added check for lifetimeState for
** Locked register variables.
** 
**    Rev 1.50   01 Nov 1993 10:08:18   nghia
** Fixed PPR 8962 - Variable server handles SMALL/LARGE pointer types
** Revised getPointerValue() to receive a size parameter to process pointer.
** Revised ConvTextAndWriteMem() to treat SMALL/LARGE pointer differently.
** Revised all textGen for SMALL/LARGE pointer types using typeInfo->size.
** Default edit field for pointer types is 4 for SMALL and 8 for LARGE type.
** 
**    Rev 1.49   30 Sep 1993 15:10:24   nghia
** Revised GetEditValueToBuffer() to format DEAD register value as text.
** Added HandleViewOnlyValue() to do formatting.
** 
**    Rev 1.48   28 Jul 1993 14:22:14   marilyn
** Removed extraneous endofLine in HandleNoValueString.
** 
**    Rev 1.47   27 Jul 1993 21:20:42   marilyn
** When a variable is living reg but is dead it now displays "no value"
** instead of "unknown". 
** 
**    Rev 1.46   16 Jul 1993 10:16:54   ernie
** Changed abortFromEsc from U16 to BOOLEAN
** 
**    Rev 1.45   25 Jun 1993 17:56:12   paul
** Change CHECK_ABORT to TskCheckAbort
** 
**    Rev 1.44   16 Jun 1993 10:13:40   mindy
** Fixed floating point switching bug
** 
**    Rev 1.43   15 Jun 1993 11:46:28   mindy
** 
**    Rev 1.42   25 May 1993 13:38:38   ernie
** Updated for new MemReadSized() interface
** 
**    Rev 1.41   12 May 1993 16:25:06   ron
** variable window enhancements: allow decimal editing and check for
** integer overflow.
** 
**    Rev 1.40   16 Mar 1993 14:56:28   courtney
** Added support for long double.
** 
**    Rev 1.39   08 Mar 1993 15:38:30   courtney
** Modified floatOps[] legal characters to handle all floating point
** suffixes, plus scientific notation.
** Handle 32-bit float edit.
** Handle 64-bit double edit.
** 
**    Rev 1.38   26 Feb 1993 16:21:50   courtney
** Added support for display of floating point types (float, double), which
** takes into account target/host byte order differences.  Size of buffer for
** these types was increased (previously, only hex displayed).
** 
**    Rev 1.37   11 Jan 1993 15:56:42   marilyn
** Added check_abort to array routines.
** 
**    Rev 1.36   15 Dec 1992 12:59:28   ernie
** Changed from MemXXXX calls to new MemXXXXSized calls
** 
**    Rev 1.35   07 Dec 1992 16:36:56   marilyn
** Fixed problem where locked registers could be a regRead or maybe not but
** pointers were assuming that anything NOT_REG  required endian switching
** but LOCKED_REGs could be stack reads and would require endian switching too.
** 
**    Rev 1.34   04 Dec 1992 10:00:28   marilyn
** Fixed problems with display of arrays of enums.
** 
**    Rev 1.33   02 Dec 1992 15:57:30   doug
** free memory if MemRead fails
** 
**    Rev 1.32   02 Dec 1992 13:49:14   marilyn
** Updated error messages, changed formats to use %X to match cpu and
** memory servers, updated some return code interfaces, doubles in registers
** are not anotated, changed interface for updating child vars.
** 
**    Rev 1.31   11 Nov 1992 11:56:10   marilyn
** Fixed bug with very large array indices.
** 
**    Rev 1.30   06 Nov 1992 16:18:20   marilyn
** Fixed void ptrs having no name.
** 
**    Rev 1.29   04 Nov 1992 17:42:28   marilyn
** Fixed pprs 7170,7183,7184,7198,7204,7305,7344,7345,7378,7435.
** 
**    Rev 1.28   24 Oct 1992 10:43:32   marilyn
** Fixed beta bugs.
** 
**    Rev 1.27   22 Oct 1992 21:28:48   marilyn
** Fixed enum editting bug.
** 
**    Rev 1.26   21 Oct 1992 16:11:38   marilyn
** Fixed several bugs on format for beta release.
**
**    Rev 1.25   15 Oct 1992 17:52:32   marilyn
** Fixed several bugs for beta.
**
**    Rev 1.24   09 Oct 1992 10:38:10   marilyn
** Removed define for debugging memory leaks.
** 
**    Rev 1.23   09 Oct 1992 10:29:52   marilyn
** Fixed memory leaks.
** 
**    Rev 1.22   10 Sep 1992 15:25:06   marilyn
** Changed GetCharValue to use unsigned variables and the TypeTable so
** that unsigned types use the format %u.
** 
**    Rev 1.21   27 Aug 1992 10:35:46   marilyn
** Changes to eliminate compiler warnings.
** 
**    Rev 1.20   04 Aug 1992 16:47:46   marilyn
** Added printing of enum names and editting enum values.  Void pts
** are no longer selectable.  Child vars of dereferenced pts are now
** updated with editting of the parent ptr.
**
**    Rev 1.19   31 Jul 1992 16:48:52   marilyn
** Fixed bug in editting ptrs.
** 
**    Rev 1.18   25 Jun 1992 09:08:14   marilyn
** Updates for BC 3.0.
** 
**    Rev 1.17   28 May 1992 16:33:02   marilyn
** Added frameNum parameter where appropriate.
** 
**    Rev 1.16   19 May 1992 17:13:20   marilyn
** Fixed problem of editting arrays of ptrs to different types.
** 
**    Rev 1.15   13 May 1992 11:19:40   marilyn
** Added indexing for arrays and selectable array indices.
** 
**    Rev 1.14   09 May 1992 11:58:08   marilyn
** fixed UAE on selecting floats and doubles.
** 
**    Rev 1.13   06 May 1992 11:14:30   marilyn
** Minor changes to fix bugs for bitfield support.
** 
**    Rev 1.12   04 May 1992 17:10:14   marilyn
** Added additional support for bitfield types.
** 
**    Rev 1.11   29 Apr 1992 15:30:10   marilyn
** fixes bugs for displaying arrays of function ptrs.
** 
**    Rev 1.10   24 Apr 1992 16:50:36   marilyn
** Fixed bugs related to typedef variables.
**
**    Rev 1.9   17 Apr 1992 16:16:48   marilyn
** Fixed bug preventing function name from showing and removed temp
** code from GetVarName.  Also fixed bug in MakeCompositeVarName.
** 
**    Rev 1.8   15 Apr 1992 10:18:06   marilyn
** Fixed bug in editvalue routines for handling a buffer with no editable
** value when the request is from the CLI.
**
**    Rev 1.7   06 Apr 1992 11:15:58   marilyn
** Fixed bugs for generating component type variables.
** 
**    Rev 1.6   03 Apr 1992 08:53:28   marilyn
** Fixed bugs dealing with multi-dimensional array types.
**
**    Rev 1.5   30 Mar 1992 16:51:36   marilyn
** Fixed numerous bugs for editting values of variables.
**
**    Rev 1.4   23 Mar 1992 08:59:36   marilyn
** Updated interfaces to stack server, cpu server, and mem server.
**
**    Rev 1.3   28 Feb 1992 10:57:46   marilyn
** Updated to new interfaces for memory and cpu servers.
**
**    Rev 1.2   27 Jan 1992 13:44:20   marilyn
** Bug fixes to routines handling editting of values.
** 
**    Rev 1.1   23 Jan 1992 17:42:00   marilyn
** No change.
**
**    Rev 1.0   17 Jan 1992 08:04:32   marilyn
** Initial revision.
**
**  $Header:   S:/tbird/arcppc/varsrv/textgen.c_v   1.4   31 Mar 1997 13:36:28   cjchen  $
**
**  Copyright (C) 1991-3 Microtek International.  All rights reserved.
**
*****************************************************************************/


                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#ifndef _ANOTEXT_
#include "anotext.h"
#endif

#ifndef _BASEWIND_
#include "basewind.h"
#endif

#ifndef _ADDR_
#include "addr.h"
#endif

#ifndef _PVTASK_
#include "pvtask.h"
#endif

#ifndef _SYMBLSVR_
#include "symblsvr.h"
#endif

#ifndef _TBIRDMEM_
#include "tbirdmem.h"
#endif

#ifndef _TEXTGEN_
#include "textgen.h"
#endif

#ifndef _VARTABLE_
#include "vartable.h"
#endif

#ifndef _VARSERVR_
#include "varservr.h"
#endif

#ifndef _VARERRS_
#include "varerrs.h"
#endif

#ifndef _VARUTIL_
#include "varutil.h"
#endif

#ifndef _VARIEEE_
#include "varieee.h"
#endif

#ifndef _STKSERVR_
#include "stkservr.h"
#endif

#ifndef _LDRSVR_
#include "ldrsvr.h"
#endif

#ifndef _HEAP_
#include "heap.h"
#endif

#ifndef _VARENDIA_
#include "varendia.h"
#endif

#ifndef __MEM_H
#include <mem.h>
#endif

#ifndef __STRING_H
#include <string.h>
#endif

#ifndef __CTYPE_H
#include <ctype.h>
#endif

#ifndef __STDLIB_H
#include <stdlib.h>
#endif
                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ***************************/


const char eolnString[] = "\r\n";
const char nameContStr[] = "...";
const char endOfBuffer[] = "\0";
const char blankChar[] = " ";
const char singleQuote[] = "\'";
const char doubleQuote[] = "\"";
const char semicolon[] = ";";
const char colon[] = ":";
const char commaChar[] = ",";
const char equalChar[] = "=";
const char equalString[] = " = ";
const char structString[] = "struct ";
const char classString[] = "class ";
const char unionString[] = "union ";
const char enumString[] = "enum ";
const char leftBracketChar[] = "[";
const char rightBracketChar[] = "]";
const char pointerChar[] = "*";
const char leftCurlyChar[] = "{";
const char rightCurlyChar[] = "}";
const char complexStuff[] = "{...};";
const char unknownVar[] = ": unknown";
const char noValueVar[] = "no value";
const char nonPrintableChar[] = "???";
const char contextDelimiter[] = "#";

const char lowerCase[] = "abcdefghijklmnopqrstuvwxyz";
const char upperCase[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char digits[] = "0123456789";
const char operators[] = " !\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~";
const char whiteSpace[] = " \n\t";
const char octalOp[] = "o";
const char hexOp[] = "0x";
const char floatOps[] = ".eEfFlL";
const char hexDigits[] = "abcdefABCDEF";
const char signedOps[] = "-+";
const char unsignedOps[] = "+";
const char pointerOps[] = ":";

/* Handle editing pointer size for LARGE/SMALL pointer */
#define EDIT_LARGE_PTR_DEFAULT  8
#define EDIT_SMALL_PTR_DEFAULT  8//Hera 2/17/98

#define ZERO_BUFFER  0
#define SPACES_PER_INDENT 3

#define VS_MAX_TYPE_TABLE 70
#define VS_POINTER_TYPES 32
#define VS_MAX_BUF 16
#define VS_MAX_STRING 256
#define VS_MAX_DISPLAYED_NAME 80

#define MAX_BF_BYTE_TABLE 8
#define MAX_BF_WORD_TABLE 16
#define MAX_BF_LONG_TABLE 32

#define DEFAULT_INT 6

#define VAR_NAME_MARKER  (specialChar|AT_BEGIN_TAG|AT_VAR_NAME_FIELD)
#define REF_FIELD_MARKER (specialChar|AT_BEGIN_TAG|AT_REFERENCE_FIELD)
#define EDIT_FIELD_MARK  (specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD)
#define END_EDIT_MARK    (specialChar|AT_END_TAG|AT_EDIT_FIELD)

#define MAX_DIGIT_READ_SIZE 8
#define HEX_DIGITS_PER_BYTE 2

#define MAX_U16_VAL "65535"
#define MAX_S16_VAL "32767"
#define MIN_S16_VAL "32768"
#define MAX_U32_VAL "4294967296"
#define MAX_S32_VAL "2147483647"
#define MIN_S32_VAL "2147483648"

/*
** #define DEBUG_MEM_LEAKS 1
*/
extern U32 memAlloced;
extern U32 memFreed;

VS_WARNING_TYPE warningMessages[MAX_WARNING_MESS] = {
   "\0",
   "*** WARNING *** Address Server Access Error ***\0",
   "*** WARNING *** Symbol Server Access Error ***\0",
   "*** WARNING *** Stack Server Access Error ***\0",
   "*** WARNING *** Variable Server Internal Error ***\0",
   "*** WARNING *** System Error ***\0",
   "*** WARNING *** Memory Server Access Error ***\0",
   "*** WARNING *** Cpu Server Access Error ***\0"
};

typedef enum {
   DF_NODISP    = NULL,
   DF_BINARY    = 0x02,
   DF_OCTAL     = 0x08,
   DF_DECIMAL   = 0x0A,
   DF_HEX       = 0x10,
   DF_ASCII     = 0xF0,
   DF_FLOAT     = 0xF1,
   DF_DOUBLE    = 0xF2,
   DF_LDOUBLE   = 0xF3
} DISPLAY_FORMAT;

typedef struct {
   U16            primaryEditFieldSize;
   DISPLAY_FORMAT primaryRadix;
   BOOLEAN        primaryEdit;
   U8             primaryFormatStr[10];
   U16            secondaryEditFieldSize;
   DISPLAY_FORMAT secondaryRadix;
   BOOLEAN        secondaryEdit;
   U8             secondaryFormatStr[10];
} TYPE_TABLE_ENTRY;

typedef struct {
   union utag {
      U32 longMask;
      U16 wordMask;
      U8 byteMask;
   }mask;
   S32 shiftFactor;
} BF_TABLE_TYPE;

typedef enum {
   STACK_WRITE,
   MEM_WRITE,
   REG_WRITE
} WRITE_DESTINATION_TYPE;


typedef enum {         /* see stkcli.h */
   HI_TO_LOW,
   LOW_TO_HI
} STACK_TYPE;

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/

extern VS_VAR_TABLE_TYPE  varTable;

                       /****************************
                        *                          *
                        *     LOCAL STORAGE        *
                        *                          *
                        ****************************/

VS_STRING_TYPE charSetBuf;

static U8 specialChar = AT_SPECIAL_MARK;
static DESCRIPTOR varIndex;
static U32 maxLinesForBuf;
static U32 startLineForBuf;
static DESCRIPTOR textBufferNum;
static U8 varFrameNum;
static U32 lineCount;
static BOOLEAN bufferFull;
static BOOLEAN noNewLines;
static BOOLEAN anotatedText;
static BOOLEAN stackSex;
static STRING textStartPtr;
static VAR_STORAGE_CLASS varStorageClass;
static VAR_REGISTER_CLASS varRegisterClass;
static GET_VAR_ADDR_STRUCT *elementAddr;
CHAR regValueStr[VS_MAX_STRING];
//wb
U16 toolch;
//we
/* The index into this table is by the built-in types, as defined
   by the BI_* entries in symblsvr.h.  */
TYPE_TABLE_ENTRY typeTable[VS_MAX_TYPE_TABLE] = {
{0,DF_HEX,FALSE,"%X\0",0,DF_HEX,FALSE,"%X\0"},             /* 00 */
{2,DF_HEX,TRUE,"%X\0",1,DF_ASCII,TRUE,"%c\0"},             /* BI_char */
{2,DF_HEX,TRUE,"%X\0",1,DF_ASCII,TRUE,"%c\0"},             /* BI_signed_char */
{2,DF_HEX,TRUE,"%X\0",1,DF_ASCII,TRUE,"%c\0"},             /* BI_unsigned_char */
{4,DF_HEX,TRUE,"%X\0",6,DF_DECIMAL,TRUE,"%d\0"},           /* BI_short */
{4,DF_HEX,TRUE,"%X\0",6,DF_DECIMAL,TRUE,"%d\0"},           /* BI_signed_short */
{4,DF_HEX,TRUE,"%X\0",5,DF_DECIMAL,TRUE,"%u\0"},           /* BI_unsigned_short */
{8,DF_HEX,TRUE,"%lX\0",11,DF_DECIMAL,TRUE,"%ld\0"},          /* BI_integer*/
{8,DF_HEX,TRUE,"%lX\0",11,DF_DECIMAL, TRUE,"%ld\0"},         /* BI_signed_int */
{8,DF_HEX,TRUE,"%lX\0",10,DF_DECIMAL, TRUE,"%lu\0"},         /* BI_unsigned_int */
{8,DF_HEX,TRUE,"%lX\0",11,DF_DECIMAL,TRUE,"%ld\0"},        /* BI_long */
{8,DF_HEX,TRUE,"%lX\0",11,DF_DECIMAL,TRUE,"%ld\0"},        /* BI_signed_long */
{8,DF_HEX,TRUE,"%08lX\0",10,DF_DECIMAL,TRUE,"%lu\0"},     /* BI_unsigned_long */
{0,0,0,"\0",0,0,0,"\0"},                                   /* BI_pointer*/
{F_DISPLAY_DIG,DF_FLOAT,TRUE,"%g\0",0,DF_NODISP,FALSE,"\0"},/* BI_float*/
{D_DISPLAY_DIG,DF_DOUBLE,TRUE,"%lg\0",0,DF_NODISP,FALSE,"\0"}, /*BI_dbl_prec_float*/
{D_DISPLAY_DIG,DF_DOUBLE,TRUE,"%lg\0",0,DF_NODISP,FALSE,"\0"}, /* BI_ext_prec_float */
{0,0,0,"\0",0,0,0,"\0"}, /*BI_complex*/
{0,0,0,"\0",0,0,0,"\0"}, /*BI_dbl_prec_complex*/
{0,0,0,"\0",0,0,0,"\0"}, /*noused*/
{0,DF_HEX,FALSE,"%X\0",0,DF_HEX,FALSE,"%X\0"},             /* BI_void */
{0,0,0,"\0",0,0,0,"\0"}, /*BI_boolean*/
{0,0,0,"\0",0,0,0,"\0"}, /*BI_ext_prec_complex*/
{0,0,0,"\0",0,0,0,"\0"}, /*BI_label*/
/*pointer to*/
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 1*/
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 2 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 3 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 4 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 5 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 6 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 7 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 8 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 9 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 10 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 11 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 12 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 13 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 14 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 15 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 16 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 17 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 18 */
{0,DF_HEX,TRUE,"\0",0,DF_NODISP,FALSE,"\0"},               /* 19 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 20 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 21 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 22 */
{8,DF_HEX,TRUE,"%lX\0",0,DF_NODISP,FALSE,"\0"},            /* 23 */
/*referece to*/
{0,0,0,"\0",0,0,0,"\0"}, 
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
{0,0,0,"\0",0,0,0,"\0"},
}; /* End of typeTable */

BF_TABLE_TYPE bfByteTable[MAX_BF_BYTE_TABLE] = {
{0xff,0x8},{0x7f,0x7},{0x3f,0x6},{0x1f,0x5},
{0x0f,0x4},{0x07,0x3},{0x03,0x2},{0x01,0x1}};

BF_TABLE_TYPE bfWordTable[MAX_BF_WORD_TABLE] = {
{0xffff,0x10},{0x7fff,0x0f},{0x3fff,0x0e},{0x1fff,0x0d},
{0x0fff,0x0c},{0x07ff,0x0b},{0x03ff,0x0a},{0x01ff,0x09},
{0x00ff,0x08},{0x007f,0x07},{0x003f,0x06},{0x001f,0x05},
{0x000f,0x04},{0x0007,0x03},{0x0003,0x02},{0x0001,0x01}};

BF_TABLE_TYPE bfLongTable[MAX_BF_LONG_TABLE] = {
{0xffffffffL,0x20L},{0x7fffffffL,0x1fL},{0x3fffffffL,0x1eL},{0x1fffffffL,0x1dL},
{0x0fffffffL,0x1cL},{0x07ffffffL,0x1bL},{0x03ffffffL,0x1aL},{0x01ffffffL,0x19L},
{0x00ffffffL,0x18L},{0x007fffffL,0x17L},{0x003fffffL,0x16L},{0x001fffffL,0x15L},
{0x000fffffL,0x14L},{0x0007ffffL,0x13L},{0x0003ffffL,0x12L},{0x0001ffffL,0x11L},
{0x0000ffffL,0x10L},{0x00007fffL,0x0fL},{0x00003fffL,0x0eL},{0x00001fffL,0x0dL},
{0x00000fffL,0x0cL},{0x000007ffL,0x0bL},{0x000003ffL,0x0aL},{0x000001ffL,0x09L},
{0x000000ffL,0x08L},{0x0000007fL,0x07L},{0x0000003fL,0x06L},{0x0000001fL,0x05L},
{0x0000000fL,0x04L},{0x00000007L,0x03L},{0x00000003L,0x02L},{0x00000001L,0x01L}};


                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

RETCODE PRIVATE GetFormattedSimpleType(TYPE_SUBHEADER_TYPE *typeInfo,
                                       TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                       LPSTR varname,
                                       GET_VAR_ADDR_STRUCT *addr,
                                       U8 indents,
                                       STRING *textPtr);

RETCODE PRIVATE GetFormattedStructOrUnionType(VS_COMPONENT_TYPE *component,
                                      TYPE_SUBHEADER_TYPE *typeInfo,
                                      TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                      GET_VAR_ADDR_STRUCT *addr,
                                      LPSTR varName,
                                      U8 indents,
                                      STRING *textptr);

RETCODE PRIVATE GetFormattedClassType(VS_COMPONENT_TYPE *component,
                                      TYPE_SUBHEADER_TYPE *typeInfo,
                                      TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                      GET_VAR_ADDR_STRUCT *addr,
                                      LPSTR varName,
                                      U8 indents,
                                      STRING *textptr);

RETCODE PRIVATE GetFormattedPointerType(TYPE_SUBHEADER_TYPE *typeInfo,
                                        TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                        LPSTR varName,
                                        GET_VAR_ADDR_STRUCT *addr,
                                        U8 indents,
                                        STRING *textPtr);

RETCODE PRIVATE GetFormattedArrayTypeForStruct(TYPE_SUBHEADER_TYPE *typeInfo,
                                     TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                     LPSTR varName,
                                     U8 indents,
                                     STRING *textPtr);

RETCODE PRIVATE GetFormattedArrayType(TYPE_SUBHEADER_TYPE *typeInfo,
                                      TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                      GET_VAR_ADDR_STRUCT *address,
                                      VS_COMPONENT_TYPE *component,
                                      LPSTR varName,
                                      U8 indents,
                                      STRING *textPtr);

RETCODE PRIVATE GetFormattedEnumType(TYPE_SUBHEADER_TYPE *typeInfo,
                                     TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                     LPSTR varName,
                                     GET_VAR_ADDR_STRUCT *addr,
                                     U8 indents,
                                     STRING *textPtr);

RETCODE PRIVATE GetFormattedBitfieldType(TYPE_SUBHEADER_TYPE *typeInfo,
                                     TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                     LPSTR varName,
                                     GET_VAR_ADDR_STRUCT *addr,
                                     U8 indents,
                                     U16 bitOffset,
                                     STRING *textPtr);

RETCODE PRIVATE GetFormattedUnknownType(TYPE_SUBHEADER_TYPE *typeInfo,
                                    TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                    LPSTR varName,
                                    GET_VAR_ADDR_STRUCT *addr,
                                    U8 indents,
                                    STRING *textPtr);

RETCODE PRIVATE GetWarningMessage(STRING *textPtr,
                               RETCODE errCode,
                               U8 indents);

RETCODE PRIVATE GetAlternateMemAccess(STRING *textPtr,
                                   RETCODE error);

VOID PRIVATE GetNthComponent(DESCRIPTOR varId,
                             DESCRIPTOR bufferNum,
                             U32 lineNum,
                             VS_COMPONENT_TYPE **compPtr);


BOOLEAN PRIVATE GetNewLine(STRING *textPtr,
                           U8 indents);

VOID PRIVATE GetArrayIndices(STRING *textPtr,
                             S32 index,
                             S32 fieldMarkTag);

BOOLEAN PRIVATE GetTypeName(STRING *textPtr,
                            LPSTR typeName,
			    U32 indirectionLevels);

BOOLEAN PRIVATE GetTypeNameRef(STRING *textPtr,
                            LPSTR typeName,
			    U32 indirectionLevels); //Hera 2/27/98

RETCODE PRIVATE GetVarName(STRING *textPtr,
                        LPSTR varName,
                        U8 expandableReference,
                        U8 indents);

VOID PRIVATE GetBlankSpace(STRING *textPtr);

VOID PRIVATE GetEndOfLine(STRING *textPtr);

RETCODE PRIVATE GetEditValueToBuffer(TYPE_SUBHEADER_TYPE *typeInfo,
                                     GET_VAR_ADDR_STRUCT *addr,
                                     STRING *textPtr,
                                     LPU8 *buffer,
                                     BOOLEAN *alternateAccess);

RETCODE PRIVATE GetEditValue(STRING *textPtr,
                          GET_VAR_ADDR_STRUCT *addr,
                          TYPE_SUBHEADER_TYPE *typeInfo);

RETCODE PRIVATE GetBitfieldEditValue(STRING *textPtr,
                                     GET_VAR_ADDR_STRUCT *addr,
                                     TYPE_SUBHEADER_TYPE *typeInfo,
                                     U16 bitOffset);

VOID PRIVATE GetPointerTypeInfo(TYPE_SUBHEADER_TYPE *typeHeader,
                                TYPE_SUBHEADER_TYPE **typeInfo,
                                U8 *indirectionLevels);

VOID PRIVATE GetArrayTypeInfo(TYPE_SUBHEADER_TYPE *typeHeader,
                              TYPE_SUBHEADER_TYPE **typeInfo,
                              U8 *ptrIndirectionLevels,
                              U8 *arrayIndirectionLevels);

VOID PRIVATE HandleUnknownString(STRING *textPtr);

VOID PRIVATE HandleNoValueString(STRING *textPtr);

VOID PRIVATE HandleViewOnlyValue(STRING *textPtr, U32 regValue);

VOID PRIVATE CheckStructOrUnionOrEnum(STRING *textPtr,
                                      TYPE_SUBHEADER_TYPE *typeHeader);

BOOLEAN PRIVATE ActiveVar(STRING *textPtr);


VOID PRIVATE Get16IntValue(STRING *textPtr,
                         LPU8 buffer,
                         DISPLAY_FORMAT dispValueRadix,
                         BOOLEAN dispValueEdit,
                         U8 *formatStr);

VOID PRIVATE Get32IntValue(STRING *textPtr,
                         LPU8 buffer,
                         DISPLAY_FORMAT dispValueRadix,
                         BOOLEAN dispValueEdit,
			 U8 *formatStr);

VOID PRIVATE GetCharValue(STRING *textPtr,
                          LPU8 buffer,
                          DISPLAY_FORMAT dispValueRadix,
                          BOOLEAN dispValueEdit,
                          U8 *formatStr);

VOID PRIVATE Get32FloatValue(STRING *textPtr,
                             LPU8 buffer,
                             DISPLAY_FORMAT dispValueRadix,
                             BOOLEAN dispValueEdit,
                             U8 *formatStr);

VOID PRIVATE Get64FloatValue(STRING *textPtr,
                             LPU8 buffer,
                             DISPLAY_FORMAT dispValueRadix,
                             BOOLEAN dispValueEdit,
			     U8 *formatStr);

VOID PRIVATE GetPointerValue(STRING *textPtr,
                             U32  pointerSize,
                             LPU8 buffer);

RETCODE PRIVATE GetEnumValue(STRING *textPtr,
                             LPU8 buffer,
                             TYPE_INDEX typeIndex);

VOID PRIVATE GetCharSetForType(TYPE_SUBHEADER_TYPE *typeInfo,
                               DISPLAY_FORMAT radix);

RETCODE PRIVATE  GetVarTypeAndAddr(DESCRIPTOR varId,
                                   DESCRIPTOR bufferNum,
                                   U32 lineNum,
                                   TYPE_INDEX *typeIndex,
                                   GET_VAR_ADDR_STRUCT **addr,
                                   BOOLEAN *unionEdit);

PRIVATE STRING GetFormatString(U8 editMarkCount,
                               TYPE_INDEX typeIndex);

RETCODE PRIVATE ConvTextAndWriteMem(DESCRIPTOR varId,
                                    LPSTR newValueText,
                                    TYPE_INDEX typeIndex,
                                    GET_VAR_ADDR_STRUCT *addr,
                                    U8 editMarkCount,
				    WRITE_DESTINATION_TYPE writeType);


//RETCODE PRIVATE SetAddrSpace(DESCRIPTOR addr);
//wb
//RETCODE EXPORT GetReg(CPU_REG regId,U32 *regValue);
//RETCODE EXPORT SetReg(CPU_REG regId,U32 regValue);

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/


/***********************************************************************
**
**  GetFormattedType :
**
*********************************************************************/
RETCODE GetFormattedType(DESCRIPTOR rootVarId,
                      STRING *textPtr,
                      U32 linesForThisBuf,
                      U32 startLine,
                      DESCRIPTOR bufferNum,
                      U8 frameNum)  {
   U8 indents = 0;
   TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                       *baseTypeTypeInfo;
   DESCRIPTOR parentId;
   RETCODE retcode = GOOD;

   varIndex = rootVarId;
   varStorageClass = (VAR_STORAGE_CLASS)varTable[varIndex].storageClass;
   varRegisterClass = (VAR_REGISTER_CLASS)varTable[varIndex].registerClass;
   maxLinesForBuf = linesForThisBuf;
   startLineForBuf = startLine;
   textBufferNum = bufferNum;
   varFrameNum = frameNum;
   textStartPtr = *textPtr;
   lineCount = 0;
   bufferFull = FALSE;
   noNewLines = FALSE;
   anotatedText = (BOOLEAN)varTable[varIndex].interActive;
   if (varTable[varIndex].dereferencedPtr) {
      if (varTable[varIndex].rootVarId != NOROOT) {
         parentId = varTable[varIndex].rootVarId & VS_VARID_MASK;
         UpdateChildVars(parentId,
                      varTable[varIndex].varInfo.var.component.lineNum,
                      varTable[varIndex].varInfo.var.component.bufferNum,
                      varTable[parentId].typeInfo.typeIndex,
                      &varTable[parentId].address,
                      FALSE);
      }
   }
   if (varTable[varIndex].errorCode) {
      if ((retcode = GetWarningMessage(textPtr,
            varTable[varIndex].errorCode,indents)) != GOOD)
         return retcode;
   }
   if (varStorageClass == AUTO_VAR_CLASS) {
      if ((retcode = StkGetStackDirection(0,&stackSex)) != GOOD)
         return retcode;
   }
   CheckForTypedef(&varTable[varIndex].typeInfo,&typedefTypeInfo,
         &baseTypeTypeInfo);
   if (baseTypeTypeInfo->typeChoice == SIMPLE_TYPE_CLASS) {
      if ((retcode = GetFormattedSimpleType(baseTypeTypeInfo,
            typedefTypeInfo,(LPSTR)varTable[varIndex].varName,
            &varTable[varIndex].address,indents,textPtr)) != GOOD)
         return retcode;
   }
   else  {
      switch (baseTypeTypeInfo->t.complexType)  {
         case Structure :
         case Union_Type :
            if ((retcode = GetFormattedStructOrUnionType(
                  varTable[varIndex].compListPtr,
                  baseTypeTypeInfo,typedefTypeInfo,
                  &varTable[varIndex].address,
                  (LPSTR)varTable[varIndex].varName,indents,
                  textPtr)) != GOOD)
               return retcode;
            break;
         case Class_Type :
            if ((retcode = GetFormattedClassType(
                  varTable[varIndex].compListPtr,
                  baseTypeTypeInfo,typedefTypeInfo,
                  &varTable[varIndex].address,
                  (LPSTR)varTable[varIndex].varName,indents,
                  textPtr)) != GOOD)
               return retcode;
	    break;
	 case Reference://Hera 2/27/98
         case Pointer :
            if ((retcode = GetFormattedPointerType(baseTypeTypeInfo,
                  typedefTypeInfo,(LPSTR)varTable[varIndex].varName,
                  &varTable[varIndex].address,
                  indents,textPtr)) != GOOD)
               return retcode;
            break;
         case Array_Type :
            if ((retcode = GetFormattedArrayType(baseTypeTypeInfo,
                  typedefTypeInfo,&varTable[varIndex].address,
                  varTable[varIndex].compListPtr,(LPSTR)varTable[varIndex].
                  varName,indents,textPtr)) != GOOD)
               return retcode;
            break;
         case Enumeration :
            if ((retcode = GetFormattedEnumType(baseTypeTypeInfo,
                  typedefTypeInfo,(LPSTR)varTable[varIndex].varName,
                  &varTable[varIndex].address,
                  indents,textPtr)) != GOOD)
               return retcode;
            break;
         case Bit_Type :
            if ((retcode = GetFormattedBitfieldType(baseTypeTypeInfo,
                  typedefTypeInfo,(LPSTR)varTable[varIndex].varName,
                  &varTable[varIndex].address,indents,
                  baseTypeTypeInfo->bitfieldInfo.bitOffset,textPtr))
                   != GOOD)
               return retcode;
            break;
         case UNKNOWN :
         case Function:
            if ((retcode = GetFormattedUnknownType(baseTypeTypeInfo,
                  typedefTypeInfo,(LPSTR)varTable[varIndex].varName,
                  &varTable[varIndex].address,indents,textPtr)) != GOOD)
               return retcode;
            break;
         default :
            break;
      }
   }
   *textPtr += lstrlen((LPSTR)*textPtr);
   return retcode;
}

/*************************************************************************
**
**  GetNthComponent :
**
************************************************************************/
VOID PRIVATE GetNthComponent(DESCRIPTOR varId,
                             DESCRIPTOR bufferNum,
                             U32 lineNum,
                             VS_COMPONENT_TYPE **compPtr) {

   U16 nthComp;
   LOOP_VAR i = 0;

   nthComp = (bufferNum * VS_MAX_BUFFER_LINES) + lineNum;
   if (nthComp == 0)
      *compPtr = NULL;
   if ((varTable[varId].typeInfo.typeChoice == COMPLEX_TYPE_CLASS) &&
         (varTable[varId].typeInfo.t.complexType == Typedef)) {
      if (nthComp >varTable[varId].baseTypeMemberCount)
         *compPtr = NULL;
      else
         *compPtr = varTable[varId].compListPtr;
   }
   else {
      if (nthComp > varTable[varId].memberCount)
         *compPtr = NULL;
      else
         *compPtr = varTable[varId].compListPtr;
   }
   if ((*compPtr != NULL) && nthComp) {
         while (i < nthComp) {
            if (*((*compPtr)->varName) != '\0')
               i++;
            if (i < nthComp)
               *compPtr = (*compPtr)->next;
         }
   }
   return;
}


/***********************************************************************
**
**  GetNewLine :
**
*********************************************************************/
BOOLEAN PRIVATE GetNewLine(STRING *textPtr,
                           U8 indents)  {
   LOOP_VAR i,j;

   if (noNewLines) {
      if (startLineForBuf > lineCount)
         return FALSE;
      else
         return TRUE;
   }
   noNewLines = TRUE;
   if (startLineForBuf > lineCount) {
      *textPtr = textStartPtr;
      memset(*textPtr,'\0',VS_MAX_LINE_CHARS);
      return FALSE;
   }
   if (startLineForBuf == lineCount) {
      *textPtr = textStartPtr;
      memset(*textPtr,'\0',VS_MAX_LINE_CHARS);
   }
   if (anotatedText) {
      **textPtr = specialChar|AT_INDENT_TAG|indents;
      (*textPtr)++;
   }
   else {
      /*
      ** put in blanks for the indents
      */
      for (i=0; i < indents; i++) {
         for (j=0; j < SPACES_PER_INDENT;j++)
            GetBlankSpace(textPtr);
      }
   }
   return TRUE;
}

/***********************************************************************
**
**  GetTypeName :
**
*********************************************************************/
BOOLEAN PRIVATE GetTypeName(STRING *textPtr,
                            LPSTR typeName,
                            U32 indirectionLevels)  {

   if (typeName == NULL)
      return FALSE;
   if (*typeName == '\0') {
      while(indirectionLevels--)
         strcat((LPSTR)*textPtr,pointerChar);
      *textPtr += lstrlen((LPSTR)*textPtr);
      return FALSE;
   }
   if (anotatedText) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_TYPE_NAME_FIELD;
      (*textPtr)++;
   }
   strcat((LPSTR)*textPtr,typeName);
   if (indirectionLevels)
      GetBlankSpace(textPtr);
   while (indirectionLevels--)
      strcat((LPSTR)*textPtr,pointerChar);
   *textPtr += lstrlen((LPSTR)*textPtr);
   if (anotatedText) {
      **textPtr = specialChar|AT_END_TAG|AT_TYPE_NAME_FIELD;
      (*textPtr)++;
   }
   return TRUE;
}
/***********************************************************************
**
**  GetTypeNameRef :
**
*********************************************************************/
BOOLEAN PRIVATE GetTypeNameRef(STRING *textPtr,
                            LPSTR typeName,
                            U32 indirectionLevels)  {

   if (typeName == NULL)
      return FALSE;
   if (*typeName == '\0') {
      while(indirectionLevels--)
         strcat((LPSTR)*textPtr,"&");
      *textPtr += lstrlen((LPSTR)*textPtr);
      return FALSE;
   }
   if (anotatedText) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_TYPE_NAME_FIELD;
      (*textPtr)++;
   }
   strcat((LPSTR)*textPtr,typeName);
   if (indirectionLevels)
      GetBlankSpace(textPtr);
   while (indirectionLevels--)
      strcat((LPSTR)*textPtr,"&");
   *textPtr += lstrlen((LPSTR)*textPtr);
   if (anotatedText) {
      **textPtr = specialChar|AT_END_TAG|AT_TYPE_NAME_FIELD;
      (*textPtr)++;
   }
   return TRUE;
}
/***********************************************************************
**
**  GetBlankSpace :
**
*********************************************************************/
VOID PRIVATE GetBlankSpace(STRING *textPtr)  {

   strcat((LPSTR)*textPtr,blankChar);
   *textPtr += lstrlen((LPSTR)*textPtr);
}

/***********************************************************************
**
**  GetVarName :
**
*********************************************************************/
RETCODE PRIVATE GetVarName(STRING *textPtr,
                           LPSTR varName,
                           U8 fieldFlag,
                           U8 indents)  {

   FUNC_CLASS funcClass;
   U32 stackSize;
   U32 nameLength = 0;
   DESCRIPTOR funcRangeDesc;
   VS_STRING_TYPE funcName;
   RETCODE error;

   /*
   **  a function name prefix is supplied to the user as a differentiator
   **  for like named variables.  Only the current function and globals
   **  are active at any time.  I could have retrieved the function name
   **  info earlier and stored it in the variable table but it requires
   **  an additional 256 byte char array.  I chose instead to create the
   **  name on the fly.  If the func info is not available, the variable info
   **  is still provided, any errors are logged and formatting continues.
   **
   **  In order to make variables with long names fit into one line
   **  (132 chars), I am limiting the variable name displayed to 80 chars.
   **  This includes the size of the function name as well. A variable
   **  name can actually be 256 chars.  It could take over 512 chars
   **  just to print the complete variable name including the function!!!
   **  Since no one in their right mind would have variables and functions
   **  with such long names, I don't think it is a problem to show only
   **  the first 80 chars.
   */
   if (!indents) {
      if (varTable[varIndex].context.function != NULL_SYMBOL) {
         if ((error = AdrCreateAddress(&funcRangeDesc)) == GOOD) {
            if ((error = SymGetFunc(varTable[varIndex].context.function,
                  (LPSTR)funcName,&funcClass,&stackSize,funcRangeDesc))
                  == GOOD) {
               nameLength = lstrlen((LPSTR)funcName);
               if (nameLength < VS_MAX_DISPLAYED_NAME - 1) {
                  strcpy((LPSTR)*textPtr,(LPSTR)funcName);
                  strcat((LPSTR)*textPtr,contextDelimiter);
               }
               else {
                  strncpy((LPSTR)*textPtr,(LPSTR)funcName,
                        VS_MAX_DISPLAYED_NAME);
                  strcat((LPSTR)*textPtr,nameContStr);
               }
               nameLength = lstrlen((LPSTR)*textPtr);
               *textPtr += lstrlen((LPSTR)*textPtr);    /* save the function name */
            }
            else {
               AdrDestroyAddress(funcRangeDesc);
               return error;
            }
            if ((error = AdrDestroyAddress(funcRangeDesc)) != GOOD)
               return error;
         }
      }
   }
   if (anotatedText) {
      if (nameLength < VS_MAX_DISPLAYED_NAME) {
         if (fieldFlag)
            **textPtr = specialChar|AT_BEGIN_TAG|fieldFlag;
         else
            **textPtr = specialChar|AT_BEGIN_TAG|AT_VAR_NAME_FIELD;
         (*textPtr)++;
      }
   }
   if ((nameLength + lstrlen(varName)) > VS_MAX_DISPLAYED_NAME) {
      if (nameLength < VS_MAX_DISPLAYED_NAME) {
         strncpy((LPSTR)*textPtr,varName,VS_MAX_DISPLAYED_NAME-nameLength);
         strcat((LPSTR)*textPtr,nameContStr);
      }
   }
   else {
      strcat((LPSTR)*textPtr,varName);
   }
   *textPtr += lstrlen((LPSTR)*textPtr);
   if (anotatedText) {
      if (nameLength < VS_MAX_DISPLAYED_NAME) {
         if (fieldFlag)
            **textPtr = specialChar|AT_END_TAG|fieldFlag;
         else
            **textPtr = specialChar|AT_END_TAG|AT_VAR_NAME_FIELD;
         (*textPtr)++;
      }
   }
   return GOOD;
}

/***********************************************************************
**
**  GetEndOfLine :
**
*********************************************************************/
VOID PRIVATE GetEndOfLine(STRING *textPtr)  {


   lineCount++;
   noNewLines = FALSE;
   if (lineCount < (maxLinesForBuf+(textBufferNum*VS_MAX_BUFFER_LINES))){
      strcat((LPSTR)*textPtr,eolnString);
      *textPtr += lstrlen((LPSTR)*textPtr);
      bufferFull = FALSE;
   }
   else {
      strcat((LPSTR)*textPtr,endOfBuffer);
      bufferFull = TRUE;
   }

}

/***********************************************************************
**
**  GetArrayIndices :
**
*********************************************************************/
VOID PRIVATE GetArrayIndices(STRING *textPtr,
                             S32 index,
                             S32 fieldMarkTag) {

   if (anotatedText) {
      if (fieldMarkTag) {
         **textPtr = specialChar|AT_BEGIN_TAG|fieldMarkTag;
         (*textPtr)++;
      }
   }
   strcat((LPSTR)*textPtr,leftBracketChar);
   *textPtr += lstrlen((LPSTR)*textPtr);
   sprintf((LPSTR)*textPtr,"%lu",index);
   strcat((LPSTR)*textPtr,rightBracketChar);
   *textPtr += lstrlen((LPSTR)*textPtr);
   if (anotatedText) {
      if (fieldMarkTag) {
         **textPtr = specialChar|AT_END_TAG|fieldMarkTag;
         (*textPtr)++;
      }
   }
   return;
}

VOID FlipBuffer(LPU8 buffer, U32 numBytes) {
   // !!! This routine can just be bypassed if target or host byte order
   //     happens to change.
   U8 temp, highest;
   LOOP_VAR i, end;
   if( numBytes % 2 ) return;  //  just get out if numBytes not even
   end = numBytes / 2;  // speed up for compare
   highest = numBytes - 1;
   for(i=0; i < end; i++) {
      temp = buffer[i];
      buffer[i] = buffer[highest-i];
      buffer[highest-i] = temp;
   }
}

/***********************************************************************
**
**  GetEditValueToBuffer
**
**************************************************************************/
RETCODE PRIVATE GetEditValueToBuffer(TYPE_SUBHEADER_TYPE *typeInfo,
                                     GET_VAR_ADDR_STRUCT *addr,
                                     STRING *textPtr,
                                     LPU8 *buffer,
                                     BOOLEAN *alternateAccess) {
   LPU8 bufPtr = NULL;
   RETCODE error = GOOD;
   U32 regValue;
   BOOLEAN regRead = FALSE;
   if ((*buffer = (LPU8)TMalloc(VS_MAX_BUF)) == NULL)
      return ER_OUT_OF_MEMORY;
   memset(*buffer,'\0',VS_MAX_BUF);
   if (varRegisterClass == NOT_REG) {
      if (varStorageClass == AUTO_VAR_CLASS) {
         /*
         **  StkRead cleans up after itself and does not return a buffer
         **  on a error condition.  Therefore its buffer is only freed when
         **  no error is returned.
	 */
//wb
	 error = StkVarIsActive(varTable[varIndex].context.module,
            varTable[varIndex].context.function,
            varTable[varIndex].context.lowestLevel,
            &varTable[varIndex].frameNum);
//we
         error = StkRead(addr->addrData.getAutoVar.autoVarOffset,
               typeInfo->size,varFrameNum,varTable[varIndex].frameType,
               &bufPtr);
      }
      else {
         /* STATIC_VAR_CLASS, GLOBAL_VAR_CLASS, UNKNOWN_VAR_CLASS */
         if ((error = SetAddrSpace(addr->getFixedAddrDesc)) != GOOD)
            return(error);
         error = MemReadSized(addr->getFixedAddrDesc,typeInfo->size,&bufPtr,
            BYTE_SIZE,CACHE_USE);
         /*
         **  MemRead returns a buffer even when it returns an error, so
         **  you must free the buffer always.  If an error occurs it is
         **  freed immediately, otherwise it is freed later after the
         **  data is saved into the local buffer.
         */
         if (error)
            TFree((LPSTR)bufPtr);
      }
   }
   else {
      /* Register based LIVING_REG, LOCKED_REG */
      regRead = TRUE;
      if (varRegisterClass == LIVING_REG) {
         // NOTES: 09/27/93 - Nghia
         // If variable is a DEAD register - format the value as string
         // This will make it more useful than "no value" string
	 //
         //Hera 12/30/97
         //if ((LdrToolSelect(&toolch) == GOOD) && (toolch == 2)) 
         //error = GetReg(addr->addrData.getRegisterIndex.
         //                          varLivingReg,&regValue);
         //else
         error = CpuGetStockRegister(addr->addrData.getRegisterIndex.  
	                           varLivingReg,&regValue);
         //Hera
         if (addr->addrData.getRegisterIndex.lifetimeState != LIVE ) {
            if (error == GOOD)
               HandleViewOnlyValue(textPtr, regValue);
            else
               HandleNoValueString(textPtr);
            
            *alternateAccess = TRUE;
         }            
      }
      else if (varRegisterClass == LOCKED_REG) {
         // NOTES: 09/27/93 - Nghia
         // If register is a DEAD register, format the value as string.
         // This will make it more useful than "no value" string.
         
	 // current exec context and variable currently in Register
	 //Hera 12/30/97
         error = CpuGetStockRegister(addr->addrData.getLockedReg.
	                        getRegIndex.regIndex,&regValue);
	 //error = GetReg(addr->addrData.getLockedReg.
	 //			getRegIndex.regIndex,&regValue);
         //Hera
         if ((addr->addrData.getLockedReg.lifetimeState != LIVE)
             && (varFrameNum != 0)) {
            // maybe saved on stack with offset 
            // If autoVarOffset is 0L then we know there is no alternate
            // place to look for a value - variable is unknown!
            // This often get value of variable before it was changed/accessed
            // in this routine!  Since MRI doesn't bother to tell us
            // that variable is no longer accessible!
            // !! Another bone to pick!!! It appears locked register
            // stack offsets don't bother to account for stack size pushes
            // vs odd sized variables (i.e.:char on even boundary stacks).
            if (addr->addrData.getLockedReg.autoVarOffset != 0L) {
               U32 defaultSize, stackSize;
               if( (error=ProcDefaultStackSize(&defaultSize))!= GOOD )
                  return(error);
               stackSize = typeInfo->size;
               if( typeInfo->size % defaultSize ) 
                  stackSize = defaultSize * ((typeInfo->size/defaultSize) + 1);
               if( stackSize > 4L ) return(-1); // !!!! can't ever happen???
               error = StkRead(addr->addrData.getLockedReg.autoVarOffset,
                               stackSize,varFrameNum,
                               varTable[varIndex].frameType,
                               &bufPtr);
               if (error == GOOD) {
                  memcpy(*buffer,bufPtr,stackSize);
                  FlipBuffer(*buffer,stackSize);
                  if ((error = TFree((LPSTR)bufPtr)) != GOOD) return error;
                  return(GOOD);
               }
               else {
                  // If error format as no value
                  HandleNoValueString(textPtr);
                  *alternateAccess = TRUE;
               }
            }
            else {
               // NOTES: Handle DEAD register variable && varFrameNum > 0
               // && autoVarOffset == 0 (not save on stack)
               if (error == GOOD) {
                  HandleViewOnlyValue(textPtr, regValue);
               } else {
                  HandleNoValueString(textPtr);
               }
               *alternateAccess = TRUE;
            }
         }
         else {
            // NOTES: Handle DEAD register variable && varFrameNum == 0
            if (addr->addrData.getLockedReg.lifetimeState == DEAD) {
               if (error == GOOD) 
                  HandleViewOnlyValue(textPtr, regValue);
               else 
                  HandleNoValueString(textPtr);
               *alternateAccess = TRUE;
            }
         }
      }
   }
   if (error) {
      if (GetAlternateMemAccess(textPtr,error) != GOOD)
         return error;
      *alternateAccess = TRUE;
   }
   else {
      if( *alternateAccess ) return(GOOD);
      if (regRead) {
         memcpy(*buffer,&regValue,sizeof(regValue));
      }
      else  {
         memcpy(*buffer,bufPtr,typeInfo->size);
         FlipBuffer(*buffer,typeInfo->size);
         if ((error = TFree((LPSTR)bufPtr)) != GOOD) return error;
      }  
   }
   return GOOD;
}


/*************************************************************************
**
**  GetBitfieldEditValue :
**
**************************************************************************/
RETCODE PRIVATE GetBitfieldEditValue(STRING *textPtr,
                                     GET_VAR_ADDR_STRUCT *addr,
                                     TYPE_SUBHEADER_TYPE *typeInfo,
                                     U16 bitOffset) {
   LPU8 buffer;
   BOOLEAN alternateAccess = FALSE;
   U8 byteValue;
   U16 wordValue;
   U32 longValue;
   U8 *bytePtr;
   U16 *wordPtr;
   U32 *longPtr;
   RETCODE error;

   if ((error = GetEditValueToBuffer(typeInfo,addr,textPtr,&buffer,
         &alternateAccess)) != GOOD)
      return error;
   if (alternateAccess)
      return GOOD;

   switch (typeInfo->size) { /* current base type size */
      case 1: /* byte */
         bytePtr = (U8 *)buffer;
         byteValue = *bytePtr;
         byteValue &= bfByteTable[bitOffset].mask.byteMask;
         byteValue >>= (bfByteTable[bitOffset].shiftFactor - typeInfo->
               bitfieldInfo.size);
         strcat((LPSTR)*textPtr,"0x");
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"%x",byteValue);
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case 2: /* word */
         wordPtr = (U16 *)buffer;
         wordValue = *wordPtr;
         wordValue &= bfWordTable[bitOffset].mask.wordMask;
         wordValue >>= (bfWordTable[bitOffset].shiftFactor - typeInfo->
               bitfieldInfo.size);
         strcat((LPSTR)*textPtr,"0x");
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"%x",wordValue);
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case 4: /* long */
         longPtr = (U32 *)buffer;
         longValue = *longPtr;
         longValue &= bfLongTable[bitOffset].mask.longMask;
         longValue >>= (bfLongTable[bitOffset].shiftFactor - typeInfo->
               bitfieldInfo.size);
         strcat((LPSTR)*textPtr,"0x");
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"%x",longValue);
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      default:
         break;
   }
   if ((error = TFree((LPSTR)buffer)) != GOOD)
      return error;
   return GOOD;
}

/***********************************************************************
**
**  GetEditValue :
**
*********************************************************************/
RETCODE PRIVATE GetEditValue(STRING *textPtr,
                          GET_VAR_ADDR_STRUCT *addr,
                          TYPE_SUBHEADER_TYPE *typeInfo)  {
   LPU8 buffer;
   BOOLEAN alternateAccess = FALSE;
   BOOLEAN savedAnotation;
   RETCODE error;

   if ((error = GetEditValueToBuffer(typeInfo,addr,textPtr,&buffer,
                                     &alternateAccess)) != GOOD)
      return error;
   if (alternateAccess)
      return GOOD;
   /*
   **
   **  Need to be able to edit characters, integers, floats, doubles,
   **  strings and pointer values. Check the type and call the appropriate
   **  display routine. Case statements are based on MRI IEEE 695 built in
   **  types.
   **
   */
   if (typeInfo->typeChoice == SIMPLE_TYPE_CLASS) {
      switch (typeInfo->t.simpleType) {
         //case BI_S8_SCHAR: case BI_U8_UCHAR: case BI_S8_CHAR:
         case BI_char: case BI_signed_char: case BI_unsigned_char:
         case BI_boolean:
            GetCharValue(textPtr,buffer,
                  typeTable[typeInfo->t.simpleType].primaryRadix,
                  typeTable[typeInfo->t.simpleType].primaryEdit,
                  typeTable[typeInfo->t.simpleType].primaryFormatStr);
            if(typeTable[typeInfo->t.simpleType].secondaryRadix != DF_NODISP){
               GetCharValue(textPtr,buffer,
                     typeTable[typeInfo->t.simpleType].secondaryRadix,
                     typeTable[typeInfo->t.simpleType].secondaryEdit,
                     typeTable[typeInfo->t.simpleType].secondaryFormatStr);
            }
            break;
         //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_short: case BI_signed_short: case BI_unsigned_short:
            Get16IntValue(textPtr,buffer,
                  typeTable[typeInfo->t.simpleType].primaryRadix,
                  typeTable[typeInfo->t.simpleType].primaryEdit,
                  typeTable[typeInfo->t.simpleType].primaryFormatStr);
            if(typeTable[typeInfo->t.simpleType].secondaryRadix != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get16IntValue(textPtr,buffer,
                     typeTable[typeInfo->t.simpleType].secondaryRadix,
                     typeTable[typeInfo->t.simpleType].secondaryEdit,
                     typeTable[typeInfo->t.simpleType].secondaryFormatStr);
            }
            break;
         //case BI_S32_SLONG: case BI_U32_ULONG: case BI_STACK_INT:
         //case BI_STACK_U: case BI_STACK_UINT: case BI_S32_LONG:
         case BI_integer: case BI_signed_int: case BI_unsigned_int:
         case BI_long: case BI_signed_long: case BI_unsigned_long:
            Get32IntValue(textPtr,buffer,
                  typeTable[typeInfo->t.simpleType].primaryRadix,
                  typeTable[typeInfo->t.simpleType].primaryEdit,
                  typeTable[typeInfo->t.simpleType].primaryFormatStr);
            if(typeTable[typeInfo->t.simpleType].secondaryRadix != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get32IntValue(textPtr,buffer,
                     typeTable[typeInfo->t.simpleType].secondaryRadix,
                     typeTable[typeInfo->t.simpleType].secondaryEdit,
                     typeTable[typeInfo->t.simpleType].secondaryFormatStr);
            }
            break;
         //case BI_F32:
         case BI_float:
            Get32FloatValue(textPtr,buffer,
                  typeTable[typeInfo->t.simpleType].primaryRadix,
                  typeTable[typeInfo->t.simpleType].primaryEdit,
                  typeTable[typeInfo->t.simpleType].primaryFormatStr);
            if(typeTable[typeInfo->t.simpleType].secondaryRadix != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get32FloatValue(textPtr,buffer,
                     typeTable[typeInfo->t.simpleType].secondaryRadix,
                     typeTable[typeInfo->t.simpleType].secondaryEdit,
                     typeTable[typeInfo->t.simpleType].secondaryFormatStr);
            }
            break;
         //case BI_F64: case BI_F64_BCD:
         case BI_dbl_prec_float: case BI_ext_prec_float:
            /* !!! not defering anymore done in get buffer routine
               Defer byte-flipping till we've extracted the sign/exponent
               in lower level routine.
            */
            FlipBuffer(buffer, 8);
            savedAnotation = anotatedText;
            if (varRegisterClass != NOT_REG)
               anotatedText = FALSE;
            Get64FloatValue(textPtr,buffer,
                  typeTable[typeInfo->t.simpleType].primaryRadix,
                  typeTable[typeInfo->t.simpleType].primaryEdit,
                  typeTable[typeInfo->t.simpleType].primaryFormatStr);
            if(typeTable[typeInfo->t.simpleType].secondaryRadix != DF_NODISP){
            strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get64FloatValue(textPtr,buffer,
                     typeTable[typeInfo->t.simpleType].secondaryRadix,
                     typeTable[typeInfo->t.simpleType].secondaryEdit,
                     typeTable[typeInfo->t.simpleType].secondaryFormatStr);
            }
            anotatedText = savedAnotation;
            break;
         /*   no used for ppc603e
         case BI_F_EXTEND:
             !!! not defering anymore done in get buffer routine
               Defer byte-flipping till we've extracted the sign/exponent
               in lower level routine.

            FlipBuffer(buffer, 12);
       
            GetExtendedFloatValue(textPtr,buffer,
                  typeTable[typeInfo->t.simpleType].primaryRadix,
                  typeTable[typeInfo->t.simpleType].primaryEdit,
                  typeTable[typeInfo->t.simpleType].primaryFormatStr);
            if(typeTable[typeInfo->t.simpleType].secondaryRadix != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               GetExtendedFloatValue(textPtr,buffer,
                     typeTable[typeInfo->t.simpleType].secondaryRadix,
                     typeTable[typeInfo->t.simpleType].secondaryEdit,
                     typeTable[typeInfo->t.simpleType].secondaryFormatStr);
            }
            break;
         case BI_F128:
            Get128FloatValue(textPtr,buffer,
                  typeTable[typeInfo->t.simpleType].primaryRadix,
                  typeTable[typeInfo->t.simpleType].primaryEdit,
                  typeTable[typeInfo->t.simpleType].primaryFormatStr);
            if(typeTable[typeInfo->t.simpleType].secondaryRadix != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get128FloatValue(textPtr,buffer,
                     typeTable[typeInfo->t.simpleType].secondaryRadix,
                     typeTable[typeInfo->t.simpleType].secondaryEdit,
                     typeTable[typeInfo->t.simpleType].secondaryFormatStr);
            }
            break;
         case BI_S64_SLONG: case BI_U64_ULONG:
            Get64IntValue(textPtr,buffer,
                  typeTable[typeInfo->t.simpleType].primaryRadix,
                  typeTable[typeInfo->t.simpleType].primaryEdit,
                  typeTable[typeInfo->t.simpleType].primaryFormatStr);
            if(typeTable[typeInfo->t.simpleType].secondaryRadix != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get64IntValue(textPtr,buffer,
                     typeTable[typeInfo->t.simpleType].secondaryRadix,
                     typeTable[typeInfo->t.simpleType].secondaryEdit,
                     typeTable[typeInfo->t.simpleType].secondaryFormatStr);
            }
            break;
         case BI_STRING:
            GetStringValue(textPtr,buffer,
                  typeTable[typeInfo->t.simpleType].primaryRadix,
                  typeTable[typeInfo->t.simpleType].primaryEdit,
                  typeTable[typeInfo->t.simpleType].primaryFormatStr);
            break;
         */
         case BI_pointer:
         case BI_ptr_char:    case BI_ptr_signed_char:  case BI_ptr_unsigned_char:
         case BI_ptr_short:   case BI_ptr_signed_short: case BI_ptr_unsigned_short:
         case BI_ptr_integer: case BI_ptr_signed_int:   case BI_ptr_unsigned_int:
         case BI_ptr_long:    case BI_ptr_signed_long:  case BI_ptr_unsigned_long:
         case BI_ptr_pointer: case BI_ptr_float:
         case BI_ptr_dbl_prec_float:   case BI_ptr_ext_prec_float: case BI_ptr_complex:
         case BI_ptr_dbl_prec_complex: case BI_ptr_void:           case BI_ptr_boolean:
         case BI_ptr_ext_prec_complex: case BI_ptr_lable:
            // NOTES: Nghia - 10/27/93
            // The assumed size for a pointer is the target processor natural
            // size (i.e. 68000 = 4, Z80 = 2, etc.)
            // Use typeInfo->size to get pointer value accordingly.
            GetPointerValue(textPtr, typeInfo->size, buffer);
            break;
         default:
            break;
      }
   }
   else {
      switch (typeInfo->t.complexType) {
	 case Reference://Hera 2/27/98
         case Pointer :
            // NOTES: Nghia - 10/28/93
            // Use typeInfo->size to get pointer value for SMALL/LARGE pointer
            GetPointerValue(textPtr, typeInfo->size, buffer);
            break;
         case Enumeration :
            if ((error = GetEnumValue(textPtr,buffer,typeInfo->typeIndex))
                 != GOOD) return error;
            break;
         default:   /* default to an integer */
            Get32IntValue(textPtr,buffer,
                  typeTable[DEFAULT_INT].primaryRadix,
                  typeTable[DEFAULT_INT].primaryEdit,
                  typeTable[DEFAULT_INT].primaryFormatStr);
            break;
      }
   }
   if ((error = TFree((LPSTR)buffer)) != GOOD)
      return error;
   return GOOD;
}


/***********************************************************************
**
**  GetFormattedSimpleType :
**
*********************************************************************/
RETCODE PRIVATE GetFormattedSimpleType(TYPE_SUBHEADER_TYPE *typeInfo,
                                       TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                       LPSTR varName,
                                       GET_VAR_ADDR_STRUCT *addr,
                                       U8 indents,
                                       STRING *textPtr)  {

   RETCODE error;

   if (typeInfo->t.simpleType==FT_void) //don't process for void type
      return GOOD;
   if (bufferFull)
      return GOOD;
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL)
         GetTypeName(textPtr,typeInfo->typeName,0);
      else
         GetTypeName(textPtr,typedefTypeInfo->typeName,0);
      GetBlankSpace(textPtr);
      if ((error = GetVarName(textPtr,varName,0,indents)) != GOOD)
         return error;
      if (!ActiveVar(textPtr))
         return GOOD;
      strcat((LPSTR)*textPtr,equalString);
      *textPtr += lstrlen((LPSTR)*textPtr);
      if ((error = GetEditValue(textPtr,addr,typeInfo)) != GOOD)
         return error;
      strcat((LPSTR)*textPtr,semicolon);
      *textPtr += lstrlen((LPSTR)*textPtr);
   }
   GetEndOfLine(textPtr);
   return GOOD;
}



/***********************************************************************
**
**  GetFormattedStructOrUnionType :
**
*********************************************************************/
RETCODE PRIVATE GetFormattedStructOrUnionType(VS_COMPONENT_TYPE *component,
                                       TYPE_SUBHEADER_TYPE *typeInfo,
                                       TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                       GET_VAR_ADDR_STRUCT *address,
                                       LPSTR varName,
                                       U8 indents,
                                       STRING *textPtr)  {
   RETCODE error, err;
   BOOLEAN abortFromEsc;
   GET_VAR_ADDR_STRUCT addr;
   TYPE_SUBHEADER_TYPE *baseTypeInfo,
                       *typeTypeInfo;



   if (bufferFull)
      return GOOD;
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL) {
         CheckStructOrUnionOrEnum(textPtr,typeInfo);
         GetTypeName(textPtr,typeInfo->typeName,0);
      }
      else {
         GetTypeName(textPtr,typedefTypeInfo->typeName,0);
      }
      GetBlankSpace(textPtr);
      if ((error = GetVarName(textPtr,varName,0,indents)) != GOOD)
         return error;
      if (!ActiveVar(textPtr))
         return GOOD;
      strcat((LPSTR)*textPtr,blankChar);
      strcat((LPSTR)*textPtr,leftCurlyChar);
   }
   GetEndOfLine(textPtr);
   indents++;
   /* dummy up an address for  accessing structure components */
   if ((varRegisterClass == NOT_REG) && (varStorageClass != AUTO_VAR_CLASS)) {
      if ((error = AdrDuplicateAddress(address->getFixedAddrDesc,
            &addr.getFixedAddrDesc)) != GOOD)
         return error;
   }
   else
      movmem(address,&addr,sizeof(addr));

   while ((component != NULL) && (!bufferFull))  {
      err = TskCheckAbort(&abortFromEsc);
      if(err!=GOOD) return err;
      if (abortFromEsc)
         return ER_ABORT_FROM_ESC;

      CheckForTypedef(&component->typeInfo,&typeTypeInfo,
            &baseTypeInfo);
      if (baseTypeInfo->typeChoice == SIMPLE_TYPE_CLASS)
         GetFormattedSimpleType(baseTypeInfo,typeTypeInfo,
               component->varName,&addr,indents,textPtr);
      else  {
         /* at this point in time we are not allowing in line expansion of
         ** complex types in complex types.  Special handling of structs
         ** and unions inside structs is done here.  This routine is
         ** designed with recursion ultimately in mind.  Later, to
         ** support in line expansion this routine can be called
         ** recursively with some minor revisions.
         */
         switch (baseTypeInfo->t.complexType)  {
            case Structure :
            case Union_Type :
               if (GetNewLine(textPtr,indents)) {
                  if (typeTypeInfo == NULL) {
                     CheckStructOrUnionOrEnum(textPtr,baseTypeInfo);
                     GetTypeName(textPtr,baseTypeInfo->typeName,0);
                  }
                  else {
                     GetTypeName(textPtr,typeTypeInfo->typeName,0);
                  }
                  GetBlankSpace(textPtr);
                  if ((error = GetVarName(textPtr,component->varName,0,
                        indents)) != GOOD)
                     return error;
                  strcat((LPSTR)*textPtr,blankChar);
                  strcat((LPSTR)*textPtr,complexStuff);
               }
               GetEndOfLine(textPtr);
	       break;
            case Reference://Hera 2/27/98
            case Pointer :
               if ((error = GetFormattedPointerType(baseTypeInfo,
                     typeTypeInfo,component->varName,&addr,indents,
                     textPtr)) != GOOD)
                  return error;
               break;
            case Array_Type :
               if ((error = GetFormattedArrayTypeForStruct(baseTypeInfo,
                     typeTypeInfo,component->varName,indents,
                     textPtr)) != GOOD)
                  return error;
               break;
            case Enumeration :
               if ((error = GetFormattedEnumType(baseTypeInfo,
                     typeTypeInfo,component->varName,&addr,indents,
                     textPtr)) != GOOD)
                  return error;
               break;
            case Bit_Type :
               if (*(component->varName) != '\0') {
                  if ((error = GetFormattedBitfieldType(baseTypeInfo,
                        typeTypeInfo,component->varName,&addr,indents,
                        component->bitOffset,textPtr)) != GOOD)
                     return error;
               }
               break;
            default:
               break;
         }  /* switch */
      }  /* else */
      /*
      ** now calculate the address of the next component
      ** of the struct.
      */
      if (component->next != NULL) {
         if (varRegisterClass == NOT_REG) {
            if (varStorageClass != AUTO_VAR_CLASS) {
               if ((error = AdrSubtractFromAddress(addr.getFixedAddrDesc,
                     component->offset)) != GOOD)
                  return error;
               if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
                     component->next->offset)) != GOOD)
                  return error;
            }
            else  {
               switch (stackSex) {
                  case HI_TO_LOW:
                     addr.addrData.getAutoVar.autoVarOffset -= component->offset;
                     addr.addrData.getAutoVar.autoVarOffset += component->
                           next->offset;
                     break;
                  case LOW_TO_HI:
                     addr.addrData.getAutoVar.autoVarOffset += component->offset;
                     addr.addrData.getAutoVar.autoVarOffset -= component->
                           next->offset;
                     break;
               }
            }
         }
      }
      component = component->next;
   }   /* while */
   if ((varRegisterClass == NOT_REG) &&
         (varStorageClass != AUTO_VAR_CLASS)) {
      if ((error = AdrDestroyAddress(addr.getFixedAddrDesc)) != GOOD)
         return error;
   }
   if (bufferFull)
      return GOOD;
   if (GetNewLine(textPtr,indents-1)) {
      strcat((LPSTR)*textPtr,rightCurlyChar);
      *textPtr += lstrlen((LPSTR)*textPtr);
   }
   GetEndOfLine(textPtr);
   return GOOD;
}

/***********************************************************************
**
**  GetFormattedClassType :
**
*********************************************************************/
RETCODE PRIVATE GetFormattedClassType(VS_COMPONENT_TYPE *component,
                                       TYPE_SUBHEADER_TYPE *typeInfo,
                                       TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                       GET_VAR_ADDR_STRUCT *address,
                                       LPSTR varName,
                                       U8 indents,
                                       STRING *textPtr)  {
   RETCODE error, err;
   BOOLEAN abortFromEsc;
   GET_VAR_ADDR_STRUCT addr;
   TYPE_SUBHEADER_TYPE *baseTypeInfo,
                       *typeTypeInfo;

   AUTO_VAR_OFFSET autovaroffset;//Hera 3/2/98

   if (bufferFull)
      return GOOD;
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL) {
         CheckStructOrUnionOrEnum(textPtr,typeInfo);
         GetTypeName(textPtr,typeInfo->typeName,0);
      }
      else {
         GetTypeName(textPtr,typedefTypeInfo->typeName,0);
      }
      GetBlankSpace(textPtr);
      if ((error = GetVarName(textPtr,varName,0,indents)) != GOOD)
         return error;
      if (!ActiveVar(textPtr))
         return GOOD;
      strcat((LPSTR)*textPtr,blankChar);
      strcat((LPSTR)*textPtr,leftCurlyChar);
   }
   GetEndOfLine(textPtr);
   indents++;
   /* dummy up an address for  accessing structure components */
   if ((varRegisterClass == NOT_REG) && (varStorageClass != AUTO_VAR_CLASS)) {
      if ((error = AdrDuplicateAddress(address->getFixedAddrDesc,
            &addr.getFixedAddrDesc)) != GOOD)
         return error;
   }
   else
      movmem(address,&addr,sizeof(addr));
   //Hera 3/2/98
   if (varRegisterClass == NOT_REG && varStorageClass != AUTO_VAR_CLASS) 
      autovaroffset = 0;
   else if (varRegisterClass == NOT_REG && varStorageClass == AUTO_VAR_CLASS)
      autovaroffset = addr.addrData.getAutoVar.autoVarOffset;
   //Hera
   while ((component != NULL) && (!bufferFull))  {
      //Hera 3/2/98
      if (varRegisterClass == NOT_REG) {
	 if (varStorageClass != AUTO_VAR_CLASS) {
	    if (component->offset >= autovaroffset){            
	       if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
                     (component->offset-autovaroffset))) != GOOD)
		  return error;
	    }
         }else{
            switch (stackSex) {
               case HI_TO_LOW:
                  //addr.addrData.getAutoVar.autoVarOffset -= component->offset; --Hera 3/2/98
                  addr.addrData.getAutoVar.autoVarOffset = autovaroffset + component->offset;
                  break;
               case LOW_TO_HI:
		  //addr.addrData.getAutoVar.autoVarOffset += component->offset; --Hera 3/2/98
		  addr.addrData.getAutoVar.autoVarOffset = autovaroffset - component->offset;
                  break;
            }
         }
      }//Hera
      err = TskCheckAbort(&abortFromEsc);
      if(err!=GOOD) return err;
      if (abortFromEsc)
         return ER_ABORT_FROM_ESC;

      CheckForTypedef(&component->typeInfo,&typeTypeInfo,
            &baseTypeInfo);
      if (baseTypeInfo->typeChoice == SIMPLE_TYPE_CLASS)
         GetFormattedSimpleType(baseTypeInfo,typeTypeInfo,
               component->varName,&addr,indents,textPtr);
      else  {
         /* at this point in time we are not allowing in line expansion of
         ** complex types in complex types.  Special handling of structs
         ** and unions inside structs is done here.  This routine is
         ** designed with recursion ultimately in mind.  Later, to
         ** support in line expansion this routine can be called
         ** recursively with some minor revisions.
         */
         switch (baseTypeInfo->t.complexType)  {
            case Structure :
            case Class_Type :
            case Union_Type :
               if (GetNewLine(textPtr,indents)) {
                  if (typeTypeInfo == NULL) {
                     CheckStructOrUnionOrEnum(textPtr,baseTypeInfo);
                     GetTypeName(textPtr,baseTypeInfo->typeName,0);
                  }
                  else {
                     GetTypeName(textPtr,typeTypeInfo->typeName,0);
                  }
                  GetBlankSpace(textPtr);
                  if ((error = GetVarName(textPtr,component->varName,0,
                        indents)) != GOOD)
                     return error;
                  strcat((LPSTR)*textPtr,blankChar);
                  strcat((LPSTR)*textPtr,complexStuff);
               }
               GetEndOfLine(textPtr);
               break;
            /* <Judy 8/1/97> */
	    case Function:
               if (GetNewLine(textPtr,indents)) {
                  if (typeTypeInfo != NULL)
                      GetTypeName(textPtr,typeTypeInfo->typeName,0);
                  GetBlankSpace(textPtr);
                  if ((error = GetVarName(textPtr,component->varName,0,
                        indents)) != GOOD)
                     return error;
                  strcat((LPSTR)*textPtr,blankChar);
                  strcat((LPSTR)*textPtr,complexStuff);
               }
               GetEndOfLine(textPtr);
	       break;
	    /* eof <Judy 8/1/97> */
            case Reference://Hera 2/27/98
            case Pointer :
               if ((error = GetFormattedPointerType(baseTypeInfo,
                     typeTypeInfo,component->varName,&addr,indents,
                     textPtr)) != GOOD)
                  return error;
               break;
            case Array_Type :
               if ((error = GetFormattedArrayTypeForStruct(baseTypeInfo,
                     typeTypeInfo,component->varName,indents,
                     textPtr)) != GOOD)
                  return error;
               break;
            case Enumeration :
               if ((error = GetFormattedEnumType(baseTypeInfo,
                     typeTypeInfo,component->varName,&addr,indents,
                     textPtr)) != GOOD)
                  return error;
               break;
            case Bit_Type :
               if (*(component->varName) != '\0') {
                  if ((error = GetFormattedBitfieldType(baseTypeInfo,
                        typeTypeInfo,component->varName,&addr,indents,
                        component->bitOffset,textPtr)) != GOOD)
                     return error;
               }
               break;
            default:
               break;
         }  /* switch */
      }  /* else */
      /*
      ** now calculate the address of the next component
      ** of the struct.
      */
      if (component->next != NULL) {
         if (varRegisterClass == NOT_REG) {
	    if (varStorageClass != AUTO_VAR_CLASS) {
               if (component->offset)
		  autovaroffset = component->offset;
               //if ((error = AdrSubtractFromAddress(addr.getFixedAddrDesc,
               //      component->offset)) != GOOD)
               //   return error;
               //if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
               //      component->next->offset)) != GOOD)
	       //	  return error;
            }
            /*else  {
               switch (stackSex) {
                  case HI_TO_LOW:
                     //addr.addrData.getAutoVar.autoVarOffset -= component->offset; --Hera 3/2/98
                     addr.addrData.getAutoVar.autoVarOffset += component->
                           next->offset;
                     break;
                  case LOW_TO_HI:
		     //addr.addrData.getAutoVar.autoVarOffset += component->offset; --Hera 3/2/98
                     addr.addrData.getAutoVar.autoVarOffset -= component->
                           next->offset;
                     break;
               }
	    }*/
         }
      }
      component = component->next;
   }   /* while */
   if ((varRegisterClass == NOT_REG) &&
         (varStorageClass != AUTO_VAR_CLASS)) {
      if ((error = AdrDestroyAddress(addr.getFixedAddrDesc)) != GOOD)
         return error;
   }
   if (bufferFull)
      return GOOD;
   if (GetNewLine(textPtr,indents-1)) {
      strcat((LPSTR)*textPtr,rightCurlyChar);
      *textPtr += lstrlen((LPSTR)*textPtr);
   }
   GetEndOfLine(textPtr);
   return GOOD;
}

/***********************************************************************
**
**  GetFormattedPointerType :
**
*********************************************************************/
RETCODE PRIVATE GetFormattedPointerType(TYPE_SUBHEADER_TYPE *typeInfo,
                                     TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                     LPSTR varName,
                                     GET_VAR_ADDR_STRUCT *addr,
                                     U8 indents,
                                     STRING *textPtr)  {
   TYPE_SUBHEADER_TYPE *subtypeInfo;
   U8 indirectionLevels = 1;
   RETCODE error;

   if (bufferFull)
      return GOOD;
   GetPointerTypeInfo(typeInfo->next,&subtypeInfo,&indirectionLevels);
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL) {
	 CheckStructOrUnionOrEnum(textPtr,subtypeInfo);
	 if(typeInfo->t.complexType == Reference)//Hera 2/27/98
	    GetTypeNameRef(textPtr,subtypeInfo->typeName,indirectionLevels);
         else
	    GetTypeName(textPtr,subtypeInfo->typeName,indirectionLevels);
      }
      else {
         GetTypeName(textPtr,typedefTypeInfo->typeName,0);
         GetBlankSpace(textPtr);
      }
      if ((subtypeInfo->typeChoice == SIMPLE_TYPE_CLASS) &&
            (subtypeInfo->t.simpleType == FT_void)) {
         /**
         ** we don't allow expansion of void ptrs
         **/
         if ((error = GetVarName(textPtr,varName,0,indents)) != GOOD)
            return error;
      }
      else {
      if ((error = GetVarName(textPtr,varName,AT_REFERENCE_FIELD,
                indents)) != GOOD)
	  return error;
      }
      
      if (!ActiveVar(textPtr))
         return GOOD;
      strcat((LPSTR)*textPtr,equalString);
      *textPtr += lstrlen((LPSTR)*textPtr);
      if ((error = GetEditValue(textPtr,addr,typeInfo)) != GOOD)
         return error;
      strcat((LPSTR)*textPtr,semicolon);
      *textPtr += lstrlen((LPSTR)*textPtr);
   }
   GetEndOfLine(textPtr);
   return GOOD;
}

/***********************************************************************
**
**  GetFormattedArrayTypeForStruct :
**
*********************************************************************/
RETCODE PRIVATE GetFormattedArrayTypeForStruct(TYPE_SUBHEADER_TYPE *typeInfo,
                                      TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                      LPSTR varName,
                                      U8 indents,
                                      STRING *textPtr)  {
   TYPE_SUBHEADER_TYPE *subtypeInfo,
                       *arrayTypeInfo;
   U8 ptrIndirectionLevels = 0;
   U8 arrayIndirectionLevels = 1;
   TYPE_Z_STRUCT cArray;
   RETCODE error;

   if (bufferFull)
      return GOOD;
   GetArrayTypeInfo(typeInfo->next,&subtypeInfo,&ptrIndirectionLevels,
         &arrayIndirectionLevels);
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL) {
         CheckStructOrUnionOrEnum(textPtr,subtypeInfo);
         if (GetTypeName(textPtr,subtypeInfo->typeName,ptrIndirectionLevels))
            if (!ptrIndirectionLevels)
               GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typedefTypeInfo->typeName,
               ptrIndirectionLevels))
            if (!ptrIndirectionLevels)
               GetBlankSpace(textPtr);
      }
      if ((error = GetVarName(textPtr,varName,0,indents)) != GOOD)
         return error;
      arrayTypeInfo = typeInfo;
      while (arrayIndirectionLevels--) {
         if ((error = SymGetTypeCArray(arrayTypeInfo->typeIndex,
               &cArray)) != GOOD)
            return error;
         GetArrayIndices(textPtr,cArray.highBound+1,0);
         arrayTypeInfo = arrayTypeInfo->next;
      }
      if (!ActiveVar(textPtr))
         return GOOD;
      strcat((LPSTR)*textPtr,equalString);
      strcat((LPSTR)*textPtr,complexStuff);
   }
   GetEndOfLine(textPtr);
   return GOOD;
}

/***********************************************************************
**
**  GetFormattedArrayType :
**
*********************************************************************/
RETCODE PRIVATE GetFormattedArrayType(TYPE_SUBHEADER_TYPE *typeInfo,
                                   TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                   GET_VAR_ADDR_STRUCT *address,
                                   VS_COMPONENT_TYPE *component,
                                   LPSTR varName,
                                   U8 indents,
                                   STRING *textPtr)  {
   TYPE_SUBHEADER_TYPE *subtypeInfo,
                       *baseTypeInfo,
                       *typeTypeInfo,
                       *arrayTypeInfo;
   U8 arrayIndirectionLevels = 1;
   U8 ptrIndirectionLevels = 0;
   GET_VAR_ADDR_STRUCT addr;
   U32 i = 0;           
   TYPE_Z_STRUCT cArray;
   RETCODE error, err;
   BOOLEAN abortFromEsc;



   if (bufferFull)
      return GOOD;
   GetArrayTypeInfo(typeInfo->next,&subtypeInfo,&ptrIndirectionLevels,
         &arrayIndirectionLevels);
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL) {
         CheckStructOrUnionOrEnum(textPtr,subtypeInfo);
         if (GetTypeName(textPtr,subtypeInfo->typeName,ptrIndirectionLevels))
            if (!ptrIndirectionLevels)
               GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typedefTypeInfo->typeName,
               ptrIndirectionLevels))
            if (!ptrIndirectionLevels)
               GetBlankSpace(textPtr);
      }
      if ((error = GetVarName(textPtr,varName,0,indents)) != GOOD)
         return error;
      /*
      **  here we get the array indices, use arrayIndirectionLevels
      **  to know how many indices to display.
      */
      arrayTypeInfo = typeInfo;
      while (arrayIndirectionLevels--) {
         if ((error = SymGetTypeCArray(arrayTypeInfo->typeIndex,
               &cArray)) != GOOD)
            return error;
         GetArrayIndices(textPtr,cArray.highBound+1,0);
         arrayTypeInfo = arrayTypeInfo->next;
      }
      if (!ActiveVar(textPtr))
         return GOOD;
      strcat((LPSTR)*textPtr,equalString);
      strcat((LPSTR)*textPtr,leftCurlyChar);
   }
   GetEndOfLine(textPtr);
   indents++;
   if ((error = SymGetTypeCArray(typeInfo->typeIndex,&cArray)) != GOOD)
      return error;
   /* dummy up an address for  accessing array info */

   if ((varRegisterClass == NOT_REG) &&
         (varStorageClass != AUTO_VAR_CLASS)) {
      if ((error = AdrDuplicateAddress(address->getFixedAddrDesc,
            &addr.getFixedAddrDesc)) != GOOD)
         return error;
   }
   else
      movmem(address,&addr,sizeof(addr));

   CheckForTypedef(typeInfo->next,&typeTypeInfo,
         &baseTypeInfo);

   if (baseTypeInfo->typeChoice == SIMPLE_TYPE_CLASS) {
      while ((!bufferFull) && (i <= (unsigned long)cArray.highBound)) {
         err = TskCheckAbort(&abortFromEsc);
         if(err!=GOOD) return err;
         if (abortFromEsc)
            return ER_ABORT_FROM_ESC;

         if (GetNewLine(textPtr,indents)) {
            GetArrayIndices(textPtr,i,AT_VAR_NAME_FIELD);
            if ((error = GetEditValue(textPtr,&addr,baseTypeInfo)) != GOOD)
               return error;
            if (i < (unsigned long)cArray.highBound)
               strcat((LPSTR)*textPtr,commaChar);
         }
         GetEndOfLine(textPtr);

         if (varRegisterClass == NOT_REG) {
            if (varStorageClass != AUTO_VAR_CLASS) {
               if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
                     baseTypeInfo->size)) != GOOD)
                  return error;
            }
            else  {
               switch (stackSex) {
               /*
               ** Remember that arrays are accessed on the stack with
               ** the 0th index at the greatest offset.  In other words they
               ** are on the stack upside down.
               */
                  case HI_TO_LOW:
                     addr.addrData.getAutoVar.autoVarOffset +=
                           baseTypeInfo->size;
                     break;
                  case LOW_TO_HI:
                     addr.addrData.getAutoVar.autoVarOffset -=
                           baseTypeInfo->size;
                     break;
               }
            }
         }
         i++;
      }
   }
   else {
      switch (baseTypeInfo->t.complexType) {
         case Structure :
         case Class_Type :
         case Union_Type :
            while ((!bufferFull) && (i <= (unsigned long)cArray.highBound)) {
               err = TskCheckAbort(&abortFromEsc);
               if(err!=GOOD) return err;
               if (abortFromEsc)
                  return ER_ABORT_FROM_ESC;

               GetNewLine(textPtr,indents);
               GetArrayIndices(textPtr,i,0);
               if (baseTypeInfo->t.complexType==Class_Type) {
                  GetFormattedClassType(component,baseTypeInfo,
                     typeTypeInfo,&addr,varName,indents,textPtr);
               }
               else {
                  GetFormattedStructOrUnionType(component,baseTypeInfo,
                     typeTypeInfo,&addr,varName,indents,textPtr);
               }
               if (varRegisterClass == NOT_REG) {
                  if (varStorageClass != AUTO_VAR_CLASS) {
                     if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
                           baseTypeInfo->size)) != GOOD)
                        return error;
                  }
                  else  {
                     switch (stackSex) {
                     /*
                     ** Remember that arrays are accessed on the stack with
                     ** the 0th index at the greatest offset.  In other words they
                     ** are on the stack upside down.
                     */
                        case HI_TO_LOW:
                           addr.addrData.getAutoVar.autoVarOffset +=
                                 baseTypeInfo->size;
                           break;
                        case LOW_TO_HI:
                           addr.addrData.getAutoVar.autoVarOffset -=
                                 baseTypeInfo->size;
                           break;
                     }
                  }
               }
               i++;
            }
            break;
         case Array_Type :
            while ((!bufferFull) && (i <= (unsigned long)cArray.highBound)) {
               err = TskCheckAbort(&abortFromEsc);
               if(err!=GOOD) return err;
               if (abortFromEsc)
                  return ER_ABORT_FROM_ESC;

               GetNewLine(textPtr,indents);
               GetArrayIndices(textPtr,i,AT_VAR_NAME_FIELD);
               if ((error = GetFormattedArrayType(baseTypeInfo,
                     typeTypeInfo,&addr,component,varName,
                     indents,textPtr)) != GOOD)
                  return error;
               if (varRegisterClass == NOT_REG) {
                  if (varStorageClass != AUTO_VAR_CLASS) {
                     if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
                           typeInfo->next->size)) != GOOD)
                        return error;
                  }
                  else  {
                     switch (stackSex) {
                     /*
                     ** Remember that arrays are accessed on the stack with
                     ** the 0th index at the greatest offset.  In other words they
                     ** are on the stack upside down.
                     */
                        case HI_TO_LOW:
                           addr.addrData.getAutoVar.autoVarOffset +=
                                 typeInfo->next->size;
                           break;
                        case LOW_TO_HI:
                           addr.addrData.getAutoVar.autoVarOffset -=
                                 typeInfo->next->size;
                           break;
                     }
                  }
               }
               i++;
            }
	    break;
         case Reference://Hera 2/27/98
         case Pointer :
            while ((!bufferFull) && (i <= (unsigned long)cArray.highBound)) {
               err = TskCheckAbort(&abortFromEsc);
               if(err!=GOOD) return err;
               if (abortFromEsc)
                  return ER_ABORT_FROM_ESC;

               if (GetNewLine(textPtr,indents)) {
                  GetArrayIndices(textPtr,i,AT_REFERENCE_FIELD);
                  if ((error = GetEditValue(textPtr,&addr,baseTypeInfo)) !=
                        GOOD)
                     return error;
                  if (i < cArray.highBound)
                     strcat((LPSTR)*textPtr,commaChar);
               }
               GetEndOfLine(textPtr);
               if (varRegisterClass == NOT_REG) {
                  if (varStorageClass != AUTO_VAR_CLASS) {
                     if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
                           baseTypeInfo->size)) != GOOD)
                        return error;
                  }
                  else  {
                     switch (stackSex) {
                     /*
                     ** Remember that arrays are accessed on the stack with
                     ** the 0th index at the greatest offset.  In other words they
                     ** are on the stack upside down.
                     */
                        case HI_TO_LOW:
                           addr.addrData.getAutoVar.autoVarOffset +=
                                 baseTypeInfo->size;
                           break;
                        case LOW_TO_HI:
                           addr.addrData.getAutoVar.autoVarOffset -=
                                 baseTypeInfo->size;
                           break;
                     }
                  }
               }
               i++;
            }
            break;
         case Enumeration :
            while ((!bufferFull) && (i <= (unsigned long)cArray.highBound)) {
               err = TskCheckAbort(&abortFromEsc);
               if(err!=GOOD) return err;
               if (abortFromEsc)
                  return ER_ABORT_FROM_ESC;

               if (GetNewLine(textPtr,indents)) {
                  GetArrayIndices(textPtr,i,AT_VAR_NAME_FIELD);
                  if ((error = GetEditValue(textPtr,&addr,baseTypeInfo)) !=
                        GOOD)
                     return error;
                  if (i < cArray.highBound)
                     strcat((LPSTR)*textPtr,commaChar);
               }
               GetEndOfLine(textPtr);
               if (varRegisterClass == NOT_REG) {
                  if (varStorageClass != AUTO_VAR_CLASS) {
                     if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
                           typeInfo->next->size)) != GOOD)
                        return error;
                  }
                  else  {
                     switch (stackSex) {
                     /*
                     ** Remember that arrays are accessed on the stack with
                     ** the 0th index at the greatest offset.  In other words they
                     ** are on the stack upside down.
                     */
                        case HI_TO_LOW:
                           addr.addrData.getAutoVar.autoVarOffset +=
                                 typeInfo->next->size;
                           break;
                        case LOW_TO_HI:
                           addr.addrData.getAutoVar.autoVarOffset -=
                                 typeInfo->next->size;
                           break;
                     }
                  }
               }
               i++;
            }
            break;
         default:
            break;
      }
   }
   if ((varRegisterClass == NOT_REG) &&
         (varStorageClass != AUTO_VAR_CLASS)) {
      if ((error = AdrDestroyAddress(addr.getFixedAddrDesc)) != GOOD)
         return error;
   }
   if (bufferFull)
      return GOOD;
   if (GetNewLine(textPtr,indents-1)) {
      strcat((LPSTR)*textPtr,rightCurlyChar);
      strcat((LPSTR)*textPtr,semicolon);
      *textPtr += lstrlen((LPSTR)*textPtr);
   }
   GetEndOfLine(textPtr);
   return GOOD;
}

/***********************************************************************
**
**  GetFormattedEnumType :
**
*********************************************************************/
RETCODE PRIVATE GetFormattedEnumType(TYPE_SUBHEADER_TYPE *typeInfo,
                                  TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                  LPSTR varName,
                                  GET_VAR_ADDR_STRUCT *addr,
                                  U8 indents,
                                  STRING *textPtr)  {

   RETCODE error;

   if (bufferFull)
      return GOOD;
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL) {
         CheckStructOrUnionOrEnum(textPtr,typeInfo);
         if (GetTypeName(textPtr,typeInfo->typeName,0))
            GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typedefTypeInfo->typeName,0))
            GetBlankSpace(textPtr);
      }
      if ((error = GetVarName(textPtr,varName,0,indents)) != GOOD)
         return error;
      if (!ActiveVar(textPtr))
         return GOOD;
      strcat((LPSTR)*textPtr,equalString);
      *textPtr += lstrlen((LPSTR)*textPtr);
      if ((error = GetEditValue(textPtr,addr,typeInfo)) != GOOD)
         return error;
      strcat((LPSTR)*textPtr,semicolon);
      *textPtr += lstrlen((LPSTR)*textPtr);
   }
   GetEndOfLine(textPtr);
   return GOOD;
}

/***********************************************************************
**
**  GetFormattedBitfieldType :
**
*********************************************************************/
RETCODE PRIVATE GetFormattedBitfieldType(TYPE_SUBHEADER_TYPE *typeInfo,
                                  TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                  LPSTR varName,
                                  GET_VAR_ADDR_STRUCT *addr,
                                  U8 indents,
                                  U16 bitOffset,
                                  STRING *textPtr)  {
   TYPE_SUBHEADER_TYPE *typeTypeInfo,
                       *baseTypeInfo;
   RETCODE error;

   if (bufferFull)
      return GOOD;
   if (GetNewLine(textPtr,indents)) {
      CheckForTypedef(typeInfo->next,&typeTypeInfo,&baseTypeInfo);
      if (typedefTypeInfo == NULL) {
         if (GetTypeName(textPtr,baseTypeInfo->typeName,0))
            GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typeTypeInfo->typeName,0))
            GetBlankSpace(textPtr);
      }
      if ((error = GetVarName(textPtr,varName,0,indents)) != GOOD)
         return error;
      if (!ActiveVar(textPtr))
         return GOOD;
      strcat((LPSTR)*textPtr,(LPSTR)colon);
      *textPtr += lstrlen((LPSTR)*textPtr);
      sprintf((LPSTR)*textPtr,"%i",typeInfo->bitfieldInfo.size);
      *textPtr += strlen((LPSTR)*textPtr);
      strcat((LPSTR)*textPtr,(LPSTR)equalString);
      *textPtr += lstrlen((LPSTR)*textPtr);
      if ((error = GetBitfieldEditValue(textPtr,addr,typeInfo,
            bitOffset)) != GOOD)
         return error;
      strcat((LPSTR)*textPtr,(LPSTR)semicolon);
      *textPtr += lstrlen((LPSTR)*textPtr);
   }
   GetEndOfLine(textPtr);
   return GOOD;
}

/***********************************************************************
**
**  GetFormattedUnknownType:
**
*********************************************************************/
RETCODE PRIVATE GetFormattedUnknownType(TYPE_SUBHEADER_TYPE *typeInfo,
                                  TYPE_SUBHEADER_TYPE *typedefTypeInfo,
                                  LPSTR varName,
                                  GET_VAR_ADDR_STRUCT *addr,
                                  U8 indents,
                                  STRING *textPtr)  {
   RETCODE error;

   if(typeInfo->t.complexType == Function) return GOOD; //Hera 2/25/98
   if (bufferFull)
      return GOOD;
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL) {
         if (GetTypeName(textPtr,typeInfo->typeName,0))
            GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typedefTypeInfo->typeName,0))
            GetBlankSpace(textPtr);
      }
      if ((error = GetVarName(textPtr,varName,0,indents)) != GOOD)
         return error;
      if (!ActiveVar(textPtr))
	 return GOOD;
      strcat((LPSTR)*textPtr,equalString);
      *textPtr += lstrlen((LPSTR)*textPtr);
      if (typeInfo->size == 0)
         typeInfo->size = 4;     /* default to 4 bytes */
      if ((error = GetEditValue(textPtr,addr,typeInfo)) != GOOD)
	 return error;
      strcat((LPSTR)*textPtr,semicolon);
      *textPtr += lstrlen((LPSTR)*textPtr);
   }
   GetEndOfLine(textPtr);
   return GOOD;
}

/***************************************************************************
**
**  GetWarningMessage :
**
**************************************************************************/
RETCODE PRIVATE GetWarningMessage(STRING *textPtr,
                                  RETCODE errCode,
                                  U8 indents) {
   if (errCode == GOOD)
      return GOOD;
   if (errCode > MAX_WARNING_MESS) {
      if (CheckWarning(errCode,&varTable[varIndex].errorCode) != GOOD)
         return errCode;
      errCode = varTable[varIndex].errorCode;
   }
   GetNewLine(textPtr,indents);
   if (anotatedText) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_WARNING_FIELD;
      (*textPtr)++;
   }
   strcat((LPSTR)*textPtr,(LPSTR)warningMessages[errCode]);
   *textPtr += strlen((LPSTR)*textPtr);
   if (anotatedText) {
      **textPtr = specialChar|AT_END_TAG|AT_WARNING_FIELD;
      (*textPtr)++;
   }
   GetEndOfLine(textPtr);
   textStartPtr = *textPtr;
   return GOOD;
}

/**********************************************************************
**
**  GetAlternateMemAccess :
**
************************************************************************/
RETCODE PRIVATE GetAlternateMemAccess(STRING *textPtr,
                                      RETCODE error) {
   RETCODE errorCode;

   errorCode = error;
   if (CheckWarning(error,&errorCode) != GOOD)
      return error;
   strcat((LPSTR)*textPtr,"??? ");
   *textPtr += strlen((LPSTR)*textPtr);
   if (anotatedText) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_WARNING_FIELD;
      (*textPtr)++;
   }
   strcat((LPSTR)*textPtr,(LPSTR)warningMessages[errorCode]);
   *textPtr += strlen((LPSTR)*textPtr);
   if (anotatedText) {
      **textPtr = specialChar|AT_END_TAG|AT_WARNING_FIELD;
      (*textPtr)++;
   }
   return GOOD;
}
/***********************************************************************
**
**  GetPointerTypeInfo :
**
*********************************************************************/
VOID PRIVATE GetPointerTypeInfo(TYPE_SUBHEADER_TYPE *typeHeader,
                                TYPE_SUBHEADER_TYPE **typeInfo,
                                U8 *indirectionLevels)  {

   while (typeHeader != NULL) {
      if ((typeHeader->t.complexType == Pointer) ||
            (typeHeader->t.complexType == Reference/*Hera 2/27/98*/))
         (*indirectionLevels)++;
      else
         *typeInfo = typeHeader;
      typeHeader = typeHeader->next;
   }
}

/***********************************************************************
**
**  GetArrayTypeInfo :
**
*********************************************************************/
VOID PRIVATE GetArrayTypeInfo(TYPE_SUBHEADER_TYPE *typeHeader,
                              TYPE_SUBHEADER_TYPE **typeInfo,
                              U8 *ptrIndirectionLevels,
                              U8 *arrayIndirectionLevels)  {

   if (typeHeader->typeChoice == COMPLEX_TYPE_CLASS) {
      switch(typeHeader->t.complexType) {
         case Array_Type:
            (*arrayIndirectionLevels)++;
            GetArrayTypeInfo(typeHeader->next,typeInfo,ptrIndirectionLevels,
                  arrayIndirectionLevels);
	    break;
         case Reference://Hera 2/27/98
         case Pointer:
            (*ptrIndirectionLevels)++;
            GetArrayTypeInfo(typeHeader->next,typeInfo,ptrIndirectionLevels,
                  arrayIndirectionLevels);
            break;
         default:
            *typeInfo = typeHeader;
            break;
      }
   }
   else
      *typeInfo = typeHeader;
}

/***********************************************************************
**
**  CheckStructOrUnionOrEnum :
**
*********************************************************************/
VOID PRIVATE CheckStructOrUnionOrEnum(STRING *textPtr,
                                      TYPE_SUBHEADER_TYPE *typeHeader)  {

   switch (typeHeader->t.complexType)  {
      case Class_Type :
         strcat((LPSTR)*textPtr,classString);
         *textPtr += lstrlen((LPSTR)*textPtr);
         break;
      case Structure :
         strcat((LPSTR)*textPtr,structString);
         *textPtr += lstrlen((LPSTR)*textPtr);
         break;
      case Union_Type :
         strcat((LPSTR)*textPtr,unionString);
         *textPtr += lstrlen((LPSTR)*textPtr);
         break;
      case Enumeration :
         strcat((LPSTR)*textPtr,enumString);
         *textPtr += lstrlen((LPSTR)*textPtr);
         break;
      default:
         break;
   }
}
/***********************************************************************
**
**  ActiveVar :
**
*********************************************************************/
BOOLEAN PRIVATE ActiveVar(STRING *textPtr)  {


   if (varTable[varIndex].active)
      return TRUE;
   else  {
      HandleUnknownString(textPtr);
   }
   return FALSE;
}

/*************************************************************************
**
**  Get16IntValue :
**
**************************************************************************/
VOID PRIVATE Get16IntValue(STRING *textPtr,
                           LPU8 buffer,
                           DISPLAY_FORMAT dispValueRadix,
                           BOOLEAN dispValueEdit,
                           U8 *formatStr) {

   S16 *intPtr;
   VS_STRING_TYPE tempStr;

   intPtr = (S16 *)buffer;
   switch (dispValueRadix)  {
      case DF_NODISP :
         break;
      case DF_OCTAL :
         strcat((LPSTR)*textPtr,(LPSTR)octalOp);    /* o */
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case DF_DECIMAL :
         break;
      case DF_HEX :
         strcat((LPSTR)*textPtr,(LPSTR)hexOp);      /* 0x */
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case DF_ASCII :
         break;
      case DF_BINARY :
         break;
     default:
         break;
   }
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      sprintf((LPSTR)tempStr,(LPSTR)formatStr,*intPtr);
      strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
}

/*************************************************************************
**
**  Get32IntValue :
**
**************************************************************************/
VOID PRIVATE Get32IntValue(STRING *textPtr,
                         LPU8 buffer,
                         DISPLAY_FORMAT dispValueRadix,
                         BOOLEAN dispValueEdit,
                         U8 *formatStr) {

   S32 *intPtr;
   VS_STRING_TYPE tempStr;

   intPtr = (S32 *)buffer;
   switch (dispValueRadix)  {
      case DF_NODISP :
         break;
      case DF_OCTAL :
         strcat((LPSTR)*textPtr,(LPSTR)octalOp);    /* o */
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case DF_DECIMAL :
         break;
      case DF_HEX :
         strcat((LPSTR)*textPtr,(LPSTR)hexOp);      /* 0x */
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case DF_ASCII :
         break;
      case DF_BINARY :
         break;
     default:
         break;
   }
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      sprintf((LPSTR)tempStr,(LPSTR)formatStr,*intPtr);
      strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
}

/*************************************************************************
**
**  Get64IntValue :
**
**************************************************************************/
VOID PRIVATE Get64IntValue(STRING *textPtr,
                         LPU8 buffer,
                         DISPLAY_FORMAT dispValueRadix,
                         BOOLEAN dispValueEdit,
                         U8 *formatStr) {

   S32 *intPtr;
   VS_STRING_TYPE tempStr;

   intPtr = (S32 *)buffer;
   switch (dispValueRadix)  {
      case DF_NODISP :
         break;
      case DF_OCTAL :
         strcat((LPSTR)*textPtr,(LPSTR)octalOp);    /* o */
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case DF_DECIMAL :
         break;
      case DF_HEX :
         strcat((LPSTR)*textPtr,(LPSTR)hexOp);      /* 0x */
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case DF_ASCII :
         break;
      case DF_BINARY :
         break;
     default:
         break;
   }
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      sprintf((LPSTR)tempStr,(LPSTR)formatStr,*(intPtr+1));
      strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      sprintf((LPSTR)tempStr,(LPSTR)formatStr,*intPtr);
      strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
}

/*************************************************************************
**
**  GetCharValue :
**
**************************************************************************/
VOID GetCharValue(STRING *textPtr,
                  LPU8 buffer,
                  DISPLAY_FORMAT dispValueRadix,
                  BOOLEAN dispValueEdit,
                  U8 *formatStr) {

   U8 *charPtr;
   VS_STRING_TYPE tempStr;
   U32 printable = TRUE;
   BOOLEAN ascii = FALSE;


   charPtr = (U8 *)buffer;
   switch (dispValueRadix)  {
      case DF_NODISP :
         break;
      case DF_OCTAL :
         strcat((LPSTR)*textPtr,(LPSTR)octalOp);    /* o */
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case DF_DECIMAL :
         break;
      case DF_HEX :
         strcat((LPSTR)*textPtr,(LPSTR)hexOp);      /* 0x */
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      case DF_ASCII :
         printable = isprint(*charPtr);
         if (printable) {
            strcat((LPSTR)*textPtr,equalString);
            *textPtr += strlen((LPSTR)*textPtr);
            strcat((LPSTR)*textPtr,(LPSTR)singleQuote);      /* ' */
            *textPtr += strlen((LPSTR)*textPtr);
         }
         ascii = TRUE;
         break;
      case DF_BINARY :
         break;
     default:
         break;
   }
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      if (printable) {
         sprintf((LPSTR)tempStr,(LPSTR)formatStr,*charPtr);
         strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      }  /*
         **    don't print the ??? anymore for non printable chars.
         **      else
         **         strcat((LPSTR)*textPtr,(LPSTR)nonPrintableChar);
         */
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
   if (printable && ascii) {
      strcat((LPSTR)*textPtr,(LPSTR)singleQuote);      /* ' */
      *textPtr += strlen((LPSTR)*textPtr);

   }

}

/*************************************************************************
**
**  Get32FloatValue :
**
**************************************************************************/
VOID PRIVATE Get32FloatValue(STRING *textPtr,  /* formatted output buffer */
                             LPU8 buffer,  /* input buffer */
                             DISPLAY_FORMAT dispValueRadix,
                             BOOLEAN dispValueEdit,
                             U8 *formatStr) {

   U32 *intPtr;
   VS_STRING_TYPE tempStr;
   float fpValue;

   intPtr = (U32 *)buffer;
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      /* do any conversion necessary to display float */
      Float68To86(*intPtr, &fpValue);
      sprintf((LPSTR)tempStr,(LPSTR)formatStr,fpValue);
      /* cat to the result buffer */
      strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
}

/*************************************************************************
**
**  Get64FloatValue :
**
**************************************************************************/
VOID PRIVATE Get64FloatValue(STRING *textPtr,
                             LPU8 buffer,
                             DISPLAY_FORMAT dispValueRadix,
                             BOOLEAN dispValueEdit,
                             U8 *formatStr) {

   U8 *intPtr;  /* need byte pointer or Borland interprets wrong */
   VS_STRING_TYPE tempStr;
   double dValue;

   intPtr = (U8 *)buffer;
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      /* do any conversion necessary to format IEEE double */
      Double68To86(intPtr, &dValue);
      sprintf((LPSTR)tempStr,(LPSTR)formatStr,dValue);
      /* cat to result buffer */
      strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
}

/*************************************************************************
**
**  GetExtendedFloatValue :
**
**************************************************************************/
VOID PRIVATE GetExtendedFloatValue(STRING *textPtr,
                                   LPU8 buffer,
                                   DISPLAY_FORMAT dispValueRadix,
                                   BOOLEAN dispValueEdit,
                                   U8 *formatStr) {

   U8 *bPtr;  /* need byte pointer */
   VS_STRING_TYPE tempStr;
   long double ldValue;

   bPtr = (U8 *)buffer;
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      /* do any conversion necessary to format long double for display */
      LongDouble68To86(bPtr, &ldValue);
      sprintf((LPSTR)tempStr,(LPSTR)formatStr,ldValue);
      /* cat to result buffer */
      strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
}

/*************************************************************************
**
**  Get128FloatValue :
**
**************************************************************************/
VOID PRIVATE Get128FloatValue(STRING *textPtr,
                              LPU8 buffer,
                              DISPLAY_FORMAT dispValueRadix,
                              BOOLEAN dispValueEdit,
                              U8 *formatStr) {

#if 0
/* rather, just U8 *, since Borland doesn't support */
   long long double *LLDoublePtr;
#endif
   VS_STRING_TYPE tempStr;
   U8 *qPtr;  /* pointer to 128-bit value */
   long double qValue;  /* !! insufficient to represent in Borland */

#if 0
   LLDoublePtr = (long long double *)buffer;
#endif
   qPtr = (U8 *)TMalloc(16);
   qPtr = buffer;  /* pointer assign */
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
#if 0
      Quad68To86(buffer, &qValue);
/* note!! Borland printf formats don't support this type, need to treat
    as something else (magic needed here) */
#endif
      sprintf((LPSTR)tempStr,(LPSTR)formatStr,qValue);
      /* cat to result buffer */
      strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
}

/*************************************************************************
**
**  GetStringValue :
**
**************************************************************************/
VOID PRIVATE GetStringValue(STRING *textPtr,
                            LPU8 buffer,
                            DISPLAY_FORMAT dispValueRadix,
                            BOOLEAN dispValueEdit,
                            U8 *formatStr) {

   STRING strPtr;
   VS_STRING_TYPE tempStr;

   strPtr = (STRING)buffer;
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      sprintf((LPSTR)tempStr,(LPSTR)formatStr,*strPtr);
      strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
}

/*************************************************************************
**
**  GetPointerValue :
**
**************************************************************************/
VOID PRIVATE GetPointerValue(STRING *textPtr,
                             U32  pointerSize,
                             LPU8 buffer) {

   VS_STRING_TYPE tempStr;

   // NOTES: Nghia - 10/27/93
   // Handle both 2 bytes and 4 bytes pointer type
   if (pointerSize > 2) {
      U32 *value4BytePtr;
      value4BytePtr = (U32 *)buffer;
      sprintf((LPSTR)tempStr,"%lX",*value4BytePtr);
   } else {
      U16 *value2BytePtr;
      value2BytePtr = (U16 *)buffer;
      sprintf((LPSTR)tempStr,"%X",*value2BytePtr);
   }

   strcat((LPSTR)*textPtr,"0x");
   *textPtr += lstrlen((LPSTR)*textPtr);
   if (anotatedText) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   strcat((LPSTR)*textPtr,(LPSTR)tempStr);
   *textPtr += lstrlen((LPSTR)*textPtr);
   if (anotatedText) {
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
      *textPtr += lstrlen((LPSTR)*textPtr);
   }

}
/*************************************************************************
**
**  GetEnumValue :
**
**************************************************************************/
RETCODE PRIVATE GetEnumValue(STRING *textPtr,
                             LPU8 buffer,
                             TYPE_INDEX typeIndex) {
   U32 *enumValue;
   BOOLEAN noMatch;
   U8 enumName[VS_MAX_STRING];
   VS_STRING_TYPE typeName;
   TYPE_HEADER_TYPE typeInfo;
   RETCODE err;

   typeInfo.typeName = (LPSTR)typeName;
   if ((err = SymGetTypeHeader(typeIndex,&typeInfo)) != GOOD)
      return err;
   switch (typeInfo.sizeInMAUs) {
      case 1:   /* byte */
         Get16IntValue(textPtr,buffer,DF_HEX,TRUE,(U8 *)"%X");
         break;
      case 2:
         Get16IntValue(textPtr,buffer,DF_HEX,TRUE,(U8 *)"%X");
         break;
      case 4:
         Get32IntValue(textPtr,buffer,DF_HEX,TRUE,(U8 *)"%lX");
         break;
      default:
         Get32IntValue(textPtr,buffer,DF_HEX,TRUE,(U8 *)"%lX");
         break;
   }
   enumValue = (U32 *)buffer;
   if ((err = SymGetTypeEnumName(typeIndex,*enumValue,(LPSTR)&enumName,
         &noMatch)) != GOOD)
      return err;
   strcat((LPSTR)*textPtr,(LPSTR)equalString);
   if (noMatch) {
      strcat((LPSTR)*textPtr,"unknown enum");
   }
   else {
      strcat((LPSTR)*textPtr,(LPSTR)enumName);
   }
   *textPtr += strlen((LPSTR)*textPtr);
   return GOOD;

}

/***********************************************************************
**
**  GetCharSetForType :
**
**  Based on MRI IEEE 695 standards for built in types.
**
*********************************************************************/
VOID  PRIVATE GetCharSetForType(TYPE_SUBHEADER_TYPE *typeInfo,
                                DISPLAY_FORMAT radix)  {

   /* constructs the set of legal characters for this type, into the global
      buffer 'charSetBuf' */
   memset(&charSetBuf,'\0',sizeof(charSetBuf));
   if (typeInfo->typeChoice == SIMPLE_TYPE_CLASS) {
      switch (typeInfo->t.simpleType) {
         //case BI_S8_SCHAR: case BI_U8_UCHAR: case BI_S8_CHAR:
         case BI_char: case BI_signed_char: case BI_unsigned_char:
            /*
            ** signed and unsigned chars
            */
            switch (radix) {
               case DF_NODISP:  break;
/* shouldn't these be ripped out?  We don't support */
               case DF_BINARY:  break;
               case DF_OCTAL:   break;
/* end comment */
               case DF_DECIMAL: break;
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  break;
               case DF_ASCII:
                  strcat((LPSTR)charSetBuf,(LPSTR)upperCase);
                  strcat((LPSTR)charSetBuf,(LPSTR)lowerCase);
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)operators);
                  strcat((LPSTR)charSetBuf,(LPSTR)whiteSpace);
                  break;
/* these have no meaning for char types!! */
               case DF_FLOAT:   break;
               case DF_DOUBLE:  break;
            }
            break;
         //case BI_S16_SINT: case BI_STACK_INT: case BI_S16_SHORT:
         //case  BI_S16_SHORTINT: case BI_S16_SSHORT:
         case BI_short: case BI_signed_short:
            /*
            ** signed ints
            */
            switch (radix) {
               case DF_NODISP:  break;
               case DF_BINARY:  break;
               case DF_OCTAL:   break;
               case DF_DECIMAL:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)signedOps);
                  break;
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  break;
/* default case: error or just return? */
               case DF_ASCII:   break;
               case DF_FLOAT:   break;
               case DF_DOUBLE:  break;
            }
            break;
         //case BI_U16_UINT: case BI_STACK_U: case BI_STACK_UINT:
         //case BI_S16_USHORT:
         case BI_unsigned_short:
            /*
            ** unsigned ints
            */
            switch (radix) {
               case DF_NODISP:  break;
               case DF_BINARY:  break;
               case DF_OCTAL:   break;
               case DF_DECIMAL:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)unsignedOps);
                  break;
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  break;
               case DF_ASCII:   break;
               case DF_FLOAT:   break;
               case DF_DOUBLE:  break;
            }
            break;
         //case BI_S32_SLONG: case BI_S32_LONG:
         case BI_integer: case BI_signed_int: case BI_long:
         case BI_signed_long:
            /*
            ** signed long
            */
            switch (radix) {
               case DF_NODISP:  break;
               case DF_BINARY:  break;
               case DF_OCTAL:   break;
               case DF_DECIMAL:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)signedOps);
                  break;
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  break;
               case DF_ASCII:   break;
               case DF_FLOAT:   break;
               case DF_DOUBLE:  break;
            }
            break;
         //case BI_U32_ULONG:
         case BI_unsigned_int: case BI_unsigned_long:
            /*
            ** unsigned long
            */
            switch (radix) {
               case DF_NODISP:  break;
               case DF_BINARY:  break;
               case DF_OCTAL:   break;
               case DF_DECIMAL:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)unsignedOps);
                  break;
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  break;
               case DF_ASCII:   break;
               case DF_FLOAT:   break;
               case DF_DOUBLE:  break;
            }
            break;
         //case BI_S64_SLONG: case BI_U64_ULONG: case BI_F32: case BI_F64:
	 //case BI_F_EXTEND: case BI_F128: case BI_F64_BCD:
	 case BI_float://Hera 2/25/98
         case BI_dbl_prec_float: case BI_ext_prec_float:
            /*
            **  floats and doubles
            */
            switch (radix) {
               case DF_NODISP:  break;
               case DF_BINARY:  break;
               case DF_OCTAL:   break;
               case DF_DECIMAL: break;
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  break;
               case DF_ASCII:   break;
               case DF_FLOAT:
               case DF_DOUBLE:
/* we 'beep' on illegal characters entered, but we don't enforce legal
   type syntax at this level */
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)floatOps);
                  strcat((LPSTR)charSetBuf,(LPSTR)signedOps);
                  break;
            }
           break;
         /*  not used for 603e
         case BI_STRING:
            **
            **  strings
            **
            switch (radix) {
               case DF_NODISP:  break;
               case DF_BINARY:  break;
               case DF_OCTAL:   break;
               case DF_DECIMAL: break;
               case DF_HEX:     break;
               case DF_ASCII:
                  strcat((LPSTR)charSetBuf,(LPSTR)lowerCase);
                  strcat((LPSTR)charSetBuf,(LPSTR)upperCase);
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)operators);
                  strcat((LPSTR)charSetBuf,(LPSTR)whiteSpace);
                  break;
               case DF_FLOAT:   break;
               case DF_DOUBLE:  break;
            }
           break;
         */
         case BI_pointer:
         case BI_ptr_char:    case BI_ptr_signed_char:  case BI_ptr_unsigned_char:
         case BI_ptr_short:   case BI_ptr_signed_short: case BI_ptr_unsigned_short:
         case BI_ptr_integer: case BI_ptr_signed_int:   case BI_ptr_unsigned_int:
         case BI_ptr_long:    case BI_ptr_signed_long:  case BI_ptr_unsigned_long:
         case BI_ptr_pointer: case BI_ptr_float:
         case BI_ptr_dbl_prec_float:   case BI_ptr_ext_prec_float: case BI_ptr_complex:
         case BI_ptr_dbl_prec_complex: case BI_ptr_void:           case BI_ptr_boolean:
         case BI_ptr_ext_prec_complex: case BI_ptr_lable:
            /*
            **  pointers
            */
            strcat((LPSTR)charSetBuf,(LPSTR)digits);
            strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
            strcat((LPSTR)charSetBuf,(LPSTR)pointerOps);
            break;
         default:
            break;
      }
   }
   else {
      switch (typeInfo->t.complexType) {
         case Reference://Hera 2/27/98
         case Pointer:
            /*
            **  pointers
            */
            strcat((LPSTR)charSetBuf,(LPSTR)digits);
            strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
            strcat((LPSTR)charSetBuf,(LPSTR)pointerOps);
            break;
         case Enumeration:
           switch (radix) {
               case DF_NODISP:  break;
               case DF_BINARY:  break;
               case DF_OCTAL:   break;
               case DF_DECIMAL:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  break;
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  break;
               case DF_ASCII:   break;
               case DF_FLOAT:   break;
               case DF_DOUBLE:  break;
            }
            break;
         default:
            break;
      }
   }
}

/************************************************************************
**
**  GetCharSetBuf :
**
**  This routine determines the field width and the legal char set for
**  editting values.
**
*************************************************************************/
RETCODE  GetCharSetBuf(DESCRIPTOR varId,
                       DESCRIPTOR bufferNum,
		       U32 lineNum,
                       U16 *fieldWidth,
                       U16 startCol) {

   VS_COMPONENT_TYPE *compPtr;
   VS_VAR_ENTRY_TYPE *varPtr;
   TYPE_SUBHEADER_TYPE *baseTypeInfo;
   VS_DISPLAY_PTR displayBufPtr;
   STRING textPtr, tmpPtr;
   LOOP_VAR i;
   BOOLEAN primaryEditField;
   U32 byteOffset;
   U16 memberIndex;
   ARRAY_LIST_NODE *arrayNode;
   RETCODE retcode;
   TYPE_SUBHEADER_TYPE typeInfo;
   TYPE_INDEX typeIndex;


#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   /*
   **  Determine which edit field has been selected for editting
   */
   if ((retcode = GetVSdispBuf(varId,bufferNum,0,&displayBufPtr)) != GOOD)
      return retcode;
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   textPtr = displayBufPtr->text;
   /*
   ** find the same line
   */
   for (i=0; i != lineNum; i++) {
      while (*textPtr != '\n')
         textPtr++;
      textPtr++;     /* skip over newline */
   }
   /*
   **  look for the first edit field mark
   */
   tmpPtr = textPtr + startCol;
   while (*textPtr != EDIT_FIELD_MARK)
      textPtr++; 
   /*
   ** determine which edit field it is, primary or secondary
   ** (Modified by Ron, 5/12/93, during Var. Window Enhancements)
   */
   /* if (strncmp((LPSTR)textPtr,(LPSTR)charSetBuf,*fieldWidth) == GOOD) */
   if (tmpPtr == textPtr)
      primaryEditField = TRUE;
   else
      primaryEditField = FALSE;

   FreeVSBuf(displayBufPtr);
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   varPtr = &varTable[varId];
   GetNthComponent(varId,bufferNum,lineNum,&compPtr);
   if (compPtr != NULL) {     /* a component variable */
      /*
      ** We have a component match so now get the legal char set into
      ** a global buffer, charSetBuf.
      */
      typeIndex =  compPtr->typeInfo.typeIndex;
      memmove(&typeInfo,&compPtr->typeInfo,sizeof(typeInfo));
      typeInfo.typeName = (LPSTR)typeInfo.typeNameStr;

      if ((typeInfo.typeChoice == COMPLEX_TYPE_CLASS) &&
            (typeInfo.t.complexType == Typedef)) {
         while (typeInfo.t.complexType == Typedef) {
            if ((retcode = SymGetTypeTypeIndex(typeIndex,&typeIndex)) != GOOD)
               return retcode;
            if ((retcode = SymGetTypeHeader(typeIndex,
                  (TYPE_HEADER_TYPE *)&typeInfo)) != GOOD)
               return retcode;
            typeInfo.typeIndex = typeIndex;
         }
      }
      if (typeInfo.typeChoice == COMPLEX_TYPE_CLASS) {
         if ((typeInfo.t.complexType == Pointer) ||
                (typeInfo.t.complexType == Reference/*Hera 2/27/98*/)) {
             GetCharSetForType(&typeInfo,DF_HEX);
	     switch(typeInfo.t.complexType) {
                case Reference://Hera 2/27/98
                case Pointer :
                   *fieldWidth = EDIT_SMALL_PTR_DEFAULT;
                   break;
                default:
                   /* Include TY_LARGE_PTR */
                   *fieldWidth = EDIT_LARGE_PTR_DEFAULT;
             }
         }
         else if (typeInfo.t.complexType == Enumeration)  {
            GetCharSetForType(&typeInfo,DF_HEX);
            *fieldWidth = typeInfo.size * HEX_DIGITS_PER_BYTE;
         }
      }
      else if (typeInfo.typeChoice == SIMPLE_TYPE_CLASS) {
         if (primaryEditField) {
            GetCharSetForType(&typeInfo,typeTable[typeInfo.t.simpleType]
                  .primaryRadix);
            *fieldWidth = typeTable[typeInfo.t.simpleType].
                  primaryEditFieldSize;
         }
         else {
            GetCharSetForType(&typeInfo,typeTable[typeInfo.t.simpleType]
                  .secondaryRadix);
            *fieldWidth = typeTable[typeInfo.t.simpleType].
                  secondaryEditFieldSize;
         }
      }
   }
   else {
      /*
      ** Pointers, enums,typedefs, and arrays of editable types are the only
      ** complex type that have editable values.
      ** Intel format XXXX:YYYY allows 9 characters max for pointers.
      ** Motorola format XXXXXXXX allows 8 characters max for pointers.
      ** Use base type for arrays. An array of structures must map
      ** the lineNum to the component of the array to determine the
      ** legal char set of the component.
      */
      typeIndex =  varPtr->typeInfo.typeIndex;
      memmove(&typeInfo,&varPtr->typeInfo,sizeof(typeInfo));
      typeInfo.typeName = (LPSTR)typeInfo.typeNameStr;

      if ((typeInfo.typeChoice == COMPLEX_TYPE_CLASS) &&
            (typeInfo.t.complexType == Typedef)) {
         while (typeInfo.t.complexType == Typedef) {
            if ((retcode = SymGetTypeTypeIndex(typeIndex,&typeIndex))
                  != GOOD)
               return retcode;
            if ((retcode = SymGetTypeHeader(typeIndex,
                  (TYPE_HEADER_TYPE *)&typeInfo)) != GOOD)
               return retcode;
            typeInfo.typeIndex = typeIndex;
         }
      }
      if (typeInfo.typeChoice == COMPLEX_TYPE_CLASS) {
         if ((typeInfo.t.complexType == Pointer) ||
                (typeInfo.t.complexType == Reference/*Hera 2/27/98*/)) {
             GetCharSetForType(&typeInfo,DF_HEX);
	     switch(typeInfo.t.complexType) {
                case Reference://Hera 2/27/98
                case Pointer :
                   *fieldWidth = EDIT_SMALL_PTR_DEFAULT;
                   break;
                default:
                   /* Include TY_LARGE_PTR */
                   *fieldWidth = EDIT_LARGE_PTR_DEFAULT;
             }
         }
         else if (typeInfo.t.complexType == Enumeration)  {
            GetCharSetForType(&typeInfo,DF_HEX);
            *fieldWidth = typeInfo.size * HEX_DIGITS_PER_BYTE;
         }
         else {  /* must be an array type */
            GetSubArrayType(&typeInfo,&baseTypeInfo);
            if (baseTypeInfo->typeChoice == SIMPLE_TYPE_CLASS)  {
               if (primaryEditField) {
                  GetCharSetForType(baseTypeInfo,typeTable[baseTypeInfo->t.
                        simpleType].primaryRadix);
                  *fieldWidth = typeTable[baseTypeInfo->t.simpleType].
                        primaryEditFieldSize;
               }
               else {
                  GetCharSetForType(baseTypeInfo,typeTable[baseTypeInfo->t.
                        simpleType].secondaryRadix);
                  *fieldWidth = typeTable[baseTypeInfo->t.simpleType].
                        secondaryEditFieldSize;
               }
            }
            else { /* an array of a complex editable type */
               if ((baseTypeInfo->t.complexType == Pointer) ||
                     (baseTypeInfo->t.complexType == Reference/*Hera 2/27/98*/)) {
                  GetCharSetForType(baseTypeInfo,0);
		  switch(baseTypeInfo->t.complexType) {
                     case Reference://Hera 2/27/98
                     case Pointer :
                        *fieldWidth = EDIT_SMALL_PTR_DEFAULT;
                        break;
                     default:
                        /* Include TY_LARGE_PTR */
                        *fieldWidth = EDIT_LARGE_PTR_DEFAULT;
                  }
               } else if (baseTypeInfo->t.complexType == Enumeration)  {
                  GetCharSetForType(baseTypeInfo,DF_HEX);
                  *fieldWidth = baseTypeInfo->size * HEX_DIGITS_PER_BYTE;
               } else if (varPtr->compListPtr != NULL) {
                  if ((retcode = MapArrayLine2Offset(&typeInfo,
                        ((bufferNum * VS_MAX_BUFFER_LINES) + lineNum),0,
                        &byteOffset,&memberIndex,&typeIndex,&arrayNode,
                        NULL)) != GOOD)
                     return retcode;
                  compPtr = varPtr->compListPtr;
                  for (i=0; i != memberIndex;i++)
                     compPtr = compPtr->next;
                  if ((compPtr->typeInfo.t.complexType == Pointer) ||
                        (compPtr->typeInfo.t.complexType == Reference/*Hera 2/27/98*/)) {
                     GetCharSetForType(&compPtr->typeInfo,0);
		     switch(compPtr->typeInfo.t.complexType) {
                        case Reference://Hera 2/27/98
                        case Pointer :
                           *fieldWidth = EDIT_SMALL_PTR_DEFAULT;
                           break;
                        default:
                           /* Include TY_LARGE_PTR */
                           *fieldWidth = EDIT_LARGE_PTR_DEFAULT;
                     }
                     
                  } else {
                     if (primaryEditField) {
                        GetCharSetForType(&compPtr->typeInfo,typeTable[compPtr->
                              typeInfo.t.simpleType].primaryRadix);
                        *fieldWidth = typeTable[compPtr->typeInfo.t.simpleType].
                              primaryEditFieldSize;
                     } else {
                        GetCharSetForType(&compPtr->typeInfo,typeTable[compPtr->
                              typeInfo.t.simpleType].secondaryRadix);
                        *fieldWidth = typeTable[compPtr->typeInfo.t.simpleType].
                              secondaryEditFieldSize;
                     }
                  }
               }  /* else if compPtr == NULL? */
            }
         }
      }
      else {   /* a simple type */
         baseTypeInfo = &typeInfo;
         if (primaryEditField) {
            GetCharSetForType(baseTypeInfo,typeTable[baseTypeInfo->t.
                  simpleType].primaryRadix);
            *fieldWidth = typeTable[baseTypeInfo->t.simpleType].
                  primaryEditFieldSize;
         }
         else {
            GetCharSetForType(baseTypeInfo,typeTable[baseTypeInfo->t.
                  simpleType].secondaryRadix);
            *fieldWidth = typeTable[baseTypeInfo->t.simpleType].
                  secondaryEditFieldSize;
         }
      }
   }
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   return GOOD;
}

/************************************************************************
**
**  EditValueField :
**
**  This routine attempts to convert the editted text to HEX and store
**  it in memory.
**
*************************************************************************/
RETCODE  EditValueField(DESCRIPTOR varId,
                        DESCRIPTOR bufferNum,
                        U32 lineNum,
                        U16 editFieldCharOffset,
                        LPSTR newValueText,
                        VS_DISPLAY_PTR *displayBufPtr)  {
   RETCODE retcode;
   STRING textPtr,searchPtr;
   U8 editMarkCount = 0;
   TYPE_INDEX typeIndex;
   GET_VAR_ADDR_STRUCT *addr;
   LOOP_VAR i;
   WRITE_DESTINATION_TYPE writeType;
   BOOLEAN savedFlag;
   BOOLEAN isUnionEdit = FALSE;

   /*
   **  It is easier to find the edit field when the buffer is
   **  anotated.  Get an anotated display buffer regardless of
   **  user mode.  Save and restore original user mode.
   */
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   savedFlag = varTable[varId].interActive;
   varTable[varId].interActive = TRUE;
   if ((retcode = GetVSdispBuf(varId,bufferNum,varTable[varId].frameNum,
         displayBufPtr)) != GOOD)
      return retcode;
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   varTable[varId].interActive = savedFlag;
   textPtr = (*displayBufPtr)->text;
   /*
   ** find the same line
   */
   for (i=0; i != lineNum; i++) {
      while (*textPtr != '\n')
         textPtr++;
      textPtr++;     /* skip over newline */
   }
   /*
   **  if we don't know the editFieldCharOffset then look
   **  for the first edit field mark. The request most likely
   **  came from the CLI.  If we can't find the EDIT_FIELD_MARK
   **  there is a problem with the display buffer of the variable
   **  and it most likely does not have an edittable value. So just
   **  return an error in that case.
   */
   if (editFieldCharOffset == 0) {
      while ((*(textPtr + editFieldCharOffset) != EDIT_FIELD_MARK) &&
            (*(textPtr + editFieldCharOffset) != '\n') &&
            (*(textPtr + editFieldCharOffset) != '\0'))
         editFieldCharOffset++;
      if (*(textPtr + editFieldCharOffset) != EDIT_FIELD_MARK) {
         /*
         ** we didn't find the marker so return an error
         */
         retcode = ER_VS_VALU_EDIT_FAIL;
         goto CLEANUP;
      }
      else
         editFieldCharOffset++;   /* offset is to the actual editable char */

   }
   /*
   ** determine which edit field it is, primary or secondary
   */
   searchPtr = textPtr;
   while (textPtr != (searchPtr + editFieldCharOffset - 1)) {
      if (*textPtr == EDIT_FIELD_MARK)
         editMarkCount++;
      textPtr++;
   }
   if (*textPtr == EDIT_FIELD_MARK)
      editMarkCount++;
   if (editMarkCount == 0) { /* WHAT?? No Edit Marks?? For Shame!! */
      retcode = ER_VS_INVALID_EDITFIELDCHAROFFSET;
      goto CLEANUP;
   }
   /*
   ** now string compare the original value with newValueText
   ** if the same then no change otherwise write memory
   */
   searchPtr = textPtr;
   while (*searchPtr != END_EDIT_MARK)
      searchPtr++;
   if ((strncmp((LPSTR)textPtr,(LPSTR)newValueText,(searchPtr-textPtr))
         == GOOD) &&
         ((strlen((LPSTR)newValueText) - 1) == (searchPtr-textPtr))) {
      return GOOD;
   }
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   if ((retcode = GetVarTypeAndAddr(varId,bufferNum,lineNum,&typeIndex, 
         &addr,&isUnionEdit)) != GOOD) {
      goto CLEANUP;
   }
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   if (varTable[varId].registerClass == NOT_REG) {
      if (varTable[varId].storageClass == AUTO_VAR_CLASS)
         writeType = STACK_WRITE;
      else
         writeType = MEM_WRITE;
   }
   else
      writeType = REG_WRITE;
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   if ((retcode = ConvTextAndWriteMem(varId,newValueText,typeIndex,addr,
         editMarkCount,writeType)) != GOOD)
      goto CLEANUP;
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   if ((retcode = UpdateChildVars(varId,lineNum,bufferNum,typeIndex,
         addr,isUnionEdit)) != GOOD)
      goto CLEANUP;
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   /*
   **  get new display buffer based on new memory value but first
   **  remember to deallocate the one we already have.
   **  If we just finished editting an array of simple type then
   **  be sure to deallocate the temporary address structure used
   **  to access the individual elements.
   */
   if (elementAddr != NULL) {
      if (writeType == MEM_WRITE) {
         if ((retcode = AdrDestroyAddress(elementAddr->getFixedAddrDesc))
               != GOOD)
            return retcode;
      }
      if ((retcode = TFree((LPSTR)elementAddr)) != GOOD)
         return retcode;
      elementAddr = NULL;
   }
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   FreeVSBuf(*displayBufPtr);
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   return(GetVSdispBuf(varId,bufferNum,varTable[varId].frameNum,
         displayBufPtr));

CLEANUP:
   FreeVSBuf(*displayBufPtr);
#ifdef DEBUG_MEM_LEAKS
   HeapDump(&memAlloced,&memFreed);
#endif
   return retcode;
}

/***********************************************************************
**
**  ConvertTextAndWriteMem :
**
**  This routine converts ascii strings based on different formats for
**  different types and writes the values to memory.
**
************************************************************************/
RETCODE PRIVATE ConvTextAndWriteMem(DESCRIPTOR varId,
                                    LPSTR newValueText,
                                    TYPE_INDEX typeIndex,
                                    GET_VAR_ADDR_STRUCT *addr,
                                    U8 editMarkCount,
                                    WRITE_DESTINATION_TYPE writeType)  {
   U32 ptrValue = 0;
   U8 *byteStream;
   LPU8 valueText,memBuf;
   STRING formatStr,valuePtr,searchPtr;
   TYPE_HEADER_TYPE typeInfo;
   VS_STRING_TYPE typeName;
   RETCODE error,retcode;
   int strCount; /* used to capture the return value of sscanf */

   retcode = GOOD;
   typeInfo.typeName = (LPSTR)typeName;
   if ((valueText = (LPU8)TMalloc(VS_MAX_STRING)) == NULL)
      return ER_OUT_OF_MEMORY;
   if ((writeType == MEM_WRITE) || (writeType == STACK_WRITE)) {
      if ((memBuf = (LPU8)TMalloc(VS_MAX_STRING)) == NULL)
         return ER_OUT_OF_MEMORY;
   }
   /*
   **  Strip out the encoding markers from newValueText
   **  and then convert based on type formats
   */
   valuePtr = (STRING)valueText;
   memset(valueText,'\0',VS_MAX_STRING);
   if (varTable[varId].interActive) {  /* anotated text */
      searchPtr = (STRING)newValueText;
      while (*searchPtr != END_EDIT_MARK) {
         if (*searchPtr == EDIT_FIELD_MARK)
            searchPtr++;
         else {
            *valuePtr = *searchPtr;
            valuePtr++;
            searchPtr++;
         }
      }
   }
   else
      lstrcpy((LPSTR)valueText,newValueText);
   if (typeIndex < VS_MAX_TYPE_TABLE) {
      if ((formatStr = GetFormatString(editMarkCount,typeIndex)) == NULL) {
         retcode = ER_VS_VALU_EDIT_FAIL;
         goto CLEANUP;
      }
   }
   else {
      if ((varTable[varId].typeInfo.t.complexType == Pointer) ||
            (varTable[varId].typeInfo.t.complexType == Reference/*Hera 2/27/98*/)) {
         if ((retcode = SymGetTypeHeader(typeIndex,&typeInfo)) != GOOD)
            goto CLEANUP;
         /* Some type of pointer value or enum  */
         sscanf((LPSTR)valueText,"%lX",&ptrValue);
         byteStream = (U8 *)&ptrValue;

         // NOTES: Nghia - 10/27/93
         // Handling SMALL/LARGE pointer type using their sizeInMAUs.
         if (writeType != REG_WRITE) 
            FlipBuffer(byteStream, typeInfo.sizeInMAUs);
         
         switch (writeType) {
            case STACK_WRITE:
               memmove(memBuf, &ptrValue, typeInfo.sizeInMAUs);
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                            typeInfo.sizeInMAUs,
                            varTable[varId].frameNum,
                            varTable[varId].frameType,memBuf) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
              if ((retcode = SetAddrSpace(addr->getFixedAddrDesc)) != GOOD)
                  goto CLEANUP;
               memmove(memBuf, &ptrValue, typeInfo.sizeInMAUs);
               if (MemWriteSized(addr->getFixedAddrDesc,
                                 typeInfo.sizeInMAUs,
                                 memBuf,
                                 SIZE_BYTE) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
	    case REG_WRITE:
               //Hera 12/30/97
               if (CpuSetStockRegister(addr->addrData.getRegisterIndex.
                     varLivingReg,ptrValue) != GOOD)  {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
	       }
	       /*if (SetReg(addr->addrData.getRegisterIndex.
                                        varLivingReg,ptrValue) != GOOD)  {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
	       }*/
               //Hera
               break;
         }
         retcode = GOOD;
         goto CLEANUP;
      }
      else {
         /*
         **  must be an enum
         */
         U8 enumByte;
         U16 enumShort;
         U32 enumInt;
         U32 enumValue;

         if ((retcode = SymGetTypeHeader(typeIndex,&typeInfo)) != GOOD)
            goto CLEANUP;
         switch (typeInfo.sizeInMAUs) {
            case 1:  /* byte */
               sscanf((LPSTR)valueText,"%x",&enumByte);
               enumValue = enumByte;
               break;
            case 2:
               sscanf((LPSTR)valueText,"%x",&enumShort);
               byteStream = (U8 *)&enumShort;
               if (writeType != REG_WRITE) FlipBuffer(byteStream,2);
               enumValue = enumShort;
               break;
            case 4:
               sscanf((LPSTR)valueText,"%lX",&enumInt);
               byteStream = (U8 *)&enumInt;
               if (writeType != REG_WRITE) FlipBuffer(byteStream,4);
               enumValue = enumInt;
               break;
            default:
               retcode = ER_VS_VALU_EDIT_FAIL;
               goto CLEANUP;
         }
         switch (writeType) {
            case STACK_WRITE:
               memmove(memBuf,&enumValue,typeInfo.sizeInMAUs);
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                    typeInfo.sizeInMAUs,varTable[varId].frameNum,
                    varTable[varId].frameType,memBuf) != GOOD)   {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               if ((retcode = SetAddrSpace(addr->getFixedAddrDesc)) != GOOD)
                  goto CLEANUP;
               memmove(memBuf,&enumValue,typeInfo.sizeInMAUs);
               if (MemWriteSized(addr->getFixedAddrDesc,typeInfo.sizeInMAUs,
                     memBuf,SIZE_BYTE) != GOOD)  {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
	    case REG_WRITE:
               //Hera 12/30/97
               if (CpuSetStockRegister(addr->addrData.getRegisterIndex.
                     varLivingReg,enumValue) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
	       }
	       /*if (SetReg(addr->addrData.getRegisterIndex.
                     varLivingReg,enumValue) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
	       }*/
               //Hera
               break;
         }
         retcode = GOOD;
         goto CLEANUP;
      }
   }
   switch(typeIndex) {
      //case BI_S8_SCHAR: case BI_U8_UCHAR: case BI_S8_CHAR: {    /* 8 bits */
      case BI_char: case BI_signed_char: case BI_unsigned_char: {
         S8 tempS8 = 0;
         sscanf((LPSTR)valueText,(LPSTR)formatStr,&tempS8);
         switch (writeType) {
            case STACK_WRITE:
               memmove(memBuf,&tempS8,sizeof(tempS8));
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                     sizeof(tempS8),varTable[varId].frameNum,
                     varTable[varId].frameType,memBuf) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               if ((retcode = SetAddrSpace(addr->getFixedAddrDesc)) != GOOD)
                  goto CLEANUP;
               memmove(memBuf,&tempS8,sizeof(tempS8));
               if (MemWriteSized(addr->getFixedAddrDesc,sizeof(tempS8),
                     memBuf,SIZE_BYTE) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
	    case REG_WRITE:
               //Hera 12/30/97
               if (CpuSetStockRegister(addr->addrData.getRegisterIndex.
                     varLivingReg,(U32)tempS8) != GOOD)  {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
	       }
	       /*if (SetReg(addr->addrData.getRegisterIndex.
                     varLivingReg,(U32)tempS8) != GOOD)  {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
	       }*/
               //Hera
               break;
         }
         break;
      }
      //case BI_S16_SINT: case  BI_U16_UINT: case BI_S16_SHORT:
      //case BI_S16_USHORT: case BI_S16_SHORTINT:   /* 16 bits */
      //case BI_S16_SSHORT:  {
      case BI_short: case BI_signed_short: case BI_unsigned_short: {
         S16 tempS16 = 0;
         /* marked because BI_U16_UINT and BI_S16_USHORT
         if ((retcode = CheckForIntegerOverflow(varId, newValueText, 16, 
               (typeIndex != BI_U16_UINT && typeIndex != BI_S16_USHORT))) != GOOD) {
            goto CLEANUP;
         }
         */
         strCount = sscanf((LPSTR)valueText,(LPSTR)formatStr,&tempS16);
         if (strCount != 1) {
            retcode = ER_VS_VALU_EDIT_FAIL;
            goto CLEANUP;
         }
         byteStream = (U8 *)&tempS16;
         if (writeType != REG_WRITE) FlipBuffer(byteStream,2);
         switch (writeType) {
            case STACK_WRITE:
               memmove(memBuf,&tempS16,sizeof(tempS16));
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                     sizeof(tempS16),varTable[varId].frameNum,
                     varTable[varId].frameType,memBuf) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               if ((retcode = SetAddrSpace(addr->getFixedAddrDesc)) != GOOD)
                  goto CLEANUP;
               memmove(memBuf,&tempS16,sizeof(tempS16));
               if (MemWriteSized(addr->getFixedAddrDesc,sizeof(tempS16),
                     memBuf,SIZE_BYTE) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
	    case REG_WRITE:
               //Hera 12/30/97
               if (CpuSetStockRegister(addr->addrData.getRegisterIndex.
                     varLivingReg,(U32)tempS16) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
	       }
	       /*if (SetReg(addr->addrData.getRegisterIndex.
                     varLivingReg,(U32)tempS16) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
	       }*/
               //Hera
               break;
         }
         break;
      }
      //case BI_S32_SLONG: case BI_U32_ULONG: case BI_F32: case BI_STACK_INT:
      //case BI_STACK_U: case BI_STACK_UINT: case BI_S32_LONG: { /* 32 bits */
      case BI_float: //Hera 2/25/98
      case BI_integer: case BI_signed_int: case BI_unsigned_int:
      case BI_long: case BI_signed_long: case BI_unsigned_long: {
         S32 tempS32 = 0;
         /*  marked because BI_U32_ULONG and BI_STACK_UINT and BI_STACK_U
         if ((retcode = CheckForIntegerOverflow(varId, newValueText, 32, 
               (typeIndex != BI_U32_ULONG && typeIndex != BI_STACK_UINT &&
               typeIndex != BI_STACK_U))) != GOOD) {
            goto CLEANUP;
         }
         */
         strCount = sscanf((LPSTR)valueText,(LPSTR)formatStr,&tempS32);
         if (strCount != 1) {
            retcode = ER_VS_VALU_EDIT_FAIL;
            goto CLEANUP;
         }
         byteStream = (U8 *)&tempS32;
         if (writeType != REG_WRITE) FlipBuffer(byteStream,4);
         switch (writeType) {
            case STACK_WRITE:
               memmove(memBuf,&tempS32,sizeof(tempS32));
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                     sizeof(tempS32),varTable[varId].frameNum,
                     varTable[varId].frameType,memBuf) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               if ((retcode = SetAddrSpace(addr->getFixedAddrDesc)) != GOOD)
                  goto CLEANUP;
               memmove(memBuf,&tempS32,sizeof(tempS32));
               if (MemWriteSized(addr->getFixedAddrDesc,sizeof(tempS32),
                     memBuf,SIZE_BYTE) != GOOD)   {
                   retcode = ER_VS_VALU_EDIT_FAIL;
                   goto CLEANUP;
               }
               break;
	    case REG_WRITE:
              //Hera 12/29/97
              //if ((LdrToolSelect(&toolch) == GOOD) && (toolch == 2)) {
              //if (SetReg(addr->addrData.getRegisterIndex.
              //         varLivingReg,(U32)tempS32) != GOOD) {
              //      retcode = ER_VS_VALU_EDIT_FAIL;
              //      goto CLEANUP;
              //   }
              //} else {
              if (CpuSetStockRegister(addr->addrData.getRegisterIndex.
                      varLivingReg,(U32)tempS32) != GOOD) {
                    retcode = ER_VS_VALU_EDIT_FAIL;
                    goto CLEANUP;
              }
	      //}
              //Hera
               break;
         }
         break;
      }
      //case BI_S64_SLONG: case BI_U64_ULONG: case BI_F64: case BI_F64_BCD:  {       /* 64 bits */
      case BI_dbl_prec_float: case BI_ext_prec_float: {
         double aDouble;

         sscanf((LPSTR)valueText, (LPSTR)formatStr, &aDouble);
         byteStream = (U8 *)&aDouble;
         if (writeType != REG_WRITE) FlipBuffer(byteStream,8);
         switch (writeType) {
            case STACK_WRITE:
               /* call to stack write ultimately calls the memory server,
                  which will want to free the buffer.  Hence we have to
                  incur yet another data copy. */
               memcpy(memBuf, byteStream, sizeof(double));
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                     sizeof(double), varTable[varId].frameNum,
                     varTable[varId].frameType, memBuf) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
              /* ah, the good old consumer/producer problem.  We are
                 required to create a buffer to pass to the memory call,
                 since the mem server will always want to free it. */
              if ((retcode = SetAddrSpace(addr->getFixedAddrDesc)) != GOOD)
                 goto CLEANUP;
              memcpy(memBuf, byteStream, sizeof(double));
              if (MemWriteSized(addr->getFixedAddrDesc, sizeof(double),
                  memBuf, SIZE_BYTE) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case REG_WRITE:
               /*
               **   !!!! won't fit into single register
               **        what to do here ????
               **   if ((CPuSetRegister(addr->addrData.getRegisterIndex.
               **        varLivingReg,(U32)tempL)) != GOOD)
               **     return ER_VS_VALU_EDIT_FAIL;
               */
               retcode = ER_VS_DOUBLE_EDIT_FAIL;
               goto CLEANUP;
         }
         break;
      }
      /*
      case BI_F_EXTEND: case BI_F128:  {             ** 128 bits **
         double tempD = 0;
         sscanf((LPSTR)valueText,(LPSTR)formatStr,&tempD);
         switch (writeType) {
            case STACK_WRITE:
               memmove(memBuf,&tempD,sizeof(tempD));
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                     sizeof(tempD),varTable[varId].frameNum,
                     varTable[varId].frameType,memBuf) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
	       }
               break;
            case MEM_WRITE:
              if ((retcode = SetAddrSpace(addr->getFixedAddrDesc)) != GOOD)
                 goto CLEANUP;
               memmove(memBuf,&tempD,sizeof(tempD));
               if (MemWriteSized(addr->getFixedAddrDesc,sizeof(tempD),
                     memBuf,SIZE_BYTE) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case REG_WRITE:
               **
               **   !!!! won't fit into single register
               **        what to do here ????
	       **  if ((CpuSetRegister(processor,addr->addrData.getRegisterIndex.
               **        varLivingReg,(U32)tempD)) != GOOD)
               **     return ER_VS_VALU_EDIT_FAIL;
               **
               retcode = ER_VS_DOUBLE_EDIT_FAIL;
               goto CLEANUP;
         }
         break;
      }
      case BI_STRING: {          ** strings **
         U8 tempStr[VS_MAX_STRING];
         sscanf((LPSTR)valueText,(LPSTR)formatStr,tempStr);
         switch (writeType) {
            case STACK_WRITE:
               memmove(memBuf,tempStr,VS_MAX_STRING);
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                     sizeof(tempStr),varTable[varId].frameNum,
                     varTable[varId].frameType,memBuf) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               if ((retcode = SetAddrSpace(addr->getFixedAddrDesc)) != GOOD)
                  goto CLEANUP;
               memmove(memBuf,tempStr,VS_MAX_STRING);
               if(MemWriteSized(addr->getFixedAddrDesc,strlen((LPSTR)tempStr),
                     memBuf,SIZE_BYTE) != GOOD) {
                  retcode = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case REG_WRITE:
               break;
         }
         break;
      }
      */
   }

CLEANUP:
   if ((error = TFree((LPSTR)valueText)) != GOOD)
      return error;
   return retcode;
}

/************************************************************************
**
**  GetVarTypeAndAddr :
**
**  Given a variable id, buffernum, and linenum, find the relevant type
**  information and address.
**
************************************************************************/
RETCODE PRIVATE  GetVarTypeAndAddr(DESCRIPTOR varId,
                                DESCRIPTOR bufferNum,
                                U32 lineNum,
                                TYPE_INDEX *typeIndex,
                                GET_VAR_ADDR_STRUCT **addr,
                                BOOLEAN *unionEdit) {

   VS_COMPONENT_TYPE *compPtr;
   TYPE_SUBHEADER_TYPE *baseTypeInfo;
   U32 byteOffset;
   S32 autoOffset;
   U16 memberIndex;
   ARRAY_LIST_NODE *arrayNode;
   LOOP_VAR i;
   RETCODE retcode;
   TYPE_SUBHEADER_TYPE typeInfo;
   TYPE_INDEX typedefTypeIndex;

   *unionEdit = FALSE;
   GetNthComponent(varId,bufferNum,lineNum,&compPtr);
   if (compPtr != NULL) {   /* component variable */
      /*
      ** you can only edit simple types and pointers within
      ** a component type variable
      */
      typedefTypeIndex =  compPtr->typeInfo.typeIndex;
      memmove(&typeInfo,&compPtr->typeInfo,sizeof(typeInfo));
      typeInfo.typeName = (LPSTR)typeInfo.typeNameStr;

      if ((typeInfo.typeChoice == COMPLEX_TYPE_CLASS) &&
            (typeInfo.t.complexType == Typedef)) {
         while (typeInfo.t.complexType == Typedef) {
            if ((retcode = SymGetTypeTypeIndex(typedefTypeIndex,
		  &typedefTypeIndex)) != GOOD)
               return retcode;
            if ((retcode = SymGetTypeHeader(typedefTypeIndex,
                  (TYPE_HEADER_TYPE *)&typeInfo)) != GOOD)
               return retcode;
            typeInfo.typeIndex = typedefTypeIndex;
         }
      }
      *typeIndex = typeInfo.typeIndex;
      if ((elementAddr = (GET_VAR_ADDR_STRUCT *)TMalloc(sizeof
            (GET_VAR_ADDR_STRUCT))) == NULL)
         return ER_OUT_OF_MEMORY;
      if (varTable[varId].registerClass == NOT_REG) {
         if (varTable[varId].storageClass == AUTO_VAR_CLASS) {
            memcpy(elementAddr,&varTable[varId].address,
                  sizeof(GET_VAR_ADDR_STRUCT));
            autoOffset = (S32)compPtr->offset;
            /*if (elementAddr->addrData.getAutoVar.autoVarOffset > 0)
	       autoOffset = (S32)(-autoOffset); -- Hera 2/19/98*/
            if ((retcode = StkCalcStkOffset(&elementAddr->addrData.
                     getAutoVar.autoVarOffset,autoOffset)) != GOOD)
                  return retcode;

         }
         else {
            /* STATIC_VAR_CLASS, GLOBAL_VAR_CLASS, UNKNOWN_VAR_CLASS */
            if ((retcode = AdrDuplicateAddress(varTable[varId].address.
                  getFixedAddrDesc,&elementAddr->getFixedAddrDesc)) != GOOD)
               return retcode;
            if ((retcode = AdrAddToAddress(elementAddr->
                  getFixedAddrDesc,compPtr->offset)) != GOOD)
               return retcode;
         }
      }
      else {
         /* Register based LIVING_REG, LOCKED_REG */
            memcpy(elementAddr,&varTable[varId].address,
                  sizeof(GET_VAR_ADDR_STRUCT));
      }
      typedefTypeIndex =  varTable[varId].typeInfo.typeIndex;
      memmove(&typeInfo,&varTable[varId].typeInfo,sizeof(typeInfo));
      typeInfo.typeName = (LPSTR)typeInfo.typeNameStr;

      if ((typeInfo.typeChoice == COMPLEX_TYPE_CLASS) &&
            (typeInfo.t.complexType == Typedef)) {
         while (typeInfo.t.complexType == Typedef) {
            if ((retcode = SymGetTypeTypeIndex(typedefTypeIndex,
                  &typedefTypeIndex)) != GOOD)
               return retcode;
            if ((retcode = SymGetTypeHeader(typedefTypeIndex,
                  (TYPE_HEADER_TYPE *)&typeInfo)) != GOOD)
               return retcode;
            typeInfo.typeIndex = typedefTypeIndex;
         }
      }
      if (typeInfo.t.complexType == Union_Type)
         *unionEdit = TRUE;
      *addr = elementAddr;

   }
   else {    /* variable with no components */
      typedefTypeIndex =  varTable[varId].typeInfo.typeIndex;
      memmove(&typeInfo,&varTable[varId].typeInfo,sizeof(typeInfo));
      typeInfo.typeName = (LPSTR)typeInfo.typeNameStr;

      if ((typeInfo.typeChoice == COMPLEX_TYPE_CLASS) &&
            (typeInfo.t.complexType == Typedef)) {
         while (typeInfo.t.complexType == Typedef) {
            if ((retcode = SymGetTypeTypeIndex(typedefTypeIndex,
                  &typedefTypeIndex)) != GOOD)
               return retcode;
            if ((retcode = SymGetTypeHeader(typedefTypeIndex,
                  (TYPE_HEADER_TYPE *)&typeInfo)) != GOOD)
               return retcode;
            typeInfo.typeIndex = typedefTypeIndex;
         }
      }
      if (typeInfo.typeChoice == COMPLEX_TYPE_CLASS) {
         /*
         **  an editable complex type which includes pointers,
         **  enums, and arrays of editable types.
         */

	 if ((typeInfo.t.complexType == Pointer) ||
               (typeInfo.t.complexType == Reference/*Hera 2/27/98*/) ||
               (typeInfo.t.complexType == Enumeration)) {
            *typeIndex = typeInfo.typeIndex;
            *addr = &varTable[varId].address;
         }
         else {
            if ((varTable[varId].registerClass == NOT_REG) &&
                  (varTable[varId].storageClass == AUTO_VAR_CLASS)) {
               /*
               ** array on the stack
               */
               if ((elementAddr = (GET_VAR_ADDR_STRUCT *)TMalloc(sizeof
                     (GET_VAR_ADDR_STRUCT))) == NULL)
                  return ER_OUT_OF_MEMORY;
               memcpy(elementAddr,&varTable[varId].address,
                     sizeof(GET_VAR_ADDR_STRUCT));
               elementAddr->getFixedAddrDesc = NULL;
               if ((retcode = MapArrayLine2Offset(&varTable[varId].typeInfo,
                     ((bufferNum * VS_MAX_BUFFER_LINES) + lineNum),0,
                     &byteOffset,&memberIndex,typeIndex,&arrayNode,
                     NULL)) != GOOD)
                  return retcode;
               autoOffset = (S32)byteOffset;
               /*if (elementAddr->addrData.getAutoVar.autoVarOffset > 0)
                  autoOffset = (S32)(-autoOffset); --Hera 2/19/98*/
               if ((retcode = StkCalcStkOffset(&elementAddr->addrData.
                     getAutoVar.autoVarOffset,autoOffset)) != GOOD)
                  return retcode;
               *addr = elementAddr;

            }
            else {
               if ((varTable[varId].registerClass == NOT_REG) &&
                     (varTable[varId].storageClass != AUTO_VAR_CLASS))  {
                  /*
                  ** array in memory
                  */
                  if ((elementAddr = (GET_VAR_ADDR_STRUCT *)TMalloc(sizeof(
                        GET_VAR_ADDR_STRUCT))) == NULL)
                     return ER_OUT_OF_MEMORY;
                  *addr = &varTable[varId].address;
                  if ((retcode = MapArrayLine2Offset(&varTable[varId].typeInfo,
                        ((bufferNum * VS_MAX_BUFFER_LINES) + lineNum),0,
                        &byteOffset,&memberIndex,typeIndex,&arrayNode,
                        NULL)) != GOOD)
                     return retcode;
                  if ((retcode = AdrDuplicateAddress((*addr)->getFixedAddrDesc,
                        &elementAddr->getFixedAddrDesc)) != GOOD)
                     return retcode;
                  if ((retcode = AdrAddToAddress(elementAddr->
                        getFixedAddrDesc,byteOffset)) != GOOD)
                     return retcode;
                  *addr = elementAddr;
               }
               else {
                  if (varTable[varId].registerClass != NOT_REG) {
                  /*
                  ** an unused array in a reg
                  */
                     if ((elementAddr =
                           (GET_VAR_ADDR_STRUCT *)TMalloc(sizeof
                           (GET_VAR_ADDR_STRUCT))) == NULL)
                        return ER_OUT_OF_MEMORY;
                     memcpy(elementAddr,&varTable[varId].address,
                           sizeof(GET_VAR_ADDR_STRUCT));
                     elementAddr->getFixedAddrDesc = NULL;
                     *addr = elementAddr;
                  }
               }
            }
            GetSubArrayType(&varTable[varId].typeInfo,&baseTypeInfo);
            if (baseTypeInfo != NULL) {
               *typeIndex = baseTypeInfo->typeIndex;
               /*
               **  an array of complex types, use the memberIndex to
               **  determine the editable component type.
               */
               if (varTable[varId].compListPtr != NULL ) {
                  compPtr = varTable[varId].compListPtr;
                  for (i=0; i != memberIndex; i++)
                      compPtr = compPtr->next;
                  *typeIndex = compPtr->typeInfo.typeIndex;
                  if (baseTypeInfo->t.complexType == Union_Type)
                     *unionEdit = TRUE;
               }
            }
         }
      }
      else {
         if (typeInfo.typeChoice == SIMPLE_TYPE_CLASS) {
            *typeIndex = typeInfo.typeIndex;
            *addr = &varTable[varId].address;
         }
      }

   }
   return GOOD;

}


/*************************************************************************
**
**  GetFormatString :
**
**  This routine returns a format string based on type and primary or
**  secondary edit field.
**
**************************************************************************/
PRIVATE STRING GetFormatString(U8 editMarkCount,
                               TYPE_INDEX typeIndex) {
   switch(editMarkCount) {
      case 1:
         return(typeTable[typeIndex].primaryFormatStr);
      case 2:
         return(typeTable[typeIndex].secondaryFormatStr);
      default:
         return(NULL);
   }
}

/*****************************************************************************
**
** HandleUnknownString
**
** Used for variables that are inactive and therefore Unknown (out of scope).
**
******************************************************************************/
VOID PRIVATE HandleUnknownString(STRING *textPtr){
   GetBlankSpace(textPtr);
   strcat((LPSTR)*textPtr,unknownVar);
   *textPtr += lstrlen((LPSTR)*textPtr);
   GetEndOfLine(textPtr);
}

/*****************************************************************************
**
** HandleNoValueString
**
** Used for register variables that are either DEAD or cannot access value.
**
******************************************************************************/
VOID PRIVATE HandleNoValueString(STRING *textPtr){

   strcat((LPSTR)*textPtr,noValueVar);
   *textPtr += lstrlen((LPSTR)*textPtr);
}

/***********************************************************************
**
**  CheckForIntegerOverflow :
**
**  Description:
**    This routine extracts decimal digits from ASCII strings
**    and makes sure no overflow will occur.  Note that we
**    just look for decimal digits, since if it's really
**    a hex number we just won't read (much) of it.  (Only
**    decimal representations could overflow.)
**
**  Parameters:
**    varId (in): the symbol Id of the variable
**    newValueText (in): the text representation of the new value
**    length (in): the length of the integer (16 or 32)
**    signd (in): TRUE if a signed integer type, FALSE otherwise
**
************************************************************************/
RETCODE PRIVATE CheckForIntegerOverflow(DESCRIPTOR varId,
                                 LPSTR newValueText,
                                 U8 length,
                                 BOOL signd)  {
   LPU8 valueText; /* not LPSTR since anotated text uses high bit */
   LPSTR unsignedText;
   STRING valuePtr,searchPtr;
   RETCODE retcode = GOOD;
   U16 textLen = 0;
   BOOL negative = FALSE;

   if ((valueText = (LPU8)TMalloc(VS_MAX_STRING)) == NULL) {
      return (ER_OUT_OF_MEMORY);
   }
   /*
   **  Strip out the encoding markers from newValueText (this is from
   **  ConvTextAndWriteMem).
   */
   valuePtr = (STRING)valueText;
   memset(valueText,'\0',VS_MAX_STRING);
   if (varTable[varId].interActive) {  /* anotated text */
      searchPtr = (STRING)newValueText;
      while (*searchPtr != END_EDIT_MARK) {
         if (*searchPtr == EDIT_FIELD_MARK)
            searchPtr++;
         else {
            *valuePtr = *searchPtr;
            valuePtr++;
            searchPtr++;
         }
      }
   }
   else {
      lstrcpy((LPSTR)valueText,newValueText);
   }
   if ((unsignedText = (LPSTR)TMalloc(VS_MAX_STRING)) == NULL) {
      TFree((LPSTR)valueText);
      return (ER_OUT_OF_MEMORY);
   }
   valuePtr = (STRING)unsignedText;
   memset(unsignedText,'\0',VS_MAX_STRING);
   searchPtr = (STRING)valueText;
   /*
   ** Record a minus sign, and copy decimal digits to unsignedText.
   ** Break when anything but minus, plus, or digits is seen.
   */
   if (*searchPtr == '-' || *searchPtr == '+') {
      negative = (*searchPtr == '-') ? TRUE : FALSE;
      searchPtr++;
   }
   while (*searchPtr && isdigit(*searchPtr)) {
      *valuePtr++ = *searchPtr++;
   }
   if ((LPSTR) valuePtr == (LPSTR) unsignedText) { /* No digits seen */
      TFree((LPSTR)valueText);
      TFree((LPSTR)unsignedText);
      return (GOOD);
   }
   textLen = lstrlen(unsignedText);

   if (!signd) { /* an unsigned integer */
      switch(length) {
         case 16: {
            if (textLen > 5) {
               retcode = ER_VS_USHORT_OVERFLOW;
            }
            else if (textLen == 5) {
               if (lstrcmp(unsignedText, MAX_U16_VAL) > 0) {
                  retcode = ER_VS_USHORT_OVERFLOW;
               }
            }
         }
         break;
         case 32: {
            if (textLen > 10) {
               retcode = ER_VS_ULONG_OVERFLOW;
            }
            else if (textLen == 10) {
               if (lstrcmp(unsignedText, MAX_U32_VAL) > 0) {
                  retcode = ER_VS_ULONG_OVERFLOW;
               }
            }
         }
      }
   }
   else { /* a signed integer */
      switch(length) {
         case 16: {
            if (textLen > 5) {
               retcode = ER_VS_SHORT_OVERFLOW;
            }
            else if (textLen == 5) {
               if (!negative && lstrcmp(unsignedText, MAX_S16_VAL) > 0) {
                  retcode = ER_VS_SHORT_OVERFLOW;
               }
               else if (negative && lstrcmp(unsignedText, MIN_S16_VAL) > 0) {
                  retcode = ER_VS_SHORT_OVERFLOW;
               }
            }
         }
         break;
         case 32: {
            if (textLen > 10) {
               retcode = ER_VS_LONG_OVERFLOW;
            }
            else if (textLen == 10) {
               if (!negative && lstrcmp(unsignedText, MAX_S32_VAL) > 0) {
                  retcode = ER_VS_LONG_OVERFLOW;
               }
               else if (negative && lstrcmp(unsignedText, MIN_S32_VAL) > 0) {
                  retcode = ER_VS_LONG_OVERFLOW;
               }
            }
         }
      }
   }
   TFree((LPSTR)valueText);
   TFree((LPSTR)unsignedText);
   return (retcode);
}

/**********************************************************************
**
** HandleViewOnlyValue
**
** Used for variables that are active but have no known value at that   
** point in time.  ie. Living Registers with variable lifetime.
**
*************************************************************************/
VOID PRIVATE HandleViewOnlyValue(STRING *textPtr, U32 regValue){

   sprintf((LPSTR)regValueStr, "0x%lX", regValue);
   strcat((LPSTR)*textPtr, regValueStr);
   *textPtr += lstrlen((LPSTR)*textPtr);
}

/**********************************************************************
**
** SetAddrSpace
**
*************************************************************************/
RETCODE EXPORT SetAddrSpace(DESCRIPTOR addr) {
SPACE_MODE spaceMode;
RETCODE err;
ADDR_SPACE addrSpace;

   if ((err=CpuGetSpaceMode(&spaceMode)) != GOOD)
      return err;
   if (LdrSpaceMode() != spaceMode)
      return ER_ADR_SPACE_INVALID;
   addrSpace = (spaceMode == SUPERVISOR_MODE) ? SPACE_SD : SPACE_UD;
   return AdrSetAddrSpace(addr, addrSpace);
}

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