Directory Entries


About

This package is distributed under GPL. This is a tentative, written in the hope to provide a common handling of directory entries with various Scheme implementations on various platforms.

Scheme is so abstract that only a few system interfaces are provided by itself. There are standard i/o procedures such as call-with-input-file or open-input-file, easy and powerful to use, but how they work is deliberately given to implementors. The lack of system interface specifications has led to various system interfacing procedure definitions which differ depending on inplementations. The standard i/o procedures allow processing only one file at a time.

I tried to provide some directory entry name handlings using the system calls to ls command for unix and similar systems, and to dir command for Windows and OS/2. SCM's system interfaces make an exception because the system call to Windows' dir command does not return long filenames or filenames with space while they do.

The command execution results are taken into Scheme through PIPE or a temporary file if piping is not available.

Dai Inukai (inukai.d@jeans.ocn.ne.jp)

Limitations

Restrictions

To execute the command ls or dir from within a Scheme implementation, the SYSTEM procedure must be available by the implmentation. For instance, mit-scheme for os/2 does not provide system procedure and this package can not work. It annoys me because there would be no inconvenience to include it.

For implementations not providing the PIPE function, the piping is realized through a temporary file which is deleted by the procedure delete-file after the command execution. So the procedure must be available, too. If not, the procedure needs to be replaced by the call to (system "rm TEMPORARY-FILE") or (system "del (or delte) TEMPORARY-FILE").

To get the current directory, the procedure getcwd is used (or pwd for mit-scheme.) It must be available, too.

The rest of this package is r5rs compliant, I hope.

In addition, procedures in SLIB packages, particularly those in string-search, line-i/o, common-list-functions and glob are required in this package and the implementation needs to be able to make use of SLIB. Or "strsrch.scm", "lineio.scm" and so on must be loaded independently beforehand.

Tested Environments

The procedures in "direntry.scm" are tested with scm5d4, STk-4.0.1, guile-1.4 and mit-scheme-7.5.4 on FreeBSD Release 4.2, with scm5d4, STk-4.0.1 and guile-1.4 on Linux (kernel 2.2r1), scm5d4 on OS/2, Windows 98 and Windows 2000.

Procedures

Procedure: port->string-list vector-output?

Boolean argument vector-output? is optional. Returns a procedure which takes one arguement, open input port. This returned procedure, given an open input port, returns the lines read from the port as list if no argument or #f is given to vector-output?, or as vector if #t is given to vector-output?.

Suppose inport is linked to a file containing following texts:

