Commit 84647964 authored by Seblu's avatar Seblu
Browse files

lexer handle quoting

read from argline like stdin
fix bug on debuging
parent 1e4aa1e2
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -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))
+43 −40
Original line number Diff line number Diff line
@@ -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,49 +68,45 @@ 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()
        except BadArgument, e:
            if 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
+4 −2
Original line number Diff line number Diff line
@@ -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):