28 #define MAX_REG_COUNT 1000
40 Pass::Pass(std::string name, std::string short_help) : pass_name(name), short_help(short_help)
43 first_queued_pass =
this;
56 while (first_queued_pass) {
96 log(
"No help message for command `%s'.\n",
pass_name.c_str());
102 if (args.size() <= 1)
104 log(
"Full command line:");
105 for (
size_t i = 0; i < args.size(); i++)
106 log(
" %s", args[i].c_str());
112 std::string command_text;
115 for (
size_t i = 0; i < args.size(); i++) {
117 error_pos += args[i].size() + 1;
118 command_text = command_text + (command_text.empty() ?
"" :
" ") + args[i];
121 log(
"\nSyntax error in command `%s':\n", command_text.c_str());
125 msg.c_str(), command_text.c_str(), error_pos,
"");
130 for (; argidx < args.size(); argidx++)
132 std::string arg = args[argidx];
134 if (arg.substr(0, 1) ==
"-")
135 cmd_error(args, argidx,
"Unknown option or option in arguments.");
138 cmd_error(args, argidx,
"Extra argument.");
148 std::vector<std::string>
args;
150 std::string cmd_buf = command;
151 std::string tok =
next_token(cmd_buf,
" \t\r\n");
153 if (tok.empty() || tok[0] ==
'#')
157 cmd_buf = command.substr(command.find(
'!') + 1);
158 while (!cmd_buf.empty() && (cmd_buf.back() ==
' ' || cmd_buf.back() ==
'\t' ||
159 cmd_buf.back() ==
'\r' || cmd_buf.back() ==
'\n'))
160 cmd_buf.resize(cmd_buf.size()-1);
161 log_header(
"Shell command: %s\n", cmd_buf.c_str());
164 log_cmd_error(
"Shell command returned error code %d.\n", retCode);
168 while (!tok.empty()) {
171 if (tok.back() ==
';') {
172 int num_semikolon = 0;
173 while (!tok.empty() && tok.back() ==
';')
174 tok.resize(tok.size()-1), num_semikolon++;
179 if (num_semikolon == 2)
180 call(design,
"clean");
181 if (num_semikolon == 3)
182 call(design,
"clean -purge");
193 if (args.size() == 0 || args[0][0] ==
'#')
198 for (
size_t i = 0; i < args.size(); i++)
199 log(
"%s%s", i ?
" " :
"", args[i].c_str());
204 log_cmd_error(
"No such command: %s (type 'help' for a command overview)\n", args[0].c_str());
267 Pass(name.rfind(
"=", 0) == 0 ? name.substr(1) :
"read_" + name, short_help),
268 frontend_name(name.rfind(
"=", 0) == 0 ? name.substr(1) : name)
289 std::istream *f =
NULL;
292 execute(f, std::string(), args, design);
296 }
while (!args.empty());
304 bool called_with_fp = f !=
NULL;
307 for (; argidx < args.size(); argidx++)
309 std::string arg = args[argidx];
311 if (arg.substr(0, 1) ==
"-")
312 cmd_error(args, argidx,
"Unknown option or option in arguments.");
314 cmd_error(args, argidx,
"Extra filename argument in direct file mode.");
317 if (filename ==
"<<" && argidx+1 < args.size())
318 filename += args[++argidx];
319 if (filename.substr(0, 2) ==
"<<") {
321 log_error(
"Unexpected here document '%s' outside of script!\n", filename.c_str());
322 if (filename.size() <= 2)
323 log_error(
"Missing EOT marker in here document!\n");
324 std::string eot_marker = filename.substr(2);
331 log_error(
"Unexpected end of file in here document '%s'!\n", filename.c_str());
333 if (buffer.size() > 0 && (buffer[buffer.size() - 1] ==
'\n' || buffer[buffer.size() - 1] ==
'\r'))
336 size_t indent = buffer.find_first_not_of(
" \t\r\n");
337 if (indent != std::string::npos && buffer.substr(indent, eot_marker.size()) == eot_marker)
343 if (filename.substr(0, 2) ==
"+/")
345 std::ifstream *ff =
new std::ifstream;
346 ff->open(filename.c_str());
353 log_cmd_error(
"Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno));
355 for (
size_t i = argidx+1; i < args.size(); i++)
356 if (args[i].substr(0, 1) ==
"-")
357 cmd_error(args, i,
"Found option, expected arguments.");
359 if (argidx+1 < args.size()) {
362 args.erase(args.begin()+argidx+1, args.end());
367 cmd_error(args, argidx,
"No filename given.");
370 args.push_back(filename);
377 std::vector<std::string>
args;
378 char *s = strdup(command.c_str());
379 for (
char *p = strtok(s,
" \t\r\n"); p; p = strtok(
NULL,
" \t\r\n"))
387 if (args.size() == 0)
396 }
else if (filename ==
"-") {
397 std::istream *f_cin = &std::cin;
402 if (!filename.empty())
403 args.push_back(filename);
411 Pass(name.rfind(
"=", 0) == 0 ? name.substr(1) :
"write_" + name, short_help),
412 backend_name(name.rfind(
"=", 0) == 0 ? name.substr(1) : name)
431 std::ostream *f =
NULL;
433 execute(f, std::string(), args, design);
441 bool called_with_fp = f !=
NULL;
443 for (; argidx < args.size(); argidx++)
445 std::string arg = args[argidx];
447 if (arg.substr(0, 1) ==
"-" && arg !=
"-")
448 cmd_error(args, argidx,
"Unknown option or option in arguments.");
450 cmd_error(args, argidx,
"Extra filename argument in direct file mode.");
453 filename =
"<stdout>";
459 std::ofstream *ff =
new std::ofstream;
460 ff->open(filename.c_str(), std::ofstream::trunc);
463 log_cmd_error(
"Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
469 args.push_back(filename);
474 filename =
"<stdout>";
481 std::vector<std::string>
args;
482 char *s = strdup(command.c_str());
483 for (
char *p = strtok(s,
" \t\r\n"); p; p = strtok(
NULL,
" \t\r\n"))
491 if (args.size() == 0)
502 }
else if (filename ==
"-") {
503 std::ostream *f_cout = &std::cout;
508 if (!filename.empty())
509 args.push_back(filename);
524 log(
" help ............. list all commands\n");
525 log(
" help <command> ... print help message for given command\n");
526 log(
" help -all ........ print complete command reference\n");
532 while ((pos = tex.find(
'_', pos)) != std::string::npos) {
533 tex.replace(pos, 1,
"\\_");
537 void write_tex(FILE *f, std::string cmd, std::string title, std::string text)
539 size_t begin = text.find_first_not_of(
"\n"), end = text.find_last_not_of(
"\n");
540 if (begin != std::string::npos && end != std::string::npos && begin < end)
541 text = text.substr(begin, end-begin+1);
542 std::string cmd_unescaped = cmd;
545 fprintf(f,
"\\section{%s -- %s}\n", cmd.c_str(), title.c_str());
546 fprintf(f,
"\\label{cmd:%s}\n", cmd_unescaped.c_str());
547 fprintf(f,
"\\begin{lstlisting}[numbers=left,frame=single]\n");
548 fprintf(f,
"%s\n\\end{lstlisting}\n\n", text.c_str());
553 while ((pos = html.find_first_of(
"<>&", pos)) != std::string::npos)
556 html.replace(pos, 1,
"<");
560 html.replace(pos, 1,
">");
564 html.replace(pos, 1,
"&");
569 void write_html(FILE *idxf, std::string cmd, std::string title, std::string text)
571 FILE *f = fopen(
stringf(
"cmd_%s.in", cmd.c_str()).c_str(),
"wt");
572 fprintf(idxf,
"<li><a href=\"cmd_%s.html\"> ", cmd.c_str());
578 fprintf(idxf,
"%s</a> <span>%s</span></a>\n", cmd.c_str(), title.c_str());
580 fprintf(f,
"@cmd_header %s@\n", cmd.c_str());
581 fprintf(f,
"<h1>%s - %s</h1>\n", cmd.c_str(), title.c_str());
582 fprintf(f,
"<pre>%s</pre>\n", text.c_str());
583 fprintf(f,
"@footer@\n");
589 if (args.size() == 1) {
592 log(
" %-20s %s\n", it.first.c_str(), it.second->short_help.c_str());
594 log(
"Type 'help <command>' for more information on a command.\n");
599 if (args.size() == 2) {
600 if (args[1] ==
"-all") {
603 log(
"%s -- %s\n", it.first.c_str(), it.second->short_help.c_str());
604 for (
size_t i = 0; i < it.first.size() + it.second->short_help.size() + 6; i++)
611 else if (args[1] ==
"-write-tex-command-reference-manual") {
612 FILE *f = fopen(
"command-reference-manual.tex",
"wt");
613 fprintf(f,
"%% Generated using the yosys 'help -write-tex-command-reference-manual' command.\n\n");
615 std::ostringstream buf;
619 write_tex(f, it.first, it.second->short_help, buf.str());
624 else if (args[1] ==
"-write-web-command-reference-manual") {
625 FILE *f = fopen(
"templates/cmd_index.in",
"wt");
627 std::ostringstream buf;
631 write_html(f, it.first, it.second->short_help, buf.str());
636 log(
"No such command: %s\n", args[1].c_str());
647 EchoPass() :
Pass(
"echo",
"turning echoing back of commands on and off") { }
653 log(
"Print all commands to log before executing them.\n");
658 log(
"Do not print all commands to log before executing them. (default)\n");
664 cmd_error(args, 2,
"Unexpected argument.");
666 if (args.size() == 2) {
669 else if (args[1] ==
"off")
672 cmd_error(args, 1,
"Unexpected argument.");
static std::string next_token(bool pass_newline=false)
void cmd_error(const std::vector< std::string > &args, size_t argidx, std::string msg)
virtual void run_register()
std::vector< RTLIL::Selection > selection_stack
std::string stringf(const char *fmt,...)
const char * create_prompt(RTLIL::Design *design, int recursion_counter)
void cmd_log_args(const std::vector< std::string > &args)
void handle_extra_select_args(Pass *pass, std::vector< std::string > args, size_t argidx, size_t args_size, RTLIL::Design *design)
static std::string last_here_document
void log_header(const char *format,...)
#define YOSYS_NAMESPACE_END
static void frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::string command)
std::map< std::string, Frontend * > frontend_register
std::string frontend_name
void log_error(const char *format,...)
void escape_tex(std::string &tex)
static FILE * current_script_file
int run_command(const std::string &command, std::function< void(const std::string &)> process_line)
void write_html(FILE *idxf, std::string cmd, std::string title, std::string text)
std::vector< std::ostream * > log_streams
void extra_args(std::ostream *&f, std::string &filename, std::vector< std::string > args, size_t argidx)
static void backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::string command)
virtual void execute(std::vector< std::string > args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL
static std::vector< std::string > next_args
virtual void execute(std::vector< std::string > args, RTLIL::Design *)
#define log_assert(_assert_expr_)
virtual void execute(std::vector< std::string > args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL
static void done_register()
virtual void run_register()
void escape_html(std::string &html)
void log_cmd_error(const char *format,...)
Pass(std::string name, std::string short_help="** document me **")
Backend(std::string name, std::string short_help="** document me **")
#define YOSYS_NAMESPACE_BEGIN
virtual void execute(std::vector< std::string > args, RTLIL::Design *)
static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command)
void log(const char *format,...)
pre_post_exec_state_t pre_execute()
virtual void run_register()
std::map< std::string, Pass * > pass_register
std::string proc_share_dirname()
std::string selected_active_module
static void init_register()
static void call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
void write_tex(FILE *f, std::string cmd, std::string title, std::string text)
static void call(RTLIL::Design *design, std::string command)
void extra_args(std::istream *&f, std::string &filename, std::vector< std::string > args, size_t argidx)
Frontend(std::string name, std::string short_help="** document me **")
std::map< std::string, Backend * > backend_register
void post_execute(pre_post_exec_state_t state)