Can anyone help me understand how to get the following to work?
I save lots of newsgroup items into a specified folder, call it
"ZippoRama:deCap:". Some of these items are buried deeper in
subfolders I create in "ZippoRama:deCap:".
I would like to remove various header lines from every file in this
folder, and save the filtered files in another folder (call it
"ZippoRama:Filtrate:", which is not a subfolder of
"ZippoRama:deCap:"). I would also like to change the file type of the
replacement files to "TEXT" and the creator to "NISI" so that they
open easily in an Nisus (a great word processor, BTW). Then I want to
delete all of the original files. Finally, I want this to happen
without getting an Open dialog or needing to interact with the pgm in
any way other than launching it.
First I wrote a program that could do the filtering of a single file
selected by the user via a FILES$(fOpen, xxx, xxx) command. In this
pgm the filtered file is created in the same folder as the original.
While this routine is inelegant in how it does the filtering and how
it saves the files, it works fine. Here's the code:
'=====================
' filename: deCap_v0.3
'
' 29 Aug 99:
'
' description:
' **** Takes a TEXT file and removes header lines based on first
three characters in a line.
' **** Sets creator to NISI.
' planned evolution:
' **** more elegant and robust filtering technique, more efficient
method of saving replacement file
' **** should process all files in a specific or user-specified
directory; delete original file
' ****
' revision history (see predecessor for earlier changes):
' **** 29 Aug 99: v0.1 begun
' **** 30 Aug 99: v0.2 begun
' **** 31 Aug 99: v0.3 begun and working:
' **** * setting type and creator works
' **** * only one file at a time
'---------------- Header ----------------
COMPILE 0, _caseInsensitive
'-------------- Constants ---------------
_mFile = 1
_iFilterAFile = 1
_iQuit = 2
'--------------- Globals ----------------
DIM infilename$, outfilename$
DIM vcase%, counter&(10240), lyncount&
DIM textBuff%(256000), lyn%(2048), textBuffPtr&
END GLOBALS
'-------------- Includes ---------------
'-------------- Functions ---------------
LOCAL FN prompt
PRINT
PRINT "Select operation from File menu, or <cmd-period> to exit: "
END FN
LOCAL FN initialize
DEF OPEN "TEXT"
MENU _mFile, 0, _enable, "File"
MENU _mFile, _iFilterAFile, _enable, "GetInFile/1"
MENU _mFile, _iQuit, _enable, "Quit/."
textBuffPtr& = VARPTR(textBuff%(0))
END FN
LOCAL FN userDial
CLS
PRINT
PRINT "Input file must be in TEXT format."
PRINT
PRINT "Select operation from File menu, or <cmd-period> to exit: "
END FN
'-----------------------------------------
'ChangeTypeCreator
'-----------------------------------------
'This function will change the creator and
'file type of a file
'-----------------------------------------
_myIoFlFndrInfo = 32
CLEAR LOCAL
DIM pBlock.128
DIM err
DIM oldType&
DIM oldCreator&
DIM attrib
DIM 90 msg$
LOCAL FN ChangeTypeCreator(filename$, vRefNum)
ftyp&=CVI("TEXT")
crea&=CVI("NISI")
pBlock.ioCompletion& = 0
pBlock.ioNamePtr& = @fileName$
pBlock.ioVRefNum% = vRefNum
pBlock.ioDirID& = 0
pBlock.ioFDirIndex% = 0
err = FN HGETFILEINFO(@pBlock)
LONG IF err = _noErr
oldType& = pBlock.myIoFlFndrInfo.fdType&
oldCreator& = pBlock.myIoFlFndrInfo.fdCreator&
LONG IF theType& <> oldType& OR theCreator& <> oldCreator&
attrib = PEEK(@pBlock + _ioFlAttrib)
SELECT CASE
CASE (attrib AND BIT(0)) <> 0 'file is locked
PRINT "File is locked: ";filename$
BEEP
CASE (attrib AND BIT(7)) <> 0 'file is already open
PRINT "File is already open: ";filename$
BEEP
CASE ELSE
pBlock.myIoFlFndrInfo.fdType& = ftyp&
pBlock.myIoFlFndrInfo.fdCreator& = crea&
err = FN SETFILEINFO(@pBlock)
'for educational value only...
DEFSTR LONG
END SELECT
END IF
XELSE
PRINT "HGetFileInfo returned an error: ";err
BEEP
END IF
END FN = err
LOCAL FN filterAFile
infilename$ = FILES$(_fOpen, "TEXT",, vrn%)
LONG IF LEN(infilename$)>0
outfilename$ = LEFT$(infilename$, LEN(infilename$)-4)
OPEN "I", #1, infilename$,,vrn%
recsInFile& = LOF(1,1)
READ FILE #1, textBuffPtr&, recsInFile&
CLOSE #1
counter& = 0
WHILE counter& < recsInFile&
lyncount&=0
lyn%(0)=122 'chr$(122)--> 'z'
lyn%(1)=122
lyn%(2)=122
lyn%(3)=122
WHILE PEEK(textBuffPtr& + counter& + lyncount&) <> 13
lyn%(lyncount&) = PEEK(textBuffPtr& + counter& + lyncount&)
lyncount& = lyncount& + 1
WEND
lyncount& = lyncount& + 1
be$=CHR$(lyn%(0))+CHR$(lyn%(1))
beg$ = be$+CHR$(lyn%(2))
begg$ = be$+CHR$(lyn%(2))+CHR$(lyn%(3))
LONG IF (be$="X-" OR beg$="To" OR begg$="Send" OR begg$="Appr"
OR begg$="Path" OR begg$="Xref" OR begg$="Repl" OR begg$="Mime" OR
begg$="Refe" OR begg$="News" OR begg$="Orga" OR begg$="Line" OR
begg$="NNTP" OR begg$="Mess" OR begg$="MIME" OR be
gg$="C
XELSE
OPEN "A",#5,outfilename$,,vrn%
WRITE FILE #5, textBuffPtr& + counter&, lyncount&
CLOSE #5
END IF
counter& = counter& + lyncount&
WEND
END IF
FN ChangeTypeCreator(outfilename$, vrn%)
END FN
LOCAL FN splash
CLS
PRINT ""
PRINT " deCap"
PRINT " version 0.3"
PRINT ""
PRINT " (strips ugly header lines)"
PRINT ""
PRINT " © Wm. A. Christens-Barry, 1999"
PRINT ""
PRINT ""
PRINT ""
END FN
LOCAL FN buildWindow
wid%=SYSTEM(_scrnWidth)
hgt%=SYSTEM(_scrnHeight)
WINDOW #1, "deCap_v0.3", (0,40)-(wid%,hgt%), _docZoom + _NoGoAway
DELAY 100
TEXT _courier, 12
END FN
LOCAL FN wndRefresh
CLS
PRINT ""
PRINT ""
PRINT "Select operation from File menu, or <cmd-period> to exit: "
END FN
LOCAL FN doMenu
menuid = MENU(_menuID)
itemid = MENU(_itemID)
SELECT menuid
CASE _mFile
SELECT itemid
CASE _iFilterAFile
FN filterAFile
FN wndRefresh
CASE _iQuit
CLS
END
END SELECT
END SELECT
MENU
END FN
LOCAL FN doDialog
evnt = DIALOG(0)
id = DIALOG(evnt)
SELECT evnt
CASE _wndRefresh
FN wndRefresh
END SELECT
END FN
LOCAL FN doMouse
m = MOUSE(0)
mh = MOUSE(_horz)
mv = MOUSE(_vert)
END FN
'---------------- Main ------------------
FN buildWindow
FN splash
CLS
FN initialize
FN userDial
ON MENU FN doMenu
ON MOUSE FN doMouse
ON DIALOG FN doDialog
DO
HANDLEEVENTS
UNTIL programEnds
END
'=====================
Next I used the code in the FutureBASIC help entry for "FILES$
<root>" to learn how to recursively descend from the main root. I
modified this to be able to start at a top level folder of my choice
(e.g. "Volume:newsItemFolder"). This routine simply lists the files
and folders it finds during this descent.
Here's the code:
'===================
LOCAL FN rootContents (root$, indent) 'look in root
FOR x = 1 TO 2000
TRON x 'break out
rootFiles$ = FILES$(-x, "",root$, volRefNum%)
'PRINT root$, rootFiles$
LONG IF LEN(rootFiles$)
LONG IF INSTR(1, rootFiles$,":") 'is it another folder?
PRINT STRING$(indent,".") rootFiles$
subRoot$ = root$ + rootFiles$
'root:root2:root3...
FN rootContents(subRoot$,indent+5) '(recursive)
XELSE
PRINT STRING$(indent,".") rootFiles$
END IF
XELSE
x = 2000
END IF
NEXT
END FN
LOCAL FN buildWindow
WINDOW #1, "contents of ZippoRama:deCap:",(0,0)-(500,SYSTEM(_scrnHeight)-50)
TEXT _geneva, 9
AUTOCLIP=0
WIDTH = _noTextWrap
PRINT "ZippoRama:deCap:"
END FN
'---------------------- Main ---------------------------
FN buildWindow
root$="ZippoRama:deCap:"
FN rootContents (root$, 5)
DELAY 10000
'===================
Now, I am trying to combine the two. I recognize that several things
must change. First, in order to avoid the open dialog, the file to be
filtered by the filtering function (and the path to it) must be
passed to it by the calling routine. This is where I've run into
trouble. I realize I don't really understand how FILES$(),
folderVolRefName%, and volRefNum% work.
Several questions I have:
1. In the local function rootContents above, I find that if I try to
print the value of rootFile$ returned by
rootFiles$ = FILES$(-x, "",root$, volRefNum%)
I get gibberish. Why is this? What is actually returned by FILES$()
used in this manner?
2. How can I pass the filenames that are simply printed in
rootContents to the local fn filterAFile in the first program? I'm
unsure about how the volRefNum% and folderVolRefNum% commands work
and so I don't know how to pass the file location information to the
filtering routine.
Any info or examples would really help me on this.
Thanks.
Bill Christens-Barry