diff options
Diffstat (limited to 'contrib/llvm/utils/lit/lit/TclUtil.py')
-rw-r--r-- | contrib/llvm/utils/lit/lit/TclUtil.py | 322 |
1 files changed, 0 insertions, 322 deletions
diff --git a/contrib/llvm/utils/lit/lit/TclUtil.py b/contrib/llvm/utils/lit/lit/TclUtil.py deleted file mode 100644 index 4a3f345..0000000 --- a/contrib/llvm/utils/lit/lit/TclUtil.py +++ /dev/null @@ -1,322 +0,0 @@ -import itertools - -from ShCommands import Command, Pipeline - -def tcl_preprocess(data): - # Tcl has a preprocessing step to replace escaped newlines. - i = data.find('\\\n') - if i == -1: - return data - - # Replace '\\\n' and subsequent whitespace by a single space. - n = len(data) - str = data[:i] - i += 2 - while i < n and data[i] in ' \t': - i += 1 - return str + ' ' + data[i:] - -class TclLexer: - """TclLexer - Lex a string into "words", following the Tcl syntax.""" - - def __init__(self, data): - self.data = tcl_preprocess(data) - self.pos = 0 - self.end = len(self.data) - - def at_end(self): - return self.pos == self.end - - def eat(self): - c = self.data[self.pos] - self.pos += 1 - return c - - def look(self): - return self.data[self.pos] - - def maybe_eat(self, c): - """ - maybe_eat(c) - Consume the character c if it is the next character, - returning True if a character was consumed. """ - if self.data[self.pos] == c: - self.pos += 1 - return True - return False - - def escape(self, c): - if c == 'a': - return '\x07' - elif c == 'b': - return '\x08' - elif c == 'f': - return '\x0c' - elif c == 'n': - return '\n' - elif c == 'r': - return '\r' - elif c == 't': - return '\t' - elif c == 'v': - return '\x0b' - elif c in 'uxo': - raise ValueError,'Invalid quoted character %r' % c - else: - return c - - def lex_braced(self): - # Lex until whitespace or end of string, the opening brace has already - # been consumed. - - str = '' - while 1: - if self.at_end(): - raise ValueError,"Unterminated '{' quoted word" - - c = self.eat() - if c == '}': - break - elif c == '{': - str += '{' + self.lex_braced() + '}' - elif c == '\\' and self.look() in '{}': - str += self.eat() - else: - str += c - - return str - - def lex_quoted(self): - str = '' - - while 1: - if self.at_end(): - raise ValueError,"Unterminated '\"' quoted word" - - c = self.eat() - if c == '"': - break - elif c == '\\': - if self.at_end(): - raise ValueError,'Missing quoted character' - - str += self.escape(self.eat()) - else: - str += c - - return str - - def lex_unquoted(self, process_all=False): - # Lex until whitespace or end of string. - str = '' - while not self.at_end(): - if not process_all: - if self.look().isspace() or self.look() == ';': - break - - c = self.eat() - if c == '\\': - if self.at_end(): - raise ValueError,'Missing quoted character' - - str += self.escape(self.eat()) - elif c == '[': - raise NotImplementedError, ('Command substitution is ' - 'not supported') - elif c == '$' and not self.at_end() and (self.look().isalpha() or - self.look() == '{'): - raise NotImplementedError, ('Variable substitution is ' - 'not supported') - else: - str += c - - return str - - def lex_one_token(self): - if self.maybe_eat('"'): - return self.lex_quoted() - elif self.maybe_eat('{'): - # Check for argument substitution. - if not self.maybe_eat('*'): - return self.lex_braced() - - if not self.maybe_eat('}'): - return '*' + self.lex_braced() - - if self.at_end() or self.look().isspace(): - return '*' - - raise NotImplementedError, "Argument substitution is unsupported" - else: - return self.lex_unquoted() - - def lex(self): - while not self.at_end(): - c = self.look() - if c in ' \t': - self.eat() - elif c in ';\n': - self.eat() - yield (';',) - else: - yield self.lex_one_token() - -class TclExecCommand: - kRedirectPrefixes1 = ('<', '>') - kRedirectPrefixes2 = ('<@', '<<', '2>', '>&', '>>', '>@') - kRedirectPrefixes3 = ('2>@', '2>>', '>>&', '>&@') - kRedirectPrefixes4 = ('2>@1',) - - def __init__(self, args): - self.args = iter(args) - - def lex(self): - try: - return self.args.next() - except StopIteration: - return None - - def look(self): - next = self.lex() - if next is not None: - self.args = itertools.chain([next], self.args) - return next - - def parse_redirect(self, tok, length): - if len(tok) == length: - arg = self.lex() - if arg is None: - raise ValueError,'Missing argument to %r redirection' % tok - else: - tok,arg = tok[:length],tok[length:] - - if tok[0] == '2': - op = (tok[1:],2) - else: - op = (tok,) - return (op, arg) - - def parse_pipeline(self): - if self.look() is None: - raise ValueError,"Expected at least one argument to exec" - - commands = [Command([],[])] - while 1: - arg = self.lex() - if arg is None: - break - elif arg == '|': - commands.append(Command([],[])) - elif arg == '|&': - # Write this as a redirect of stderr; it must come first because - # stdout may have already been redirected. - commands[-1].redirects.insert(0, (('>&',2),'1')) - commands.append(Command([],[])) - elif arg[:4] in TclExecCommand.kRedirectPrefixes4: - commands[-1].redirects.append(self.parse_redirect(arg, 4)) - elif arg[:3] in TclExecCommand.kRedirectPrefixes3: - commands[-1].redirects.append(self.parse_redirect(arg, 3)) - elif arg[:2] in TclExecCommand.kRedirectPrefixes2: - commands[-1].redirects.append(self.parse_redirect(arg, 2)) - elif arg[:1] in TclExecCommand.kRedirectPrefixes1: - commands[-1].redirects.append(self.parse_redirect(arg, 1)) - else: - commands[-1].args.append(arg) - - return Pipeline(commands, False, pipe_err=True) - - def parse(self): - ignoreStderr = False - keepNewline = False - - # Parse arguments. - while 1: - next = self.look() - if not isinstance(next, str) or next[0] != '-': - break - - if next == '--': - self.lex() - break - elif next == '-ignorestderr': - ignoreStderr = True - elif next == '-keepnewline': - keepNewline = True - else: - raise ValueError,"Invalid exec argument %r" % next - - return (ignoreStderr, keepNewline, self.parse_pipeline()) - -### - -import unittest - -class TestTclLexer(unittest.TestCase): - def lex(self, str, *args, **kwargs): - return list(TclLexer(str, *args, **kwargs).lex()) - - def test_preprocess(self): - self.assertEqual(tcl_preprocess('a b'), 'a b') - self.assertEqual(tcl_preprocess('a\\\nb c'), 'a b c') - - def test_unquoted(self): - self.assertEqual(self.lex('a b c'), - ['a', 'b', 'c']) - self.assertEqual(self.lex(r'a\nb\tc\ '), - ['a\nb\tc ']) - self.assertEqual(self.lex(r'a \\\$b c $\\'), - ['a', r'\$b', 'c', '$\\']) - - def test_braced(self): - self.assertEqual(self.lex('a {b c} {}'), - ['a', 'b c', '']) - self.assertEqual(self.lex(r'a {b {c\n}}'), - ['a', 'b {c\\n}']) - self.assertEqual(self.lex(r'a {b\{}'), - ['a', 'b{']) - self.assertEqual(self.lex(r'{*}'), ['*']) - self.assertEqual(self.lex(r'{*} a'), ['*', 'a']) - self.assertEqual(self.lex(r'{*} a'), ['*', 'a']) - self.assertEqual(self.lex('{a\\\n b}'), - ['a b']) - - def test_quoted(self): - self.assertEqual(self.lex('a "b c"'), - ['a', 'b c']) - - def test_terminators(self): - self.assertEqual(self.lex('a\nb'), - ['a', (';',), 'b']) - self.assertEqual(self.lex('a;b'), - ['a', (';',), 'b']) - self.assertEqual(self.lex('a ; b'), - ['a', (';',), 'b']) - -class TestTclExecCommand(unittest.TestCase): - def parse(self, str): - return TclExecCommand(list(TclLexer(str).lex())).parse() - - def test_basic(self): - self.assertEqual(self.parse('echo hello'), - (False, False, - Pipeline([Command(['echo', 'hello'], [])], - False, True))) - self.assertEqual(self.parse('echo hello | grep hello'), - (False, False, - Pipeline([Command(['echo', 'hello'], []), - Command(['grep', 'hello'], [])], - False, True))) - - def test_redirect(self): - self.assertEqual(self.parse('echo hello > a >b >>c 2> d |& e'), - (False, False, - Pipeline([Command(['echo', 'hello'], - [(('>&',2),'1'), - (('>',),'a'), - (('>',),'b'), - (('>>',),'c'), - (('>',2),'d')]), - Command(['e'], [])], - False, True))) - -if __name__ == '__main__': - unittest.main() |