/****************************************************************************
**
**  Name:  TEXTGEN.C
**
**  Description:
**     Routines to generate text buffers for display by presenters.
**
**  Status:  TESTED
**
**  $Log:   S:/tbird/mt2_186/varsrv/textgen.c_v  $
** 
**    Rev 1.0   16 Dec 1996 14:48:00   Judy
** Initial revision.
** 
**    Rev 1.74   14 Jun 1995 11:50:52   marilyn
** Updated BI_STACK types to check for stack size to determine 16 or 32 bit
** operations.
** 
**    Rev 1.73   07 Jun 1995 10:31:14   marilyn
** Fixed editting for unknown types to work better.
** 
**    Rev 1.72   06 Jun 1995 15:55:16   marilyn
** Fixed pprs 10465, difficulty showing char types in arrays, and ppr
** 10467, remove ability to inspect void *ptrs and cleanup of error
** recovery from MemReadSized.
** 
**    Rev 1.71   18 May 1995 14:54:26   marilyn
** Fixed GPF when inspecting certain composite variables, fixed bug
** with turning off anotation for dummy fields.
** 
**    Rev 1.70   16 May 1995 18:28:38   nghia
** Fixed bugs for PP 2.4:
** - Turn off edit flag for all padding fields.
** - Fixed GPF bug in GetNthComponent().  When varName == NULL for padding
**   fields.
** - Fixed travsering the componentList correctly.  Ignored component varName.
** - Cleanup and added check for invalid pointer.
** 
**    Rev 1.69   04 May 1995 12:23:32   marilyn
** Changes to Get32Float, Get64Float, GetExtendedFloat to support error
** checking in varieee.c routines.
** 
**    Rev 1.68   04 May 1995 11:11:02   marilyn
** Fixed ppr 10304 and 10309, display of non_ascii char in a string.
** 
**    Rev 1.67   25 Apr 1995 11:31:56   marilyn
** Fixed ppr 10223 and a bitfield display bug.
** 
**    Rev 1.66   28 Mar 1995 11:44:06   marilyn
** Updated IsPointer interface.
** 
**    Rev 1.65   15 Mar 1995 10:08:44   marilyn
** Writing out long doubles to memory was not flipping the bytes, fixes
** ppr 10080.
** 
**    Rev 1.64   10 Mar 1995 16:55:22   marilyn
** Fixed bug in displaying character strings.
** 
**    Rev 1.63   03 Feb 1995 10:57:46   marilyn
** Fixed ppr 9631.  Dereferences char * now show character strings.
** 
**    Rev 1.62   01 Feb 1995 14:19:00   marilyn
** For ppr 9961, check for valid address before attempting to read memory for
** values.  If invalid address then show unknown for value.
** 
**    Rev 1.61   25 Jan 1995 11:55:54   marilyn
** Mem reads are now based on current global access size, fixes ppr 9331.
** 
**    Rev 1.60   24 Jan 1995 16:46:48   marilyn
** Added support for bitfields in LSB orientation, also additional display
** for bitfields, and support for editting bitfields in their base type
** format.
** 
**    Rev 1.59   28 Nov 1994 10:01:52   marilyn
** Added X86 floating point support.
** 
**    Rev 1.58   24 Oct 1994 11:51:10   marilyn
** Some structure changes required field updates for ppr 9964.
** 
**    Rev 1.57   12 Oct 1994 15:16:42   marilyn
** Fixed pprs 9845,9842,9843,9668,9669.
** 
**    Rev 1.56   10 Oct 1994 17:41:30   marilyn
** fixed ppr 9668.
** 
**    Rev 1.55   14 Sep 1994 10:03:18   marilyn
** Fixed bug in GetPointerSubtypes which did not check for COMPLEX_TYPE_CLASS
** before examining complex member of union.
** 
**    Rev 1.54   08 Sep 1994 16:40:42   marilyn
** Fixed numerous problems with display of ptrs, editing and derefencing ptrs,
** and some strange combinations of typedefs.
** 
**    Rev 1.53   24 Aug 1994 09:54:06   marilyn
** Updated for X86 support.
** 
**    Rev 1.52   16 Jun 1994 13:09:02   nghia
** Merged 1.51.1.0 to trunk
** 
**    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/mt2_186/varsrv/textgen.c_v   1.0   16 Dec 1996 14:48:00   Judy  $
**
**  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 _CPU_
#include "cpu.h"
#endif

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

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

#ifndef _INIUTIL_
#include "iniutil.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 unionString[] = "union ";
const char unknownString[] = "unknown";
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[] = "\x2E";
const char contextDelimiter[] = "#";
const char unknownFloat[] = "NAN";

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[] = ":";

#define ZERO_BUFFER  0
#define SPACES_PER_INDENT 3

#define VS_MAX_TYPE_TABLE 256  /* support 256 IEEE695 built-in types */
#define VS_POINTER_TYPES 32
#define VS_MAX_BUF 256
#define VS_MAX_STRING 256
#define VS_MAX_DISPLAYED_NAME 80
#define VS_MAX_DISPLAYED_STR  60

#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 STACK_32BIT 0x4L  /* bytes */
#define STACK_16BIT 0x2L  /* bytes */

/*
** #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,
   DF_STRING    = 0xF4
} DISPLAY_FORMAT;

typedef struct {
   U16            primaryEditFieldSize;
   DISPLAY_FORMAT primaryRadix;
   BOOLEAN        primaryEdit;
   U8             primaryPrintFormatStr[10];
   U8             primaryScanFormatStr[10];
   U16            secondaryEditFieldSize;
   DISPLAY_FORMAT secondaryRadix;
   BOOLEAN        secondaryEdit;
   U8             secondaryPrintFormatStr[10];
   U8             secondaryScanFormatStr[10];
} TYPE_TABLE_ENTRY;

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

typedef enum {
   BF_MSB,
   BF_LSB
} BF_ORIENTATION;

typedef enum {
   STACK_WRITE,
   MEM_WRITE,
   REG_WRITE
} WRITE_DESTINATION_TYPE;


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

typedef enum {
   PRINT_FORMAT,
   SCAN_FORMAT
} FORMAT_STRING_TYPE;

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

extern VS_VAR_TABLE_TYPE  varTable;
extern PROCESSOR_FAMILY procFamily;
extern ENDIAN_TYPE procEndian;
extern U32 procStackSize;

                       /****************************
                        *                          *
                        *     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 BOOLEAN invalidAddress;
static STRING textStartPtr;
static VAR_STORAGE_CLASS varStorageClass;
static VAR_REGISTER_CLASS varRegisterClass;
static GET_VAR_ADDR_STRUCT *elementAddr;
CHAR regValueStr[VS_MAX_STRING];

/* 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] = {
// 00: unknown type
{0,DF_HEX,FALSE,"%X\0","%X\0",0,DF_HEX,FALSE,"%X\0","%X\0"},  
// 01: void type
{0,DF_HEX,FALSE,"%X\0","%X\0",0,DF_HEX,FALSE,"%X\0","%X\0"}, 
// 02 8 bit signed char
{2,DF_HEX,TRUE,"%X\0","%X\0",1,DF_ASCII,TRUE,"%c\0","%c\0"},
// 03: 8 bit unsigned char
{2,DF_HEX,TRUE,"%X\0","%X\0",1,DF_ASCII,TRUE,"%c\0","%c\0"},
// 04: 16 bit signed char
{4,DF_HEX,TRUE,"%X\0","%X\0",6,DF_DECIMAL,TRUE,"%hd\0","%hd\0"}, 
// 05: 16 bit unsigned char
{4,DF_HEX,TRUE,"%X\0","%X\0",5,DF_DECIMAL,TRUE,"%hu\0","%hu\0"},
// 06: 32 bit signed int
{8,DF_HEX,TRUE,"%lX\0","%lX\0",11,DF_DECIMAL,TRUE,"%ld\0","%ld\0"}, 
// 07: 32 bit unsigned int
{8,DF_HEX,TRUE,"%lX\0","%lX\0",10,DF_DECIMAL,TRUE,"%lu\0","%lu\0"}, 
// 08: 64 bit signed long
{16,DF_HEX,TRUE,"%08lX\0","%08lX\0",16,DF_DECIMAL,TRUE,"%ld\0","%ld\0"},
// 09: 64 bit unsigned long
{16,DF_HEX,TRUE,"%08lX\0","%08lX\0",16,DF_DECIMAL,TRUE,"%lu\0","%lu\0"}, 

// 05/12/95 - Nghia
// Fixed PPR 10338 - floating point display with default precision - 6 digits
// Specified floating-point precision:
// float = 7 digits, double = 15 digits, long double = 19 digit.
// If these precision value is not specified, the default is 6 digit precision.
// i.e., the value is truncated/rounded to 6 digits for (double/long double).
// All floating-point values are left-justified, 0 padding to the right.
/* floating point types */
// 10: 32 bit float BI_F32
{F_DISPLAY_DIG,DF_FLOAT,TRUE,"%-#.7g\0","%g\0",0,DF_NODISP,FALSE,"\0","\0"},
// 11: 64 bit float BI_F64 
{D_DISPLAY_DIG,DF_DOUBLE,TRUE,"%-#.15lg\0","%lg\0",0,DF_NODISP,FALSE,"\0","\0"},
// 12: extended precision long double BI_F_EXT 
{LD_DISPLAY_DIG,DF_LDOUBLE,TRUE,"%-#.19Lg\0","%Lg\0",0,DF_NODISP,FALSE,"\0","\0"},

/* display not currently supported */
// 13: 128 bit float BI_F128   
{32,DF_LDOUBLE,TRUE,"%-#.19Lf\0","%Lf\0",0,DF_NODISP,FALSE,"\0","\0"},

// 14: string
{255,DF_STRING,TRUE,"%.*s\0","%.*s\0",0,DF_NODISP,FALSE,"\0","\0"},  
// 15: code location/instruction address
{0,DF_NODISP,FALSE,"\0","\0",0,DF_NODISP,FALSE,"\0","\0"},      
// 16: 16 or 32 bit signed stack push BI_STACK_INT
{8,DF_HEX,TRUE,"%lX\0","%lX\0",11,DF_DECIMAL,TRUE,"%ld\0","%ld\0"},  
// 17: 16 or 32 bit unsigned stack push BI_STACK_U  
{8,DF_HEX,TRUE,"%lX\0","%lX\0",10,DF_DECIMAL,TRUE,"%lu\0","%lu\0"}, 
// 18: 16 or 32 bit unsigned stack push BI_STACK_UINT
{8,DF_HEX,TRUE,"%lX\0","%lX\0",10,DF_DECIMAL,TRUE,"%lu\0","%lu\0"},
// 19: 8 bit signed char
{2,DF_HEX,TRUE,"%X\0","%lX\0",1,DF_ASCII,TRUE,"%c\0","%c\0"},    
// 20: 32 bit signed integer 
{8,DF_HEX,TRUE,"%lX\0","%lX\0",11,DF_DECIMAL,TRUE,"%ld\0","%ld\0"}, 
// 21: 16 bit signed integer
{4,DF_HEX,TRUE,"%X\0","%lX\0",6,DF_DECIMAL,TRUE,"%d\0","%d\0"},   
// 22: 16 bit unsigned integer
{4,DF_HEX,TRUE,"%X\0","%lX\0",5,DF_DECIMAL,TRUE,"%u\0","%u\0"},  
// 23: 16 bit signed integer
{4,DF_HEX,TRUE,"%X\0","%lX\0",6,DF_DECIMAL,TRUE,"%d\0","%d\0"}, 
// 24: 16 bit signed integer
{4,DF_HEX,TRUE,"%X\0","%lX\0",6,DF_DECIMAL,TRUE,"%d\0","%d\0"},
// 25: 64 bit BCD float   
{16,DF_DOUBLE,TRUE,"%-#.15lf\0","%lf\0",0,DF_NODISP,FALSE,"\0","\0"}, 
// 26: reserved
{0,DF_NODISP,FALSE,"\0","\0",0,DF_NODISP,FALSE,"\0","\0"},        
// 27: reserved
{0,DF_NODISP,FALSE,"\0","\0",0,DF_NODISP,FALSE,"\0","\0"},       
// 28: reserved
{0,DF_NODISP,FALSE,"\0","\0",0,DF_NODISP,FALSE,"\0","\0"},      
// 29: reserved
{0,DF_NODISP,FALSE,"\0","\0",0,DF_NODISP,FALSE,"\0","\0"},     
// 30: reserved
{0,DF_NODISP,FALSE,"\0","\0",0,DF_NODISP,FALSE,"\0","\0"},    
// 31: reserved
{0,DF_NODISP,FALSE,"\0","\0",0,DF_NODISP,FALSE,"\0","\0"},   

