diff --git a/regression/verilog/preprocessor/include1.desc b/regression/verilog/preprocessor/include1.desc new file mode 100644 index 000000000..f62a87cae --- /dev/null +++ b/regression/verilog/preprocessor/include1.desc @@ -0,0 +1,15 @@ +CORE +include1.v +--preprocess +// Enable multi-line checking +activate-multi-line-match +`line 1 "include1.v" 0 +`line 1 "include1b.v" 1 +line b 1 +line b 2 +`line 2 "include1.v" 2 +line 2 +line 3 +^EXIT=0$ +^SIGNAL=0$ +-- diff --git a/regression/verilog/preprocessor/include1.v b/regression/verilog/preprocessor/include1.v new file mode 100644 index 000000000..b7ee716d9 --- /dev/null +++ b/regression/verilog/preprocessor/include1.v @@ -0,0 +1,3 @@ +`include "include1b.v" +line 2 +line 3 diff --git a/regression/verilog/preprocessor/include1b.v b/regression/verilog/preprocessor/include1b.v new file mode 100644 index 000000000..255fd89de --- /dev/null +++ b/regression/verilog/preprocessor/include1b.v @@ -0,0 +1,2 @@ +line b 1 +line b 2 diff --git a/src/verilog/verilog_preprocessor.cpp b/src/verilog/verilog_preprocessor.cpp index 6bdc2681d..7b5072708 100644 --- a/src/verilog/verilog_preprocessor.cpp +++ b/src/verilog/verilog_preprocessor.cpp @@ -98,45 +98,19 @@ Function: verilog_preprocessort::include \*******************************************************************/ -void verilog_preprocessort::include(const std::string &filename) +std::string +verilog_preprocessort::find_include_file(const std::string &filename) { // first try filename as is - { -#ifdef _MSC_VER - auto in = new std::ifstream(widen(filename)); -#else - auto in = new std::ifstream(filename); -#endif - - if(*in) - { - context_stack.emplace_back(true, in, filename); - context().print_line_directive(out, 1); // 'enter' - return; // done - } - else - delete in; - } + if(file_exists(filename)) + return filename; // done // try include paths in given order for(const auto &path : config.verilog.include_paths) { auto full_name = concat_dir_file(path, filename); - -#ifdef _MSC_VER - auto in = new std::ifstream(widen(full_name)); -#else - auto in = new std::ifstream(full_name); -#endif - - if(*in) - { - context_stack.emplace_back(true, in, filename); - context().print_line_directive(out, 1); // 'enter' - return; // done - } - - delete in; + if(file_exists(full_name)) + return full_name; // done } throw verilog_preprocessor_errort() @@ -486,8 +460,23 @@ void verilog_preprocessort::directive() // strip quotes off string literal, escaping, etc. auto filename = file_token.string_literal_value(); + auto full_path = find_include_file(filename); + +#ifdef _MSC_VER + auto in = new std::ifstream(widen(full_path)); +#else + auto in = new std::ifstream(full_path); +#endif + + if(!*in) + throw verilog_preprocessor_errort() << "failed to open an include file"; + tokenizer().skip_until_eol(); - include(filename); + tokenizer().next_token(); // eat the \n + + context_stack.emplace_back(true, in, filename); + context().print_line_directive(out, 1); // 'enter' + // we now continue in the new context } else if(text=="resetall") { diff --git a/src/verilog/verilog_preprocessor.h b/src/verilog/verilog_preprocessor.h index ed55645f1..7ed75f45b 100644 --- a/src/verilog/verilog_preprocessor.h +++ b/src/verilog/verilog_preprocessor.h @@ -44,7 +44,7 @@ class verilog_preprocessort:public preprocessort definest defines; void directive(); - void include(const std::string &filename); + std::string find_include_file(const std::string &filename); definet::parameterst parse_define_parameters(); using define_argumentst = std::map>; diff --git a/src/verilog/verilog_preprocessor_tokenizer.cpp b/src/verilog/verilog_preprocessor_tokenizer.cpp index 1e70f1468..e9ae9c5bb 100644 --- a/src/verilog/verilog_preprocessor_tokenizer.cpp +++ b/src/verilog/verilog_preprocessor_tokenizer.cpp @@ -88,13 +88,19 @@ verilog_preprocessor_tokenizert::verilog_preprocessor_tokenizert( std::size_t verilog_preprocessor_tokenizert::yy_input(char *buffer, std::size_t max_size) { - std::size_t result; - for(result = 0; result < max_size; result++) + std::size_t result = 0; + while(result < max_size) { char ch; if(!in.get(ch)) - return result; // eof - buffer[result] = ch; + break; // eof + buffer[result++] = ch; + if(ch == '\n') + { + // We need to abort prematurely to enable + // switching input streams on `include. + break; + } } return result; }