change log for rtems-tools (2010-08-08)

rtems-vc at rtems.org rtems-vc at rtems.org
Mon Aug 9 02:10:37 UTC 2010


 *ccj*:
branches:  1.1.1;
Initial revision

A    1.1  README

diff -u /dev/null rtems-tools/README:1.1
--- /dev/null	Sun Aug  8 21:10:35 2010
+++ rtems-tools/README	Sun Aug  8 20:04:21 2010
@@ -0,0 +1,10 @@
+RTEMS Tools
+
+The RTEMS Tools are a collection of packages, scripts and tools used by or with
+the RTEMS project to help maintain the RTEMS project or aid the users of RTEMS.
+
+If you have a script or tool you use that you think may be of use to the RTEMS
+community please post something about it the RTEMS Users List.
+
+Chris Johns
+9th August 2010


 *ccj* (on branch UNKNOWN):
Create RTEMS Tools.

A 1.1.1.1  README

diff -u /dev/null rtems-tools/README:1.1.1.1
--- /dev/null	Sun Aug  8 21:10:35 2010
+++ rtems-tools/README	Sun Aug  8 20:04:21 2010
@@ -0,0 +1,10 @@
+RTEMS Tools
+
+The RTEMS Tools are a collection of packages, scripts and tools used by or with
+the RTEMS project to help maintain the RTEMS project or aid the users of RTEMS.
+
+If you have a script or tool you use that you think may be of use to the RTEMS
+community please post something about it the RTEMS Users List.
+
+Chris Johns
+9th August 2010


 *ccj*:
2010-08-09      Chris Johns <chrisj at rtems.org>

        * specbuilder, specbuilder/sb-build, specbuilder/sb-crossgcc,
        specbuilder/sb-setup, specbuilder/sb-specdump,
        specbuilder/sb-status, specbuilder/specbuilder/.cvsignore,
        specbuilder/specbuilder/build.py,
        specbuilder/specbuilder/config.sub,
        specbuilder/specbuilder/crossgcc.py,
        specbuilder/specbuilder/darwin.py,
        specbuilder/specbuilder/defaults.py,
        specbuilder/specbuilder/error.py,
        specbuilder/specbuilder/execute.py,
        specbuilder/specbuilder/log.py, specbuilder/specbuilder/setup.py,
        specbuilder/specbuilder/spec.py,
        specbuilder/specbuilder/status.py: New.

A    1.1  ChangeLog
A    1.1  specbuilder/sb-build
A    1.1  specbuilder/sb-crossgcc
A    1.1  specbuilder/sb-setup
A    1.1  specbuilder/sb-specdump
A    1.1  specbuilder/sb-status
A    1.1  specbuilder/specbuilder/.cvsignore
A    1.1  specbuilder/specbuilder/build.py
A    1.1  specbuilder/specbuilder/config.sub
A    1.1  specbuilder/specbuilder/crossgcc.py
A    1.1  specbuilder/specbuilder/darwin.py
A    1.1  specbuilder/specbuilder/defaults.py
A    1.1  specbuilder/specbuilder/error.py
A    1.1  specbuilder/specbuilder/execute.py
A    1.1  specbuilder/specbuilder/log.py
A    1.1  specbuilder/specbuilder/setup.py
A    1.1  specbuilder/specbuilder/spec.py
A    1.1  specbuilder/specbuilder/status.py

diff -u /dev/null rtems-tools/ChangeLog:1.1
--- /dev/null	Sun Aug  8 21:10:35 2010
+++ rtems-tools/ChangeLog	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,15 @@
+2010-08-09	Chris Johns <chrisj at rtems.org>
+
+	* specbuilder, specbuilder/sb-build, specbuilder/sb-crossgcc,
+	specbuilder/sb-setup, specbuilder/sb-specdump,
+	specbuilder/sb-status, specbuilder/specbuilder/.cvsignore,
+	specbuilder/specbuilder/build.py,
+	specbuilder/specbuilder/config.sub,
+	specbuilder/specbuilder/crossgcc.py,
+	specbuilder/specbuilder/darwin.py,
+	specbuilder/specbuilder/defaults.py,
+	specbuilder/specbuilder/error.py,
+	specbuilder/specbuilder/execute.py,
+	specbuilder/specbuilder/log.py, specbuilder/specbuilder/setup.py,
+	specbuilder/specbuilder/spec.py,
+	specbuilder/specbuilder/status.py: New.

diff -u /dev/null rtems-tools/specbuilder/sb-build:1.1
--- /dev/null	Sun Aug  8 21:10:35 2010
+++ rtems-tools/specbuilder/sb-build	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,33 @@
+#! /usr/bin/env python
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import sys, os
+base = os.path.dirname(sys.argv[0])
+sys.path.insert(0, base + '/specbuilder')
+try:
+    import build
+    build.run(sys.argv)
+except ImportError:
+    print >> sys.stderr, "Incorrect SpecBulder installation"
+    sys.exit(1)

diff -u /dev/null rtems-tools/specbuilder/sb-crossgcc:1.1
--- /dev/null	Sun Aug  8 21:10:35 2010
+++ rtems-tools/specbuilder/sb-crossgcc	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,33 @@
+#! /usr/bin/env python
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import sys, os
+base = os.path.dirname(sys.argv[0])
+sys.path.insert(0, base + '/specbuilder')
+try:
+    import crossgcc
+    crossgcc.run()
+except ImportError:
+    print >> sys.stderr, "Incorrect SpecBulder installation"
+    sys.exit(1)

diff -u /dev/null rtems-tools/specbuilder/sb-setup:1.1
--- /dev/null	Sun Aug  8 21:10:35 2010
+++ rtems-tools/specbuilder/sb-setup	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,33 @@
+#! /usr/bin/env python
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import sys, os
+base = os.path.dirname(sys.argv[0])
+sys.path.insert(0, base + '/specbuilder')
+try:
+    import setup
+    setup.run()
+except ImportError:
+    print >> sys.stderr, "Incorrect SpecBulder installation"
+    sys.exit(1)

diff -u /dev/null rtems-tools/specbuilder/sb-specdump:1.1
--- /dev/null	Sun Aug  8 21:10:35 2010
+++ rtems-tools/specbuilder/sb-specdump	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,33 @@
+#! /usr/bin/env python
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import sys, os
+base = os.path.dirname(sys.argv[0])
+sys.path.insert(0, base + '/specbuilder')
+try:
+    import spec
+    spec.run()
+except ImportError:
+    print >> sys.stderr, "Incorrect SpecBulder installation"
+    sys.exit(1)

diff -u /dev/null rtems-tools/specbuilder/sb-status:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/sb-status	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,33 @@
+#! /usr/bin/env python
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import sys, os
+base = os.path.dirname(sys.argv[0])
+sys.path.insert(0, base + '/specbuilder')
+try:
+    import status
+    status.run()
+except ImportError:
+    print >> sys.stderr, "Incorrect SpecBulder installation"
+    sys.exit(1)

diff -u /dev/null rtems-tools/specbuilder/specbuilder/.cvsignore:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/.cvsignore	Sun Aug  8 20:29:43 2010
@@ -0,0 +1 @@
+*.pyc

