[Patches] pindent: eliminate "# end"-tags

Peter Schneider-Kamp peter@schneider-kamp.de
Mon, 29 May 2000 22:31:49 +0200


This is a multi-part message in MIME format.
--------------1BA7580EFB4ADADF51A557A3
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Problem:
A Python program can be completed and reformatted using
Tools/scripts/pindent.py. Unfortunately there is no option
for removal of the generated "# end"-tags.
Although a few Python commands or a "grep -v '# end '"
can do wonders here, there are two drawbacks:
- not everyone has grep/time to write a Python script
- it is not checked whether the "# end"-tags were used validly
  
Solution:
add extra option "-e" (eliminate) to pindent.py

patch attached as plaintext context diff
--
I confirm that, to the best of my knowledge and belief, this
contribution is free of any claims of third parties under
copyright, patent or other rights or interests ("claims").  To
the extent that I have any such claims, I hereby grant to CNRI a
nonexclusive, irrevocable, royalty-free, worldwide license to
reproduce, distribute, perform and/or display publicly, prepare
derivative versions, and otherwise use this contribution as part
of the Python software and its related documentation, or any
derivative versions thereof, at no cost to CNRI or its licensed
users, and to authorize others to do so.

I acknowledge that CNRI may, at its sole discretion, decide
whether or not to incorporate this contribution in the Python
software and its related documentation.  I further grant CNRI
permission to use my name and other identifying information
provided to CNRI by me for use in connection with the Python
software and its related documentation.
--
Peter Schneider-Kamp          ++47-7388-7331
Herman Krags veg 51-11        mailto:peter@schneider-kamp.de
N-7050 Trondheim              http://schneider-kamp.de
--------------1BA7580EFB4ADADF51A557A3
Content-Type: text/plain; charset=us-ascii;
 name="pindent.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="pindent.patch"

diff -c -b --recursive python/dist/src/Tools/scripts/pindent.py python-mod/dist/src/Tools/scripts/pindent.py
*** python/dist/src/Tools/scripts/pindent.py	Fri Jun 19 23:39:27 1998
--- python-mod/dist/src/Tools/scripts/pindent.py	Mon May 29 22:20:22 2000
***************
*** 1,10 ****
  #! /usr/bin/env python
  
! # This file contains a class and a main program that perform two
  # related (though complimentary) formatting operations on Python
! # programs.  When called as "pindend -c", it takes a valid Python
  # program as input and outputs a version augmented with block-closing
! # comments.  When called as "pindent -r" it assumes its input is a
  # Python program with block-closing comments but with its indentation
  # messed up, and outputs a properly indented version.
  
--- 1,12 ----
  #! /usr/bin/env python
  
! # This file contains a class and a main program that perform three
  # related (though complimentary) formatting operations on Python
! # programs.  When called as "pindent -c", it takes a valid Python
  # program as input and outputs a version augmented with block-closing
! # comments.  When called as "pindent -e", it assumes its input is a
! # Python program with block-closing comments and outputs a commentless
! # version.   When called as "pindent -r" it assumes its input is a
  # Python program with block-closing comments but with its indentation
  # messed up, and outputs a properly indented version.
  
***************
*** 34,44 ****
  # that indentation is not significant when interpreting block-closing
  # comments).
  
! # Both operations are idempotent (i.e. applied to their own output
  # they yield an identical result).  Running first "pindent -c" and
  # then "pindent -r" on a valid Python program produces a program that
  # is semantically identical to the input (though its indentation may
! # be different).
  
  # Other options:
  # -s stepsize: set the indentation step size (default 8)
--- 36,47 ----
  # that indentation is not significant when interpreting block-closing
  # comments).
  
! # The operations are idempotent (i.e. applied to their own output
  # they yield an identical result).  Running first "pindent -c" and
  # then "pindent -r" on a valid Python program produces a program that
  # is semantically identical to the input (though its indentation may
! # be different). Running "pindent -e" on that output produces a
! # program that only differs from the original in indentation.
  
  # Other options:
  # -s stepsize: set the indentation step size (default 8)
***************
*** 193,198 ****
--- 196,245 ----
  		# end if
  	# end def reformat
  	
+ 	def eliminate(self):
+ 		stack = []
+ 		while 1:
+ 			line = self.getline()
+ 			if not line: break	# EOF
+ 			# end if
+ 			m = self.endprog.match(line)
+ 			if m:
+ 				kw = 'end'
+ 				kw2 = m.group('kw')
+ 				if not stack:
+ 					self.error('unexpected end')
+ 				elif stack[-1][0] != kw2:
+ 					self.error('unmatched end')
+ 				# end if
+ 				del stack[-1:]
+ 				#self.putline(line, len(stack))
+ 				continue
+ 			# end if
+ 			m = self.kwprog.match(line)
+ 			if m:
+ 				kw = m.group('kw')
+ 				if kw in start:
+ 					self.putline(line, len(stack))
+ 					stack.append((kw, kw))
+ 					continue
+ 				# end if
+ 				if next.has_key(kw) and stack:
+ 					self.putline(line, len(stack)-1)
+ 					kwa, kwb = stack[-1]
+ 					stack[-1] = kwa, kw
+ 					continue
+ 				# end if
+ 			# end if
+ 			self.putline(line, len(stack))
+ 		# end while
+ 		if stack:
+ 			self.error('unterminated keywords')
+ 			for kwa, kwb in stack:
+ 				self.write('\t%s\n' % kwa)
+ 			# end for
+ 		# end if
+ 	# end def eliminate
+ 	
  	def complete(self):
  		self.indentsize = 1
  		stack = []
