3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-07-28 06:57:57 +00:00

Revert "Add groups to command reference"

This commit is contained in:
N. Engelhardt 2025-07-23 14:41:49 +00:00 committed by GitHub
parent 2223d7848b
commit 81f87ce6ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
124 changed files with 474 additions and 2035 deletions

View file

@ -90,10 +90,10 @@ public:
template<typename T>
void array(const T &&values)
{
begin_array();
begin_object();
for (auto &item : values)
value(item);
end_array();
end_object();
}
};

View file

@ -1,151 +0,0 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2025 Krystine Dawn <krystinedawn@yosyshq.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/log_help.h"
USING_YOSYS_NAMESPACE
Json ContentListing::to_json() {
Json::object object;
object["type"] = type;
if (body.length()) object["body"] = body;
if (strcmp(source_file, "unknown") != 0) object["source_file"] = source_file;
if (source_line != 0) object["source_line"] = source_line;
object["options"] = Json(options);
Json::array content_array;
for (auto child : _content) content_array.push_back(child->to_json());
object["content"] = content_array;
return object;
}
void ContentListing::usage(const string &text,
const source_location location)
{
log_assert(type.compare("root") == 0);
add_content("usage", text, location);
}
void ContentListing::option(const string &text, const string &description,
const source_location location)
{
auto option = open_option(text);
if (description.length())
option->add_content("text", description, location);
}
void ContentListing::codeblock(const string &code, const string &language,
const source_location location)
{
add_content("code", code, location);
back()->set_option("language", language);
}
void ContentListing::paragraph(const string &text,
const source_location location)
{
add_content("text", text, location);
}
ContentListing* ContentListing::open_usage(const string &text,
const source_location location)
{
usage(text, location);
return back();
}
ContentListing* ContentListing::open_option(const string &text,
const source_location location)
{
log_assert(type.compare("root") == 0 || type.compare("usage") == 0);
auto option = new ContentListing("option", text, location);
add_content(option);
return option;
}
#define MAX_LINE_LEN 80
void log_pass_str(const std::string &pass_str, std::string indent_str, bool leading_newline=false) {
if (pass_str.empty())
return;
std::istringstream iss(pass_str);
if (leading_newline)
log("\n");
for (std::string line; std::getline(iss, line);) {
log("%s", indent_str.c_str());
auto curr_len = indent_str.length();
std::istringstream lss(line);
for (std::string word; std::getline(lss, word, ' ');) {
while (word[0] == '`' && word.back() == '`')
word = word.substr(1, word.length()-2);
if (curr_len + word.length() >= MAX_LINE_LEN-1) {
curr_len = 0;
log("\n%s", indent_str.c_str());
}
if (word.length()) {
log("%s ", word.c_str());
curr_len += word.length() + 1;
}
}
log("\n");
}
}
void log_pass_str(const std::string &pass_str, int indent=0, bool leading_newline=false) {
std::string indent_str(indent*4, ' ');
log_pass_str(pass_str, indent_str, leading_newline);
}
PrettyHelp *current_help = nullptr;
PrettyHelp::PrettyHelp()
{
_prior = current_help;
_root_listing = ContentListing("root", "");
current_help = this;
}
PrettyHelp::~PrettyHelp()
{
current_help = _prior;
}
PrettyHelp *PrettyHelp::get_current()
{
if (current_help == nullptr)
new PrettyHelp();
return current_help;
}
void PrettyHelp::log_help()
{
for (auto content : _root_listing.get_content()) {
if (content->type.compare("usage") == 0) {
log_pass_str(content->body, 1, true);
log("\n");
} else if (content->type.compare("option") == 0) {
log_pass_str(content->body, 1);
for (auto text : content->get_content()) {
log_pass_str(text->body, 2);
log("\n");
}
} else {
log_pass_str(content->body, 0);
log("\n");
}
}
}

View file

