From 776672576d271fc0581d4bcd933f87fee9e7b537 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Fri, 19 Apr 2024 14:05:01 -0700 Subject: [PATCH 1/2] Verilog: KNOWNBUG test for file in subdirectory with local include This adds a KNOWNBUG test for the case where a Verilog file is in a subdirectory and a local include is in the same subdirectory. --- regression/verilog/preprocessor/in_subdir.desc | 7 +++++++ regression/verilog/preprocessor/subdir/in_subdir.v | 1 + 2 files changed, 8 insertions(+) create mode 100644 regression/verilog/preprocessor/in_subdir.desc create mode 100644 regression/verilog/preprocessor/subdir/in_subdir.v diff --git a/regression/verilog/preprocessor/in_subdir.desc b/regression/verilog/preprocessor/in_subdir.desc new file mode 100644 index 000000000..79c0404fb --- /dev/null +++ b/regression/verilog/preprocessor/in_subdir.desc @@ -0,0 +1,7 @@ +KNOWNBUG +subdir/in_subdir.v +--preprocess +^EXIT=0$ +^SIGNAL=0$ +-- +include file in subdirectory not found diff --git a/regression/verilog/preprocessor/subdir/in_subdir.v b/regression/verilog/preprocessor/subdir/in_subdir.v new file mode 100644 index 000000000..4168cc1fc --- /dev/null +++ b/regression/verilog/preprocessor/subdir/in_subdir.v @@ -0,0 +1 @@ +`include "include_file.vh" From 85fa857768e572698521ed9d386e2e54de4095e4 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Fri, 19 Apr 2024 14:30:31 -0700 Subject: [PATCH 2/2] Verilog: fix includes of files in same subdirectory This fixes the case where a Verilog file is in a subdirectory and a local include is in the same subdirectory. --- .../verilog/preprocessor/in_subdir.desc | 4 +-- regression/verilog/preprocessor/include2.desc | 2 +- src/verilog/verilog_preprocessor.cpp | 29 +++++++++++-------- src/verilog/verilog_preprocessor.h | 6 ++-- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/regression/verilog/preprocessor/in_subdir.desc b/regression/verilog/preprocessor/in_subdir.desc index 79c0404fb..998d4c477 100644 --- a/regression/verilog/preprocessor/in_subdir.desc +++ b/regression/verilog/preprocessor/in_subdir.desc @@ -1,7 +1,7 @@ -KNOWNBUG +CORE subdir/in_subdir.v --preprocess +`line 1 "subdir/include_file\.vh" 1 ^EXIT=0$ ^SIGNAL=0$ -- -include file in subdirectory not found diff --git a/regression/verilog/preprocessor/include2.desc b/regression/verilog/preprocessor/include2.desc index e4dbd15bd..7f16878c3 100644 --- a/regression/verilog/preprocessor/include2.desc +++ b/regression/verilog/preprocessor/include2.desc @@ -4,7 +4,7 @@ include2.v // Enable multi-line checking activate-multi-line-match `line 1 "include2\.v" 0 -`line 1 "include_file\.vh" 1 +`line 1 "subdir/include_file\.vh" 1 `line 2 "include2\.v" 2 ^EXIT=0$ diff --git a/src/verilog/verilog_preprocessor.cpp b/src/verilog/verilog_preprocessor.cpp index 503022e9b..22f3e198b 100644 --- a/src/verilog/verilog_preprocessor.cpp +++ b/src/verilog/verilog_preprocessor.cpp @@ -99,26 +99,30 @@ Function: verilog_preprocessort::include \*******************************************************************/ std::string verilog_preprocessort::find_include_file( - const std::string &filename, + const std::string &including_file, + const std::string &given_filename, bool include_paths_only) { if(!include_paths_only) { - // first try filename as is - if(std::filesystem::directory_entry(filename).exists()) - return filename; // done + // First try given filename relative to the path of the + // including file. + auto path = std::filesystem::path(including_file); + path.replace_filename(given_filename); + if(std::filesystem::directory_entry(path).exists()) + return path; // done } - // try include paths in given order + // Then try include paths in given order. for(const auto &path : config.verilog.include_paths) { - auto full_name = std::filesystem::path(path).append(filename); + auto full_name = std::filesystem::path(path).append(given_filename); if(std::filesystem::directory_entry(full_name).exists()) return full_name; // done } throw verilog_preprocessor_errort() - << "include file `" << filename << "' not found"; + << "include file `" << given_filename << "' not found"; } /*******************************************************************\ @@ -507,7 +511,7 @@ void verilog_preprocessort::directive() // We expect one of: // -- include paths only // "filename" -- relative path, then include paths. - std::string filename; + std::string given_filename; bool include_paths_only; if(tokenizer().peek().is_string_literal()) @@ -516,7 +520,7 @@ void verilog_preprocessort::directive() const auto file_token = tokenizer().next_token(); CHECK_RETURN(file_token.is_string_literal()); // strip quotes off string literal, escaping, etc. - filename = file_token.string_literal_value(); + given_filename = file_token.string_literal_value(); } else if(tokenizer().peek() == '<') { @@ -528,7 +532,7 @@ void verilog_preprocessort::directive() if(tokenizer().peek().is_eof()) throw verilog_preprocessor_errort() << "eof in include directive"; - filename += tokenizer().next_token().text; + given_filename += tokenizer().next_token().text; } tokenizer().next_token(); // > @@ -539,7 +543,8 @@ void verilog_preprocessort::directive() << "expecting either \" or < after `include"; } - auto full_path = find_include_file(filename, include_paths_only); + auto full_path = + find_include_file(context().filename, given_filename, include_paths_only); #ifdef _MSC_VER auto in = new std::ifstream(widen(full_path)); @@ -553,7 +558,7 @@ void verilog_preprocessort::directive() tokenizer().skip_until_eol(); tokenizer().next_token(); // eat the \n - context_stack.emplace_back(true, in, filename); + context_stack.emplace_back(true, in, full_path); emit_line_directive(1); // 'enter' // we now continue in the new context } diff --git a/src/verilog/verilog_preprocessor.h b/src/verilog/verilog_preprocessor.h index 31b918d28..1c3cb0964 100644 --- a/src/verilog/verilog_preprocessor.h +++ b/src/verilog/verilog_preprocessor.h @@ -44,8 +44,10 @@ class verilog_preprocessort:public preprocessort definest defines; void directive(); - std::string - find_include_file(const std::string &filename, bool include_paths_only); + std::string find_include_file( + const std::string &including_file, + const std::string &given_filename, + bool include_paths_only); definet::parameterst parse_define_parameters(); using define_argumentst = std::map>;