[futurebasic] how to filter and save every file within a specified folder?

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : September 1999 : Group Archive : Group : All Groups

From: Bill Christens-Barry <wacb@...>
Date: Wed, 01 Sep 1999 14:25:51 -0400
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