11#! /usr/bin/env python
22
3- # This file contains a class and a main program that perform two
3+ # This file contains a class and a main program that perform three
44# related (though complimentary) formatting operations on Python
5- # programs. When called as "pindend -c", it takes a valid Python
5+ # programs. When called as "pindent -c", it takes a valid Python
66# program as input and outputs a version augmented with block-closing
7- # comments. When called as "pindent -r" it assumes its input is a
7+ # comments. When called as "pindent -e", it assumes its input is a
8+ # Python program with block-closing comments and outputs a commentless
9+ # version. When called as "pindent -r" it assumes its input is a
810# Python program with block-closing comments but with its indentation
911# messed up, and outputs a properly indented version.
1012
3436# that indentation is not significant when interpreting block-closing
3537# comments).
3638
37- # Both operations are idempotent (i.e. applied to their own output
39+ # The operations are idempotent (i.e. applied to their own output
3840# they yield an identical result). Running first "pindent -c" and
3941# then "pindent -r" on a valid Python program produces a program that
4042# is semantically identical to the input (though its indentation may
41- # be different).
43+ # be different). Running "pindent -e" on that output produces a
44+ # program that only differs from the original in indentation.
4245
4346# Other options:
4447# -s stepsize: set the indentation step size (default 8)
@@ -193,6 +196,34 @@ def reformat(self):
193196 # end if
194197 # end def reformat
195198
199+ def eliminate (self ):
200+ begin_counter = 0
201+ end_counter = 0
202+ while 1 :
203+ line = self .getline ()
204+ if not line : break # EOF
205+ # end if
206+ m = self .endprog .match (line )
207+ if m :
208+ end_counter = end_counter + 1
209+ continue
210+ # end if
211+ m = self .kwprog .match (line )
212+ if m :
213+ kw = m .group ('kw' )
214+ if kw in start :
215+ begin_counter = begin_counter + 1
216+ # end if
217+ # end if
218+ self .putline (line )
219+ # end while
220+ if begin_counter - end_counter < 0 :
221+ sys .stderr .write ('Warning: input contained more end tags than expected\n ' )
222+ elif begin_counter - end_counter > 0 :
223+ sys .stderr .write ('Warning: input contained less end tags than expected\n ' )
224+ # end if
225+ # end def eliminate
226+
196227 def complete (self ):
197228 self .indentsize = 1
198229 stack = []
@@ -293,12 +324,18 @@ def complete(self):
293324# - xxx_string(s): take and return string object
294325# - xxx_file(filename): process file in place, return true iff changed
295326
296- def complete_filter (input = sys .stdin , output = sys .stdout ,
327+ def complete_filter (input = sys .stdin , output = sys .stdout ,
297328 stepsize = STEPSIZE , tabsize = TABSIZE ):
298329 pi = PythonIndenter (input , output , stepsize , tabsize )
299330 pi .complete ()
300331# end def complete_filter
301332
333+ def eliminate_filter (input = sys .stdin , output = sys .stdout ,
334+ stepsize = STEPSIZE , tabsize = TABSIZE ):
335+ pi = PythonIndenter (input , output , stepsize , tabsize )
336+ pi .eliminate ()
337+ # end def eliminate_filter
338+
302339def reformat_filter (input = sys .stdin , output = sys .stdout ,
303340 stepsize = STEPSIZE , tabsize = TABSIZE ):
304341 pi = PythonIndenter (input , output , stepsize , tabsize )
@@ -357,6 +394,14 @@ def complete_string(source, stepsize = STEPSIZE, tabsize = TABSIZE):
357394 return output .getvalue ()
358395# end def complete_string
359396
397+ def eliminate_string (source , stepsize = STEPSIZE , tabsize = TABSIZE ):
398+ input = StringReader (source )
399+ output = StringWriter ()
400+ pi = PythonIndenter (input , output , stepsize , tabsize )
401+ pi .eliminate ()
402+ return output .getvalue ()
403+ # end def eliminate_string
404+
360405def reformat_string (source , stepsize = STEPSIZE , tabsize = TABSIZE ):
361406 input = StringReader (source )
362407 output = StringWriter ()
@@ -380,13 +425,30 @@ def complete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE):
380425 return 1
381426# end def complete_file
382427
428+ def eliminate_file (filename , stepsize = STEPSIZE , tabsize = TABSIZE ):
429+ source = open (filename , 'r' ).read ()
430+ result = eliminate_string (source , stepsize , tabsize )
431+ if source == result : return 0
432+ # end if
433+ import os
434+ try : os .rename (filename , filename + '~' )
435+ except os .error : pass
436+ # end try
437+ f = open (filename , 'w' )
438+ f .write (result )
439+ f .close ()
440+ return 1
441+ # end def eliminate_file
442+
383443def reformat_file (filename , stepsize = STEPSIZE , tabsize = TABSIZE ):
384444 source = open (filename , 'r' ).read ()
385445 result = reformat_string (source , stepsize , tabsize )
386446 if source == result : return 0
387447 # end if
388448 import os
389- os .rename (filename , filename + '~' )
449+ try : os .rename (filename , filename + '~' )
450+ except os .error : pass
451+ # end try
390452 f = open (filename , 'w' )
391453 f .write (result )
392454 f .close ()
@@ -396,8 +458,9 @@ def reformat_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE):
396458# Test program when called as a script
397459
398460usage = """
399- usage: pindent (-c|-r) [-s stepsize] [-t tabsize] [file] ...
461+ usage: pindent (-c|-e|- r) [-s stepsize] [-t tabsize] [file] ...
400462-c : complete a correctly indented program (add #end directives)
463+ -e : eliminate #end directives
401464-r : reformat a completed program (use #end directives)
402465-s stepsize: indentation step (default %(STEPSIZE)d)
403466-t tabsize : the worth in spaces of a tab (default %(TABSIZE)d)
@@ -409,7 +472,7 @@ def reformat_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE):
409472def test ():
410473 import getopt
411474 try :
412- opts , args = getopt .getopt (sys .argv [1 :], 'crs :t:' )
475+ opts , args = getopt .getopt (sys .argv [1 :], 'cers :t:' )
413476 except getopt .error , msg :
414477 sys .stderr .write ('Error: %s\n ' % msg )
415478 sys .stderr .write (usage )
@@ -421,6 +484,8 @@ def test():
421484 for o , a in opts :
422485 if o == '-c' :
423486 action = 'complete'
487+ elif o == '-e' :
488+ action = 'eliminate'
424489 elif o == '-r' :
425490 action = 'reformat'
426491 elif o == '-s' :
@@ -431,7 +496,7 @@ def test():
431496 # end for
432497 if not action :
433498 sys .stderr .write (
434- 'You must specify -c(omplete) or -r(eformat)\n ' )
499+ 'You must specify -c(omplete), -e(eliminate) or -r(eformat)\n ' )
435500 sys .stderr .write (usage )
436501 sys .exit (2 )
437502 # end if
0 commit comments