aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/verilog/preproc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/verilog/preproc.cc')
-rw-r--r--frontends/verilog/preproc.cc57
1 files changed, 42 insertions, 15 deletions
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc
index ee742d485..161253a99 100644
--- a/frontends/verilog/preproc.cc
+++ b/frontends/verilog/preproc.cc
@@ -28,7 +28,7 @@
*
* Ad-hoc implementation of a Verilog preprocessor. The directives `define,
* `include, `ifdef, `ifndef, `else and `endif are handled here. All other
- * directives are handled by the lexer (see lexer.l).
+ * directives are handled by the lexer (see verilog_lexer.l).
*
*/
@@ -183,8 +183,9 @@ static std::string next_token(bool pass_newline = false)
const char *ok = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789";
if (ch == '`' || strchr(ok, ch) != NULL)
{
+ char first = ch;
ch = next_char();
- if (ch == '"') {
+ if (first == '`' && (ch == '"' || ch == '`')) {
token += ch;
} else do {
if (strchr(ok, ch) == NULL) {
@@ -244,6 +245,7 @@ static bool try_expand_macro(std::set<std::string> &defines_with_args,
args.push_back(std::string());
while (1)
{
+ skip_spaces();
tok = next_token(true);
if (tok == ")" || tok == "}" || tok == "]")
level--;
@@ -264,6 +266,9 @@ static bool try_expand_macro(std::set<std::string> &defines_with_args,
}
insert_input(defines_map[name]);
return true;
+ } else if (tok == "``") {
+ // Swallow `` in macro expansion
+ return true;
} else return false;
}
@@ -366,14 +371,31 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
ff.clear();
std::string fixed_fn = fn;
ff.open(fixed_fn.c_str());
- if (ff.fail() && fn.size() > 0 && fn[0] != '/' && filename.find('/') != std::string::npos) {
+
+ bool filename_path_sep_found;
+ bool fn_relative;
+#ifdef _WIN32
+ // Both forward and backslash are acceptable separators on Windows.
+ filename_path_sep_found = (filename.find_first_of("/\\") != std::string::npos);
+ // Easier just to invert the check for an absolute path (e.g. C:\ or C:/)
+ fn_relative = !(fn[1] == ':' && (fn[2] == '/' || fn[2] == '\\'));
+#else
+ filename_path_sep_found = (filename.find('/') != std::string::npos);
+ fn_relative = (fn[0] != '/');
+#endif
+
+ if (ff.fail() && fn.size() > 0 && fn_relative && filename_path_sep_found) {
// if the include file was not found, it is not given with an absolute path, and the
// currently read file is given with a path, then try again relative to its directory
ff.clear();
+#ifdef _WIN32
+ fixed_fn = filename.substr(0, filename.find_last_of("/\\")+1) + fn;
+#else
fixed_fn = filename.substr(0, filename.rfind('/')+1) + fn;
+#endif
ff.open(fixed_fn);
}
- if (ff.fail() && fn.size() > 0 && fn[0] != '/') {
+ if (ff.fail() && fn.size() > 0 && fn_relative) {
// if the include file was not found and it is not given with an absolute path, then
// search it in the include path
for (auto incdir : include_dirs) {
@@ -383,10 +405,12 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
if (!ff.fail()) break;
}
}
- if (ff.fail())
+ if (ff.fail()) {
output_code.push_back("`file_notfound " + fn);
- else
+ } else {
input_file(ff, fixed_fn);
+ yosys_input_files.insert(fixed_fn);
+ }
continue;
}
@@ -466,13 +490,17 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
}
while (newline_count-- > 0)
return_char('\n');
- // printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
- defines_map[name] = value;
- if (state == 2)
- defines_with_args.insert(name);
- else
- defines_with_args.erase(name);
- global_defines_cache[name] = std::pair<std::string, bool>(value, state == 2);
+ if (strchr("abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789", name[0])) {
+ // printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
+ defines_map[name] = value;
+ if (state == 2)
+ defines_with_args.insert(name);
+ else
+ defines_with_args.erase(name);
+ global_defines_cache[name] = std::pair<std::string, bool>(value, state == 2);
+ } else {
+ log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name.c_str());
+ }
continue;
}
@@ -505,7 +533,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
if (try_expand_macro(defines_with_args, defines_map, tok))
continue;
-
+
output_code.push_back(tok);
}
@@ -521,4 +549,3 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
}
YOSYS_NAMESPACE_END
-