| class Command: | |
| def __init__(self, args, redirects): | |
| self.args = list(args) | |
| self.redirects = list(redirects) | |
| def __repr__(self): | |
| return 'Command(%r, %r)' % (self.args, self.redirects) | |
| def __cmp__(self, other): | |
| if not isinstance(other, Command): | |
| return -1 | |
| return cmp((self.args, self.redirects), | |
| (other.args, other.redirects)) | |
| def toShell(self, file): | |
| for arg in self.args: | |
| if "'" not in arg: | |
| quoted = "'%s'" % arg | |
| elif '"' not in arg and '$' not in arg: | |
| quoted = '"%s"' % arg | |
| else: | |
| raise NotImplementedError,'Unable to quote %r' % arg | |
| print >>file, quoted, | |
| # For debugging / validation. | |
| import ShUtil | |
| dequoted = list(ShUtil.ShLexer(quoted).lex()) | |
| if dequoted != [arg]: | |
| raise NotImplementedError,'Unable to quote %r' % arg | |
| for r in self.redirects: | |
| if len(r[0]) == 1: | |
| print >>file, "%s '%s'" % (r[0][0], r[1]), | |
| else: | |
| print >>file, "%s%s '%s'" % (r[0][1], r[0][0], r[1]), | |
| class Pipeline: | |
| def __init__(self, commands, negate=False, pipe_err=False): | |
| self.commands = commands | |
| self.negate = negate | |
| self.pipe_err = pipe_err | |
| def __repr__(self): | |
| return 'Pipeline(%r, %r, %r)' % (self.commands, self.negate, | |
| self.pipe_err) | |
| def __cmp__(self, other): | |
| if not isinstance(other, Pipeline): | |
| return -1 | |
| return cmp((self.commands, self.negate, self.pipe_err), | |
| (other.commands, other.negate, self.pipe_err)) | |
| def toShell(self, file, pipefail=False): | |
| if pipefail != self.pipe_err: | |
| raise ValueError,'Inconsistent "pipefail" attribute!' | |
| if self.negate: | |
| print >>file, '!', | |
| for cmd in self.commands: | |
| cmd.toShell(file) | |
| if cmd is not self.commands[-1]: | |
| print >>file, '|\n ', | |
| class Seq: | |
| def __init__(self, lhs, op, rhs): | |
| assert op in (';', '&', '||', '&&') | |
| self.op = op | |
| self.lhs = lhs | |
| self.rhs = rhs | |
| def __repr__(self): | |
| return 'Seq(%r, %r, %r)' % (self.lhs, self.op, self.rhs) | |
| def __cmp__(self, other): | |
| if not isinstance(other, Seq): | |
| return -1 | |
| return cmp((self.lhs, self.op, self.rhs), | |
| (other.lhs, other.op, other.rhs)) | |
| def toShell(self, file, pipefail=False): | |
| self.lhs.toShell(file, pipefail) | |
| print >>file, ' %s\n' % self.op | |
| self.rhs.toShell(file, pipefail) |