aaa
bbb
ccc ddd
((port->string-list) inport)    => ("aaa" "bbb" "ccc ddd")
((port->string-list #t) inport) => #("aaa" "bbb" "ccc ddd")

Procedure: char-in-set? char charset

charset is optional. This predicative returns #t if char is in charset otherwise #f. If no charset is given to the argument, charset defaults to that for which char-whitespace? returns #t.

(char-in-set? #\space)           => #t
(char-in-set? #\newline)         => #t
(char-in-set? #\newline #\space) => #f
(char-in-set? #\, #\space #\,)   => #t

Procedure: decompose-string entry delimiters

delimiters are optional and mean the same as in char-in-set? and string-last-split. The procedure break down the entry string into substrings separated by delimiters, excluded, and returns a list of them.

(decompose-string "This is a sample string.")
        => ("This" "is" "a" "sample" "string.")
(decompose-string "One, two, three and four are integers." 
                  #\space #\,)
        => ("One" "two" "three" "and" "four" "are" "integers.")
(decompose-string "One, two, three and four are integers." 
                  #\space #\, #\.)
        => ("One" "two" "three" "and" "four" "are" "integers")

Procedure: recompose-string prepend? string-list delimiters

The procedure returns a concatenated string of the string elements given to the list string-list separated by the delimiters. The boolean argument prepend? controls whether the specified delimiters are put before the concatenated strings or after them. delimiters are optional and default to #\space if not specified. Recompose-string is not exactly the inverse of the decompose-string in that the delimiters are specified in the appending order to the string-list. If the number of delimiters is more than that of the string-list elements, they are truncated to that of the string-list elements. On the contrary, the number of delimiters is extended using the last element of the delimiters list if it is less than that of the string-list.

(recompose-string #f '("This" "is" "a" "sample" "string."))
            => "This is a sample string."
(recompose-string #t '("This" "is" "a" "sample" "string."))
            => " This is a sample string."
(recompose-string #f '("This" "is" "a" "sample" "string.") #\,)
            => "This,is,a,sample,string."
(recompose-string #f '("direntry" "scm" "is" "to be" "required.") 
                      #\. #\space)
            => "direntry.scm is to be required."
(recompose-string #f '("A" "test" "string" "") #\space #\- #\.)
            => "A test-string."
(recompose-string #f '("A" "test" "string" " ") #\space #\- #\.)
            => "A test-string. "

Procedure: string-last-split string nth delimiters

delimiters are optional. The procedure returns a consed list of which car is the substrings of the strings ending at the last occurence of the delimiters exclusive, and cdr is the list of substrings beginning from the next character to the last occurrence of the delimiters. The argument nth controls the length of the cdr list. If the delimiters are not given, it is that for which char-whitespace? returns #t.

(string-last-split "This is a sample string." 1)  
                 => (("This" "is" "a" "sample")  "string.")
(string-last-split "A-little-brown-fox" 1 #\-)
                 => ("A" "little" "brown")  "fox")
(string-last-split "A-little-brown-fox" 2 #\-)
                 => (("A" "little") "brown" "fox")
(string-last-split "1, 2, 3 and 4" 1 #\, #\space) 
                 => (("1" "2" "3" "and") "4")
(string-last-split "This is a sample string." 0 #\,)
                 => (("This is a sample string."))
(string-last-split "This is a sample string." 3 #\,)
                 => (() "This is a sample string.")
(string-last-split "This is a sample string." 5 #\,)
                 => (()  "This is a sample string.")

Procedure: string-join-split consed-list

Makes a new string list from the consed list made by the procedure string-last-split and returns it.

(string-join-split (string-last-split "This is a sample string." 1))
                 => ("This" "is" "a" "sample" "string.")
(string-join-split (string-last-split "A-little-brown-fox" 2 #\-))
                 => ("A" "little" "brown" "fox")

In order to recompose the original string, the procedure recompose-string is needed.

(recompose-string #f 
                  (string-join-split 
                    (string-last-split "A-little-brown-fox" 2 #\-)) 
                  #\-)
                 => "A-little-brown-fox"

Procedure: call-with-input-pipe command-string proc

Command-string is any string constituting a valid system command which is passed to the system procedure. Proc is a procedure accepting one argument, Scheme open input port. Call-with-input-pipe executes the system command with argument coomand-string, opens a pipe, passes the command execution result to the pipe, passes the pipe end to the proc as opened input port and closes the pipe after the execution of proc. The procedure returns the value returned by proc.

Suppose the current directory is "direntry":

(load "direntry.scm")
(call-with-input-pipe "ls ."
  (lambda (inport)
    (do ((l (read-line inport)(read-line inport)))
	((eof-object? l))
	(write-line l))))
ChangeLog
About
direntry.scm
direntry.texi
=> ;; returns the evaluated value of the do expression.

Procedure: is-directory? name-string

Returns #t if the string given to the arguement name-string is a directory and #f otherwise. The procedure returns #f, too, if the string given to name-string does not exist in the file system.

(is-directory? ".")                       => #t
(is-directory? "./direntry")              => #t
(is-directory? "./direntry/direntry.scm") => #f
(is-directory? "/usr/local")              => #t

Procedure: directory-empty? name-string

Returns #t if the directory name specified to the arguement name-string contains nothing and #f otherwise.

(directory-empty? "/usr/local")           => #f

Procedure: dirent:scan-directory directories?

The procedure is called from directory-contains. The boolean arggument directories? controls whether to scan for the directories if #t is spcified, and other contents if #f is specified. dirent:scan-directory returns a procedure which returns the maatched paths to the string specified to its argument.

The returned procedure takes search-string, short-specs? and absolute? as arguments. short-specs? and absolute? are optional and default both to #t if none is specified. As the procedure uses unix's ls or ms-dos's dir as command string to the system procedure, file or directory details are returned if short-specs? are #f. The absolute path to the file or directory is returned if #t is specified to absolute?.

Suppose the current direcoty is "/usr/local/lib/slib/direntry":

((dirent:scan-directory  #f) ".")
        => ("/usr/local/lib/slib/direntry/About" 
                   "/usr/local/lib/slib/direntry/COPYING" 
                   "/usr/local/lib/slib/direntry/ChangeLog" 
                   "/usr/local/lib/slib/direntry/direntry.info" 
                   "/usr/local/lib/slib/direntry/direntry.scm" 
                   "/usr/local/lib/slib/direntry/direntry.texi")
((dirent:scan-directory #f) "." #t #t)
        => ("/usr/local/lib/slib/direntry/About" 
                   "/usr/local/lib/slib/direntry/COPYING" 
                   "/usr/local/lib/slib/direntry/ChangeLog" 
                   "/usr/local/lib/slib/direntry/direntry.info" 
                   "/usr/local/lib/slib/direntry/direntry.scm" 
                   "/usr/local/lib/slib/direntry/direntry.texi")
((dirent:scan-directory #f) "." #t #f)
        => ("About" "COPYING" "ChangeLog" "direntry.info" 
                   "direntry.scm" "direntry.texi")
((dirent:scan-directory #t) "." #t #f)                            
        => ("." "..")
((dirent:scan-directory #t) "." #t #t)
        => ("/usr/local/lib/slib/direntry/." 
                   "/usr/local/lib/slib/direntry/..")
((dirent:scan-directory #t) "/usr/local/lib/slib" #f #f)
        => ("drwxr-xr-x 2 root wheel 512 3/21 05:00 direntry" 
                   "drwxr-xr-x 2 root wheel 512 3/27 05:03 jfilter" 
                   "drwxr-xr-x 2 root wheel 512 3/22 02:45 wb")
((dirent:scan-directory #f) "/usr/lib/libm.so.[0-9]" #t #f)
        => ("libm.so.2")
((dirent:scan-directory #f) "/usr/lib/libm.so.[0-9]" #t #t)
        => ("/usr/lib/libm.so.2")
((dirent:scan-directory #f) "/usr/lib/libm.so.[0-9]" #f #f)
        => ("-r--r--r-- 1 root wheel 118992 11/20 20:58 libm.so.2")
((dirent:scan-directory #f) "/usr/lib/libm.so.[0-9]" #f #t)
        => ("-r--r--r-- 1 root wheel 118992 11/20 20:58 
                   /usr/lib/libm.so.2")

Procedure: directory-contains directories? vector-output? short-specs? absolute? search-strings
Returns the matches of the search-strings specifications. The directory paths are returned if #t is specified to directories? and paths to files otherwise. The value is returned as vector if #t is specified to vector-output? or as list if #f is specified.

short-specs?, absolute? and search-strings are all optional and as many arguments can be specified in any order. The first encountered boolean argument is assigned to short-specs?, the second to absolute?, and more than two boolean arguments are ignored. Multiple search-string can be specified or search-strings can all be in one string separated by #\space, which are converted into list of strings and scanned for one by one by dirent:scan-directory.

If none is specified for option arguments, short-specs? defaults to #t, absolute? to #t and the current directory is scanned.

(directory-contains #f #f "/usr/lib/libm.*" "/usr/lib/libc.*" #t #f)
        => ("libc.a" "libc.so" "libc.so.4" "libm.a" "libm.so" 
                   "libm.so.2")
(directory-contains #f #f "/usr/lib/libm.* /usr/lib/libc.*" #t #f)
        => ("libc.a" "libc.so" "libc.so.4" "libm.a" "libm.so" 
                   "libm.so.2")
(directory-contains #f #f "/usr/lib/libm.*" #t #t)
        => ("/usr/lib/libm.a" "/usr/lib/libm.so" 
                   "/usr/lib/libm.so.2")
(directory-contains #f #f "/usr/lib/libm.*" #f #f)
        => ("-r--r--r-- 1 root wheel 118992 11/20 20:58 libm.so.2" 
                   "-r--r--r-- 1 root wheel 274862 11/20 20:58 libm.a" 
                   "lrwxrwxrwx 1 root wheel 9 2/ 9 09:43 libm.so 
                                                        -> libm.so.2")
(directory-contains #f #f "/usr/lib/libm.*" #f #t)
        => ("-r--r--r-- 1 root wheel 118992 11/20 20:58 
                    /usr/lib/libm.so.2" 
                   "-r--r--r-- 1 root wheel 274862 11/20 20:58 
                    /usr/lib/libm.a" 
                   "lrwxrwxrwx 1 root wheel 9 2/ 9 09:43 
                    /usr/lib/libm.so -> libm.so.2")

files, files-v, dirs and dirs-v are provided as shortcuts to directory-contains.

Procedure: files short-specs? absolute? search-strings
short-specs?, absolute? and search-strings are all optional and as many arguments can be specified in any order. See directory-contains.

Returns path names to file matching the search-strings as list.

Procedure: files-v short-specs? absolute? search-strings
short-specs?, absolute? and search-strings are all optional and as many arguments can be specified in any order. See directory-contains.

Returns path names to file matching the search-strings as vector.

Procedure: dirs short-specs? absolute? search-strings
short-specs?, absolute? and search-strings are all optional and as many arguments can be specified in any order. See directory-contains.

Returns path names to directory matching the search-strings as list.

Procedure: dirs-v short-specs? absolute? search-strings
short-specs?, absolute? and search-strings are all optional and as many arguments can be specified in any order. See directory-contains.

Returns path names to directory matching the search-strings as vector.

Procedure: directoryname-in-path pathname
Returns the valid directory components in pathname.

(directoryname-in-path "/usr/local/lib") 
        => "/usr/local/lib"
(directoryname-in-path "/usr/local/bin/scm")
        => "/usr/local/bin"
(directoryname-in-path "/usr/local/lib/non-existing-name")
        => "/usr/local/lib"
(directoryname-in-path "/usr/local/lib/slib/nclients.scm")
        => "/usr/local/lib/slib"
(directoryname-in-path ".")
        => "/usr/local/lib/slib/direntry"
        ;; current directory's path is returned.

Procedure: filename-in-path pathname
Returns the file name in pathname. If pathname is a directory or the file does not exist in the file system, null string is returned.

(filename-in-path "/usr/local/lib/slib/nclients.scm")
        => "nclients.scm"
(filename-in-path "/usr/local/lib/slib")
        => ""
(filename-in-path "/usr/local/lib/non-existing-name")
        => ""

Procedure: basename-in-path pathname
Returns the last component of the pathname whether or not the pathname is a directory or the file does not exist.

(basename-in-path "/usr/local/lib/slib/nclients.scm")
        => "nclients.scm"
(basename-in-path "/usr/local/lib/slib")
        => "slib"
(basename-in-path "/usr/local/lib/non-existing-name")
        => "non-existing-name"

Procedure: get-extension pathname updown
updown is optional. The procedure returns the last string after period (.) in the last component of the pathname (extension), case conversion made according to the specification to the argument updown. Null string is returned if the last component has no extension.

The specification to updown is none: no conversion is made, #t: down-case conversion and #f: up-case conversion.

(get-extension "scm.EXE")      => "EXE"
(get-extension "scm.EXE" #t)   => "exe"
(get-extension "scm.exe" #f)   => "EXE"

Install

Expand the "direntry.zip" into the appropriate directory, for instance into your home directory $HOME. This makes a directory "$HOME/direntry" and opens out the contents into it.

Add to your Scheme implementation's initialization file a line consing the package to SLIB *catalog*.

unzip direntry.zip -d ~.
(require 'glob) ; in case the *catalog* variable is not available.
(set! *catalog*
  (cons (cons 'directory-entries "your-home-directory/direntry") *catalog*))

Or if you find this package useful, rewrite mklibcat.scm under SLIB directory and recreate SLIBCAT as root:

*** mklibcat.scm.orig	Fri Mar 30 19:48:40 2001
--- mklibcat.scm	Wed Mar 21 05:21:58 2001
***************
*** 37,42 ****
--- 37,45 ----
  	    (cons 'portable-scheme-debugger
  		  (in-vicinity (sub-vicinity (library-vicinity) "psd")
  			       "psd-slib"))
+ 	    (cons 'directory-entries
+ 		  (in-vicinity (sub-vicinity (library-vicinity) "direntry")
+ 			       "direntry"))
  	    (cons 'jfilter
  		  (in-vicinity (sub-vicinity (library-vicinity) "jfilter")
  			       "jfilter")))

The above rewrite done, issue followings from Scheme still as root:

(require 'new-catalog)
(require 'directory-entries)

And a new SLIBCAT is created.

Jump to: b - c - d - f - g - i - p - r - s

b

  • basename-in-path
  • c

  • call-with-input-pipe
  • char-in-set?
  • d

  • decompose-string
  • directory-contains
  • directory-empty?
  • directoryname-in-path
  • dirent:scan-directory
  • dirs
  • dirs-v
  • f

  • filename-in-path
  • files
  • files-v
  • g

  • get-extension
  • i

  • is-directory?
  • p

  • port->string-list
  • r

  • recompose-string
  • s

  • string-join-split
  • string-last-split
  • Jump to: a - l - r - t

    a

  • About
  • l

  • Limitations
  • r

  • restrictions
  • t

  • Tested Environments

  • This document was generated on 7 April 2001 using the texi2html translator version 1.52.