Skip to content
Snippets Groups Projects
Commit 84647964 authored by Seblu's avatar Seblu
Browse files

lexer handle quoting

read from argline like stdin
fix bug on debuging
parent 1e4aa1e2
No related branches found
No related tags found
No related merge requests found
......@@ -13,7 +13,7 @@ import pprint
import re
import warnings
from cccli import version, debug
import cccli
from cccli.cli import Cli
from cccli.printer import Printer
from cccli.exception import *
......@@ -51,7 +51,7 @@ try:
# Parse line argument
oparser = optparse.OptionParser(usage="usage: %prog [options] [commands]",
version=version)
version=cccli.version)
oparser.add_option("-d", "--debug",
action="store_true",
dest="debug",
......@@ -98,7 +98,7 @@ try:
# debug stuff
if "debug" in settings:
debug = bool(settings["debug"])
cccli.debug = bool(settings["debug"])
else:
warnings.filterwarnings("ignore")
printer.debug("Debugging on")
......@@ -131,9 +131,8 @@ except BadArgument, e:
except KeyboardInterrupt:
exit(1)
except Exception, e:
if debug:
if cccli.debug:
printer.fatal(str(e), exitcode=-1)
raise
printer.warn("This is a not expected error, please report it!")
printer.fatal(str(e))
......@@ -9,6 +9,8 @@ import os, os.path
import sys
import re
import subprocess
import shlex
import StringIO
from cccli import version, debug
from cccli.command import Command, Alias
......@@ -21,37 +23,38 @@ from sjrpc.core.exceptions import *
class Cli(object):
def __init__(self, settings):
self.isinteractive = sys.stderr.isatty() and sys.stdin.isatty()
self.settings = settings
self.prompt = "> "
self.prompt = ""
self.rpc = None
self.printer = None
self.alias = Alias()
def start(self, line=""):
'''Start a CLI'''
# not interactive if command line
# line stuff
if line:
self.isinteractive = False
sys.stdin = StringIO.StringIO(line)
# set interactive mode
self.interactive = sys.stderr.isatty() and sys.stdin.isatty()
# start printer and load history
self.printer = Printer(self.isinteractive)
self.printer = Printer(self.interactive)
self.printer.history.load(self.settings.get("history", ""))
self.printer.history.maxsize(self.settings.get("hsize", None))
# load alias
self.alias.load(self.settings.get("alias", ""))
# print debug
self.printer.debug("Interactive: %s"%self.interactive)
self.printer.debug("Alias: %s"%self.alias)
self.printer.debug("Loaded history: %s"%len(self.printer.history))
# Connecting
self._connect()
# authentifications
self._auth()
# run parsing args
if line:
self._parse_line(line)
else:
self._shell()
# Parsing
self._parse()
# save history
self.printer.history.save(self.settings.get("history", ""))
def _connect(self):
self.printer.debug("Connecting...")
rpcc = SimpleRpcClient.from_addr(self.settings["server"],
......@@ -65,50 +68,46 @@ class Cli(object):
self.rpc = ConnectionProxy(rpcc)
def _auth(self):
'''Handle server authentification'''
self.printer.debug("Authenticating...")
if self.rpc.authentify(self.settings["login"], self.settings["pass"]):
self.printer.debug("Authenticated.")
else:
self.printer.fatal("Autentification failed!")
def _shell(self):
'''Shell parser'''
def _parse(self):
'''Parse a line'''
prompt = "> " if self.interactive else ""
while True:
try:
line = self.printer.getline(self.prompt)
self._parse_line(line)
argv = shlex.split(self.printer.getline(prompt), comments=True)
# alias subsitution
if argv[0] in self.alias:
argv[0] = self.alias[argv[0]]
except ValueError, e:
self.printer.error("Lexer: %s"%str(e))
continue
except EOFError:
self.printer.out("")
break
except SystemExit:
break
except KeyboardInterrupt:
self.printer.out("")
self.printer.out("Tcho!")
self._exec_command(argv)
if self.interactive:
self.printer.out("tcho!")
def _parse_line(self, line):
'''Parse a line (more than one command)'''
for cmd in line.split(";"):
if (cmd.strip() == "" or cmd[0] == "#"):
continue
elif (cmd[0] == "!"):
p = subprocess.Popen(cmd[1:], close_fds=True, shell=True)
def _exec_command(self, argv):
'''Execute command'''
try:
if (argv[0] == "!"):
p = subprocess.Popen(argv[1:], close_fds=True, shell=True)
p.wait()
ret = p.returncode
elif (cmd[0] == "?"):
elif (argv[0] == "?"):
Command(["help"], self).call()
else:
self._parse_command(cmd)
def _parse_command(self, cmd):
try:
# lex command
argv = self._lex_argv(cmd)
# alias subs
if argv[0] in self.alias:
argv[0] = self.alias[argv[0]]
# execute command
Command(argv, self).call()
Command(argv, self).call()
except BadArgument, e:
if str(e):
self.printer.error("Bad argument: %s."%str(e))
......@@ -129,10 +128,6 @@ class Cli(object):
if debug: raise
self.printer.error("%s: %s."%(argv[0], str(e)))
def _lex_argv(self, string):
'''Lex command argument'''
return string.split(" ")
class CliHandler(RpcHandler):
'''Handle RPC incoming request'''
......@@ -144,3 +139,11 @@ class CliHandler(RpcHandler):
@pure
def quit(self, rpc=None):
self.printer.fatal("Disconnected from server!")
class CliLexer(object):
def __init__(self, fd):
self.fd = fd
def get_next_token(self):
pass
......@@ -9,7 +9,7 @@ import sys
import os
import getpass
from cccli import debug
import cccli
color = {
# regular
......@@ -80,7 +80,7 @@ class Printer(object):
nl)
def debug(self, message, fd=sys.stderr, nl=os.linesep):
if debug:
if cccli.debug:
self.out(message, fd, nl)
def getline(self, msg, history=True):
......@@ -119,6 +119,8 @@ class History(object):
yield self.readline.get_history_item(i)
def __len__(self):
if self.readline is None:
return 0
return self.readline.get_current_history_length()
def load(self, path):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment