1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-04-07 16:41:59 +00:00

Wildcard names for file utilities

This commit is contained in:
David Schmenk 2020-01-01 13:50:57 -08:00
parent 438ab01254
commit 7c3dfe2b2e
9 changed files with 333 additions and 173 deletions

View File

@ -1,4 +1,4 @@
import match
import matchfiles
predef matchName(src, exp)#1
predef matchList(pathptr, exp)#2
predef isWildName(exp)#1

View File

@ -3,24 +3,6 @@ include "inc/fileio.plh"
var dirbuf
//
// Copy string with upper case conversion
//
def cpyuprstr(dst, src)#0
byte i, chr
if ^src
for i = 1 to ^src
chr = src->[i]
if chr >= 'a' and chr <= 'z'
dst->[i] = chr - 'a' + 'A'
else
dst->[i] = chr
fin
next
fin
^dst = ^src
end
//
// Match next section of source and expression
//
def matchNext(src, srcofst, exp, expofst)
@ -46,34 +28,26 @@ end
// Start off matching process
//
export def matchName(src, exp)#1
char matchSrc[16], matchExp[16]
//
// Ensure valid filename lengths
//
if ^src > 15 or ^exp > 15
return FALSE
fin
//
// Match on empty wildcard name (same as '*')
//
if not ^exp
return TRUE
fin
//
// Convert strings to upper case
//
cpyuprstr(@matchSrc, src)
cpyuprstr(@matchExp, exp)
return matchNext(@matchSrc, 1, @matchExp, 1)
return matchNext(src, 1, exp, 1)
end
export def matchList(pathstr, exp)#2
byte refnum
char[64] curpath
var firstblk, entrylen, entriesblk, i, entry, filecnt, entrylist, entryptr, entrycnt
if not dirbuf
dirbuf = heapallocalign(512, 8, 0)
fin
if not ^pathstr
fileio:getpfx(@curpath)
pathstr = @curpath
fin
if pathstr->[^pathstr] <> '/' // Make sure path ends with a '/'
^pathstr++
pathstr->[^pathstr] = '/'

View File