/* 05/26/94 - Nghia
** Defined additional built-in types for the Variable Server TypeTable
** to support built-in pointer type.
** This wil be removed when the Symbol server is changed the built-in type
** table to support built-in pointer types.
*/
// 32: ptr to unknown type
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},    
// 33: ptr to void
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},     
// 34: ptr to 8 bit signed char
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},      
// 35: ptr to 8 bit unsigned char
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},       
// 36: ptr to 16 bit signed int
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},        
// 37: ptr to 16 bit unsigned int
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},         
// 38: ptr to 32 bit signed long 
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},          
// 39: ptr to 32 bit unsigned long
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},
// 40: ptr to 64 bit signed double
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"}, 
// 41: ptr to 64 bit unsigned double
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},  
// 42: ptr to 32 bit float
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},   
// 43: ptr to 64 bit float
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},
// 44: ptr to extended precision float long double
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"}, 
// 45: ptr to 128 bit float
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},  
// 46: ptr to string
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},
// 47: ptr to code location/instruction address
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"}, 
// 48: ptr to 16 or 32 bit signed stack push
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},  
// 49: ptr to 16 or 32 bit unsigned stack push
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},
// 50: ptr to 16 or 32 bit unsigned stack push
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"}, 
// 51: ptr to 8 bit signed char
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},  
// 52: ptr to 32 bit signed integer
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},
// 53: ptr to 16 bit signed integer
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"}, 
// 54: ptr to 16 bit unsigned integer
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},  
// 55: ptr to 16 bit signed integer
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"},
// 56: ptr to 16 bit signed integer
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"}, 
// 57: ptr to 64 bit BCD float
{8,DF_HEX,TRUE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\0","\0"}, 
/* 58 - 255  are reserved for future */
{8,DF_HEX,FALSE,"%lX\0","%lX\0",0,DF_NODISP,FALSE,"\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 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);


VOID PRIVATE GetNthComponent(DESCRIPTOR varId,
                             DESCRIPTOR bufferNum,
                             U16 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,
                            TYPE_SUBHEADER_TYPE *typeInfo,
                            U32 indirectionLevels);

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 Get64IntValue(STRING *textPtr,
                           LPU8 buffer,
                           DISPLAY_FORMAT dispValueRadix,
                           BOOLEAN dispValueEdit,
                           U8 *formatStr);

RETCODE PRIVATE GetCharValue(STRING *textPtr,
                          LPU8 buffer,
                          GET_VAR_ADDR_STRUCT *addr,
                          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 GetExtendedFloatValue(STRING *textPtr,
                                   LPU8 buffer,
                                   DISPLAY_FORMAT dispValueRadix,
                                   BOOLEAN dispValueEdit,
                                   U8 *formatStr,
                                   U32 extendedSize);

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

RETCODE PRIVATE GetStringValue(STRING *textPtr,
                            LPU8 buffer,
                            GET_VAR_ADDR_STRUCT *addr,
                            DISPLAY_FORMAT dispValueRadix,
                            BOOLEAN dispValueEdit,
                            U8 *formatStr);

RETCODE PRIVATE GetPointerValue(STRING *textPtr,
                                TYPE_SUBHEADER_TYPE *typeInfo,
                                COMPLEX_TYPE ptrType,
                                GET_VAR_ADDR_STRUCT *varAddr,
                                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,
                                   U16 lineNum,
                                   TYPE_INDEX *typeIndex,
                                   GET_VAR_ADDR_STRUCT **addr,
                                   BOOLEAN *unionEdit);

PRIVATE STRING GetFormatString(U8 editMarkCount,
                               TYPE_INDEX typeIndex,
                               FORMAT_STRING_TYPE formatType);

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

RETCODE PRIVATE CheckForIntegerOverflow(DESCRIPTOR varId,
                                 LPSTR newValueText,
                                 U8 length,
                                 BOOL signd);

RETCODE PRIVATE CheckPointerEditValue(DESCRIPTOR varId,
                                      LPSTR newValueText);

RETCODE PRIVATE GetBitfieldValue(STRING *textPtr,
                                 LPU8 buffer,
                                 TYPE_SUBHEADER_TYPE *typeInfo,
                                 U16 bitOffset,
                                 BF_ORIENTATION bitfieldType);

RETCODE PRIVATE GetBitfieldOrientation(BF_ORIENTATION *bitfieldType);

                       /****************************
                        *                          *
                        *      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 rootId;
   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;
   invalidAddress = varTable[varIndex].invalidAddress;
   anotatedText = (BOOLEAN)varTable[varIndex].interActive;
   if (varTable[varIndex].dereferencedPtr) {
      if (varTable[varIndex].rootVarId != NOROOT) {
         rootId = varTable[varIndex].rootVarId & VS_VARID_MASK;
         UpdateChildVars(rootId,
                      varTable[varIndex].varInfo.var.component.lineNum,
                      varTable[varIndex].varInfo.var.component.bufferNum,
                      varTable[rootId].typeInfo.typeIndex,
                      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->th.typeChoice == SIMPLE_TYPE_CLASS) {
      if ((retcode = GetFormattedSimpleType(baseTypeTypeInfo,
            typedefTypeInfo,(LPSTR)varTable[varIndex].varName,
            &varTable[varIndex].address,indents,textPtr)) != GOOD)
         return retcode;
   }
   else  {
      switch (baseTypeTypeInfo->th.t.complexType)  {
         case TY_STRUCT :
         case TY_UNION :
            if ((retcode = GetFormattedStructOrUnionType(
                  varTable[varIndex].compListPtr,
                  baseTypeTypeInfo,typedefTypeInfo,
                  &varTable[varIndex].address,
                  (LPSTR)varTable[varIndex].varName,indents,
                  textPtr)) != GOOD)
               return retcode;
            break;
         case TY_SMALL_PTR :
         case TY_LARGE_PTR :
         case TY_16_16_PTR :
         case TY_16_32_PTR :
            if ((retcode = GetFormattedPointerType(baseTypeTypeInfo,
                  typedefTypeInfo,(LPSTR)varTable[varIndex].varName,
                  &varTable[varIndex].address,
                  indents,textPtr)) != GOOD)
               return retcode;
            break;
         case TY_C_ARRAY :
            if ((retcode = GetFormattedArrayType(baseTypeTypeInfo,
                  typedefTypeInfo,&varTable[varIndex].address,
                  varTable[varIndex].compListPtr,(LPSTR)varTable[varIndex].
                  varName,indents,textPtr)) != GOOD)
               return retcode;
            break;
         case TY_ENUM_C :
            if ((retcode = GetFormattedEnumType(baseTypeTypeInfo,
                  typedefTypeInfo,(LPSTR)varTable[varIndex].varName,
                  &varTable[varIndex].address,
                  indents,textPtr)) != GOOD)
               return retcode;
            break;
         case TY_BITFIELD :
            if ((retcode = GetFormattedBitfieldType(baseTypeTypeInfo,
                  typedefTypeInfo,(LPSTR)varTable[varIndex].varName,
                  &varTable[varIndex].address,indents,
                  baseTypeTypeInfo->bitfieldInfo.bitOffset,textPtr))
                   != GOOD)
               return retcode;
            break;
         case TY_UNKNOWN :
         case TY_FUNC_NODEP :
         case TY_FUNC_DEP :
         case TY_VOID :
            // 05/15/95 - Nghia
            // Added TY_VOID to the unknown type list
            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,
                             U16 lineNum,
                             VS_COMPONENT_TYPE **compPtr) {
   U16 nthComp;
   LOOP_VAR i;

   nthComp = (bufferNum * VS_MAX_BUFFER_LINES) + lineNum;
   if (nthComp == 0) 
      *compPtr = NULL;
   if ((varTable[varId].typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS) &&
         (varTable[varId].typeInfo.th.t.complexType == TY_TYPE)) {
      if (nthComp >varTable[varId].baseTypeMemberCount)
         *compPtr = NULL;
      else
         *compPtr = varTable[varId].compListPtr;
   }
   else {
      if (nthComp > varTable[varId].memberCount)
         *compPtr = NULL;
      else if (nthComp)
         *compPtr = varTable[varId].compListPtr;
   }
   if ((*compPtr != NULL) && (nthComp > 0)) {
      // 05/15/95 - Nghia
      // Do not need to check for varName of the component. Since
      // there are unname components (fields) being used for structure
      // boundary alignment, these fields will have NULL as their
      // varName which will cause a GPF.  Beside that, the varName is not
      // relevant in locating the nth component.
      // NOTES: component list start from 0..n, nthComp is start from 1
      for (i = 0; (*compPtr && (i < nthComp-1)); i++) {
         // Traverse the component list to the <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,
                            TYPE_SUBHEADER_TYPE *typeInfo,
                            U32 indirectionLevels)  {

   BOOLEAN typeNameFound = FALSE;
   TYPE_SUBHEADER_TYPE *subtype;

   if (typeInfo == NULL)
      return typeNameFound;
   if (typeInfo->th.typeName == NULL)
      return typeNameFound;
   if (*typeInfo->th.typeName == '\0') {  // no type name
      // see if we can find a base type to display
      if ((typeInfo->th.typeChoice == COMPLEX_TYPE_CLASS) &&
          (typeInfo->th.t.complexType == TY_TYPE)) {   
         if (typeInfo->next != NULL) {
            subtype = typeInfo->next;
            while ((subtype->next != NULL))
               subtype = subtype->next;
            if ((subtype != NULL) && (*subtype->th.typeName != '\0')) {
               typeNameFound = TRUE;
               typeInfo = subtype;
            }
         }
      }
   }
   else
      typeNameFound = TRUE;
   if (!typeNameFound) {
      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,typeInfo->th.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;
}

/***********************************************************************
**
**  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);
               /* save the function name */
               *textPtr += lstrlen((LPSTR)*textPtr);    
            }
            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) {
   U8 temp, highest;
   LOOP_VAR i, end;
   
   if (procEndian == LITTLE_ENDIAN)     // Intel processor
      return;
   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;
   ACCESS_SIZE accessSize;

   if ((*buffer = (LPU8)TMalloc(VS_MAX_BUF)) == NULL)
      return ER_OUT_OF_MEMORY;
   memset(*buffer,'\0',VS_MAX_BUF);
   if ((error = MemGetAccessSize(&accessSize)) != GOOD)
      return error;
   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.
         */
         error = StkRead(addr->addrData.getAutoVar.autoVarOffset,
                         typeInfo->th.sizeInMAUs,
                         varFrameNum,varTable[varIndex].frameType,
                         &bufPtr);
      }
      else {
         /* STATIC_VAR_CLASS, GLOBAL_VAR_CLASS, UNKNOWN_VAR_CLASS */
         error = MemReadSized(addr->getFixedAddrDesc,
                              typeInfo->th.sizeInMAUs,
                              &bufPtr, accessSize,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.
         **  06/02/95 Marilyn: correction, always returns a buffer UNLESS
         **  it is ER_OUT_OF_MEMORY in which case no buffer is returned.
         **  Better verify that buffer.  This is the error returned when
         **  a length of 0 bytes is to be read (TY_VOID)...
         */
         if ((error != GOOD) && (bufPtr != NULL))
            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
         // 
         error = CpuGetRegister(addr->addrData.getRegisterIndex.  
                                varLivingReg,&regValue);
         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 
         error = CpuGetRegister(addr->addrData.getLockedReg.
                                getRegIndex.regIndex,&regValue);
         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->th.sizeInMAUs;
               if( typeInfo->th.sizeInMAUs % defaultSize ) 
                  stackSize =
                     defaultSize * ((typeInfo->th.sizeInMAUs/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);
                  // 05/15/95 - Nghia
                  // return error code directly, do need to check the error
                  return TFree((LPSTR)bufPtr);
               }
               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;
            }
         }
      }
   }
   // 05/15/95 - Nghia
   // To be corect, check if (error != GOOD), not (error != 0)
   if (error != GOOD) {
      return error;
   }
   else {
      if( *alternateAccess ) return(GOOD);
      if (regRead) {
         memcpy(*buffer,&regValue,sizeof(regValue));
      }
      else  {
         memcpy(*buffer,bufPtr,typeInfo->th.sizeInMAUs);
         FlipBuffer(*buffer,typeInfo->th.sizeInMAUs);
         // 05/15/95 - Nghia
         // return error directly
         return TFree((LPSTR)bufPtr);
      }  
   }
   return GOOD;
}