diff -u /dev/null rtems-tools/specbuilder/specbuilder/build.py:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/build.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,411 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# This code builds a package given a spec file. It only builds to be installed
+# not to be package unless you run a packager around this.
+#
+
+import getopt
+import os
+import shutil
+import stat
+import sys
+import urllib2
+import urlparse
+
+import defaults
+import error
+import execute
+import log
+import spec
+
+#
+# Version of Spec Builder.
+#
+version = '0.1'
+
+def _notice(opts, text):
+    if not opts.quiet() and not log.default.has_stdout():
+        print text
+    log.output(text)
+    log.flush()
+
+class script:
+    """Create and manage a shell script."""
+
+    def __init__(self, quiet = True):
+        self.quiet = quiet
+        self.reset()
+
+    def reset(self):
+        self.body = []
+        self.lc = 0
+
+    def append(self, text):
+        if type(text) is str:
+            text = text.splitlines()
+        if not self.quiet:
+            i = 0
+            for l in text:
+                i += 1
+                log.output('script:%3d: ' % (self.lc + i) + l)
+        self.lc += len(text)
+        self.body.extend(text)
+
+    def write(self, name, check_for_errors = False):
+        s = None
+        try:
+            s = open(name, 'w')
+            s.write('\n'.join(self.body))
+            s.close()
+            os.chmod(name, stat.S_IRWXU | \
+                         stat.S_IRGRP | stat.S_IXGRP | \
+                         stat.S_IROTH | stat.S_IXOTH)
+        except IOError, err:
+            raise error.general('creating script: ' + name)
+        finally:
+            if s is not None:
+                s.close()
+
+class build:
+    """Build a package given a spec file."""
+
+    def __init__(self, name, _defaults, opts):
+        self.opts = opts
+        _notice(opts, 'building: ' + name)
+        self.spec = spec.file(name, _defaults = _defaults, opts = opts)
+        self.script = script(quiet = opts.quiet())
+
+    def _output(self, text):
+        if not self.opts.quiet():
+            log.output(text)
+
+    def rmdir(self, path):
+        if not self.opts.dry_run():
+            self._output('removing: ' + path)
+            if os.path.exists(path):
+                try:
+                    shutil.rmtree(path)
+                except IOError, err:
+                    raise error.error('error removing: ' + path)
+
+    def mkdir(self, path):
+        if not self.opts.dry_run():
+            self._output('making dir: ' + path)
+            try:
+                os.makedirs(path)
+            except IOError, err:
+                raise error.general('error creating path: ' + path)
+
+    def get_file(self, url, local):
+        if not os.path.isdir(os.path.dirname(local)):
+            raise error.general('source path not found: ' + os.path.dirname(local))
+        if not os.path.exists(local):
+            #
+            # Not localy found so we need to download it. Check if a URL
+            # has been provided on the command line.
+            #
+            url_bases = self.opts.urls()
+            urls = []
+            if url_bases is not None:
+                for base in url_bases:
+                    if base[-1:] != '/':
+                        base += '/'
+                    url_path = urlparse.urlsplit(url).path
+                    slash = url_path.rfind('/')
+                    if slash < 0:
+                        url_file = url_path
+                    else:
+                        url_file = url_path[slash + 1:]
+                    urls.append(urlparse.urljoin(base, url_file))
+            urls.append(url)
+            for url in urls:
+                _notice(self.opts, 'download: ' + url + ' -> ' + local)
+                if not self.opts.dry_run():
+                    failed = False
+                    _in = None
+                    _out = None
+                    try:
+                        _in = urllib2.urlopen(url)
+                        _out = open(local, 'wb')
+                        _out.write(_in.read())
+                    except IOError, err:
+                        _notice(self.opts, 'download: ' + url + ': failed: ' + str(err))
+                        if os.path.exists(local):
+                            os.remove(local)
+                        failed = True
+                    finally:
+                        if _out is not None:
+                            _out.close()
+                    if _in is not None:
+                        del _in
+                    if not failed:
+                        if not os.path.isfile(local):
+                            raise error.general('source is not a file: ' + local)
+                        return
+            raise error.general('downloading ' + url + ': all paths have failed, giving up')
+
+    def parse_url(self, url):
+        #
+        # Split the source up into the parts we need.
+        #
+        source = {}
+        source['url'] = url
+        source['path'] = os.path.dirname(url)
+        source['file'] = os.path.basename(url)
+        source['name'], source['ext'] = os.path.splitext(source['file'])
+        #
+        # Get the file. Checks the local source directory first.
+        #
+        source['local'] = os.path.join(self.spec.abspath('_sourcedir'), 
+                                       source['file'])
+        #
+        # Is the file compressed ?
+        #
+        esl = source['ext'].split('.')
+        if esl[-1:][0] == 'gz':
+            source['compressed'] = '%{__gzip} -dc'
+        elif esl[-1:][0] == 'bz2':
+            source['compressed'] = '%{__bzip2} -dc'
+        elif esl[-1:][0] == 'bz2':
+            source['compressed'] = '%{__zip} -u'
+        source['script'] = ''
+        return source
+
+    def source(self, package, source_tag):
+        #
+        # Scan the sources found in the spec file for the one we are
+        # after. Infos or tags are lists.
+        #
+        sources = package.sources()
+        url = None
+        for s in sources:
+            tag = s[len('source'):]
+            if tag.isdigit():
+                if int(tag) == source_tag:
+                    url = sources[s][0]
+                    break
+        if url is None:
+            raise error.general('source tag not found: source' + str(source_tag))
+        source = self.parse_url(url)
+        self.get_file(source['url'], source['local'])
+        if 'compressed' in source:
+            source['script'] = source['compressed'] + ' ' + \
+                source['local'] + ' | %{__tar_extract} -'
+        else:
+            source['script'] = '%{__tar_extract} ' + source['local']
+        return source
+
+    def patch(self, package, args):
+        #
+        # Scan the patches found in the spec file for the one we are
+        # after. Infos or tags are lists.
+        #
+        patches = package.patches()
+        url = None
+        for p in patches:
+            if args[0][1:].lower() == p:
+                url = patches[p][0]
+                break
+        if url is None:
+            raise error.general('patch tag not found: ' + args[0])
+        patch = self.parse_url(url)
+        self.get_file(patch['url'], patch['local'])
+        if 'compressed' in patch:
+            patch['script'] = patch['compressed'] + ' ' +  patch['local']
+        else:
+            patch['script'] = '%{__cat} ' + patch['local']
+        patch['script'] += ' | %{__patch} ' + ' '.join(args[1:])
+        self.script.append(self.spec.expand(patch['script']))
+
+    def setup(self, package, args):
+        self._output('prep: ' + package.name() + ': ' + ' '.join(args))
+        opts, args = getopt.getopt(args[1:], 'qDcTn:b:a:')
+        source_tag = 0
+        quiet = False
+        unpack_default_source = True
+        delete_before_unpack = True
+        create_dir = False
+        name = None
+        unpack_before_chdir = True
+        for o in opts:
+            if o[0] == '-q':
+                quiet = True
+            elif o[0] == '-D':
+                delete_before_unpack = False
+            elif o[0] == '-c':
+                create_dir = True
+            elif o[0] == '-T':
+                unpack_default_source = False
+            elif o[0] == '-n':
+                name = o[1]
+            elif o[0] == '-b':
+                unpack_before_chdir = True
+                if not o[1].isdigit():
+                    raise error.general('setup source tag no a number: ' + o[1])
+                source_tag = int(o[1])
+            elif o[0] == '-a':
+                unpack_before_chdir = False
+                source_tag = int(o[1])
+        source0 = None
+        source = self.source(package, source_tag)
+        if name is None:
+            if source:
+                name = source['name']
+            else:
+                name = source0['name']
+        self.script.append(self.spec.expand('cd %{_builddir}'))
+        if delete_before_unpack:
+            self.script.append(self.spec.expand('%{__rm} -rf ' + name))
+        if create_dir:
+            self.script.append(self.spec.expand('%{__mkdir_p} ' + name))
+        #
+        # If -a? then change directory before unpacking.
+        #
+        if not unpack_before_chdir:
+            self.script.append(self.spec.expand('cd ' + name))
+        #
+        # Unpacking the source. Note, treated the same as -a0.
+        #
+        if unpack_default_source and source_tag != 0:
+            source0 = self.source(package, 0)
+            if source0 is None:
+                raise error.general('no setup source0 tag found')
+            self.script.append(self.spec.expand(source0['script']))
+        self.script.append(self.spec.expand(source['script']))
+        if unpack_before_chdir:
+            self.script.append(self.spec.expand('cd ' + name))
+        self.script.append(self.spec.expand('%{__setup_post}'))
+        if create_dir:
+            self.script.append(self.spec.expand('cd ..'))
+
+    def run(self, command, shell_opts = '', cwd = None):
+        e = execute.capture_execution(log = log.default, dump = self.opts.quiet())
+        cmd = self.spec.expand('%{___build_shell} -ex ' + shell_opts + ' ' + command)
+        self._output('run: ' + cmd)
+        exit_code, proc, output = e.shell(cmd, cwd = cwd)
+        if exit_code != 0:
+            raise error.general('shell cmd failed: ' + cmd)
+
+    def builddir(self):
+        builddir = self.spec.abspath('_builddir')
+        self.rmdir(builddir)
+        if not self.opts.dry_run():
+            self.mkdir(builddir)
+
+    def prep(self, package):
+        self.script.append('echo "==> %prep:"')
+        _prep = package.prep()
+        for l in _prep:
+            args = l.split()
+            if args[0] == '%setup':
+                self.setup(package, args)
+            elif args[0].startswith('%patch'):
+                self.patch(package, args)
+            else:
+                self.script.append(' '.join(args))
+
+    def build(self, package):
+        self.script.append('echo "==> %build:"')
+        _build = package.build()
+        for l in _build:
+            args = l.split()
+            self.script.append(' '.join(args))
+
+    def install(self, package):
+        self.script.append('echo "==> %install:"')
+        _install = package.install()
+        for l in _install:
+            args = l.split()
+            self.script.append(' '.join(args))
+
+    def files(self, package):
+        self.script.append('echo "==> %files:"')
+        prefixbase = self.opts.prefixbase()
+        if prefixbase is None:
+            prefixbase = ''
+        inpath = os.path.join('%{buildroot}', prefixbase)
+        self.script.append(self.spec.expand('cd ' + inpath))
+        tar = os.path.join('%{_rpmdir}', package.long_name() + '.tar.bz2')
+        cmd = self.spec.expand('%{__tar} -cf - . ' + '| %{__bzip2} > ' + tar)
+        self.script.append(cmd)
+        self.script.append(self.spec.expand('cd %{_builddir}'))
+
+    def clean(self, package):
+        self.script.append('echo "==> %clean:"')
+        _clean = package.clean()
+        for l in _clean:
+            args = l.split()
+            self.script.append(' '.join(args))
+        
+    def cleanup(self):
+        buildroot = self.spec.abspath('buildroot')
+        builddir = self.spec.abspath('_builddir')
+        self.rmdir(buildroot)
+        self.rmdir(builddir)
+
+    def make(self):
+        packages = self.spec.packages()
+        package = packages['main']
+        _notice(self.opts, 'package: ' + package.name() + '-' + package.version())
+        self.script.reset()
+        self.script.append(self.spec.expand('%{___build_template}'))
+        self.script.append('echo "=> ' + package.name() + '-' + package.version() + ':"')
+        self.prep(package)
+        self.build(package)
+        self.install(package)
+        self.files(package)
+        if not self.opts.no_clean():
+            self.clean(package)
+        if not self.opts.dry_run():
+            self.builddir()
+            sn = self.spec.expand(os.path.join('%{_builddir}', 'doit'))
+            self._output('write script: ' + sn)
+            self.script.write(sn)
+            self.run(sn)
+        if not self.opts.no_clean():
+            self.cleanup()
+
+def run(args):
+    try:
+        opts, _defaults = defaults.load(args)
+        log.default = log.log(opts.logfiles())
+        _notice(opts, 'RTEMS Tools, Spec Builder, v%s' % (version))
+        for spec_file in opts.spec_files():
+            b = build(spec_file, _defaults = _defaults, opts = opts)
+            b.make()
+            del b
+    except error.general, gerr:
+        print gerr
+        sys.exit(1)
+    except error.internal, ierr:
+        print ierr
+        sys.exit(1)
+    except KeyboardInterrupt:
+        _notice(opts, 'user terminated')
+        sys.exit(1)
+    sys.exit(0)
+
+if __name__ == "__main__":
+    run(sys.argv)

diff -u /dev/null rtems-tools/specbuilder/specbuilder/config.sub:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/config.sub	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,1705 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2010-07-29'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+        -bluegene*)
+	        os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+        microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+        -auroraux)
+	        os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

diff -u /dev/null rtems-tools/specbuilder/specbuilder/crossgcc.py:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/crossgcc.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,157 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# This code builds a cross-gcc compiler suite of tools given an architecture.
+#
+
+import distutils.dir_util
+import operator
+import os
+
+import build
+import defaults
+import error
+import log
+
+#
+# Version of Spec CrossGCC Builder.
+#
+version = '0.1'
+
+def _notice(opts, text):
+    if not opts.quiet() and not log.default.has_stdout():
+        print text
+    log.output(text)
+    log.flush()
+
+class crossgcc:
+    """Build a Cross GCC Compiler tool suite."""
+
+    _order = { 'binutils': 0,
+               'gcc'     : 1,
+               'gdb'     : 2 }
+
+    def __init__(self, arch, _defaults, opts):
+        self.arch = arch
+        self.opts = opts
+        self.defaults = _defaults
+
+    def _output(self, text):
+        if not self.opts.quiet():
+            log.output(text)
+
+    def copy(self, src, dst):
+        what = src + ' -> ' + dst
+        _notice(self.opts, 'coping: ' + what)
+        try:
+            files = distutils.dir_util.copy_tree(src, dst)
+            for f in files:
+                self._output(f)
+        except IOError, err:
+            raise error.general('coping tree: ' + what + ': ' + str(err))
+
+    def first_package(self, _build):
+        path = os.path.join(_build.spec.abspath('%{_tmppath}'),
+                            _build.spec.expand('crossgcc-%(%{__id_u} -n)'))
+        _build.rmdir(path)
+        _build.mkdir(path)
+        prefix = os.path.join(_build.spec.expand('%{_prefix}'), 'bin')
+        if prefix[0] == os.sep:
+            prefix = prefix[1:]
+        binpath = os.path.join(path, prefix)
+        os.environ['PATH'] = binpath + os.pathsep + os.environ['PATH']
+        self._output('path: ' + os.environ['PATH'])
+        return path
+
+    def every_package(self, _build, path):
+        self.copy(_build.spec.abspath('%{buildroot}'), path)
+        _build.cleanup()
+
+    def last_package(self, _build, path):
+        tar = os.path.join('%{_rpmdir}', self.arch + '-tools.tar.bz2')
+        cmd = _build.spec.expand("'cd " + path + \
+                                     " && %{__tar} -cf - . | %{__bzip2} > " + tar + "'")
+        _build.run(cmd, shell_opts = '-c', cwd = path)
+        if not self.opts.no_clean():
+            _build.rmdir(path)
+
+    def make(self):
+
+        def _sort(specs):
+            _specs = {}
+            for spec in specs:
+                for order in crossgcc._order:
+                    if spec.lower().find(order) >= 0:
+                        _specs[spec] = crossgcc._order[order]
+            sorted_specs = sorted(_specs.iteritems(), key = operator.itemgetter(1))
+            specs = []
+            for s in range(0, len(sorted_specs)):
+                specs.append(sorted_specs[s][0])
+            return specs
+
+        _notice(self.opts, 'arch: ' + self.arch)
+        specs = self.opts.get_spec_files('*' + self.arch + '*')
+        arch_specs = []
+        for spec in specs:
+            if spec.lower().find(self.arch.lower()) >= 0:
+                arch_specs.append(spec)
+        arch_specs = _sort(arch_specs)
+        self.opts.opts['no-clean'] = '1'
+        current_path = os.environ['PATH']
+        try:
+            for s in range(0, len(arch_specs)):
+                b = build.build(arch_specs[s], _defaults = self.defaults, opts = self.opts)
+                if s == 0:
+                    path = self.first_package(b)
+                b.make()
+                self.every_package(b, path)
+                if s == len(arch_specs) - 1:
+                    self.last_package(b, path)
+                del b
+        finally:
+            os.environ['PATH'] = current_path
+
+def run():
+    import sys
+    try:
+        opts, _defaults = defaults.load(sys.argv)
+        log.default = log.log(opts.logfiles())
+        _notice(opts, 'RTEMS Tools, CrossGCC Spec Builder, v%s' % (version))
+        for arch in opts.params():
+            c = crossgcc(arch, _defaults = _defaults, opts = opts)
+            c.make()
+            del c
+    except error.general, gerr:
+        print gerr
+        sys.exit(1)
+    except error.internal, ierr:
+        print ierr
+        sys.exit(1)
+    except KeyboardInterrupt:
+        _notice(opts, 'user terminated')
+        sys.exit(1)
+    sys.exit(0)
+
+if __name__ == "__main__":
+    run()

diff -u /dev/null rtems-tools/specbuilder/specbuilder/darwin.py:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/darwin.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,52 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# This code is based on what ever doco about spec files I could find and 
+# RTEMS project's spec files.
+#
+
+import pprint
+import os
+
+def load():
+    uname = os.uname()
+    defines = { 
+        '_os':                     'darwin',
+        '_host':                   uname[4] + '-apple-darwin' + uname[2],
+        '_host_vendor':            'apple',
+        '_host_os':                'darwin',
+        '_host_cpu':               uname[4],
+        '_host_alias':             '%{nil}',
+        '_host_arch':              uname[4],
+        '_usr':                    '/opt/local',
+        '_var':                    '/opt/local/var',
+        'optflags':                '-O2 -fasynchronous-unwind-tables',
+        '_smp_mflags':             '-j4',
+        # Build readline with gdb.
+        'without_system_readline': 'without_system_readline'
+        }
+    return defines
+
+if __name__ == '__main__':
+    pprint.pprint(load())

