[test-suite] r260354 - lit: Factor out commandline parsing into an own file.

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 9 19:56:35 PST 2016


Author: matze
Date: Tue Feb  9 21:56:34 2016
New Revision: 260354

URL: http://llvm.org/viewvc/llvm-project?rev=260354&view=rev
Log:
lit: Factor out commandline parsing into an own file.

Added:
    test-suite/trunk/litsupport/shellcommand.py
Modified:
    test-suite/trunk/litsupport/runsafely.py

Modified: test-suite/trunk/litsupport/runsafely.py
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/litsupport/runsafely.py?rev=260354&r1=260353&r2=260354&view=diff
==============================================================================
--- test-suite/trunk/litsupport/runsafely.py (original)
+++ test-suite/trunk/litsupport/runsafely.py Tue Feb  9 21:56:34 2016
@@ -1,5 +1,6 @@
 import shlex
 import timeit
+import shellcommand
 try:
     from shlex import quote  # python 3.3 and above
 except:
@@ -8,42 +9,12 @@ except:
 
 def prepareRunSafely(context, commandline, outfile):
     config = context.config
-
-    stdin = None
-    stdout = None
-    stderr = None
-    workdir = None
-    tokens = shlex.split(commandline)
-    # Parse "< INPUTFILE", "> OUTFILE", "2> OUTFILE" patterns
-    i = 0
-    while i < len(tokens):
-        if tokens[i] == "<" and i+1 < len(tokens):
-            stdin = tokens[i+1]
-            del tokens[i+1]
-            del tokens[i]
-            continue
-        elif tokens[i] == ">" and i+1 < len(tokens):
-            stdout = tokens[i+1]
-            del tokens[i+1]
-            del tokens[i]
-            continue
-        elif tokens[i] == "2>" and i+1 < len(tokens):
-            stderr = tokens[i+1]
-            del tokens[i+1]
-            del tokens[i]
-            continue
-        if i+2 < len(tokens) and tokens[i] == "cd" and tokens[i+2] == ";":
-            workdir = tokens[i+1]
-            del tokens[i+2]
-            del tokens[i+1]
-            del tokens[i]
-            continue
-        i += 1
+    cmd = shellcommand.parse(commandline)
 
     runsafely = "%s/RunSafely.sh" % config.test_suite_root
     runsafely_prefix = [runsafely]
-    if workdir is not None:
-        runsafely_prefix += ["-d", workdir]
+    if cmd.workdir is not None:
+        runsafely_prefix += ["-d", cmd.workdir]
     timeit = "%s/tools/timeit" % config.test_source_root
     if config.remote_host:
         timeit = "%s/tools/timeit-target" % config.test_source_root
@@ -58,19 +29,22 @@ def prepareRunSafely(context, commandlin
         runsafely_prefix += ["-u", config.run_under]
     if not config.traditional_output:
         runsafely_prefix += ["-n"]
-        if stdout is not None:
-            runsafely_prefix += ["-o", stdout]
-        if stderr is not None:
-            runsafely_prefix += ["-e", stderr]
+        if cmd.stdout is not None:
+            runsafely_prefix += ["-o", cmd.stdout]
+        if cmd.stderr is not None:
+            runsafely_prefix += ["-e", cmd.stderr]
     else:
-        if stdout is not None or stderr is not None:
+        if cmd.stdout is not None or cmd.stderr is not None:
             raise Exception("separate stdout/stderr redirection not possible with traditional output")
     timeout = "7200"
-    if stdin is None:
+    if cmd.stdin is not None:
+        stdin = cmd.stdin
+    else:
         stdin = "/dev/null"
     runsafely_prefix += ["-t", timeit, timeout, stdin, outfile]
 
-    new_commandline = " ".join(map(quote, runsafely_prefix + tokens))
+    complete_command = runsafely_prefix + [cmd.executable] + cmd.arguments
+    new_commandline = " ".join(map(quote, complete_command))
     return new_commandline
 
 

Added: test-suite/trunk/litsupport/shellcommand.py
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/litsupport/shellcommand.py?rev=260354&view=auto
==============================================================================
--- test-suite/trunk/litsupport/shellcommand.py (added)
+++ test-suite/trunk/litsupport/shellcommand.py Tue Feb  9 21:56:34 2016
@@ -0,0 +1,62 @@
+import shlex
+
+# Loosely modeled after posix specification for sh
+reserved_words = [ '!', '{', '}', 'case', 'do', 'done', 'elif', 'else', 'esac',
+                   'fi', 'for', 'if', 'in', 'then', 'until', 'while' ]
+
+chaining_tokens = set([';', '&&', '||', '|', '&'])
+unhandled_tokens = set([';;', '<<', '>>', '<&', '>&', '<>', '<<-', '>|', '(',
+                        ')'])
+
+class ShellCommand:
+    def __init__(self):
+        self.stdin = None
+        self.stdout = None
+        self.stderr = None
+        self.executable = None
+        self.arguments = []
+        self.modifiers = None
+        self.workdir = None
+
+def parse(commandline):
+    previous_commands = []
+    result = ShellCommand()
+    tokens = shlex.split(commandline)
+    i = 0
+    first_word = True
+    while i < len(tokens):
+        token = tokens[i]
+        i += 1
+        if token == '<' and i < len(tokens):
+            result.stdin = tokens[i]
+            i+=1
+            continue
+        if token == '>' and i < len(tokens):
+            result.stdout = tokens[i]
+            i+=1
+            continue
+        if token == '2>' and i < len(tokens):
+            result.stderr = tokens[i]
+            i+=1
+            continue
+        if first_word:
+            if token in reserved_words or token in unhandled_tokens:
+                raise Exception("Reserved word '%s' not supported" % token)
+            result.executable = token
+            first_word = False
+        else:
+            if token in chaining_tokens:
+                # Currently we only allow the special case of 'cd DIR ;'
+                if token == ';' and result.executable == 'cd' and \
+                      len(result.arguments) == 1:
+                    newresult = ShellCommand()
+                    newresult.workdir = result.arguments[0]
+                    result = newresult
+                    first_word = True
+                    continue
+                raise Exception("Command chaining not supported yet")
+            if token in unhandled_tokens or token in reserved_words:
+                raise Exception("Commandline with '%s' not supported yet" %
+                                token)
+            result.arguments.append(token)
+    return result




More information about the llvm-commits mailing list