aboutsummaryrefslogtreecommitdiff
path: root/utils/llvm-build
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2011-11-03 17:56:10 +0000
committerDaniel Dunbar <daniel@zuster.org>2011-11-03 17:56:10 +0000
commit9da6b1244191319b39779307d60d7729811d3d5c (patch)
tree98c986953a77250405c407c4efd4062c794d8446 /utils/llvm-build
parentdf578254a1241a6cab122aa6d5396995d928e24a (diff)
llvm-build: Fill in more of component parsing to be more strict and
differentiate between strings and lists. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143622 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/llvm-build')
-rw-r--r--utils/llvm-build/llvmbuild/componentinfo.py108
-rw-r--r--utils/llvm-build/llvmbuild/util.py20
2 files changed, 108 insertions, 20 deletions
diff --git a/utils/llvm-build/llvmbuild/componentinfo.py b/utils/llvm-build/llvmbuild/componentinfo.py
index a434bd884c..e15dbda756 100644
--- a/utils/llvm-build/llvmbuild/componentinfo.py
+++ b/utils/llvm-build/llvmbuild/componentinfo.py
@@ -5,6 +5,11 @@ Descriptor objects for entities that are part of the LLVM project.
import ConfigParser
import sys
+from util import *
+
+class ParseError(Exception):
+ pass
+
class ComponentInfo(object):
"""
Base class for component descriptions.
@@ -12,6 +17,15 @@ class ComponentInfo(object):
type_name = None
+ @staticmethod
+ def parse_items(items, has_dependencies = True):
+ kwargs = {}
+ kwargs['name'] = items.get_string('name')
+ kwargs['parent'] = items.get_optional_string('parent')
+ if has_dependencies:
+ kwargs['dependencies'] = items.get_list('dependencies')
+ return kwargs
+
def __init__(self, subpath, name, dependencies, parent):
if not subpath.startswith('/'):
raise ValueError,"invalid subpath: %r" % subpath
@@ -31,14 +45,28 @@ class GroupComponentInfo(ComponentInfo):
type_name = 'Group'
+ @staticmethod
+ def parse(subpath, items):
+ kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
+ return GroupComponentInfo(subpath, **kwargs)
+
def __init__(self, subpath, name, parent):
ComponentInfo.__init__(self, subpath, name, [], parent)
class LibraryComponentInfo(ComponentInfo):
type_name = 'Library'
- def __init__(self, subpath, name, dependencies, parent, library_name = None,
- required_libraries = [], add_to_library_groups = []):
+ @staticmethod
+ def parse(subpath, items):
+ kwargs = ComponentInfo.parse_items(items)
+ kwargs['library_name'] = items.get_optional_string('name')
+ kwargs['required_libraries'] = items.get_list('required_libraries')
+ kwargs['add_to_library_groups'] = items.get_list(
+ 'add_to_library_groups')
+ return LibraryComponentInfo(subpath, **kwargs)
+
+ def __init__(self, subpath, name, dependencies, parent, library_name,
+ required_libraries, add_to_library_groups):
ComponentInfo.__init__(self, subpath, name, dependencies, parent)
# If given, the name to use for the library instead of deriving it from
@@ -56,6 +84,14 @@ class LibraryComponentInfo(ComponentInfo):
class LibraryGroupComponentInfo(ComponentInfo):
type_name = 'LibraryGroup'
+ @staticmethod
+ def parse(subpath, items):
+ kwargs = ComponentInfo.parse_items(items, has_dependencies = False)
+ kwargs['required_libraries'] = items.get_list('required_libraries')
+ kwargs['add_to_library_groups'] = items.get_list(
+ 'add_to_library_groups')
+ return LibraryGroupComponentInfo(subpath, **kwargs)
+
def __init__(self, subpath, name, parent, required_libraries = [],
add_to_library_groups = []):
ComponentInfo.__init__(self, subpath, name, [], parent)
@@ -71,8 +107,14 @@ class LibraryGroupComponentInfo(ComponentInfo):
class ToolComponentInfo(ComponentInfo):
type_name = 'Tool'
+ @staticmethod
+ def parse(subpath, items):
+ kwargs = ComponentInfo.parse_items(items)
+ kwargs['required_libraries'] = items.get_list('required_libraries')
+ return ToolComponentInfo(subpath, **kwargs)
+
def __init__(self, subpath, name, dependencies, parent,
- required_libraries = []):
+ required_libraries):
ComponentInfo.__init__(self, subpath, name, dependencies, parent)
# The names of the library components which are required to link this
@@ -82,6 +124,38 @@ class ToolComponentInfo(ComponentInfo):
class BuildToolComponentInfo(ToolComponentInfo):
type_name = 'BuildTool'
+ @staticmethod
+ def parse(subpath, items):
+ kwargs = ComponentInfo.parse_items(items)
+ kwargs['required_libraries'] = items.get_list('required_libraries')
+ return BuildToolComponentInfo(subpath, **kwargs)
+
+###
+
+class IniFormatParser(dict):
+ def get_list(self, key):
+ # Check if the value is defined.
+ value = self.get(key)
+ if value is None:
+ return []
+
+ # Lists are just whitespace separated strings.
+ return value.split()
+
+ def get_optional_string(self, key):
+ value = self.get_list(key)
+ if not value:
+ return None
+ if len(value) > 1:
+ raise ParseError("multiple values for scalar key: %r" % key)
+ return value[0]
+
+ def get_string(self, key):
+ value = self.get_optional_string(key)
+ if not value:
+ raise ParseError("missing value for required string: %r" % key)
+ return value
+
_component_type_map = dict(
(t.type_name, t)
for t in (GroupComponentInfo,
@@ -97,38 +171,32 @@ def load_from_path(path, subpath):
for section in parser.sections():
if not section.startswith('component'):
# We don't expect arbitrary sections currently, warn the user.
- print >>sys.stderr, "warning: ignoring unknown section %r in %r" % (
- section, path)
+ warning("ignoring unknown section %r in %r" % (section, path))
continue
- # Load the component that this section describes. For now we just do
- # this the trivial way by letting python validate the argument
- # assignment. This is simple, but means users see lame diagnostics. We
- # should audit the component manually, eventually.
+ # Determine the type of the component to instantiate.
if not parser.has_option(section, 'type'):
- print >>sys.stderr, "error: invalid component %r in %r: %s" % (
- section, path, "no component type")
- raise SystemExit, 1
+ fatal("invalid component %r in %r: %s" % (
+ section, path, "no component type"))
type_name = parser.get(section, 'type')
type_class = _component_type_map.get(type_name)
if type_class is None:
- print >>sys.stderr, "error: invalid component %r in %r: %s" % (
- section, path, "invalid component type: %r" % type_name)
- raise SystemExit, 1
-
- items = dict(parser.items(section))
- items['subpath'] = subpath
- items.pop('type')
+ fatal("invalid component %r in %r: %s" % (
+ section, path, "invalid component type: %r" % type_name))
# Instantiate the component based on the remaining values.
try:
- info = type_class(**items)
+ info = type_class.parse(subpath,
+ IniFormatParser(parser.items(section)))
except TypeError:
print >>sys.stderr, "error: invalid component %r in %r: %s" % (
section, path, "unable to instantiate: %r" % type_name)
import traceback
traceback.print_exc()
raise SystemExit, 1
+ except ParseError,e:
+ fatal("unable to load component %r in %r: %s" % (
+ section, path, e.message))
yield info
diff --git a/utils/llvm-build/llvmbuild/util.py b/utils/llvm-build/llvmbuild/util.py
new file mode 100644
index 0000000000..cf6fa28573
--- /dev/null
+++ b/utils/llvm-build/llvmbuild/util.py
@@ -0,0 +1,20 @@
+import inspect
+import os
+import sys
+
+def _write_message(kind, message):
+ # Get the file/line where this message was generated.
+ f = inspect.currentframe()
+ # Step out of _write_message, and then out of wrapper.
+ f = f.f_back.f_back
+ file,line,_,_,_ = inspect.getframeinfo(f)
+ location = '%s:%d' % (os.path.basename(file), line)
+
+ print >>sys.stderr, '%s: %s: %s' % (location, kind, message)
+
+note = lambda message: _write_message('note', message)
+warning = lambda message: _write_message('warning', message)
+error = lambda message: _write_message('error', message)
+fatal = lambda message: (_write_message('fatal error', message), sys.exit(1))
+
+__all__ = ['note', 'warning', 'error', 'fatal']