# A generic class to build line-oriented command interpreters
#
# Interpreters constructed with this class obey the following conventions:
#
# 1. End of file on input is processed as the command 'EOF'.
# 2. A command is parsed out of each line by collecting the prefix composed
#    of characters in the identchars member.
# 3. A command `foo' is dispatched to a method 'do_foo()'; the do_ method
#    is passed a single argument consisting of the remainder of the line.
# 4. Typing an empty line repeats the last command.  (Actually, it calls the
#    method `emptyline', which may be overridden in a subclass.)
# 5. There is a predefined `help' method.  Given an argument `topic', it
#    calls the command `help_topic'.  With no arguments, it lists all topics
#    with defined help_ functions, broken into up to three topics; documented
#    commands, miscellaneous help topics, and undocumented commands.
# 6. The command '?' is a synonym for `help'.  The command '!' is a synonym
#    for `shell', if a do_shell method exists.
#
# The `default' method may be overridden to intercept commands for which there
# is no do_ method.
#
# The data member `self.ruler' sets the character used to draw separator lines
# in the help messages.  If empty, no ruler line is drawn.  It defaults to "=".
#
# If the value of `self.intro' is nonempty when the cmdloop method is called,
# it is printed out on interpreter startup.  This value may be overridden
# via an optional argument to the cmdloop() method.
#
# The data members `self.doc_header', `self.misc_header', and
# `self.undoc_header' set the headers used for the help function's
# listings of documented functions, miscellaneous topics, and undocumented
# functions respectively.
#
# These interpreters use raw_input; thus, if the readline module is loaded,
# they automatically support Emacs-like command history and editing features.
#

import string
import sys
import linecache

PROMPT = '(Cmd) '
IDENTCHARS = string.letters + string.digits + '_'

class Cmd:
	prompt = PROMPT
	identchars = IDENTCHARS
	ruler = '='
	lastcmd = ''
	intro = None
	doc_header = "Documented commands (type help <topic>):"
	misc_header = "Miscellaneous help topics:"
	undoc_header = "Undocumented commands:"

	def __init__(self): pass

	def cmdloop(self, intro=None):
		self.preloop()
		if intro != None:
			self.intro = intro
		if self.intro:
			print self.intro
		stop = None
		while not stop:
			try:
				line = raw_input(self.prompt)
			except EOFError:
				line = 'EOF'
			self.precmd()
			stop = self.onecmd(line)
			self.postcmd()
		self.postloop()

	def precmd(self):
		pass

	def postcmd(self):
		pass

	def preloop(self):
		pass

	def postloop(self):
		pass

	def onecmd(self, line):
		line = string.strip(line)
		if line == '?':
			line = 'help'
		elif line == '!':
			if hasattr(self, 'do_shell'):
				line = 'shell'
			else:
				self.default(line)
				return
		elif not line:
			self.emptyline()
			return
		self.lastcmd = line
		i, n = 0, len(line)
		while i < n and line[i] in self.identchars: i = i+1
		cmd, arg = line[:i], string.strip(line[i:])
		if cmd == '':
			return self.default(line)
		else:
			try:
				func = getattr(self, 'do_' + cmd)
			except AttributeError:
				return self.default(line)
			return func(arg)

	def emptyline(self):
		return self.onecmd(self.lastcmd)

	def default(self, line):
		print '*** Unknown syntax:', line

	def do_help(self, arg):
		if arg:
			# XXX check arg syntax
			try:
				func = getattr(self, 'help_' + arg)
			except:
				print '*** No help on', `arg`
				return
			func()
		else:
			names = dir(self.__class__)
			cmds_doc = []
			cmds_undoc = []
			help = {}
			for name in names:
				if name[:5] == 'help_':
					help[name[5:]]=1
			for name in names:
				if name[:3] == 'do_':
					cmd=name[3:]
					if help.has_key(cmd):
						cmds_doc.append(cmd)
						del help[cmd]
					else:
						cmds_undoc.append(cmd)
			print 
			self.print_topics(self.doc_header,   cmds_doc,   15,80)
			self.print_topics(self.misc_header,  help.keys(),15,80)
			self.print_topics(self.undoc_header, cmds_undoc, 15,80)

	def print_topics(self, header, cmds, cmdlen, maxcol):
		if cmds:
			print header;
			if self.ruler:
			    print self.ruler * len(header)
			(cmds_per_line,junk)=divmod(maxcol,cmdlen)
			col=cmds_per_line
			for cmd in cmds:
				if col==0: print
				print (("%-"+`cmdlen`+"s") % cmd),
				col = (col+1) % cmds_per_line
			print "\n"
