3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-10-10 09:48:06 +00:00

Handle quoted arguments in passes

Use `std::quoted()` from `<iomanip>` to quote/unquote pass arguments.
In order to maintain handling of (unquoted) comments and semicolons this occurs when adding the token to the arg list, rather than in the tokenization itself.
Passes no longer receive tokenized-but-raw arguments and are instead pre-unquoted.
This will cause problems for some passes (e.g. `setparam`) which rely on arguments having quotation marks for disambiguation.
In order to maintain reproducibility with `echo on`, arguments which require quoting will automatically quote (arguments which were quoted but didn't need to be will not be quoted in the echo).
This commit is contained in:
Krystine Sherwin 2025-09-24 14:20:12 +12:00
parent 0a88c159c1
commit 0ab1d6d28c
No known key found for this signature in database
3 changed files with 28 additions and 4 deletions

View file

@ -2,6 +2,7 @@
#include "kernel/log.h" #include "kernel/log.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <iomanip>
#if !defined(WIN32) #if !defined(WIN32)
#include <dirent.h> #include <dirent.h>
@ -592,4 +593,21 @@ void format_emit_void_ptr(std::string &result, std::string_view spec, int *dynam
format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg); format_emit_stringf(result, spec, dynamic_ints, num_dynamic_ints, arg);
} }
bool needs_quote(const std::string &s) {
return (s.find(' ') != std::string::npos) || (s.find('\\') != std::string::npos);
}
std::string quote(const std::string &s) {
std::ostringstream ss;
ss << std::quoted(s);
return ss.str();
}
std::string unquote(const std::string &s) {
std::string result;
std::istringstream ss(s);
ss >> std::quoted(result);
return result;
}
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END

View file

@ -470,6 +470,10 @@ void remove_directory(std::string dirname);
bool create_directory(const std::string& dirname); bool create_directory(const std::string& dirname);
std::string escape_filename_spaces(const std::string& filename); std::string escape_filename_spaces(const std::string& filename);
bool needs_quote(const std::string &s);
std::string quote(const std::string &s);
std::string unquote(const std::string &s);
YOSYS_NAMESPACE_END YOSYS_NAMESPACE_END
#endif // YOSYS_IO_H #endif // YOSYS_IO_H

View file

@ -222,7 +222,7 @@ void Pass::call(RTLIL::Design *design, std::string command)
while (!tok.empty() && tok.back() == ';') while (!tok.empty() && tok.back() == ';')
tok.resize(tok.size()-1), num_semikolon++; tok.resize(tok.size()-1), num_semikolon++;
if (!tok.empty()) if (!tok.empty())
args.push_back(tok); args.push_back(unquote(tok));
call(design, args); call(design, args);
args.clear(); args.clear();
if (num_semikolon == 2) if (num_semikolon == 2)
@ -230,7 +230,7 @@ void Pass::call(RTLIL::Design *design, std::string command)
if (num_semikolon == 3) if (num_semikolon == 3)
call(design, "clean -purge"); call(design, "clean -purge");
} else } else
args.push_back(tok); args.push_back(unquote(tok));
bool found_nl = false; bool found_nl = false;
for (auto c : cmd_buf) { for (auto c : cmd_buf) {
if (c == ' ' || c == '\t') if (c == ' ' || c == '\t')
@ -256,8 +256,10 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args)
if (echo_mode) { if (echo_mode) {
log("%s", create_prompt(design, 0)); log("%s", create_prompt(design, 0));
for (size_t i = 0; i < args.size(); i++) for (size_t i = 0; i < args.size(); i++) {
log("%s%s", i ? " " : "", args[i]); auto maybe_quoted = needs_quote(args[i]) ? quote(args[i]) : args[i];
log("%s%s", i ? " " : "", maybe_quoted);
}
log("\n"); log("\n");
} }