Added a _v21 def to FL.py and added two new input field types
Added runcall(func, *args) interfaces to profile.py, bdb.py, pdb.py, wdb.py
Added new module bisect.py and used it in sched.py.
Mostly cosmetic changes to profile.py (changed output format).
diff --git a/Lib/bdb.py b/Lib/bdb.py
index 15a8023..8a722fe 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -68,7 +68,7 @@
 		return self.trace_dispatch
 	
 	# Normally derived classes don't override the following
-	# functions, but they may if they want to redefine the
+	# methods, but they may if they want to redefine the
 	# definition of stopping and breakpoints.
 	
 	def stop_here(self, frame):
@@ -93,28 +93,28 @@
 	def break_anywhere(self, frame):
 		return self.breaks.has_key(frame.f_code.co_filename)
 	
-	# Derived classes should override the user_* functions
+	# Derived classes should override the user_* methods
 	# to gain control.
 	
 	def user_call(self, frame, argument_list):
-		# This function is called when there is the remote possibility
+		# This method is called when there is the remote possibility
 		# that we ever need to stop in this function
 		pass
 	
 	def user_line(self, frame):
-		# This function is called when we stop or break at this line
+		# This method is called when we stop or break at this line
 		pass
 	
 	def user_return(self, frame, return_value):
-		# This function is called when a return trap is set here
+		# This method is called when a return trap is set here
 		pass
 	
 	def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
-		# This function is called if an exception occurs,
+		# This method is called if an exception occurs,
 		# but only if we are to stop at or just below this level
 		pass
 	
-	# Derived classes and clients can call the following functions
+	# Derived classes and clients can call the following methods
 	# to affect the stepping state.
 	
 	def set_step(self):
@@ -147,8 +147,8 @@
 		self.quitting = 1
 		sys.settrace(None)
 	
-	# Derived classes and clients can call the following functions
-	# to manipulate breakpoints.  These functions return an
+	# Derived classes and clients can call the following methods
+	# to manipulate breakpoints.  These methods return an
 	# error message is something went wrong, None if all is well.
 	# Call self.get_*break*() to see the breakpoints.
 	
@@ -196,7 +196,7 @@
 	def get_all_breaks(self):
 		return self.breaks
 	
-	# Derived classes and clients can call the following function
+	# Derived classes and clients can call the following method
 	# to get a data structure representing a stack trace.
 	
 	def get_stack(self, f, t):
@@ -234,7 +234,7 @@
 		if line: s = s + ': ' + string.strip(line)
 		return s
 	
-	# The following two functions can be called by clients to use
+	# The following two methods can be called by clients to use
 	# a debugger to debug a statement, given as a string.
 	
 	def run(self, cmd):
@@ -253,7 +253,20 @@
 		finally:
 			self.quitting = 1
 			sys.settrace(None)
-		# XXX What to do if the command finishes normally?
+
+	# This method is more useful to debug a single function call.
+
+	def runcall(self, func, *args):
+		self.reset()
+		sys.settrace(self.trace_dispatch)
+		try:
+			try:
+				apply(func, args)
+			except BdbQuit:
+				pass
+		finally:
+			self.quitting = 1
+			sys.settrace(None)
 
 
 # -------------------- testing --------------------
diff --git a/Lib/bisect.py b/Lib/bisect.py
new file mode 100644
index 0000000..688666a
--- /dev/null
+++ b/Lib/bisect.py
@@ -0,0 +1,23 @@
+# Bisection algorithms
+
+
+# Insert item x in list a, and keep it sorted assuming a is sorted
+
+def insort(a, x):
+        lo, hi = 0, len(a)
+        while lo < hi:
+		mid = (lo+hi)/2
+		if x < a[mid]: hi = mid
+		else: lo = mid+1
+	a.insert(lo, x)
+
+
+# Find the index where to insert item x in list a, assuming a is sorted
+
+def bisect(a, x):
+        lo, hi = 0, len(a)
+        while lo < hi:
+		mid = (lo+hi)/2
+		if x < a[mid]: hi = mid
+		else: lo = mid+1
+	return lo
diff --git a/Lib/irix5/FL.py b/Lib/irix5/FL.py
index 3142b1b..65184df 100755
--- a/Lib/irix5/FL.py
+++ b/Lib/irix5/FL.py
@@ -4,6 +4,7 @@
 # Alternate use: from FL import *; ... NORMAL_BOX ... etc.
 
 _v20 = 1
