Skip to content

Verilog: directives inside `include argument #879

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/Hazard3/Hazard3-vlindex.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
14 changes: 4 additions & 10 deletions regression/verilog/preprocessor/include3.desc
Original file line number Diff line number Diff line change
@@ -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.
51 changes: 33 additions & 18 deletions src/verilog/verilog_preprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
// <filename> -- 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
{
Expand Down
Loading