English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. Blitz Basic

 
 
Thread Tools
Old 19 April 2018, 01:27   #1
earok
Registered User

 
Join Date: Dec 2013
Location: Auckland
Posts: 1,647
Enumerating through files in a directory?

Is there a way to loop through all of the files in a directory? Just being able to get an array of filenames from a directory would be fine.
earok is offline  
AdSense AdSense  
Old 19 April 2018, 10:26   #2
Daedalus
Registered User

Daedalus's Avatar
 
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 2,747
If you're using Amiblitz 3, there's a dos_Scandir{} function in the dos include that cycles through all entries in a particular path. It includes optional pattern matching and uses the OS calls internally.
Code:
Repeat
  name$ = dos_ScanDir{"Work:Files", "#?", #dos_scan_files}
  NPrint name$
Until name$ = ""
The second parameter is the pattern to match, and the last parameter is a modifier flag. Possible values are #dos_scan_dirs, #dos_scan_files, #dos_scan_nocasesense and #dos_scan_sorted, and can be ORed together.

In Blitz 2.1, the ElmoreDOSLib user lib has some similar commands. MoreEntries returns true if there are more entries in the current directory, and EntryName$, EntryDate etc. return properties of the current entry.

Code:
ChDir "Work:Files"

While MoreEntries
  Print EntryName$
  If EntryDIR Then NPrint " (Dir)" Else NPrint ""
End While
Creating an array from either method should be pretty straightforward.
Daedalus is offline  
Old 19 April 2018, 10:31   #3
StingRay
move.l #$c0ff33,throat

StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 5,860
Lock the directory, use Examine() to fill the FiB, then use ExNext() until you get ERROR_NO_MORE_ENTRIES.

Edit: just noticed it's the BB2 section here but as I know you are able to read/code asm too I hope it still is useful.

Code:
	INCLUDE	SOURCES:INCLUDE/LVOs.i
	
PARSEDIR
	lea	VARS(pc),a5
	move.l	$4.w,a6
	moveq	#37,d0			; at least OS 2.04 is needed
	lea	DOSname(pc),a1
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,DOSbase(a5)
	beq.b	.error

	
	lea	FILENAME(pc),a0		; = directory name here
	move.l	a0,d1
	moveq	#-2,d2			; ACCESS_READ
	move.l	DOSbase(a5),a6
	jsr	_LVOLock(a6)
	move.l	d0,DIRLOCK(a5)
	beq.b	.error
	move.l	d0,d1
	lea	FILEINFO(a5),a0
	move.l	a0,d2
	jsr	_LVOExamine(a6)
	tst.l	d0
	beq.b	.error

.loop	move.l	DIRLOCK(a5),d1
	lea	FILEINFO(a5),a0
	move.l	a0,d2
	jsr	_LVOExNext(a6)
	tst.l	d0
	bne.b	.fileok
	jsr	_LVOIoErr(a6)
	cmp.w	#232,d0			; ERROR_NO_MORE_ENTRIES
	bne.b	.error
	bra.b	.end
.fileok	lea	FILEINFO+8(a5),a0	; file name

	bra.b	.loop


	rts
.end
.error	move.l	DOSbase(a5),a1
	move.l	$4.w,a6
	jsr	_LVOCloseLibrary(a6)
	rts

DOSname		dc.b	"dos.library",0
FILENAME	dc.b	"RAM:1/",0

		CNOP	0,4	; FiB must be longword aligned!
VARS		RSRESET
DOSbase		rs.l	1
DIRLOCK		rs.l	1
FILEINFO	rs.b	260		; fib_SIZEOF
SIZEOF		rs.b	0
		ds.b	SIZEOF
Attached Files
File Type: s ExmaineDir.s (1,014 Bytes, 9 views)

Last edited by StingRay; 19 April 2018 at 11:06. Reason: Code added and source attached
StingRay is offline  
Old 19 April 2018, 11:47   #4
earok
Registered User

 
Join Date: Dec 2013
Location: Auckland
Posts: 1,647
Thanks guys, that should be more than enough to get me through it

Blitz supports inline ASM, though I'm not totally sure how it it'd handle the LVOs. In any case it also supports DOS library calls with standard basic, so I could try that too.
earok is offline  
Old 19 April 2018, 12:02   #5
StingRay
move.l #$c0ff33,throat

StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 5,860
Quote:
Originally Posted by earok View Post
Blitz supports inline ASM, though I'm not totally sure how it it'd handle the LVOs.
I can easily adapt the source not to use any LVOs if needed.
StingRay is offline  
Old 20 April 2018, 23:57   #6
earok
Registered User

 
Join Date: Dec 2013
Location: Auckland
Posts: 1,647
EDIT: I know this is a dumb question but, how do I CHANGE the current directory we're in? I guess I could run an "execute cd [directoryname]" command or the like but that seems ridiculous..


I didn't have much luck with the Elmore DOS library but this seems to work as expected for populating my array with names (using the DOS calls per Stingray's suggestion but ported to Basic).