diff -u /dev/null rtems-tools/specbuilder/specbuilder/defaults.py:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/defaults.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,407 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Determine the defaults and load the specific file.
+#
+
+import glob
+import pprint
+import re
+import os
+
+import error
+import execute
+
+defaults = {
+# Hack. Suspect a hidden platform or comand line thing
+'_with_noarch_subpackages': '1',
+
+# Paths
+'_host_platform': '%{_host_cpu}-%{_host_vendor}-%{_host_os}%{?_gnu}',
+'_build':         '%{_host}',
+'_arch':          '%{_host_arch}',
+'_topdir':        os.getcwd(),
+'_srcrpmdir':     '%{_topdir}/SRPMS',
+'_sourcedir':     '%{_topdir}/SOURCES', 
+'_specdir':       '%{_topdir}/SPECS',
+'_rpmdir':        '%{_topdir}/TARS',
+'_builddir':      '%{_topdir}/BUILD/%{name}-%{version}-%{release}',
+'_docdir':        '%{_defaultdocdir}',
+'_usrlibrpm':     '%{_topdir}/RPMLIB',
+'_tmppath':       '%{_topdir}/TMP',
+'buildroot:':     '%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)',
+
+# Not sure.
+'_gnu':           '-gnu',
+
+# Cloned stuff from an RPM insall
+'___build_args': '-e',
+'___build_cmd':  '%{?_sudo:%{_sudo} }%{?_remsh:%{_remsh} %{_remhost} }%{?_remsudo:%{_remsudo} }%{?_remchroot:%{_remchroot} %{_remroot} }%{___build_shell} %{___build_args}',
+'___build_post': 'exit 0',
+'___build_pre': '''# ___build_pre in defaults.py
+RPM_SOURCE_DIR="%{_sourcedir}"
+RPM_BUILD_DIR="%{_builddir}"
+RPM_OPT_FLAGS="%{optflags}"
+RPM_ARCH="%{_arch}"
+RPM_OS="%{_os}"
+export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS
+RPM_DOC_DIR="%{_docdir}"
+export RPM_DOC_DIR
+RPM_PACKAGE_NAME="%{name}"
+RPM_PACKAGE_VERSION="%{version}"
+RPM_PACKAGE_RELEASE="%{release}"
+export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE
+%{?buildroot:RPM_BUILD_ROOT="%{buildroot}"}
+export RPM_BUILD_ROOT
+%{?_javaclasspath:CLASSPATH="%{_javaclasspath}"; export CLASSPATH}
+LANG=C
+export LANG
+unset DISPLAY || :
+umask 022
+cd "%{_builddir}"''',
+'___build_shell': '%{?_buildshell:%{_buildshell}}%{!?_buildshell:/bin/sh}',
+'___build_template': '''#!%{___build_shell}
+%{___build_pre}
+%{nil}''',
+'__aclocal':           'aclocal',
+'__ar':                'ar',
+'__arch_install_post': '%{nil}',
+'__as':                'as',
+'__autoconf':          'autoconf',
+'__autoheader':        'autoheader',
+'__automake':          'automake',
+'__awk':               'awk',
+'__bash':              '/bin/bash',
+'__bzip2':             '/usr/bin/bzip2',
+'__cat':               '/bin/cat',
+'__cc':                '/usr/bin/gcc',
+'__check_files':       '%{_usrlibrpm}/check-files %{buildroot}',
+'__chgrp':             '/usr/bin/chgrp',
+'__chmod':             '/bin/chmod',
+'__chown':             '/usr/sbin/chown',
+'__cp':                '/bin/cp',
+'__cpio':              '/usr/bin/cpio',
+'__cpp':               '/usr/bin/gcc -E',
+'__cxx':               '/usr/bin/g++',
+'__grep':              '/usr/bin/grep',
+'__gzip':              '/usr/bin/gzip',
+'__id':                '/usr/bin/id',
+'__id_u':              '%{__id} -u',
+'__install':           '/usr/bin/install',
+'__install_info':      '/usr/bin/install-info',
+'__ld':                '/usr/bin/ld',
+'__ldconfig':          '/sbin/ldconfig',
+'__ln_s':              'ln -s',
+'__make':              '/usr/bin/make',
+'__mkdir':             '/bin/mkdir',
+'__mkdir_p':           '/bin/mkdir -p',
+'__mv':                '/bin/mv',
+'__nm':                '/usr/bin/nm',
+'__objcopy':           '%{_bindir}/objcopy',
+'__objdump':           '%{_bindir}/objdump',
+'__patch':             '/usr/bin/patch',
+'__perl':              'perl',
+'__perl_provides':     '%{_usrlibrpm}/perl.prov',
+'__perl_requires':     '%{_usrlibrpm}/perl.req',
+'__ranlib':            'ranlib',
+'__remsh':             '%{__rsh}',
+'__rm':                '/bin/rm',
+'__rsh':               '/usr/bin/rsh',
+'__sed':               '/usr/bin/sed',
+'__setup_post':        '%{__chmod} -R a+rX,g-w,o-w .',
+'__sh':                '/bin/sh',
+'__tar':               '/usr/bin/tar',
+'__tar_extract':       '%{__tar} -xvvf',
+'__unzip':             '/usr/bin/unzip',
+'_datadir':            '%{_prefix}/share',
+'_defaultdocdir':      '%{_prefix}/share/doc',
+'_exeext':             '',
+'_exec_prefix':        '%{_prefix}',
+'_lib':                'lib',
+'_libdir':             '%{_exec_prefix}/%{_lib}',
+'_libexecdir':         '%{_exec_prefix}/libexec',
+'_localedir':          '%{_datadir}/locale',
+'_localstatedir':      '%{_prefix}/var',
+'_usr':                '/usr/local',
+'_usrsrc':             '%{_usr}/src',
+'_var':                '/usr/local/var',
+'_varrun':             '%{_var}/run',
+'nil':                 ''
+}
+
+class command_line:
+    """Process the command line in a common way across all speculater commands."""
+
+    _defaults = { 'params'   : [],
+                  'warn-all' : '0',
+                  'quiet'    : '0',
+                  'trace'    : '0',
+                  'dry-run'  : '0',
+                  'no-clean' : '0' }
+
+    _long_opts = { '--prefix'     : '_prefix',
+                   '--prefixbase' : '_prefixbase',
+                   '--topdir'     : '_topdir',
+                   '--specdir'    : '_specdir',
+                   '--builddir'   : '_builddir',
+                   '--sourcedir'  : '_sourcedir',
+                   '--usrlibrpm'  : '_usrlibrpm',
+                   '--tmppath'    : '_tmppath',
+                   '--log'        : '_logfile',
+                   '--url'        : '_url_base' }
+
+    _long_true_opts = { '--trace'    : '_trace',
+                        '--warn-all' : '_warn_all',
+                        '--no-clean' : '_no_clean' }
+
+    _target_triplets = { '--host'   :   '_host',
+                         '--build'  :  '_build',
+                         '--target' : '_target' }
+
+    def __init__(self, argv):
+        self.command_path = os.path.dirname(argv[0])
+        if len(self.command_path) == 0:
+            self.command_path = '.'
+        self.command_name = os.path.basename(argv[0])
+        self.args = argv[1:]
+        self.defaults = {}
+        for to in command_line._long_true_opts:
+            self.defaults[command_line._long_true_opts[to]] = '0'
+        self._process()
+
+    def __str__(self):
+        def _dict(dd):
+            s = ''
+            ddl = dd.keys()
+            ddl.sort()
+            for d in ddl:
+                s += '  ' + d + ': ' + str(dd[d]) + '\n'
+            return s
+
+        s = 'command: ' + self.command() + \
+            '\nargs: ' + str(self.args) + \
+            '\nopts:\n' + _dict(self.opts)
+
+        return s
+
+    def _expand(self, s, _defaults):
+        """Simple basic expander of spec file macros."""
+        mf = re.compile(r'%{[^}]+}')
+        expanded = True
+        while expanded:
+            expanded = False
+            for m in mf.findall(s):
+                name = m[2:-1]
+                if name in _defaults:
+                    s = s.replace(m, _defaults[name])
+                    expanded = True
+                else:
+                    raise error.general('cannot process default macro: ' + m)
+        return s
+
+    def _process(self):
+
+        def _process_lopt(opt, arg, long_opts, args, values = False):
+            for lo in long_opts:
+                if values and opt.startswith(lo):
+                    equals = opt.find('=')
+                    if equals < 0:
+                        if arg == len(args) - 1:
+                            raise error.general('missing option value: ' + lo)
+                        arg += 1
+                        value = args[arg]
+                    else:
+                        value = opt[equals + 1:]
+                    return lo, long_opts[lo], value, arg
+                elif opt == lo:
+                    return lo, long_opts[lo], True, arg
+            return None, None, None, arg
+
+        self.opts = command_line._defaults
+        i = 0
+        while i < len(self.args):
+            a = self.args[i]
+            if a.startswith('-'):
+                if a.startswith('--'):
+                    if a.startswith('--warn-all'):
+                        self.opts['warn-all'] = True
+                    else:
+                        lo, macro, value, i = _process_lopt(a, i,
+                                                            command_line._long_true_opts,
+                                                            self.args)
+                        if lo:
+                            self.defaults[macro] = '1'
+                            self.opts[lo[2:]] = '1'
+                        else:
+                            lo, macro, value, i = _process_lopt(a, i,
+                                                                command_line._long_opts,
+                                                                self.args, True)
+                            if lo:
+                                self.defaults[macro] = value
+                                self.opts[lo[2:]] = value
+                            else:
+                                #
+                                # The target triplet is 'cpu-vendor-os'.
+                                #
+                                lo, macro, value, i = _process_lopt(a, i,
+                                                                    command_line._target_triplets,
+                                                                    self.args, True)
+                                if lo:
+                                    #
+                                    # This is a target triplet. Run it past config.sub to make
+                                    # make sure it is ok.
+                                    #
+                                    e = execute.capture_execution()
+                                    config_sub = os.path.join(self.command_path, 'config.sub')
+                                    exit_code, proc, output = e.shell(config_sub + ' ' + value)
+                                    if exit_code == 0:
+                                        value = output
+                                    self.defaults[macro] = value
+                                    self.opts[lo[2:]] = value
+                                    _arch = macro + '_cpu'
+                                    _vendor = macro + '_vendor'
+                                    _os = macro + '_os'
+                                    _arch_value = ''
+                                    _vendor_value = ''
+                                    _os_value = ''
+                                    dash = value.find('-')
+                                    if dash >= 0:
+                                        _arch_value = value[:dash]
+                                        value = value[dash + 1:]
+                                    dash = value.find('-')
+                                    if dash >= 0:
+                                        _vendor_value = value[:dash]
+                                        value = value[dash + 1:]
+                                    if len(value):
+                                        _os_value = value
+                                    self.defaults[_arch] = _arch_value
+                                    self.defaults[_vendor] = _vendor_value
+                                    self.defaults[_os] = _os_value
+                                if not lo:
+                                    raise error.general('invalid argument: ' + a)
+                else:
+                    if a == '-n':
+                        self.opts['dry-run'] = '1'
+                    elif a == '-q':
+                        self.opts['quiet'] = '1'
+            else:
+                self.opts['params'].append(a)
+            i += 1
+
+    def _post_process(self, _defaults):
+        pass
+
+    def command(self):
+        return os.path.join(self.command_path, self.command_name)
+        
+    def dry_run(self):
+        return self.opts['dry-run'] != '0'
+
+    def quiet(self):
+        return self.opts['quiet'] != '0'
+
+    def trace(self):
+        return self.opts['trace'] != '0' 
+
+    def warn_all(self):
+        return self.opts['warn-all'] != '0'
+
+    def no_clean(self):
+        return self.opts['no-clean'] != '0'
+
+    def params(self):
+        return self.opts['params']
+
+    def get_spec_files(self, spec):
+        if spec.find('*') >= 0 or spec.find('?'):
+            specdir = os.path.dirname(spec)
+            specbase = os.path.basename(spec)
+            if len(specbase) == 0:
+                specbase = '*'
+            if len(specdir) == 0:
+                specdir = self._expand(defaults['_specdir'], defaults)
+            if not os.path.isdir(specdir):
+                raise error.general('specdir is not a directory or does not exist: ' + specdir)
+            files = glob.glob(os.path.join(specdir, specbase))
+            specs = files
+        else:
+            specs = [spec]
+        return specs
+
+    def spec_files(self):
+        specs = []
+        for spec in self.opts['params']:
+            specs.extend(self.get_spec_files(spec))
+        return specs
+
+    def logfiles(self):
+        if 'log' in self.opts:
+            return self.opts['log'].split(',')
+        return ['stdout']
+
+    def urls(self):
+        if 'url' in self.opts:
+            return self.opts['url'].split(',')
+        return None
+
+    def prefixbase(self):
+        if 'prefixbase' in self.opts:
+            return self.opts['prefixbase']
+        return None
+
+def load(args):
+    """
+    Copy the defaults, get the host specific values and merge
+    them overriding any matching defaults, then create an options
+    object to handle the command line merging in any command line
+    overrides. Finally post process the command line.
+    """
+    d = defaults
+    overrides = None
+    uname = os.uname()
+    if uname[0] == 'Darwin':
+        import darwin
+        overrides = darwin.load()
+    for k in overrides:
+        d[k] = overrides[k]
+    o = command_line(args)
+    for k in o.defaults:
+        d[k] = o.defaults[k]
+    o._post_process(d)
+    return o, d
+
+if __name__ == '__main__':
+    import sys
+    try:
+        _opts, _defaults = load(args = sys.argv)
+        print _opts
+        pprint.pprint(_defaults)
+    except error.general, gerr:
+        print gerr
+        sys.exit(1)
+    except error.internal, ierr:
+        print ierr
+        sys.exit(1)
+    sys.exit(0)
+

diff -u /dev/null rtems-tools/specbuilder/specbuilder/error.py:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/error.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,53 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Various errors we can raise.
+#
+
+class error(Exception):
+    """Base class for Builder exceptions."""
+    def set_output(self, msg):
+        self.msg = msg
+    def __str__(self):
+        return self.msg
+
+class general(error):
+    """Raise for a general error."""
+    def __init__(self, what):
+        self.set_output('error: ' + what)
+    
+class internal(error):
+    """Raise for an internal error."""
+    def __init__(self, what):
+        self.set_output('internal error: ' + what)
+    
+if __name__ == '__main__':
+    try:
+        raise general('a general error')
+    except general, gerr:
+        print 'caught:', gerr
+    try:
+        raise internal('an internal error')
+    except internal, ierr:
+        print 'caught:', ierr

diff -u /dev/null rtems-tools/specbuilder/specbuilder/execute.py:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/execute.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,367 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Execute commands or scripts.
+#
+# Note, the subprocess module is only in Python 2.4 or higher.
+#
+
+import os
+import re
+import sys
+import subprocess
+import threading
+
+import error
+import log
+
+# Redefine the PIPE from subprocess
+PIPE = subprocess.PIPE
+
+# Regular expression to find quotes.
+qstr = re.compile('[rR]?\'([^\\n\'\\\\]|\\\\.)*\'|[rR]?"([^\\n"\\\\]|\\\\.)*"')
+
+def check_type(command):
+    """Checks the type of command we have. The types are spawn and
+    shell."""
+    if command in ['spawn', 'shell']:
+        return True
+    return False
+
+def arg_list(args):
+    """Turn a string of arguments into a list suitable for
+    spawning a command. If the args are already a list return
+    it."""
+    if type(args) is list:
+        return args
+    argstr = args
+    args = []
+    while len(argstr):
+        qs = qstr.search(argstr)
+        if not qs:
+            args.extend(argstr.split())
+            argstr= ''
+        else:
+            # We have a quoted string. Get the string before
+            # the quoted string and spltt on white space then
+            # add the quoted string as an option then remove
+            # the first + quoted string and try again
+            front = argstr[:qs.start()]
+            args.extend(front.split())
+            args.append(argstr[qs.start() + 1:qs.end() - 1])
+            argstr = argstr[qs.end():]
+    return args
+
+def arg_subst(command, substs):
+    """Substitute the %[0-9] in the command with the subst values."""
+    args = arg_list(command)
+    if substs:
+        for a in range(0, len(args)):
+            for r in range(0, len(substs)):
+                args[a] = re.compile(('%%%d' % (r))).sub(substs[r], args[a])
+    return args
+
+def arg_subst_str(command, subst):
+    cmd = arg_subst(command, subst)
+    def add(x, y): return x + ' ' + str(y)
+    return reduce(add, cmd, '')
+
+class execute:
+    """Execute commands or scripts. The 'output' is a funtion
+    that handles the output from the process."""
+    def __init__(self, output = None, error_prefix = '', verbose = False):
+        self.output = output
+        self.error_prefix = error_prefix
+        self.verbose = verbose
+        self.shell_exe = None
+        self.shell_commands = False
+        self.path = None
+        self.environment = None
+
+    def capture(self, proc, timeout = None):
+        """Create 2 threads to read stdout and stderr and send to the
+        output handler. Based on the 'communicate' code in the subprocess
+        module."""
+        def _readthread(fh, out, prefix = ''):
+            """Read from a file handle and write to the output handler
+            until the file closes."""
+            while True:
+                line = fh.readline()
+                if len(line) == 0:
+                    break
+                if out:
+                    out(prefix + line)
+                else:
+                    log.output(prefix + line)
+        def _timerthread(proc, timer):
+            """Timer thread calls the timer handler if one
+            is present once a second. The user provides a handler
+            and returns False to kill the process or True continue."""
+            while True:
+                time.sleep(1)
+                if not timer(proc):
+                    proc.stdout.close()
+                    proc.stderr.close()
+
+        if proc.stdout:
+            stdout_thread = threading.Thread(target = _readthread,
+                                             args = (proc.stdout,
+                                                     self.output,
+                                                     ''))
+            stdout_thread.setDaemon(True)
+            stdout_thread.start()
+        if proc.stderr:
+            stderr_thread = threading.Thread(target = _readthread,
+                                             args = (proc.stderr,
+                                                     self.output,
+                                                     self.error_prefix))
+            stderr_thread.setDaemon(True)
+            stderr_thread.start()
+        if proc.stdout:
+            stdout_thread.join()
+        if proc.stderr:
+            stderr_thread.join()
+        return proc.wait()
+
+    def open(self, command, capture = True, shell = False,
+             cwd = None, env = None,
+             stdin = None, stdout = None, stderr = None):
+        """Open a command with arguments. Provide the arguments as a list or
+        a string."""
+        if self.verbose:
+            s = command
+            if type(command) is list:
+                def add(x, y): return x + ' ' + str(y)
+                s = reduce(add, command, '')[1:]
+            what = 'spawn'
+            if shell:
+                what = 'shell'
+            log.output(what + ': ' + s)
+        if shell and self.shell_exe:
+            command = arg_list(command)
+            command[:0] = self.shell_exe
+        if not stdout:
+            stdout = subprocess.PIPE
+        if not stderr:
+            stderr = subprocess.PIPE
+        proc = None
+        if cwd is None:
+            cwd = self.path
+        if env is None:
+            env = self.environment
+        try:
+            # Work around a problem on Windows with commands that
+            # have a '.' and no extension. Windows needs the full
+            # command name.
+            if sys.platform == "win32" and type(command) is list:
+                if command[0].find('.') >= 0:
+                    r, e = os.path.splitext(command[0])
+                    if e not in ['.exe', '.com', '.bat']:
+                        command[0] = command[0] + '.exe'
+            proc = subprocess.Popen(command, shell = shell,
+                                    cwd = cwd, env = env,
+                                    stdin = stdin, stdout = stdout,
+                                    stderr = stderr)
+            if not capture:
+                return (0, proc)
+            exit_code = self.capture(proc)
+            if self.verbose:
+                log.output('exit: ' + str(exit_code))
+        except OSError, ose:
+            exit_code = ose.errno
+            if self.verbose:
+                log.output('exit: ' + str(ose))
+        return (exit_code, proc)
+
+    def spawn(self, command, capture = True, cwd = None, env = None,
+              stdin = None, stdout = None, stderr = None):
+        """Spawn a command with arguments. Provide the arguments as a list or
+        a string."""
+        return self.open(command, capture, False, cwd, env,
+                         stdin, stdout, stderr)
+
+    def shell(self, command, capture = True, cwd = None, env = None,
+              stdin = None, stdout = None, stderr = None):
+        """Execute a command within a shell context. The command can contain
+        argumments. The shell is specific to the operating system. For example
+        it is cmd.exe on Windows XP."""
+        return self.open(command, capture, True, cwd, env,
+                         stdin, stdout, stderr)
+
+    def command(self, command, args = None, capture = True, shell = False,
+                cwd = None, env = None,
+                stdin = None, stdout = None, stderr = None):
+        """Run the command with the args. The args can be a list
+        or a string."""
+        if args and not type(args) is list:
+            args = arg_list(args)
+        cmd = [command]
+        if args:
+            cmd.extend(args)
+        return self.open(cmd, capture = capture, shell = shell,
+                         cwd = cwd, env = env,
+                         stdin = stdin, stdout = stdout, stderr = stderr)
+
+    def command_subst(self, command, substs, capture = True, shell = False,
+                      cwd = None, env = None,
+                      stdin = None, stdout = None, stderr = None):
+        """Run the command from the config data with the
+        option format string subsituted with the subst variables."""
+        args = arg_subst(command, substs)
+        return self.command(args[0], args[1:], capture = capture,
+                            shell = shell or self.shell_commands,
+                            cwd = cwd, env = env,
+                            stdin = stdin, stdout = stdout, stderr = stderr)
+
+    def set_shell(self, execute):
+        """Set the shell to execute when issuing a shell command."""
+        args = arg_list(execute)
+        if len(args) == 0 or not os.path.isfile(args[0]):
+            raise error.general('could find shell: ' + execute)
+        self.shell_exe = args
+
+    def command_use_shell(self):
+        """Force all commands to use a shell. This can be used with set_shell
+        to allow Unix commands be executed on Windows with a Unix shell such
+        as Cygwin or MSYS. This may cause piping to fail."""
+        self.shell_commands = True
+
+    def set_output(self, output):
+        """Set the output handler. The stdout of the last process in a pipe
+        line is passed to this handler."""
+        old_output = self.output
+        self.output = output
+        return old_output
+
+    def set_path(self, path):
+        """Set the path changed to before the child process is created."""
+        old_path = self.path
+        self.path = path
+        return old_path
+
+    def set_environ(self, environment):
+        """Set the environment passed to the child process when created."""
+        old_environment = self.environment
+        self.environment = environment
+        return old_environment
+
+class capture_execution(execute):
+    """Capture all output as a string and return it."""
+
+    class _output_snapper:
+        def __init__(self, log = None, dump = False):
+            self.output = ''
+            self.log = log
+            self.dump = dump
+
+        def handler(self, text):
+            if not self.dump:
+                if self.log is not None:
+                    self.log.output(text)
+                else:
+                    self.output += text
+
+        def get_and_clear(self):
+            text = self.output
+            self.output = ''
+            return text.strip()
+
+    def __init__(self, log = None, dump = False, error_prefix = '', verbose = False):
+        self.snapper = capture_execution._output_snapper(log = log, dump = dump)
+        execute.__init__(self, output = self.snapper.handler,
+                         error_prefix = error_prefix,
+                         verbose = verbose)
+
+    def open(self, command, capture = True, shell = False, cwd = None, env = None,
+             stdin = None, stdout = None, stderr = None):
+        if not capture:
+            raise error.general('output capture must be true; leave as default')
+        #self.snapper.get_and_clear()
+        exit_code, proc = execute.open(self, command, capture = True, shell = shell,
+                                       cwd = cwd, env = env, 
+                                       stdin = stdin, stdout = stdout, stderr = stderr)
+        return (exit_code, proc, self.snapper.get_and_clear())
+
+    def set_output(self, output):
+        raise error.general('output capture cannot be overrided')
+
+if __name__ == "__main__":
+    def run_tests(e, commands, use_shell):
+        for c in commands['shell']:
+            e.shell(c)
+        for c in commands['spawn']:
+            e.spawn(c)
+        for c in commands['cmd']:
+            if type(c) is str:
+                e.command(c, shell = use_shell)
+            else:
+                e.command(c[0], c[1], shell = use_shell)
+        for c in commands['csubsts']:
+            e.command_subst(c[0], c[1], shell = use_shell)
+        ec, proc = e.command(commands['pipe'][0], commands['pipe'][1],
+                             capture = False, stdin = subprocess.PIPE)
+        if ec == 0:
+            print 'piping input into ' + commands['pipe'][0] + ': ' + \
+                  commands['pipe'][2]
+            proc.stdin.write(commands['pipe'][2])
+            proc.stdin.close()
+            e.capture(proc)
+            del proc
+        
+    cmd_shell_test = 'if "%OS%" == "Windows_NT" (echo It is WinNT) else echo Is is not WinNT'
+    sh_shell_test = 'x="me"; if [ $x = "me" ]; then echo "It was me"; else "It was him"; fi'
+    
+    commands = {}
+    commands['windows'] = {}
+    commands['unix'] = {}
+    commands['windows']['shell'] = ['cd', 'dir /w', '.\\xyz', cmd_shell_test]
+    commands['windows']['spawn'] = ['hostname', 'hostnameZZ', ['netstat', '/e']]
+    commands['windows']['cmd'] = [('ipconfig'), ('nslookup', 'www.python.org')]
+    commands['windows']['csubsts'] = [('netstat %0', ['-a']),
+                                      ('netstat %0 %1', ['-a', '-n'])]
+    commands['windows']['pipe'] = ('ftp', None, 'help\nquit')
+    commands['unix']['shell'] = ['pwd', 'ls -las', './xyz', sh_shell_test]
+    commands['unix']['spawn'] = ['ls', 'execute.pyc', ['ls', '-i']]
+    commands['unix']['cmd'] = [('date'), ('date', '-R'), ('date', ['-u', '+%d %D']),
+                               ('date', '-u "+%d %D %S"')]
+    commands['unix']['csubsts'] = [('date %0 "+%d %D %S"', ['-u']),
+                                   ('date %0 %1', ['-u', '+%d %D %S'])]
+    commands['unix']['pipe'] = ('grep', 'hello', 'hello world')
+    
+    print arg_list('cmd a1 a2 "a3 is a string" a4')
+    print arg_list('cmd b1 b2 "b3 is a string a4')
+    print arg_subst(['nothing', 'xx-%0-yyy', '%1', '%2-something'],
+                    ['subst0', 'subst1', 'subst2'])
+    
+    e = execute(error_prefix = 'ERR: ', verbose = True)
+    if sys.platform == "win32":
+        run_tests(e, commands['windows'], False)
+        if os.path.exists('c:\\msys\\1.0\\bin\\sh.exe'):
+            e.set_shell('c:\\msys\\1.0\\bin\\sh.exe --login -c')
+            commands['unix']['pipe'] = ('c:\\msys\\1.0\\bin\\grep',
+                                        'hello', 'hello world')
+            run_tests(e, commands['unix'], True)
+    else:
+        run_tests(e, commands['unix'], False)
+    del e

