This is a small conversion of MemFedit.prg of Clipper Summer87
Original
* Program: Memfedit.prg
* Author: Glenn Toney
* Version: Clipper Summer '87
* Note(s): This program creates a text file from a Clipper .mem
* file. You can edit the text file using MEMOEDIT()
* and then write the text file back to a .mem file.
*
CLEAR
SET SCOREBOARD OFF
mm_fcnt = ADIR("*.mem") && Count mem files.
DECLARE fil_name[mm_fcnt+1],fil_size[mm_fcnt+1]
ADIR("*.mem",fil_name,fil_size) && Get mem files.
* This is used to sort the name with the file size
FOR mm_i = 1 TO mm_fcnt
mm_flen = LEN(TRIM(fil_name[mm_i]))
fil_name[mm_i] = fil_name[mm_i] + SPACE(15-mm_flen) + ;
str(fil_size[mm_i])
NEXT
ASORT(fil_name)
fil_name[mm_fcnt+1] = "new file" && Add a new file to the array.
fil_size[mm_fcnt+1] = 0
mm_newmem = .F.
* Separate the size from the file name.
FOR mm_i = 1 TO mm_fcnt
fil_size[mm_i] = val(STUFF(fil_name[mm_i],1,15,""))
fil_name[mm_i] = STUFF(fil_name[mm_i],16,10,"")
NEXT
* Select the memory file.
@ 2,33 TO 21,46 DOUBLE
@ 4,34 TO 4,45 DOUBLE
@ 3,34 SAY "Memory Files"
mm_choice = ACHOICE(5,34,20,45,fil_name)
IF mm_choice = 0
CLEAR
RETURN
ENDIF
CLEAR
@ 10,23 SAY "CREATING TEXT FILE, PLEASE WAIT ..."
mm_memfile = fil_name[mm_choice]
IF mm_choice < mm_fcnt + 1 && If mm_choice = mm_fcnt you
mm_fsize = fil_size[mm_choice] && have a new file.
mm_handle = FOPEN(mm_memfile) && Low-level file handling.
mm_block = mm_fsize && I set up a buffer for the
mm_buffer = SPACE(mm_block) && size of the file.
* This reads the memory file into the buffer by using Clippers
* low-level file handling feature.
FREAD(mm_handle,@mm_buffer, mm_block)
* This restores the memory file to get the values of the numeric
* variables and the Date variables.
RESTORE FROM &mm_memfile. ADDITIVE
mm_offset = 0 && Offset of each new variable in the memory file.
mm_varno = 1 && Variable counter.
mm_maxvar = int(mm_fsize/32)+1 && Maximum variable in file.
DECLARE mm_mvar[mm_maxvar],mm_mtyp[mm_maxvar],mm_mval[mm_maxvar]
* Initialize arrays.
AFILL(mm_mtyp,"")
AFILL(mm_mvar,"")
AFILL(mm_mval,"")
mm_endvar = .N.
* This loop is used to increment the position in the buffer.
FOR mm_i = 1 TO mm_block
* The ASCII value is obtained from the byte being scanned.
mm_asc = VAL(TRANSFORM(ASC(SUBSTR(mm_buffer,mm_i,1)),"999"))
IF mm_offset < 11 && Variable Names are Bytes 0-10.
IF mm_asc <> 0 .AND. .NOT. mm_endvar
mm_mvar[mm_varno] = mm_mvar[mm_varno] + CHR(mm_asc)
ELSE
mm_endvar = .Y. && Variable Name is found.
ENDIF
ENDIF
IF mm_offset = 11 && Byte 11 is the varible type.
IF mm_asc = 195 && Variable is a character.
mm_mtyp[mm_varno] = 'C'
ENDIF
IF mm_asc = 206 && Variable is a numeric.
mm_mtyp[mm_varno] = 'N'
ENDIF
IF mm_asc = 204 && Variable is a logical.
mm_mtyp[mm_varno] = 'L'
ENDIF
IF mm_asc = 196 && Variable is a date.
mm_mtyp[mm_varno] = 'D'
ENDIF
ENDIF
IF mm_offset > 31 && Byte 32 is first byte of
IF mm_mtyp[mm_varno] = 'C' && the value.
IF mm_asc <> 0 .AND. mm_asc <> 13 .AND. mm_asc <> 26
mm_mval[mm_varno] = mm_mval[mm_varno] + CHR(mm_asc)
ELSE
* Begin a new variable.
mm_varno = mm_varno + 1
mm_offset = -1
mm_endvar = .N.
ENDIF
ENDIF
IF mm_mtyp[mm_varno] = 'N' .OR. mm_mtyp[mm_varno] = 'D'
IF (mm_asc <> 0 .AND. mm_asc <> 13 .AND. mm_asc <> 26 ;
.AND. mm_offset < 40)
mm_mval[mm_varno] = mm_mval[mm_varno] + CHR(mm_asc)
ELSE
* If the offset is greater than 39 and the current
* variable is type 'N' or 'D', move to the next
* variable to obtain the variable name.
IF mm_offset > 39
mm_varno = mm_varno + 1
IF mm_asc <> 0 .AND. mm_asc <> 13 .AND. ;
mm_asc <> 26
mm_mvar[mm_varno] = mm_mvar[mm_varno] + ;
CHR(mm_asc)
ENDIF
mm_offset = 0
mm_endvar = .N.
ENDIF
ENDIF
ENDIF
IF mm_mtyp[mm_varno] = "L" .AND. mm_offset = 32
IF mm_asc <> 0 .AND. mm_asc <> 13
mm_mval[mm_varno] = ".T."
ELSE
mm_mval[mm_varno] = ".F."
ENDIF
* Begin a new variable.
mm_varno = mm_varno + 1
mm_offset = -1
mm_endvar = .N.
ENDIF
ENDIF
mm_offset = mm_offset + 1
NEXT
FCLOSE(mm_handle)
CLEAR
mm_pos = AT(".MEM",mm_memfile)
mm_txtfile = STUFF(mm_memfile,mm_pos,4,".TXT")
SET DEVICE TO PRINT
SET PRINT TO &mm_txtfile.
* Output variables and their values to an ASCII text file.
FOR mm_i = 1 TO mm_varno - 1
IF mm_mtyp[mm_i] = 'C'
mm_mvar[mm_i] = mm_mvar[mm_i]+' = '+'"'+mm_mval[mm_i]+'"'
@ mm_i-1,0 SAY mm_mvar[mm_i]
ENDIF
IF mm_mtyp[mm_i] = 'N'
* Instead of converting bytes to a numeric value, just
* restore the memory file and set the variable equal to
* its value.
mm_value = mm_mvar[mm_i]
mm_mval[mm_i] = &mm_value. && Macro used to get value.
mm_mvar[mm_i] = mm_mvar[mm_i]+'= '+ ;
LTRIM(str(mm_mval[mm_i]))
@ mm_i-1,0 SAY mm_mvar[mm_i]
ENDIF
IF mm_mtyp[mm_i] = 'L'
mm_mvar[mm_i] = mm_mvar[mm_i]+' = '+ mm_mval[mm_i]
@ mm_i-1,0 SAY mm_mvar[mm_i]
ENDIF
IF mm_mtyp[mm_i] = 'D'
* Instead of converting bytes to a Clipper date, just
* restore the memory file and set the variable equal to
* its value.
mm_value = mm_mvar[mm_i]
mm_mval[mm_i] = &mm_value. && Macro used to get value.
mm_mvar[mm_i] = ;
mm_mvar[mm_i]+'= CTOD("'+ DTOC(mm_mval[mm_i])+'")'
@ mm_i-1,0 SAY mm_mvar[mm_i]
ENDIF
NEXT
SET DEVICE TO SCREEN
SET PRINTER TO
RELEASE ALL EXCEPT mm_*
ELSE && Get new file name.
mm_memfile = SPACE(8)
@ 22,10 SAY "New File Name:"
@ 22,25 GET mm_memfile PICTURE '!!!!!!!!' VALID ;
Validf(mm_memfile)
@ 22,33 SAY ".MEM"
read
mm_memfile = TRIM(mm_memfile) + ".MEM"
IF mm_memfile = ".MEM"
CLEAR
RETURN
ENDIF
mm_pos = AT(".MEM",mm_memfile)
mm_txtfile = STUFF(mm_memfile,mm_pos,4,".TXT")
mm_fsize = 0
mm_newmem = .T.
ENDIF
* INITIAL VALUES FOR MEMOEDIT
mm_txtfile = TRIM(mm_txtfile)
mm_return = 0 && Return value for user function.
mm_altered = .F. && Flag to check for file being altered.
mm_top = 0 && Top Row.
mm_lft = 0 && Left Margin.
mm_bot = 23 && Bottom Row.
mm_rgt = 79 && Right Margin.
mm_upd = .T.
mm_browse = .T.
mm_linelen = 100
mm_ins_on = .F.
mm_msglen = 45
mm_tab = 4
IF FILE(mm_txtfile) && If text file size too large, you can not
IF mm_fsize > 22000 && use this editor. This value may vary.
mm_kyp = ' '
@ mm_bot + 1, mm_lft SAY ;
"File Too Large, Press any key TO exit" GET mm_kyp
READ
RETURN
ENDIF
ENDIF
IF FILE(mm_txtfile)
mm_memo = MEMOREAD(mm_txtfile)
mm_newtxt = .N.
ELSE
mm_memo = SPACE(100)
mm_newtxt = .Y.
ENDIF
mm_lineno = 1
mm_colno = 0
mm_altered = .F.
CLEAR
@ mm_top, mm_lft, mm_bot, mm_rgt BOX CHR(213)+CHR(205)+CHR(184)+;
CHR(179)+CHR(190)+CHR(205)+CHR(212)+CHR(179)
@ mm_bot + 1, mm_lft SAY LOWER(mm_txtfile)
@ mm_bot + 1, mm_lft+14 say " Save & Exit Exit"
* This is a clipper text file editer with a user-defined function,
* you may use any text editor.
mm_memo = MEMOEDIT(mm_memo, mm_top + 1, mm_lft + 1, mm_bot - 1, ;
mm_rgt - 1, mm_upd, "Mfunc",mm_linelen, mm_tab,mm_lineno, ;
mm_colno)
IF .NOT. EMPTY(mm_memo) .AND. mm_return = 23
IF .NOT. MEMOWRIT(mm_txtfile, mm_memo)
@ mm_bot + 1, mm_lft SAY Pad("Disk Write Error.", mm_msglen)
mm_i = INKEY(2)
RETURN
ENDIF
@ mm_bot + 1, mm_lft SAY Pad("Write successful.", mm_msglen)
mm_i = INKEY(2)
ENDIF
mm_endline = mlcount(mm_memo, 100)
DECLARE mm_newvar[mm_endline] && This array holds the variables
CLEAR && and their values.
FOR mm_line = 1 TO mm_endline
mm_newvar[mm_line] = MEMOLINE(mm_memo, 100, mm_line)
NEXT
* This loop will store the values to their respective variables.
FOR mm_line = 1 TO mm_endline
mm_exp = mm_newvar[mm_line]
mm_pos = AT("=",mm_exp) && Check for an equal sign.
IF mm_pos > 0
mm_left_arg = SUBSTR(mm_exp,1,mm_pos-1) && Variable.
mm_right_arg = ;
SUBSTR(mm_exp,mm_pos+1,LEN(mm_exp)-mm_pos) && Value.
STORE &mm_right_arg. TO &mm_left_arg.
ENDIF
NEXT
CLEAR
DECLARE mchoice[4]
mchoice[1] = "1. Create "+upper(TRIM(mm_memfile))+" From "+;
upper(TRIM(mm_txtfile))+" & SAVE "+ upper(TRIM(mm_txtfile)) + ;
SPACE(55)
mchoice[2] = "2. Create "+upper(TRIM(mm_memfile))+" From "+;
upper(TRIM(mm_txtfile))+" & DELETE "+ upper(TRIM(mm_txtfile)) + ;
SPACE(55)
mchoice[3] = "3. DELETE "+upper(TRIM(mm_txtfile))+" & Exit " + ;
SPACE(55)
mchoice[4] = "4. Exit " + SPACE(55)
@ 2,9 TO 9,71 DOUBLE
@ 4,10 TO 4,70 DOUBLE
@ 3,10 SAY SPACE(20)+"Selection Menu"+SPACE(21)
mm_choice = ACHOICE(5,10,8,70,mchoice)
DO CASE
CASE mm_choice = 1 .OR. mm_choice = 2
IF mm_choice = 2
DELETE FILE &mm_txtfile.
ENDIF
savefile = mm_memfile
* Release all the variables used in this program and save
* the variables that were assigned value in the editor.
RELEASE ALL LIKE mm_*
SAVE TO &savefile. ALL EXCEPT savefile
CASE mm_choice = 3
DELETE FILE &mm_txtfile.
ENDCASE
CLEAR
FUNCTION Mfunc && MEMOEDIT() user function
PARAMETERS mode, line, col
PRIVATE kp,yesno
mm_return = 0
DO CASE
CASE mode = 0 && Idle.
@ mm_bot + 1, mm_rgt - 20 SAY "Line: " + ;
Pad(LTRIM(STR(line)), 4)
@ mm_bot + 1, mm_rgt - 8 SAY "Col: " + ;
Pad(LTRIM(STR(col)), 3)
OTHERWISE
kp = LASTKEY() && Keystroke exception.
* Save values to possibly resume edit
IF mode = 2
mm_altered = .T.
ENDIF
DO CASE
CASE kp = 23 .OR. kp = -1
* ^W or F2 to save file.
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
IF .NOT. FILE(mm_txtfile)
@ mm_bot + 1, mm_lft SAY "Writing " + ;
LOWER(mm_txtfile) + "..."
mm_return = 23
ELSE
@ mm_bot + 1, mm_lft SAY "Exist...Replace (Y/N)? "
yesno = " "
DO WHILE .NOT. yesno $ "YN"
yesno = UPPER(CHR(INKEY(0)))
ENDDO
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
IF yesno = "Y"
mm_return = 23
ELSE
mm_return = 27
ENDIF
ENDIF
CASE kp = 301 .OR. kp = 27
* Esc or Alt-X to exit.
IF .NOT. mm_altered
mm_return = 27 && No change.
ELSE
* Changes have been made to memo.
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
@ mm_bot + 1, mm_lft SAY "SAVE [Y/N]? "
yesno = " "
DO WHILE .NOT. yesno $ "YN"
yesno = UPPER(CHR(INKEY(0)))
ENDDO
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
DO CASE
CASE yesno = "N" && Abort.
mm_return = 27
CASE yesno = "Y" && Save and exit.
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
IF .not. FILE(mm_txtfile)
@ mm_bot + 1, mm_lft SAY "Writing " + ;
LOWER(mm_txtfile) + "..."
mm_return = 23
ELSE
@ mm_bot + 1, mm_lft SAY ;
"Exist...Replace (Y/N)? "
yesno = " "
DO WHILE .NOT. yesno $ "YN"
yesno = UPPER(CHR(INKEY(0)))
ENDDO
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
IF yesno = "Y"
mm_return = 23
ELSE
mm_return = 27
ENDIF
ENDIF
ENDCASE
ENDIF
CASE (kp = 279 .OR. kp = 22) .AND. mm_upd
* ^V or Ins or Alt-I toggles insert mode.
mm_ins_on = .NOT. mm_ins_on
@ mm_bot + 1, mm_rgt - 25 SAY IF(mm_ins_on, "I", " ")
mm_return = 22
ENDCASE
ENDCASE
RETURN mm_return
FUNCTION Pad && Pad with spaces.
PARAMETERS string, length
RETURN SUBSTR(string + SPACE(length), 1, length)
FUNCTION Validf && Checks for filename validity.
parameter mfile
mfile = TRIM(mfile)
mlen = LEN(mfile)
mvalid = .Y.
FOR mm_i = 1 TO mlen
mchar = SUBSTR(mfile,mm_i,1)
IF mchar = ' '
mvalid = .N.
ENDIF
IF mchar < '0' .OR. mchar > '_'
mvalid = .N.
ENDIF
IF mchar > '9' .AND. mchar < 'A'
mvalid = .N.
ENDIF
* IF mchar > 'Z' .AND. ASC(mchar) < '_'
* mvalid = .N.
* ENDIF
NEXT
RETURN(mvalid)
Modify by me( for fwh )
* Program: Memfedit.prg
* Author: Glenn Toney
* Version: Clipper Summer '87
* Note(s): This program creates a text file from a Clipper .mem
* file. You can edit the text file using MEMOEDIT()
* and then write the text file back to a .mem file.
*
#include "fivewin.ch"
Function Main()
*CLEAR
*SET SCOREBOARD OFF
local mm_fcnt := ADIR("*.mem") && Count mem files.
local fil_name := array(mm_fcnt+1)
local fil_size:= array(mm_fcnt+1)
ADIR("*.mem",fil_name,fil_size) && Get mem files.
* This is used to sort the name with the file size
FOR mm_i = 1 TO mm_fcnt
mm_flen = LEN(TRIM(fil_name[mm_i]))
fil_name[mm_i] = fil_name[mm_i] + SPACE(15-mm_flen) + ;
str(fil_size[mm_i])
NEXT
ASORT(fil_name)
fil_name[mm_fcnt+1] = "new file" && Add a new file to the array.
fil_size[mm_fcnt+1] = 0
mm_newmem = .F.
* Separate the size from the file name.
FOR mm_i = 1 TO mm_fcnt
fil_size[mm_i] = val(STUFF(fil_name[mm_i],1,15,""))
fil_name[mm_i] = STUFF(fil_name[mm_i],16,10,"")
NEXT
* Select the memory file.
*@ 2,33 TO 21,46 DOUBLE
*@ 4,34 TO 4,45 DOUBLE
*@ 3,34 SAY "Memory Files"
//mm_choice = ACHOICE(5,34,20,45,fil_name)
mm_choice = MsgList(fil_name,"Memory Files")
IF mm_choice = 0
CLEAR
RETURN
ENDIF
OpenMemFile(mm_choice,fil_name,mm_fcnt,fil_size)
*CLEAR
Return nil
//----------------------------------------------------------//
Function OpenMemFile(mm_choice,fil_name,mm_fcnt,fil_size)
*@ 10,23 SAY "CREATING TEXT FILE, PLEASE WAIT ..."
local mm_memfile := fil_name[mm_choice]
local mm_fsize,mm_handle,mm_block,mm_buffer
local mm_maxvar,mm_mvar,mm_mtyp,mm_mval
local mm_offset,mm_varno,mm_endvar
local mm_i
local mm_asc
local mm_pos,mm_txtfile
local aVars := {}
local oText
IF mm_choice < mm_fcnt + 1 && If mm_choice = mm_fcnt you
mm_fsize := fil_size[mm_choice] && have a new file.
mm_handle := FOPEN(mm_memfile) && Low-level file handling.
mm_block := mm_fsize && I set up a buffer for the
mm_buffer := SPACE(mm_block) && size of the file.
* This reads the memory file into the buffer by using Clippers
* low-level file handling feature.
FREAD(mm_handle,@mm_buffer, mm_block)
* This restores the memory file to get the values of the numeric
* variables and the Date variables.
RESTORE FROM &mm_memfile. ADDITIVE
mm_offset := 0 && Offset of each new variable in the memory file.
mm_varno := 1 && Variable counter.
mm_maxvar := int(mm_fsize/32)+1 && Maximum variable in file.
mm_mvar:=array(mm_maxvar)
mm_mtyp:=array(mm_maxvar)
mm_mval:=array(mm_maxvar)
* Initialize arrays.
AFILL(mm_mtyp,"")
AFILL(mm_mvar,"")
AFILL(mm_mval,"")
mm_endvar := .N.
* This loop is used to increment the position in the buffer.
FOR mm_i = 1 TO mm_block
* The ASCII value is obtained from the byte being scanned.
mm_asc := VAL(TRANSFORM(ASC(SUBSTR(mm_buffer,mm_i,1)),"999"))
IF mm_offset < 11 && Variable Names are Bytes 0-10.
IF mm_asc <> 0 .AND. .NOT. mm_endvar
mm_mvar[mm_varno] = mm_mvar[mm_varno] + CHR(mm_asc)
ELSE
mm_endvar = .Y. && Variable Name is found.
ENDIF
ENDIF
IF mm_offset = 11 && Byte 11 is the varible type.
IF mm_asc = 195 && Variable is a character.
mm_mtyp[mm_varno] = 'C'
ENDIF
IF mm_asc = 206 && Variable is a numeric.
mm_mtyp[mm_varno] = 'N'
ENDIF
IF mm_asc = 204 && Variable is a logical.
mm_mtyp[mm_varno] = 'L'
ENDIF
IF mm_asc = 196 && Variable is a date.
mm_mtyp[mm_varno] = 'D'
ENDIF
ENDIF
IF mm_offset > 31 && Byte 32 is first byte of
IF mm_mtyp[mm_varno] = 'C' && the value.
IF mm_asc <> 0 .AND. mm_asc <> 13 .AND. mm_asc <> 26
mm_mval[mm_varno] = mm_mval[mm_varno] + CHR(mm_asc)
ELSE
* Begin a new variable.
mm_varno = mm_varno + 1
mm_offset = -1
mm_endvar = .N.
ENDIF
ENDIF
IF mm_mtyp[mm_varno] = 'N' .OR. mm_mtyp[mm_varno] = 'D'
IF (mm_asc <> 0 .AND. mm_asc <> 13 .AND. mm_asc <> 26 ;
.AND. mm_offset < 40)
mm_mval[mm_varno] = mm_mval[mm_varno] + CHR(mm_asc)
ELSE
* If the offset is greater than 39 and the current
* variable is type 'N' or 'D', move to the next
* variable to obtain the variable name.
IF mm_offset > 39
mm_varno = mm_varno + 1
IF mm_asc <> 0 .AND. mm_asc <> 13 .AND. ;
mm_asc <> 26
mm_mvar[mm_varno] = mm_mvar[mm_varno] + ;
CHR(mm_asc)
ENDIF
mm_offset = 0
mm_endvar = .N.
ENDIF
ENDIF
ENDIF
IF mm_mtyp[mm_varno] = "L" .AND. mm_offset = 32
IF mm_asc <> 0 .AND. mm_asc <> 13
mm_mval[mm_varno] = ".T."
ELSE
mm_mval[mm_varno] = ".F."
ENDIF
* Begin a new variable.
mm_varno = mm_varno + 1
mm_offset = -1
mm_endvar = .N.
ENDIF
ENDIF
mm_offset = mm_offset + 1
NEXT
FCLOSE(mm_handle)
*CLEAR
mm_pos := AT(".MEM",mm_memfile)
mm_txtfile := STUFF(mm_memfile,mm_pos,4,".TXT")
//SET DEVICE TO PRINT
//SET PRINT TO &mm_txtfile.
oText:=TTxtFile():New( mm_txtfile )
if oText:Open()
* Output variables and their values to an ASCII text file.
FOR mm_i = 1 TO mm_varno - 1
IF mm_mtyp[mm_i] = 'C'
mm_mvar[mm_i] = mm_mvar[mm_i]+' = '+'"'+mm_mval[mm_i]+'"'
*@ mm_i-1,0 SAY mm_mvar[mm_i]
ENDIF
IF mm_mtyp[mm_i] = 'N'
* Instead of converting bytes to a numeric value, just
* restore the memory file and set the variable equal to
* its value.
mm_value = mm_mvar[mm_i]
mm_mval[mm_i] = &mm_value. && Macro used to get value.
mm_mvar[mm_i] = mm_mvar[mm_i]+'= '+ ;
LTRIM(str(mm_mval[mm_i]))
*@ mm_i-1,0 SAY mm_mvar[mm_i]
ENDIF
IF mm_mtyp[mm_i] = 'L'
mm_mvar[mm_i] = mm_mvar[mm_i]+' = '+ mm_mval[mm_i]
*@ mm_i-1,0 SAY mm_mvar[mm_i]
ENDIF
IF mm_mtyp[mm_i] = 'D'
* Instead of converting bytes to a Clipper date, just
* restore the memory file and set the variable equal to
* its value.
mm_value = mm_mvar[mm_i]
mm_mval[mm_i] = &mm_value. && Macro used to get value.
mm_mvar[mm_i] = ;
mm_mvar[mm_i]+'= CTOD("'+ DTOC(mm_mval[mm_i])+'")'
*@ mm_i-1,0 SAY mm_mvar[mm_i]
ENDIF
*aadd (avars, {mm_mvar[mm_i]})
oText:Add( mm_mvar[mm_i] )
NEXT
oText:Close()
Endif
/*For n=1 to Len(aVars)
if oText:Open()
oText:Add( aVars[n][1] )
oText:Close()
endif
Next
*/
MsgInfo( MemoRead( mm_txtfile ) )
*xbrowser avars
//SET DEVICE TO SCREEN
//SET PRINTER TO
RELEASE ALL EXCEPT mm_*
ELSE && Get new file name.
mm_memfile = SPACE(8)
/*
@ 22,10 SAY "New File Name:"
@ 22,25 GET mm_memfile PICTURE '!!!!!!!!' VALID ;
Validf(mm_memfile)
@ 22,33 SAY ".MEM"
read
IF mm_memfile = ".MEM"
CLEAR
RETURN
ENDIF
*/
mm_memfile := TRIM(mm_memfile) + ".MEM"
mm_pos := AT(".MEM",mm_memfile)
mm_txtfile := STUFF(mm_memfile,mm_pos,4,".TXT")
mm_fsize := 0
mm_newmem = .T.
ENDIF
* INITIAL VALUES FOR MEMOEDIT
mm_txtfile := TRIM(mm_txtfile)
mm_return := 0 && Return value for user function.
mm_altered := .F. && Flag to check for file being altered.
mm_top := 0 && Top Row.
mm_lft := 0 && Left Margin.
mm_bot := 23 && Bottom Row.
mm_rgt := 79 && Right Margin.
mm_upd := .T.
mm_browse := .T.
mm_linelen := 100
mm_ins_on := .F.
mm_msglen := 45
mm_tab := 4
IF FILE(mm_txtfile) && If text file size too large, you can not
IF mm_fsize > 22000 && use this editor. This value may vary.
mm_kyp := ' '
@ mm_bot + 1, mm_lft SAY ;
"File Too Large, Press any key TO exit" GET mm_kyp
READ
RETURN
ENDIF
ENDIF
IF FILE(mm_txtfile)
mm_memo = MEMOREAD(mm_txtfile)
mm_newtxt = .N.
ELSE
mm_memo = SPACE(100)
mm_newtxt = .Y.
ENDIF
mm_lineno = 1
mm_colno = 0
mm_altered = .F.
CLEAR
@ mm_top, mm_lft, mm_bot, mm_rgt BOX CHR(213)+CHR(205)+CHR(184)+;
CHR(179)+CHR(190)+CHR(205)+CHR(212)+CHR(179)
@ mm_bot + 1, mm_lft SAY LOWER(mm_txtfile)
@ mm_bot + 1, mm_lft+14 say " Save & Exit Exit"
* This is a clipper text file editer with a user-defined function,
* you may use any text editor.
mm_memo = MEMOEDIT(mm_memo, mm_top + 1, mm_lft + 1, mm_bot - 1, ;
mm_rgt - 1, mm_upd, "Mfunc",mm_linelen, mm_tab,mm_lineno, ;
mm_colno)
IF .NOT. EMPTY(mm_memo) .AND. mm_return = 23
IF .NOT. MEMOWRIT(mm_txtfile, mm_memo)
@ mm_bot + 1, mm_lft SAY Pad("Disk Write Error.", mm_msglen)
mm_i = INKEY(2)
RETURN
ENDIF
@ mm_bot + 1, mm_lft SAY Pad("Write successful.", mm_msglen)
mm_i = INKEY(2)
ENDIF
mm_endline = mlcount(mm_memo, 100)
DECLARE mm_newvar[mm_endline] && This array holds the variables
CLEAR && and their values.
FOR mm_line = 1 TO mm_endline
mm_newvar[mm_line] = MEMOLINE(mm_memo, 100, mm_line)
NEXT
* This loop will store the values to their respective variables.
FOR mm_line = 1 TO mm_endline
mm_exp = mm_newvar[mm_line]
mm_pos = AT("=",mm_exp) && Check for an equal sign.
IF mm_pos > 0
mm_left_arg = SUBSTR(mm_exp,1,mm_pos-1) && Variable.
mm_right_arg = ;
SUBSTR(mm_exp,mm_pos+1,LEN(mm_exp)-mm_pos) && Value.
STORE &mm_right_arg. TO &mm_left_arg.
ENDIF
NEXT
CLEAR
DECLARE mchoice[4]
mchoice[1] = "1. Create "+upper(TRIM(mm_memfile))+" From "+;
upper(TRIM(mm_txtfile))+" & SAVE "+ upper(TRIM(mm_txtfile)) + ;
SPACE(55)
mchoice[2] = "2. Create "+upper(TRIM(mm_memfile))+" From "+;
upper(TRIM(mm_txtfile))+" & DELETE "+ upper(TRIM(mm_txtfile)) + ;
SPACE(55)
mchoice[3] = "3. DELETE "+upper(TRIM(mm_txtfile))+" & Exit " + ;
SPACE(55)
mchoice[4] = "4. Exit " + SPACE(55)
@ 2,9 TO 9,71 DOUBLE
@ 4,10 TO 4,70 DOUBLE
@ 3,10 SAY SPACE(20)+"Selection Menu"+SPACE(21)
mm_choice = ACHOICE(5,10,8,70,mchoice)
DO CASE
CASE mm_choice = 1 .OR. mm_choice = 2
IF mm_choice = 2
DELETE FILE &mm_txtfile.
ENDIF
savefile = mm_memfile
* Release all the variables used in this program and save
* the variables that were assigned value in the editor.
RELEASE ALL LIKE mm_*
SAVE TO &savefile. ALL EXCEPT savefile
CASE mm_choice = 3
DELETE FILE &mm_txtfile.
ENDCASE
CLEAR
//--------------------------------------------------------------------------//
FUNCTION Mfunc && MEMOEDIT() user function
PARAMETERS mode, line, col
PRIVATE kp,yesno
mm_return = 0
DO CASE
CASE mode = 0 && Idle.
@ mm_bot + 1, mm_rgt - 20 SAY "Line: " + ;
Pad(LTRIM(STR(line)), 4)
@ mm_bot + 1, mm_rgt - 8 SAY "Col: " + ;
Pad(LTRIM(STR(col)), 3)
OTHERWISE
kp = LASTKEY() && Keystroke exception.
* Save values to possibly resume edit
IF mode = 2
mm_altered = .T.
ENDIF
DO CASE
CASE kp = 23 .OR. kp = -1
* ^W or F2 to save file.
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
IF .NOT. FILE(mm_txtfile)
@ mm_bot + 1, mm_lft SAY "Writing " + ;
LOWER(mm_txtfile) + "..."
mm_return = 23
ELSE
@ mm_bot + 1, mm_lft SAY "Exist...Replace (Y/N)? "
yesno = " "
DO WHILE .NOT. yesno $ "YN"
yesno = UPPER(CHR(INKEY(0)))
ENDDO
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
IF yesno = "Y"
mm_return = 23
ELSE
mm_return = 27
ENDIF
ENDIF
CASE kp = 301 .OR. kp = 27
* Esc or Alt-X to exit.
IF .NOT. mm_altered
mm_return = 27 && No change.
ELSE
* Changes have been made to memo.
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
@ mm_bot + 1, mm_lft SAY "SAVE [Y/N]? "
yesno = " "
DO WHILE .NOT. yesno $ "YN"
yesno = UPPER(CHR(INKEY(0)))
ENDDO
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
DO CASE
CASE yesno = "N" && Abort.
mm_return = 27
CASE yesno = "Y" && Save and exit.
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
IF .not. FILE(mm_txtfile)
@ mm_bot + 1, mm_lft SAY "Writing " + ;
LOWER(mm_txtfile) + "..."
mm_return = 23
ELSE
@ mm_bot + 1, mm_lft SAY ;
"Exist...Replace (Y/N)? "
yesno = " "
DO WHILE .NOT. yesno $ "YN"
yesno = UPPER(CHR(INKEY(0)))
ENDDO
@ mm_bot + 1, mm_lft SAY SPACE(mm_msglen)
IF yesno = "Y"
mm_return = 23
ELSE
mm_return = 27
ENDIF
ENDIF
ENDCASE
ENDIF
CASE (kp = 279 .OR. kp = 22) .AND. mm_upd
* ^V or Ins or Alt-I toggles insert mode.
mm_ins_on = .NOT. mm_ins_on
@ mm_bot + 1, mm_rgt - 25 SAY IF(mm_ins_on, "I", " ")
mm_return = 22
ENDCASE
ENDCASE
RETURN mm_return
//-----------------------------------------------------------------------//
FUNCTION Pad && Pad with spaces.
PARAMETERS string, length
RETURN SUBSTR(string + SPACE(length), 1, length)
//-----------------------------------------------------------------------//
FUNCTION Validf && Checks for filename validity.
parameter mfile
mfile = TRIM(mfile)
mlen = LEN(mfile)
mvalid = .Y.
FOR mm_i = 1 TO mlen
mchar = SUBSTR(mfile,mm_i,1)
IF mchar = ' '
mvalid = .N.
ENDIF
IF mchar < '0' .OR. mchar > '_'
mvalid = .N.
ENDIF
IF mchar > '9' .AND. mchar < 'A'
mvalid = .N.
ENDIF
* IF mchar > 'Z' .AND. ASC(mchar) < '_'
* mvalid = .N.
* ENDIF
NEXT
RETURN(mvalid)
To simulate the command SET PRINT TO &mm_txtfile.
I used TxtFile class to create a xxxx.Txt from xxxx.mem
then MemFedit use a memoedit to edit this txt
but I not understood how converte it
then it save a new file with SAVE TO &savefile. ALL EXCEPT savefile
Perhaps to Edit all variables we can save all variables and values on array and then can use Xbrowse
then wecan save all or converte into inifile
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour March-April 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com