PreviousUpNext

15.4.870  src/lib/src/dir.pkg

## dir.pkg
## Author: Matthias Blume (blume@cs.princeton.edu)

# Compiled by:
#     src/lib/std/standard.lib

# Compare to:
#     src/lib/src/dir-tree.pkg

stipulate
    package lms =  list_mergesort;                              # list_mergesort        is from   src/lib/src/list-mergesort.pkg
    package psx =  posixlib;                                    # posixlib              is from   src/lib/std/src/psx/posixlib.pkg
herein

    package dir
    :       Dir                                                 # Dir                   is from   src/lib/src/dir.api
    {
        fun is_file filename
            =
            psx::stat::is_file
                (psx::stat filename)
            except
                _ = FALSE;

        fun is_directory  name
            =
            psx::stat::is_directory
                (psx::stat name)
            except
                _ = FALSE;

        exists = is_directory;

        fun is_something  name
            =
            {   (psx::stat name);
                TRUE;                                           # Something exists by that name.
            }
            except
                _ = FALSE;

        fun is_dot_initial  name
            =
            string::get (name, 0)   ==   '.';

        # Return an alphabetically sorted list of directory entries,
        # e.g. [ "bar", "foo", "zot" ], skipping "." and "..",
        # returning those satisfying 'is_foo':
        #
        fun foo_names  { directory_name:                String,
                         is_foo:                        String -> Bool,         # This will be either is_file or is_directory.
                         allow_dot_initial_names:       Bool
                       }
            =
            file_list
            where
                #
                # Collect everything in directory
                # as a list of strings:
                #
                file_list
                    =
                    safely::do
                        {
                          open_it  =>  .{ psx::open_directory_stream  directory_name; },
                          close_it =>     psx::close_directory_stream,
                          cleanup  =>     fn _ =  ()
                        }
                       .{   loop []
                            where
                                fun loop results
                                    =
                                    case (psx::read_directory_entry  #directory_stream)
                                        #
                                        NULL =>   lms::sort_list  string::(>)  results;
                                        #
                                        THE name =>
                                            #
                                            # Ignore everything but vanilla files:
                                            #
                                            if   (name == ".")                                                  loop results;
                                            elif (name == "..")                                                 loop results;
                                            elif (not allow_dot_initial_names  and  is_dot_initial name)        loop results;
                                            elif (is_foo (directory_name + "/" + name))                         loop (name ! results);
                                            else                                                                loop results;
                                            fi;
                                    esac;
                            end;
                        };
                    #
                #
            end;

        # Return an alphabetically sorted list of files in directory,
        # e.g. [ "bar", "foo", "zot" ], skipping those starting with a dot:
        #
        fun file_names (directory_name: String)
            =
            foo_names  { directory_name,  is_foo => is_file,  allow_dot_initial_names => FALSE };

        # Return an alphabetically sorted list of subdirectories in directory,
        # e.g. [ "bar", "foo", "zot" ], skipping those starting with a dot:
        #
        fun directory_names (directory_name: String)
            =
            foo_names  { directory_name,  is_foo => is_directory,  allow_dot_initial_names => FALSE };


        # Return an alphabetically sorted list of files in directory,
        # e.g. [ "bar", "foo", "zot" ], including those starting with a dot:
        #
        fun file_names' (directory_name: String)
            =
            foo_names  { directory_name,  is_foo => is_file,  allow_dot_initial_names => TRUE };

        # Return an alphabetically sorted list of subdirectories in directory,
        # e.g. [ "bar", "foo", "zot" ], skipping only "." and "..":
        #
        fun directory_names' (directory_name: String)
            =
            foo_names { directory_name,  is_foo => is_directory,  allow_dot_initial_names => TRUE };


        # Return an alphabetically sorted list of directory entries,
        # e.g. [ "bar", "foo", "zot" ], skipping those starting with a dot:
        #
        fun entry_names (directory_name: String)
            =
            {
                # Collect everything in directory
                # as a list of strings:
                #
                file_list
                    =
                    safely::do
                        {
                          open_it  =>  .{ psx::open_directory_stream  directory_name; },
                          close_it =>     psx::close_directory_stream,
                          cleanup  =>     fn _ =  ()
                        }
                       .{   loop []
                            where
                                fun loop results
                                    =
                                    case (psx::read_directory_entry  #directory_stream)
                                        #
                                        NULL =>   lms::sort_list  string::(>)  results;
                                        #
                                        THE filename =>
                                            #
                                            # Ignore names starting with a dot:
                                            #
                                            if   (string::length filename > 0
                                            and  string::get   (filename, 0) == '.')
                                                #
                                                loop results;
                                            else
                                                loop (filename ! results);
                                            fi;
                                    esac;
                            end;
                        };

                file_list;
            };

        # Return an alphabetically sorted list of directory entries,
        # e.g. [ ".bashrc", "bar", "foo", "zot" ], skipping "." and "..":
        #
        fun entry_names' (directory_name: String)
            =
            {
                # Collect everything in directory
                # as a list of strings:
                #
                file_list
                    =
                    safely::do
                        {
                          open_it  =>  .{ psx::open_directory_stream  directory_name; },
                          close_it =>     psx::close_directory_stream,
                          cleanup  =>     fn _ =  ()
                        }
                       .{   loop []
                            where
                                fun loop results
                                    =
                                    case (psx::read_directory_entry  #directory_stream)
                                        #
                                        NULL =>   lms::sort_list  string::(>)  results;
                                        #
                                        THE filename =>
                                            #
                                            # Ignore "." and "..":
                                            #
                                            if  (filename == "."
                                            or   filename == "..")
                                                #
                                                loop results;
                                            else
                                                loop (filename ! results);
                                            fi;
                                    esac;
                            end;
                        };

                file_list;
            };

        # Return an alphabetically sorted list of directory entries,
        # e.g. [ ".", ".."  ".bashrc", "bar", "foo", "zot" ], including "." and "..":
        #
        fun entry_names'' (directory_name: String)
            =
            {
                # Collect everything in directory
                # as a list of strings:
                #
                file_list
                    =
                    safely::do
                        {
                          open_it  =>  .{ psx::open_directory_stream  directory_name; },
                          close_it =>     psx::close_directory_stream,
                          cleanup  =>     fn _ =  ()
                        }
                       .{   loop []
                            where
                                fun loop results
                                    =
                                    case (psx::read_directory_entry  #directory_stream)
                                        #
                                        NULL         =>   lms::sort_list  string::(>)  results;
                                        THE filename =>   loop (filename ! results);
                                    esac;
                            end;
                        };

                file_list;
            };

        # Same as foo_names, but returning absolute paths ("/foo/bar/zot"):
        #
        fun foos  arg
            =
            {   cwd =  winix__premicrothread::file::current_directory ();               # Get current directory, so we can return full pathnames.
                #
                result =  foo_names  arg;

                map'  result  (fn name =  cwd + "/" + name); 
            };


        # Return an alphabetically sorted list of files in directory
        # e.g. [ "/home/jcb/bar", "/home/jcb/foo", "/home/jcb/zot" ], skipping those starting with a dot:
        #
        fun files  (directory_name: String)
            =
            foos  { directory_name, is_foo => is_file,  allow_dot_initial_names => FALSE };


        # Return an alphabetically sorted list of directories in directory
        # e.g. [ "/home/jcb/bar", "/home/jcb/foo", "/home/jcb/zot" ], skipping those starting with a dot:
        #
        fun directories  (directory_name: String)
            =
            foos  { directory_name, is_foo => is_directory,  allow_dot_initial_names => FALSE };



        # Return an alphabetically sorted list of files in directory
        # e.g. [ "/home/jcb/bar", "/home/jcb/foo", "/home/jcb/zot" ], allowing dot-initial names:
        #
        fun files'  (directory_name: String)
            =
            foos  { directory_name, is_foo => is_file,  allow_dot_initial_names => TRUE };


        # Return an alphabetically sorted list of directories in directory
        # e.g. [ "/home/jcb/bar", "/home/jcb/foo", "/home/jcb/zot" ], allowing dot-initial names other than "." and ".."
        #
        fun directories'  (directory_name: String)
            =
            foos  { directory_name,  is_foo => is_directory,  allow_dot_initial_names => TRUE };




        # Return an alphabetically sorted list of directory entries,
        # e.g. [ "bar", "foo", "zot" ], skipping those starting with a dot:
        #
        fun entries (directory_name: String)
            =
            {
                # Get current directory, so we can
                # print out full pathnames:
                cwd = winix__premicrothread::file::current_directory ();

                # Collect everything in directory
                # as a list of strings:
                #
                file_list
                    =
                    safely::do
                        {
                          open_it  =>  .{ psx::open_directory_stream  directory_name; },
                          close_it =>     psx::close_directory_stream,
                          cleanup  =>     fn _ =  ()
                        }
                       .{   loop []
                            where
                                fun loop results
                                    =
                                    case (psx::read_directory_entry  #directory_stream)
                                        #
                                        NULL =>   lms::sort_list  string::(>)  results;
                                        #
                                        THE filename =>
                                            #   
                                            # Ignore names starting with a dot:
                                            #
                                            if  (string::length filename > 0
                                            and  string::get   (filename, 0) == '.')
                                                #
                                                loop results;
                                            else
                                                loop (cwd + "/" + filename ! results);
                                            fi;
                                    esac;
                            end;
                        };

                file_list;
            };

        # Return an alphabetically sorted list of directory entries,
        # e.g. [ ".bashrc", "bar", "foo", "zot" ], skipping "." and "..":
        #
        fun entries' (directory_name: String)
            =
            {
                # Get current directory, so we can
                # print out full pathnames:
                cwd = winix__premicrothread::file::current_directory ();

                # Collect everything in directory
                # as a list of strings:
                #
                file_list
                    =
                    safely::do
                        {
                          open_it  =>  .{ psx::open_directory_stream  directory_name; },
                          close_it =>     psx::close_directory_stream,
                          cleanup  =>     fn _ =  ()
                        }
                       .{   loop []
                            where
                                fun loop results
                                    =
                                    case (psx::read_directory_entry  #directory_stream)
                                        #
                                        NULL =>   lms::sort_list  string::(>)  results;
                                        #
                                        THE filename =>
                                            #
                                            # Ignore "." and "..":
                                            #
                                            if  (filename == "."
                                            or   filename == "..")
                                                #
                                                loop results;
                                            else
                                                loop (cwd + "/" + filename ! results);
                                            fi;
                                    esac;
                            end;
                        };

                file_list;
            };

        # Return an alphabetically sorted list of directory entries,
        # e.g. [ ".", ".."  ".bashrc", "bar", "foo", "zot" ], including "." and "..":
        #
        fun entries'' (directory_name: String)
            =
            {
                # Get current directory, so we can
                # print out full pathnames:
                cwd = winix__premicrothread::file::current_directory ();

                # Collect everything in directory
                # as a list of strings:
                #
                file_list
                    =
                    safely::do
                        {
                          open_it  =>  .{ psx::open_directory_stream  directory_name; },
                          close_it =>     psx::close_directory_stream,
                          cleanup  =>     fn _ =  ()
                        }
                       .{   loop []
                            where
                                fun loop results
                                    =
                                    case (psx::read_directory_entry  #directory_stream)
                                        #
                                        NULL         =>   lms::sort_list  string::(>)  results;
                                        THE filename =>   loop (cwd + "/" + filename ! results);
                                    esac;
                            end;
                        };

                file_list;
            };


    #                     # 'root_directory' (usually build7.seed-libraries)
    #                     # is the directory containing our seed-library
    #                     # freezefiles.  In general it will contain one
    #                     # subdirectory for each independent package it
    #                     # contains.  (In practice, we have now reduced
    #                     # that to one subdirectory named ROOT.)
    #                     #
    #                     # We now set up the anchor dictionary with
    #                     # one anchor per subdirectory, the anchor
    #                     # name being the subdirectory name.
    #                     # 
    # print ("src/app/makelib/main/makelib-g.pkg/read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'/AAA: root_directory = " + root_directory + " cwd= " + (psx::current_directory()) + "\n");
    #               {
    #                   # Read the boot-directory directory-stream,
    #                   # consing up a list of all its contents:
    #                   #
    #                   fun list_dir  directory_stream
    #                       =
    # 
    #                   # Collect everything in boot_dir
    #                         # as a list of strings:
    #                   #
    #                   file_list
    #                       =
    #                       safely::do
    #                               {
    #                                 open_it  =>  .{ psx::open_directory_stream  root_directory; },
    #                             close_it =>  psx::close_directory_stream,
    #                             cleanup  => fn _ =  ()
    #                           }
    #                       loop []
    #                           where
    #                           fun loop l
    #                               =
    #                               case (psx::read_directory_entry  directory_stream)
    #                                        NULL  =>  l;
    ###                                  THE x =>  loop (x ! l);
    #                                    THE x =>
    # { print ("src/app/makelib/main/makelib-g.pkg/read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'/loop: found " + root_directory + " entry " + x + "\n");
    #                                                   loop (x ! l);
    # };
    #                                   esac;
    #                       end;
    # 
    #                   fun is_directory x
    #                       =
    #                       psx::is_directory x
    #                             except
    #                                 _ =  FALSE;
    # 
    # 
    #                         # Filter the contents of boot_dir,
    #                         # ignoring everything but subdirectories:
    #                   #
    #                   fun sub_dir x
    #                       =
    #                       {   d = p::cat (root_directory, x);
    # 
    #                           if   is_directory d
    #                           then THE (x, d);
    #                           else NULL;          fi;
    #                       };
    # 
    #                   # Generate a list of (directory_name, directory_path)
    #                   # pairs, which we shall momentarily treat as a list of
    #                   # (anchor, definition) pairs:
    #                   #
    #                   pair_list
    #                             =
    #                             list::map_partial_fn
    #                                 sub_dir
    #                                 file_list;
    # 
    # print ("src/app/makelib/main/makelib-g.pkg/read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries': pair_list #1s = " + (string::join " " (map #1 pair_list)) + "\n");
    # print ("src/app/makelib/main/makelib-g.pkg/read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries': pair_list #2s = " + (string::join " " (map #2 pair_list)) + "\n");
    #                   fun set_anchor (anchor, definition)
    #                       =
    # { print ("src/app/makelib/main/makelib-g.pkg/II: calling ad::set_anchor to set " + anchor + " to " + definition + "\n");
    # print ("src/app/makelib/stuff/makelib-g.pkg: cwd = " + (psx::current_directory()) + "\n");
    #                       ad::set_anchor  (anchor_dictionary, anchor, THE definition);
    # };
    # 
    #                   apply  set_anchor  pair_list;
    #               };

    };
end;


## Copyright (c) 1999, 2000 by Lucent Bell Laboratories
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2013,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext