diff options
-rw-r--r-- | gcc/rust/rust-lang.cc | 1 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 87 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.h | 41 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/bad=file-name.rs | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/bad_file_name.txt.rs (renamed from gcc/testsuite/rust/compile/bad-file-name.txt.rs) | 0 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/specify-crate-name.rs | 2 |
6 files changed, 89 insertions, 44 deletions
diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc index c746941..4584c93 100644 --- a/gcc/rust/rust-lang.cc +++ b/gcc/rust/rust-lang.cc @@ -458,6 +458,7 @@ run_rust_tests () simple_assert (); rust_cfg_parser_test (); rust_privacy_ctx_test (); + rust_crate_name_validation_test (); } } // namespace selftest diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 1a6afd7..15a02f81 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -35,6 +35,7 @@ #include "diagnostic.h" #include "input.h" #include "rust-target.h" +#include "selftest.h" extern bool saw_errors (void); @@ -55,9 +56,10 @@ const char *kHIRTypeResolutionDumpFile = "gccrs.type-resolution.dump"; const char *kTargetOptionsDumpFile = "gccrs.target-options.dump"; const std::string kDefaultCrateName = "rust_out"; +const size_t kMaxNameLength = 64; static std::string -infer_crate_name (const std::string filename) +infer_crate_name (const std::string &filename) { if (filename == "-") return kDefaultCrateName; @@ -74,9 +76,42 @@ infer_crate_name (const std::string filename) if (ext_position != std::string::npos) crate.erase (ext_position); + // Replace all the '-' symbols with '_' per Rust rules + for (auto &c : crate) + { + if (c == '-') + c = '_'; + } return crate; } +bool +CompileOptions::validate_crate_name (const std::string &crate_name) +{ + if (crate_name.empty ()) + { + rust_error_at (Location (), "crate name cannot be empty"); + return false; + } + if (crate_name.length () > kMaxNameLength) + { + rust_error_at (Location (), "crate name cannot exceed %ld characters", + kMaxNameLength); + return false; + } + for (auto &c : crate_name) + { + if (!(ISALNUM (c) || c == '_')) + { + rust_error_at (Location (), + "invalid character %<%c%> in crate name: %<%s%>", c, + crate_name.c_str ()); + return false; + } + } + return true; +} + // Implicitly enable a target_feature (and recursively enable dependencies). void Session::implicitly_enable_feature (std::string feature_name) @@ -496,21 +531,25 @@ Session::enable_dump (std::string arg) void Session::parse_files (int num_files, const char **files) { - rust_assert (num_files > 0); - if (options.crate_name.empty ()) { /* HACK: We use the first file to infer the crate name, which might be * incorrect: since rustc only allows one file to be supplied in the * command-line */ - auto crate_name = infer_crate_name (files[0]); - rust_debug_loc (Location (), "inferred crate name: %s", - crate_name.c_str ()); + auto filename = "-"; + if (num_files > 0) + filename = files[0]; + + auto crate_name = infer_crate_name (filename); + rust_debug ("inferred crate name: %s", crate_name.c_str ()); if (!options.set_crate_name (crate_name)) { - rust_inform (Location (), - "crate name inferred from the input file %<%s%>", - files[0]); + // fake a linemapping so that we can show the filename + linemap->start_file (filename, 0); + linemap->start_line (0, 1); + rust_inform (linemap->get_location (0), + "crate name inferred from this file"); + linemap->stop (); return; } } @@ -1157,3 +1196,33 @@ TargetOptions::enable_implicit_feature_reqs (std::string feature) * - code generation * - link */ } // namespace Rust + +#if CHECKING_P +namespace selftest { +void +rust_crate_name_validation_test (void) +{ + ASSERT_TRUE (Rust::CompileOptions::validate_crate_name ("example")); + ASSERT_TRUE (Rust::CompileOptions::validate_crate_name ("abcdefg_1234")); + ASSERT_TRUE (Rust::CompileOptions::validate_crate_name ("1")); + // FIXME: The next test does not pass as of current implementation + // ASSERT_TRUE (Rust::CompileOptions::validate_crate_name ("惊吓")); + // NOTE: - is not allowed in the crate name ... + /* + ASSERT_FALSE (Rust::CompileOptions::validate_crate_name ("abcdefg-1234")); + ASSERT_FALSE (Rust::CompileOptions::validate_crate_name ("a+b")); + ASSERT_FALSE (Rust::CompileOptions::validate_crate_name ("/a+b/")); */ + + /* Tests for crate name inference */ + ASSERT_EQ (Rust::infer_crate_name ("c.rs"), "c"); + // NOTE: ... but - is allowed when in the filename + ASSERT_EQ (Rust::infer_crate_name ("a-b.rs"), "a_b"); + ASSERT_EQ (Rust::infer_crate_name ("book.rs.txt"), "book.rs"); +#if defined(HAVE_DOS_BASED_FILE_SYSTEM) + ASSERT_EQ (Rust::infer_crate_name ("a\\c\\a-b.rs"), "a_b"); +#else + ASSERT_EQ (Rust::infer_crate_name ("a/c/a-b.rs"), "a_b"); +#endif +} +} // namespace selftest +#endif // CHECKING_P diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h index 75a017e..2b20486 100644 --- a/gcc/rust/rust-session-manager.h +++ b/gcc/rust/rust-session-manager.h @@ -42,8 +42,6 @@ namespace HIR { struct Crate; } -const size_t kMaxNameLength = 64; - /* Data related to target, most useful for conditional compilation and * whatever. */ struct TargetOptions @@ -217,43 +215,13 @@ struct CompileOptions /* Validate the crate name using the ASCII rules TODO: Support Unicode version of the rules */ - bool validate_crate_name (const std::string &crate_name) - { - if (crate_name.empty ()) - { - rust_error_at (Location (), "crate name cannot be empty"); - return false; - } - if (crate_name.length () > kMaxNameLength) - { - rust_error_at (Location (), "crate name cannot exceed %ld characters", - kMaxNameLength); - return false; - } - for (auto &c : crate_name) - { - if (!(ISALNUM (c) || c == '_' || c == '-')) - { - rust_error_at (Location (), - "invalid character %<%c%> in crate name: %<%s%>", c, - crate_name.c_str ()); - return false; - } - } - return true; - } + static bool validate_crate_name (const std::string &crate_name); bool set_crate_name (std::string name) { if (!validate_crate_name (name)) return false; - /* Replace all the '-' symbols with '_' per Rust rules */ - for (auto &c : name) - { - if (c == '-') - c = '_'; - } crate_name = std::move (name); return true; } @@ -343,4 +311,11 @@ private: }; } // namespace Rust +#if CHECKING_P +namespace selftest { +extern void +rust_crate_name_validation_test (void); +} +#endif // CHECKING_P + #endif diff --git a/gcc/testsuite/rust/compile/bad=file-name.rs b/gcc/testsuite/rust/compile/bad=file-name.rs index 12b54e1..cfbebb0 100644 --- a/gcc/testsuite/rust/compile/bad=file-name.rs +++ b/gcc/testsuite/rust/compile/bad=file-name.rs @@ -1,4 +1,4 @@ -// { dg-additional-options "-fdump-tree-gimple -frust-crate=good-name" } +// { dg-additional-options "-fdump-tree-gimple -frust-crate=good_name" } pub fn does_nothing() {} fn main() { does_nothing() diff --git a/gcc/testsuite/rust/compile/bad-file-name.txt.rs b/gcc/testsuite/rust/compile/bad_file_name.txt.rs index 56e2093..56e2093 100644 --- a/gcc/testsuite/rust/compile/bad-file-name.txt.rs +++ b/gcc/testsuite/rust/compile/bad_file_name.txt.rs diff --git a/gcc/testsuite/rust/compile/specify-crate-name.rs b/gcc/testsuite/rust/compile/specify-crate-name.rs index 5f437b4..a867915 100644 --- a/gcc/testsuite/rust/compile/specify-crate-name.rs +++ b/gcc/testsuite/rust/compile/specify-crate-name.rs @@ -1,4 +1,4 @@ -// { dg-additional-options "-frust-crate=fancy-crate_name -fdump-tree-gimple" } +// { dg-additional-options "-frust-crate=fancy_crate_name -fdump-tree-gimple" } pub fn does_nothing() {} fn main() { does_nothing() |