/*************************************************************************
**
**  GetBitfieldEditValue :
**
**************************************************************************/
RETCODE PRIVATE GetBitfieldEditValue(STRING *textPtr,
                                     GET_VAR_ADDR_STRUCT *addr,
                                     TYPE_SUBHEADER_TYPE *typeInfo,
                                     U16 bitOffset) {
   LPU8 buffer;
   BOOLEAN alternateAccess = FALSE;
   BF_ORIENTATION bitfieldType;
   RETCODE error;

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

   if ((error = GetBitfieldOrientation(&bitfieldType)) != GOOD)
      return error;

   if ((error = GetBitfieldValue(textPtr,buffer,typeInfo,bitOffset,
         bitfieldType)) != GOOD)
      return error;
   
   // 05/15/95 - Nghia
   // return error code directly
   return TFree((LPSTR)buffer);
}

/***********************************************************************
**
**  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->th.typeChoice == SIMPLE_TYPE_CLASS) {
      switch (typeInfo->th.t.simpleType) {
         case BI_S8_SCHAR: case BI_U8_UCHAR: case BI_S8_CHAR:
            GetCharValue(textPtr,buffer,addr,
               typeTable[typeInfo->th.t.simpleType].primaryRadix,
               typeTable[typeInfo->th.t.simpleType].primaryEdit,
               typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
            if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                != DF_NODISP){
               GetCharValue(textPtr,buffer,addr,
                  typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                  typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                  typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr);
            }
            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:
            Get16IntValue(textPtr,buffer,
               typeTable[typeInfo->th.t.simpleType].primaryRadix,
               typeTable[typeInfo->th.t.simpleType].primaryEdit,
               typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
            if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get16IntValue(textPtr,buffer,
                  typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                  typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                  typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr);
            }
            break;
         case BI_S32_SLONG: case BI_U32_ULONG: case BI_S32_LONG:
            Get32IntValue(textPtr,buffer,
               typeTable[typeInfo->th.t.simpleType].primaryRadix,
               typeTable[typeInfo->th.t.simpleType].primaryEdit,
               typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
            if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get32IntValue(textPtr,buffer,
                  typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                  typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                  typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr);
            }
            break;
         case BI_STACK_INT: 
            // check proc stack size to determine 16 or 32 bit
            // override 16 bit signed stack push to the
            // 16 bit signed int type since stack push defaults to
            // 32 bits
            if (procStackSize == STACK_16BIT) {
               Get16IntValue(textPtr,buffer,
                  typeTable[BI_S16_SINT].primaryRadix,
                  typeTable[BI_S16_SINT].primaryEdit,
                  typeTable[BI_S16_SINT].primaryPrintFormatStr);
               if (typeTable[BI_S16_SINT].secondaryRadix
                   != DF_NODISP){
                  strcat((LPSTR)*textPtr,equalString);
                  *textPtr += strlen((LPSTR)*textPtr);
                  Get16IntValue(textPtr,buffer,
                     typeTable[BI_S16_SINT].secondaryRadix,
                     typeTable[BI_S16_SINT].secondaryEdit,
                     typeTable[BI_S16_SINT].secondaryPrintFormatStr);
               }
            }
            else  {
               // procStackSize == STACK_32BIT or 4 bytes
               Get32IntValue(textPtr,buffer,
                  typeTable[typeInfo->th.t.simpleType].primaryRadix,
                  typeTable[typeInfo->th.t.simpleType].primaryEdit,
                  typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
               if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                   != DF_NODISP){
                  strcat((LPSTR)*textPtr,equalString);
                  *textPtr += strlen((LPSTR)*textPtr);
                  Get32IntValue(textPtr,buffer,
                     typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                     typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                     typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr);
               }
            }
            break;
         case BI_STACK_U: case BI_STACK_UINT:
            // check proc stack size to determine 16 or 32 bit
            // override the 16 bit unsigned stack push to a 16 bit
            // signed int type since stack push type defaults to
            // 32 bits
            if (procStackSize == STACK_16BIT) {
               Get16IntValue(textPtr,buffer,
                  typeTable[BI_U16_UINT].primaryRadix,
                  typeTable[BI_U16_UINT].primaryEdit,
                  typeTable[BI_U16_UINT].primaryPrintFormatStr);
               if (typeTable[BI_U16_UINT].secondaryRadix
                   != DF_NODISP){
                  strcat((LPSTR)*textPtr,equalString);
                  *textPtr += strlen((LPSTR)*textPtr);
                  Get16IntValue(textPtr,buffer,
                     typeTable[BI_U16_UINT].secondaryRadix,
                     typeTable[BI_U16_UINT].secondaryEdit,
                     typeTable[BI_U16_UINT].secondaryPrintFormatStr);
               }
            }
            else  {
               // procStackSize == STACK_32BIT or 4 bytes
               Get32IntValue(textPtr,buffer,
                  typeTable[typeInfo->th.t.simpleType].primaryRadix,
                  typeTable[typeInfo->th.t.simpleType].primaryEdit,
                  typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
               if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                   != DF_NODISP){
                  strcat((LPSTR)*textPtr,equalString);
                  *textPtr += strlen((LPSTR)*textPtr);
                  Get32IntValue(textPtr,buffer,
                     typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                     typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                     typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr);
               }
            }
            break;
         case BI_F32:
            Get32FloatValue(textPtr,buffer,
               typeTable[typeInfo->th.t.simpleType].primaryRadix,
               typeTable[typeInfo->th.t.simpleType].primaryEdit,
               typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
            if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get32FloatValue(textPtr,buffer,
                  typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                  typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                  typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr);
            }
            break;
         case BI_F64: case BI_F64_BCD:
            // NOTES: 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->th.t.simpleType].primaryRadix,
               typeTable[typeInfo->th.t.simpleType].primaryEdit,
               typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
            if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                != DF_NODISP){
            strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get64FloatValue(textPtr,buffer,
                  typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                  typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                  typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr);
            }
            anotatedText = savedAnotation;
            break;
         case BI_F_EXTEND:
            // NOTES: Not defering anymore done in get buffer routine
            // Defer byte-flipping till we've extracted the sign/exponent
            // in lower level routine.
            // 03/14/95 Marilyn : not all extended float types are the
            // same size in bytes.  It is compiler dependent.
            //
            FlipBuffer(buffer, typeInfo->th.sizeInMAUs);
            GetExtendedFloatValue(textPtr,buffer,
               typeTable[typeInfo->th.t.simpleType].primaryRadix,
               typeTable[typeInfo->th.t.simpleType].primaryEdit,
               typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr,
               typeInfo->th.sizeInMAUs);
            if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               GetExtendedFloatValue(textPtr,buffer,
                  typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                  typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                  typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr,
                  typeInfo->th.sizeInMAUs);
            }
            break;
         case BI_F128:
            Get128FloatValue(textPtr,buffer,
               typeTable[typeInfo->th.t.simpleType].primaryRadix,
               typeTable[typeInfo->th.t.simpleType].primaryEdit,
               typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
            if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get128FloatValue(textPtr,buffer,
                  typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                  typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                  typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr);
            }
            break;
         case BI_S64_SLONG: case BI_U64_ULONG:
            Get64IntValue(textPtr,buffer,
               typeTable[typeInfo->th.t.simpleType].primaryRadix,
               typeTable[typeInfo->th.t.simpleType].primaryEdit,
               typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
            if (typeTable[typeInfo->th.t.simpleType].secondaryRadix
                != DF_NODISP){
               strcat((LPSTR)*textPtr,equalString);
               *textPtr += strlen((LPSTR)*textPtr);
               Get64IntValue(textPtr,buffer,
                  typeTable[typeInfo->th.t.simpleType].secondaryRadix,
                  typeTable[typeInfo->th.t.simpleType].secondaryEdit,
                  typeTable[typeInfo->th.t.simpleType].secondaryPrintFormatStr);
            }
            break;
         case BI_STRING:
            GetStringValue(textPtr,buffer,addr,
               typeTable[typeInfo->th.t.simpleType].primaryRadix,
               typeTable[typeInfo->th.t.simpleType].primaryEdit,
               typeTable[typeInfo->th.t.simpleType].primaryPrintFormatStr);
            break;
         case BI_P_S8_SCHAR:     case BI_P_U8_UCHAR:   case BI_P_S16_SINT:
         case BI_P_U16_UINT:     case BI_P_S32_SLONG:  case BI_P_U32_ULONG:
         case BI_P_S64_SLONG:    case BI_P_U64_ULONG:  case BI_P_F32:
         case BI_P_F64:          case BI_P_F_EXTEND:   case BI_P_F128:
         case BI_P_STRING:       case BI_P_JUMP:       case BI_P_STACK_INT:
         case BI_P_STACK_U:      case BI_P_STACK_UINT: case BI_P_S8_CHAR:
         case BI_P_S32_LONG:     case BI_P_S16_SHORT:  case BI_P_S16_USHORT:
         case BI_P_S16_SHORTINT: case BI_P_S16_SSHORT: case BI_P_F64_BCD:
            // 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->th.sizeInMAUs to get pointer value accordingly.
            if (typeInfo->th.sizeInMAUs != 2)
               if ((error = GetPointerValue(textPtr, typeInfo,
                     TY_LARGE_PTR, addr, buffer)) != GOOD)
                  return error;
            else
               if ((error = GetPointerValue(textPtr, typeInfo,
                     TY_SMALL_PTR, addr, buffer)) != GOOD)
                  return error;
            break;
         default:
            break;
      }
   }
   else {
      switch (typeInfo->th.t.complexType) {
         case TY_SMALL_PTR :
         case TY_LARGE_PTR :
         case TY_16_16_PTR :
         case TY_16_32_PTR :
            // NOTES: Nghia - 10/28/93
            // Use typeInfo->th.sizeInMAUs to get pointer value for
            // SMALL/LARGE pointer
            if ((error = GetPointerValue(textPtr, typeInfo,
                         typeInfo->th.t.complexType, addr, buffer)) != GOOD)
               return error;
            break;
         case TY_ENUM_C :
            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].primaryPrintFormatStr);
            break;
      }
   }

   // 05/15/95 - Nghia
   // return error code directly
   return TFree((LPSTR)buffer);
}


/***********************************************************************
**
**  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 (bufferFull) return GOOD;
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL)
         GetTypeName(textPtr,typeInfo,0);
      else 
         GetTypeName(textPtr,typedefTypeInfo,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 (invalidAddress)
         strcat((LPSTR)*textPtr,unknownString);
      else {
         if ((error = GetEditValue(textPtr,addr,typeInfo)) != GOOD)
            strcat((LPSTR)*textPtr,unknownString);
      }
      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,0);
      }
      else {
         GetTypeName(textPtr,typedefTypeInfo,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))  {
      // Check abort
      if ((err = TskCheckAbort(&abortFromEsc)) != GOOD) return err;
      if (abortFromEsc) return ER_ABORT_FROM_ESC;

      CheckForTypedef(&component->typeInfo,&typeTypeInfo, &baseTypeInfo);
      if (baseTypeInfo->th.typeChoice == SIMPLE_TYPE_CLASS) {
         // 05/16/95 - Nghia
         // If the component->varName == "" does not have a name,
         // it is a padding field.  If anotation is on then turn it off
         // to make value read only (like in the shell).
         // Restore the global <anotatedText> when done.
         BOOLEAN oldFlag = anotatedText;
         if (anotatedText)
            anotatedText = (*component->varName != NULL);
         GetFormattedSimpleType(baseTypeInfo,typeTypeInfo,
               component->varName,&addr,indents,textPtr);
         anotatedText = oldFlag;
      } 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->th.t.complexType)  {
            case TY_STRUCT :
            case TY_UNION :
               if (GetNewLine(textPtr,indents)) {
                  if (typeTypeInfo == NULL) {
                     CheckStructOrUnionOrEnum(textPtr,baseTypeInfo);
                     GetTypeName(textPtr,baseTypeInfo,0);
                  }
                  else {
                     GetTypeName(textPtr,typeTypeInfo,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 TY_SMALL_PTR :
            case TY_LARGE_PTR :
            case TY_16_16_PTR :
            case TY_16_32_PTR :
               if ((error = GetFormattedPointerType(baseTypeInfo,
                     typeTypeInfo,component->varName,&addr,indents,
                     textPtr)) != GOOD)
                  return error;
               break;
            case TY_C_ARRAY :
               if ((error = GetFormattedArrayTypeForStruct(baseTypeInfo,
                     typeTypeInfo,component->varName,indents,
                     textPtr)) != GOOD)
                  return error;
               break;
            case TY_ENUM_C :
               if ((error = GetFormattedEnumType(baseTypeInfo,
                     typeTypeInfo,component->varName,&addr,indents,
                     textPtr)) != GOOD)
                  return error;
               break;
            case TY_BITFIELD :
               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 we fail to calculate the correct address
      ** we will bail out, since we should never show incorrect info.
      */
      if (component->next != NULL) {
         if (varRegisterClass == NOT_REG) {
            if (varStorageClass != AUTO_VAR_CLASS) {
               if ((error = AdrSubtractFromAddress(addr.getFixedAddrDesc,
                     component->offset)) != GOOD)
                  invalidAddress = TRUE;
               if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
                     component->next->offset)) != GOOD)
                  invalidAddress = TRUE;
            }
            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;
}

