diff options
| author | Daniel Dunbar <daniel@zuster.org> | 2009-07-31 07:59:05 +0000 | 
|---|---|---|
| committer | Daniel Dunbar <daniel@zuster.org> | 2009-07-31 07:59:05 +0000 | 
| commit | 108759918557137be4317767b2db03d194bf3aaf (patch) | |
| tree | f9a3eb861b6237c778bc2afba88135474dc808fa /clang/utils | |
| parent | 7de154708ac97d803894c7129c90384e129f6acb (diff) | |
| download | bcm5719-llvm-108759918557137be4317767b2db03d194bf3aaf.tar.gz bcm5719-llvm-108759918557137be4317767b2db03d194bf3aaf.zip  | |
MultiTestRunner: Add module for lexing 'sh' commands.
llvm-svn: 77668
Diffstat (limited to 'clang/utils')
| -rw-r--r-- | clang/utils/test/ShUtil.py | 126 | 
1 files changed, 126 insertions, 0 deletions
diff --git a/clang/utils/test/ShUtil.py b/clang/utils/test/ShUtil.py new file mode 100644 index 00000000000..b8485b1596f --- /dev/null +++ b/clang/utils/test/ShUtil.py @@ -0,0 +1,126 @@ +import Util + +class ShLexer: +    def __init__(self, data): +        self.data = data +        self.pos = 0 +        self.end = len(data) + +    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 lex_arg(self, c): +        if c in "'\"": +            str = self.lex_arg_quoted(c) +        else: +            str = c +        while self.pos != self.end: +            c = self.look() +            if c.isspace() or c in "|><&": +                break +            elif c == '"': +                self.eat() +                str += self.lex_arg_quoted('"') +            else: +                str += self.eat() +        return str + +    def lex_arg_quoted(self, delim): +        str = '' +        while self.pos != self.end: +            c = self.eat() +            if c == delim: +                return str +            elif c == '\\' and delim == '"': +                # Shell escaping is just '\"' to avoid termination, no actual +                # escaping. +                if self.pos == self.end: +                    Util.warning("escape at end of quoted argument in: %r" %  +                                 self.data) +                    return str +                c = self.eat() +                if c != delim: +                    str += '\\' +                str += c +            else: +                str += c +        Util.warning("missing quote character in %r" % self.data) +        return str + +    def lex_one_token(self): +        """ +        lex_one_token - Lex a single 'sh' token. """ + +        c = self.eat() +        if c == ';': +            return (c) +        if c == '|': +            if self.maybe_eat('|'): +                return ('||',) +            return (c,) +        if c == '&': +            if self.maybe_eat('&'): +                return ('&&',) +            if self.maybe_eat('>'):  +                return ('&>',) +            return (c,) +        if c == '>': +            if self.maybe_eat('&'): +                return ('>&',) +            if self.maybe_eat('>'): +                return ('>>',) +            return (c,) +        if c == '<': +            if self.maybe_eat('&'): +                return ('<&',) +            if self.maybe_eat('>'): +                return ('<<',) +        return self.lex_arg(c) + +    def lex(self): +        while self.pos != self.end: +            if self.look().isspace(): +                self.eat() +            else: +                yield self.lex_one_token() + +### + +import unittest + +class TestShLexer(unittest.TestCase): +    def lex(self, str): +        return list(ShLexer(str).lex()) + +    def testops(self): +        self.assertEqual(self.lex('a2>c'), +                         ['a2', ('>',), 'c']) +        self.assertEqual(self.lex('a 2>c'), +                         ['a', '2', ('>',), 'c']) +         +    def testquoting(self): +        self.assertEqual(self.lex(""" 'a' """), +                         ['a']) +        self.assertEqual(self.lex(""" "hello\\"world" """), +                         ['hello"world']) +        self.assertEqual(self.lex(""" "hello\\'world" """), +                         ["hello\\'world"]) +        self.assertEqual(self.lex(""" he"llo wo"rld """), +                         ["hello world"]) + +if __name__ == '__main__': +    unittest.main()  | 

