diff options
| author | Graydon Hoare <graydon@mozilla.com> | 2011-06-09 17:24:25 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2011-06-09 17:24:32 -0700 |
| commit | ab3635eebef2b8cf0e19cdbc5b4e8dd7a49a4658 (patch) | |
| tree | b008edfdeed1019c27b17ad5b75cb31c4e5a1489 /src/comp/front | |
| parent | c9c1d860f14d2d422106d21a30beb2ea237d9de3 (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.rs | 2 | ||||
| -rw-r--r-- | src/comp/front/creader.rs | 83 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 16 |
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 (_) { |