@ -29,7 +29,7 @@ TYPE = rel/apple/TYPE\#FE1000
SIEVE = rel/SIEVE\#FE1000
PRIMEGAP = rel/PRIMEGAP\#FE1000
ARGS = rel/ARGS\#FE1000
MATCH = rel/MATCH\#FE1000
MATCHFILES = rel/apple/MATCHFILES\#FE1000
SPIPORT = rel/apple/SPIPORT\#FE1000
SDFAT = rel/apple/SDFAT\#FE1000
FATCAT = rel/apple/FATCAT\#FE1000
@ -103,7 +103,7 @@ TXTTYPE = .TXT
#SYSTYPE = \#FF2000
#TXTTYPE = \#040000
apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(PLVMJIT03) $(CMD) $(CMDJIT) $(JIT) $(JIT16) $(JITUNE) $(SOSCMD) $(SOSCMDJIT) $(PLASMAPLASM) $(CODEOPT) $(MATCH) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(COPY) $(DEL) $(REN) $(CAT) $(NEWDIR) $(TYPE) $(SOS) $(ROD) $(SIEVE) $(PRIMEGAP) $(MOUSE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(TFTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(LINES) $(HGRSPRITE) $(HGRLIB) $(HGRTEST) $(GRLIB) $(DGRLIB) $(GRTEST) $(DGRTEST) $(HGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(INT32) $(INT32TEST) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(LZ4) $(LZ4CAT) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(PLVMJIT03) $(CMD) $(CMDJIT) $(JIT) $(JIT16) $(JITUNE) $(SOSCMD) $(SOSCMDJIT) $(PLASMAPLASM) $(CODEOPT) $(MATCHFILES) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(COPY) $(DEL) $(REN) $(CAT) $(NEWDIR) $(TYPE) $(SOS) $(ROD) $(SIEVE) $(PRIMEGAP) $(MOUSE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(TFTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(LINES) $(HGRSPRITE) $(HGRLIB) $(HGRTEST) $(GRLIB) $(DGRLIB) $(GRTEST) $(DGRTEST) $(HGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(INT32) $(INT32TEST) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(LZ4) $(LZ4CAT) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ)
-rm vmsrc/plvmzp.inc
@ -225,9 +225,9 @@ $(ED): toolsrc/ed.pla $(PLVM02) $(PLASM) toolsrc/ed.pla
./$(PLASM) -AMOW < toolsrc/ed.pla > toolsrc/ed.a
acme --setpc 4094 -o $(ED) toolsrc/ed.a
$(MATCH): libsrc/match.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/match.pla > libsrc/match.a
acme --setpc 4094 -o $(MATCH) libsrc/match.a
$(MATCHFILES): libsrc/apple/matchfiles.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/apple/matchfiles.pla > libsrc/apple/matchfiles.a
acme --setpc 4094 -o $(MATCHFILES) libsrc/apple/matchfiles.a
$(ARGS): libsrc/args.pla $(PLVM02) $(PLASM)
./$(PLASM) -AMOW < libsrc/args.pla > libsrc/args.a

View File

@ -20,7 +20,7 @@ cp rel/apple/REN#FE1000 prodos/sys/REN.REL
cp rel/apple/CAT#FE1000 prodos/sys/CAT.REL
cp rel/apple/NEWDIR#FE1000 prodos/sys/NEWDIR.REL
cp rel/apple/TYPE#FE1000 prodos/sys/TYPE.REL
cp rel/MATCH#FE1000 prodos/sys/MATCH.REL
cp rel/apple/MATCHFILES#FE1000 prodos/sys/MATCHFILES.REL
cp rel/ARGS#FE1000 prodos/sys/ARGS.REL
cp rel/ED#FE1000 prodos/sys/ED.REL
cp rel/FIBER#FE1000 prodos/sys/FIBER.REL
@ -153,7 +153,7 @@ cp samplesrc/lz4cat.pla prodos/bld/samples/Z4CAT.PLA.TXT
mkdir prodos/bld/inc
cp inc/args.plh prodos/bld/inc/ARGS.PLH.TXT
cp inc/match.plh prodos/bld/inc/MATCH.PLH.TXT
cp inc/matchfiles.plh prodos/bld/inc/MATCHFILES.PLH.TXT
cp inc/cmdsys.plh prodos/bld/inc/CMDSYS.PLH.TXT
cp inc/conio.plh prodos/bld/inc/CONIO.PLH.TXT
cp inc/lines.plh prodos/bld/inc/LINES.PLH.TXT

View File

@ -6,7 +6,7 @@ echo "BLD/CODEOPT"; atftp $1 --put -l rel/CODEOPT#FE1000 -r $2/BLD/CODEOPT#FE10
#Build incs
echo "BLD/INC/ARGS.PLH"; atftp $1 --put -l inc/args.plh -r $2/BLD/INC/ARGS.PLH#040000
echo "BLD/INC/MATCH.PLH"; atftp $1 --put -l inc/match.plh -r $2/BLD/INC/MATCH.PLH#040000
echo "BLD/INC/MATCHFILES.PLH"; atftp $1 --put -l inc/matchfiles.plh -r $2/BLD/INC/MATCHFILES.PLH#040000
echo "BLD/INC/CMDSYS.PLH"; atftp $1 --put -l inc/cmdsys.plh -r $2/BLD/INC/CMDSYS.PLH#040000
echo "BLD/INC/CONIO.PLH"; atftp $1 --put -l inc/conio.plh -r $2/BLD/INC/CONIO.PLH#040000
echo "BLD/INC/LINES.PLH"; atftp $1 --put -l inc/lines.plh -r $2/BLD/INC/LINES.PLH#040000

View File

@ -11,7 +11,7 @@ echo "SYS/JIT16"; atftp $1 --put -l rel/apple/JIT16#FE1000 -r $2/SYS/JIT16#F
echo "SYS/JITUNE"; atftp $1 --put -l rel/apple/JITUNE#FE1000 -r $2/SYS/JITUNE#FE1000
# Core libraries
echo "SYS/MATCH"; atftp $1 --put -l rel/MATCH#FE1000 -r $2/SYS/MATCH#FE1000
echo "SYS/MATCHFILES"; atftp $1 --put -l rel/apple/MATCHFILES#FE1000 -r $2/SYS/MATCHFILES#FE1000
echo "SYS/ARGS"; atftp $1 --put -l rel/ARGS#FE1000 -r $2/SYS/ARGS#FE1000
echo "SYS/INT32"; atftp $1 --put -l rel/INT32#FE1000 -r $2/SYS/INT32#FE1000
echo "SYS/DHCP"; atftp $1 --put -l rel/DHCP#FE1000 -r $2/SYS/DHCP#FE1000

View File

@ -1,7 +1,7 @@
include "inc/cmdsys.plh"
include "inc/longjmp.plh"
include "inc/args.plh"
include "inc/match.plh"
include "inc/matchfiles.plh"
include "inc/fileio.plh"
include "inc/int32.plh"
@ -28,17 +28,23 @@ def putb(b)#0
fin
putc(h)
end
def strupper(strptr)#0
//
// Copy string with upper case conversion
//
def struprcpy(dst, src)#0
byte i, chr
if ^strptr
for i = 1 to ^strptr
chr = strptr->[i]
if ^src
for i = 1 to ^src
chr = src->[i]
if chr >= 'a' and chr <= 'z'
strptr->[i] = chr - 'a' + 'A'
dst->[i] = chr - 'a' + 'A'
else
dst->[i] = chr
fin
next
fin
^dst = ^src
end
def filefrompath(filestr, pathstr)#0
byte i
@ -87,9 +93,10 @@ def printentry(entryptr)#0
end
def printentries(pathstr, entries, num)#0
byte page
page = 20
puts(pathstr); putln
puts("=NAME==========TYPE===AUX====LENGTH=\n")
page = 20
repeat
printentry(entries)
entries = entries + t_fileentry
@ -152,10 +159,8 @@ if not except(exit)
fin
arg = argNext(arg)
fin
recurse = TRUE
if ^arg
strcpy(@path, arg)
strupper(@path)
struprcpy(@path, arg)
//
// Check if cataloging a directory
//

View File

@ -1,14 +1,31 @@
include "inc/cmdsys.plh"
include "inc/longjmp.plh"
include "inc/args.plh"
include "inc/fileio.plh"
include "inc/matchfiles.plh"
const MAXBUFSIZE = 16384
var arg, srcref, dstref, copybuff, copysize, copyxfer
char[64] srcfilename, dstfilename
var arg, recurse, exit, srcfilelist, srcfileptr, srccnt
char[64] dstpath
res[t_fileinfo] srcfileinfo, dstfileinfo
//
// Handy string functions
// Copy string with upper case conversion
//
def struprcpy(dst, src)#0
byte i, chr
if ^src
for i = 1 to ^src
chr = src->[i]
if chr >= 'a' and chr <= 'z'
dst->[i] = chr - 'a' + 'A'
else
dst->[i] = chr
fin
next
fin
^dst = ^src
end
def filefrompath(filestr, pathstr)#0
byte i
@ -21,126 +38,184 @@ def filefrompath(filestr, pathstr)#0
memcpy(filestr + 1, pathstr + 1 + i, ^filestr)
end
//
// Check destination filename
// Check destination path
//
def checkdst
char[17] basefile
def chkdstpath(dstfile)
//
// Check if destination exists
//
if fileio:getfileinfo(@dstfilename, @dstfileinfo) == FILE_ERR_OK
if fileio:getfileinfo(dstfile, @dstfileinfo) == FILE_ERR_OK
//
// Check if copying into a directory
//
if dstfileinfo.file_type == $0F
if dstfilename[dstfilename] <> '/'
if dstfile->[^dstfile] <> '/'
//
// Add path seperator
//
dstfilename++
dstfilename[dstfilename] = '/'
^dstfile++
dstfile->[^dstfile] = '/'
fin
filefrompath(@basefile, @srcfilename)
strcat(@dstfilename, @basefile)
if fileio:getfileinfo(@dstfilename, @dstfileinfo) == FILE_ERR_OK
//
// Check if *that* is a directory
//
if dstfileinfo.file_type == $0F
puts("Destination is a directory filename\n")
return FALSE
return TRUE
fin
fin
return FALSE
end
def copyfiles(srcfile, dstfile)#0
var entrylist, entry, entrycnt, srcref, dstref, copybuff, copyrel, copysize, copyxfer
char[64] srcpath
char[64] srcfilepath
char[64] dstfilepath
char[16] wildname
copysize = MAXBUFSIZE
while isult(heapavail, copysize + 512)
copysize = copysize / 2
loop
copyrel = heapalloc(copysize)
if copyrel
//
// Round buffer to page boundary for faster transfers
//
copybuff = (copyrel + $FF) & $FF00
//
// Check if copying a directory
//
strcpy(@srcpath, srcfile)
wildname = 0
if fileio:getfileinfo(@srcpath, @srcfileinfo) <> FILE_ERR_OK or srcfileinfo.file_type <> $0F
filefrompath(@wildname, @srcpath)
srcpath = srcpath - wildname
fin
entrylist, entrycnt = matchList(@srcpath, @wildname)
if not entrylist
//
// Unable to open source
//
puts("Unable to open: "); puts(@srcpath); putln
throw(exit, TRUE)
fin
entry = entrylist
while entrycnt
strcpy(@srcfilepath, @srcpath)
strcat(@srcfilepath, entry)
strcpy(@dstfilepath, dstfile)
if chkdstpath(@dstfilepath)
strcat(@dstfilepath, entry)
fin
puts(@srcfilepath); puts(" ==> "); puts(@dstfilepath); putln
//
// Check if source is a directory
//
if entry->entry_type == $0F
fileio:create(@dstfilepath, $0F, $0000)
if not chkdstpath(@dstfilepath)
puts("Unable to create: "); puts(@dstfilepath); putln
throw(exit, TRUE)
fin
if recurse
copyfiles(@srcfilepath, @dstfilepath)
fin
else
return TRUE
fin
fin
//
// Remove existing file
//
fileio:destroy(@dstfilename)
fin
return TRUE
end
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg
strcpy(@srcfilename, arg)
fileio:iobufalloc(2) // Reserve two I/O buffers
if fileio:getfileinfo(@srcfilename, @srcfileinfo) == FILE_ERR_OK
//
// Check that source isn't a directory - can't handle that yet
//
if srcfileinfo.file_type == $0F
puts("Can't copy directories (yet)\n")
return
fin
else
//
// File not found
//
puts("File not found: "); puts(@srcfilename); putln
return
fin
srcref = fileio:open(@srcfilename)
if srcref
arg = argNext(arg)
if ^arg
strcpy(@dstfilename, arg)
if checkdst()
//
// Check if destination exists
//
if fileio:getfileinfo(@dstfilepath, @dstfileinfo) == FILE_ERR_OK
fileio:destroy(@dstfilepath)
fin
//
// Create the destination file and open for writing
//
if fileio:create(@dstfilename, srcfileinfo.file_type, srcfileinfo:aux_type) == FILE_ERR_OK
dstref = fileio:open(@dstfilename)
if fileio:create(@dstfilepath, entry->entry_type, entry=>entry_aux) == FILE_ERR_OK
srcref = fileio:open(@srcfilepath)
dstref = fileio:open(@dstfilepath)
if dstref
//
// Let the copying begin
//
copysize = MAXBUFSIZE
while isult(heapavail, copysize + 512)
copysize = copysize / 2
loop
copybuff = heapalloc(copysize)
if copybuff
//
// Round buffer to page boundary for faster transfers
//
copybuff = (copybuff + $FF) & $FF00
copyxfer = fileio:read(srcref, copybuff, copysize)
while copyxfer
if fileio:write(dstref, copybuff, copyxfer) <> copyxfer
puts("Error writing: "); puts(@dstfilepath); putln
throw(exit, TRUE)
fin
copyxfer = fileio:read(srcref, copybuff, copysize)
while copyxfer
if fileio:write(dstref, copybuff, copyxfer) <> copyxfer
puts("Error writing: "); puts(@dstfilename); putln
break
fin
copyxfer = fileio:read(srcref, copybuff, copysize)
loop
else
puts("No memory available!\n")
fin
loop
fileio:close(dstref)
else
puts("Unable to open: "); puts(@dstfilename); putln
puts("Unable to open: "); puts(@dstfilepath); putln
throw(exit, TRUE)
fin
fileio:close(srcref)
else
puts("Unable to create: "); puts(@dstfilename); putln
puts("Unable to create: "); puts(@dstfilepath); putln
throw(exit, TRUE)
fin
fin
fileio:close(0)
entry = entry + t_fileentry
entrycnt--
loop
heaprelease(entrylist)
else
puts("No memory available!\n")
throw(exit, TRUE)
fin
heaprelease(copyrel)
end
//
// Install error exit
//
exit = heapalloc(t_except)
if not except(exit)
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg and arg->[1] == '-'
if ^arg > 1 and toupper(arg->[2]) == 'R'
recurse = TRUE
fin
arg = argNext(arg)
fin
if ^arg
srcfilelist = heapalloc(^arg + 1)
struprcpy(srcfilelist, arg)
srccnt++
arg = argNext(arg)
if ^arg
struprcpy(@dstpath, arg)
arg = argNext(arg)
while ^arg
//
// Add to source list
//
srcfileptr = heapalloc(dstpath + 1)
strcpy(srcfileptr, @dstpath)
srccnt++
//
// Set new destination
//
struprcpy(@dstpath, arg)
arg = argNext(arg)
loop
if not chkdstpath(@dstpath) and (srccnt > 1 or isWildName(srcfilelist))
puts("Destination must be directory: "); puts(@dstpath); putln
throw(exit, TRUE)
fin
fileio:iobufalloc(2) // Reserve two I/O buffers
srcfileptr = srcfilelist
while srccnt
//
// Copy files in list
//
copyfiles(srcfileptr, @dstpath)
srcfileptr = srcfileptr + ^srcfileptr + 1
srccnt--
loop
return
fin
else
//
// Unable to open source
//
puts("Unable to open: "); puts(@srcfilename); putln
return
fin
//
// Close all files
//
fileio:close(0)
return
puts("Usage: +COPY <SRCFILE>+ <DEST>\n")
fin
puts("Usage: +COPY SRCFILE DEST\n")
fileio:close(0)
done

View File

@ -1,62 +1,168 @@
include "inc/cmdsys.plh"
include "inc/longjmp.plh"
include "inc/args.plh"
include "inc/fileio.plh"
include "inc/matchfiles.plh"
char[64] filename
var arg
var arg, recurse, exit, filelist, fileptr, filecnt
char[64] path
res[t_fileinfo] fileinfo
//
// Copy string with upper case conversion
//
def struprcpy(dst, src)#0
byte i, chr
if ^src
for i = 1 to ^src
chr = src->[i]
if chr >= 'a' and chr <= 'z'
dst->[i] = chr - 'a' + 'A'
else
dst->[i] = chr
fin
next
fin
^dst = ^src
end
def filefrompath(filestr, pathstr)#0
byte i
for i = ^pathstr downto 1
if pathstr->[i] == '/'
break
fin
next
^filestr = ^pathstr - i
memcpy(filestr + 1, pathstr + 1 + i, ^filestr)
end
//
// Check filename
//
def checkfile
var refnum, dirbuf
res[t_fileinfo] fileinfo
def chkfile(file)#1
var refnum, dirbuf, filecnt
//
// Check if file exists
//
if fileio:getfileinfo(@filename, @fileinfo) == FILE_ERR_OK
if fileio:getfileinfo(file, @fileinfo) == FILE_ERR_OK
//
// Check if deleting a directory
//
if fileinfo.file_type == $0F
refnum = fileio:open(@filename)
refnum = fileio:open(file)
if refnum
//
// Check for files inside directory
//
filecnt = 0
dirbuf = heapalloc(512)
if fileio:read(refnum, dirbuf, 512) == 512
fileio:close(refnum)
if dirbuf=>$25 // File count in directory
puts("Directory not empty: "); puts(@filename); putln
return FALSE
fin
filecnt = dirbuf=>$25 // File count in directory
fin
heaprelease(dirbuf)
if filecnt
puts("Directory not empty: "); puts(file); putln
return FALSE
fin
fin
fin
return TRUE
fin
puts("File not found: "); puts(@filename); putln
puts("File not found: "); puts(file); putln
return FALSE
end
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg
strcpy(@filename, arg)
if checkfile()
//
// Remove existing file
//
fileio:destroy(@filename)
def delfiles(delfile)#0
var entrylist, entry, entrycnt
char[64] delpath
char[64] delfilepath
char[16] wildname
strcpy(@delpath, delfile)
wildname = 0
//if fileio:getfileinfo(@delpath, @fileinfo) <> FILE_ERR_OK or fileinfo.file_type <> $0F
if delpath[delpath] <> '/'
filefrompath(@wildname, @delpath)
delpath = delpath - wildname
fin
//
// Close all files
// Check arguments and file types
//
fileio:close(0)
return
entrylist, entrycnt = matchList(@delpath, @wildname)
if entrylist
entry = entrylist
while entrycnt
strcpy(@delfilepath, @delpath)
strcat(@delfilepath, entry)
//
// Check if file is a directory
//
if entry->entry_type == $0F
if recurse
strcat(@delfilepath, "/")
strcat(@delfilepath, @wildname)
delfiles(@delfilepath)
fin
strcpy(@delfilepath, @delpath)
strcat(@delfilepath, entry)
if chkfile(@delfilepath)
puts("Removing: "); puts(@delfilepath); putln
fileio:destroy(@delfilepath)
fin
else
puts("Removing: "); puts(@delfilepath); putln
fileio:destroy(@delfilepath)
fin
entry = entry + t_fileentry
entrycnt--
loop
elsif not wildname
puts("Not found: "); puts(@delpath); puts("/"); puts(@wildname); putln
fin
end
//
// Install error exit
//
exit = heapalloc(t_except)
if not except(exit)
//
// Check arguments and file types
//
arg = argNext(argFirst)
if ^arg and arg->[1] == '-'
if ^arg > 1 and toupper(arg->[2]) == 'R'
recurse = TRUE
fin
arg = argNext(arg)
fin
if ^arg
filelist = heapmark()
while ^arg
//
// Add to file list
//
fileptr = heapalloc(^arg + 1)
struprcpy(fileptr, arg)
filecnt++
arg = argNext(arg)
loop
fileptr = filelist
while filecnt
//
// Delete files in list
//
if recurse and fileio:getfileinfo(fileptr, @fileinfo) == FILE_ERR_OK and fileinfo.file_type == $0F
strcpy(@path,fileptr)
strcat(@path, "/")
delfiles(@path)
fin
delfiles(fileptr)
fileptr = fileptr + ^fileptr + 1
filecnt--
loop
else
puts("Usage: +DEL <FILE>+\n")
fin
fin
puts("Usage: +DEL FILE\n")
done