***************
*** 293,304 ****
  # - xxx_string(s): take and return string object
  # - xxx_file(filename): process file in place, return true iff changed
  
! def complete_filter(input= sys.stdin, output = sys.stdout,
  		    stepsize = STEPSIZE, tabsize = TABSIZE):
  	pi = PythonIndenter(input, output, stepsize, tabsize)
  	pi.complete()
  # end def complete_filter
  
  def reformat_filter(input = sys.stdin, output = sys.stdout,
  		    stepsize = STEPSIZE, tabsize = TABSIZE):
  	pi = PythonIndenter(input, output, stepsize, tabsize)
--- 340,357 ----
  # - xxx_string(s): take and return string object
  # - xxx_file(filename): process file in place, return true iff changed
  
! def complete_filter(input = sys.stdin, output = sys.stdout,
  	stepsize = STEPSIZE, tabsize = TABSIZE):
  	pi = PythonIndenter(input, output, stepsize, tabsize)
  	pi.complete()
  # end def complete_filter
  
+ def eliminate_filter(input= sys.stdin, output = sys.stdout,
+ 	stepsize = STEPSIZE, tabsize = TABSIZE):
+ 	pi = PythonIndenter(input, output, stepsize, tabsize)
+ 	pi.eliminate()
+ # end def eliminate_filter
+ 
  def reformat_filter(input = sys.stdin, output = sys.stdout,
  	stepsize = STEPSIZE, tabsize = TABSIZE):
  	pi = PythonIndenter(input, output, stepsize, tabsize)
***************
*** 357,362 ****
--- 410,423 ----
  	return output.getvalue()
  # end def complete_string
  
+ def eliminate_string(source, stepsize = STEPSIZE, tabsize = TABSIZE):
+ 	input = StringReader(source)
+ 	output = StringWriter()
+ 	pi = PythonIndenter(input, output, stepsize, tabsize)
+ 	pi.eliminate()
+ 	return output.getvalue()
+ # end def eliminate_string
+ 
  def reformat_string(source, stepsize = STEPSIZE, tabsize = TABSIZE):
  	input = StringReader(source)
  	output = StringWriter()
***************
*** 380,392 ****
  	return 1
  # end def complete_file
  
  def reformat_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE):
  	source = open(filename, 'r').read()
  	result = reformat_string(source, stepsize, tabsize)
  	if source == result: return 0
  	# end if
  	import os
! 	os.rename(filename, filename + '~')
  	f = open(filename, 'w')
  	f.write(result)
  	f.close()
--- 441,470 ----
  	return 1
  # end def complete_file
  
+ def eliminate_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE):
+ 	source = open(filename, 'r').read()
+ 	result = eliminate_string(source, stepsize, tabsize)
+ 	if source == result: return 0
+ 	# end if
+ 	import os
+ 	try: os.rename(filename, filename + '~')
+ 	except os.error: pass
+ 	# end try
+ 	f = open(filename, 'w')
+ 	f.write(result)
+ 	f.close()
+ 	return 1
+ # end def eliminate_file
+ 
  def reformat_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE):
  	source = open(filename, 'r').read()
  	result = reformat_string(source, stepsize, tabsize)
  	if source == result: return 0
  	# end if
  	import os
! 	try: os.rename(filename, filename + '~')
! 	except os.error: pass
! 	# end try
  	f = open(filename, 'w')
  	f.write(result)
  	f.close()
***************
*** 396,403 ****
  # Test program when called as a script
  
  usage = """
! usage: pindent (-c|-r) [-s stepsize] [-t tabsize] [file] ...
  -c         : complete a correctly indented program (add #end directives)
  -r         : reformat a completed program (use #end directives)
  -s stepsize: indentation step (default %(STEPSIZE)d)
  -t tabsize : the worth in spaces of a tab (default %(TABSIZE)d)
--- 474,482 ----
  # Test program when called as a script
  
  usage = """
! usage: pindent (-c|-e|-r) [-s stepsize] [-t tabsize] [file] ...
  -c         : complete a correctly indented program (add #end directives)
+ -e         : eliminate #end directives
  -r         : reformat a completed program (use #end directives)
  -s stepsize: indentation step (default %(STEPSIZE)d)
  -t tabsize : the worth in spaces of a tab (default %(TABSIZE)d)
***************
*** 409,415 ****
  def test():
  	import getopt
  	try:
! 		opts, args = getopt.getopt(sys.argv[1:], 'crs:t:')
  	except getopt.error, msg:
  		sys.stderr.write('Error: %s\n' % msg)
  		sys.stderr.write(usage)
--- 488,494 ----
  def test():
  	import getopt
  	try:
! 		opts, args = getopt.getopt(sys.argv[1:], 'cers:t:')
  	except getopt.error, msg:
  		sys.stderr.write('Error: %s\n' % msg)
  		sys.stderr.write(usage)
***************
*** 421,426 ****
--- 500,507 ----
  	for o, a in opts:
  		if o == '-c':
  			action = 'complete'
+ 		elif o == '-e':
+ 			action = 'eliminate'
  		elif o == '-r':
  			action = 'reformat'
  		elif o == '-s':
***************
*** 431,437 ****
  	# end for
  	if not action:
  		sys.stderr.write(
! 			'You must specify -c(omplete) or -r(eformat)\n')
  		sys.stderr.write(usage)
  		sys.exit(2)
  	# end if
--- 512,518 ----
  	# end for
  	if not action:
  		sys.stderr.write(
! 		        'You must specify -c(omplete), -e(eliminate) or -r(eformat)\n')
  		sys.stderr.write(usage)
  		sys.exit(2)
  	# end if

--------------1BA7580EFB4ADADF51A557A3--