Thanks for your help guys

Code:
Dim DirectoryInfo$(4096)
DirectoryCount=0

NEWTYPE .DateStamp
   ds_Days.l;	      /* Number of days since Jan. 1, 1978 */
   ds_Minute.l;	      /* Number of minutes past midnight */
   ds_Tick.l;	      /* Number of ticks past minute */
End NEWTYPE

NEWTYPE .FileInfoBlock 
   fib_DiskKey.l
   fib_DirEntryType.l;  /* Type of Directory. If < 0, then a plain file.    * If > 0 a directory */
   fib_FileName.b[108]; /* Null terminated. Max 30 chars used for now */
   fib_Protection.l;    /* bit mask of protection, rwxd are 3-0.	   */
   fib_EntryType.l;
   fib_Size.l;	     /* Number of bytes in file */
   fib_NumBlocks.l;     /* Number of blocks in file */
   fib_Date.DateStamp;/* Date file last changed */
   fib_Comment.b[80];  /* Null terminated comment associated with file */

   ;/* Note: the following fields are not supported by all filesystems.	*/
   ;/* They should be initialized to 0 sending an ACTION_EXAMINE packet.	*/
   ;/* When Examine() is called, these are set to 0 for you.		*/
   ;/* AllocDosObject() also initializes them to 0.			*/
   fib_OwnerUID.w;		/* owner's UID */
   fib_OwnerGID.w;		/* owner's GID */

   fib_Reserved.b[32];
End NEWTYPE
   
Statement ReadDirectory{Address$}

	Shared DirectoryInfo$()
	Shared DirectoryCount
		
	DEFTYPE .FileInfoBlock FIB
	
	DirectoryCount=0
	Lock.l = Lock_(Address$,-2)
	if Examine_( Lock, &FIB )
		While ExNext_( Lock, &FIB ) 
			if FIB\fib_DirEntryType>0 ;This is a directory
				DirectoryInfo$(DirectoryCount) = Peek$(&FIB\fib_FileName)
				DirectoryCount+1
			endif			
		Wend
	endif
	Unlock_(Lock)
	
End Statement

Last edited by earok; 21 April 2018 at 00:07.
earok is offline  
Old 21 April 2018, 12:59   #7
Daedalus
Registered User

Daedalus's Avatar
 
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 2,747
I think SetCurrentDirName_(Dirname$) should do it, though you should get Dirname$ from GetLockName_() of a lock on the new directory to do it properly.

As an aside, the resident file "amigalibs.res" includes all the standard Amiga OS headers, including structs (Newtypes) and constants. If you add this to your project in the Compiler settings window, you won't have to include the Newtype definitions for DateStamp, FileInfoBlock or anything else in your code.

That will also let you use OS constants like #SHARED_LOCK instead of the -2 magic number - more typing, but easier to read code when you come back to it in a year's time
Daedalus is offline  
Old 22 April 2018, 02:35   #8
idrougge
Registered User
 
Join Date: Sep 2007
Location: Stockholm
Posts: 3,328
ChangeDir changes directory.
idrougge is offline  
AdSense AdSense  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Reading files from current directory in assembly hukka Coders. System 29 01 January 2018 22:03
Shell: need to list directory of files with their attributes Foebane support.Apps 2 08 February 2017 22:54
Listing files, loading files and allocating all available chip ram. h0ffman Coders. System 16 04 April 2013 21:24
UAE files! Where is the database providing these WinUAE setup files? taichi_tarot Retrogaming General Discussion 3 02 June 2006 00:36
limit to files in a directory? yadster support.Hardware 7 09 August 2003 15:00

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 15:50.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.
Page generated in 0.09200 seconds with 15 queries