@@ -52,6 +52,11 @@ def __init__ (self, filename=None, file=None, **options):
5252 self .filename = filename
5353 self .file = file
5454 self .current_line = 0 # assuming that file is at BOF!
55+
56+ # 'linestart' stores the file offset of the start of each logical
57+ # line; it is used to back up the file pointer when the caller
58+ # wants to "unread" a line
59+ self .linestart = []
5560
5661
5762 def open (self , filename ):
@@ -81,6 +86,11 @@ def readline (self):
8186 buildup_line = ''
8287
8388 while 1 :
89+ # record current file position; this will be appended to
90+ # the linestart array *unless* we're accumulating a
91+ # continued logical line
92+ current_pos = self .file .tell ()
93+
8494 # read the line, optionally strip comments
8595 line = self .file .readline ()
8696 if self .strip_comments and line :
@@ -101,6 +111,11 @@ def readline (self):
101111 self .current_line [1 ] = self .current_line [1 ] + 1
102112 else :
103113 self .current_line = [self .current_line , self .current_line + 1 ]
114+
115+ # Forget current position: don't want to save it in the
116+ # middle of a logical line
117+ current_pos = None
118+
104119 # just an ordinary line, read it as usual
105120 else :
106121 if not line :
@@ -111,7 +126,7 @@ def readline (self):
111126 self .current_line = self .current_line [1 ] + 1
112127 else :
113128 self .current_line = self .current_line + 1
114-
129+
115130
116131 # strip whitespace however the client wants (leading and
117132 # trailing, or one or the other, or neither)
@@ -128,6 +143,12 @@ def readline (self):
128143 if line == '' or line == '\n ' and self .skip_blanks :
129144 continue
130145
146+ # if we're still here and have kept the current position,
147+ # then this physical line starts a logical line; record its
148+ # starting offset
149+ if current_pos is not None :
150+ self .linestart .append (current_pos )
151+
131152 if self .join_lines :
132153 if line [- 1 ] == '\\ ' :
133154 buildup_line = line [:- 1 ]
@@ -147,6 +168,14 @@ def readline (self):
147168 # end readline
148169
149170
171+ def unreadline (self ):
172+ if not self .linestart :
173+ raise IOError , "at beginning of file -- can't unreadline"
174+ pos = self .linestart [- 1 ]
175+ del self .linestart [- 1 ]
176+ self .file .seek (pos )
177+
178+
150179 def readlines (self ):
151180 lines = []
152181 while 1 :
0 commit comments