[test-suite] r263531 - litsupport/shellcommand: Add toCommandline() and wrap() convenience functions, support envvars

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 14 22:12:18 PDT 2016


Author: matze
Date: Tue Mar 15 00:12:18 2016
New Revision: 263531

URL: http://llvm.org/viewvc/llvm-project?rev=263531&view=rev
Log:
litsupport/shellcommand: Add toCommandline() and wrap() convenience functions, support envvars

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

Modified: test-suite/trunk/litsupport/shellcommand.py
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/litsupport/shellcommand.py?rev=263531&r1=263530&r2=263531&view=diff
==============================================================================
--- test-suite/trunk/litsupport/shellcommand.py (original)
+++ test-suite/trunk/litsupport/shellcommand.py Tue Mar 15 00:12:18 2016
@@ -1,24 +1,62 @@
 import shlex
 import logging
-
-# 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([';;', '<<', '>>', '<&', '>&', '<>', '<<-', '>|', '(',
-                        ')'])
+import re
+try:
+        from shlex import quote  # python 3.3 and above
+except:
+        from pipes import quote  # python 3.2 and earlier
 
 
 class ShellCommand:
-    def __init__(self):
+    '''This class represents a parsed shell command (a subset, we do not support
+    arbitrary shell commands yet). The parsed form allows direct access to
+    information like the executable name, working directory or the file
+    to which stdin/stdout/stderr is redirected.'''
+    def __init__(self, executable=None, arguments=None):
         self.stdin = None
         self.stdout = None
         self.stderr = None
-        self.executable = None
-        self.arguments = []
-        self.modifiers = None
+        self.executable = executable
+        if arguments is None:
+            arguments = []
+        self.arguments = arguments
         self.workdir = None
+        self.envvars = {}
+
+    def toCommandline(self):
+        result = ""
+
+        if self.workdir is not None:
+            result += "cd %s && " % quote(self.workdir)
+
+        res_list = [self.executable] + self.arguments
+        result += " ".join(map(quote, res_list))
+
+        envlist = []
+        for key, value in self.envvars.items():
+            result += "%s=%s " % (key, quote(value))
+
+        if self.stdin is not None:
+            result += " < %s" % quote(self.stdin)
+        if self.stdout is not None:
+            result += " > %s" % quote(self.stdout)
+        if self.stderr is not None:
+            result += " 2> %s" % quote(self.stderr)
+        return result
+
+    def wrap(self, new_executable, args):
+        self.arguments = args + [self.executable] + self.arguments
+        self.executable = new_executable
+
+
+# Tokens/keywords for shell command parsing, 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([';;', '<<', '>>', '<&', '>&', '<>', '<<-', '>|', '(',
+                        ')'])
 
 
 def parse(commandline):
@@ -42,6 +80,11 @@ def parse(commandline):
             result.stderr = tokens[i]
             i += 1
             continue
+        assignment=re.match('([A-Za-z_][A-Za-z_0-9]*)=(.*)', token)
+        if assignment:
+            result.envvars[m.group(1)] = m.group(2)
+            continue
+
         if first_word:
             if token in reserved_words or token in unhandled_tokens:
                 raise Exception("Reserved word '%s' not supported" % token)
@@ -50,8 +93,9 @@ def parse(commandline):
         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:
+                if (token == ';' or token == '&&') and \
+                        result.executable == 'cd' and \
+                        len(result.arguments) == 1:
                     newresult = ShellCommand()
                     newresult.workdir = result.arguments[0]
                     result = newresult




More information about the llvm-commits mailing list