.TITLE SEARCHDIR Wildcard directory search for VAX C ;======================================================================== ;= = ;= Programmer: Hunter Goatley = ;= Routine: SEARCHDIR.MAR = ;= Language: VAX-11 MACRO32 = ;= Purpose: Return filenames from a directory search = ;= System: VAX 11/785 VAX/VMS v4.2 = ;= Shop: WKU/ACRS = ;= Date: May 20, 1986 = ;= = ;======================================================================== ;= = ;= Functional description = ;= = ;= SEARCHDIR is a VAX-11 MACRO routine that can be called from = ;= a VAX C program. It will take a file specification and return = ;= a pointer to an array of pointers to character strings. This = ;= routine is designed to allow wildcard processing (as the UNIX = ;= shell and DCL do). Each file specification is terminated by = ;= a NULL byte ('\0') to work with VAX C. = ;= = ;= Calling sequence: = ;= = ;= int number; = ;= char **spec_ptr; = ;= = ;= spec_ptr = searchdir(&number,"filename.ext"); = ;= or spec_ptr = searchdir(&number, *argv); = ;= = ;= Input arguments: = ;= = ;= number -- Integer to receive the number of files that matched = ;= the file specification. Passed by address. (&) = ;= = ;= filename - Pointer to the file specification. = ;= = ;= Output arguments: = ;= = ;= spec_ptr - Pointer to an array of pointers to character. = ;= Like **argv. Each pointer points to a valid file = ;= specification. = ;= = ;= Return values: = ;= = ;= A pointer to the array of file spec addresses is returned. If = ;= an error occurs, a -1 is returned. = ;= = ;======================================================================== ; .PSECT DATA,NOEXE,LONG .SUBTITLE Macro definitions ; $RMSDEF ; RMS symbols $FABDEF ; FAB symbols $NAMDEF ; NAM block definitions ; .SUBTITLE FABs and NAMs .ALIGN LONG ; ;*** File Access Block for RMS Parse & Search ; SEARCH_FAB: $FAB FOP=NAM, - ; Use NAM block inputs NAM=SEARCH_NAM, - ; The address of the NAM block FNA=FILNAM_ADDR ; The address of the file name ; ;*** Record Access Block for input ; SEARCH_NAM: $NAM RSA=RES_FILNAM, - ; Buffer address for resultant filename RSS=NAM$C_MAXRSS, - ; Resultant string area size ESA=EXP_FILNAM, - ; Buffer addr for the expanded string ESS=NAM$C_MAXRSS ; Expanded string area size FILNAM_ADDR: ; The file specification .BLKB NAM$C_MAXRSS ; RES_FILNAM: ; The resultant string area .BLKB NAM$C_MAXRSS ; EXP_FILNAM: ; The expanded string area .BLKB NAM$C_MAXRSS ; FILNAM_LEN: ; Length of wildcard file specification .BLKL 1 ; ; ARGV2: .BLKL 4096 ; Array of pointers to character strings END_ARGV = . ; ; VM_PTR: .BLKL 1 ; Pointer to virtual memory ; NUM_BYTES: ; Number of bytes for LIB$GET_VM to .BLKL 1 ; ... allocate ; ;=============================================================================== ; .SUBTITLE Main routine .PSECT SEARCHDIR,EXE,NOWRT .ENTRY SEARCHDIR,^M ; MOVL 8(AP),R3 ; Get ARGV2 from C LOCC #0,#NAM$C_MAXRSS,(R3) ; Find the end of it SUBL3 R3,R1,R6 ; Get its length BNEQU 5$ ; If file not specified, ret w/ error BRW BYE ; 5$: MOVC3 R6,(R3),FILNAM_ADDR ; Copy the file spec to FILNAM_ADDR LOCC #^A/./,R6,FILNAM_ADDR ; Is an extension given? BNEQU 10$ ; Yes -- go on MOVW #^A/.*/,FILNAM_ADDR(R6) ; No -- Move ".*" to file spec INCL R6 ; Bump up pointer INCL R6 ; ... ; ; Call $PARSE once to establish the RMS context for parsing ; 10$: MOVB R6,SEARCH_FAB+FAB$B_FNS ; Set the file specification size $PARSE FAB=SEARCH_FAB ; Parse the file specification BLBC R0,BYE ; Error? ; MOVAB ARGV2,R6 ; Move the array addr to R3 MOVAL VM_PTR,R7 ; Move the VM pointer to memory MOVAB RES_FILNAM,R8 ; Get the addr of the resultant str buff MOVAL NUM_BYTES,R9 ; Get the addr of NUM_BYTES CLRL R10 ; Clear the count of matching file names ; ; Search until all possibilities are eliminated ; LOOP: CMPL #END_ARGV,R6 ; Have we reached the maximum number? BEQLU BYE ; Yes -- leave $SEARCH FAB=SEARCH_FAB ; Search for filename matching spec BLBC R0,BYE ; Error? MOVZBL SEARCH_NAM+NAM$B_RSL,R4 ; Move the resulting length to R1 MOVB #0,(R8)[R4] ; Move a 0 byte after the string INCL R4 ; Bump up # of bytes to allow for '\0' MOVL R4,(R9) ; Move the length to NUM_BYTES ; PUSHL R7 ; Push the VM pointer address PUSHL R9 ; Push the number of bytes to allocate CALLS #2,G^LIB$GET_VM ; Allocate dynamic storage ; MOVL (R7),R1 ; Get the address of the allocated mem MOVL R1,(R6)+ ; Move it to ARGV2 array (+ bump ptr) MOVC3 R4,(R8),(R1) ; Move resultant string to alloc memory INCL R10 ; Bump up number of matching file specs BRB LOOP ; Search until No More Files ; BYE: CMPL #RMS$_NMF,R0 ; Are there more matching files? BEQLU 5$ ; NO -- exit ; ; Here if error ; MOVL #0,@4(AP) ; Move 0 to the filename count MOVL #-1,R0 ; Move a -1 to R0 (return w/ error) RET ; Return to caller ; ; Here if normal return ; 5$: MOVL R10,@4(AP) ; Move the count of filename to C count MOVAL ARGV2,R0 ; Move the address of the array for RET RET ; Return to caller .END