diff -u /dev/null rtems-tools/specbuilder/specbuilder/log.py:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/log.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,115 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-testing'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Log output to stdout and/or a file.
+#
+
+import os
+import sys
+
+import error
+
+#
+# A global log.
+#
+default = None
+
+def set_default_once(log):
+    if default is None:
+        default = log
+
+def output(text = os.linesep, log = None):
+    """Output the text to a log if provided else send it to stdout."""
+    if text is None:
+        text = os.linesep
+    if type(text) is list:
+        _text = ''
+        for l in text:
+            _text += l + os.linesep
+        text = _text
+    if log:
+        log.output(text)
+    elif default is not None:
+        default.output(text)
+    else:
+        for l in text.replace(chr(13), '').splitlines():
+            print l
+
+def flush(log = None):
+    if log:
+        log.flush()
+    elif default is not None:
+        default.flush()
+
+class log:
+    """Log output to stdout or a file."""
+    def __init__(self, streams = None):
+        self.fhs = [None, None]
+        if streams:
+            for s in streams:
+                if s == 'stdout':
+                    self.fhs[0] = sys.stdout
+                elif s == 'stderr':
+                    self.fhs[1] = sys.stderr
+                else:
+                    try:
+                        self.fhs.append(file(s, 'w'))
+                    except IOError, ioe:
+                         raise error.general("creating log file '" + s + \
+                                             "': " + str(ioe))
+
+    def __del__(self):
+        for f in range(2, len(self.fhs)):
+            self.fhs[f].close()
+
+    def has_stdout(self):
+        return self.fhs[0] is not None
+
+    def has_stderr(self):
+        return self.fhs[1] is not None
+
+    def output(self, text):
+        """Output the text message to all the logs."""
+        # Reformat the text to have local line types.
+        out = ''
+        for l in text.replace(chr(13), '').splitlines():
+            out += l + os.linesep 
+        for f in range(0, len(self.fhs)):
+            if self.fhs[f] is not None:
+                self.fhs[f].write(out)
+
+    def flush(self):
+        """Flush the output."""
+        for f in range(0, len(self.fhs)):
+            if self.fhs[f] is not None:
+                self.fhs[f].flush()
+        
+if __name__ == "__main__":
+    l = log(['stdout', 'log.txt'])
+    for i in range(0, 10):
+        l.output('hello world: %d\n' % (i))
+    l.output('hello world CRLF\r\n')
+    l.output('hello world NONE')
+    l.flush()
+    del l

diff -u /dev/null rtems-tools/specbuilder/specbuilder/setup.py:1.1
--- /dev/null	Sun Aug  8 21:10:36 2010
+++ rtems-tools/specbuilder/specbuilder/setup.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,101 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Setup a series of directories ready for building with the Spec Builder.
+#
+
+import os
+import shutil
+
+import build
+import defaults
+import error
+import log
+
+#
+# Version of Spec CrossGCC Builder.
+#
+version = '0.1'
+
+def _notice(opts, text):
+    if not opts.quiet() and not log.default.has_stdout():
+        print text
+    log.output(text)
+    log.flush()
+
+class setup:
+    """Set up the various directories in a specified path"""
+
+    _dirs = [ 'TARS',
+              'TARS',
+              'SPECS',
+              'SOURCE',
+              'RPMLIB',
+              'BUILD',
+              'TMP' ]
+
+    def __init__(self, path, _defaults, opts):
+        self.path = path
+        self.opts = opts
+        self.defaults = _defaults
+
+    def _output(self, text):
+        if not self.opts.quiet():
+            log.output(text)
+
+    def mkdir(self, path):
+        if not self.opts.dry_run():
+            self._output('making dir: ' + path)
+            try:
+                os.makedirs(path)
+            except IOError, err:
+                raise error.general('error creating path: ' + path)
+
+    def make(self, path):
+        for d in setup._dirs:
+            self.mkdir(os.path.join(path, d))
+
+def run():
+    import sys
+    try:
+        opts, _defaults = defaults.load(sys.argv)
+        log.default = log.log(opts.logfiles())
+        _notice(opts, 'RTEMS Tools, Setup Spec Builder, v%s' % (version))
+        for path in opts.params():
+            s = setup(path, _defaults = _defaults, opts = opts)
+            s.make()
+            del s
+    except error.general, gerr:
+        print gerr
+        sys.exit(1)
+    except error.internal, ierr:
+        print ierr
+        sys.exit(1)
+    except KeyboardInterrupt:
+        print 'user terminated'
+        sys.exit(1)
+    sys.exit(0)
+
+if __name__ == "__main__":
+    run()

diff -u /dev/null rtems-tools/specbuilder/specbuilder/spec.py:1.1
--- /dev/null	Sun Aug  8 21:10:37 2010
+++ rtems-tools/specbuilder/specbuilder/spec.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,760 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# This code is based on what ever doco about spec files I could find and 
+# RTEMS project's spec files. It parses a spec file into Python data types
+# that can be used by other software modules.
+#
+
+import os
+import re
+import sys
+
+import defaults
+import error
+import execute
+import log
+
+debug = False
+
+class package:
+
+    def __init__(self, name, arch):
+        self._name = name
+        self._arch = arch
+        self.directives = {}
+        self.infos = {}
+
+    def __str__(self):
+
+        def _dictlist(dl):
+            s = ''
+            dll = dl.keys()
+            dll.sort()
+            for d in dll:
+                s += '  ' + d + ':\n'
+                for l in dl[d]:
+                    s += '    ' + l + '\n'
+            return s
+
+        s = '\npackage: ' + self._name + \
+            '\n directives:\n' + _dictlist(self.directives) + \
+            '\n infos:\n' + _dictlist(self.infos)
+        
+        return s
+            
+    def get_info(self, info):
+        if not info in self.infos:
+            raise error.general('no ' + info + ' in package "' + self.name + '"')
+        return self.info
+
+    def version(self):
+        return self.get_info('Version')
+
+    def extract_info(self, label):
+        infos = {}
+        for i in self.infos:
+            il = i.lower()
+            if il.startswith(label) and il[len(label):].isdigit():
+                infos[il] = self.infos[i]
+        return infos
+
+    def find_info(self, label):
+        for i in self.infos:
+            if i.lower() == label:
+                return self.infos[i]
+        return None
+
+    def find_directive(self, label):
+        for d in self.directives:
+            if d.lower() == label:
+                return self.directives[d]
+        return None
+
+    def name(self):
+        info = self.find_info('name')
+        if info:
+            return info[0]
+        return self._name
+
+    def version(self):
+        info = self.find_info('version')
+        if not info:
+            return None
+        return info[0]
+
+    def release(self):
+        info = self.find_info('release')
+        if not info:
+            return None
+        return info[0]
+
+    def buildarch(self):
+        info = self.find_info('buildarch')
+        if not info:
+            return self._arch
+        return info[0]
+
+    def sources(self):
+        return self.extract_info('source');
+
+    def patches(self):
+        return self.extract_info('patch')
+
+    def prep(self):
+        return self.find_directive('%prep')
+        
+    def build(self):
+        return self.find_directive('%build')
+
+    def install(self):
+        return self.find_directive('%install')
+
+    def clean(self):
+        return self.find_directive('%clean')
+        
+    def post(self):
+        return self.find_directive('%post')
+
+    def long_name(self):
+        buildarch = self.buildarch()
+        return '-'.join([self.name(), self.version(), self.release()]) + \
+                            '.' + buildarch
+
+class file:
+    """Parse a spec file."""
+
+    _directive = [ '%description',
+                   '%prep',
+                   '%build',
+                   '%install',
+                   '%clean',
+                   '%post',
+                   '%preun',
+                   '%files' ]
+
+    _ignore = [ re.compile('%setup'),
+                re.compile('%doc'),
+                re.compile('%dir'),
+                re.compile('%ghost'),
+                re.compile('%exclude'),
+                re.compile('%source[0-9]*'),
+                re.compile('%patch[0-9]*'),
+                re.compile('%__os_install_post') ]
+
+    def __init__(self, name, _defaults, opts):
+        self.opts = opts
+        self.specpath = 'not set'
+        self.wss = re.compile(r'\s+')
+        self.tags = re.compile(r':+')
+        self.sf = re.compile(r'%\([^\)]+\)')
+        self.default_defines = {}
+        for d in _defaults:
+            self.default_defines[self._label(d)] = _defaults[d]
+        for arg in self.opts.args:
+            if arg.startswith('--with-') or arg.startswith('--without-'):
+                label = arg[2:].lower().replace('-', '_')
+                self.default_defines[self._label(label)] = label
+        self.load(name)
+
+    def __str__(self):
+
+        def _dict(dd):
+            s = ''
+            ddl = dd.keys()
+            ddl.sort()
+            for d in ddl:
+                s += '  ' + d + ': ' + dd[d] + '\n'
+            return s
+
+        s = 'spec: %s' % (self.specpath) + \
+            '\n' + str(self.opts) + \
+            '\nlines parsed: %d' % (self.lc) + \
+            '\nname: ' + self.name + \
+            '\ndefines:\n' + _dict(self.defines)
+        for _package in self._packages:
+            s += str(self._packages[_package])
+        return s
+
+    def _output(self, text):
+        if not self.opts.quiet():
+            log.output(text)
+
+    def _warning(self, msg):
+        self._output('warning: ' + self.name + ':' + str(self.lc) + ': ' + msg)
+
+    def _error(self, msg):
+        print >> sys.stderr, \
+            'error: ' + self.name + ':' + str(self.lc) + ': ' + msg
+        self.in_error = True
+
+    def _label(self, name):
+        return '%{' + name.lower() + '}'
+
+    def _macro_split(self, s):
+        '''Split the string (s) up by macros. Only split on the
+           outter level. Nested levels will need to split with futher calls.'''
+        trace_me = False
+        macros = []
+        nesting = []
+        has_braces = False
+        c = 0
+        while c < len(s):
+            if trace_me:
+                print 'ms:', c, '"' + s[c:] + '"', has_braces, len(nesting), nesting
+            #
+            # We need to watch for shell type variables or the form '${var}' because
+            # they can upset the brace matching.
+            #
+            if s[c] == '%' or s[c] == '$':
+                start = s[c]
+                c += 1
+                if c == len(s):
+                    continue
+                #
+                # Do we have '%%' or '%(' or '$%' or '$(' or not '${' ?
+                #
+                if s[c] == '%' or s[c] == '(' or (start == '$' and s[c] != '{'):
+                    continue
+                elif not s[c].isspace():
+                    #
+                    # If this is a shell macro and we are at the outter
+                    # level or is '$var' forget it and move on.
+                    #
+                    if start == '$' and (s[c] != '{' or len(nesting) == 0):
+                        continue
+                    if s[c] == '{':
+                        this_has_braces = True
+                    else:
+                        this_has_braces = False
+                    nesting.append((c - 1, has_braces))
+                    has_braces = this_has_braces
+            elif len(nesting) > 0:
+                if s[c] == '}' or (s[c].isspace() and not has_braces):
+                    #
+                    # Can have '%{?test: something %more}' where the
+                    # nested %more ends with the '}' which also ends
+                    # the outter macro.
+                    #
+                    if not has_braces:
+                        if s[c] == '}':
+                            macro_start, has_braces = nesting[len(nesting) - 1]
+                            nesting = nesting[:-1]
+                            if len(nesting) == 0:
+                                macros.append(s[macro_start:c].strip())
+                    if len(nesting) > 0:
+                        macro_start, has_braces = nesting[len(nesting) - 1]
+                        nesting = nesting[:-1]
+                        if len(nesting) == 0:
+                            macros.append(s[macro_start:c + 1].strip())
+            c += 1
+        if trace_me:
+            print 'ms:', macros
+        return macros
+                    
+    def _shell(self, line):
+        sl = self.sf.findall(line)
+        if len(sl):
+            e = execute.capture_execution()
+            for s in sl:
+                exit_code, proc, output = e.shell(s[2:-1])
+                if exit_code == 0:
+                    line = line.replace(s, output)
+                else:
+                    raise error.general('shell macro failed: ' + s + ': ' + output)
+        return line
+
+    def _expand(self, s):
+        expanded = True
+        while expanded:
+            expanded = False
+            ms = self._macro_split(s)
+            for m in ms:
+                mn = m
+                #
+                # A macro can be '%{macro}' or '%macro'. Turn the later into
+                # the former.
+                #
+                show_warning = True
+                if mn[1] != '{':
+                    for r in self._ignore:
+                        if r.match(mn) is not None:
+                            mn = None
+                            break
+                    else:
+                        mn = self._label(mn[1:])
+                        show_warning = False
+                elif m.startswith('%{expand'):
+                    colon = m.find(':')
+                    if colon < 8:
+                        self._warning('malformed expand macro, no colon found')
+                    else:
+                        e = self._expand(m[colon + 1:-1].strip())
+                        s = s.replace(m, e)
+                        expanded = True
+                        mn = None
+                elif m.startswith('%{with '):
+                    #
+                    # Change the ' ' to '_' because the macros have no spaces.
+                    #
+                    n = self._label('with_' + m[7:-1].strip())
+                    if n in self.defines:
+                        s = s.replace(m, '1')
+                    else:
+                        s = s.replace(m, '0')
+                    expanded = True
+                    mn = None
+                elif m.startswith('%{echo'):
+                    mn = None
+                elif m.startswith('%{defined'):
+                    n = self._label(m[9:-1].strip())
+                    if n in self.defines:
+                        s = s.replace(m, '1')
+                    else:
+                        s = s.replace(m, '0')
+                    expanded = True
+                    mn = None
+                elif m.startswith('%{?') or m.startswith('%{!?'):
+                    if m[2] == '!':
+                        start = 4
+                    else:
+                        start = 3
+                    colon = m[start:].find(':')
+                    if colon < 0:
+                        if not m.endswith('}'):
+                            self._warning("malform conditional macro'" + m)
+                            mn = None
+                        else:
+                            mn = self._label(m[start:-1])
+                    else:
+                        mn = self._label(m[start:start + colon])
+                    if mn:
+                        if m.startswith('%{?'):
+                            if mn in self.defines:
+                                if colon >= 0:
+                                    s = s.replace(m, m[start + colon + 1:-1])
+                                    expanded = True
+                                    mn = None
+                            else:
+                                mn = '%{nil}'
+                        else:
+                            if mn not in self.defines:
+                                if colon >= 0:
+                                    s = s.replace(m, m[start + colon + 1:-1])
+                                    expanded = True
+                                    mn = None
+                            else:
+                                mn = '%{nil}'
+                if mn:
+                    if mn.lower() in self.defines:
+                        s = s.replace(m, self.defines[mn.lower()])
+                        expanded = True
+                    elif show_warning:
+                        self._error("macro '" + mn + "' not found")
+        return self._shell(s)
+
+    def _define(self, spec, ls):
+        if len(ls) <= 1:
+            self._warning('invalid macro definition')
+        else:
+            d = self._label(ls[1])
+            if d not in self.defines:
+                if len(ls) == 2: 
+                    self.defines[d] = '1'
+                else:
+                    self.defines[d] = ls[2].strip()
+            else:
+                if self.opts.warn_all():
+                    self._warning("macro '" + d + "' already defined")
+
+    def _undefine(self, spec, ls):
+        if len(ls) <= 1:
+            self._warning('invalid macro definition')
+        else:
+            mn = self._label(ls[1])
+            if mn in self.defines:
+                self._error("macro '" + mn + "' not defined")
+            del self.defines[mn]
+
+    def _ifs(self, spec, ls, label, iftrue, isvalid):
+        text = []
+        in_iftrue = True
+        while True:
+            if isvalid and \
+                    ((iftrue and in_iftrue) or (not iftrue and not in_iftrue)):
+                this_isvalid = True
+            else:
+                this_isvalid = False
+            r = self._parse(spec, roc = True, isvalid = this_isvalid)
+            if r[0] == 'control':
+                if r[1] == '%end':
+                    self._error(label + ' without %endif')
+                if r[1] == '%endif':
+                    return text
+                if r[1] == '%else':
+                    in_iftrue = False
+            elif r[0] == 'data':
+                if this_isvalid:
+                    text.extend(r[1])
+
+    def _if(self, spec, ls, isvalid):
+        
+        global debug
+
+        def add(x, y):
+            return x + ' ' + str(y)
+
+        def check_bool(value):
+            if value.isdigit():
+                if int(value) == 0:
+                    istrue = False
+                else:
+                    istrue = True
+            else:
+                istrue = None
+            return istrue
+
+        istrue = False
+        if isvalid:
+            if len(ls) == 2:
+                s = ls[1]
+            else:
+                s = (ls[1] + ' ' + ls[2])
+            ifls = s.split()
+            if len(ifls) == 1:
+                istrue = check_bool(ifls[0])
+                if istrue == None:
+                    self._error('invalid if bool value: ' + reduce(add, ls, ''))
+                    istrue = False
+            elif len(ifls) == 2:
+                if ifls[0] == '!':
+                    istrue = check_bool(ifls[1])
+                    if istrue == None:
+                        self._error('invalid if bool value: ' + reduce(add, ls, ''))
+                        istrue = False
+                    else:
+                        istrue = not istrue
+                else:
+                    self._error('invalid if bool operator: ' + reduce(add, ls, ''))
+            elif len(ifls) == 3:
+                if ifls[1] == '==':
+                    if ifls[0] == ifls[2]:
+                        istrue = True
+                    else:
+                        istrue = False
+                elif ifls[1] == '!=' or ifls[1] == '=!':
+                    if ifls[0] != ifls[2]:
+                        istrue = True
+                    else:
+                        istrue = False
+                elif ifls[1] == '>':
+                    if ifls[0] > ifls[2]:
+                        istrue = True
+                    else:
+                        istrue = False
+                elif ifls[1] == '>=' or ifls[1] == '=>':
+                    if ifls[0] >= ifls[2]:
+                        istrue = True
+                    else:
+                        istrue = False
+                elif ifls[1] == '<=' or ifls[1] == '=<':
+                    if ifls[0] <= ifls[2]:
+                        istrue = True
+                    else:
+                        istrue = False
+                elif ifls[1] == '<':
+                    if ifls[0] < ifls[2]:
+                        istrue = True
+                    else:
+                        istrue = False
+                else:
+                    self._error('invalid %if operator: ' + reduce(add, ls, ''))
+            else:
+                self._error('malformed if: ' + reduce(add, ls, ''))
+            if debug:
+                print '_if:  ', ifls, istrue
+        return self._ifs(spec, ls, '%if', istrue, isvalid)
+            
+    def _ifos(self, spec, ls, isvalid):
+        isos = False
+        if isvalid:
+            os = self.define('_os')
+            if ls[0].find(os) >= 0 or ls[1].find(os) >= 0:
+                isos = True
+            else:
+                isos = False
+        return self._ifs(spec, ls, '%ifos', isos, isvalid)
+
+    def _ifarch(self, spec, positive, ls, isvalid):
+        isarch = False
+        if isvalid:
+            arch = self.define('_arch')
+            if ls[0].find(arch) >= 0 or ls[1].find(arch) >= 0:
+                isarch = True
+            else:
+                isarch = False
+        if not positive:
+            isarch = not isarch
+        return self._ifs(spec, ls, '%ifarch', isarch, isvalid)
+
+    def _parse(self, spec, roc = False, isvalid = True):
+        # roc = return on control
+
+        global debug
+
+        def _clean(line):
+            line = line[0:-1]
+            b = line.find('#')
+            if b >= 0:
+                line = line[1:b]
+            return line.strip()
+
+        #
+        # Need to add code to count matching '{' and '}' and if they
+        # do not match get the next line and add to the string until
+        # they match. This closes an opening '{' that is on another
+        # line.
+        #
+
+        for l in spec:
+            self.lc += 1
+            l = _clean(l)
+            if len(l) == 0:
+                continue
+            if debug:
+                print '%03d: %d %s' % (self.lc, isvalid, l)
+            if isvalid:
+                l = self._expand(l)
+            if len(l) == 0:
+                continue
+            if l[0] == '%':
+                ls = self.wss.split(l, 2)
+                if ls[0] == '%package':
+                    if isvalid:
+                        if ls[1] == '-n':
+                            name = ls[2]
+                        else:
+                            name = self.name + '-' + ls[1]
+                        return ('package', name)
+                elif ls[0] == '%define' or ls[0] == '%global':
+                    if isvalid:
+                        self._define(spec, ls)
+                elif ls[0] == '%undefine':
+                    if isvalid:
+                        self._undefine(spec, ls)
+                elif ls[0] == '%if':
+                    d = self._if(spec, ls, isvalid)
+                    if len(d):
+                        return ('data', d)
+                elif ls[0] == '%ifos':
+                    d = self._ifos(spec, ls, isvalid)
+                    if len(d):
+                        return ('data', d)
+                elif ls[0] == '%ifarch':
+                    d = self._ifarch(spec, True, ls, isvalid)
+                    if len(d):
+                        return ('data', d)
+                elif ls[0] == '%ifnarch':
+                    d = self._ifarch(spec, False, ls, isvalid)
+                    if len(d):
+                        return ('data', d)
+                elif ls[0] == '%endif':
+                    if roc:
+                        return ('control', '%endif')
+                    self._warning("unexpected '" + ls[0] + "'")
+                elif ls[0] == '%else':
+                    if roc:
+                        return ('control', '%else')
+                    self._warning("unexpected '" + ls[0] + "'")
+                elif ls[0].startswith('%defattr'):
+                    return ('data', [l])
+                elif ls[0] == '%bcond_with':
+                    if isvalid:
+                        #
+                        # Check is already defined. Would be by the command line or
+                        # even a host specific default.
+                        #
+                        if self._label('with_' + ls[1]) not in self.defines:
+                            self._define(spec, (ls[0], 'without_' + ls[1]))
+                elif ls[0] == '%bcond_without':
+                    if isvalid:
+                        if self._label('without_' + ls[1]) not in self.defines:
+                            self._define(spec, (ls[0], 'with_' + ls[1]))
+                else:
+                    for r in self._ignore:
+                        if r.match(ls[0]) is not None:
+                            return ('data', [l])
+                    if isvalid:
+                        for d in self._directive:
+                            if ls[0].strip() == d:
+                                if len(ls) == 1:
+                                    package = 'main'
+                                elif len(ls) == 2:
+                                    package = ls[1].strip()
+                                else:
+                                    if ls[1].strip() != '-n':
+                                        self._warning("unknown directive option: '" + ls[1] + "'")
+                                    package = ls[2].strip()
+                                return ('directive', ls[0].strip(), package)
+                        self._warning("unknown directive: '" + ls[0] + "'")
+                        return ('data', [l])
+            else:
+                return ('data', [l])
+        return ('control', '%end')
+
+    def _set_package(self, _package):
+        if self.package == 'main' and \
+                self._packages[self.package].name() != None:
+            if self._packages[self.package].name() == _package:
+                return
+        if _package not in self._packages:
+            self._packages[_package] = package(_package, 
+                                               self.define('%{_arch}'))
+        self.package = _package
+
+    def _directive_extend(self, dir, data):
+        if dir not in self._packages[self.package].directives:
+            self._packages[self.package].directives[dir] = []
+        for i in range(0, len(data)):
+            data[i] = data[i].strip()
+        self._packages[self.package].directives[dir].extend(data)
+
+    def _info_append(self, info, data):
+        if info not in self._packages[self.package].infos:
+            self._packages[self.package].infos[info] = []
+        self._packages[self.package].infos[info].append(data)
+
+    def load(self, name):
+
+        global debug
+
+        self.in_error = False
+        self.name = name
+        self.lc = 0
+        self.defines = self.default_defines
+        self.conditionals = {}
+        self._packages = {}
+        self.package = 'main'
+        self._packages[self.package] = package(self.package, 
+                                               self.define('%{_arch}'))
+        self.specpath = os.path.join(self.abspath('_specdir'), name)
+        if not os.path.exists(self.specpath):
+            raise error.general('no spec file found: ' + self.specpath)
+        try:
+            spec = open(self.specpath, 'r')
+        except IOError, err:
+            raise error.general('error opening spec file: ' + self.specpath)
+        try:
+            dir = None
+            data = []
+            while True:
+                r = self._parse(spec)
+                if r[0] == 'package':
+                    self._set_package(r[1])
+                    dir = None
+                elif r[0] == 'control':
+                    if r[1] == '%end':
+                        break
+                    self._warning("unexpected '" + r[1] + "'")
+                elif r[0] == 'directive':
+                    self._set_package(r[2])
+                    if dir and dir != r[1]:
+                        self._directive_extend(dir, data)
+                    dir = r[1]
+                    data = []
+                elif r[0] == 'data':
+                    for l in r[1]:
+                        l = self._expand(l)
+                        if not dir:
+                            ls = self.tags.split(l, 1)
+                            if debug:
+                                print '_tag: ', l, ls
+                            if len(ls) > 1:
+                                i = ls[0]
+                                self._info_append(i, ls[1].strip())
+                                # It seems like the info's also appear as
+                                # defines or can be accessed via macros.
+                                if ls[0][len(ls[0]) - 1] == ':':
+                                    ls[0] = ls[0][:-1]
+                                ls[0] = ls[0].lower()
+                                self._define(None, ('', ls[0], ls[1]))
+                            else:
+                                self._warning("invalid format: '" + l[:-1] + "'")
+                        else:
+                            data.append(l)
+                else:
+                    self._error("invalid parse state: '" + r[0] + "'")
+            self._directive_extend(dir, data)
+        finally:
+            spec.close()
+
+    def define(self, name):
+        if name.lower() in self.defines:
+            d = self.defines[name.lower()]
+        else:
+            n = self._label(name)
+            if n in self.defines:
+                d = self.defines[n]
+            else:
+                raise error.general('macro "' + name + '" not found')
+        return self._expand(d)
+
+    def expand(self, line):
+        return self._expand(line)
+
+    def directive(self, _package, name):
+        if _package not in self._packages:
+            raise error.general('package "' + _package + '" not found')
+        if name not in self._packages[_package].directives:
+            raise error.general('directive "' + name + \
+                                    '" not found in package "' + _package + '"')
+        return self._packages[_package].directives[name]
+
+    def abspath(self, path):
+        return os.path.abspath(self.define(path))
+
+    def packages(self):
+        return self._packages
+
+def run():
+    import sys
+    try:
+        opts, _defaults = defaults.load(sys.argv)
+        for spec_file in opts.spec_files():
+            s = file(spec_file, _defaults = _defaults, opts = opts)
+            print s
+            del s
+    except error.general, gerr:
+        print gerr
+        sys.exit(1)
+    except error.internal, ierr:
+        print ierr
+        sys.exit(1)
+    except KeyboardInterrupt:
+        print 'user terminated'
+        sys.exit(1)
+    sys.exit(0)
+
+if __name__ == "__main__":
+    run()

