# 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.libpackage 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;
};