/***********************************************************************
**
**  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);
         GetTypeName(textPtr,subtypeInfo,indirectionLevels);
      }
      else {
         if (*typedefTypeInfo->th.typeName == '\0') {
            CheckStructOrUnionOrEnum(textPtr,subtypeInfo);
            GetTypeName(textPtr,typedefTypeInfo,indirectionLevels);
         }
         else  {
            GetTypeName(textPtr,typedefTypeInfo,0);
            GetBlankSpace(textPtr);
         }
      }
      if (((subtypeInfo->th.typeChoice == COMPLEX_TYPE_CLASS) &&
            (subtypeInfo->th.t.complexType == TY_VOID))  ||
          ((subtypeInfo->th.typeChoice == SIMPLE_TYPE_CLASS) &&
           (subtypeInfo->th.t.simpleType == BI_VOID))) {
         // IMPORTANT: 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 (invalidAddress)
         strcat((LPSTR)*textPtr,unknownString);
      else {
         if ((error = GetEditValue(textPtr, addr, typeInfo)) != GOOD)
            strcat((LPSTR)*textPtr,unknownString);
      }
      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,ptrIndirectionLevels))
            if (!ptrIndirectionLevels)
               GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typedefTypeInfo,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,ptrIndirectionLevels))
            if (!ptrIndirectionLevels)
               GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typedefTypeInfo,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->th.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 (invalidAddress)
               strcat((LPSTR)*textPtr,unknownString);
            else {
               if ((error = GetEditValue(textPtr, &addr,
                                         baseTypeInfo)) != GOOD)
                  strcat((LPSTR)*textPtr,unknownString);
            }
            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->th.sizeInMAUs)) != GOOD)
                  invalidAddress = TRUE;
            }
            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->th.sizeInMAUs;
                     break;
                  case LOW_TO_HI:
                     addr.addrData.getAutoVar.autoVarOffset -=
                           baseTypeInfo->th.sizeInMAUs;
                     break;
               }
            }
         }
         i++;
      }
   }
   else {
      switch (baseTypeInfo->th.t.complexType) {
         case TY_STRUCT :
         case TY_UNION :
            while ((!bufferFull) && (i <= (unsigned long)cArray.highBound)) {
               // Check Abort
               if (((err = TskCheckAbort(&abortFromEsc)) != GOOD) ||
                   (abortFromEsc))
                  return (err != GOOD) ? err : ER_ABORT_FROM_ESC;
               GetNewLine(textPtr,indents);
               GetArrayIndices(textPtr,i,0);
               GetFormattedStructOrUnionType(component,baseTypeInfo,
                     typeTypeInfo,&addr,varName,indents,textPtr);
               if (varRegisterClass == NOT_REG) {
                  if (varStorageClass != AUTO_VAR_CLASS) {
                     if ((error = AdrAddToAddress(addr.getFixedAddrDesc,
                           baseTypeInfo->th.sizeInMAUs)) != GOOD)
                        invalidAddress = TRUE;
                  }
                  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->th.sizeInMAUs;
                           break;
                        case LOW_TO_HI:
                           addr.addrData.getAutoVar.autoVarOffset -=
                                 baseTypeInfo->th.sizeInMAUs;
                           break;
                     }
                  }
               }
               i++;
            }
            break;
         case TY_C_ARRAY :
            while ((!bufferFull) && (i <= (unsigned long)cArray.highBound)) {
               if ((err = TskCheckAbort(&abortFromEsc)) != 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->th.sizeInMAUs)) != GOOD)
                        invalidAddress = TRUE;
                  }
                  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->th.sizeInMAUs;
                           break;
                        case LOW_TO_HI:
                           addr.addrData.getAutoVar.autoVarOffset -=
                                 typeInfo->next->th.sizeInMAUs;
                           break;
                     }
                  }
               }
               i++;
            }
            break;
         case TY_LARGE_PTR :
         case TY_SMALL_PTR :
         case TY_16_16_PTR :
         case TY_16_32_PTR :
            while ((!bufferFull) && (i <= (unsigned long)cArray.highBound)) {
               if ((err = TskCheckAbort(&abortFromEsc)) != GOOD)
                  return err;
               if (abortFromEsc) return ER_ABORT_FROM_ESC;

               if (GetNewLine(textPtr,indents)) {
                  GetArrayIndices(textPtr,i,AT_REFERENCE_FIELD);
                  if (invalidAddress)
                     strcat((LPSTR)*textPtr,unknownString);
                  else {
                     if ((error = GetEditValue(textPtr,&addr,
                                               baseTypeInfo)) != GOOD)
                        strcat((LPSTR)*textPtr,unknownString);
                  }
                  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->th.sizeInMAUs)) != GOOD)
                        invalidAddress = TRUE;
                  }
                  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->th.sizeInMAUs;
                           break;
                        case LOW_TO_HI:
                           addr.addrData.getAutoVar.autoVarOffset -=
                                 baseTypeInfo->th.sizeInMAUs;
                           break;
                     }
                  }
               }
               i++;
            }
            break;
         case TY_ENUM_C :
            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 (invalidAddress)
                     strcat((LPSTR)*textPtr,unknownString);
                  else {
                     if ((error = GetEditValue(textPtr,&addr,
                                               baseTypeInfo)) != GOOD)
                        strcat((LPSTR)*textPtr,unknownString);
                  }
                  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->th.sizeInMAUs)) != GOOD)
                        invalidAddress = TRUE;
                  }
                  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->th.sizeInMAUs;
                           break;
                        case LOW_TO_HI:
                           addr.addrData.getAutoVar.autoVarOffset -=
                                 typeInfo->next->th.sizeInMAUs;
                           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,0))
            GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typedefTypeInfo,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 (invalidAddress)
         strcat((LPSTR)*textPtr,unknownString);
      else {
         if ((error = GetEditValue(textPtr,addr,typeInfo)) != GOOD)
            strcat((LPSTR)*textPtr,unknownString);
      }
      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,0))
            GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typeTypeInfo,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.bField.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 (bufferFull) return GOOD;
   if (GetNewLine(textPtr,indents)) {
      if (typedefTypeInfo == NULL) {
         if (GetTypeName(textPtr,typeInfo,0))
            GetBlankSpace(textPtr);
      }
      else {
         if (GetTypeName(textPtr,typedefTypeInfo,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->th.sizeInMAUs == 0)
         typeInfo->th.sizeInMAUs = 4;     /* default to 4 bytes */
      if (invalidAddress)
         strcat((LPSTR)*textPtr,unknownString);
      else {
         if ((error = GetEditValue(textPtr, addr, typeInfo)) != GOOD)
            strcat((LPSTR)*textPtr,unknownString);
      }
      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;
}

