11"""A lexical analyzer class for simple shell-like syntaxes."""
22
3- # Module and documentation by Eric S. Raymond, 21 Dec 1998
3+ # Module and documentation by Eric S. Raymond, 21 Dec 1998
44# Input stacking and error message cleanup added by ESR, March 2000
5+ # push_source() and pop_source() made explicit by ESR, January 2001.
56
67import os .path
78import sys
89
9-
1010class shlex :
11- "A lexical analyzer class for simple shell-like syntaxes."
11+ "A lexical analyzer class for simple shell-like syntaxes."
1212 def __init__ (self , instream = None , infile = None ):
1313 if instream :
1414 self .instream = instream
@@ -38,6 +38,28 @@ def push_token(self, tok):
3838 print "shlex: pushing token " + `tok`
3939 self .pushback = [tok ] + self .pushback
4040
41+ def push_source (self , newstream , newfile = None ):
42+ "Push an input source onto the lexer's input source stack."
43+ self .filestack .insert (0 , (self .infile , self .instream , self .lineno ))
44+ self .infile = newfile
45+ self .instream = newstream
46+ self .lineno = 1
47+ if self .debug :
48+ if newfile :
49+ print 'shlex: pushing to file %s' % (self .infile ,)
50+ else :
51+ print 'shlex: pushing to stream %s' % (self .instream ,)
52+
53+ def pop_source (self ):
54+ "Pop the input source stack."
55+ self .instream .close ()
56+ (self .infile , self .instream , self .lineno ) = self .filestack [0 ]
57+ self .filestack = self .filestack [1 :]
58+ if self .debug :
59+ print 'shlex: popping to %s, line %d' \
60+ % (self .instream , self .lineno )
61+ self .state = ' '
62+
4163 def get_token (self ):
4264 "Get a token from the input stream (or from stack if it's nonempty)"
4365 if self .pushback :
@@ -50,26 +72,17 @@ def get_token(self):
5072 raw = self .read_token ()
5173 # Handle inclusions
5274 while raw == self .source :
53- (newfile , newstream ) = self .sourcehook (self .read_token ())
54- self .filestack .insert (0 , (self .infile , self .instream , self .lineno ))
55- self .infile = newfile
56- self .instream = newstream
57- self .lineno = 1
58- if self .debug :
59- print 'shlex: pushing to file %s' % (self .infile ,)
75+ spec = self .sourcehook (self .read_token ())
76+ if spec :
77+ (newfile , newstream ) = spec
78+ self .push_source (newstream , newfile )
6079 raw = self .get_token ()
6180 # Maybe we got EOF instead?
6281 while raw == "" :
6382 if len (self .filestack ) == 0 :
6483 return ""
6584 else :
66- self .instream .close ()
67- (self .infile , self .instream , self .lineno ) = self .filestack [0 ]
68- self .filestack = self .filestack [1 :]
69- if self .debug :
70- print 'shlex: popping to %s, line %d' \
71- % (self .instream , self .lineno )
72- self .state = ' '
85+ self .pop_source ()
7386 raw = self .get_token ()
7487 # Neither inclusion nor EOF
7588 if self .debug >= 1 :
@@ -88,13 +101,13 @@ def read_token(self):
88101 self .lineno = self .lineno + 1
89102 if self .debug >= 3 :
90103 print "shlex: in state" , repr (self .state ), \
91- "I see character:" , repr (nextchar )
104+ "I see character:" , repr (nextchar )
92105 if self .state is None :
93- self .token = '' # past end of file
106+ self .token = '' # past end of file
94107 break
95108 elif self .state == ' ' :
96109 if not nextchar :
97- self .state = None # end of file
110+ self .state = None # end of file
98111 break
99112 elif nextchar in self .whitespace :
100113 if self .debug >= 2 :
@@ -123,14 +136,14 @@ def read_token(self):
123136 if nextchar == self .state :
124137 self .state = ' '
125138 break
126- elif not nextchar : # end of file
139+ elif not nextchar : # end of file
127140 if self .debug >= 2 :
128141 print "shlex: I see EOF in quotes state"
129142 # XXX what error should be raised here?
130143 raise ValueError , "No closing quotation"
131144 elif self .state == 'a' :
132145 if not nextchar :
133- self .state = None # end of file
146+ self .state = None # end of file
134147 break
135148 elif nextchar in self .whitespace :
136149 if self .debug >= 2 :
@@ -181,7 +194,7 @@ def error_leader(self, infile=None, lineno=None):
181194 return "\" %s\" , line %d: " % (infile , lineno )
182195
183196
184- if __name__ == '__main__' :
197+ if __name__ == '__main__' :
185198 if len (sys .argv ) == 1 :
186199 lexer = shlex ()
187200 else :
0 commit comments