+_v21 = 1
 ##import fl
 ##try:
 ##	_v20 = (fl.get_rgbmode <> None)
@@ -198,6 +199,9 @@
 	FLOAT_INPUT = 1
 	INT_INPUT = 2
 	HIDDEN_INPUT = 3
+	if _v21:
+		MULTILINE_INPUT = 4
+		SECRET_INPUT = 5
 else:
 	ALWAYS_INPUT = 1
 INPUT_BOXTYPE = DOWN_BOX
diff --git a/Lib/lib-stdwin/wdb.py b/Lib/lib-stdwin/wdb.py
index 9914f3f..b3d6b73 100644
--- a/Lib/lib-stdwin/wdb.py
+++ b/Lib/lib-stdwin/wdb.py
@@ -283,6 +283,11 @@
 	try: x.runctx(statement, globals, locals)
 	finally: x.close()
 
+def runcall(*args):
+	x = Wdb().init()
+	try: apply(Pdb().init().runcall, args)
+	finally: x.close()
+
 TESTCMD = 'import x; x.main()'
 
 def test():
diff --git a/Lib/pdb.py b/Lib/pdb.py
index 0dd975b..f564f64 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -254,6 +254,9 @@
 def runctx(statement, globals, locals):
 	Pdb().init().runctx(statement, globals, locals)
 
+def runcall(*args):
+	apply(Pdb().init().runcall, args)
+
 TESTCMD = 'import x; x.main()'
 
 def test():
diff --git a/Lib/plat-irix5/FL.py b/Lib/plat-irix5/FL.py
index 3142b1b..65184df 100755
--- a/Lib/plat-irix5/FL.py
+++ b/Lib/plat-irix5/FL.py
@@ -4,6 +4,7 @@
 # Alternate use: from FL import *; ... NORMAL_BOX ... etc.
 
 _v20 = 1
+_v21 = 1
 ##import fl
 ##try:
 ##	_v20 = (fl.get_rgbmode <> None)
@@ -198,6 +199,9 @@
 	FLOAT_INPUT = 1
 	INT_INPUT = 2
 	HIDDEN_INPUT = 3
+	if _v21:
+		MULTILINE_INPUT = 4
+		SECRET_INPUT = 5
 else:
 	ALWAYS_INPUT = 1
 INPUT_BOXTYPE = DOWN_BOX
diff --git a/Lib/profile.py b/Lib/profile.py
index 1c7a6e2..046b70b 100755
--- a/Lib/profile.py
+++ b/Lib/profile.py
@@ -1,12 +1,16 @@
 #
 # Class for profiling python code.
 # Author: Sjoerd Mullender
+# Hacked somewhat by: Guido van Rossum
 #
 # See the accompanying document profile.doc for more information.
 
 import sys
 import codehack
-import posix
+import os
+import string
+import fpformat
+import marshal
 
 class Profile():
 
@@ -30,7 +34,7 @@
 				if self.profile_func.has_key(funcname):
 					return
 				self.profiling = 1
-			t = posix.times()
+			t = os.times()
 			t = t[0] + t[1]
 			lineno = codehack.getlineno(frame.f_code)
 			filename = frame.f_code.co_filename
@@ -42,13 +46,16 @@
 				s0 = 'call: ' + key + ' depth: ' + `self.call_level` + ' time: ' + `t`
 			if pframe:
 				pkey = pframe.f_code.co_filename + ':' + \
-					  `codehack.getlineno(pframe.f_code)` + '(' + \
-					  codehack.getcodename(pframe.f_code) + ')'
+					  `codehack.getlineno(pframe.f_code)` \
+					  + '(' + \
+					  codehack.getcodename(pframe.f_code) \
+					  + ')'
 				if self.debug:
 					s1 = 'parent: ' + pkey
 				if pframe.f_locals.has_key('__start_time'):
 					st = pframe.f_locals['__start_time']
-					nc, tt, ct, callers, callees = self.timings[pkey]
+					nc, tt, ct, callers, callees = \
+						self.timings[pkey]
 					if self.debug:
 						s1 = s1+' before: st='+`st`+' nc='+`nc`+' tt='+`tt`+' ct='+`ct`
 					if callers.has_key(key):
@@ -80,7 +87,8 @@
 			if self.profile_func:
 				if not self.profiling:
 					return
-				if self.profile_func.has_key(codehack.getcodename(frame.f_code)):
+				if self.profile_func.has_key( \
+					codehack.getcodename(frame.f_code)):
 					self.profiling = 0
 			self.call_level = depth(frame)
 			self.cur_frame = frame
@@ -106,11 +114,12 @@
 			self.call_level = call_level
 			self.cur_frame = frame
 			return
-		print 'profile.Profile.dispatch: unknown debugging event:', `event`
+		print 'profile.Profile.dispatch: unknown debugging event:',
+		print `event`
 		return
 
 	def handle_return(self, pframe, frame, s0):
-		t = posix.times()
+		t = os.times()
 		t = t[0] + t[1]
 		funcname = codehack.getcodename(frame.f_code)
 		lineno = codehack.getlineno(frame.f_code)
@@ -128,11 +137,13 @@
 			if pframe.f_locals.has_key('__start_time') and \
 				  self.timings.has_key(pkey):
 				st = pframe.f_locals['__start_time']
-				nc, tt, ct, callers, callees = self.timings[pkey]
+				nc, tt, ct, callers, callees = \
+					self.timings[pkey]
 				if self.debug:
 					s1 = s1+' before: st='+`st`+' nc='+`nc`+' tt='+`tt`+' ct='+`ct`
 					s1 = s1+' after: st='+`t`+' nc='+`nc`+' tt='+`tt`+' ct='+`ct+(t-st)`
-				self.timings[pkey] = nc, tt, ct + (t - st), callers, callees
+				self.timings[pkey] = \
+					nc, tt, ct + (t - st), callers, callees
 				pframe.f_locals['__start_time'] = t
 		if self.timings.has_key(key):
 			nc, tt, ct, callers, callees = self.timings[key]
@@ -147,35 +158,30 @@
 			s0 = s0+' after: nc='+`nc`+' tt='+`tt+(t-st)`+' ct='+`ct+(t-st)`
 			print s0
 			print s1
-		self.timings[key] = nc, tt + (t - st), ct + (t - st), callers, callees
+		self.timings[key] = \
+			nc, tt + (t - st), ct + (t - st), callers, callees
 
 	def print_stats(self):
-		import string
-		s = string.rjust('# calls', 8)
-		s = s + ' ' + string.rjust('tot time', 8)
-		s = s + ' ' + string.rjust('per call', 8)
-		s = s + ' ' + string.rjust('cum time', 8)
-		s = s + ' ' + string.rjust('per call', 8)
-		print s + ' filename(function)'
+		# Print in reverse order by ct
+		print_title()
+		list = []
 		for key in self.timings.keys():
 			nc, tt, ct, callers, callees = self.timings[key]
 			if nc == 0:
 				continue
-			s = string.rjust(`nc`, 8)
-			s = s + ' ' + string.rjust(`tt`, 8)
-			s = s + ' ' + string.rjust(`tt/nc`, 8)
-			s = s + ' ' + string.rjust(`ct`, 8)
-			s = s + ' ' + string.rjust(`ct/nc`, 8)
-			print s + ' ' + key
+			list.append(ct, tt, nc, key)
+		list.sort()
+		list.reverse()
+		for ct, tt, nc, key in list:
+			print_line(nc, tt, ct, os.path.basename(key))
 
 	def dump_stats(self, file):
-		import marshal
 		f = open(file, 'w')
 		marshal.dump(self.timings, f)
 		f.close()
 
-	# The following two functions can be called by clients to use
-	# a debugger to debug a statement, given as a string.
+	# The following two methods can be called by clients to use
+	# a profiler to profile a statement, given as a string.
 	
 	def run(self, cmd):
 		import __main__
@@ -183,17 +189,21 @@
 		self.runctx(cmd, dict, dict)
 	
 	def runctx(self, cmd, globals, locals):
-##		self.reset()
 		sys.setprofile(self.trace_dispatch)
 		try:
-##			try:
-				exec(cmd + '\n', globals, locals)
-##			except ProfQuit:
-##				pass
+			exec(cmd + '\n', globals, locals)
 		finally:
-##			self.quitting = 1
 			sys.setprofile(None)
-		# XXX What to do if the command finishes normally?
+
+	# This method is more useful to profile a single function call.
+
+	def runcall(self, func, *args):
+		sys.setprofile(self.trace_dispatch)
+		try:
+			apply(func, args)
+		finally:
+			sys.setprofile(None)
+
 
 def depth(frame):
 	d = 0
@@ -202,98 +212,8 @@
 		frame = frame.f_back
 	return d
 
-def run(statement, *args):
-	prof = Profile().init()
-	try:
-		prof.run(statement)
-	except SystemExit:
-		pass
-	if len(args) == 0:
-		prof.print_stats()
-	else:
-		prof.dump_stats(args[0])
-
-def cv_float(val, width):
-	import string
-	s = `val`
-	try:
-		e = string.index(s, 'e')
-		exp = s[e+1:]
-		s = s[:e]
-		width = width - len(exp) - 1
-	except string.index_error:
-		exp = ''
-	try:
-		d = string.index(s, '.')
-		frac = s[d+1:]
-		s = s[:d]
-		width = width - len(s) - 1
-	except string.index_error:
-		if exp <> '':
-			return s + 'e' + exp
-		else:
-			return s
-	if width < 0:
-		width = 0
-	while width < len(frac):
-		c = frac[width]
-		frac = frac[:width]
-		if ord(c) >= ord('5'):
-			carry = 1
-			for i in range(width-1, -1, -1):
-				if frac[i] == '9':
-					frac = frac[:i]
-					# keep if trailing zeroes are wanted
-					# + '0' + frac[i+1:width]
-				else:
-					frac = frac[:i] + chr(ord(frac[i])+1) + frac[i+1:width]
-					carry = 0
-					break
-			if carry:
-				for i in range(len(s)-1, -1, -1):
-					if s[i] == '9':
-						s = s[:i] + '0' + s[i+1:]
-						if i == 0:
-							# gets one wider, so
-							# should shorten
-							# fraction by one
-							s = '1' + s
-							if width > 0:
-								width = width - 1
-					else:
-						s = s[:i] + chr(ord(s[i])+1) + s[i+1:]
-						break
-	# delete trailing zeroes
-	for i in range(len(frac)-1, -1, -1):
-		if frac[i] == '0':
-			frac = frac[:i]
-		else:
-			break
-	# build up the number
-	if width > 0 and len(frac) > 0:
-		s = s + '.' + frac[:width]
-	if exp <> '':
-		s = s + 'e' + exp
-	return s
-
-def print_line(nc, tt, ct, callers, callees, key):
-	import string
-	s = string.rjust(cv_float(nc,8), 8)
-	s = s + ' ' + string.rjust(cv_float(tt,8), 8)
-	if nc == 0:
-		s = s + ' '*9
-	else:
-		s = s + ' ' + string.rjust(cv_float(tt/nc,8), 8)
-	s = s + ' ' + string.rjust(cv_float(ct,8), 8)
-	if nc == 0:
-		s = s + ' '*9
-	else:
-		s = s + ' ' + string.rjust(cv_float(ct/nc,8), 8)
-	print s + ' ' + key
-
 class Stats():
 	def init(self, file):
-		import marshal
 		f = open(file, 'r')
 		self.stats = marshal.load(f)
 		f.close()
@@ -301,26 +221,22 @@
 		return self
 
 	def print_stats(self):
-		import string
-		s = string.rjust('# calls', 8)
-		s = s + ' ' + string.rjust('tot time', 8)
-		s = s + ' ' + string.rjust('per call', 8)
-		s = s + ' ' + string.rjust('cum time', 8)
-		s = s + ' ' + string.rjust('per call', 8)
-		print s + ' filename(function)'
+		print_title()
 		if self.stats_list:
 			for i in range(len(self.stats_list)):
-				nc, tt, ct, callers, callees, key = self.stats_list[i]
-				print_line(nc, tt, ct, callers, callees, key)
+				nc, tt, ct, callers, callees, key = \
+					self.stats_list[i]
+				print_line(nc, tt, ct, key)
 		else:
 			for key in self.stats.keys():
 				nc, tt, ct, callers, callees = self.stats[key]
-				print_line(nc, tt, ct, callers, callees, key)
+				print_line(nc, tt, ct, key)
 
 	def print_callers(self):
 		if self.stats_list:
 			for i in range(len(self.stats_list)):
-				nc, tt, ct, callers, callees, key = self.stats_list[i]
+				nc, tt, ct, callers, callees, key = \
+					self.stats_list[i]
 				print key,
 				for func in callers.keys():
 					print func+'('+`callers[func]`+')',
@@ -336,7 +252,8 @@
 	def print_callees(self):
 		if self.stats_list:
 			for i in range(len(self.stats_list)):
-				nc, tt, ct, callers, callees, key = self.stats_list[i]
+				nc, tt, ct, callers, callees, key = \
+					self.stats_list[i]
 				print key,
 				for func in callees.keys():
 					print func+'('+`callees[func]`+')',
@@ -375,8 +292,10 @@
 				nt = nt[:field] + t[0:1] + nt[field:]
 			self.stats_list.append(nt)
 
+	def reverse_order(self):
+		self.stats_list.reverse()
+
 	def strip_dirs(self):
-		import os
 		newstats = {}
 		for key in self.stats.keys():
 			nc, tt, ct, callers, callees = self.stats[key]
@@ -391,7 +310,44 @@
 		self.stats = newstats
 		self.stats_list = None
 
-# test command
+def print_title():
+	print string.rjust('ncalls', 8),
+	print string.rjust('tottime', 8),
+	print string.rjust('percall', 8),
+	print string.rjust('cumtime', 8),
+	print string.rjust('percall', 8),
+	print 'filename:lineno(function)'
+
+def print_line(nc, tt, ct, key):
+	print string.rjust(`nc`, 8),
+	print f8(tt),
+	if nc == 0:
+		print ' '*8,
+	else:
+		print f8(tt/nc),
+	print f8(ct),
+	if nc == 0:
+		print ' '*8,
+	else:
+		print f8(ct/nc),
+	print key
+
+def f8(x):
+	return string.rjust(fpformat.fix(x, 3), 8)
+
+# simplified user interface
+def run(statement, *args):
+	prof = Profile().init()
+	try:
+		prof.run(statement)
+	except SystemExit:
+		pass
+	if len(args) == 0:
+		prof.print_stats()
+	else:
+		prof.dump_stats(args[0])
+
+# test command with debugging
 def debug():
 	prof = Profile().init()
 	prof.debug = 1
@@ -401,5 +357,6 @@
 		pass
 	prof.print_stats()
 
+# test command
 def test():
 	run('import x; x.main()')
diff --git a/Lib/sched.py b/Lib/sched.py
index 4a45309..685b2bc 100644
--- a/Lib/sched.py
+++ b/Lib/sched.py
@@ -28,6 +28,8 @@
 # XXX instead of having to define a module or class just to hold
 # XXX the global state of your particular time and delay functtions.
 
+import bisect
+
 class scheduler:
 	#
 	# Initialize a new instance, passing the time and delay functions
@@ -43,16 +45,7 @@
 	# to remove it, if necessary.
 	#
 	def enterabs(self, event):
-		time, priority, action, argument = event
-		q = self.queue
-		# XXX Could use bisection or linear interpolation?
-		for i in range(len(q)):
-			qtime, qpri, qact, qarg = q[i]
-			if time < qtime: break
-			if time == qtime and priority < qpri: break
-		else:
-			i = len(q)
-		q.insert(i, event)
+		bisect.insort(self.queue, event)
 		return event # The ID
 	#
 	# A variant that specifies the time as a relative time.
diff --git a/Lib/stdwin/wdb.py b/Lib/stdwin/wdb.py
index 9914f3f..b3d6b73 100755
--- a/Lib/stdwin/wdb.py
+++ b/Lib/stdwin/wdb.py
@@ -283,6 +283,11 @@
 	try: x.runctx(statement, globals, locals)
 	finally: x.close()
 
+def runcall(*args):
+	x = Wdb().init()
+	try: apply(Pdb().init().runcall, args)
+	finally: x.close()
+
 TESTCMD = 'import x; x.main()'
 
 def test():