mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-07 01:54:10 +00:00
Allow specifying multiple regexes to match in exec
command output, and also to specify regexes that must _not_ match.
This commit is contained in:
parent
e6c09f1e0e
commit
8ba49a8462
|
@ -35,41 +35,54 @@ struct ExecPass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
log("Execute a command in the operating system shell. All supplied arguments are\n");
|
log("Execute a command in the operating system shell. All supplied arguments are\n");
|
||||||
log("concatenated and passed as a command to popen(3). Whitespace is not guaranteed\n");
|
log("concatenated and passed as a command to popen(3). Whitespace is not guaranteed\n");
|
||||||
log("to be preserved, even if quoted. stdin is not connected, while stdout is\n");
|
log("to be preserved, even if quoted. stdin and stderr are not connected, while stdout is\n");
|
||||||
log("logged and stderr is logged as a warning.\n");
|
log("logged unless the \"-q\" option is specified.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -q\n");
|
log(" -q\n");
|
||||||
log(" suppress stdout and stderr from subprocess\n");
|
log(" Suppress stdout and stderr from subprocess\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -expected-return <int>\n");
|
log(" -expect-return <int>\n");
|
||||||
log(" generates an error if popen() does not return specified value.\n");
|
log(" Generate an error if popen() does not return specified value.\n");
|
||||||
|
log(" May only be specified once; the final specified value is controlling\n");
|
||||||
|
log(" if specified multiple times.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -expected-stdout <regex>\n");
|
log(" -expect-stdout <regex>\n");
|
||||||
log(" generates an error if specified regex does not match any line\n");
|
log(" Generate an error if the specified regex does not match any line\n");
|
||||||
log(" in subprocess stdout.\n");
|
log(" in subprocess's stdout. May be specified multiple times.\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -not-expect-stdout <regex>\n");
|
||||||
|
log(" Generate an error if the specified regex matches any line\n");
|
||||||
|
log(" in subprocess's stdout. May be specified multiple times.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" Example: exec -q -expected-return 0 -- echo \"bananapie\" | grep \"nana\"\n");
|
log(" Example: exec -q -expect-return 0 -- echo \"bananapie\" | grep \"nana\"\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||||
{
|
{
|
||||||
if(args.size() == 0)
|
|
||||||
log_cmd_error("No command provided.\n");
|
|
||||||
|
|
||||||
std::string cmd = "";
|
std::string cmd = "";
|
||||||
char buf[4096] = {};
|
char buf[4096] = {};
|
||||||
std::string linebuf = "";
|
std::string linebuf = "";
|
||||||
bool flag_cmd = false;
|
bool flag_cmd = false;
|
||||||
bool flag_quiet = false;
|
bool flag_quiet = false;
|
||||||
bool flag_expected_return = false;
|
bool flag_expect_return = false;
|
||||||
bool flag_expected_stdout = false;
|
int expect_return_value = 0;
|
||||||
int expected_return_value = 0;
|
bool flag_expect_stdout = false;
|
||||||
YS_REGEX_TYPE expected_stdout_re;
|
struct expect_stdout_elem {
|
||||||
std::string expected_stdout_re_str;
|
bool matched;
|
||||||
bool expected_stdout_re_matched = false;
|
bool polarity; //true: this regex must match at least one line
|
||||||
|
//false: this regex must not match any line
|
||||||
|
std::string str;
|
||||||
|
YS_REGEX_TYPE re;
|
||||||
|
|
||||||
|
expect_stdout_elem() : matched(false), polarity(true), str(), re(){};
|
||||||
|
};
|
||||||
|
std::vector<expect_stdout_elem> expect_stdout;
|
||||||
|
|
||||||
|
if(args.size() == 0)
|
||||||
|
log_cmd_error("No command provided.\n");
|
||||||
|
|
||||||
for(size_t argidx = 1; argidx < args.size(); ++argidx) {
|
for(size_t argidx = 1; argidx < args.size(); ++argidx) {
|
||||||
if (flag_cmd) {
|
if (flag_cmd) {
|
||||||
|
@ -79,24 +92,41 @@ struct ExecPass : public Pass {
|
||||||
flag_cmd = true;
|
flag_cmd = true;
|
||||||
else if (args[argidx] == "-q")
|
else if (args[argidx] == "-q")
|
||||||
flag_quiet = true;
|
flag_quiet = true;
|
||||||
else if (args[argidx] == "-expected-return") {
|
else if (args[argidx] == "-expect-return") {
|
||||||
flag_expected_return = true;
|
flag_expect_return = true;
|
||||||
++argidx;
|
++argidx;
|
||||||
if (argidx >= args.size())
|
if (argidx >= args.size())
|
||||||
log_cmd_error("No expected return value specified.\n");
|
log_cmd_error("No expected return value specified.\n");
|
||||||
|
|
||||||
expected_return_value = atoi(args[argidx].c_str());
|
expect_return_value = atoi(args[argidx].c_str());
|
||||||
} else if (args[argidx] == "-expected-stdout") {
|
} else if (args[argidx] == "-expect-stdout") {
|
||||||
flag_expected_stdout = true;
|
flag_expect_stdout = true;
|
||||||
++argidx;
|
++argidx;
|
||||||
if (argidx >= args.size())
|
if (argidx >= args.size())
|
||||||
log_cmd_error("No expected regular expression to find in stdout specified.\n");
|
log_cmd_error("No expected regular expression specified.\n");
|
||||||
|
|
||||||
try{
|
try{
|
||||||
expected_stdout_re_str = args[argidx];
|
expect_stdout_elem x;
|
||||||
expected_stdout_re = YS_REGEX_COMPILE(args[argidx]);
|
x.str = args[argidx];
|
||||||
|
x.re = YS_REGEX_COMPILE(args[argidx]);
|
||||||
|
expect_stdout.push_back(x);
|
||||||
} catch (const YS_REGEX_NS::regex_error& e) {
|
} catch (const YS_REGEX_NS::regex_error& e) {
|
||||||
log_cmd_error("Error in regex expression '%s' !\n", expected_stdout_re_str.c_str());
|
log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
|
||||||
|
}
|
||||||
|
} else if (args[argidx] == "-not-expect-stdout") {
|
||||||
|
flag_expect_stdout = true;
|
||||||
|
++argidx;
|
||||||
|
if (argidx >= args.size())
|
||||||
|
log_cmd_error("No expected regular expression specified.\n");
|
||||||
|
|
||||||
|
try{
|
||||||
|
expect_stdout_elem x;
|
||||||
|
x.str = args[argidx];
|
||||||
|
x.re = YS_REGEX_COMPILE(args[argidx]);
|
||||||
|
x.polarity = false;
|
||||||
|
expect_stdout.push_back(x);
|
||||||
|
} catch (const YS_REGEX_NS::regex_error& e) {
|
||||||
|
log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
|
@ -124,8 +154,10 @@ struct ExecPass : public Pass {
|
||||||
if (!flag_quiet)
|
if (!flag_quiet)
|
||||||
log("%s\n", line.c_str());
|
log("%s\n", line.c_str());
|
||||||
|
|
||||||
if(YS_REGEX_NS::regex_search(line, expected_stdout_re))
|
if (flag_expect_stdout)
|
||||||
expected_stdout_re_matched = true;
|
for(auto &x : expect_stdout)
|
||||||
|
if (YS_REGEX_NS::regex_search(line, x.re))
|
||||||
|
x.matched = true;
|
||||||
|
|
||||||
pos = linebuf.find('\n');
|
pos = linebuf.find('\n');
|
||||||
}
|
}
|
||||||
|
@ -143,11 +175,13 @@ struct ExecPass : public Pass {
|
||||||
retval = WSTOPSIG(status);
|
retval = WSTOPSIG(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag_expected_return && retval != expected_return_value)
|
if (flag_expect_return && retval != expect_return_value)
|
||||||
log_cmd_error("Return value %d did not match expected return value %d.\n", retval, expected_return_value);
|
log_cmd_error("Return value %d did not match expected return value %d.\n", retval, expect_return_value);
|
||||||
|
|
||||||
if (flag_expected_stdout && !expected_stdout_re_matched)
|
if (flag_expect_stdout)
|
||||||
log_cmd_error("Command stdout did not have a line matching given regex \"%s\".\n", expected_stdout_re_str.c_str());
|
for (auto &x : expect_stdout)
|
||||||
|
if (x.polarity ^ x.matched)
|
||||||
|
log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str.c_str());
|
||||||
|
|
||||||
log_pop();
|
log_pop();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue