| #!/usr/bin/env python |
| # -*- coding: iso-8859-1 -*- |
| # |
| # $Id: 4924bbb91e59566666746c62bd76c59e178b4b6a $ |
| |
| """ |
| Configuration classes for *sqlcmd*. |
| |
| COPYRIGHT AND LICENSE |
| |
| Copyright © 2008 Brian M. Clapper |
| |
| This is free software, released under the following BSD-like license: |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are met: |
| |
| 1. Redistributions of source code must retain the above copyright notice, |
| this list of conditions and the following disclaimer. |
| |
| 2. The end-user documentation included with the redistribution, if any, |
| must include the following acknowlegement: |
| |
| This product includes software developed by Brian M. Clapper |
| (bmc@clapper.org, http://www.clapper.org/bmc/). That software is |
| copyright © 2008 Brian M. Clapper. |
| |
| Alternately, this acknowlegement may appear in the software itself, if |
| and wherever such third-party acknowlegements normally appear. |
| |
| THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
| EVENT SHALL BRIAN M. CLAPPER BE LIABLE FOR ANY DIRECT, INDIRECT, |
| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| $Id: 4924bbb91e59566666746c62bd76c59e178b4b6a $ |
| """ |
| |
| # --------------------------------------------------------------------------- |
| # Imports |
| # --------------------------------------------------------------------------- |
| |
| from cmd import Cmd |
| import logging |
| import os |
| import sys |
| |
| # --------------------------------------------------------------------------- |
| # Exports |
| # --------------------------------------------------------------------------- |
| |
| __all__ = ['ECmd'] |
| |
| # --------------------------------------------------------------------------- |
| # Constants |
| # --------------------------------------------------------------------------- |
| |
| # --------------------------------------------------------------------------- |
| # Globals |
| # --------------------------------------------------------------------------- |
| |
| log = logging.getLogger('sqlcmd.ecmd') |
| |
| # --------------------------------------------------------------------------- |
| # Classes |
| # --------------------------------------------------------------------------- |
| |
| class ECmd(Cmd): |
| """ |
| Slightly enhanced version of ``cmd.Cmd`` that changes the command loop |
| a little to handle SIGINT more appropriately. |
| """ |
| def __init__(self, completekey='tab', stdin=None, stdout=None): |
| """ |
| Instantiate a line-oriented interpreter framework. |
| |
| The optional argument 'completekey' is the readline name of a |
| completion key; it defaults to the Tab key. If completekey is |
| not None and the readline module is available, command completion |
| is done automatically. The optional arguments stdin and stdout |
| specify alternate input and output file objects; if not specified, |
| sys.stdin and sys.stdout are used. |
| |
| """ |
| Cmd.__init__(self, completekey, stdin, stdout) |
| |
| def interrupted(self): |
| """ |
| Called by ``cmdloop`` on interrupt. |
| """ |
| pass |
| |
| def cmdloop(self, intro=None): |
| """ |
| Repeatedly issue a prompt, accept input, parse an initial prefix |
| off the received input, and dispatch to action methods, passing them |
| the remainder of the line as argument. |
| |
| This version is a direct rip-off of the parent class's ``cmdloop()`` |
| method, with some changes to support SIGINT properly. |
| """ |
| self.preloop() |
| if self.use_rawinput and self.completekey: |
| try: |
| import readline |
| self.old_completer = readline.get_completer() |
| readline.set_completer(self.complete) |
| readline.parse_and_bind(self.completekey+": complete") |
| except ImportError: |
| pass |
| try: |
| if intro is not None: |
| self.intro = intro |
| if self.intro: |
| self.stdout.write(str(self.intro)+"\n") |
| stop = None |
| while not stop: |
| try: |
| if self.cmdqueue: |
| line = self.cmdqueue.pop(0) |
| else: |
| line = self.get_input(self.prompt) |
| |
| line = self.precmd(line) |
| stop = self.onecmd(line) |
| stop = self.postcmd(stop, line) |
| except KeyboardInterrupt: |
| self.interrupted() |
| |
| self.postloop() |
| finally: |
| if self.use_rawinput and self.completekey: |
| try: |
| import readline |
| readline.set_completer(self.old_completer) |
| except ImportError: |
| pass |
| |
| def get_input(self, prompt): |
| if self.use_rawinput: |
| try: |
| line = raw_input(self.prompt) |
| except EOFError: |
| line = 'EOF' |
| else: |
| self.stdout.write(self.prompt) |
| self.stdout.flush() |
| line = self.stdin.readline() |
| if not len(line): |
| line = 'EOF' |
| else: |
| line = line[:-1] # chop \n |
| |
| return line |
| |