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.

Reply via email to