From: Justin Cinkelj <[email protected]>
Committer: Nadav Har'El <[email protected]>
Branch: master
command line: allow runscript with multiple lines
Signed-off-by: Justin Cinkelj <[email protected]>
Message-Id: <[email protected]>
---
diff --git a/core/commands.cc b/core/commands.cc
--- a/core/commands.cc
+++ b/core/commands.cc
@@ -71,6 +71,12 @@ parse_command_line_min(const std::string line, bool &ok)
{
std::vector<std::vector<std::string> > result;
+ // Lines with only {blank char or ;} are ignored.
+ if (std::string::npos == line.find_first_not_of(" \f\n\r\t\v;")) {
+ ok = true;
+ return result;
+ }
+
commands g;
sciter iter = std::begin(line);
sciter end = std::end(line);
@@ -93,32 +99,37 @@ If cmd doesn't start with runscript, then vector with
size 0 is returned.
*/
std::vector<std::vector<std::string>> runscript_expand(const
std::vector<std::string>& cmd, bool &ok)
{
- std::vector<std::vector<std::string> > result;
+ std::vector<std::vector<std::string> > result2, result3;
if (cmd[0] == "runscript") {
/*
The cmd vector ends with additional ";" or "\0" element.
*/
if (cmd.size() != 3 && cmd[2].c_str()[0] != 0x00) {
puts("Failed expanding runscript - filename missing or extra
parameters present.");
ok = false;
- return result;
+ return result2;
}
auto fn = cmd[1];
std::ifstream in(fn);
std::string line;
- // only first line up to \n is used.
- getline(in, line);
- bool ok2;
- result = parse_command_line_min(line, ok2);
- debug("runscript expand fn='%s' line='%s'\n", fn.c_str(),
line.c_str());
- if (ok2 == false) {
- printf("Failed expanding runscript file='%s' line='%s'.\n",
fn.c_str(), line.c_str());
- result.clear();
- ok = false;
+ size_t line_num = 0;
+ while (!in.eof()) {
+ getline(in, line);
+ bool ok2;
+ result3 = parse_command_line_min(line, ok2);
+ debug("runscript expand fn='%s' line=%d '%s'\n", fn.c_str(),
line_num, line.c_str());
+ if (ok2 == false) {
+ printf("Failed expanding runscript file='%s'
line=%d '%s'.\n", fn.c_str(), line_num, line.c_str());
+ result2.clear();
+ ok = false;
+ return result2;
+ }
+ result2.insert(result2.end(), result3.begin(), result3.end());
+ line_num++;
}
}
- return result;
+ return result2;
}
std::vector<std::vector<std::string>>
diff --git a/tests/tst-commands.cc b/tests/tst-commands.cc
--- a/tests/tst-commands.cc
+++ b/tests/tst-commands.cc
@@ -515,6 +515,116 @@ static bool
test_runscript_multiple_commands_per_line_with_args_quotes()
return true;
}
+static bool test_runscript_multiline()
+{
+ std::ofstream of1("/myscript", std::ios::out | std::ios::binary);
+ of1 << "/prog1\n";
+ of1 << "/prog2 \n";
+ of1 << " /prog3; \n";
+ of1 << " /prog4 ; \n";
+ of1 << " \n";
+ of1 << "\n";
+ of1 << " ; \n";
+ of1 << " ; \n";
+ of1.close();
+
+ std::vector<std::vector<std::string> > result;
+ std::vector<std::string> cmd =
{ "/prog1", "/prog2", "/prog3", "/prog4" };
+ size_t expected_size[] = {2, 2, 2, 2};
+ bool ok;
+
+
+ result = osv::parse_command_line(
+ std::string("runscript \"/myscript\"; "),
+ ok);
+
+ if (!ok) {
+ return false;
+ }
+
+ if (result.size() != 4) {
+ return false;
+ }
+
+ for (size_t i = 0; i < result.size(); i++) {
+ if (result[i].size() != expected_size[i]) {
+ return false;
+ }
+ if (result[i][0] != cmd[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool
test_runscript_multiline_multiple_commands_per_line_with_args_quotes()
+{
+ std::ofstream of1("/myscript", std::ios::out | std::ios::binary);
+ of1 << "/prog1 pp1a pp1b\n";
+ of1 << "\t/prog2 pp2a \"pp2b1 pp2b2\" pp2c ; \n";
+ of1 << " /prog3 pp3a pp3b \"pp3c1 pp3c2\"; /prog4 \"pp4a1 pp4a2\";
\n";
+ of1.close();
+
+ std::vector<std::vector<std::string> > result;
+ std::vector<std::string> cmd =
{ "/prog1", "/prog2", "/prog3", "/prog4" };
+ size_t expected_size[] = {4, 5, 5, 3};
+ bool ok;
+
+ result = osv::parse_command_line(
+ std::string("runscript \"/myscript\"; "),
+ ok);
+
+ if (!ok) {
+ return false;
+ }
+
+ if (result.size() != 4) {
+ return false;
+ }
+
+ for (size_t i = 0; i < result.size(); i++) {
+ if (result[i].size() != expected_size[i]) {
+ return false;
+ }
+ if (result[i][0] != cmd[i]) {
+ return false;
+ }
+ }
+
+ if (result[0][1] != std::string("pp1a")) {
+ return false;
+ }
+ if (result[0][2] != std::string("pp1b")) {
+ return false;
+ }
+
+ if (result[1][1] != std::string("pp2a")) {
+ return false;
+ }
+ if (result[1][2] != std::string("pp2b1 pp2b2")) {
+ return false;
+ }
+ if (result[1][3] != std::string("pp2c")) {
+ return false;
+ }
+
+ if (result[2][1] != std::string("pp3a")) {
+ return false;
+ }
+ if (result[2][2] != std::string("pp3b")) {
+ return false;
+ }
+ if (result[2][3] != std::string("pp3c1 pp3c2")) {
+ return false;
+ }
+
+ if (result[3][1] != std::string("pp4a1 pp4a2")) {
+ return false;
+ }
+
+ return true;
+}
+
int main(int argc, char *argv[])
{
report(test_parse_simplest(), "simplest command line");
@@ -537,6 +647,10 @@ int main(int argc, char *argv[])
"runscript multiple commands per line with args");
report(test_runscript_multiple_commands_per_line_with_args_quotes(),
"runscript multiple commands per line with args and quotes");
+ report(test_runscript_multiline(),
+ "runscript multiple lines");
+
report(test_runscript_multiline_multiple_commands_per_line_with_args_quotes(),
+ "runscript multiple lines, multiple commands per line, with
args and quotes");
printf("SUMMARY: %d tests, %d failures\n", tests, fails);
return 0;
}
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.