/***********************************************************************
**
**  GetPointerTypeInfo :
**
*********************************************************************/
VOID PRIVATE GetPointerTypeInfo(TYPE_SUBHEADER_TYPE *typeHeader,
                                TYPE_SUBHEADER_TYPE **typeInfo,
                                U8 *indirectionLevels)  {

   while (typeHeader != NULL) {
      if (IsPointer(&typeHeader->th))
         (*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->th.typeChoice == COMPLEX_TYPE_CLASS) {
      switch(typeHeader->th.t.complexType) {
         case TY_C_ARRAY:
            (*arrayIndirectionLevels)++;
            GetArrayTypeInfo(typeHeader->next,typeInfo,ptrIndirectionLevels,
                  arrayIndirectionLevels);
            break;
         case TY_SMALL_PTR:
         case TY_LARGE_PTR:
         case TY_16_16_PTR:
         case TY_16_32_PTR:
            (*ptrIndirectionLevels)++;
            GetArrayTypeInfo(typeHeader->next,typeInfo,ptrIndirectionLevels,
                  arrayIndirectionLevels);
            break;
         default:
            *typeInfo = typeHeader;
            break;
      }
   }
   else
      *typeInfo = typeHeader;
}

/***********************************************************************
**
**  CheckStructOrUnionOrEnum :
**
**  NOTE: 10/11/94 check the type name to see if it already contains the
**  keyword struct, union, or enum.  We don't want to display it twice.
**
*********************************************************************/
VOID PRIVATE CheckStructOrUnionOrEnum(STRING *textPtr,
                                      TYPE_SUBHEADER_TYPE *typeHeader)  {

   switch (typeHeader->th.t.complexType)  {
      case TY_STRUCT :
         if (_fstrnicmp(structString,(LPSTR)typeHeader->th.typeName,
               strlen(structString)) != GOOD) {
            strcat((LPSTR)*textPtr,structString);
            *textPtr += lstrlen((LPSTR)*textPtr);
         }
         break;
      case TY_UNION :
         if (_fstrnicmp(unionString,(LPSTR)typeHeader->th.typeName,
               strlen(unionString)) != GOOD) {
            strcat((LPSTR)*textPtr,unionString);
            *textPtr += lstrlen((LPSTR)*textPtr);
         }
         break;
      case TY_ENUM_C :
         if (_fstrnicmp(enumString,(LPSTR)typeHeader->th.typeName,
               strlen(enumString)) != GOOD) {
            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 :
**
**************************************************************************/
RETCODE PRIVATE GetCharValue(STRING *textPtr,
                             LPU8 buffer,
                             GET_VAR_ADDR_STRUCT *addr,
                             DISPLAY_FORMAT dispValueRadix,
                             BOOLEAN dispValueEdit,
                             U8 *formatStr) {

   U8 *charPtr;
   VS_STRING_TYPE tempStr;
   BOOLEAN printable = TRUE;  
   BOOLEAN achar = FALSE;
   BOOLEAN string = FALSE;


   memset((LPSTR)tempStr,'\0',sizeof(VS_STRING_TYPE));
   if ((dispValueRadix == DF_ASCII) && (varTable[varIndex].dereferencedPtr)) 
      return(GetStringValue(textPtr,buffer,addr,DF_STRING,
                            FALSE,(LPU8)"%.*s"));
   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);
            achar = TRUE;
         }
         break;
      case DF_STRING :
         printable = isprint(*charPtr);
         if (printable) {
            strcat((LPSTR)*textPtr,equalString);
            *textPtr += strlen((LPSTR)*textPtr);
            strcat((LPSTR)*textPtr,(LPSTR)doubleQuote);      /* " */
            *textPtr += strlen((LPSTR)*textPtr);
            string = TRUE;
         }
         break;
      case DF_BINARY :
         break;
     default:
         break;
   }
   if (!printable)
      return GOOD;
   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      if (!string)
         sprintf((LPSTR)tempStr,(LPSTR)formatStr,*charPtr);
      else {
         /* format string %.*s */
         /* 05/03/95 Marilyn: 
         ** check each character for isprintable, unprintable
         ** or not ascii (0x0 to 0x7F) substitute the nonpritable char.
         */
         LPSTR tmpCharPtr = (LPSTR)charPtr;
         U32 strLen = strlen((LPSTR)charPtr);
         if (strLen > VS_MAX_DISPLAYED_STR)
            strLen = VS_MAX_DISPLAYED_STR;
         while (strLen > 0) {
            if (isascii(*tmpCharPtr) && isprint(*tmpCharPtr))
               strncat((LPSTR)tempStr,(LPSTR)tmpCharPtr,1);
            else
               strcat((LPSTR)tempStr,(LPSTR)nonPrintableChar);
            tmpCharPtr++;
            strLen--;
         }
      }
      if (strlen((LPSTR)tempStr) >= VS_MAX_DISPLAYED_STR) {
         strncat((LPSTR)*textPtr,(LPSTR)tempStr,VS_MAX_DISPLAYED_STR);
         strcat((LPSTR)*textPtr,"...");
      }
      else {
         strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      }
      // Increment pointer to the end
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
   if (achar) {
      strcat((LPSTR)*textPtr,(LPSTR)singleQuote);      /* ' */
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if (string) {
      strcat((LPSTR)*textPtr,(LPSTR)doubleQuote);      /* " */
      *textPtr += strlen((LPSTR)*textPtr);
   }
      
   return GOOD;
}

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

   U32 *intPtr;
   U32 numByte=0L;
   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 */
      if (ConvertFloat32(*intPtr, &fpValue) != GOOD)
         strcpy((LPSTR)*textPtr,(LPSTR)unknownFloat);
      else {
         numByte = sprintf((LPSTR)*textPtr,(LPSTR)formatStr,fpValue);
         if (!numByte)
            strcpy((LPSTR)*textPtr,(LPSTR)unknownFloat);
      }
      *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 */
   U32 numByte=0L;
   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 */
      if (ConvertDouble64(intPtr, &dValue) != GOOD)
         strcpy((LPSTR)*textPtr,(LPSTR)unknownFloat);
      else {
         numByte = sprintf((LPSTR)*textPtr,(LPSTR)formatStr,dValue);
         if (!numByte)
            strcpy((LPSTR)*textPtr,(LPSTR)unknownFloat);
      }
      *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,
                                   U32 extendedSize) {

   U8 *bPtr;  /* need byte pointer */
   U32 numByte=0L;
   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 */
      if (ConvertLongDouble(bPtr, extendedSize, &ldValue) != GOOD)
         strcpy((LPSTR)*textPtr,(LPSTR)unknownFloat);
      else {
         numByte = sprintf((LPSTR)*textPtr,(LPSTR)formatStr,ldValue);
         if (!numByte)
            strcpy((LPSTR)*textPtr,(LPSTR)unknownFloat);
      }
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
}

/*************************************************************************
**
**  Get128FloatValue :
**
**************************************************************************/
#pragma argsused
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;
   U8 *qPtr;  /* pointer to 128-bit value */
#endif
   VS_STRING_TYPE tempStr;
   long double qValue = 0;  /* !! insufficient to represent in Borland */

#if 0
   LLDoublePtr = (long long double *)buffer;
   qPtr = (U8 *)TMalloc(16);
#endif
   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 :
**
**************************************************************************/
#pragma argsused
RETCODE PRIVATE GetStringValue(STRING *textPtr,
                               LPU8 buffer,
                               GET_VAR_ADDR_STRUCT *addr,
                               DISPLAY_FORMAT dispValueRadix,
                               BOOLEAN dispValueEdit,
                               U8 *formatStr) {

   LPU8 strPtr;
   VS_STRING_TYPE tempStr;
   BOOLEAN alternateAccess = FALSE;
   RETCODE err = GOOD;
   U32 savedSize = 0;
   U32 strLen = 0;

   memset((LPSTR)tempStr,'\0',sizeof(VS_STRING_TYPE));
   // for a string we should read a larger chunk of memory
   // say VS_MAX_BUF-1.  So save the original typeinfo size
   savedSize = varTable[varIndex].typeInfo.th.sizeInMAUs;
   varTable[varIndex].typeInfo.th.sizeInMAUs = VS_MAX_BUF - 1;
   if ((err = GetEditValueToBuffer(&varTable[varIndex].typeInfo,
         addr,textPtr,&buffer,&alternateAccess)) != GOOD)
      return err;
   varTable[varIndex].typeInfo.th.sizeInMAUs = savedSize;
   if (alternateAccess)
      return GOOD;
   strcat((LPSTR)*textPtr,equalString);
   *textPtr += strlen((LPSTR)*textPtr);
   strcat((LPSTR)*textPtr,(LPSTR)doubleQuote);      /* " */
   *textPtr += strlen((LPSTR)*textPtr);
   strPtr = buffer;

   if ((dispValueEdit) && (anotatedText)) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   if (dispValueRadix != DF_NODISP) {
      LPSTR tmpCharPtr = (LPSTR)strPtr;
      strLen = strlen((LPSTR)strPtr);
      if (strLen > VS_MAX_DISPLAYED_STR)
         strLen = VS_MAX_DISPLAYED_STR;
      while (strLen > 0) {
         if (isascii(*tmpCharPtr) && isprint(*tmpCharPtr))
            strncat((LPSTR)tempStr,(LPSTR)tmpCharPtr,1);
         else
            strcat((LPSTR)tempStr,(LPSTR)nonPrintableChar);
         tmpCharPtr++;
         strLen--;
      }
      strLen = strlen((LPSTR)tempStr);
      if (strLen > VS_MAX_DISPLAYED_STR) {  /* > 60  chars */
         strncat((LPSTR)*textPtr,(LPSTR)tempStr,VS_MAX_DISPLAYED_STR);
         strcat((LPSTR)*textPtr,"...");
      }
      else {
         strcat((LPSTR)*textPtr,(LPSTR)tempStr);
      }
      *textPtr += strlen((LPSTR)*textPtr);
   }
   if ((dispValueEdit) && (anotatedText))
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
   *textPtr += strlen((LPSTR)*textPtr);
   strcat((LPSTR)*textPtr,(LPSTR)doubleQuote);      /* " */
   *textPtr += strlen((LPSTR)*textPtr);
   if ((err = TFree((LPSTR)buffer)) != GOOD)
      return err;
   return GOOD;
}

/*************************************************************************
**
**  GetPointerValue :
**
**************************************************************************/
RETCODE PRIVATE GetPointerValue(STRING *textPtr,
                                TYPE_SUBHEADER_TYPE *typeInfo,
                                COMPLEX_TYPE ptrType,
                                GET_VAR_ADDR_STRUCT *varAddr,
                                LPU8 buffer) {

   GET_VAR_ADDR_STRUCT newAddr;
   CHAR ptrValueText[ADDR_BUFF_SZ];
   LPSTR tmpPtrValueText = ptrValueText;
   LPSTR tempPtr = NULL;
   U32 segStrLen = 0;
   RETCODE err;

   if (procFamily == FAMILY_68K) {

      // NOTES: Nghia - 10/27/93
      // Handle both 2 bytes and 4 bytes pointer type
      if (typeInfo->th.sizeInMAUs > 2) {
         U32 *value4BytePtr;
         value4BytePtr = (U32 *)buffer;
         sprintf(tmpPtrValueText,"%8.8lX",*value4BytePtr);
      } else {
         U16 *value2BytePtr;
         value2BytePtr = (U16 *)buffer;
         sprintf(tmpPtrValueText,"%4.4X",*value2BytePtr);
      }
   }
   else {
      newAddr.getFixedAddrDesc = NULL;
      if ((err = GetPtrDereference(varRegisterClass, varStorageClass, 
            typeInfo, ptrType, 0, varFrameNum, varTable[varIndex].frameType,
            varAddr, &newAddr)) != GOOD)
         return err;
      if ((err = AdrConvAddressToText(newAddr.getFixedAddrDesc, ptrValueText))
            != GOOD)
         return err;
      if ((err = AdrCremateAddress(&newAddr.getFixedAddrDesc)) != GOOD)
         return err;
   }

   switch (ptrType) {
      case TY_16_16_PTR:
      case TY_16_32_PTR:
         break;
      case TY_LARGE_PTR:
      case TY_SMALL_PTR:
      default:
         if (procFamily == FAMILY_X86) { /* DS:<offset> */
            tempPtr = _fstrpbrk(tmpPtrValueText,pointerOps);
            if (tempPtr != NULL) {
               segStrLen = tempPtr - tmpPtrValueText + 1;
               strncpy((LPSTR)*textPtr,tmpPtrValueText,segStrLen);
               tmpPtrValueText += segStrLen;
               *textPtr += lstrlen((LPSTR)*textPtr);
            }
         }
         else {   /* 0x<offset> */
            strcat((LPSTR)*textPtr,"0x");
            *textPtr += lstrlen((LPSTR)*textPtr);
         }
         break;
   }
   if (anotatedText) {
      **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
      (*textPtr)++;
   }
   strcat((LPSTR)*textPtr,(LPSTR)tmpPtrValueText);
   *textPtr += lstrlen((LPSTR)*textPtr);
   if (anotatedText) {
      **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
      *textPtr += lstrlen((LPSTR)*textPtr);
   }
   return GOOD;
}
/*************************************************************************
**
**  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->th.typeChoice == SIMPLE_TYPE_CLASS) {
      switch (typeInfo->th.t.simpleType) {
         case BI_S8_SCHAR: case BI_U8_UCHAR: case BI_S8_CHAR:
            /*
            ** signed and unsigned chars
            */
            switch (radix) {
               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;
               default: break;
            }
            break;
         case BI_S16_SINT: case BI_STACK_INT: case BI_S16_SHORT:
         case  BI_S16_SHORTINT: case BI_S16_SSHORT:
            /*
            ** signed ints
            */
            switch (radix) {
               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:  break;
            }
            break;
         case BI_U16_UINT: case BI_STACK_U: case BI_STACK_UINT:
         case BI_S16_USHORT:
            /*
            ** unsigned ints
            */
            switch (radix) {
               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;
               default: break;
            }
            break;
         case BI_S32_SLONG: case BI_S32_LONG:
            /*
            ** signed long
            */
            switch (radix) {
               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;
               default: break;
            }
            break;
         case BI_U32_ULONG:
            /*
            ** unsigned long
            */
            switch (radix) {
               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;
               default: 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:
            /*
            **  floats and doubles
            */
            switch (radix) {
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  break;
               case DF_FLOAT:
               case DF_DOUBLE:
               case DF_LDOUBLE:
                  // 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;
               default: break;
            }
           break;
         case BI_STRING:
            /*
            **  strings
            */
            switch (radix) {
               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;
              default: break;
            }
           break;
         case BI_P_S8_SCHAR:     case BI_P_U8_UCHAR:   case BI_P_S16_SINT:
         case BI_P_U16_UINT:     case BI_P_S32_SLONG:  case BI_P_U32_ULONG:
         case BI_P_S64_SLONG:    case BI_P_U64_ULONG:  case BI_P_F32:
         case BI_P_F64:          case BI_P_F_EXTEND:   case BI_P_F128:
         case BI_P_STRING:       case BI_P_JUMP:       case BI_P_STACK_INT:
         case BI_P_STACK_U:      case BI_P_STACK_UINT: case BI_P_S8_CHAR:
         case BI_P_S32_LONG:     case BI_P_S16_SHORT:  case BI_P_S16_USHORT:
         case BI_P_S16_SHORTINT: case BI_P_S16_SSHORT: case BI_P_F64_BCD:
            /*
            **  pointers
            */
            strcat((LPSTR)charSetBuf,(LPSTR)digits);
            strcat((LPSTR)charSetBuf,(LPSTR)lowerCase);
            strcat((LPSTR)charSetBuf,(LPSTR)upperCase);
            if (procFamily == FAMILY_X86)
               strcat((LPSTR)charSetBuf,(LPSTR)pointerOps);
            break;
         default:
            break;
      }
   }
   else {
      switch (typeInfo->th.t.complexType) {
         case TY_SMALL_PTR:
         case TY_LARGE_PTR:
         case TY_16_16_PTR:
         case TY_16_32_PTR:
            /*
            **  pointers
            */
            strcat((LPSTR)charSetBuf,(LPSTR)digits);
            strcat((LPSTR)charSetBuf,(LPSTR)lowerCase);
            strcat((LPSTR)charSetBuf,(LPSTR)upperCase);
            if (procFamily == FAMILY_X86)
               strcat((LPSTR)charSetBuf,(LPSTR)pointerOps);
            break;
         case TY_ENUM_C:
         case TY_BITFIELD:
         case TY_VOID:
           // 05/15/95 - Nghia
           // Added TY_VOID to getCharSetForType()
           switch (radix) {
               case DF_DECIMAL:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  break;
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  break;
               default: break;
            }
            break;
         case TY_TYPE: {
            TYPE_SUBHEADER_TYPE *baseTypeInfo=NULL,
                                *typeTypeInfo=NULL;
            CheckForTypedef(typeInfo,&typeTypeInfo,&baseTypeInfo);
            if (baseTypeInfo->th.typeChoice == COMPLEX_TYPE_CLASS)
               GetCharSetForType(baseTypeInfo,DF_HEX);
            else
               GetCharSetForType(baseTypeInfo,
                typeTable[baseTypeInfo->th.t.simpleType].primaryRadix);
            }
            break;
         default:
           switch (radix) {
               case DF_DECIMAL:
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  break;
               case DF_HEX:
                  strcat((LPSTR)charSetBuf,(LPSTR)hexDigits);
                  strcat((LPSTR)charSetBuf,(LPSTR)digits);
                  break;
               default: break;
            }
            break;
      }
   }
}

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

   VS_COMPONENT_TYPE *compPtr;
   VS_VAR_ENTRY_TYPE *varPtr;
   TYPE_SUBHEADER_TYPE *baseTypeInfo=NULL,
                       *typeTypeInfo=NULL;
   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
   //
   // IMPORTANT: 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
   *fieldWidth = 0;
   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.th.typeName = (LPSTR)typeInfo.typeNameStr;
      if ((typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS) &&
            (typeInfo.th.t.complexType == TY_TYPE)) {
         while (typeInfo.th.t.complexType == TY_TYPE) {
            if ((retcode = SymGetTypeTypeIndex(typeIndex,&typeIndex)) != GOOD)
               return retcode;
            if ((retcode = SymGetTypeHeader(typeIndex,
                  (TYPE_HEADER_TYPE *)&typeInfo)) != GOOD)
               return retcode;
            typeInfo.typeIndex = typeIndex;
         }
      }
      if (typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS) {
         if (IsPointer(&typeInfo.th)) {
             GetCharSetForType(&typeInfo,DF_HEX);
             *fieldWidth = GetPointerEditFieldWidth(typeInfo.th.t.complexType);       
         }
         else if ((typeInfo.th.t.complexType == TY_ENUM_C) ||
                  (typeInfo.th.t.complexType == TY_BITFIELD))  {
            GetCharSetForType(&typeInfo,DF_HEX);
            *fieldWidth = typeInfo.th.sizeInMAUs * HEX_DIGITS_PER_BYTE;
         }
      }
      else if (typeInfo.th.typeChoice == SIMPLE_TYPE_CLASS) {
         U32 useTypeIndex = typeInfo.th.t.simpleType;
         if (procStackSize == STACK_16BIT) {
            // override the stack push type with its 16 bit equivalent
            // since stack push type defaults to 32 bits
            switch (typeInfo.th.t.simpleType) {
               case BI_STACK_INT:
                  useTypeIndex = BI_S16_SINT;
                  break;
               case BI_STACK_U: case BI_STACK_UINT:
                  useTypeIndex = BI_U16_UINT;
                  break;
               default:
                  break;
            }
         }
         if (primaryEditField) {
            GetCharSetForType(&typeInfo,typeTable[useTypeIndex].primaryRadix);
            *fieldWidth = typeTable[useTypeIndex].primaryEditFieldSize;
         }
         else {
            GetCharSetForType(&typeInfo,typeTable[useTypeIndex].secondaryRadix);
            *fieldWidth = typeTable[useTypeIndex].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.
      ** Intel format XXXX:YYYYYYYY allows 13 characters max for ptr.
      ** 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.th.typeName = (LPSTR)typeInfo.typeNameStr;

      if ((typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS) &&
            (typeInfo.th.t.complexType == TY_TYPE)) {
         while (typeInfo.th.t.complexType == TY_TYPE) {
            if ((retcode = SymGetTypeTypeIndex(typeIndex,&typeIndex))
                  != GOOD)
               return retcode;
            if ((retcode = SymGetTypeHeader(typeIndex,
                  (TYPE_HEADER_TYPE *)&typeInfo)) != GOOD)
               return retcode;
            typeInfo.typeIndex = typeIndex;
            typeInfo.next = NULL;
         }
      }
      if (typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS) {
         if (IsPointer(&typeInfo.th)) {
             GetCharSetForType(&typeInfo,DF_HEX);
             *fieldWidth = GetPointerEditFieldWidth(typeInfo.th.t.complexType);
         }
         else if (typeInfo.th.t.complexType == TY_ENUM_C)  {
            GetCharSetForType(&typeInfo,DF_HEX);
            *fieldWidth = typeInfo.th.sizeInMAUs * HEX_DIGITS_PER_BYTE;
         }
         else if (typeInfo.th.t.complexType == TY_C_ARRAY) {
            // 05/16/95 - Nghia
            // Make sure that it's really an array type, else
            // it will GPF.
            /* must be an array type */
            GetSubArrayType(&typeInfo,&baseTypeInfo);
            CheckForTypedef(baseTypeInfo,&typeTypeInfo,&baseTypeInfo);
            if (baseTypeInfo->th.typeChoice == SIMPLE_TYPE_CLASS)  {
               if (primaryEditField) {
                  GetCharSetForType(baseTypeInfo,typeTable[baseTypeInfo->th.t.
                        simpleType].primaryRadix);
                  *fieldWidth = typeTable[baseTypeInfo->th.t.simpleType].
                        primaryEditFieldSize;
               }
               else {
                  GetCharSetForType(baseTypeInfo,typeTable[baseTypeInfo->th.t.
                        simpleType].secondaryRadix);
                  *fieldWidth = typeTable[baseTypeInfo->th.t.simpleType].
                        secondaryEditFieldSize;
               }
            }
            else { /* an array of a complex editable type */
               if (IsPointer(&baseTypeInfo->th)) {
                  GetCharSetForType(baseTypeInfo,0);
                  *fieldWidth = GetPointerEditFieldWidth(baseTypeInfo->
                        th.t.complexType);
               } else if (baseTypeInfo->th.t.complexType == TY_ENUM_C)  {
                  GetCharSetForType(baseTypeInfo,DF_HEX);
                  *fieldWidth = baseTypeInfo->th.sizeInMAUs
                                * HEX_DIGITS_PER_BYTE;
               } else if (varPtr && 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;
                  // 05/16/95 - Nghia
                  // GPF when inspect padding field - comPtr == NULL
                  for (i=0; (compPtr && (i < memberIndex));i++)
                     compPtr = compPtr->next;
                  
                  if ((compPtr->typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS)
                      && compPtr->typeInfo.th.t.complexType == TY_TYPE) {
                     CheckForTypedef(&compPtr->typeInfo,
                                     &typeTypeInfo, &baseTypeInfo);
                  }
                  else
                      baseTypeInfo = &compPtr->typeInfo;
                  if (baseTypeInfo->th.typeChoice == COMPLEX_TYPE_CLASS)  {
                     if (IsPointer(&baseTypeInfo->th)) {
                        GetCharSetForType(baseTypeInfo,0);
                        *fieldWidth = GetPointerEditFieldWidth(baseTypeInfo->
                              th.t.complexType);
                     }
                     else if (baseTypeInfo->th.t.complexType == TY_ENUM_C)  {
                        GetCharSetForType(baseTypeInfo,DF_HEX);
                        *fieldWidth = baseTypeInfo->th.sizeInMAUs
                                      * HEX_DIGITS_PER_BYTE;
                     }
                  } else {
                     if (primaryEditField) {
                        GetCharSetForType(baseTypeInfo,typeTable[
                              baseTypeInfo->th.t.simpleType].primaryRadix);
                        *fieldWidth = typeTable[baseTypeInfo->th.t.simpleType].
                              primaryEditFieldSize;
                     } else {
                        GetCharSetForType(baseTypeInfo,typeTable[baseTypeInfo->
                              th.t.simpleType].secondaryRadix);
                        *fieldWidth = typeTable[baseTypeInfo->th.t.simpleType].
                              secondaryEditFieldSize;
                     }
                  }
               }  /* else if compPtr == NULL fall through 
                  ** returning 0 for fieldwidth 

                  */
            }           
         } 
         else { // else (!TY_C_ARRAY) we don't know what it is 
                // default to typeInfo and size
            GetCharSetForType(&typeInfo,DF_HEX);
            *fieldWidth = typeInfo.th.sizeInMAUs * HEX_DIGITS_PER_BYTE;
         }
      }
      else {   /* a simple type */
         U32 useTypeIndex = typeInfo.th.t.simpleType;
         baseTypeInfo = &typeInfo;
         if (procStackSize == STACK_16BIT) {
            // override the stack push type with its 16 bit equivalent
            // since stack push type defaults to 32 bits
            switch (typeInfo.th.t.simpleType) {
               case BI_STACK_INT:
                  useTypeIndex = BI_S16_SINT;
                  break;
               case BI_STACK_U: case BI_STACK_UINT:
                  useTypeIndex = BI_U16_UINT;
                  break;
               default:
                  break;
            }
         }
         if (primaryEditField) {
            GetCharSetForType(baseTypeInfo,
                              typeTable[useTypeIndex].primaryRadix);
            *fieldWidth = typeTable[useTypeIndex].primaryEditFieldSize;
         }
         else {
            GetCharSetForType(baseTypeInfo,
                              typeTable[useTypeIndex].secondaryRadix);
            *fieldWidth = typeTable[useTypeIndex].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,
                        U16 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
   // Check for valid pointer edits
   if ( IsPointer(&varTable[varId].typeInfo.th))
      if ((retcode = CheckPointerEditValue(varId,newValueText)) != GOOD)
         goto CLEANUP;
   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,
         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)  {
   CHAR ptrBuf[6];      
   U8 *byteStream;
   LPU8 valueText,memBuf;
   STRING formatStr,valuePtr,searchPtr;
   TYPE_HEADER_TYPE typeInfo;
   VS_STRING_TYPE typeName;
   DESCRIPTOR tempAddr = NULL;
   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 ((procStackSize != STACK_32BIT) && (typeIndex == BI_STACK_INT)) {
         // override default 32 bit signed stack push by 
         // substituting 16 bit signed type BI_S16_SINT
         if ((formatStr = GetFormatString(editMarkCount,
                                          BI_S16_SINT,
                                          SCAN_FORMAT)) == NULL) {
            error = ER_VS_VALU_EDIT_FAIL;
            goto CLEANUP;
         }
      } 
      else if ( (procStackSize != STACK_32BIT) &&
                ( (typeIndex == BI_STACK_U) ||
                  (typeIndex == BI_STACK_UINT) ) ) {
         // override default 32 bit unsigned stack push by
         // substituting 16 bit unsigned type BI_U16_UINT
         if ((formatStr = GetFormatString(editMarkCount,
                                          BI_U16_UINT,
                                          SCAN_FORMAT)) == NULL) {
            error = ER_VS_VALU_EDIT_FAIL;
            goto CLEANUP;
         }
      }
      else {
         if ((formatStr = GetFormatString(editMarkCount,
                                          typeIndex,
                                          SCAN_FORMAT)) == NULL) {
            error = ER_VS_VALU_EDIT_FAIL;
            goto CLEANUP;
         }
      }
   }
   else {
      /* Some type of pointer value or enum  */
      if (IsPointer(&varTable[varId].typeInfo.th)) {
         if ((error = SymGetTypeHeader(typeIndex,&typeInfo)) != GOOD)
            goto CLEANUP;
         if ((error = AdrDuplicateAddress(addr->getFixedAddrDesc,
               &tempAddr)) != GOOD)
            goto CLEANUP;
         if ((error = AdrConvTextToAddress(tempAddr,(LPSTR)valueText)) != GOOD)
            goto CLEANUP;
         if ((error = AdrConvertAddressToPointer(tempAddr,
               typeInfo.sizeInMAUs,
               typeInfo.t.complexType,(LPU8)ptrBuf)) != GOOD)
            goto CLEANUP;
         if ((error = AdrCremateAddress(&tempAddr)) != GOOD)
            goto CLEANUP;
         byteStream = (U8 *)ptrBuf;   

         // 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, ptrBuf, typeInfo.sizeInMAUs);
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                            typeInfo.sizeInMAUs,
                            varTable[varId].frameNum,
                            varTable[varId].frameType,memBuf) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               memmove(memBuf, ptrBuf, typeInfo.sizeInMAUs);
               if (MemWriteSized(addr->getFixedAddrDesc,
                                 typeInfo.sizeInMAUs,
                                 memBuf,
                                 SIZE_BYTE) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case REG_WRITE:
               // 6 byte ptrs don't fit into registers so no problem.
               // 2 and 4 byte pointers use the DS so only the offset
               // portion of the ptr is written to a register, the
               // segment portion of the ptr is not editable.
               if (CpuSetRegister(addr->addrData.getRegisterIndex.
                     varLivingReg,*(U32 *)ptrBuf) != GOOD)  {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
         }
         error = GOOD;
         goto CLEANUP;
      }
      else {
         /*
         **  must be an enum or something strange
         */
         U8 enumByte;
         U16 enumShort;
         U32 enumInt;
         U32 enumValue;

         if ((error = 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 0:  // if no size default to 4 bytes and drop thru
               typeInfo.sizeInMAUs = 4;
            case 4:
               sscanf((LPSTR)valueText,"%lX",&enumInt);
               byteStream = (U8 *)&enumInt;
               if (writeType != REG_WRITE) FlipBuffer(byteStream,4);
               enumValue = enumInt;
               break;
            default:
               error = 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)   {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               memmove(memBuf,&enumValue,typeInfo.sizeInMAUs);
               if (MemWriteSized(addr->getFixedAddrDesc,typeInfo.sizeInMAUs,
                     memBuf,SIZE_BYTE) != GOOD)  {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case REG_WRITE:
               if (CpuSetRegister(addr->addrData.getRegisterIndex.
                     varLivingReg,enumValue) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
         }
         error = GOOD;
         goto CLEANUP;
      }
   }
   switch(typeIndex) {
      case BI_S8_SCHAR: case BI_U8_UCHAR: case BI_S8_CHAR: {    /* 8 bits */
         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) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               memmove(memBuf,&tempS8,sizeof(tempS8));
               if (MemWriteSized(addr->getFixedAddrDesc,sizeof(tempS8),
                     memBuf,SIZE_BYTE) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case REG_WRITE:
               if (CpuSetRegister(addr->addrData.getRegisterIndex.
                     varLivingReg,(U32)tempS8) != GOOD)  {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               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:  {
         S16 tempS16 = 0;
         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) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               memmove(memBuf,&tempS16,sizeof(tempS16));
               if (MemWriteSized(addr->getFixedAddrDesc,sizeof(tempS16),
                     memBuf,SIZE_BYTE) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case REG_WRITE:
               if (CpuSetRegister(addr->addrData.getRegisterIndex.
                     varLivingReg,(U32)tempS16) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
         }
         break;
      }
      case BI_S32_SLONG: case BI_U32_ULONG: case BI_F32:
      case BI_S32_LONG: { /* 32 bits */
         S32 tempS32 = 0;
         if ((retcode = CheckForIntegerOverflow(varId, newValueText, 32, 
               (typeIndex != BI_U32_ULONG))) != 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) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               memmove(memBuf,&tempS32,sizeof(tempS32));
               if (MemWriteSized(addr->getFixedAddrDesc,sizeof(tempS32),
                     memBuf,SIZE_BYTE) != GOOD)   {
                   error = ER_VS_VALU_EDIT_FAIL;
                   goto CLEANUP;
               }
               break;
            case REG_WRITE:
               if (CpuSetRegister(addr->addrData.getRegisterIndex.
                     varLivingReg,(U32)tempS32) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
         }
         break;
      }
      case BI_STACK_INT: case BI_STACK_U: case BI_STACK_UINT: {
         if (procStackSize == STACK_16BIT) {
            S16 tempS16 = 0;
            if ((retcode = CheckForIntegerOverflow(varId, newValueText, 16, 
                  ((typeIndex != BI_STACK_U) && 
                   (typeIndex != BI_STACK_UINT)))) != 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) {
                     error = ER_VS_VALU_EDIT_FAIL;
                     goto CLEANUP;
                  }
                  break;
               case MEM_WRITE:
                  memmove(memBuf,&tempS16,sizeof(tempS16));
                  if (MemWriteSized(addr->getFixedAddrDesc,sizeof(tempS16),
                        memBuf,SIZE_BYTE) != GOOD) {
                     error = ER_VS_VALU_EDIT_FAIL;
                     goto CLEANUP;
                  }
                  break;
               case REG_WRITE:
                  if (CpuSetRegister(addr->addrData.getRegisterIndex.
                        varLivingReg,(U32)tempS16) != GOOD) {
                     error = ER_VS_VALU_EDIT_FAIL;
                     goto CLEANUP;
                  }
                  break;
            }
         }
         else { // procStackSize == STACK_32BIT or 4 bytes
            S32 tempS32 = 0;
            if ((retcode = CheckForIntegerOverflow(varId, newValueText, 32, 
                  ((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) {
                     error = ER_VS_VALU_EDIT_FAIL;
                     goto CLEANUP;
                  }
                  break;
               case MEM_WRITE:
                  memmove(memBuf,&tempS32,sizeof(tempS32));
                  if (MemWriteSized(addr->getFixedAddrDesc,sizeof(tempS32),
                        memBuf,SIZE_BYTE) != GOOD)   {
                      error = ER_VS_VALU_EDIT_FAIL;
                      goto CLEANUP;
                  }
                  break;
               case REG_WRITE:
                  if (CpuSetRegister(addr->addrData.getRegisterIndex.
                        varLivingReg,(U32)tempS32) != GOOD) {
                     error = ER_VS_VALU_EDIT_FAIL;
                     goto CLEANUP;
                  }
                  break;
            }
         }
         break;
      }
      case BI_S64_SLONG: case BI_U64_ULONG: case BI_F64: case BI_F64_BCD:  {       /* 64 bits */
         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) {
                  error = 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. */
              memcpy(memBuf, byteStream, sizeof(double));
              if (MemWriteSized(addr->getFixedAddrDesc, sizeof(double),
                  memBuf, SIZE_BYTE) != GOOD) {
                  error = 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;
               */
               error = ER_VS_DOUBLE_EDIT_FAIL;
               goto CLEANUP;
         }
         break;
      }
      case BI_F_EXTEND: case BI_F128:  {             /*  80 to 128 bits */
         long double templD = 0;
         sscanf((LPSTR)valueText,(LPSTR)formatStr,&templD);
         byteStream = (U8 *)&templD;
         if (writeType != REG_WRITE) FlipBuffer(byteStream,sizeof(templD));
         switch (writeType) {
            case STACK_WRITE:
               memmove(memBuf,&templD,sizeof(templD));
               if (StkWrite(addr->addrData.getAutoVar.autoVarOffset,
                     sizeof(templD),varTable[varId].frameNum,
                     varTable[varId].frameType,memBuf) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               memmove(memBuf,&templD,sizeof(templD));
               if (MemWriteSized(addr->getFixedAddrDesc,sizeof(templD),
                     memBuf,SIZE_BYTE) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case REG_WRITE:
               // NOTES: 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;
               error = 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) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case MEM_WRITE:
               memmove(memBuf,tempStr,VS_MAX_STRING);
               if(MemWriteSized(addr->getFixedAddrDesc,strlen((LPSTR)tempStr),
                     memBuf,SIZE_BYTE) != GOOD) {
                  error = ER_VS_VALU_EDIT_FAIL;
                  goto CLEANUP;
               }
               break;
            case REG_WRITE:
               break;
         }
         break;
      }
   }

CLEANUP:
   if ((error = TFree((LPSTR)valueText)) != GOOD)
      return error;
   if (tempAddr != NULL)
      if ((error = AdrCremateAddress(&tempAddr)) != GOOD)
         return error;
   if (retcode != GOOD) /* CheckForIntegerOverflow found an error */
      return retcode;
   return GOOD;
}

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

   VS_COMPONENT_TYPE *compPtr;
   TYPE_SUBHEADER_TYPE *baseTypeInfo;
   TYPE_SUBHEADER_TYPE *typeTypeInfo;
   U32 byteOffset;
   S32 autoOffset;
   U16 memberIndex;
   ARRAY_LIST_NODE *arrayNode;
   LOOP_VAR i;
   RETCODE error;
   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.th.typeName = (LPSTR)typeInfo.typeNameStr;

      if ((typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS) &&
            (typeInfo.th.t.complexType == TY_TYPE)) {
         while (typeInfo.th.t.complexType == TY_TYPE) {
            if ((error = SymGetTypeTypeIndex(typedefTypeIndex,
                  &typedefTypeIndex)) != GOOD)
               return error;
            if ((error = SymGetTypeHeader(typedefTypeIndex,
                  (TYPE_HEADER_TYPE *)&typeInfo)) != GOOD)
               return error;
            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);
            if ((error = StkCalcStkOffset(&elementAddr->addrData.
                     getAutoVar.autoVarOffset,autoOffset)) != GOOD)
                  return error;

         }
         else {
            /* STATIC_VAR_CLASS, GLOBAL_VAR_CLASS, UNKNOWN_VAR_CLASS */
            if ((error = AdrDuplicateAddress(varTable[varId].address.
                  getFixedAddrDesc,&elementAddr->getFixedAddrDesc)) != GOOD)
               return error;
            if ((error = AdrAddToAddress(elementAddr->
                  getFixedAddrDesc,compPtr->offset)) != GOOD)
               invalidAddress = TRUE;
         }
      }
      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.th.typeName = (LPSTR)typeInfo.typeNameStr;

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

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

      if ((typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS) &&
            (typeInfo.th.t.complexType == TY_TYPE)) {
         while (typeInfo.th.t.complexType == TY_TYPE) {
            if ((error = SymGetTypeTypeIndex(typedefTypeIndex,
                  &typedefTypeIndex)) != GOOD)
               return error;
            if ((error = SymGetTypeHeader(typedefTypeIndex,
                  (TYPE_HEADER_TYPE *)&typeInfo)) != GOOD)
               return error;
            typeInfo.typeIndex = typedefTypeIndex;
         }
      }
      if (typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS) {
         // an editable complex type which includes pointers,
         // enums, and arrays of editable types.
         if (IsPointer(&typeInfo.th) ||
               (typeInfo.th.t.complexType == TY_ENUM_C)) {
            *typeIndex = typeInfo.typeIndex;
            *addr = &varTable[varId].address;
         }
         else {
            if ((varTable[varId].registerClass == NOT_REG) &&
                  (varTable[varId].storageClass == AUTO_VAR_CLASS)) {
               // An 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 ((error = MapArrayLine2Offset(&varTable[varId].typeInfo,
                     ((bufferNum * VS_MAX_BUFFER_LINES) + lineNum),0,
                     &byteOffset,&memberIndex,typeIndex,&arrayNode,
                     NULL)) != GOOD)
                  return error;
               autoOffset = (S32)byteOffset;
               if (elementAddr->addrData.getAutoVar.autoVarOffset > 0)
                  autoOffset = (S32)(-autoOffset);
               if ((error = StkCalcStkOffset(&elementAddr->addrData.
                     getAutoVar.autoVarOffset,autoOffset)) != GOOD)
                  return error;
               *addr = elementAddr;
            }
            else {
               if ((varTable[varId].registerClass == NOT_REG) &&
                     (varTable[varId].storageClass != AUTO_VAR_CLASS))  {
                  // An 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 ((error = MapArrayLine2Offset(&varTable[varId].typeInfo,
                        ((bufferNum * VS_MAX_BUFFER_LINES) + lineNum),0,
                        &byteOffset,&memberIndex,typeIndex,&arrayNode,
                        NULL)) != GOOD)
                     return error;
                  if ((error = AdrDuplicateAddress((*addr)->getFixedAddrDesc,
                        &elementAddr->getFixedAddrDesc)) != GOOD)
                     return error;
                  if ((error = AdrAddToAddress(elementAddr->
                        getFixedAddrDesc,byteOffset)) != GOOD)
                     invalidAddress = TRUE;
                  *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);
            CheckForTypedef(baseTypeInfo,&typeTypeInfo,&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;
                  if ((compPtr->typeInfo.th.typeChoice == COMPLEX_TYPE_CLASS)
                      && compPtr->typeInfo.th.t.complexType == TY_TYPE) {
                     CheckForTypedef(&compPtr->typeInfo,&typeTypeInfo,
                           &baseTypeInfo);
                  }
                  else
                      baseTypeInfo = &compPtr->typeInfo;
                  *typeIndex = baseTypeInfo->typeIndex;
                  if (baseTypeInfo->th.t.complexType == TY_UNION)
                     *unionEdit = TRUE;
               }
            }
         }
      }
      else {
         if (typeInfo.th.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,
                               FORMAT_STRING_TYPE formatType) {
   switch(editMarkCount) {
      case 1:
         if (formatType == PRINT_FORMAT)
            return(typeTable[typeIndex].primaryPrintFormatStr);
         else if (formatType == SCAN_FORMAT)
            return(typeTable[typeIndex].primaryScanFormatStr);
         break;
      case 2:
         if (formatType == PRINT_FORMAT)
            return(typeTable[typeIndex].secondaryPrintFormatStr);
         else if (formatType == SCAN_FORMAT)
            return(typeTable[typeIndex].secondaryScanFormatStr);
         break;
      default:
         return (NULL);
   }
   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 error = 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) {
               error = ER_VS_USHORT_OVERFLOW;
            }
            else if (textLen == 5) {
               if (lstrcmp(unsignedText, MAX_U16_VAL) > 0) {
                  error = ER_VS_USHORT_OVERFLOW;
               }
            }
         }
         break;
         case 32: {
            if (textLen > 10) {
               error = ER_VS_ULONG_OVERFLOW;
            }
            else if (textLen == 10) {
               if (lstrcmp(unsignedText, MAX_U32_VAL) > 0) {
                  error = ER_VS_ULONG_OVERFLOW;
               }
            }
         }
      }
   }
   else { /* a signed integer */
      switch(length) {
         case 16: {
            if (textLen > 5) {
               error = ER_VS_SHORT_OVERFLOW;
            }
            else if (textLen == 5) {
               if (!negative && lstrcmp(unsignedText, MAX_S16_VAL) > 0) {
                  error = ER_VS_SHORT_OVERFLOW;
               }
               else if (negative && lstrcmp(unsignedText, MIN_S16_VAL) > 0) {
                  error = ER_VS_SHORT_OVERFLOW;
               }
            }
         }
         break;
         case 32: {
            if (textLen > 10) {
               error = ER_VS_LONG_OVERFLOW;
            }
            else if (textLen == 10) {
               if (!negative && lstrcmp(unsignedText, MAX_S32_VAL) > 0) {
                  error = ER_VS_LONG_OVERFLOW;
               }
               else if (negative && lstrcmp(unsignedText, MIN_S32_VAL) > 0) {
                  error = ER_VS_LONG_OVERFLOW;
               }
            }
         }
      }
   }
   TFree((LPSTR)valueText);
   TFree((LPSTR)unsignedText);
   return (error);
}

