Path: news.uiowa.edu!news.physics.uiowa.edu!math.ohio-state.edu!uwm.edu!vixen.cso.uiuc.edu!news.uoregon.edu!cie-2.uoregon.edu!nparker From: nparker@cie-2.uoregon.edu (Neil Parker) Newsgroups: comp.sys.apple2.programmer Subject: Re: Program to put catalog of disk to txt file Date: 10 Jan 1996 11:01:11 GMT Organization: University of Oregon Campus Information Exchange Lines: 102 Message-ID: <4d069n$on8@pith.uoregon.edu> References: NNTP-Posting-Host: cie-2.uoregon.edu In article tomk@pro-nsdapple.cts.com (Tom Kelly) writes: >I am trying to create a short program that will write the catalog of a disk >to a text file. It seems to me that the following should work. >It does not create a file that I am able to load into a editor. >Does anyone know what I have done wrong? > >10?CHR$(4);"OPEN LISTING.FILE" >20?CHR$(4);"cat" >30?CHR$(4);"WRITE LISTING.FILE" >40?CHR$(4);"CLOSE LISTING.FILE" Right off hand, I can see two problems. 1. This is the obvious one: You put the CAT command before the WRITE command. Anything you want printed to the file must go *after* the WRITE command executes. 2. Alas, you can't ever print the output of a DOS command to a file, because all DOS commands (even just PRINT CHR$(4) by itself) turn off WRITE mode. So even if you move the CAT command to the right place, you'll still end up with an empty file. It *is* possible to get a directory listing into a text file, but the programming turns out to be suprisingly inconvenient. The most obvious method is to open the directory as a text file, read the information from it, and write it to listing file, like this: 10 D$ = CHR$(4) 20 DI$ = "(insert directory pathname here)" 30 F$ = "(insert listing filename here)" 40 DIM A$(100):I = 0 50 PRINT D$"OPEN"DI$",TDIR" 60 PRINT D$"READ"DI$ 70 INPUT A$(I) 80 IF LEFT$ (A$(I),11) < > "BLOCKS FREE" THEN I = I + 1: GOTO 70 90 PRINT D$"CLOSE"DI$ 100 PRINT D$"OPEN"F$ 110 PRINT D$"WRITE"F$ 120 FOR J = 0 TO I: PRINT A$(J): NEXT 130 PRINT D$"CLOSE"F$ This works, but only on directories with less than 102 files in them. If you need to to work on a directory with more files than that, you can increase the DIM size in line 40, but the basic problem remains: with this method, you need to know in advance how big the biggest directory you're going to work on is. It might occur to you to eliminate this problem by opening both files at once and do something like "read a line from the directory, write it to the file, repeat until all lines are copied." This sounds great on paper, but unfortunately, it doesn't work. If you try to OPEN a directory and a text file at the same time, BASIC.SYSTEM will lose track of where it is in the directory file, and give you the same line over and over again until you press control-C. Here's a program that does work, and doesn't require you to know in advance how big to DIM an array: 10 DI$ = "(insert name of directory here)" 20 T$ = "(insert name of listing file here)" 30 D$ = CHR$ (4) 40 FOR X = 768 TO 782: READ Y: POKE X,Y: NEXT 50 DATA 132,8,160,0,145,6,230,6,208,2,230,7,164,8,96 60 POKE 6,0: POKE 7,32: REM Buffer start = $2000 70 VL = PEEK (48688):VH = PEEK (48689): REM Save I/O vector 80 POKE 48688,0: POKE 48689,3: REM Install my I/O vector 90 PRINT D$"CATALOG"DI$ 100 POKE 48688,VL: POKE 48689,VH: REM Restore old I/O vector 110 PRINT D$"CREATE"T$",TTXT" 120 PRINT D$"BSAVE"T$",TTXT,A8192,E" PEEK (6) + 256 * PEEK (7) - 1 Like the previous program, this reads the entire directory into memory before saving it, but by an entirely different method. It patches the standard output vector, pointing it at a little machine language routine that saves all the printed characters in a buffer in memory. It CATALOGs the directory, and then BSAVEs the buffer. There is a danger of running out of memory, but it would take a *really* big directory to cause a problem. For the curious, the machine code in line 40 is as follows: BUFPTR EQU 6 YSAVE EQU 8 ORG $300 STY YSAVE ;Save Y reg LDY #0 STA (BUFPTR),Y ;Store char in buffer INC BUFPTR ;Advance buffer ptr BNE L1 INC BUFPTR+1 L1 LDY YSAVE ;Restore Y reg RTS - Neil Parker -- Neil Parker, nparker@{cie-2,cie}.uoregon.edu, http://cie-2.uoregon.edu/~nparker "Evolution is vastly overrated." -- Ambassador Delenn, _Babylon_5_ Newsgroups: comp.sys.apple2.programmer Path: news.uiowa.edu!news.physics.uiowa.edu!math.ohio-state.edu!uwm.edu!vixen.cso.uiuc.edu!newsfeed.internetmci.com!in1.uu.net!comp.vuw.ac.nz!actrix.gen.nz!dempson From: dempson@atlantis.actrix.gen.nz (David Empson) Subject: Re: Program to put catalog of disk to txt file Message-ID: Sender: news@actrix.gen.nz (News Administrator) Organization: Actrix - Internet Services Date: Wed, 10 Jan 1996 11:17:57 GMT References: X-Nntp-Posting-Host: atlantis.actrix.gen.nz Lines: 80 In article , Tom Kelly wrote: > I am trying to create a short program that will write the catalog of a disk > to a text file. It seems to me that the following should work. > It does not create a file that I am able to load into a editor. > Does anyone know what I have done wrong? > Thanks > > 10?CHR$(4);"OPEN LISTING.FILE" > 20?CHR$(4);"cat" > 30?CHR$(4);"WRITE LISTING.FILE" > 40?CHR$(4);"CLOSE LISTING.FILE" The obvious error is that you have to do the WRITE command before trying to output to the file. However, even this will not work. When you send a command to ProDOS (or DOS 3.3), text file input and output is cancelled until you do another WRITE. It is not possible to get a catalog into a file in this manner. What you can do is something like the following: 10 D$=CHR$(4) 20 PRINT D$;"PREFIX" 30 INPUT PR$ 40 PRINT D$;"OPEN ";PR$;",TDIR": REM Open the directory 50 PRINT D$;"OPEN LISTING.FILE" 60 PRINT D$;"READ ";PR$ 70 INPUT P$: REM Read prefix line 80 INPUT T$: REM Read title line 90 INPUT B$: REM Read blank line 100 PRINT D$;"WRITE LISTING.FILE" 110 PRINT P$: PRINT: PRINT T$: PRINT B$ 120 PRINT D$;"READ ";PR$ 130 INPUT L$: REM Read one line of the directory 140 PRINT D$;"WRITE LISTING.FILE" 150 PRINT L$ 160 IF L$<>"" THEN GOTO 120: REM Keep going until the last file has been read 170 PRINT D$;"READ ";PR$ 180 INPUT L$: REM Read summary line 190 PRINT D$;"WRITE LISTING.FILE" 200 PRINT: PRINT L$ 210 PRINT D$;"CLOSE" The above makes use of BASIC.SYSTEM's ability to read directories from within programs. You open the directory as if it is a text file (you just need to specify a file type in the OPEN command), then read the catalog in one line at a time. The lines are as follows: Partial prefix (name of this directory) Title line Blank line File line (repeated for each file) Blank line Disk space usage summary line All lines are in the same format as the 80-column catalog display. The only difference between the above line order and the actual display when you use the CATALOG command is that there is an extra blank line between the partial prefix and title line (my sample program puts this line back). A program can make use of this facility to read the directory listing into an array, and use string functions to process each line, e.g. to extract a listing of interesting files and displaying the relevant infomration in a menu. This is vastly easier than trying to do a similar operation in DOS 3.3, where you generally need to hook the output vector with a machine code routine and capture the output to the CATALOG command, or peek text back off the screen (limited to short catalog listings). -- David Empson dempson@actrix.gen.nz Snail mail: P.O. Box 27-103, Wellington, New Zealand