From: Justin Cinkelj <justin.cink...@xlab.si>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

command line: allow runscript with multiple lines

Signed-off-by: Justin Cinkelj <justin.cink...@xlab.si>
Message-Id: <1479825169-15499-5-git-send-email-justin.cink...@xlab.si>

---
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 osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to