[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