/**********************************************************************
**
** 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);
}

/***********************************************************************
**
**  CheckPointerEditValue:
**
**  Description:
**    This routine verifies that the tokens of the pointer edit
**    are valid for an address. 
**
**  Parameters:
**    varId (in): the symbol Id of the variable
**    newValueText (in): the text representation of the new value
**
************************************************************************/
#pragma argsused
RETCODE PRIVATE CheckPointerEditValue(DESCRIPTOR varId,
                                 LPSTR newValueText) {

   if (procFamily == FAMILY_68K)
      return GOOD; // address server verifies address
   else {
      // look for ':' token, if no token disallow a physical
      // or linear format address.
      if (_fstrpbrk(newValueText,":") == NULL) {  
         // single token 
         if (_fstrpbrk(newValueText,"lL") != NULL)
            return ER_VS_ILLEGAL_PTR_EDIT;
         if (_fstrpbrk(newValueText,"pP") != NULL)
            return ER_VS_ILLEGAL_PTR_EDIT;
      }
   }
   return GOOD;
}

/*************************************************************************
**
**  GetBitfieldValue:        
**     For LSB:
**     1. Bitwise and value by the mask indexed by the size and offset.
**     2. Shift value by offset.
**     For MSB:
**     1.  bitwise and the value to clear upper bits
**     2.  shift value by shift factor - size
**
**************************************************************************/
RETCODE PRIVATE GetBitfieldValue(STRING *textPtr,
                                 LPU8 buffer,
                                 TYPE_SUBHEADER_TYPE *typeInfo,
                                 U16 bitOffset,
                                 BF_ORIENTATION bitfieldType) {
   U8 byteValue;
   U16 wordValue;
   U32 longValue;
   U8 *bytePtr;
   U16 *wordPtr;
   U32 *longPtr;

   switch (typeInfo->th.sizeInMAUs) { /* current base type size */
      case 1: /* byte */
         bytePtr = (U8 *)buffer;
         byteValue = *bytePtr;
         strcat((LPSTR)*textPtr,"[0x");
         *textPtr += strlen((LPSTR)*textPtr);
         if (anotatedText) 
            **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"%02x",byteValue);
         *textPtr += strlen((LPSTR)*textPtr);
         if (anotatedText)
            **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"]:%d = ",typeInfo->
               bitfieldInfo.bField.size);
         *textPtr += strlen((LPSTR)*textPtr);
         if (bitfieldType == BF_LSB) {
            byteValue &= bfByteTable[(sizeof(U8) * BITS_PER_BYTE) - 
                  (typeInfo->bitfieldInfo.bField.size + 
                  bitOffset)].mask.byteMask;
            byteValue >>= bitOffset;
         }
         else if (bitfieldType == BF_MSB) {
            byteValue &= bfByteTable[bitOffset].mask.byteMask;
            byteValue >>= (bfByteTable[bitOffset].shiftFactor - typeInfo->
                  bitfieldInfo.bField.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;
         strcat((LPSTR)*textPtr,"[0x");
         *textPtr += strlen((LPSTR)*textPtr);
         if (anotatedText) 
            **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"%04x",wordValue);
         *textPtr += strlen((LPSTR)*textPtr);
         if (anotatedText)
            **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"]:%d = ",typeInfo->
               bitfieldInfo.bField.size);
         *textPtr += strlen((LPSTR)*textPtr);
         if (bitfieldType == BF_LSB) {
            wordValue &= bfWordTable[(sizeof(U16) * BITS_PER_BYTE) - 
                  (typeInfo->bitfieldInfo.bField.size + 
                  bitOffset)].mask.wordMask;
                 
            wordValue >>= bitOffset;
         }
         else if (bitfieldType == BF_MSB) {
            wordValue &= bfWordTable[bitOffset].mask.wordMask;
            wordValue >>= (bfWordTable[bitOffset].shiftFactor - typeInfo->
                  bitfieldInfo.bField.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;
         strcat((LPSTR)*textPtr,"[0x");
         *textPtr += strlen((LPSTR)*textPtr);
         if (anotatedText) 
            **textPtr = specialChar|AT_BEGIN_TAG|AT_EDIT_FIELD;
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"%08lx",longValue);
         *textPtr += strlen((LPSTR)*textPtr);
         if (anotatedText)
            **textPtr = specialChar|AT_END_TAG|AT_EDIT_FIELD;
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"]:%d = ",typeInfo->
               bitfieldInfo.bField.size);
         *textPtr += strlen((LPSTR)*textPtr);
         if (bitfieldType == BF_LSB) {
            longValue &= bfLongTable[(sizeof(U32) * BITS_PER_BYTE) - 
                  (typeInfo->bitfieldInfo.bField.size + 
                  bitOffset)].mask.longMask;
            longValue >>= bitOffset;
         }
         else if (bitfieldType == BF_MSB) {
            longValue &= bfLongTable[bitOffset].mask.longMask;
            longValue >>= (bfLongTable[bitOffset].shiftFactor - typeInfo->
                  bitfieldInfo.bField.size);
         }
         strcat((LPSTR)*textPtr,"0x");
         *textPtr += strlen((LPSTR)*textPtr);
         sprintf((LPSTR)*textPtr,"%lx",longValue);
         *textPtr += strlen((LPSTR)*textPtr);
         break;
      default:
         break;
   }
   return GOOD;
}


/*************************************************************************
**
**  GetBitfieldOrientation: 
**     Bitfield orientation depends on processor and toolchain
**     used.   Read the ini file for toolchain used.
** 
**
**************************************************************************/
RETCODE PRIVATE GetBitfieldOrientation(BF_ORIENTATION *bitfieldType) {

   CHAR toolchain[MAX_STRING_SIZE];
   RETCODE err;

   switch(procFamily) {
      case FAMILY_68K:
         // check toolchain
         if ((err = IniGetString("ToolChain","CompilerUsed",NULL,
               toolchain)) != GOOD)
            return err;
         if (stricmp(toolchain,"Hiware") == GOOD)
            *bitfieldType = BF_LSB;
         else
            *bitfieldType = BF_MSB;
         break;
      case FAMILY_X86:
         *bitfieldType = BF_LSB;
         break;
   }
   return GOOD;
}

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