about summary refs log tree commit diff
path: root/src/comp/front
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
parentc9c1d860f14d2d422106d21a30beb2ea237d9de3 (diff)
Encode meta tags in the crate and start sketching enhanced logic for resolving crate "use" directives.
Diffstat (limited to 'src/comp/front')
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/creader.rs83
-rw-r--r--src/comp/front/parser.rs16
3 files changed, 79 insertions, 22 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index b36a956464c..fd0fd7f0193 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -97,7 +97,7 @@ type crate_directive = spanned[crate_directive_];
 
 
 type meta_item = spanned[meta_item_];
-type meta_item_ = rec(ident name, str value);
+type meta_item_ = rec(ident key, str value);
 
 type block = spanned[block_];
 type block_ = rec(vec[@stmt] stmts,
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 {
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index d3a8fa9a329..666df9d8eb3 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -1992,20 +1992,26 @@ fn parse_native_mod_items(&parser p, &str native_name,
             items=items);
 }
 
-fn default_native_name(session::session sess, str id) -> str {
+fn default_native_lib_naming(session::session sess)
+    -> rec(str prefix, str suffix) {
     alt (sess.get_targ_cfg().os) {
         case (session::os_win32) {
-            ret id + ".dll";
+            ret rec(prefix="", suffix=".dll");
         }
         case (session::os_macos) {
-            ret "lib" + id + ".dylib";
+            ret rec(prefix="lib", suffix=".dylib");
         }
         case (session::os_linux) {
-            ret "lib" + id + ".so";
+            ret rec(prefix="lib", suffix=".so");
         }
     }
 }
 
+fn default_native_name(session::session sess, str id) -> str {
+    auto n = default_native_lib_naming(sess);
+    ret n.prefix + id + n.suffix;
+}
+
 fn parse_item_native_mod(&parser p) -> @ast::item {
     auto lo = p.get_last_lo_pos();
     auto abi = ast::native_abi_cdecl;
@@ -2194,7 +2200,7 @@ fn parse_meta_item(&parser p) -> @ast::meta_item {
         case (token::LIT_STR(?s)) {
             auto hi = p.get_hi_pos();
             p.bump();
-            ret @spanned(lo, hi, rec(name = ident,
+            ret @spanned(lo, hi, rec(key = ident,
                                      value = p.get_str(s)));
         }
         case (_) {