@ -1,132 +0,0 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2025 Krystine Dawn <krystinedawn@yosyshq.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#ifndef LOG_HELP_H
#define LOG_HELP_H
#include "kernel/yosys_common.h"
#include "kernel/json.h"
YOSYS_NAMESPACE_BEGIN
class ContentListing {
vector<ContentListing *> _content;
public:
string type;
string body;
const char* source_file;
int source_line;
std::map<string, string> options;
ContentListing(
string type = "root", string body = "",
const char* source_file = "unknown", int source_line = 0
) : type(type), body(body), source_file(source_file), source_line(source_line) {
_content = {};
options = {};
}
ContentListing(string type, string body, source_location location) :
ContentListing(type, body, location.file_name(), location.line()) { }
void add_content(ContentListing *new_content) {
_content.push_back(new_content);
}
void add_content(string type, string body, source_location location) {
auto new_content = new ContentListing(type, body, location);
add_content(new_content);
}
bool has_content() { return _content.size() != 0; }
const vector<ContentListing *> get_content() {
const vector<ContentListing *> content = _content;
return content;
}
ContentListing* back() {
return _content.back();
}
void set_option(string key, string val = "") {
options[key] = val;
}
void usage(
const string &text,
const source_location location = source_location::current()
);
void option(
const string &text,
const string &description = "",
const source_location location = source_location::current()
);
void codeblock(
const string &code,
const string &language = "none",
const source_location location = source_location::current()
);
void paragraph(
const string &text,
const source_location location = source_location::current()
);
ContentListing* open_usage(
const string &text,
const source_location location = source_location::current()
);
ContentListing* open_option(
const string &text,
const source_location location = source_location::current()
);
Json to_json();
};
class PrettyHelp
{
public:
string group = "unknown";
private:
PrettyHelp *_prior;
ContentListing _root_listing;
public:
PrettyHelp();
~PrettyHelp();
static PrettyHelp *get_current();
bool has_content() { return _root_listing.has_content(); }
const vector<ContentListing *> get_content() {
return _root_listing.get_content();
}
ContentListing* get_root() {
return &_root_listing;
}
void set_group(const string g) { group = g; }
bool has_group() { return group.compare("unknown") != 0; }
void log_help();
};
YOSYS_NAMESPACE_END
#endif

View file