diff -u /dev/null rtems-tools/specbuilder/specbuilder/status.py:1.1
--- /dev/null	Sun Aug  8 21:10:37 2010
+++ rtems-tools/specbuilder/specbuilder/status.py	Sun Aug  8 20:29:43 2010
@@ -0,0 +1,95 @@
+#
+# $Id$
+#
+# RTEMS Tools Project (http://www.rtems.org/)
+# Copyright 2010 Chris Johns (chrisj at rtems.org)
+# All rights reserved.
+#
+# This file is part of the RTEMS Tools package in 'rtems-tools'.
+#
+# RTEMS Tools is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# RTEMS Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Extract the status of the spec files found in the SPECS directory.
+# The status is the name, source and patches.
+#
+
+import os
+
+import defaults
+import error
+import spec
+
+class status:
+    """Return the status of a package given a spec file."""
+
+    def __init__(self, name, _defaults, opts):
+        self.opts = opts
+        self.spec = spec.file(name, _defaults = _defaults, opts = opts)
+
+    def __str__(self):
+
+        def str_package(package):
+            sources = package.sources()
+            patches = package.patches()
+            version = package.version()
+            release = package.release()
+            buildarch = package.buildarch()
+            s = '\n name: ' + package.name()
+            if buildarch:
+                s += '\n    arch: ' + buildarch
+            if version:
+                s += '\n version: ' + version
+            if release:
+                s += '\n release: ' + release
+            if len(sources):
+                s += '\n sources: %d' % (len(sources))
+                c = 1
+                for i in sources:
+                    s += '\n  %d: ' % (c) + sources[i][0]
+                    c += 1
+                s += '\n patches: %d' % (len(patches))
+                c = 1
+                for i in patches:
+                    s += '\n  %d: ' % (c) + patches[i][0]
+                    c += 1
+            return s
+
+        packages = self.spec.packages()
+        s = 'spec: ' + os.path.basename(self.spec.name) + \
+            str_package(packages['main'])
+        for p in packages:
+            if p != 'main':
+                s += str_package(packages[p])
+        return s
+
+def run():
+    import sys
+    try:
+        opts, _defaults = defaults.load(sys.argv)
+        for spec_file in opts.spec_files():
+            s = status(spec_file, _defaults = _defaults, opts = opts)
+            print s
+            del s
+    except error.general, gerr:
+        print gerr
+        sys.exit(1)
+    except error.internal, ierr:
+        print ierr
+        sys.exit(1)
+    sys.exit(0)
+
+if __name__ == "__main__":
+    run()



--

Generated by Deluxe Loginfo [http://www.codewiz.org/projects/index.html#loginfo] 2.122 by Bernardo Innocenti <bernie at develer.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/vc/attachments/20100808/ef88b906/attachment.html>


More information about the vc mailing list