summary refs log tree commit diff
path: root/src/comp/front/creader.rs
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2011-06-09 17:24:25 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-06-09 17:24:32 -0700
commitab3635eebef2b8cf0e19cdbc5b4e8dd7a49a4658 (patch)
treeb008edfdeed1019c27b17ad5b75cb31c4e5a1489 /src/comp/front/creader.rs
parentc9c1d860f14d2d422106d21a30beb2ea237d9de3 (diff)
Encode meta tags in the crate and start sketching enhanced logic for resolving crate "use" directives.
Diffstat (limited to 'src/comp/front/creader.rs')
-rw-r--r--src/comp/front/creader.rs83
1 files changed, 67 insertions, 16 deletions
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs
index e0be9606384..d9dad04db92 100644
--- a/src/comp/front/creader.rs
+++ b/src/comp/front/creader.rs
@@ -500,24 +500,75 @@ fn get_metadata_section(str filename) -> option::t[vec[u8]] {
 }
 
 
-fn load_crate(session::session sess,
-              int cnum,
-              ast::ident ident,
-              vec[str] library_search_paths) {
-    auto filename = parser::default_native_name(sess, ident);
+fn metadata_matches(&vec[u8] data,
+                    &vec[@ast::meta_item] metas) -> bool {
+    ret true;
+}
+
+fn find_library_crate(&session::session sess,
+                      &ast::ident ident,
+                      &vec[@ast::meta_item] metas,
+                      &vec[str] library_search_paths)
+    -> option::t[tup(str, vec[u8])] {
+
+    let str crate_name = ident;
+    for (@ast::meta_item mi in metas) {
+        if (mi.node.key == "name") {
+            crate_name = mi.node.value;
+            break;
+        }
+    }
+    auto nn = parser::default_native_lib_naming(sess);
+    let str prefix = nn.prefix + crate_name;
+
+    // FIXME: we could probably use a 'glob' function in std::fs but it will
+    // be much easier to write once the unsafe module knows more about FFI
+    // tricks. Currently the glob(3) interface is a bit more than we can
+    // stomach from here, and writing a C++ wrapper is more work than just
+    // manually filtering fs::list_dir here.
+
     for (str library_search_path in library_search_paths) {
-        auto path = fs::connect(library_search_path, filename);
-        alt (get_metadata_section(path)) {
-            case (option::some(?cvec)) {
-                sess.set_external_crate(cnum, rec(name=ident, data=cvec));
-                ret;
+
+        for (str path in fs::list_dir(library_search_path)) {
+
+            let str f = fs::basename(path);
+            if (! (str::starts_with(f, prefix) &&
+                   str::ends_with(f, nn.suffix))) {
+                log #fmt("skipping %s, doesn't look like %s*%s",
+                         path, prefix, nn.suffix);
+                cont;
+            }
+
+            alt (get_metadata_section(path)) {
+                case (option::some(?cvec)) {
+                    if (!metadata_matches(cvec, metas)) {
+                        log #fmt("skipping %s, metadata doesn't match", path);
+                        cont;
+                    }
+                    log #fmt("found %s with matching metadata", path);
+                    ret some(tup(path, cvec));
+                }
+                case (_) {}
             }
-            case (_) {}
         }
     }
-
-    log_err #fmt("can't open crate '%s' (looked for '%s' in lib search path)",
-                 ident, filename);
+    ret none;
+}
+
+fn load_library_crate(&session::session sess,
+                      &int cnum,
+                      &ast::ident ident,
+                      &vec[@ast::meta_item] metas,
+                      &vec[str] library_search_paths) {
+    alt (find_library_crate(sess, ident, metas, library_search_paths)) {
+        case (some(?t)) {
+            sess.set_external_crate(cnum, rec(name=ident,
+                                              data=t._1));
+            ret;
+        }
+        case (_) {}
+    }
+    log_err #fmt("can't find crate for '%s'", ident);
     fail;
 }
 
@@ -535,8 +586,8 @@ fn visit_view_item(env e, &@ast::view_item i) {
             auto cnum;
             if (!e.crate_cache.contains_key(ident)) {
                 cnum = e.next_crate_num;
-                load_crate(e.sess, cnum, ident,
-                           e.library_search_paths);
+                load_library_crate(e.sess, cnum, ident, meta_items,
+                                   e.library_search_paths);
                 e.crate_cache.insert(ident, e.next_crate_num);
                 e.next_crate_num += 1;
             } else {