#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # gameshell.py # # Copyright 2018 chees # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. # # Ver. 0.1.0017 import types as _types import traceback as _tb class Shell(object): def __init__(self): self.__commands = {'exit': self.exitShell} self.__aliases = {} self.ps1 = '> ' self.ps2 = '> ' self.__exit = False def run(self): """The main game/shell loop""" while not self.__exit: print(self.ps1, end = '') command = self.scanInput() # we have to handle shell built-ins first (when we get some) if len(command) == 0: continue if command[0] in self.__commands: try: self.__commands[command[0]](command[1:]) except Exception as e: _tb.print_exc() print(e) else: self.handleUnknownCommand(command) self.update() def man(self, args): help(self.__commands[args[0]]) def registerCommand(self, commandName: str, command: _types.FunctionType): """command must be a function that takes one argument: a list of strings, conventionally called args or argv""" self.__commands[commandName] = command def registerAlias(self, a: str, original: list): """makes 'a' an alias for original. 'a' must be one token, but original can be multiple.""" self.__aliases[a] = original def getAlias(self, a: str): if a in self.__aliases: return self.__aliases[a] else: return None def exitShell(self, args): """The default exit command.""" self.__exit = True # Beyond this point are functions that are called within the main loop. def scanInput(self): """Parses input. Override this for custom input parsing, or input source.""" ret = input() if ret == '': return [] ret = ret.split() a = self.getAlias(ret[0]) if a: ret = a[:] + ret[1:] return ret def handleUnknownCommand(self, command): """Handle commands that aren't registered. Override this if you want to do something with those commands.""" print("Bad command.") def update(self): """Runs at the end of each loop. Does nothing by default. Override this if there is something you want the shell to do between every command.""" pass def main(args): return 0 if __name__ == '__main__': import sys sys.exit(main(sys.argv))