2008-06-13 20:17:25 -04:00
|
|
|
#!/usr/bin/env python
|
2008-05-26 23:57:09 -04:00
|
|
|
import code
|
|
|
|
import optparse
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import StringIO
|
|
|
|
import traceback
|
|
|
|
|
|
|
|
class EPython(object):
|
|
|
|
def __init__(self, globals_, locals_):
|
|
|
|
self.lines = []
|
|
|
|
self.globals = globals_
|
|
|
|
self.locals = locals_
|
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
self.lines = []
|
|
|
|
|
|
|
|
def prompt(self):
|
|
|
|
if self.lines:
|
|
|
|
return "PROMPT:..>"
|
|
|
|
else:
|
|
|
|
return "PROMPT:>>>"
|
|
|
|
|
|
|
|
def handle(self, line):
|
|
|
|
if line.startswith('ENTER:'):
|
|
|
|
self.push(line[6:-1])
|
|
|
|
elif line.startswith('COMPLETE:'):
|
|
|
|
self.complete(line[9:-1])
|
|
|
|
else:
|
|
|
|
print "ERROR:invalid input"
|
|
|
|
|
|
|
|
def complete(self, s):
|
|
|
|
candidates = []
|
|
|
|
names = s.split('.')
|
|
|
|
obj = None
|
|
|
|
i = 0
|
|
|
|
name = names[0]
|
|
|
|
if len(names) > 1:
|
|
|
|
while i < len(names):
|
|
|
|
name = names[i]
|
|
|
|
if obj is None:
|
|
|
|
if name in self.locals:
|
|
|
|
obj = self.locals[name]
|
|
|
|
elif name in self.globals:
|
|
|
|
obj = self.globals[name]
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
if hasattr(obj, name):
|
|
|
|
obj = getattr(obj, name)
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
i += 1
|
|
|
|
|
|
|
|
if i == len(names) - 1:
|
|
|
|
base = '.'.join(names[:-1])
|
|
|
|
if base:
|
|
|
|
base += '.'
|
|
|
|
if obj is not None:
|
|
|
|
newnames = dir(obj)
|
|
|
|
else:
|
|
|
|
newnames = set()
|
|
|
|
newnames.update(dir(__builtins__))
|
|
|
|
newnames.update(self.locals)
|
|
|
|
newnames.update(self.globals)
|
|
|
|
candidates = [base + x for x in newnames if x.startswith(name)]
|
|
|
|
print "COMPLETIONS:%s" % ('|'.join(candidates))
|
|
|
|
|
|
|
|
def push(self, s):
|
|
|
|
self.lines.append(s)
|
|
|
|
s2 = '\n'.join(self.lines)
|
|
|
|
try:
|
|
|
|
code_obj = code.compile_command(s2)
|
|
|
|
if code_obj is None:
|
|
|
|
return
|
|
|
|
try:
|
|
|
|
exec code_obj in self.globals, self.locals
|
|
|
|
except Exception, e:
|
|
|
|
print str(e) + "\n" + traceback.format_exc()
|
|
|
|
except (SyntaxError, OverflowError, ValueError), e:
|
|
|
|
print str(e) + "\n" + traceback.format_exc()
|
|
|
|
self.reset()
|
|
|
|
|
|
|
|
def main(self):
|
|
|
|
while True:
|
|
|
|
print '\n' + self.prompt()
|
|
|
|
sys.stdout.flush()
|
|
|
|
line = sys.stdin.readline()
|
|
|
|
if not line:
|
|
|
|
break
|
|
|
|
self.handle(line)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
stanzas = []
|
|
|
|
def add_eval(option, opt, value, parser):
|
|
|
|
stanzas.append(('eval', value))
|
|
|
|
def add_path(option, opt, value, parser):
|
|
|
|
stanzas.append(('path', value))
|
|
|
|
parser = optparse.OptionParser()
|
|
|
|
parser.add_option('-e', '--eval', type='string', action='callback', callback=add_eval)
|
2008-05-28 11:42:40 -04:00
|
|
|
parser.add_option('-r', '--run', type='string', action='callback', callback=add_path)
|
|
|
|
parser.add_option('-p', '--pipe', action='store_true')
|
2008-05-26 23:57:09 -04:00
|
|
|
parser.parse_args()
|
|
|
|
del parser, add_path, add_eval
|
|
|
|
|
|
|
|
__EP = EPython(globals_=globals(), locals_=locals())
|
|
|
|
sys.path.insert(0, os.getcwd())
|
|
|
|
for (type_, value) in stanzas:
|
|
|
|
#break
|
|
|
|
if type_ == 'eval':
|
|
|
|
exec value in __EP.globals, __EP.locals
|
|
|
|
__EP.push(value)
|
|
|
|
elif type_ == 'path':
|
|
|
|
f = open(value, 'r')
|
|
|
|
exec f in __EP.globals, __EP.locals
|
|
|
|
f.close()
|
|
|
|
else:
|
|
|
|
raise Exception, 'how can this happen?'
|
|
|
|
del stanzas
|
|
|
|
|
|
|
|
__EP.reset()
|
|
|
|
__EP.main()
|