aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/rust-session-manager.cc
diff options
context:
space:
mode:
authorliushuyu <liushuyu011@gmail.com>2022-04-07 04:40:14 -0600
committerliushuyu <liushuyu011@gmail.com>2022-04-12 18:37:09 -0600
commit1a7391d97ffef5efb797f3701a82577c7270ce66 (patch)
tree28aadfa16376730558896c624c7301b3b2a14529 /gcc/rust/rust-session-manager.cc
parent28769ea0ab894248005db31dd6a8553df83e4907 (diff)
downloadgcc-1a7391d97ffef5efb797f3701a82577c7270ce66.zip
gcc-1a7391d97ffef5efb797f3701a82577c7270ce66.tar.gz
gcc-1a7391d97ffef5efb797f3701a82577c7270ce66.tar.bz2
rust-session-manager: address comments ...
... also more closely match rustc's behavior Signed-off-by: Zixing Liu <liushuyu011@gmail.com>
Diffstat (limited to 'gcc/rust/rust-session-manager.cc')
-rw-r--r--gcc/rust/rust-session-manager.cc87
1 files changed, 78 insertions, 9 deletions
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