3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-05-06 15:25:47 +00:00

log_help: Refactor help content adding

Content is now added to the `ContentListing` rather than the `PrettyHelp`.
`open_*` methods return the `ContentListing` that was added instead of leaving a hanging continuation.
This allows for (e.g.) options to be added directly to optiongroups, instead of requiring that groups be closed before continuation.
This also means that all `PrettyHelp`s are a listing, with the actual log being called by the default `Pass::help()`; making the mode field redundant.
Added `PrettyHelp::log_help()` which replaces the `PrettyHelp::Mode::LOG` logic.
Added `ContentListing::back()` which just returns the last element of the underlying content vector.
Some of the content tracking was made redundant and removed, in particular `PrettyHelp::_current_listing` and `ContentListing::parent`.

Converted `ContentListing` to a class instead of a struct, adjusting constructors to match.
Added `ContentListing` constructor that accepts a `source_location`.

Update `HelpPass::dump_cmds_json()` for new log_help.
This commit is contained in:
Krystine Sherwin 2025-03-21 10:26:12 +13:00
parent bce73af324
commit f4ad934542
No known key found for this signature in database
4 changed files with 166 additions and 227 deletions

View file

@ -28,11 +28,56 @@ Json ContentListing::to_json() {
if (strcmp(source_file, "unknown") != 0) object["source_file"] = source_file;
if (source_line != 0) object["source_line"] = source_line;
Json::array content_array;
for (auto child : content) content_array.push_back(child->to_json());
for (auto child : _content) content_array.push_back(child->to_json());
object["content"] = content_array;
return object;
}
void ContentListing::usage(const string &usage,
const source_location location)
{
log_assert(type.compare("root") == 0);
add_content("usage", usage, 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);
}
void ContentListing::paragraph(const string &text,
const source_location location)
{
add_content("text", text, location);
}
ContentListing* ContentListing::open_optiongroup(const string &name,
const source_location location)
{
log_assert(type.compare("root") == 0);
auto optiongroup = new ContentListing("optiongroup", name, location);
add_content(optiongroup);
return optiongroup;
}
ContentListing* ContentListing::open_option(const string &text,
const source_location location)
{
log_assert(type.compare("optiongroup") == 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())
@ -66,15 +111,10 @@ void log_pass_str(const std::string &pass_str, int indent=0, bool leading_newlin
PrettyHelp *current_help = nullptr;
PrettyHelp::PrettyHelp(Mode mode)
PrettyHelp::PrettyHelp()
{
_prior = current_help;
_mode = mode;
_root_listing = ContentListing({
.type = "root"
});
_root_listing.type = "root";
_current_listing = &_root_listing;
_root_listing = ContentListing("root", "");
current_help = this;
}
@ -91,127 +131,22 @@ PrettyHelp *PrettyHelp::get_current()
return current_help;
}
void PrettyHelp::usage(const string &usage,
const source_location location)
void PrettyHelp::log_help()
{
switch (_mode)
{
case LOG:
log_pass_str(usage, _current_indent+1, true);
log("\n");
break;
case LISTING:
add_content("usage", usage, location);
break;
default:
log_abort();
}
}
void PrettyHelp::option(const string &text, const string &description,
const source_location location)
{
open_option(text);
if (description.length()) {
switch (_mode)
{
case LOG:
log_pass_str(description, _current_indent);
for (auto content : _root_listing.get_content()) {
if (content->type.compare("usage") == 0) {
log_pass_str(content->body, 1, true);
} else if (content->type.compare("optiongroup") == 0) {
for (auto option : content->get_content()) {
log_pass_str(option->body, 1);
for (auto text : option->get_content()) {
log_pass_str(text->body, 2);
log("\n");
}
}
} else {
log_pass_str(content->body, 0, true);
log("\n");
break;
case LISTING:
add_content("text", description, location);
break;
default:
log_abort();
}
}
close(1);
}
void PrettyHelp::codeblock(const string &code, const string &language,
const source_location location)
{
switch (_mode)
{
case LOG:
log("%s\n", code.c_str());
break;
case LISTING:
add_content("code", code, location);
break;
default:
log_abort();
}
}
void PrettyHelp::paragraph(const string &text,
const source_location location)
{
switch (_mode)
{
case LOG:
log_pass_str(text, _current_indent);
log("\n");
break;
case LISTING:
add_content("text", text, location);
break;
default:
log_abort();
}
}
void PrettyHelp::open_optiongroup(const string &name,
const source_location location)
{
switch (_mode)
{
case LOG:
break;
case LISTING:
push_content("optiongroup", name, location);
break;
default:
log_abort();
}
_current_indent += 1;
}
void PrettyHelp::open_option(const string &text,
const source_location location)
{
switch (_mode)
{
case LOG:
log_pass_str(text, _current_indent);
break;
case LISTING:
push_content("option", text, location);
break;
default:
log_abort();
}
_current_indent += 1;
}
void PrettyHelp::close(int levels)
{
switch (_mode)
{
case LOG:
_current_indent -= levels;
log_assert(_current_indent >= 0);
break;
case LISTING:
for (int i=0; i<levels; i++) {
_current_indent--;
log_assert(_current_indent >= 0);
pop_content();
}
break;
default:
log_abort();
}
}