python: cleanup options parsing stuff so that it properly deals with defaults.
While we're at it, make it possible to run main.py in a somewhat
standalone mode again so that we can test things without compiling.
diff --git a/src/python/m5/main.py b/src/python/m5/main.py
index 1e21771..66a422e 100644
--- a/src/python/m5/main.py
+++ b/src/python/m5/main.py
@@ -34,9 +34,7 @@
 
 from util import attrdict
 import config
-import defines
 from options import OptionParser
-import traceflags
 
 __all__ = [ 'options', 'arguments', 'main' ]
 
@@ -132,7 +130,6 @@
     help="List all built-in SimObjects, their parameters and default values")
 
 def main():
-    import defines
     import event
     import info
     import internal
@@ -176,6 +173,8 @@
     done = False
 
     if options.build_info:
+        import defines
+
         done = True
         print 'Build information:'
         print
@@ -217,6 +216,8 @@
         print
 
     if options.trace_help:
+        import traceflags
+
         done = True
         print "Base Flags:"
         print_list(traceflags.baseFlags, indent=4)
@@ -297,27 +298,30 @@
     for when in options.debug_break:
         internal.debug.schedBreakCycle(int(when))
 
-    on_flags = []
-    off_flags = []
-    for flag in options.trace_flags:
-        off = False
-        if flag.startswith('-'):
-            flag = flag[1:]
-            off = True
-        if flag not in traceflags.allFlags:
-            print >>sys.stderr, "invalid trace flag '%s'" % flag
-            sys.exit(1)
+    if options.trace_flags:
+        import traceflags
 
-        if off:
-            off_flags.append(flag)
-        else:
-            on_flags.append(flag)
+        on_flags = []
+        off_flags = []
+        for flag in options.trace_flags:
+            off = False
+            if flag.startswith('-'):
+                flag = flag[1:]
+                off = True
+            if flag not in traceflags.allFlags:
+                print >>sys.stderr, "invalid trace flag '%s'" % flag
+                sys.exit(1)
 
-    for flag in on_flags:
-        internal.trace.set(flag)
+            if off:
+                off_flags.append(flag)
+            else:
+                on_flags.append(flag)
 
-    for flag in off_flags:
-        internal.trace.clear(flag)
+        for flag in on_flags:
+            internal.trace.set(flag)
+
+        for flag in off_flags:
+            internal.trace.clear(flag)
 
     if options.trace_start:
         def enable_trace():
@@ -358,7 +362,14 @@
 if __name__ == '__main__':
     from pprint import pprint
 
-    parse_args()
+    # load the options.py config file to allow people to set their own
+    # default options
+    options_file = config.get('options.py')
+    if options_file:
+        scope = { 'options' : options }
+        execfile(options_file, scope)
+
+    arguments = options.parse_args()
 
     print 'opts:'
     pprint(options, indent=4)
diff --git a/src/python/m5/options.py b/src/python/m5/options.py
index 50eea42..1f534a3 100644
--- a/src/python/m5/options.py
+++ b/src/python/m5/options.py
@@ -28,7 +28,6 @@
 
 import optparse
 import sys
-import util
 
 from optparse import *
 
@@ -45,19 +44,20 @@
         else:
             dest.extend(values)
 
-class OptionParser(object):
+class OptionParser(dict):
     def __init__(self, *args, **kwargs):
         kwargs.setdefault('formatter', optparse.TitledHelpFormatter())
         self._optparse = optparse.OptionParser(*args, **kwargs)
         self._optparse.disable_interspersed_args()
 
         self._allopts = {}
-        self._defaults = {}
-        self._options = util.attrdict()
 
         # current option group
         self._group = self._optparse
 
+    def set_defaults(self, *args, **kwargs):
+        return self._optparse.set_defaults(*args, **kwargs)
+
     def set_group(self, *args, **kwargs):
         '''set the current option group'''
         if not args and not kwargs:
@@ -78,16 +78,11 @@
             kwargs['action'] = 'callback'
             kwargs['callback'] = splitter(split)
 
-        default = kwargs.pop('default', nodefault)
         option = self._group.add_option(*args, **kwargs)
         dest = option.dest
         if dest not in self._allopts:
             self._allopts[dest] = option
 
-        if default != nodefault:
-            if dest not in self._options:
-                self._options[dest] = default
-
         return option
 
     def bool_option(self, name, default, help):
@@ -113,28 +108,30 @@
 
     def __getattr__(self, attr):
         if attr.startswith('_'):
-            return super(OptionParser, self).__getattr__(attr)
+            return super(OptionParser, self).__getattribute__(attr)
 
-        if attr in self._options:
-            return self._options[attr]
+        if attr in self:
+            return self[attr]
 
-        raise AttributeError, "Option %s not found" % attr
+        return super(OptionParser, self).__getattribute__(attr)
 
     def __setattr__(self, attr, value):
         if attr.startswith('_'):
-            return super(OptionParser, self).__setattr__(attr, value)
-
-        if attr in self._options:
-            self._options[attr] = value
-
-        return super(OptionParser, self).__setattr__(attr, value)
+            super(OptionParser, self).__setattr__(attr, value)
+        elif attr in self._allopts:
+            defaults = { attr : value }
+            self.set_defaults(**defaults)
+            if attr in self:
+                self[attr] = value
+        else:
+            super(OptionParser, self).__setattr__(attr, value)
 
     def parse_args(self):
         opts,args = self._optparse.parse_args()
 
         for key,val in opts.__dict__.iteritems():
-            if val is not None or key not in self._options:
-                self._options[key] = val
+            if val is not None or key not in self:
+                self[key] = val
 
         return args