@ -21,7 +21,6 @@
#include "kernel/satgen.h"
#include "kernel/json.h"
#include "kernel/gzip.h"
#include "kernel/log_help.h"
#include <string.h>
#include <stdlib.h>
@ -42,8 +41,7 @@ std::map<std::string, Backend*> backend_register;
std::vector<std::string> Frontend::next_args;
Pass::Pass(std::string name, std::string short_help, source_location location) :
pass_name(name), short_help(short_help), location(location)
Pass::Pass(std::string name, std::string short_help) : pass_name(name), short_help(short_help)
{
next_queued_pass = first_queued_pass;
first_queued_pass = this;
@ -118,19 +116,9 @@ void Pass::post_execute(Pass::pre_post_exec_state_t state)
void Pass::help()
{
auto prettyHelp = PrettyHelp();
if (formatted_help()) {
prettyHelp.log_help();
} else {
log("\n");
log("No help message for command `%s'.\n", pass_name.c_str());
log("\n");
}
}
bool Pass::formatted_help()
{
return false;
log("\n");
log("No help message for command `%s'.\n", pass_name.c_str());
log("\n");
}
void Pass::clear_flags()
@ -393,8 +381,8 @@ void ScriptPass::help_script()
script();
}
Frontend::Frontend(std::string name, std::string short_help, source_location location) :
Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help, location),
Frontend::Frontend(std::string name, std::string short_help) :
Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help),
frontend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
{
}
@ -539,8 +527,8 @@ void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string
}
}
Backend::Backend(std::string name, std::string short_help, source_location location) :
Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "write_" + name, short_help, location),
Backend::Backend(std::string name, std::string short_help) :
Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "write_" + name, short_help),
backend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
{
}
@ -693,23 +681,6 @@ static string get_cell_name(string name) {
return is_code_getter(name) ? name.substr(0, name.length()-1) : name;
}
static void log_warning_flags(Pass *pass) {
bool has_warnings = false;
const string name = pass->pass_name;
if (pass->experimental_flag) {
if (!has_warnings) log("\n");
has_warnings = true;
log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", name.c_str());
}
if (pass->internal_flag) {
if (!has_warnings) log("\n");
has_warnings = true;
log("WARNING: THE '%s' COMMAND IS INTENDED FOR INTERNAL DEVELOPER USE ONLY.\n", name.c_str());
}
if (has_warnings)
log("\n");
}
static struct CellHelpMessages {
dict<string, SimHelper> cell_help;
CellHelpMessages() {
@ -735,211 +706,155 @@ struct HelpPass : public Pass {
log(" help <celltype>+ .... print verilog code for given cell type\n");
log("\n");
}
bool dump_cmds_json(PrettyJson &json) {
// init json
json.begin_object();
json.entry("version", "Yosys command reference");
json.entry("generator", yosys_version_str);
void write_cmd_rst(std::string cmd, std::string title, std::string text)
{
FILE *f = fopen(stringf("docs/source/cmd/%s.rst", cmd.c_str()).c_str(), "wt");
// make header
size_t char_len = cmd.length() + 3 + title.length();
std::string title_line = "\n";
title_line.insert(0, char_len, '=');
fprintf(f, "%s", title_line.c_str());
fprintf(f, "%s - %s\n", cmd.c_str(), title.c_str());
fprintf(f, "%s\n", title_line.c_str());
bool raise_error = false;
std::map<string, vector<string>> groups;
json.name("cmds"); json.begin_object();
// iterate over commands
for (auto &it : pass_register) {
auto name = it.first;
auto pass = it.second;
auto title = pass->short_help;
auto cmd_help = PrettyHelp();
auto has_pretty_help = pass->formatted_help();
if (!has_pretty_help) {
enum PassUsageState {
PUState_none,
PUState_signature,
PUState_options,
PUState_optionbody,
};
source_location null_source;
string current_buffer = "";
auto root_listing = cmd_help.get_root();
auto current_listing = root_listing;
// dump command help
std::ostringstream buf;
log_streams.push_back(&buf);
pass->help();
log_streams.pop_back();
std::stringstream ss;
ss << buf.str();
// parse command help
size_t def_strip_count = 0;
auto current_state = PUState_none;
auto catch_verific = false;
auto blank_lines = 2;
for (string line; std::getline(ss, line, '\n');) {
// find position of first non space character
std::size_t first_pos = line.find_first_not_of(" \t");
std::size_t last_pos = line.find_last_not_of(" \t");
if (first_pos == std::string::npos) {
switch (current_state)
{
case PUState_signature:
root_listing->usage(current_buffer, null_source);
current_listing = root_listing;
current_state = PUState_none;
current_buffer = "";
break;
case PUState_none:
case PUState_optionbody:
blank_lines += 1;
break;
default:
break;
}
// skip empty lines
continue;
}
// strip leading and trailing whitespace
std::string stripped_line = line.substr(first_pos, last_pos - first_pos +1);
bool IsDefinition = stripped_line[0] == '-';
IsDefinition &= stripped_line[1] != ' ' && stripped_line[1] != '>';
bool IsDedent = def_strip_count && first_pos < def_strip_count;
bool IsIndent = def_strip_count < first_pos;
// line looks like a signature
bool IsSignature = stripped_line.find(name) == 0 && (stripped_line.length() == name.length() || stripped_line.at(name.size()) == ' ');
if (IsSignature && first_pos <= 4 && (blank_lines >= 2 || current_state == PUState_signature)) {
if (current_state == PUState_options || current_state == PUState_optionbody) {
current_listing->codeblock(current_buffer, "none", null_source);
current_buffer = "";
} else if (current_state == PUState_signature) {
root_listing->usage(current_buffer, null_source);
current_buffer = "";
} else if (current_state == PUState_none && !current_buffer.empty()) {
current_listing->codeblock(current_buffer, "none", null_source);
current_buffer = "";
}
current_listing = root_listing;
current_state = PUState_signature;
def_strip_count = first_pos;
catch_verific = false;
} else if (IsDedent) {
def_strip_count = first_pos;
if (current_state == PUState_optionbody) {
if (!current_buffer.empty()) {
current_listing->codeblock(current_buffer, "none", null_source);
current_buffer = "";
}
if (IsIndent) {
current_state = PUState_options;
current_listing = root_listing->back();
} else {
current_state = PUState_none;
current_listing = root_listing;
}
} else {
current_state = PUState_none;
}
}
if (IsDefinition && !catch_verific && current_state != PUState_signature) {
if (!current_buffer.empty()) {
current_listing->codeblock(current_buffer, "none", null_source);
current_buffer = "";
}
current_state = PUState_options;
current_listing = root_listing->open_option(stripped_line, null_source);
def_strip_count = first_pos;
} else {
if (current_state == PUState_options) {
current_state = PUState_optionbody;
}
if (current_buffer.empty())
current_buffer = stripped_line;
else if (current_state == PUState_signature && IsIndent)
current_buffer += stripped_line;
else if (current_state == PUState_none) {
current_buffer += (blank_lines > 0 ? "\n\n" : "\n") + line;
} else
current_buffer += (blank_lines > 0 ? "\n\n" : "\n") + stripped_line;
if (stripped_line.compare("Command file parser supports following commands in file:") == 0)
catch_verific = true;
}
blank_lines = 0;
}
if (!current_buffer.empty()) {
if (current_buffer.size() > 64 && current_buffer.substr(0, 64).compare("The following commands are executed by this synthesis command:\n\n") == 0) {
current_listing->paragraph(current_buffer.substr(0, 62), null_source);
current_listing->codeblock(current_buffer.substr(64), "yoscrypt", null_source);
} else
current_listing->codeblock(current_buffer, "none", null_source);
current_buffer = "";
}
// render html
fprintf(f, ".. cmd:def:: %s\n", cmd.c_str());
fprintf(f, " :title: %s\n\n", title.c_str());
fprintf(f, " .. only:: html\n\n");
std::stringstream ss;
std::string textcp = text;
ss << text;
bool IsUsage = true;
int blank_count = 0;
size_t def_strip_count = 0;
bool WasDefinition = false;
for (std::string line; std::getline(ss, line, '\n');) {
// find position of first non space character
std::size_t first_pos = line.find_first_not_of(" \t");
std::size_t last_pos = line.find_last_not_of(" \t");
if (first_pos == std::string::npos) {
// skip formatting empty lines
if (!WasDefinition)
fputc('\n', f);
blank_count += 1;
continue;
}
// attempt auto group
if (!cmd_help.has_group()) {
string source_file = pass->location.file_name();
bool has_source = source_file.compare("unknown") != 0;
if (pass->internal_flag)
cmd_help.group = "internal";
else if (source_file.find("backends/") == 0 || (!has_source && name.find("read_") == 0))
cmd_help.group = "backends";
else if (source_file.find("frontends/") == 0 || (!has_source && name.find("write_") == 0))
cmd_help.group = "frontends";
else if (has_source) {
auto last_slash = source_file.find_last_of('/');
if (last_slash != string::npos) {
auto parent_path = source_file.substr(0, last_slash);
cmd_help.group = parent_path;
}
// strip leading and trailing whitespace
std::string stripped_line = line.substr(first_pos, last_pos - first_pos +1);
bool IsDefinition = stripped_line[0] == '-';
IsDefinition &= stripped_line[1] != ' ' && stripped_line[1] != '>';
bool IsDedent = def_strip_count && first_pos <= def_strip_count;
bool IsIndent = first_pos == 2 || first_pos == 4;
if (cmd.compare(0, 7, "verific") == 0)
// verific.cc has strange and different formatting from the rest
IsIndent = false;
// another usage block
bool NewUsage = stripped_line.find(cmd) == 0;
if (IsUsage) {
if (stripped_line.compare(0, 4, "See ") == 0) {
// description refers to another function
fprintf(f, "\n %s\n", stripped_line.c_str());
} else {
// usage should be the first line of help output
fprintf(f, "\n .. code:: yoscrypt\n\n %s\n\n ", stripped_line.c_str());
WasDefinition = true;
}
// implicit !has_source
else if (name.find("equiv") == 0)
cmd_help.group = "passes/equiv";
else if (name.find("fsm") == 0)
cmd_help.group = "passes/fsm";
else if (name.find("memory") == 0)
cmd_help.group = "passes/memory";
else if (name.find("opt") == 0)
cmd_help.group = "passes/opt";
else if (name.find("proc") == 0)
cmd_help.group = "passes/proc";
IsUsage = false;
} else if (IsIndent && NewUsage && (blank_count >= 2 || WasDefinition)) {
// another usage block
fprintf(f, "\n .. code:: yoscrypt\n\n %s\n\n ", stripped_line.c_str());
WasDefinition = true;
def_strip_count = 0;
} else if (IsIndent && IsDefinition && (blank_count || WasDefinition)) {
// format definition term
fprintf(f, "\n\n .. code:: yoscrypt\n\n %s\n\n ", stripped_line.c_str());
WasDefinition = true;
def_strip_count = first_pos;
} else {
if (IsDedent) {
fprintf(f, "\n\n ::\n");
def_strip_count = first_pos;
} else if (WasDefinition) {
fprintf(f, "::\n");
WasDefinition = false;
}
fprintf(f, "\n %s", line.substr(def_strip_count, std::string::npos).c_str());
}
if (groups.count(cmd_help.group) == 0) {
groups[cmd_help.group] = vector<string>();
}
groups[cmd_help.group].push_back(name);
// write to json
json.name(name.c_str()); json.begin_object();
json.entry("title", title);
json.name("content"); json.begin_array();
for (auto content : cmd_help.get_content())
json.value(content->to_json());
json.end_array();
json.entry("group", cmd_help.group);
json.entry("source_file", pass->location.file_name());
json.entry("source_line", pass->location.line());
json.entry("source_func", pass->location.function_name());
json.entry("experimental_flag", pass->experimental_flag);
json.entry("internal_flag", pass->internal_flag);
json.end_object();
blank_count = 0;
}
json.end_object();
fputc('\n', f);
json.entry("groups", groups);
// render latex
fprintf(f, ".. only:: latex\n\n");
fprintf(f, " ::\n\n");
std::stringstream ss2;
ss2 << textcp;
for (std::string line; std::getline(ss2, line, '\n');) {
fprintf(f, " %s\n", line.c_str());
}
fclose(f);
}
void write_cell_rst(Yosys::SimHelper cell, Yosys::CellType ct)
{
// open
FILE *f = fopen(stringf("docs/source/cell/%s.rst", cell.filesafe_name().c_str()).c_str(), "wt");
json.end_object();
return raise_error;
// make header
string title_line;
if (cell.title.length())
title_line = stringf("%s - %s", cell.name.c_str(), cell.title.c_str());
else title_line = cell.name;
string underline = "\n";
underline.insert(0, title_line.length(), '=');
fprintf(f, "%s\n", title_line.c_str());
fprintf(f, "%s\n", underline.c_str());
// help text, with cell def for links
fprintf(f, ".. cell:def:: %s\n", cell.name.c_str());
if (cell.title.length())
fprintf(f, " :title: %s\n\n", cell.title.c_str());
else
fprintf(f, " :title: %s\n\n", cell.name.c_str());
std::stringstream ss;
ss << cell.desc;
for (std::string line; std::getline(ss, line, '\n');) {
fprintf(f, " %s\n", line.c_str());
}
// properties
fprintf(f, "\nProperties");
fprintf(f, "\n----------\n\n");
dict<string, bool> prop_dict = {
{"is_evaluable", ct.is_evaluable},
{"is_combinatorial", ct.is_combinatorial},
{"is_synthesizable", ct.is_synthesizable},
};
for (auto &it : prop_dict) {
fprintf(f, "- %s: %s\n", it.first.c_str(), it.second ? "true" : "false");
}
// source code
fprintf(f, "\nSimulation model (Verilog)");
fprintf(f, "\n--------------------------\n\n");
fprintf(f, ".. code-block:: verilog\n");
fprintf(f, " :caption: %s\n\n", cell.source.c_str());
std::stringstream ss2;
ss2 << cell.code;
for (std::string line; std::getline(ss2, line, '\n');) {
fprintf(f, " %s\n", line.c_str());
}
// footer
fprintf(f, "\n.. note::\n\n");
fprintf(f, " This page was auto-generated from the output of\n");
fprintf(f, " ``help %s``.\n", cell.name.c_str());
// close
fclose(f);
}
bool dump_cells_json(PrettyJson &json) {
// init json
@ -1045,7 +960,11 @@ struct HelpPass : public Pass {
log("=");
log("\n");
it.second->help();
log_warning_flags(it.second);
if (it.second->experimental_flag) {
log("\n");
log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
log("\n");
}
}
}
else if (args[1] == "-cells") {
@ -1059,9 +978,44 @@ struct HelpPass : public Pass {
log("\n");
return;
}
// this option is undocumented as it is for internal use only
else if (args[1] == "-write-rst-command-reference-manual") {
for (auto &it : pass_register) {
std::ostringstream buf;
log_streams.push_back(&buf);
it.second->help();
if (it.second->experimental_flag) {
log("\n");
log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
log("\n");
}
log_streams.pop_back();
write_cmd_rst(it.first, it.second->short_help, buf.str());
}
}
// this option is also undocumented as it is for internal use only
else if (args[1] == "-write-rst-cells-manual") {
bool raise_error = false;
for (auto &it : yosys_celltypes.cell_types) {
auto name = it.first.str();
if (cell_help_messages.contains(name)) {
write_cell_rst(cell_help_messages.get(name), it.second);
} else {
log("ERROR: Missing cell help for cell '%s'.\n", name.c_str());
raise_error |= true;
}
}
if (raise_error) {
log_error("One or more cells defined in celltypes.h are missing help documentation.\n");
}
}
else if (pass_register.count(args[1])) {
pass_register.at(args[1])->help();
log_warning_flags(pass_register.at(args[1]));
if (pass_register.at(args[1])->experimental_flag) {
log("\n");
log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", args[1].c_str());
log("\n");
}
}
else if (cell_help_messages.contains(args[1])) {
auto help_cell = cell_help_messages.get(args[1]);
@ -1090,17 +1044,7 @@ struct HelpPass : public Pass {
log("No such command or cell type: %s\n", args[1].c_str());
return;
} else if (args.size() == 3) {
// this option is undocumented as it is for internal use only
if (args[1] == "-dump-cmds-json") {
PrettyJson json;
if (!json.write_to_file(args[2]))
log_error("Can't open file `%s' for writing: %s\n", args[2].c_str(), strerror(errno));
if (dump_cmds_json(json)) {
log_abort();
}
}
// this option is undocumented as it is for internal use only
else if (args[1] == "-dump-cells-json") {
if (args[1] == "-dump-cells-json") {
PrettyJson json;
if (!json.write_to_file(args[2]))
log_error("Can't open file `%s' for writing: %s\n", args[2].c_str(), strerror(errno));
@ -1108,8 +1052,6 @@ struct HelpPass : public Pass {
log_error("One or more cells defined in celltypes.h are missing help documentation.\n");
}
}
else
log("Unknown help command: `%s %s'\n", args[1].c_str(), args[2].c_str());
return;
}

View file

@ -23,62 +23,27 @@
#include "kernel/yosys_common.h"
#include "kernel/yosys.h"
#include <version>
#if __cpp_lib_source_location == 201907L
#include <source_location>
using std::source_location;
#elif defined(__has_include)
# if __has_include(<experimental/source_location>)
#include <experimental/source_location>
using std::experimental::source_location;
# else
#define SOURCE_FALLBACK
# endif
#else
#define SOURCE_FALLBACK
#endif
#ifdef SOURCE_FALLBACK
struct source_location { // dummy placeholder
int line() const { return 0; }
int column() const { return 0; }
const char* file_name() const { return "unknown"; }
const char* function_name() const { return "unknown"; }
static const source_location current(...) { return source_location(); }
};
#endif
YOSYS_NAMESPACE_BEGIN
struct Pass
{
std::string pass_name, short_help;
source_location location;
Pass(std::string name, std::string short_help = "** document me **",
source_location location = source_location::current());
Pass(std::string name, std::string short_help = "** document me **");
// Prefer overriding 'Pass::on_shutdown()' if possible
virtual ~Pass();
// Makes calls to log() to generate help message
virtual void help();
// Uses PrettyHelp::get_current() to produce a more portable formatted help message
virtual bool formatted_help();
virtual void clear_flags();
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) = 0;
int call_counter;
int64_t runtime_ns;
bool experimental_flag = false;
bool internal_flag = false;
void experimental() {
experimental_flag = true;
}
void internal() {
internal_flag = true;
}
struct pre_post_exec_state_t {
Pass *parent_pass;
int64_t begin_ns;
@ -116,8 +81,7 @@ struct ScriptPass : Pass
RTLIL::Design *active_design;
std::string active_run_from, active_run_to;
ScriptPass(std::string name, std::string short_help = "** document me **", source_location location = source_location::current()) :
Pass(name, short_help, location) { }
ScriptPass(std::string name, std::string short_help = "** document me **") : Pass(name, short_help) { }
virtual void script() = 0;
@ -135,8 +99,7 @@ struct Frontend : Pass
static std::string last_here_document;
std::string frontend_name;
Frontend(std::string name, std::string short_help = "** document me **",
source_location location = source_location::current());
Frontend(std::string name, std::string short_help = "** document me **");
void run_register() override;
~Frontend() override;
void execute(std::vector<std::string> args, RTLIL::Design *design) override final;
@ -152,8 +115,7 @@ struct Frontend : Pass
struct Backend : Pass
{
std::string backend_name;
Backend(std::string name, std::string short_help = "** document me **",
source_location location = source_location::current());
Backend(std::string name, std::string short_help = "** document me **");
void run_register() override;
~Backend() override;
void execute(std::vector<std::string> args, RTLIL::Design *design) override final;