summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-05-05 21:56:49 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-05-05 21:56:49 +0800
commit203862df03f8ee9f49ab704063bd28523f13ba2d (patch)
tree2f25954cde3e90625ea979d9bfe2c9b049e8024f /src
parent7a5cd835703fdfac0634b975392f915e0230c2a7 (diff)
downloadmrust-203862df03f8ee9f49ab704063bd28523f13ba2d.tar.gz
LoadCrates - Search for crates with matching names (instead of needing a perfect filename match)
Diffstat (limited to 'src')
-rw-r--r--src/ast/crate.cpp64
1 files changed, 50 insertions, 14 deletions
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp
index 69db669e..5717cbdb 100644
--- a/src/ast/crate.cpp
+++ b/src/ast/crate.cpp
@@ -12,6 +12,7 @@
#include <hir/hir.hpp> // HIR::Crate
#include <hir/main_bindings.hpp> // HIR_Deserialise
#include <fstream>
+#include <dirent.h>
::std::vector<::std::string> AST::g_crate_load_dirs = { };
::std::map<::std::string, ::std::string> AST::g_crate_overrides;
@@ -121,31 +122,66 @@ void Crate::load_externs()
ERROR(sp, E0000, "Unable to open crate '" << name << "' at path " << path);
}
}
- else
+ else if( basename != "" )
{
// Search a list of load paths for the crate
for(const auto& p : g_crate_load_dirs)
{
- if( basename == "" )
- {
- path = p + "/lib" + name + ".hir";
- // TODO: Search for `p+"/lib"+name+"-*.hir" (which would match e.g. libnum-0.11.hir)
- }
- else
- {
- path = p + "/" + basename;
- }
+ path = p + "/" + basename;
if( ::std::ifstream(path).good() ) {
break ;
}
}
if( !::std::ifstream(path).good() ) {
- if( basename.empty() )
- ERROR(sp, E0000, "Unable to locate crate '" << name << "' in search directories");
- else
- ERROR(sp, E0000, "Unable to locate crate '" << name << "' with filename " << basename << " in search directories");
+ ERROR(sp, E0000, "Unable to locate crate '" << name << "' with filename " << basename << " in search directories");
+ }
+ }
+ else
+ {
+ ::std::vector<::std::string> paths;
+ auto name_prefix = "lib"+name+"-";
+ // Search a list of load paths for the crate
+ for(const auto& p : g_crate_load_dirs)
+ {
+
+ path = p + "/lib" + name + ".hir";
+ // TODO: Search for `p+"/lib"+name+"-*.hir" (which would match e.g. libnum-0.11.hir)
+ if( ::std::ifstream(path).good() ) {
+ paths.push_back(path);
+ }
+ path = "";
+
+ auto dp = opendir(p.c_str());
+ if( !dp ) {
+ continue ;
+ }
+ struct dirent *ent;
+ while( (ent = readdir(dp)) != nullptr && path == "" )
+ {
+ // AND the start is "lib"+name
+ size_t len = strlen(ent->d_name);
+ if( len <= 4 || strcmp(ent->d_name + len - 4, ".hir") != 0 )
+ continue ;
+
+ DEBUG(ent->d_name << " vs " << name_prefix);
+ // Check if the entry ends with .hir
+ if( strncmp(name_prefix.c_str(), ent->d_name, name_prefix.size()) != 0 )
+ continue ;
+
+ paths.push_back( p + "/" + ent->d_name );
+ }
+ closedir(dp);
+ if( paths.size() > 0 )
+ break;
+ }
+ if( paths.size() > 1 ) {
+ ERROR(sp, E0000, "Multiple options for crate '" << name << "' in search directories - " << paths);
+ }
+ if( paths.size() == 0 || !::std::ifstream(paths.front()).good() ) {
+ ERROR(sp, E0000, "Unable to locate crate '" << name << "' in search directories");
}
+ path = paths.front();
}
// NOTE: Creating `ExternCrate` loads the crate from the specified path