Signed-off-by: Justin Cinkelj <justin.cink...@xlab.si>
---
 core/commands.cc      |  35 ++++++++++------
 tests/tst-commands.cc | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+), 12 deletions(-)

diff --git a/core/commands.cc b/core/commands.cc
index 90fd1f2..b2b3a60 100644
--- 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,7 +99,7 @@ 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.
@@ -101,24 +107,29 @@ std::vector<std::vector<std::string>> 
runscript_expand(const std::vector<std::st
         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
index 3b8c1c9..de0c143 100644
--- 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;
 }
-- 
2.5.5

-- 
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