diff --git a/examples/Hazard3/Hazard3-vlindex.sh b/examples/Hazard3/Hazard3-vlindex.sh index 908c4a92a..a10e1dcdc 100755 --- a/examples/Hazard3/Hazard3-vlindex.sh +++ b/examples/Hazard3/Hazard3-vlindex.sh @@ -29,6 +29,6 @@ Number of functions.......: 7 Number of tasks...........: 0 Number of properties......: 0 Number of sequences.......: 0 -Number of module instances: 71 +Number of module instances: 70 Number of configurations..: 0 EOM diff --git a/regression/verilog/preprocessor/include3.desc b/regression/verilog/preprocessor/include3.desc index 56ea68861..a5d3ec9d5 100644 --- a/regression/verilog/preprocessor/include3.desc +++ b/regression/verilog/preprocessor/include3.desc @@ -1,13 +1,7 @@ -KNOWNBUG -include2.v +CORE +include3.v --preprocess -// Enable multi-line checking -activate-multi-line-match -`line 1 "include3\.v" 0 -`line 1 "include_file2\.vh" 1 - -`line 2 "include3\.v" 2 -^EXIT=0$ +^file include3.v line 2: preprocessor directive inside `include directive$ +^EXIT=1$ ^SIGNAL=0$ -- -Giving the include file name as a macro doesn't work. diff --git a/src/verilog/verilog_preprocessor.cpp b/src/verilog/verilog_preprocessor.cpp index 5c7913755..19700ce14 100644 --- a/src/verilog/verilog_preprocessor.cpp +++ b/src/verilog/verilog_preprocessor.cpp @@ -572,34 +572,49 @@ void verilog_preprocessort::directive() // skip whitespace tokenizer().skip_ws(); - // We expect one of: + std::string argument; + + // Read any tokens until end of line. + // 1800-2017 is silent on whether further directives are + // processed. We emit an error. + // 1800-2017 is silent wether file names in quotes are processed + // as string literals. We assume not so. + while(!tokenizer().eof() && tokenizer().peek() != '\n') + { + auto token = tokenizer().next_token(); + + if(token == '`') + { + throw verilog_preprocessor_errort() + << "preprocessor directive inside `include directive"; + } + + argument += token.text; + } + + // We expect the argument to be one of: // -- include paths only // "filename" -- relative path, then include paths. std::string given_filename; bool include_paths_only; - if(tokenizer().peek().is_string_literal()) + if(!argument.empty() && argument[0] == '"') { include_paths_only = false; - const auto file_token = tokenizer().next_token(); - CHECK_RETURN(file_token.is_string_literal()); - // strip quotes off string literal, escaping, etc. - given_filename = file_token.string_literal_value(); + auto quote_pos = argument.find('"', 1); + if(quote_pos == std::string::npos) + throw verilog_preprocessor_errort() + << "expected closing \" in include directive"; + given_filename = std::string(argument, 1, quote_pos - 1); } - else if(tokenizer().peek() == '<') + else if(!argument.empty() && argument[0] == '<') { - tokenizer().next_token(); // < include_paths_only = true; - - while(tokenizer().peek() != '>') - { - if(tokenizer().peek().is_eof()) - throw verilog_preprocessor_errort() << "eof in include directive"; - - given_filename += tokenizer().next_token().text; - } - - tokenizer().next_token(); // > + auto quote_pos = argument.find('>', 1); + if(quote_pos == std::string::npos) + throw verilog_preprocessor_errort() + << "expected closing > in include directive"; + given_filename = std::string(argument, 1, quote_pos - 1); } else {