1515class TextFile :
1616
1717 default_options = { 'strip_comments' : 1 ,
18- 'comment_re' : re .compile (r'\s*#.*' ),
1918 'skip_blanks' : 1 ,
2019 'join_lines' : 0 ,
2120 'lstrip_ws' : 0 ,
@@ -33,10 +32,7 @@ def __init__ (self, filename=None, file=None, **options):
3332 # or fallback to default_options
3433 for opt in self .default_options .keys ():
3534 if options .has_key (opt ):
36- if opt == 'comment_re' and type (options [opt ]) is StringType :
37- self .comment_re = re .compile (options [opt ])
38- else :
39- setattr (self , opt , options [opt ])
35+ setattr (self , opt , options [opt ])
4036
4137 else :
4238 setattr (self , opt , self .default_options [opt ])
@@ -76,11 +72,11 @@ def warn (self, msg, line=None):
7672 if line is None :
7773 line = self .current_line
7874 sys .stderr .write (self .filename + ", " )
79- if type (line ) is ListType :
75+ if type (line ) in ( ListType , TupleType ) :
8076 sys .stderr .write ("lines %d-%d: " % tuple (line ))
8177 else :
8278 sys .stderr .write ("line %d: " % line )
83- sys .stderr .write (msg + "\n " )
79+ sys .stderr .write (str ( msg ) + "\n " )
8480
8581
8682 def readline (self ):
@@ -97,15 +93,42 @@ def readline (self):
9793 buildup_line = ''
9894
9995 while 1 :
100- # read the line, optionally strip comments
96+ # read the line, make it None if EOF
10197 line = self .file .readline ()
98+ if line == '' : line = None
99+
102100 if self .strip_comments and line :
103- line = self .comment_re .sub ('' , line )
101+
102+ # Look for the first "#" in the line. If none, never
103+ # mind. If we find one and it's the first character, or
104+ # is not preceded by "\", then it starts a comment --
105+ # strip the comment, strip whitespace before it, and
106+ # carry on. Otherwise, it's just an escaped "#", so
107+ # unescape it (and any other escaped "#"'s that might be
108+ # lurking in there) and otherwise leave the line alone.
109+
110+ pos = string .find (line , "#" )
111+ if pos == - 1 : # no "#" -- no comments
112+ pass
113+ elif pos == 0 or line [pos - 1 ] != "\\ " : # it's a comment
114+ # Have to preserve the trailing newline; if
115+ # stripping comments resulted in an empty line, we'd
116+ # have no way to distinguish end-of-file! (NB. this
117+ # means that if the final line is all comment and
118+ # has to trailing newline, we will think that it's
119+ # EOF; I think that's OK.)
120+ has_newline = (line [- 1 ] == '\n ' )
121+ line = line [0 :pos ]
122+ if has_newline : line = line + '\n '
123+
124+ else : # it's an escaped "#"
125+ line = string .replace (line , "\\ #" , "#" )
126+
104127
105128 # did previous line end with a backslash? then accumulate
106129 if self .join_lines and buildup_line :
107130 # oops: end of file
108- if not line :
131+ if line is None :
109132 self .warn ("continuation line immediately precedes "
110133 "end-of-file" )
111134 return buildup_line
@@ -119,7 +142,7 @@ def readline (self):
119142 self .current_line = [self .current_line , self .current_line + 1 ]
120143 # just an ordinary line, read it as usual
121144 else :
122- if not line :
145+ if line is None : # eof
123146 return None
124147
125148 # still have to be careful about incrementing the line number!
@@ -217,15 +240,15 @@ def test_input (count, description, file, expected_result):
217240 out_file .close ()
218241
219242 in_file = TextFile (filename , strip_comments = 0 , skip_blanks = 0 ,
220- lstrip_ws = 0 , rstrip_ws = 0 )
243+ lstrip_ws = 0 , rstrip_ws = 0 )
221244 test_input (1 , "no processing" , in_file , result1 )
222245
223246 in_file = TextFile (filename , strip_comments = 1 , skip_blanks = 0 ,
224- lstrip_ws = 0 , rstrip_ws = 0 )
247+ lstrip_ws = 0 , rstrip_ws = 0 )
225248 test_input (2 , "strip comments" , in_file , result2 )
226249
227250 in_file = TextFile (filename , strip_comments = 0 , skip_blanks = 1 ,
228- lstrip_ws = 0 , rstrip_ws = 0 )
251+ lstrip_ws = 0 , rstrip_ws = 0 )
229252 test_input (3 , "strip blanks" , in_file , result3 )
230253
231254 in_file = TextFile (filename )
0 commit comments