PreviousUpNext

15.4.123  src/app/makelib/tools/dir/tool.pkg

# A tool for processing filesystem directories
# that contain other source files.
#
#   (C) 2000 Lucent Technologies, Bell Laboratories
#
# Author: Matthias Blume (blume@kurims.kyoto-u.ac.jp)

# Compiled by:
#     src/app/makelib/tools/dir/dir-tool.lib

package dir_tool {

    stipulate

        include package   tools;

        tool = "Dir";
        ilk = dir_tool_classify_filename::ilk;

        fun err m
            =
            raise exception TOOL_ERROR { tool, msg => m };

        fun rule { spec, context, native2pathmaker, default_ilk_of, sysinfo }
            =
            {   spec ->  { name, make_path, tool_options => too, ... } : Spec;

                pre_d = make_path ();

                # We are making up specs for the members of the directory
                # by gluing the member name to the directory name.
                # Since the result must be valid in the directories' context,
                # we use the name of the directory relative to that context.
                #
                spec_d = native_pre_spec pre_d;

                # When no options are given, we read the physical directory
                # and get for source files...
                #
                fun no_opts ()
                    =
                    {   fun getfiles s
                            =
                            {   fun loop l
                                    =
                                    case (winix__premicrothread::file::read_directory_entry s)

                                        NULL
                                            =>
                                            reverse l;

                                        THE f
                                            =>
                                            {   df = winix__premicrothread::path::make_path_from_dir_and_file
                                                      { dir => spec_d,
                                                        file => f
                                                      };

                                                fun make_path ()
                                                    =
                                                    augment pre_d [f];

                                                dfs = { name => df, make_path };

                                                case (default_ilk_of dfs)
                                                    THE ("sml") => loop (dfs ! l);
                                                    _           => loop l;
                                                esac;
                                            };
                                    esac;
                            
                                (   loop []
                                    then
                                        winix__premicrothread::file::close_directory_stream s
                                )
                                except
                                    e = {   winix__premicrothread::file::close_directory_stream s;
                                            raise exception e;
                                        };
                            };

                        fl =  getfiles (winix__premicrothread::file::open_directory_stream spec_d);

                        fun to_spec { name, make_path }
                            =
                            {   name,
                                make_path,
                                ilk => THE "sml",
                                tool_options => NULL,
                                derived => FALSE
                            };
                    
                        ( { source_files => [],
                            makelib_files  => [],
                            sources      => []
                          },
                          map to_spec fl
                        );
                    };

                # When options are given,
                # we take precisely the
                # files specified there.
                #
                fun process_options ol
                    =
                    {   fun one_file ( { name, make_path }, co, oo)
                            =
                            {   f = native_spec (srcpath (make_path ()));
                            
                                case (winix__premicrothread::path::from_string f)
                                  
                                    {   is_absolute => FALSE,
                                        disk_volume => "",
                                        arcs
                                    }
                                        =>
                                        { name       =>  winix__premicrothread::path::cat (spec_d, f),
                                          make_path  =>  \\ () = augment pre_d arcs,
                                          #
                                          ilk          => co,
                                          tool_options => oo,
                                          # 
                                          derived => FALSE
                                        };

                                    _   =>  err ("invalid directory entry: " + f);
                                esac;
                            };

                        fun one_opt (STRING fns)
                                =>
                                one_file (fns, NULL, NULL);

                            one_opt (SUBOPTS { name => "member", tool_options } )
                                =>
                                case tool_options
                                    #                             
                                    [STRING fns]
                                        =>
                                        one_file (fns, NULL, NULL);

                                    [STRING fns, SUBOPTS { name => "ilk",
                                                           tool_options => [STRING c]
                                                         }
                                    ]
                                        =>
                                        one_file (fns, THE c.name, NULL);

                                    [STRING fns, SUBOPTS { name => "options", tool_options } ]
                                        =>
                                        one_file (fns, NULL, THE tool_options);

                                    [ STRING fns,
                                      SUBOPTS { name         =>  "ilk",
                                                tool_options =>  [STRING c]
                                              },
                                      SUBOPTS { name => "options", tool_options }
                                    ]
                                        =>
                                        one_file (fns, THE c.name, THE tool_options);

                                    _   => err "illegal member specification";
                                esac;


                            one_opt (SUBOPTS so)
                                =>
                                err ("illegal option: " + so.name);
                        end;
                    
                        ( { source_files => [],
                            makelib_files  => [],
                            sources  => []
                          },

                          map one_opt ol
                        );
                    };
            
                case too
                    #             
                    THE ol => process_options ol;
                    #
                    NULL   => # We actually open the directory and read it,
                              # so we must switch to the right context:
                              # 
                              context no_opts;
                esac;
            };
    herein
        my _ = note_ilk (ilk, rule);
    end;
};


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext