1 # Copyright (c) 2005 The Regents of The University of Michigan
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.
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.
27 # Authors: Nathan Binkert
29 import code
, optparse
, os
, socket
, sys
30 from datetime
import datetime
31 from attrdict
import attrdict
34 __all__
= [ 'options', 'arguments', 'main' ]
36 usage
="%prog [m5 options] script.py [script options]"
39 Copyright (c) 2001-2006
40 The Regents of The University of Michigan
44 def print_list(items
, indent
=4):
46 for i
,item
in enumerate(items
):
47 if len(line
) + len(item
) > 76:
51 if i
< len(items
) - 1:
57 # there's only one option parsing done, so make it global and add some
58 # helper functions to make it work well.
59 parser
= optparse
.OptionParser(usage
=usage
, version
=version
,
60 description
=brief_copyright
,
61 formatter
=optparse
.TitledHelpFormatter())
62 parser
.disable_interspersed_args()
64 # current option group
67 def set_group(*args
, **kwargs
):
68 '''set the current option group'''
70 if not args
and not kwargs
:
73 group
= parser
.add_option_group(*args
, **kwargs
)
75 class splitter(object):
76 def __init__(self
, split
):
78 def __call__(self
, option
, opt_str
, value
, parser
):
79 getattr(parser
.values
, option
.dest
).extend(value
.split(self
.split
))
81 def add_option(*args
, **kwargs
):
82 '''add an option to the current option group, or global none set'''
84 # if action=split, but allows the option arguments
85 # themselves to be lists separated by the split variable'''
87 if kwargs
.get('action', None) == 'append' and 'split' in kwargs
:
88 split
= kwargs
.pop('split')
89 kwargs
['default'] = []
90 kwargs
['type'] = 'string'
91 kwargs
['action'] = 'callback'
92 kwargs
['callback'] = splitter(split
)
95 return group
.add_option(*args
, **kwargs
)
97 return parser
.add_option(*args
, **kwargs
)
99 def bool_option(name
, default
, help):
100 '''add a boolean option called --name and --no-name.
101 Display help depending on which is the default'''
103 tname
= '--%s' % name
104 fname
= '--no-%s' % name
105 dest
= name
.replace('-', '_')
107 thelp
= optparse
.SUPPRESS_HELP
111 fhelp
= optparse
.SUPPRESS_HELP
113 add_option(tname
, action
="store_true", default
=default
, help=thelp
)
114 add_option(fname
, action
="store_false", dest
=dest
, help=fhelp
)
117 add_option('-A', "--authors", action
="store_true", default
=False,
118 help="Show author information")
119 add_option('-C', "--copyright", action
="store_true", default
=False,
120 help="Show full copyright information")
121 add_option('-R', "--readme", action
="store_true", default
=False,
122 help="Show the readme")
123 add_option('-N', "--release-notes", action
="store_true", default
=False,
124 help="Show the release notes")
126 # Options for configuring the base simulator
127 add_option('-d', "--outdir", metavar
="DIR", default
=".",
128 help="Set the output directory to DIR [Default: %default]")
129 add_option('-i', "--interactive", action
="store_true", default
=False,
130 help="Invoke the interactive interpreter after running the script")
131 add_option("--pdb", action
="store_true", default
=False,
132 help="Invoke the python debugger before running the script")
133 add_option('-p', "--path", metavar
="PATH[:PATH]", action
='append', split
=':',
134 help="Prepend PATH to the system path when invoking the script")
135 add_option('-q', "--quiet", action
="count", default
=0,
136 help="Reduce verbosity")
137 add_option('-v', "--verbose", action
="count", default
=0,
138 help="Increase verbosity")
141 set_group("Statistics Options")
142 add_option("--stats-file", metavar
="FILE", default
="m5stats.txt",
143 help="Sets the output file for statistics [Default: %default]")
146 set_group("Debugging Options")
147 add_option("--debug-break", metavar
="TIME[,TIME]", action
='append', split
=',',
148 help="Cycle to create a breakpoint")
151 set_group("Trace Options")
152 add_option("--trace-help", action
='store_true',
153 help="Print help on trace flags")
154 add_option("--trace-flags", metavar
="FLAG[,FLAG]", action
='append', split
=',',
155 help="Sets the flags for tracing (-FLAG disables a flag)")
156 add_option("--trace-start", metavar
="TIME", type='int',
157 help="Start tracing at TIME (must be in ticks)")
158 add_option("--trace-file", metavar
="FILE", default
="cout",
159 help="Sets the output file for tracing [Default: %default]")
160 add_option("--trace-ignore", metavar
="EXPR", action
='append', split
=':',
161 help="Ignore EXPR sim objects")
166 def usage(exitcode
=None):
168 if exitcode
is not None:
172 _opts
,args
= parser
.parse_args()
173 opts
= attrdict(_opts
.__dict
__)
175 # setting verbose and quiet at the same time doesn't make sense
176 if opts
.verbose
> 0 and opts
.quiet
> 0:
179 # store the verbosity in a single variable. 0 is default,
180 # negative numbers represent quiet and positive values indicate verbose
181 opts
.verbose
-= opts
.quiet
186 arguments
.extend(args
)
197 if options
.copyright
:
204 print 'Author information:'
216 if options
.release_notes
:
218 print 'Release Notes:'
220 print info
.RELEASE_NOTES
223 if options
.trace_help
:
226 print_list(traceflags
.baseFlags
, indent
=4)
228 print "Compound Flags:"
229 for flag
in traceflags
.compoundFlags
:
233 print_list(traceflags
.compoundFlagMap
[flag
], indent
=8)
239 if options
.verbose
>= 0:
240 print "M5 Simulator System"
241 print brief_copyright
243 print "M5 compiled %s" % internal
.main
.cvar
.compileDate
;
244 print "M5 started %s" % datetime
.now().ctime()
245 print "M5 executing on %s" % socket
.gethostname()
246 print "command line:",
247 for argv
in sys
.argv
:
251 # check to make sure we can find the listed script
252 if not arguments
or not os
.path
.isfile(arguments
[0]):
253 if arguments
and not os
.path
.isfile(arguments
[0]):
254 print "Script %s not found" % arguments
[0]
258 # tell C++ about output directory
259 internal
.main
.setOutputDir(options
.outdir
)
261 # update the system path with elements from the -p option
262 sys
.path
[0:0] = options
.path
267 internal
.stats
.initText(options
.stats_file
)
269 # set debugging options
270 for when
in options
.debug_break
:
271 internal
.debug
.schedBreakCycle(int(when
))
275 for flag
in options
.trace_flags
:
277 if flag
.startswith('-'):
280 if flag
not in traceflags
.allFlags
:
281 print >>sys
.stderr
, "invalid trace flag '%s'" % flag
285 off_flags
.append(flag
)
287 on_flags
.append(flag
)
289 for flag
in on_flags
:
290 internal
.trace
.set(flag
)
292 for flag
in off_flags
:
293 internal
.trace
.clear(flag
)
295 if options
.trace_start
:
297 internal
.trace
.cvar
.enabled
= True
298 internal
.event
.create(enable_trace
, int(options
.trace_start
))
300 internal
.trace
.cvar
.enabled
= True
302 internal
.trace
.output(options
.trace_file
)
304 for ignore
in options
.trace_ignore
:
305 internal
.trace
.ignore(ignore
)
308 sys
.path
= [ os
.path
.dirname(sys
.argv
[0]) ] + sys
.path
310 scope
= { '__file__' : sys
.argv
[0],
311 '__name__' : '__m5_main__' }
313 # we want readline if we're doing anything interactive
314 if options
.interactive
or options
.pdb
:
315 exec "import readline" in scope
317 # if pdb was requested, execfile the thing under pdb, otherwise,
318 # just do the execfile normally
322 debugger
.run('execfile("%s")' % sys
.argv
[0], scope
)
324 execfile(sys
.argv
[0], scope
)
326 # once the script is done
327 if options
.interactive
:
328 interact
= code
.InteractiveConsole(scope
)
329 interact
.interact("M5 Interactive Console")
331 if __name__
== '__main__':
332 from pprint
import pprint
337 pprint(options
, indent
=4)
341 pprint(arguments
, indent
=4)