fix(frontends/lean/dependencies): take relative paths into account when computing dependencies

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-08-02 20:03:51 -07:00
parent 4b030c5d5f
commit bae9700260
3 changed files with 31 additions and 8 deletions

View file

@ -14,11 +14,15 @@ Author: Leonardo de Moura
namespace lean { namespace lean {
void display_deps(environment const & env, std::ostream & out, char const * fname) { void display_deps(environment const & env, std::ostream & out, char const * fname) {
name import("import"); name import("import");
name period(".");
std::ifstream in(fname); std::ifstream in(fname);
if (in.bad() || in.fail()) if (in.bad() || in.fail())
throw exception(sstream() << "failed to open file '" << fname << "'"); throw exception(sstream() << "failed to open file '" << fname << "'");
scanner s(in, fname); scanner s(in, fname);
bool import_args = false; optional<unsigned> k;
std::string base = dirname(fname);
bool import_prefix = false;
bool import_args = false;
while (true) { while (true) {
scanner::token_kind t = scanner::token_kind::Identifier; scanner::token_kind t = scanner::token_kind::Identifier;
try { try {
@ -29,18 +33,28 @@ void display_deps(environment const & env, std::ostream & out, char const * fnam
if (t == scanner::token_kind::Eof) { if (t == scanner::token_kind::Eof) {
return; return;
} else if (t == scanner::token_kind::CommandKeyword && s.get_token_info().value() == import) { } else if (t == scanner::token_kind::CommandKeyword && s.get_token_info().value() == import) {
k = optional<unsigned>();
import_prefix = true;
} else if (import_prefix && t == scanner::token_kind::Keyword && s.get_token_info().value() == period) {
if (!k)
k = 0;
else
k = *k + 1;
} else if ((import_prefix || import_args) && t == scanner::token_kind::Identifier) {
import_args = true; import_args = true;
} else if (import_args == true && t == scanner::token_kind::Identifier) { std::string m_name = find_file(base, k, name_to_file(s.get_name_val()), {".lean", ".olean", ".lua"});
std::string m_name = find_file(name_to_file(s.get_name_val()), {".lean", ".olean", ".lua"});
int last_idx = m_name.find_last_of("."); int last_idx = m_name.find_last_of(".");
std::string rawname = m_name.substr(0, last_idx); std::string rawname = m_name.substr(0, last_idx);
std::string ext = m_name.substr(last_idx); std::string ext = m_name.substr(last_idx);
if (ext == ".lean") if (ext == ".lean")
m_name = rawname + ".olean"; m_name = rawname + ".olean";
display_path(out, m_name); display_path(out, m_name);
k = optional<unsigned>();
import_prefix = true;
out << "\n"; out << "\n";
} else { } else {
import_args = false; import_args = false;
import_prefix = false;
} }
} }
} }

View file

@ -245,21 +245,28 @@ std::string find_file(std::string fname, std::initializer_list<char const *> con
throw exception(sstream() << "file '" << fname << "' not found in the LEAN_PATH"); throw exception(sstream() << "file '" << fname << "' not found in the LEAN_PATH");
} }
std::string find_file(std::string const & base, optional<unsigned> const & rel, name const & fname, char const * ext) { std::string find_file(std::string const & base, optional<unsigned> const & rel, name const & fname,
std::initializer_list<char const *> const & extensions) {
if (!rel) { if (!rel) {
return find_file(fname.to_string(g_sep_str.c_str()), {ext}); return find_file(fname.to_string(g_sep_str.c_str()), extensions);
} else { } else {
auto path = base; auto path = base;
for (unsigned i = 0; i < *rel; i++) { for (unsigned i = 0; i < *rel; i++) {
path += g_sep; path += g_sep;
path += ".."; path += "..";
} }
if (auto r = check_file(path, fname.to_string(g_sep_str.c_str()), ext)) for (auto ext : extensions) {
return *r; if (auto r = check_file(path, fname.to_string(g_sep_str.c_str()), ext))
return *r;
}
throw exception(sstream() << "file '" << fname << "' not found at '" << path << "'"); throw exception(sstream() << "file '" << fname << "' not found at '" << path << "'");
} }
} }
std::string find_file(std::string const & base, optional<unsigned> const & k, name const & fname, char const * ext) {
return find_file(base, k, fname, {ext});
}
std::string find_file(std::string fname) { std::string find_file(std::string fname) {
return find_file(fname, {".olean", ".lean", ".lua"}); return find_file(fname, {".olean", ".lean", ".lua"});
} }

View file

@ -24,6 +24,8 @@ std::string find_file(name const & fname);
std::string find_file(name const & fname, std::initializer_list<char const *> const & exts); std::string find_file(name const & fname, std::initializer_list<char const *> const & exts);
/** \brief \brief Similar to previous find_file, but if k is not none then search at the k-th parent of base. */ /** \brief \brief Similar to previous find_file, but if k is not none then search at the k-th parent of base. */
std::string find_file(std::string const & base, optional<unsigned> const & rel, name const & fname,
std::initializer_list<char const *> const & extensions);
std::string find_file(std::string const & base, optional<unsigned> const & k, name const & fname, char const * ext); std::string find_file(std::string const & base, optional<unsigned> const & k, name const & fname, char const * ext);
/** \brief Return true iff fname ends with ".lean" */ /** \brief Return true iff fname ends with ".lean" */