                    DISPLAYING A MEMORY FILE

Recently I wrote a program that allowed for the displaying of 
memory variables. The program appeared in the Jan 89 issue of 
Captains_log as well as in DOSS and a modified version is in 
Steve Straley's Release 2 of the Toolkit.

When you want to do the same thing from a memory file, the
proocedure, in principle, is the same. The differences however
are interesting.

First you must capture the data from the file with an FREAD.
Character and logical data are easy to handle because they are
essentially in the same format as a variable or in the file. This
is not the case with dates and numbers. Clipper and Dbase handle
dates as numbers and these are stored on the disk in IEEE format
as follows. The number is broken down into two parts, the
characteristic and the mantissa. This is essentially the same as
scientific notation. The mantissa is a number between 1 and 2, or
is 0, while the characteristic is the power of 2 by which to
multiply the mantissa to get the original number. To avoid the
possibility of having a negative exponent, we add 1023 to the
power to get the characteristic. when the actual number is stored
on the disk we elimanate the 1 to the left of the radix point
(binary point) and store only the fraction. To display the
number, we must convert the number to fixed point form as just
described. For a date, there is one more step. I have found that
I have problems dealing with dates before January 1, 0100. So I
use this somewhat as the starting point for dates. When I get the
number (date) from the disk and convert from floating to fixed, I
add the difference between the number for my date and the number
for 1/1/100 to the date variable for 1/1/100.

A modified version of FROMDISK is in Steve Straley's Toolkit 
Release 2 and is used to convert MEM files to TXT files in data 
driven applications.

*******************************************************************************
* Written by Essor Maso.                                                      *
* A diagnostic tool to view memory variables easily from a memory file.       *
*******************************************************************************


SET CONFIRM ON
IF ISCOLOR()
 SET COLOR TO W+/B,B/W,B,,W/B
ENDIF
MFILE=SPACE(12)
CLEAR
@ 8,10 SAY 'This program displays memory variables directly from a selected'
@ 9,10 SAY 'memory file, without bringing them in from the disk.'
@ 11,10 SAY 'Enter file ' GET MFILE PICT '@!'
READ
IF !FILE(MFILE)
 @ 13,10 SAY TRIM(MFILE)+ ' not present. Press any key.'
 INKEY(0)
 SET COLOR TO
 CLEAR
 RETURN
ENDIF

FH________=FOPEN(MFILE)  && Open the file and get a handle.
FL________=FSEEK(FH________,0,2)  && Get the length of the file.
FSEEK(FH________,0)  && Go to the beginning of the file.
CLEAR SCREEN
I_________=0
LC________=2  && Initialize a line counter.
STORE 0 TO N_________,TB________
IF FL________<2
* File contains only EOF marker.
 @ 2,0 SAY 'There are no memory variables present.'
ELSE
 DO WHILE FSEEK(FH________,0,1)+1<FL________
* Variable specific information is contained in the first 18 bytes of the
* variable packet. The value of the variable is contained from positon 33 on.
  MW________=SPACE(18)
  FREAD(FH________,@MW________,18)  && Get the variable specific information.
* The variable name is in the first 10 position with a CHR(0) terminator.
  VN________=LEFT(MW________,AT(CHR(0),MW________)-1)
* The variable type is in position 12 of the packet.
* C3h is character or memo, CCh is logical, CEh is numeric, C4h is date.
  VT________=SUBS(MW________,12,1)
* For character and logical variables, position 17 and 18 contain the hex
* value for the range of the data. For numeric and date variables, the 
* range is 8. This points to the end of the variable packet.
  VR________=BIN2W(RIGHT(MW________,2))
  IF !VT________$CHR(195)+CHR(204)+CHR(196)+CHR(206)
   @ 2,0 SAY 'This is not a valid memory file. Press a key.'
   INKEY(0)
   FCLOSE(FH________)
   SET COLOR TO
   CLEAR
   RETURN
  ENDIF
  MC________=14
  FSEEK(FH________,MC________,1)   && Prepare to get data
  IF VT________$CHR(195)+CHR(204)  && Character or Logical
   TB________=TB________+VR________
   MCHARLOG=SPACE(VR_________)
   FREAD(FH________,@MCHARLOG,VR________)  && Get the data.
  ELSE                   && Numeric or Date.
   TB________=TB________+8
   MNUMERIC=SPACE(8)
   FREAD(FH________,@MNUMERIC,8)  && Get the data.
   P1=MOD(ASC(SUBS(MNUMERIC,8,1)),128)*16
   P2=INT(ASC(SUBS(MNUMERIC,7,1))/16)
   POWER=P1+P2-1023
   MINUS=INT(ASC(SUBS(MNUMERIC,8,1))/16)>=8
   MANT0=MOD(ASC(SUBS(MNUMERIC,7,1)),16)/16
   MANT1=BIN2W(SUBS(MNUMERIC,5,2))/(65536*16)
   MANT2=BIN2W(SUBS(MNUMERIC,3,2))/(65536*65536*16)
   MANT3=BIN2W(SUBS(MNUMERIC,1,2))/(65536*65536*65536*16)
   MANTISSA=MANT0+MANT1+MANT2+MANT3
   NUMVAL=IF(MINUS,-(1+MANTISSA)*(2^POWER),(1+MANTISSA)*(2^POWER))
   SHOWDEC=ASC(RIGHT(MW________,1))
  ENDIF
  @ LC________,0 SAY VN________
  IF VR________>51.AND.VT________=CHR(195)
   @ LC________,11 SAY 'TYPE '+'C'
   @ LC________,20 SAY ["]+LEFT(MCHARLOG,50)+'> '+;
     LTRIM(STR(LEN(MCHARLOG)-1))
  ELSE
   DO CASE
    CASE VT________=CHR(195)
     @ LC________,11 SAY 'TYPE '+'C'
     @ LC________,20 SAY ["]+MCHARLOG+["]
    CASE VT________=CHR(204)
     @ LC________,11 SAY 'TYPE '+'L'
     @ LC________,20 SAY IF(ASC(MCHARLOG)#0,'.T.','.F.')
    CASE VT________=CHR(206)
     @ LC________,11 SAY 'TYPE '+'N'
     @ LC________,20 SAY LTRIM(STR(NUMVAL,20,SHOWDEC))
     @ LC________,45 SAY '( '+LTRIM(STR(NUMVAL,20,8))+' )'
    CASE VT________=CHR(196)
     @ LC________,11 SAY 'TYPE '+'D'
     @ LC________,20 SAY CTOD('01/01/0100')+NUMVAL-1757585
   ENDCASE
  ENDIF
  LC________=LC________+1
  N_________=N_________+1
  IF ROW()>20
   @ LC________+1,0 SAY 'Press Q TO Quit, Return to continue.'
   INKEY(0)
   IF LASTKEY()=81.OR.LASTKEY()=113
    FCLOSE(FH________)
    SET COLOR TO
    CLEAR
    RETURN
   ELSE
    CLEAR SCREEN
    LC________=2
   ENDIF
  ENDIF
 ENDDO
ENDIF
@ LC________+2,0 SAY 'Press Q to Quit, Return to continue.'
INKEY(0)
IF LASTKEY()=81.OR.LASTKEY()=113
 FCLOSE(FH________)
 SET COLOR TO
 CLEAR
 RETURN
ENDIF
FCLOSE(FH________)
SET COLOR TO
CLEAR
RETURN
