Skip to content

Commit f50e9a2

Browse files
committed
rust-session-manager: set and validate crate name properly ...
... should fix #789 Signed-off-by: Zixing Liu <[email protected]>
1 parent e9ab95c commit f50e9a2

File tree

2 files changed

+80
-6
lines changed

2 files changed

+80
-6
lines changed

gcc/rust/rust-session-manager.cc

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,28 @@ const char *kHIRDumpFile = "gccrs.hir.dump";
5454
const char *kHIRTypeResolutionDumpFile = "gccrs.type-resolution.dump";
5555
const char *kTargetOptionsDumpFile = "gccrs.target-options.dump";
5656

57-
const std::string kDefaultCrateName = "example";
57+
const std::string kDefaultCrateName = "rust_out";
58+
59+
static std::string
60+
infer_crate_name (const std::string filename)
61+
{
62+
if (filename == "-")
63+
return kDefaultCrateName;
64+
65+
std::string crate = std::string (filename);
66+
size_t path_sep = crate.find_last_of (file_separator);
67+
68+
// find the base filename
69+
if (path_sep != std::string::npos)
70+
crate.erase (0, path_sep + 1);
71+
72+
// find the file stem name (remove file extension)
73+
size_t ext_position = crate.find_last_of ('.');
74+
if (ext_position != std::string::npos)
75+
crate.erase (ext_position);
76+
77+
return crate;
78+
}
5879

5980
// Implicitly enable a target_feature (and recursively enable dependencies).
6081
void
@@ -311,10 +332,6 @@ Session::init ()
311332

312333
// setup backend to GCC GIMPLE
313334
backend = rust_get_backend ();
314-
315-
// set the default crate name if crate name was unset
316-
if (options.crate_name.empty ())
317-
options.set_crate_name (kDefaultCrateName);
318335
}
319336

320337
/* Initialise default options. Actually called before handle_option, unlike init
@@ -479,6 +496,25 @@ Session::enable_dump (std::string arg)
479496
void
480497
Session::parse_files (int num_files, const char **files)
481498
{
499+
rust_assert (num_files > 0);
500+
501+
if (options.crate_name.empty ())
502+
{
503+
/* HACK: We use the first file to infer the crate name, which might be
504+
* incorrect: since rustc only allows one file to be supplied in the
505+
* command-line */
506+
auto crate_name = infer_crate_name (files[0]);
507+
rust_debug_loc (Location (), "inferred crate name: %s",
508+
crate_name.c_str ());
509+
if (!options.set_crate_name (crate_name))
510+
{
511+
rust_inform (Location (),
512+
"crate name inferred from the input file %<%s%>",
513+
files[0]);
514+
return;
515+
}
516+
}
517+
482518
auto mappings = Analysis::Mappings::get ();
483519
CrateNum crate_num = mappings->setup_crate_mappings (options.crate_name);
484520
mappings->set_current_crate (crate_num);

gcc/rust/rust-session-manager.h

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ namespace HIR {
4141
struct Crate;
4242
}
4343

44+
const size_t kMaxNameLength = 64;
45+
4446
/* Data related to target, most useful for conditional compilation and
4547
* whatever. */
4648
struct TargetOptions
@@ -212,9 +214,45 @@ struct CompileOptions
212214
enable_dump_option (DumpOption::TYPE_RESOLUTION_DUMP);
213215
}
214216

217+
/* Validate the crate name using the ASCII rules
218+
TODO: Support Unicode version of the rules */
219+
bool validate_crate_name (const std::string &crate_name)
220+
{
221+
if (crate_name.empty ())
222+
{
223+
rust_error_at (Location (), "crate name cannot be empty");
224+
return false;
225+
}
226+
if (crate_name.length () > kMaxNameLength)
227+
{
228+
rust_error_at (Location (), "crate name cannot exceed %ld characters",
229+
kMaxNameLength);
230+
return false;
231+
}
232+
for (auto &c : crate_name)
233+
{
234+
if (!(ISALNUM (c) || c == '_' || c == '-'))
235+
{
236+
rust_error_at (Location (),
237+
"invalid character %<%c%> in crate name: %<%s%>", c,
238+
crate_name.c_str ());
239+
return false;
240+
}
241+
}
242+
return true;
243+
}
244+
215245
bool set_crate_name (std::string name)
216246
{
217-
// TODO: validate the crate name?
247+
if (!validate_crate_name (name))
248+
return false;
249+
250+
/* Replace all the '-' symbols with '_' per Rust rules */
251+
for (auto &c : name)
252+
{
253+
if (c == '-')
254+
c = '_';
255+
}
218256
crate_name = std::move (name);
219257
return true;
220258
}

0 commit comments

Comments
 (0)