From b7af214b0bc52080199c31d81abce37e6fd5a4ca Mon Sep 17 00:00:00 2001 From: Roland Coeurjoly Date: Fri, 30 Aug 2024 19:12:30 +0200 Subject: [PATCH] Add relative path resolution support for script I/O operations --- kernel/yosys.cc | 26 +++++++++++++++++-- tests/various/script_relative_path.ys | 1 + .../script_relative_path_files/.gitignore | 1 + .../script_relative_path_files/design.v | 3 +++ .../relative_path_read_write_operations.ys | 16 ++++++++++++ 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 tests/various/script_relative_path.ys create mode 100644 tests/various/script_relative_path_files/.gitignore create mode 100644 tests/various/script_relative_path_files/design.v create mode 100644 tests/various/script_relative_path_files/relative_path_read_write_operations.ys diff --git a/kernel/yosys.cc b/kernel/yosys.cc index efdc54b796c..db8cda6b487 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -74,7 +74,9 @@ #include #include "libs/json11/json11.hpp" - +#if !defined(__wasm) +#include +#endif YOSYS_NAMESPACE_BEGIN int autoidx = 1; @@ -712,6 +714,20 @@ void rewrite_filename(std::string &filename) if (filename.compare(0, 2, "~/") == 0) filename = filename.replace(0, 1, getenv("HOME")); #endif +#if !defined(__wasm) + if (yosys_get_design()->scratchpad_get_bool("script.relative_path_resolution_enabled")) { + std::filesystem::path file_path(filename); + if (file_path.is_relative()) { + const std::string script_dir = yosys_get_design()->scratchpad_get_string("script.dir", ""); + if (!script_dir.empty()) { + std::filesystem::path script_dir_path(script_dir); + // Use std::filesystem::path operator/= for portable path concatenation + file_path = script_dir_path / file_path; + filename = file_path.string(); + } + } + } +#endif } #ifdef YOSYS_ENABLE_TCL @@ -1193,7 +1209,13 @@ bool run_frontend(std::string filename, std::string command, RTLIL::Design *desi FILE *backup_script_file = Frontend::current_script_file; Frontend::current_script_file = f; - +#if !defined(__wasm) + const std::filesystem::path input_file_path(filename); + const std::filesystem::path script_dir = input_file_path.parent_path(); + if (!script_dir.string().empty()) { + yosys_get_design()->scratchpad_set_string("script.dir", script_dir.string()); + } +#endif try { std::string command; while (fgetline(f, command)) { diff --git a/tests/various/script_relative_path.ys b/tests/various/script_relative_path.ys new file mode 100644 index 00000000000..78f2175abc2 --- /dev/null +++ b/tests/various/script_relative_path.ys @@ -0,0 +1 @@ +script script_relative_path_files/relative_path_read_write_operations.ys \ No newline at end of file diff --git a/tests/various/script_relative_path_files/.gitignore b/tests/various/script_relative_path_files/.gitignore new file mode 100644 index 00000000000..1969f8d71a8 --- /dev/null +++ b/tests/various/script_relative_path_files/.gitignore @@ -0,0 +1 @@ +/*.il \ No newline at end of file diff --git a/tests/various/script_relative_path_files/design.v b/tests/various/script_relative_path_files/design.v new file mode 100644 index 00000000000..4629b501175 --- /dev/null +++ b/tests/various/script_relative_path_files/design.v @@ -0,0 +1,3 @@ +module top(input a, b, output o); +assign o = a & b; +endmodule diff --git a/tests/various/script_relative_path_files/relative_path_read_write_operations.ys b/tests/various/script_relative_path_files/relative_path_read_write_operations.ys new file mode 100644 index 00000000000..cfcbef322a9 --- /dev/null +++ b/tests/various/script_relative_path_files/relative_path_read_write_operations.ys @@ -0,0 +1,16 @@ +scratchpad -set script.relative_path_resolution_enabled 1 +read_verilog design.v +design -reset + +read_verilog ./design.v +design -reset + +read_verilog ../script_relative_path_files/design.v +write_rtlil design.il +design -reset +read_rtlil design.il +design -reset + +scratchpad -set script.relative_path_resolution_enabled 0 +logger -expect error "Can't open input file `design.v' for reading: No such file or directory" 1 +read_verilog design.v \ No newline at end of file