summaryrefslogtreecommitdiff
path: root/buildtools/wafadmin/Environment.py
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2012-01-04 00:31:27 +0100
committerJelmer Vernooij <jelmer@samba.org>2012-01-04 22:34:20 +0100
commit4f4bce5301ffd8c12aed1b108affa1a75feefb67 (patch)
tree1607accd70a2c37a9b996f7b42ec926b014cfe5b /buildtools/wafadmin/Environment.py
parent1b45f2aed86dda9fda6e6bcf1c9c7cbdc471c18d (diff)
downloadsamba-4f4bce5301ffd8c12aed1b108affa1a75feefb67.tar.gz
samba-4f4bce5301ffd8c12aed1b108affa1a75feefb67.tar.bz2
samba-4f4bce5301ffd8c12aed1b108affa1a75feefb67.zip
Include waf as an extracted source directory, rather than as a one-in-a-file script.
Diffstat (limited to 'buildtools/wafadmin/Environment.py')
-rw-r--r--buildtools/wafadmin/Environment.py210
1 files changed, 210 insertions, 0 deletions
diff --git a/buildtools/wafadmin/Environment.py b/buildtools/wafadmin/Environment.py
new file mode 100644
index 0000000000..52c83b4f3e
--- /dev/null
+++ b/buildtools/wafadmin/Environment.py
@@ -0,0 +1,210 @@
+#!/usr/bin/env python
+# encoding: utf-8
+# Thomas Nagy, 2005 (ita)
+
+"""Environment representation
+
+There is one gotcha: getitem returns [] if the contents evals to False
+This means env['foo'] = {}; print env['foo'] will print [] not {}
+"""
+
+import os, copy, re
+import Logs, Options, Utils
+from Constants import *
+re_imp = re.compile('^(#)*?([^#=]*?)\ =\ (.*?)$', re.M)
+
+class Environment(object):
+ """A safe-to-use dictionary, but do not attach functions to it please (break cPickle)
+ An environment instance can be stored into a file and loaded easily
+ """
+ __slots__ = ("table", "parent")
+ def __init__(self, filename=None):
+ self.table = {}
+ #self.parent = None
+
+ if filename:
+ self.load(filename)
+
+ def __contains__(self, key):
+ if key in self.table: return True
+ try: return self.parent.__contains__(key)
+ except AttributeError: return False # parent may not exist
+
+ def __str__(self):
+ keys = set()
+ cur = self
+ while cur:
+ keys.update(cur.table.keys())
+ cur = getattr(cur, 'parent', None)
+ keys = list(keys)
+ keys.sort()
+ return "\n".join(["%r %r" % (x, self.__getitem__(x)) for x in keys])
+
+ def __getitem__(self, key):
+ try:
+ while 1:
+ x = self.table.get(key, None)
+ if not x is None:
+ return x
+ self = self.parent
+ except AttributeError:
+ return []
+
+ def __setitem__(self, key, value):
+ self.table[key] = value
+
+ def __delitem__(self, key):
+ del self.table[key]
+
+ def pop(self, key, *args):
+ if len(args):
+ return self.table.pop(key, *args)
+ return self.table.pop(key)
+
+ def set_variant(self, name):
+ self.table[VARIANT] = name
+
+ def variant(self):
+ try:
+ while 1:
+ x = self.table.get(VARIANT, None)
+ if not x is None:
+ return x
+ self = self.parent
+ except AttributeError:
+ return DEFAULT
+
+ def copy(self):
+ # TODO waf 1.6 rename this method derive, #368
+ newenv = Environment()
+ newenv.parent = self
+ return newenv
+
+ def detach(self):
+ """TODO try it
+ modifying the original env will not change the copy"""
+ tbl = self.get_merged_dict()
+ try:
+ delattr(self, 'parent')
+ except AttributeError:
+ pass
+ else:
+ keys = tbl.keys()
+ for x in keys:
+ tbl[x] = copy.deepcopy(tbl[x])
+ self.table = tbl
+
+ def get_flat(self, key):
+ s = self[key]
+ if isinstance(s, str): return s
+ return ' '.join(s)
+
+ def _get_list_value_for_modification(self, key):
+ """Gets a value that must be a list for further modification. The
+ list may be modified inplace and there is no need to
+ "self.table[var] = value" afterwards.
+ """
+ try:
+ value = self.table[key]
+ except KeyError:
+ try: value = self.parent[key]
+ except AttributeError: value = []
+ if isinstance(value, list):
+ value = value[:]
+ else:
+ value = [value]
+ else:
+ if not isinstance(value, list):
+ value = [value]
+ self.table[key] = value
+ return value
+
+ def append_value(self, var, value):
+ current_value = self._get_list_value_for_modification(var)
+
+ if isinstance(value, list):
+ current_value.extend(value)
+ else:
+ current_value.append(value)
+
+ def prepend_value(self, var, value):
+ current_value = self._get_list_value_for_modification(var)
+
+ if isinstance(value, list):
+ current_value = value + current_value
+ # a new list: update the dictionary entry
+ self.table[var] = current_value
+ else:
+ current_value.insert(0, value)
+
+ # prepend unique would be ambiguous
+ def append_unique(self, var, value):
+ current_value = self._get_list_value_for_modification(var)
+
+ if isinstance(value, list):
+ for value_item in value:
+ if value_item not in current_value:
+ current_value.append(value_item)
+ else:
+ if value not in current_value:
+ current_value.append(value)
+
+ def get_merged_dict(self):
+ """compute a merged table"""
+ table_list = []
+ env = self
+ while 1:
+ table_list.insert(0, env.table)
+ try: env = env.parent
+ except AttributeError: break
+ merged_table = {}
+ for table in table_list:
+ merged_table.update(table)
+ return merged_table
+
+ def store(self, filename):
+ "Write the variables into a file"
+ file = open(filename, 'w')
+ merged_table = self.get_merged_dict()
+ keys = list(merged_table.keys())
+ keys.sort()
+ for k in keys: file.write('%s = %r\n' % (k, merged_table[k]))
+ file.close()
+
+ def load(self, filename):
+ "Retrieve the variables from a file"
+ tbl = self.table
+ code = Utils.readf(filename)
+ for m in re_imp.finditer(code):
+ g = m.group
+ tbl[g(2)] = eval(g(3))
+ Logs.debug('env: %s', self.table)
+
+ def get_destdir(self):
+ "return the destdir, useful for installing"
+ if self.__getitem__('NOINSTALL'): return ''
+ return Options.options.destdir
+
+ def update(self, d):
+ for k, v in d.iteritems():
+ self[k] = v
+
+
+ def __getattr__(self, name):
+ if name in self.__slots__:
+ return object.__getattr__(self, name)
+ else:
+ return self[name]
+
+ def __setattr__(self, name, value):
+ if name in self.__slots__:
+ object.__setattr__(self, name, value)
+ else:
+ self[name] = value
+
+ def __delattr__(self, name):
+ if name in self.__slots__:
+ object.__delattr__(self, name)
+ else:
+ del self[name]
+