diff options
Diffstat (limited to 'frontends/verilog/preproc.cc')
-rw-r--r-- | frontends/verilog/preproc.cc | 57 |
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 - |