main.py (8327:dda2a88eb7c4) main.py (8333:c1a07ecb6619)
1# Copyright (c) 2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Nathan Binkert
28
29import code
30import datetime
31import os
32import socket
33import sys
34
35__all__ = [ 'options', 'arguments', 'main' ]
36
37usage="%prog [gem5 options] script.py [script options]"
38version="%prog 2.0"
1# Copyright (c) 2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Nathan Binkert
28
29import code
30import datetime
31import os
32import socket
33import sys
34
35__all__ = [ 'options', 'arguments', 'main' ]
36
37usage="%prog [gem5 options] script.py [script options]"
38version="%prog 2.0"
39brief_copyright='''
40Copyright (c) 2001-2011
41The Regents of The University of Michigan
42All Rights Reserved
43'''
39brief_copyright=\
40 "gem5 is copyrighted software; use the --copyright option for details."
44
45def parse_options():
46 import config
47 from options import OptionParser
48
49 options = OptionParser(usage=usage, version=version,
50 description=brief_copyright)
51 option = options.add_option
52 group = options.set_group
53
54 # Help options
41
42def parse_options():
43 import config
44 from options import OptionParser
45
46 options = OptionParser(usage=usage, version=version,
47 description=brief_copyright)
48 option = options.add_option
49 group = options.set_group
50
51 # Help options
55 option('-A', "--authors", action="store_true", default=False,
56 help="Show author information")
57 option('-B', "--build-info", action="store_true", default=False,
58 help="Show build information")
59 option('-C', "--copyright", action="store_true", default=False,
60 help="Show full copyright information")
61 option('-R', "--readme", action="store_true", default=False,
62 help="Show the readme")
63
64 # Options for configuring the base simulator
65 option('-d', "--outdir", metavar="DIR", default="m5out",
66 help="Set the output directory to DIR [Default: %default]")
67 option('-r', "--redirect-stdout", action="store_true", default=False,
68 help="Redirect stdout (& stderr, without -e) to file")
69 option('-e', "--redirect-stderr", action="store_true", default=False,
70 help="Redirect stderr to file")
71 option("--stdout-file", metavar="FILE", default="simout",
72 help="Filename for -r redirection [Default: %default]")
73 option("--stderr-file", metavar="FILE", default="simerr",
74 help="Filename for -e redirection [Default: %default]")
75 option('-i', "--interactive", action="store_true", default=False,
76 help="Invoke the interactive interpreter after running the script")
77 option("--pdb", action="store_true", default=False,
78 help="Invoke the python debugger before running the script")
79 option('-p', "--path", metavar="PATH[:PATH]", action='append', split=':',
80 help="Prepend PATH to the system path when invoking the script")
81 option('-q', "--quiet", action="count", default=0,
82 help="Reduce verbosity")
83 option('-v', "--verbose", action="count", default=0,
84 help="Increase verbosity")
85
86 # Statistics options
87 group("Statistics Options")
88 option("--stats-file", metavar="FILE", default="stats.txt",
89 help="Sets the output file for statistics [Default: %default]")
90
91 # Configuration Options
92 group("Configuration Options")
93 option("--dump-config", metavar="FILE", default="config.ini",
94 help="Dump configuration output file [Default: %default]")
95
96 # Debugging options
97 group("Debugging Options")
98 option("--debug-break", metavar="TIME[,TIME]", action='append', split=',',
99 help="Cycle to create a breakpoint")
100 option("--debug-help", action='store_true',
101 help="Print help on trace flags")
102 option("--debug-flags", metavar="FLAG[,FLAG]", action='append', split=',',
103 help="Sets the flags for tracing (-FLAG disables a flag)")
104 option("--remote-gdb-port", type='int', default=7000,
105 help="Remote gdb base port (set to 0 to disable listening)")
106
107 # Tracing options
108 group("Trace Options")
109 option("--trace-start", metavar="TIME", type='int',
110 help="Start tracing at TIME (must be in ticks)")
111 option("--trace-file", metavar="FILE", default="cout",
112 help="Sets the output file for tracing [Default: %default]")
113 option("--trace-ignore", metavar="EXPR", action='append', split=':',
114 help="Ignore EXPR sim objects")
115
116 # Help options
117 group("Help Options")
118 option("--list-sim-objects", action='store_true', default=False,
119 help="List all built-in SimObjects, their params and default values")
120
121 # load the options.py config file to allow people to set their own
122 # default options
123 options_file = config.get('options.py')
124 if options_file:
125 scope = { 'options' : options }
126 execfile(options_file, scope)
127
128 arguments = options.parse_args()
129
130 return options,arguments
131
132def interact(scope):
133 banner = "gem5 Interactive Console"
134 sys.argv = []
135 try:
136 from IPython.Shell import IPShellEmbed
137 ipshell = IPShellEmbed(banner=banner,user_ns=scope)
138 ipshell()
139 except ImportError:
140 code.InteractiveConsole(scope).interact(banner)
141
142def main(*args):
143 import m5
144
145 import core
146 import debug
147 import defines
148 import event
149 import info
150 import stats
151 import trace
152
153 from util import fatal
154
155 if len(args) == 0:
156 options, arguments = parse_options()
157 elif len(args) == 2:
158 options, arguments = args
159 else:
160 raise TypeError, "main() takes 0 or 2 arguments (%d given)" % len(args)
161
162 m5.options = options
163
164 def check_tracing():
165 if defines.TRACING_ON:
166 return
167
168 fatal("Tracing is not enabled. Compile with TRACING_ON")
169
170 if not os.path.isdir(options.outdir):
171 os.makedirs(options.outdir)
172
173 # These filenames are used only if the redirect_std* options are set
174 stdout_file = os.path.join(options.outdir, options.stdout_file)
175 stderr_file = os.path.join(options.outdir, options.stderr_file)
176
177 # Print redirection notices here before doing any redirection
178 if options.redirect_stdout and not options.redirect_stderr:
179 print "Redirecting stdout and stderr to", stdout_file
180 else:
181 if options.redirect_stdout:
182 print "Redirecting stdout to", stdout_file
183 if options.redirect_stderr:
184 print "Redirecting stderr to", stderr_file
185
186 # Now redirect stdout/stderr as desired
187 if options.redirect_stdout:
188 redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
189 os.dup2(redir_fd, sys.stdout.fileno())
190 if not options.redirect_stderr:
191 os.dup2(redir_fd, sys.stderr.fileno())
192
193 if options.redirect_stderr:
194 redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
195 os.dup2(redir_fd, sys.stderr.fileno())
196
197 done = False
198
199 if options.build_info:
200 done = True
201 print 'Build information:'
202 print
203 print 'compiled %s' % defines.compileDate;
204 print 'build options:'
205 keys = defines.buildEnv.keys()
206 keys.sort()
207 for key in keys:
208 val = defines.buildEnv[key]
209 print ' %s = %s' % (key, val)
210 print
211
212 if options.copyright:
213 done = True
52 option('-B', "--build-info", action="store_true", default=False,
53 help="Show build information")
54 option('-C', "--copyright", action="store_true", default=False,
55 help="Show full copyright information")
56 option('-R', "--readme", action="store_true", default=False,
57 help="Show the readme")
58
59 # Options for configuring the base simulator
60 option('-d', "--outdir", metavar="DIR", default="m5out",
61 help="Set the output directory to DIR [Default: %default]")
62 option('-r', "--redirect-stdout", action="store_true", default=False,
63 help="Redirect stdout (& stderr, without -e) to file")
64 option('-e', "--redirect-stderr", action="store_true", default=False,
65 help="Redirect stderr to file")
66 option("--stdout-file", metavar="FILE", default="simout",
67 help="Filename for -r redirection [Default: %default]")
68 option("--stderr-file", metavar="FILE", default="simerr",
69 help="Filename for -e redirection [Default: %default]")
70 option('-i', "--interactive", action="store_true", default=False,
71 help="Invoke the interactive interpreter after running the script")
72 option("--pdb", action="store_true", default=False,
73 help="Invoke the python debugger before running the script")
74 option('-p', "--path", metavar="PATH[:PATH]", action='append', split=':',
75 help="Prepend PATH to the system path when invoking the script")
76 option('-q', "--quiet", action="count", default=0,
77 help="Reduce verbosity")
78 option('-v', "--verbose", action="count", default=0,
79 help="Increase verbosity")
80
81 # Statistics options
82 group("Statistics Options")
83 option("--stats-file", metavar="FILE", default="stats.txt",
84 help="Sets the output file for statistics [Default: %default]")
85
86 # Configuration Options
87 group("Configuration Options")
88 option("--dump-config", metavar="FILE", default="config.ini",
89 help="Dump configuration output file [Default: %default]")
90
91 # Debugging options
92 group("Debugging Options")
93 option("--debug-break", metavar="TIME[,TIME]", action='append', split=',',
94 help="Cycle to create a breakpoint")
95 option("--debug-help", action='store_true',
96 help="Print help on trace flags")
97 option("--debug-flags", metavar="FLAG[,FLAG]", action='append', split=',',
98 help="Sets the flags for tracing (-FLAG disables a flag)")
99 option("--remote-gdb-port", type='int', default=7000,
100 help="Remote gdb base port (set to 0 to disable listening)")
101
102 # Tracing options
103 group("Trace Options")
104 option("--trace-start", metavar="TIME", type='int',
105 help="Start tracing at TIME (must be in ticks)")
106 option("--trace-file", metavar="FILE", default="cout",
107 help="Sets the output file for tracing [Default: %default]")
108 option("--trace-ignore", metavar="EXPR", action='append', split=':',
109 help="Ignore EXPR sim objects")
110
111 # Help options
112 group("Help Options")
113 option("--list-sim-objects", action='store_true', default=False,
114 help="List all built-in SimObjects, their params and default values")
115
116 # load the options.py config file to allow people to set their own
117 # default options
118 options_file = config.get('options.py')
119 if options_file:
120 scope = { 'options' : options }
121 execfile(options_file, scope)
122
123 arguments = options.parse_args()
124
125 return options,arguments
126
127def interact(scope):
128 banner = "gem5 Interactive Console"
129 sys.argv = []
130 try:
131 from IPython.Shell import IPShellEmbed
132 ipshell = IPShellEmbed(banner=banner,user_ns=scope)
133 ipshell()
134 except ImportError:
135 code.InteractiveConsole(scope).interact(banner)
136
137def main(*args):
138 import m5
139
140 import core
141 import debug
142 import defines
143 import event
144 import info
145 import stats
146 import trace
147
148 from util import fatal
149
150 if len(args) == 0:
151 options, arguments = parse_options()
152 elif len(args) == 2:
153 options, arguments = args
154 else:
155 raise TypeError, "main() takes 0 or 2 arguments (%d given)" % len(args)
156
157 m5.options = options
158
159 def check_tracing():
160 if defines.TRACING_ON:
161 return
162
163 fatal("Tracing is not enabled. Compile with TRACING_ON")
164
165 if not os.path.isdir(options.outdir):
166 os.makedirs(options.outdir)
167
168 # These filenames are used only if the redirect_std* options are set
169 stdout_file = os.path.join(options.outdir, options.stdout_file)
170 stderr_file = os.path.join(options.outdir, options.stderr_file)
171
172 # Print redirection notices here before doing any redirection
173 if options.redirect_stdout and not options.redirect_stderr:
174 print "Redirecting stdout and stderr to", stdout_file
175 else:
176 if options.redirect_stdout:
177 print "Redirecting stdout to", stdout_file
178 if options.redirect_stderr:
179 print "Redirecting stderr to", stderr_file
180
181 # Now redirect stdout/stderr as desired
182 if options.redirect_stdout:
183 redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
184 os.dup2(redir_fd, sys.stdout.fileno())
185 if not options.redirect_stderr:
186 os.dup2(redir_fd, sys.stderr.fileno())
187
188 if options.redirect_stderr:
189 redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC)
190 os.dup2(redir_fd, sys.stderr.fileno())
191
192 done = False
193
194 if options.build_info:
195 done = True
196 print 'Build information:'
197 print
198 print 'compiled %s' % defines.compileDate;
199 print 'build options:'
200 keys = defines.buildEnv.keys()
201 keys.sort()
202 for key in keys:
203 val = defines.buildEnv[key]
204 print ' %s = %s' % (key, val)
205 print
206
207 if options.copyright:
208 done = True
214 print info.LICENSE
209 print info.COPYING
215 print
216
210 print
211
217 if options.authors:
218 done = True
219 print 'Author information:'
220 print
221 print info.AUTHORS
222 print
223
224 if options.readme:
225 done = True
226 print 'Readme:'
227 print
228 print info.README
229 print
230
231 if options.debug_help:
232 done = True
233 check_tracing()
234 debug.help()
235
236 if options.list_sim_objects:
237 import SimObject
238 done = True
239 print "SimObjects:"
240 objects = SimObject.allClasses.keys()
241 objects.sort()
242 for name in objects:
243 obj = SimObject.allClasses[name]
244 print " %s" % obj
245 params = obj._params.keys()
246 params.sort()
247 for pname in params:
248 param = obj._params[pname]
249 default = getattr(param, 'default', '')
250 print " %s" % pname
251 if default:
252 print " default: %s" % default
253 print " desc: %s" % param.desc
254 print
255 print
256
257 if done:
258 sys.exit(0)
259
260 # setting verbose and quiet at the same time doesn't make sense
261 if options.verbose > 0 and options.quiet > 0:
262 options.usage(2)
263
264 verbose = options.verbose - options.quiet
265 if options.verbose >= 0:
212 if options.readme:
213 done = True
214 print 'Readme:'
215 print
216 print info.README
217 print
218
219 if options.debug_help:
220 done = True
221 check_tracing()
222 debug.help()
223
224 if options.list_sim_objects:
225 import SimObject
226 done = True
227 print "SimObjects:"
228 objects = SimObject.allClasses.keys()
229 objects.sort()
230 for name in objects:
231 obj = SimObject.allClasses[name]
232 print " %s" % obj
233 params = obj._params.keys()
234 params.sort()
235 for pname in params:
236 param = obj._params[pname]
237 default = getattr(param, 'default', '')
238 print " %s" % pname
239 if default:
240 print " default: %s" % default
241 print " desc: %s" % param.desc
242 print
243 print
244
245 if done:
246 sys.exit(0)
247
248 # setting verbose and quiet at the same time doesn't make sense
249 if options.verbose > 0 and options.quiet > 0:
250 options.usage(2)
251
252 verbose = options.verbose - options.quiet
253 if options.verbose >= 0:
266 print "gem5 Simulator System"
254 print "gem5 Simulator System. http://gem5.org"
267 print brief_copyright
268 print
269
270 print "gem5 compiled %s" % defines.compileDate;
271
272 print "gem5 started %s" % \
273 datetime.datetime.now().strftime("%b %e %Y %X")
274 print "gem5 executing on %s" % socket.gethostname()
275
276 print "command line:",
277 for argv in sys.argv:
278 print argv,
279 print
280
281 # check to make sure we can find the listed script
282 if not arguments or not os.path.isfile(arguments[0]):
283 if arguments and not os.path.isfile(arguments[0]):
284 print "Script %s not found" % arguments[0]
285
286 options.usage(2)
287
288 # tell C++ about output directory
289 core.setOutputDir(options.outdir)
290
291 # update the system path with elements from the -p option
292 sys.path[0:0] = options.path
293
294 # set stats options
295 stats.initText(options.stats_file)
296
297 # set debugging options
298 debug.setRemoteGDBPort(options.remote_gdb_port)
299 for when in options.debug_break:
300 debug.schedBreakCycle(int(when))
301
302 if options.debug_flags:
303 check_tracing()
304
305 on_flags = []
306 off_flags = []
307 for flag in options.debug_flags:
308 off = False
309 if flag.startswith('-'):
310 flag = flag[1:]
311 off = True
312
313 if flag not in debug.flags:
314 print >>sys.stderr, "invalid debug flag '%s'" % flag
315 sys.exit(1)
316
317 if off:
318 debug.flags[flag].disable()
319 else:
320 debug.flags[flag].enable()
321
322 if options.trace_start:
323 check_tracing()
324 e = event.create(trace.enable, event.Event.Trace_Enable_Pri)
325 event.mainq.schedule(e, options.trace_start)
326 else:
327 trace.enable()
328
329 trace.output(options.trace_file)
330
331 for ignore in options.trace_ignore:
332 check_tracing()
333 trace.ignore(ignore)
334
335 sys.argv = arguments
336 sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path
337
338 filename = sys.argv[0]
339 filedata = file(filename, 'r').read()
340 filecode = compile(filedata, filename, 'exec')
341 scope = { '__file__' : filename,
342 '__name__' : '__m5_main__' }
343
344 # we want readline if we're doing anything interactive
345 if options.interactive or options.pdb:
346 exec "import readline" in scope
347
348 # if pdb was requested, execfile the thing under pdb, otherwise,
349 # just do the execfile normally
350 if options.pdb:
351 import pdb
352 import traceback
353
354 pdb = pdb.Pdb()
355 try:
356 pdb.run(filecode, scope)
357 except SystemExit:
358 print "The program exited via sys.exit(). Exit status: ",
359 print sys.exc_info()[1]
360 except:
361 traceback.print_exc()
362 print "Uncaught exception. Entering post mortem debugging"
363 t = sys.exc_info()[2]
364 while t.tb_next is not None:
365 t = t.tb_next
366 pdb.interaction(t.tb_frame,t)
367 else:
368 exec filecode in scope
369
370 # once the script is done
371 if options.interactive:
372 interact(scope)
373
374if __name__ == '__main__':
375 from pprint import pprint
376
377 options, arguments = parse_options()
378
379 print 'opts:'
380 pprint(options, indent=4)
381 print
382
383 print 'args:'
384 pprint(arguments, indent=4)
255 print brief_copyright
256 print
257
258 print "gem5 compiled %s" % defines.compileDate;
259
260 print "gem5 started %s" % \
261 datetime.datetime.now().strftime("%b %e %Y %X")
262 print "gem5 executing on %s" % socket.gethostname()
263
264 print "command line:",
265 for argv in sys.argv:
266 print argv,
267 print
268
269 # check to make sure we can find the listed script
270 if not arguments or not os.path.isfile(arguments[0]):
271 if arguments and not os.path.isfile(arguments[0]):
272 print "Script %s not found" % arguments[0]
273
274 options.usage(2)
275
276 # tell C++ about output directory
277 core.setOutputDir(options.outdir)
278
279 # update the system path with elements from the -p option
280 sys.path[0:0] = options.path
281
282 # set stats options
283 stats.initText(options.stats_file)
284
285 # set debugging options
286 debug.setRemoteGDBPort(options.remote_gdb_port)
287 for when in options.debug_break:
288 debug.schedBreakCycle(int(when))
289
290 if options.debug_flags:
291 check_tracing()
292
293 on_flags = []
294 off_flags = []
295 for flag in options.debug_flags:
296 off = False
297 if flag.startswith('-'):
298 flag = flag[1:]
299 off = True
300
301 if flag not in debug.flags:
302 print >>sys.stderr, "invalid debug flag '%s'" % flag
303 sys.exit(1)
304
305 if off:
306 debug.flags[flag].disable()
307 else:
308 debug.flags[flag].enable()
309
310 if options.trace_start:
311 check_tracing()
312 e = event.create(trace.enable, event.Event.Trace_Enable_Pri)
313 event.mainq.schedule(e, options.trace_start)
314 else:
315 trace.enable()
316
317 trace.output(options.trace_file)
318
319 for ignore in options.trace_ignore:
320 check_tracing()
321 trace.ignore(ignore)
322
323 sys.argv = arguments
324 sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path
325
326 filename = sys.argv[0]
327 filedata = file(filename, 'r').read()
328 filecode = compile(filedata, filename, 'exec')
329 scope = { '__file__' : filename,
330 '__name__' : '__m5_main__' }
331
332 # we want readline if we're doing anything interactive
333 if options.interactive or options.pdb:
334 exec "import readline" in scope
335
336 # if pdb was requested, execfile the thing under pdb, otherwise,
337 # just do the execfile normally
338 if options.pdb:
339 import pdb
340 import traceback
341
342 pdb = pdb.Pdb()
343 try:
344 pdb.run(filecode, scope)
345 except SystemExit:
346 print "The program exited via sys.exit(). Exit status: ",
347 print sys.exc_info()[1]
348 except:
349 traceback.print_exc()
350 print "Uncaught exception. Entering post mortem debugging"
351 t = sys.exc_info()[2]
352 while t.tb_next is not None:
353 t = t.tb_next
354 pdb.interaction(t.tb_frame,t)
355 else:
356 exec filecode in scope
357
358 # once the script is done
359 if options.interactive:
360 interact(scope)
361
362if __name__ == '__main__':
363 from pprint import pprint
364
365 options, arguments = parse_options()
366
367 print 'opts:'
368 pprint(options, indent=4)
369 print
370
371 print 'args:'
372 pprint(arguments, indent=4)